From a1ce2d1ac8d646b63532ed9ac459ffea39ec8c20 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 19 May 2025 13:09:59 +1000 Subject: [PATCH] Use _u32 in FeeRate constructor instead of _unchecked When constructing an `Amount` it was observed recently that a `u32` is often big enough. For the same reason we can use a `u32` to construct a fee rate instead of overflowing. Use `_u32`in the constructor and remove the panic. --- bitcoin/src/blockdata/script/tests.rs | 4 ++-- bitcoin/src/psbt/mod.rs | 2 +- units/src/fee_rate/mod.rs | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bitcoin/src/blockdata/script/tests.rs b/bitcoin/src/blockdata/script/tests.rs index b1bfae4e0..590d233d3 100644 --- a/bitcoin/src/blockdata/script/tests.rs +++ b/bitcoin/src/blockdata/script/tests.rs @@ -751,7 +751,7 @@ fn default_dust_value() { assert!(script_p2wpkh.is_p2wpkh()); assert_eq!(script_p2wpkh.minimal_non_dust(), Amount::from_sat_u32(294)); assert_eq!( - script_p2wpkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_unchecked(6)), + script_p2wpkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_u32(6)), Some(Amount::from_sat_u32(588)) ); @@ -765,7 +765,7 @@ fn default_dust_value() { assert!(script_p2pkh.is_p2pkh()); assert_eq!(script_p2pkh.minimal_non_dust(), Amount::from_sat_u32(546)); assert_eq!( - script_p2pkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_unchecked(6)), + script_p2pkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_u32(6)), Some(Amount::from_sat_u32(1092)) ); } diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index 9418ae8bf..d7ebf59bd 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -130,7 +130,7 @@ impl Psbt { /// 1000 sats/vByte. 25k sats/vByte is obviously a mistake at this point. /// /// [`extract_tx`]: Psbt::extract_tx - pub const DEFAULT_MAX_FEE_RATE: FeeRate = FeeRate::from_sat_per_vb_unchecked(25_000); + pub const DEFAULT_MAX_FEE_RATE: FeeRate = FeeRate::from_sat_per_vb_u32(25_000); /// An alias for [`extract_tx_fee_rate_limit`]. /// diff --git a/units/src/fee_rate/mod.rs b/units/src/fee_rate/mod.rs index 520790e37..c8da2afdb 100644 --- a/units/src/fee_rate/mod.rs +++ b/units/src/fee_rate/mod.rs @@ -49,10 +49,10 @@ impl FeeRate { /// Minimum fee rate required to broadcast a transaction. /// /// The value matches the default Bitcoin Core policy at the time of library release. - pub const BROADCAST_MIN: FeeRate = FeeRate::from_sat_per_vb_unchecked(1); + pub const BROADCAST_MIN: FeeRate = FeeRate::from_sat_per_vb_u32(1); /// Fee rate used to compute dust amount. - pub const DUST: FeeRate = FeeRate::from_sat_per_vb_unchecked(3); + pub const DUST: FeeRate = FeeRate::from_sat_per_vb_u32(3); /// Constructs a new [`FeeRate`] from satoshis per virtual bytes. /// @@ -66,8 +66,9 @@ impl FeeRate { Some(FeeRate::from_sat_per_kwu(sat_vb.checked_mul(1000 / 4)?)) } - /// Constructs a new [`FeeRate`] from satoshis per virtual bytes without overflow check. - pub const fn from_sat_per_vb_unchecked(sat_vb: u64) -> Self { + /// Constructs a new [`FeeRate`] from satoshis per virtual bytes. + pub const fn from_sat_per_vb_u32(sat_vb: u32) -> Self { + let sat_vb = sat_vb as u64; // No `Into` in const context. FeeRate::from_sat_per_kwu(sat_vb * (1000 / 4)) } @@ -304,15 +305,14 @@ mod tests { } #[test] - fn from_sat_per_vb_unchecked() { - let fee_rate = FeeRate::from_sat_per_vb_unchecked(10); + fn from_sat_per_vb_u32() { + let fee_rate = FeeRate::from_sat_per_vb_u32(10); assert_eq!(FeeRate::from_sat_per_kwu(2500), fee_rate); } #[test] #[cfg(debug_assertions)] - #[should_panic = "attempt to multiply with overflow"] - fn from_sat_per_vb_unchecked_panic() { FeeRate::from_sat_per_vb_unchecked(u64::MAX); } + fn from_sat_per_vb_u32_cannot_panic() { FeeRate::from_sat_per_vb_u32(u32::MAX); } #[test] fn raw_feerate() {