@@ -23,7 +23,15 @@ impl fmt::Debug for Amount {
2323 }
2424}
2525
26+ const MAX_MSATS : u64 = 21_000_000_0000_0000_000 ;
27+
2628impl Amount {
29+ /// The maximum possible [`Amount`], equal to 21 million BTC
30+ pub const MAX : Amount = Amount ( MAX_MSATS ) ;
31+
32+ /// Zero milli-satoshis
33+ pub const ZERO : Amount = Amount ( 0 ) ;
34+
2735 /// The amount in milli-satoshis
2836 #[ inline]
2937 pub const fn milli_sats ( & self ) -> u64 {
@@ -48,19 +56,34 @@ impl Amount {
4856
4957 /// Constructs a new [`Amount`] for the given number of milli-satoshis.
5058 #[ inline]
51- pub const fn from_milli_sats ( msats : u64 ) -> Self {
52- Amount ( msats)
59+ pub const fn from_milli_sats ( msats : u64 ) -> Result < Self , ( ) > {
60+ if msats > MAX_MSATS {
61+ Err ( ( ) )
62+ } else {
63+ Ok ( Amount ( msats) )
64+ }
5365 }
5466
5567 /// Constructs a new [`Amount`] for the given number of satoshis.
5668 #[ inline]
57- pub const fn from_sats ( sats : u64 ) -> Self {
58- Amount ( sats * 1000 )
69+ pub const fn from_sats ( sats : u64 ) -> Result < Self , ( ) > {
70+ Self :: from_milli_sats ( sats. saturating_mul ( 1000 ) )
71+ }
72+
73+ /// Constructs a new [`Amount`] for the given number of satoshis, panicking if the amount is
74+ /// too large.
75+ pub ( crate ) const fn from_sats_panicy ( sats : u64 ) -> Self {
76+ let amt = sats. saturating_mul ( 1000 ) ;
77+ if amt > MAX_MSATS {
78+ panic ! ( "Sats value greater than 21 million Bitcoin" ) ;
79+ } else {
80+ Amount ( amt)
81+ }
5982 }
6083
6184 /// Adds an [`Amount`] to this [`Amount`], saturating to avoid overflowing 21 million bitcoin.
6285 #[ inline]
63- pub fn saturating_add ( self , rhs : Amount ) -> Amount {
86+ pub const fn saturating_add ( self , rhs : Amount ) -> Amount {
6487 match self . 0 . checked_add ( rhs. 0 ) {
6588 Some ( amt) if amt <= 21_000_000_0000_0000_000 => Amount ( amt) ,
6689 _ => Amount ( 21_000_000_0000_0000_000 ) ,
@@ -69,7 +92,7 @@ impl Amount {
6992
7093 /// Subtracts an [`Amount`] from this [`Amount`], saturating to avoid underflowing.
7194 #[ inline]
72- pub fn saturating_sub ( self , rhs : Amount ) -> Amount {
95+ pub const fn saturating_sub ( self , rhs : Amount ) -> Amount {
7396 Amount ( self . 0 . saturating_sub ( rhs. 0 ) )
7497 }
7598
@@ -120,15 +143,15 @@ mod test {
120143 #[ test]
121144 #[ rustfmt:: skip]
122145 fn test_display ( ) {
123- assert_eq ! ( Amount :: from_milli_sats( 0 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0" ) ;
124- assert_eq ! ( Amount :: from_milli_sats( 1 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00000001" ) ;
125- assert_eq ! ( Amount :: from_sats( 1 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00000001" ) ;
126- assert_eq ! ( Amount :: from_sats( 10 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.0000001" ) ;
127- assert_eq ! ( Amount :: from_sats( 15 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00000015" ) ;
128- assert_eq ! ( Amount :: from_sats( 1_0000 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.0001" ) ;
129- assert_eq ! ( Amount :: from_sats( 1_2345 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00012345" ) ;
130- assert_eq ! ( Amount :: from_sats( 1_2345_6789 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "1.23456789" ) ;
131- assert_eq ! ( Amount :: from_sats( 1_0000_0000 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "1" ) ;
132- assert_eq ! ( Amount :: from_sats( 5_0000_0000 ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "5" ) ;
146+ assert_eq ! ( Amount :: from_milli_sats( 0 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0" ) ;
147+ assert_eq ! ( Amount :: from_milli_sats( 1 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00000001" ) ;
148+ assert_eq ! ( Amount :: from_sats( 1 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00000001" ) ;
149+ assert_eq ! ( Amount :: from_sats( 10 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.0000001" ) ;
150+ assert_eq ! ( Amount :: from_sats( 15 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00000015" ) ;
151+ assert_eq ! ( Amount :: from_sats( 1_0000 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.0001" ) ;
152+ assert_eq ! ( Amount :: from_sats( 1_2345 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "0.00012345" ) ;
153+ assert_eq ! ( Amount :: from_sats( 1_2345_6789 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "1.23456789" ) ;
154+ assert_eq ! ( Amount :: from_sats( 1_0000_0000 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "1" ) ;
155+ assert_eq ! ( Amount :: from_sats( 5_0000_0000 ) . unwrap ( ) . btc_decimal_rounding_up_to_sats( ) . to_string( ) , "5" ) ;
133156 }
134157}
0 commit comments