From 13595fbe7d5ddcab0492445169297e009b6d6cc7 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 28 Feb 2025 10:45:34 +1100 Subject: [PATCH] Fix amount whole bitcoin constructors I royally botched the recent effort to make const amount constructors use a smaller type. I left in an unnecessary panic and forgot to do both of them. Note these function return values will change again very shortly when we start enforcing the MAX_MONEY invariant. However the 64 to 32 bit change is unrelated to that and is easier to review if done separately. Whole bitcoin can not in any sane environment be greater than 21,000,000 which fits in 32 bits so we can take a 32 bit integer in the whole bitcoin constructors without loss of utility. Doing so removes the potential panic. This is a breaking API change. We elect not to deprecate because we want to keep the same function names. --- units/src/amount/signed.rs | 26 ++++++++------------------ units/src/amount/unsigned.rs | 23 ++++++----------------- 2 files changed, 14 insertions(+), 35 deletions(-) diff --git a/units/src/amount/signed.rs b/units/src/amount/signed.rs index bdabfefde..df9aa18f3 100644 --- a/units/src/amount/signed.rs +++ b/units/src/amount/signed.rs @@ -121,29 +121,19 @@ impl SignedAmount { } /// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`]. - /// - /// # Errors - /// - /// The function errors if the argument multiplied by the number of sats - /// per bitcoin overflows an `i64` type. - pub fn from_int_btc>(whole_bitcoin: T) -> Result { - match whole_bitcoin.into().checked_mul(100_000_000) { - Some(amount) => Ok(Self::from_sat(amount)), - None => Err(OutOfRangeError { is_signed: true, is_greater_than_max: true }), - } + #[allow(clippy::missing_panics_doc)] + pub fn from_int_btc>(whole_bitcoin: T) -> SignedAmount { + SignedAmount::from_int_btc_const(whole_bitcoin.into()) } /// Converts from a value expressing a whole number of bitcoin to a [`SignedAmount`] /// in const context. - /// - /// # Panics - /// - /// The function panics if the argument multiplied by the number of sats - /// per bitcoin overflows an `i64` type. - pub const fn from_int_btc_const(whole_bitcoin: i64) -> SignedAmount { - match whole_bitcoin.checked_mul(100_000_000) { + #[allow(clippy::missing_panics_doc)] + pub const fn from_int_btc_const(whole_bitcoin: i32) -> SignedAmount { + let btc = whole_bitcoin as i64; // Can't call `into` in const context. + match btc.checked_mul(100_000_000) { Some(amount) => SignedAmount::from_sat(amount), - None => panic!("checked_mul overflowed"), + None => panic!("cannot overflow in i64"), } } diff --git a/units/src/amount/unsigned.rs b/units/src/amount/unsigned.rs index 27435fba0..167ad85f3 100644 --- a/units/src/amount/unsigned.rs +++ b/units/src/amount/unsigned.rs @@ -119,30 +119,19 @@ impl Amount { } /// Converts from a value expressing a whole number of bitcoin to an [`Amount`]. - /// - /// # Errors - /// - /// The function errors if the argument multiplied by the number of sats - /// per bitcoin overflows a `u64` type. - pub fn from_int_btc>(whole_bitcoin: T) -> Result { - match whole_bitcoin.into().checked_mul(100_000_000) { - Some(amount) => Ok(Self::from_sat(amount)), - None => Err(OutOfRangeError { is_signed: false, is_greater_than_max: true }), - } + #[allow(clippy::missing_panics_doc)] + pub fn from_int_btc>(whole_bitcoin: T) -> Amount { + Amount::from_int_btc_const(whole_bitcoin.into()) } /// Converts from a value expressing a whole number of bitcoin to an [`Amount`] /// in const context. - /// - /// # Panics - /// - /// The function panics if the argument multiplied by the number of sats - /// per bitcoin overflows a `u64` type. + #[allow(clippy::missing_panics_doc)] pub const fn from_int_btc_const(whole_bitcoin: u32) -> Amount { - let btc = whole_bitcoin as u64; // Can't call u64::from in const context. + let btc = whole_bitcoin as u64; // Can't call `into` in const context. match btc.checked_mul(100_000_000) { Some(amount) => Amount::from_sat(amount), - None => panic!("checked_mul overflowed"), + None => panic!("cannot overflow a u64"), } }