Merge rust-bitcoin/rust-bitcoin#3839: Use `_unchecked` to construct amounts

a7c44cebf9 Use _unchecked to construct amounts (Tobin C. Harding)
09df951760 Use sat variable in tests (Tobin C. Harding)
4a5b2c60c6 Use ssat variable in tests (Tobin C. Harding)

Pull request description:

  We have a `_unchecked` constructor now for both `Amount` and `SignedAmount`. Soon we would like to start enforcing the `MAX_MONEY` invariant in both amount types. To make that change easier do a few refactorings:

  - Patch 1 and 2 introduce local variables for amount constructors.
  - Patch 3 replaces the local variables introduce in  (1) and (2) with macros
  - Patch 4 uses `_unchecked` constructor for hard coded integers

  The strange patch separation is done intentionally so we don't inadvertently reduce test coverage by using the wrong constructor. I made this mistake already in a previous PR, lesson learned.

  Note please, the macro introduced in patch 3 is in preparation for enforcing `MAX_MONEY`. The macros allow us to panic (`from_sat().unwrap()`) instead of using the `_unchecked` version.

ACKs for top commit:
  apoelstra:
    ACK a7c44cebf9975c4eeba56a65c0ea65be90e5c7f3; successfully ran local tests

Tree-SHA512: 55c2428ae231882542a4cfa724675341f7b493d158f4bec26277d3eefb04d9597cc29b05dce859661a96855fa6f4bac250d53c3dfa9f86a9611d43387ee18667
This commit is contained in:
merge-script 2025-01-08 04:08:39 +00:00
commit 515a66b854
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
11 changed files with 143 additions and 125 deletions

View File

