Merge rust-bitcoin/rust-bitcoin#1870: Add from_int_btc method to Amount

9f7449b572 Use from_int_btc function for const context (yancy)
f93e67977a Add from_int_btc function to Amount (yancy)

Pull request description:

  Followup PR from https://github.com/rust-bitcoin/rust-bitcoin/pull/1811

  Added a `const` associated function `from_int_btc()` for Amount.  `panic()` in const context is only available after 1.57+ so a work around is provided.

ACKs for top commit:
  tcharding:
    ACK 9f7449b572
  apoelstra:
    ACK 9f7449b572

Tree-SHA512: 7755234f2e573577d754f0224083cb7acc059e58833790fe344b0d9bad0acd89b0f74054d9efcba2133576222c7e9ab8dc3d81ddc10fbdcd4f83638d697118c4
This commit is contained in:
Andrew Poelstra 2023-06-13 22:48:21 +00:00
commit b1078febc2
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 37 additions and 5 deletions

View File

@ -49,7 +49,7 @@ const UTXO_1: P2trUtxo = P2trUtxo {
script_pubkey: UTXO_SCRIPT_PUBKEY, script_pubkey: UTXO_SCRIPT_PUBKEY,
pubkey: UTXO_PUBKEY, pubkey: UTXO_PUBKEY,
master_fingerprint: UTXO_MASTER_FINGERPRINT, 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, derivation_path: BIP86_DERIVATION_PATH,
}; };
@ -60,7 +60,7 @@ const UTXO_2: P2trUtxo = P2trUtxo {
script_pubkey: UTXO_SCRIPT_PUBKEY, script_pubkey: UTXO_SCRIPT_PUBKEY,
pubkey: UTXO_PUBKEY, pubkey: UTXO_PUBKEY,
master_fingerprint: UTXO_MASTER_FINGERPRINT, 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, derivation_path: BIP86_DERIVATION_PATH,
}; };
@ -71,7 +71,7 @@ const UTXO_3: P2trUtxo = P2trUtxo {
script_pubkey: UTXO_SCRIPT_PUBKEY, script_pubkey: UTXO_SCRIPT_PUBKEY,
pubkey: UTXO_PUBKEY, pubkey: UTXO_PUBKEY,
master_fingerprint: UTXO_MASTER_FINGERPRINT, 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, derivation_path: BIP86_DERIVATION_PATH,
}; };

View File

@ -502,9 +502,9 @@ impl Amount {
/// Exactly one satoshi. /// Exactly one satoshi.
pub const ONE_SAT: Amount = Amount(1); pub const ONE_SAT: Amount = Amount(1);
/// Exactly one bitcoin. /// 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. /// 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. /// The minimum value of an amount.
pub const MIN: Amount = Amount::ZERO; pub const MIN: Amount = Amount::ZERO;
/// The maximum value of an amount. /// The maximum value of an amount.
@ -529,6 +529,28 @@ impl Amount {
Amount::from_float_in(btc, Denomination::Bitcoin) 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. /// 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 /// 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] #[test]
fn mul_div() { fn mul_div() {
let sat = Amount::from_sat; let sat = Amount::from_sat;