diff --git a/bitcoin/examples/taproot-psbt.rs b/bitcoin/examples/taproot-psbt.rs index 0ad84de0..3794688d 100644 --- a/bitcoin/examples/taproot-psbt.rs +++ b/bitcoin/examples/taproot-psbt.rs @@ -49,7 +49,7 @@ const UTXO_1: P2trUtxo = P2trUtxo { script_pubkey: UTXO_SCRIPT_PUBKEY, pubkey: UTXO_PUBKEY, master_fingerprint: UTXO_MASTER_FINGERPRINT, - amount_in_sats: Amount::from_sat(50 * 100_000_000), // 50 BTC + amount_in_sats: Amount::from_int_btc(50), derivation_path: BIP86_DERIVATION_PATH, }; @@ -60,7 +60,7 @@ const UTXO_2: P2trUtxo = P2trUtxo { script_pubkey: UTXO_SCRIPT_PUBKEY, pubkey: UTXO_PUBKEY, master_fingerprint: UTXO_MASTER_FINGERPRINT, - amount_in_sats: Amount::from_sat(50 * 100_000_000), // 50 BTC + amount_in_sats: Amount::from_int_btc(50), derivation_path: BIP86_DERIVATION_PATH, }; @@ -71,7 +71,7 @@ const UTXO_3: P2trUtxo = P2trUtxo { script_pubkey: UTXO_SCRIPT_PUBKEY, pubkey: UTXO_PUBKEY, master_fingerprint: UTXO_MASTER_FINGERPRINT, - amount_in_sats: Amount::from_sat(50 * 100_000_000), // 50 BTC + amount_in_sats: Amount::from_int_btc(50), derivation_path: BIP86_DERIVATION_PATH, }; diff --git a/bitcoin/src/amount.rs b/bitcoin/src/amount.rs index a8895d59..aa008b44 100644 --- a/bitcoin/src/amount.rs +++ b/bitcoin/src/amount.rs @@ -502,9 +502,9 @@ impl Amount { /// Exactly one satoshi. pub const ONE_SAT: Amount = Amount(1); /// Exactly one bitcoin. - pub const ONE_BTC: Amount = Amount(100_000_000); + pub const ONE_BTC: Amount = Self::from_int_btc(1); /// The maximum value allowed as an amount. Useful for sanity checking. - pub const MAX_MONEY: Amount = Amount(21_000_000 * 100_000_000); + pub const MAX_MONEY: Amount = Self::from_int_btc(21_000_000); /// The minimum value of an amount. pub const MIN: Amount = Amount::ZERO; /// The maximum value of an amount. @@ -529,6 +529,28 @@ impl Amount { Amount::from_float_in(btc, Denomination::Bitcoin) } + /// Convert from a value expressing integer values of bitcoins 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. + pub const fn from_int_btc(btc: u64) -> Amount { + // TODO replace whith unwrap() when available in const context. + match btc.checked_mul(100_000_000) { + Some(amount) => Amount::from_sat(amount), + None => { + // TODO replace with panic!() when MSRV = 1.57+ + #[allow(unconditional_panic)] + // disabling this lint until panic!() can be used. + #[allow(clippy::let_unit_value)] + let _int_overflow_converting_btc_to_sats = [(); 0][1]; + Amount(0) + } + } + } + /// Parse a decimal string as a value in the given denomination. /// /// Note: This only parses the value string. If you want to parse a value @@ -1589,6 +1611,16 @@ mod tests { } } + #[test] + fn from_int_btc() { + let amt = Amount::from_int_btc(2); + assert_eq!(Amount::from_sat(200_000_000), amt); + } + + #[should_panic] + #[test] + fn from_int_btc_panic() { Amount::from_int_btc(u64::MAX); } + #[test] fn mul_div() { let sat = Amount::from_sat;