@ -46,12 +46,12 @@ const BIP84_DERIVATION_PATH: &str = "m/84'/0'/0'";
const MASTER_FINGERPRINT: &str = "9680603f";
// The dummy UTXO amounts we are spending.
const DUMMY_UTXO_AMOUNT_INPUT_1: Amount = Amount::from_sat(20_000_000);
const DUMMY_UTXO_AMOUNT_INPUT_2: Amount = Amount::from_sat(10_000_000);
const DUMMY_UTXO_AMOUNT_INPUT_1: Amount = Amount::from_sat_unchecked(20_000_000);
const DUMMY_UTXO_AMOUNT_INPUT_2: Amount = Amount::from_sat_unchecked(10_000_000);
// The amounts we are sending to someone, and receiving back as change.
const SPEND_AMOUNT: Amount = Amount::from_sat(25_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat(4_990_000); // 10_000 sat fee.
const SPEND_AMOUNT: Amount = Amount::from_sat_unchecked(25_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat_unchecked(4_990_000); // 10_000 sat fee.
// Derive the external address xpriv.
fn get_external_address_xpriv<C: Signing>(

View File

@ -12,9 +12,9 @@ use bitcoin::{
Txid, WPubkeyHash, Witness,
};
const DUMMY_UTXO_AMOUNT: Amount = Amount::from_sat(20_000_000);
const SPEND_AMOUNT: Amount = Amount::from_sat(5_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat(14_999_000); // 1000 sat fee.
const DUMMY_UTXO_AMOUNT: Amount = Amount::from_sat_unchecked(20_000_000);
const SPEND_AMOUNT: Amount = Amount::from_sat_unchecked(5_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat_unchecked(14_999_000); // 1000 sat fee.
fn main() {
let secp = Secp256k1::new();

View File

@ -13,9 +13,9 @@ use bitcoin::{
Txid, Witness,
};
const DUMMY_UTXO_AMOUNT: Amount = Amount::from_sat(20_000_000);
const SPEND_AMOUNT: Amount = Amount::from_sat(5_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat(14_999_000); // 1000 sat fee.
const DUMMY_UTXO_AMOUNT: Amount = Amount::from_sat_unchecked(20_000_000);
const SPEND_AMOUNT: Amount = Amount::from_sat_unchecked(5_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat_unchecked(14_999_000); // 1000 sat fee.
fn main() {
let secp = Secp256k1::new();

View File

@ -45,12 +45,12 @@ const BIP86_DERIVATION_PATH: &str = "m/86'/0'/0'";
const MASTER_FINGERPRINT: &str = "9680603f";
// The dummy UTXO amounts we are spending.
const DUMMY_UTXO_AMOUNT_INPUT_1: Amount = Amount::from_sat(20_000_000);
const DUMMY_UTXO_AMOUNT_INPUT_2: Amount = Amount::from_sat(10_000_000);
const DUMMY_UTXO_AMOUNT_INPUT_1: Amount = Amount::from_sat_unchecked(20_000_000);
const DUMMY_UTXO_AMOUNT_INPUT_2: Amount = Amount::from_sat_unchecked(10_000_000);
// The amounts we are sending to someone, and receiving back as change.
const SPEND_AMOUNT: Amount = Amount::from_sat(25_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat(4_990_000); // 10_000 sat fee.
const SPEND_AMOUNT: Amount = Amount::from_sat_unchecked(25_000_000);
const CHANGE_AMOUNT: Amount = Amount::from_sat_unchecked(4_990_000); // 10_000 sat fee.
// Derive the external address xpriv.
fn get_external_address_xpriv<C: Signing>(

View File

@ -40,7 +40,7 @@ const UTXO_SCRIPT_PUBKEY: &str =
"5120be27fa8b1f5278faf82cab8da23e8761f8f9bd5d5ebebbb37e0e12a70d92dd16";
const UTXO_PUBKEY: &str = "a6ac32163539c16b6b5dbbca01b725b8e8acaa5f821ba42c80e7940062140d19";
const UTXO_MASTER_FINGERPRINT: &str = "e61b318f";
const ABSOLUTE_FEES_IN_SATS: Amount = Amount::from_sat(1_000);
const ABSOLUTE_FEES_IN_SATS: Amount = Amount::from_sat_unchecked(1_000);
// UTXO_1 will be used for spending example 1
const UTXO_1: P2trUtxo = P2trUtxo {

View File

@ -112,7 +112,7 @@ fn bitcoin_genesis_tx(params: &Params) -> Transaction {
witness: Witness::default(),
});
ret.output.push(TxOut { value: Amount::from_sat(50 * 100_000_000), script_pubkey: out_script });
ret.output.push(TxOut { value: Amount::from_sat_unchecked(50 * 100_000_000), script_pubkey: out_script });
// end
ret

View File

@ -676,7 +676,7 @@ fn bitcoinconsensus() {
let spent_bytes = hex!("0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d");
let spent = Script::from_bytes(&spent_bytes);
let spending = hex!("010000000001011f97548fbbe7a0db7588a66e18d803d0089315aa7d4cc28360b6ec50ef36718a0100000000ffffffff02df1776000000000017a9146c002a686959067f4866b8fb493ad7970290ab728757d29f0000000000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d04004730440220565d170eed95ff95027a69b313758450ba84a01224e1f7f130dda46e94d13f8602207bdd20e307f062594022f12ed5017bbf4a055a06aea91c10110a0e3bb23117fc014730440220647d2dc5b15f60bc37dc42618a370b2a1490293f9e5c8464f53ec4fe1dfe067302203598773895b4b16d37485cbe21b337f4e4b650739880098c592553add7dd4355016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000");
spent.verify(0, crate::Amount::from_sat(18393430), &spending).unwrap();
spent.verify(0, crate::Amount::from_sat_unchecked(18393430), &spending).unwrap();
}
#[test]
@ -685,10 +685,10 @@ fn default_dust_value() {
// well-known scriptPubKey types.
let script_p2wpkh = Builder::new().push_int_unchecked(0).push_slice([42; 20]).into_script();
assert!(script_p2wpkh.is_p2wpkh());
assert_eq!(script_p2wpkh.minimal_non_dust(), crate::Amount::from_sat(294));
assert_eq!(script_p2wpkh.minimal_non_dust(), crate::Amount::from_sat_unchecked(294));
assert_eq!(
script_p2wpkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_unchecked(6)),
crate::Amount::from_sat(588)
crate::Amount::from_sat_unchecked(588)
);
let script_p2pkh = Builder::new()
@ -699,10 +699,10 @@ fn default_dust_value() {
.push_opcode(OP_CHECKSIG)
.into_script();
assert!(script_p2pkh.is_p2pkh());
assert_eq!(script_p2pkh.minimal_non_dust(), crate::Amount::from_sat(546));
assert_eq!(script_p2pkh.minimal_non_dust(), crate::Amount::from_sat_unchecked(546));
assert_eq!(
script_p2pkh.minimal_non_dust_custom(FeeRate::from_sat_per_vb_unchecked(6)),
crate::Amount::from_sat(1092)
crate::Amount::from_sat_unchecked(1092)
);
}

View File

@ -2075,7 +2075,7 @@ mod tests {
).unwrap();
let spk = ScriptBuf::from_hex("00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1").unwrap();
let value = Amount::from_sat(600_000_000);
let value = Amount::from_sat_unchecked(600_000_000);
let mut cache = SighashCache::new(&tx);
assert_eq!(
@ -2116,7 +2116,7 @@ mod tests {
let redeem_script =
ScriptBuf::from_hex("001479091972186c449eb1ded22b78e40d009bdf0089").unwrap();
let value = Amount::from_sat(1_000_000_000);
let value = Amount::from_sat_unchecked(1_000_000_000);
let mut cache = SighashCache::new(&tx);
assert_eq!(
@ -2166,7 +2166,7 @@ mod tests {
)
.unwrap();
let value = Amount::from_sat(987_654_321);
let value = Amount::from_sat_unchecked(987_654_321);
(tx, witness_script, value)
}

View File

@ -1425,14 +1425,14 @@ mod tests {
}],
output: vec![
TxOut {
value: Amount::from_sat(99_999_699),
value: Amount::from_sat_unchecked(99_999_699),
script_pubkey: ScriptBuf::from_hex(
"76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac",
)
.unwrap(),
},
TxOut {
value: Amount::from_sat(100_000_000),
value: Amount::from_sat_unchecked(100_000_000),
script_pubkey: ScriptBuf::from_hex(
"a9143545e6e33b832c47050f24d3eeb93c9c03948bc787",
)
@ -1498,7 +1498,7 @@ mod tests {
)]),
}],
output: vec![TxOut {
value: Amount::from_sat(190_303_501_938),
value: Amount::from_sat_unchecked(190_303_501_938),
script_pubkey: ScriptBuf::from_hex(
"a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587",
)
@ -1549,7 +1549,7 @@ mod tests {
Input {
non_witness_utxo: Some(tx),
witness_utxo: Some(TxOut {
value: Amount::from_sat(190_303_501_938),
value: Amount::from_sat_unchecked(190_303_501_938),
script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(),
}),
sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::<PsbtSighashType>().unwrap()),
@ -1674,11 +1674,11 @@ mod tests {
],
output: vec![
TxOut {
value: Amount::from_sat(99_999_699),
value: Amount::from_sat_unchecked(99_999_699),
script_pubkey: ScriptBuf::from_hex("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac").unwrap(),
},
TxOut {
value: Amount::from_sat(100_000_000),
value: Amount::from_sat_unchecked(100_000_000),
script_pubkey: ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap(),
},
],
@ -1721,11 +1721,11 @@ mod tests {
],
output: vec![
TxOut {
value: Amount::from_sat(200_000_000),
value: Amount::from_sat_unchecked(200_000_000),
script_pubkey: ScriptBuf::from_hex("76a91485cff1097fd9e008bb34af709c62197b38978a4888ac").unwrap(),
},
TxOut {
value: Amount::from_sat(190_303_501_938),
value: Amount::from_sat_unchecked(190_303_501_938),
script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(),
},
],
@ -2007,11 +2007,11 @@ mod tests {
],
output: vec![
TxOut {
value: Amount::from_sat(99_999_699),
value: Amount::from_sat_unchecked(99_999_699),
script_pubkey: ScriptBuf::from_hex("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac").unwrap(),
},
TxOut {
value: Amount::from_sat(100_000_000),
value: Amount::from_sat_unchecked(100_000_000),
script_pubkey: ScriptBuf::from_hex("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787").unwrap(),
},
],
@ -2054,11 +2054,11 @@ mod tests {
],
output: vec![
TxOut {
value: Amount::from_sat(200_000_000),
value: Amount::from_sat_unchecked(200_000_000),
script_pubkey: ScriptBuf::from_hex("76a91485cff1097fd9e008bb34af709c62197b38978a4888ac").unwrap(),
},
TxOut {
value: Amount::from_sat(190_303_501_938),
value: Amount::from_sat_unchecked(190_303_501_938),
script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(),
},
],
@ -2167,9 +2167,9 @@ mod tests {
#[test]
fn fee() {
let output_0_val = Amount::from_sat(99_999_699);
let output_1_val = Amount::from_sat(100_000_000);
let prev_output_val = Amount::from_sat(200_000_000);
let output_0_val = Amount::from_sat_unchecked(99_999_699);
let output_1_val = Amount::from_sat_unchecked(100_000_000);
let prev_output_val = Amount::from_sat_unchecked(200_000_000);
let t = Psbt {
unsigned_tx: Transaction {
@ -2230,7 +2230,7 @@ mod tests {
script_pubkey: ScriptBuf::new()
},
TxOut {
value: Amount::from_sat(190_303_501_938),
value: Amount::from_sat_unchecked(190_303_501_938),
script_pubkey: ScriptBuf::new()
},
],
@ -2292,7 +2292,7 @@ mod tests {
// First input we can spend. See comment above on key_map for why we use defaults here.
let txout_wpkh = TxOut {
value: Amount::from_sat(10),
value: Amount::from_sat_unchecked(10),
script_pubkey: ScriptBuf::new_p2wpkh(pk.wpubkey_hash().unwrap()),
};
psbt.inputs[0].witness_utxo = Some(txout_wpkh);
@ -2304,7 +2304,7 @@ mod tests {
// Second input is unspendable by us e.g., from another wallet that supports future upgrades.
let unknown_prog = WitnessProgram::new(WitnessVersion::V4, &[0xaa; 34]).unwrap();
let txout_unknown_future = TxOut {
value: Amount::from_sat(10),
value: Amount::from_sat_unchecked(10),
script_pubkey: ScriptBuf::new_witness_program(&unknown_prog),
};
psbt.inputs[1].witness_utxo = Some(txout_unknown_future);

View File

@ -238,7 +238,7 @@ fn serde_regression_psbt() {
.unwrap()]),
}],
output: vec![TxOut {
value: Amount::from_sat(190_303_501_938),
value: Amount::from_sat_unchecked(190_303_501_938),
script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587")
.unwrap(),
}],
@ -285,7 +285,7 @@ fn serde_regression_psbt() {
inputs: vec![Input {
non_witness_utxo: Some(tx),
witness_utxo: Some(TxOut {
value: Amount::from_sat(190_303_501_938),
value: Amount::from_sat_unchecked(190_303_501_938),
script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(),
}),
sighash_type: Some(PsbtSighashType::from("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::<EcdsaSighashType>().unwrap())),

View File

@ -759,8 +759,8 @@ fn serde_as_btc() {
}
let orig = T {
amt: Amount::from_sat(20_000_000__000_000_01),
samt: SignedAmount::from_sat(-20_000_000__000_000_01),
amt: Amount::from_sat_unchecked(20_000_000__000_000_01),
samt: SignedAmount::from_sat_unchecked(-20_000_000__000_000_01),
};
let json = "{\"amt\": 20000000.00000001, \
@ -795,7 +795,7 @@ fn serde_as_str() {
}
serde_test::assert_tokens(
&T { amt: Amount::from_sat(123_456_789), samt: SignedAmount::from_sat(-123_456_789) },
&T { amt: Amount::from_sat_unchecked(123_456_789), samt: SignedAmount::from_sat_unchecked(-123_456_789) },
&[
serde_test::Token::Struct { name: "T", len: 2 },
serde_test::Token::String("amt"),
@ -823,8 +823,8 @@ fn serde_as_btc_opt() {
}
let with = T {
amt: Some(Amount::from_sat(2_500_000_00)),
samt: Some(SignedAmount::from_sat(-2_500_000_00)),
amt: Some(Amount::from_sat_unchecked(2_500_000_00)),
samt: Some(SignedAmount::from_sat_unchecked(-2_500_000_00)),
};
let without = T { amt: None, samt: None };
@ -865,8 +865,8 @@ fn serde_as_sat_opt() {
}
let with = T {
amt: Some(Amount::from_sat(2_500_000_00)),
samt: Some(SignedAmount::from_sat(-2_500_000_00)),
amt: Some(Amount::from_sat_unchecked(2_500_000_00)),
samt: Some(SignedAmount::from_sat_unchecked(-2_500_000_00)),
};
let without = T { amt: None, samt: None };
@ -907,8 +907,8 @@ fn serde_as_str_opt() {
}
let with = T {
amt: Some(Amount::from_sat(123_456_789)),
samt: Some(SignedAmount::from_sat(-123_456_789)),
amt: Some(Amount::from_sat_unchecked(123_456_789)),
samt: Some(SignedAmount::from_sat_unchecked(-123_456_789)),
};
let without = T { amt: None, samt: None };
@ -936,48 +936,48 @@ fn serde_as_str_opt() {
#[test]
fn sum_amounts() {
let sat = Amount::from_sat;
let ssat = SignedAmount::from_sat;
assert_eq!(Amount::ZERO, [].iter().sum::<Amount>());
assert_eq!(SignedAmount::ZERO, [].iter().sum::<SignedAmount>());
let amounts = [Amount::from_sat(42), Amount::from_sat(1337), Amount::from_sat(21)];
assert_eq!(amounts.iter().sum::<Amount>(), Amount::from_sat(1400));
let amounts = [sat(42), sat(1337), sat(21)];
let sum = amounts.into_iter().sum::<Amount>();
assert_eq!(Amount::from_sat(1400), sum);
let amounts =
[SignedAmount::from_sat(-42), SignedAmount::from_sat(1337), SignedAmount::from_sat(21)];
assert_eq!(amounts.iter().sum::<SignedAmount>(), SignedAmount::from_sat(1316));
assert_eq!(sat(1400), sum);
let amounts = [ssat(-42), ssat(1337), ssat(21)];
let sum = amounts.into_iter().sum::<SignedAmount>();
assert_eq!(SignedAmount::from_sat(1316), sum);
assert_eq!(ssat(1316), sum);
}
#[test]
fn checked_sum_amounts() {
let sat = Amount::from_sat;
let ssat = SignedAmount::from_sat;
assert_eq!(Some(Amount::ZERO), [].into_iter().checked_sum());
assert_eq!(Some(SignedAmount::ZERO), [].into_iter().checked_sum());
let amounts = [Amount::from_sat(42), Amount::from_sat(1337), Amount::from_sat(21)];
let amounts = [sat(42), sat(1337), sat(21)];
let sum = amounts.into_iter().checked_sum();
assert_eq!(Some(Amount::from_sat(1400)), sum);
assert_eq!(Some(sat(1400)), sum);
let amounts = [Amount::from_sat(u64::MAX), Amount::from_sat(1337), Amount::from_sat(21)];
let amounts = [sat(u64::MAX), sat(1337), sat(21)];
let sum = amounts.into_iter().checked_sum();
assert_eq!(None, sum);
let amounts = [SignedAmount::MIN, SignedAmount::from_sat(-1), SignedAmount::from_sat(21)];
let amounts = [SignedAmount::MIN, ssat(-1), ssat(21)];
let sum = amounts.into_iter().checked_sum();
assert_eq!(None, sum);
let amounts = [SignedAmount::MAX, SignedAmount::from_sat(1), SignedAmount::from_sat(21)];
let amounts = [SignedAmount::MAX, ssat(1), ssat(21)];
let sum = amounts.into_iter().checked_sum();
assert_eq!(None, sum);
let amounts =
[SignedAmount::from_sat(42), SignedAmount::from_sat(3301), SignedAmount::from_sat(21)];
let amounts = [ssat(42), ssat(3301), ssat(21)];
let sum = amounts.into_iter().checked_sum();
assert_eq!(Some(SignedAmount::from_sat(3364)), sum);
assert_eq!(Some(ssat(3364)), sum);
}
#[test]
@ -1020,35 +1020,39 @@ fn disallow_unknown_denomination() {
#[test]
#[cfg(feature = "alloc")]
fn trailing_zeros_for_amount() {
assert_eq!(format!("{}", Amount::from_sat(1_000_000)), "0.01 BTC");
let sat = Amount::from_sat;
assert_eq!(format!("{}", sat(1_000_000)), "0.01 BTC");
assert_eq!(format!("{}", Amount::ONE_SAT), "0.00000001 BTC");
assert_eq!(format!("{}", Amount::ONE_BTC), "1 BTC");
assert_eq!(format!("{}", Amount::from_sat(1)), "0.00000001 BTC");
assert_eq!(format!("{}", Amount::from_sat(10)), "0.0000001 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(10)), "0.00 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(100)), "0.00 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(1000)), "0.00 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(10_000)), "0.00 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(100_000)), "0.00 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(1_000_000)), "0.01 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(10_000_000)), "0.10 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(100_000_000)), "1.00 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(500_000)), "0.01 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(9_500_000)), "0.10 BTC");
assert_eq!(format!("{:.2}", Amount::from_sat(99_500_000)), "1.00 BTC");
assert_eq!(format!("{}", Amount::from_sat(100_000_000)), "1 BTC");
assert_eq!(format!("{}", Amount::from_sat(40_000_000_000)), "400 BTC");
assert_eq!(format!("{:.10}", Amount::from_sat(100_000_000)), "1.0000000000 BTC");
assert_eq!(format!("{}", Amount::from_sat(400_000_000_000_010)), "4000000.0000001 BTC");
assert_eq!(format!("{}", Amount::from_sat(400_000_000_000_000)), "4000000 BTC");
assert_eq!(format!("{}", sat(1)), "0.00000001 BTC");
assert_eq!(format!("{}", sat(10)), "0.0000001 BTC");
assert_eq!(format!("{:.2}", sat(10)), "0.00 BTC");
assert_eq!(format!("{:.2}", sat(100)), "0.00 BTC");
assert_eq!(format!("{:.2}", sat(1000)), "0.00 BTC");
assert_eq!(format!("{:.2}", sat(10_000)), "0.00 BTC");
assert_eq!(format!("{:.2}", sat(100_000)), "0.00 BTC");
assert_eq!(format!("{:.2}", sat(1_000_000)), "0.01 BTC");
assert_eq!(format!("{:.2}", sat(10_000_000)), "0.10 BTC");
assert_eq!(format!("{:.2}", sat(100_000_000)), "1.00 BTC");
assert_eq!(format!("{:.2}", sat(500_000)), "0.01 BTC");
assert_eq!(format!("{:.2}", sat(9_500_000)), "0.10 BTC");
assert_eq!(format!("{:.2}", sat(99_500_000)), "1.00 BTC");
assert_eq!(format!("{}", sat(100_000_000)), "1 BTC");
assert_eq!(format!("{}", sat(40_000_000_000)), "400 BTC");
assert_eq!(format!("{:.10}", sat(100_000_000)), "1.0000000000 BTC");
assert_eq!(format!("{}", sat(400_000_000_000_010)), "4000000.0000001 BTC");
assert_eq!(format!("{}", sat(400_000_000_000_000)), "4000000 BTC");
}
#[test]
#[allow(clippy::op_ref)]
fn unsigned_addition() {
let one = Amount::from_sat(1);
let two = Amount::from_sat(2);
let three = Amount::from_sat(3);
let sat = Amount::from_sat;
let one = sat(1);
let two = sat(2);
let three = sat(3);
assert!(one + two == three);
assert!(&one + two == three);
@ -1059,9 +1063,11 @@ fn unsigned_addition() {
#[test]
#[allow(clippy::op_ref)]
fn unsigned_subtract() {
let one = Amount::from_sat(1);
let two = Amount::from_sat(2);
let three = Amount::from_sat(3);
let sat = Amount::from_sat;
let one = sat(1);
let two = sat(2);
let three = sat(3);
assert!(three - two == one);
assert!(&three - two == one);
@ -1071,32 +1077,38 @@ fn unsigned_subtract() {
#[test]
fn unsigned_add_assign() {
let mut f = Amount::from_sat(1);
f += Amount::from_sat(2);
assert_eq!(f, Amount::from_sat(3));
let sat = Amount::from_sat;
let mut f = Amount::from_sat(1);
f += &Amount::from_sat(2);
assert_eq!(f, Amount::from_sat(3));
let mut f = sat(1);
f += sat(2);
assert_eq!(f, sat(3));
let mut f = sat(1);
f += &sat(2);
assert_eq!(f, sat(3));
}
#[test]
fn unsigned_sub_assign() {
let mut f = Amount::from_sat(3);
f -= Amount::from_sat(2);
assert_eq!(f, Amount::from_sat(1));
let sat = Amount::from_sat;
let mut f = Amount::from_sat(3);
f -= &Amount::from_sat(2);
assert_eq!(f, Amount::from_sat(1));
let mut f = sat(3);
f -= sat(2);
assert_eq!(f, sat(1));
let mut f = sat(3);
f -= &sat(2);
assert_eq!(f, sat(1));
}
#[test]
#[allow(clippy::op_ref)]
fn signed_addition() {
let one = SignedAmount::from_sat(1);
let two = SignedAmount::from_sat(2);
let three = SignedAmount::from_sat(3);
let ssat = SignedAmount::from_sat;
let one = ssat(1);
let two = ssat(2);
let three = ssat(3);
assert!(one + two == three);
assert!(&one + two == three);
@ -1107,9 +1119,11 @@ fn signed_addition() {
#[test]
#[allow(clippy::op_ref)]
fn signed_subtract() {
let one = SignedAmount::from_sat(1);
let two = SignedAmount::from_sat(2);
let three = SignedAmount::from_sat(3);
let ssat = SignedAmount::from_sat;
let one = ssat(1);
let two = ssat(2);
let three = ssat(3);
assert!(three - two == one);
assert!(&three - two == one);
@ -1119,22 +1133,26 @@ fn signed_subtract() {
#[test]
fn signed_add_assign() {
let mut f = SignedAmount::from_sat(1);
f += SignedAmount::from_sat(2);
assert_eq!(f, SignedAmount::from_sat(3));
let ssat = SignedAmount::from_sat;
let mut f = SignedAmount::from_sat(1);
f += &SignedAmount::from_sat(2);
assert_eq!(f, SignedAmount::from_sat(3));
let mut f = ssat(1);
f += ssat(2);
assert_eq!(f, ssat(3));
let mut f = ssat(1);
f += &ssat(2);
assert_eq!(f, ssat(3));
}
#[test]
fn signed_sub_assign() {
let mut f = SignedAmount::from_sat(3);
f -= SignedAmount::from_sat(2);
assert_eq!(f, SignedAmount::from_sat(1));
let ssat = SignedAmount::from_sat;
let mut f = SignedAmount::from_sat(3);
f -= &SignedAmount::from_sat(2);
assert_eq!(f, SignedAmount::from_sat(1));
let mut f = ssat(3);
f -= ssat(2);
assert_eq!(f, ssat(1));
let mut f = ssat(3);
f -= &ssat(2);
assert_eq!(f, ssat(1));
}