11use std:: io:: { self , ErrorKind } ;
22use std:: io:: { Read , Write } ;
33use std:: iter:: Sum ;
4- use std:: ops:: Add ;
4+ use std:: ops:: { Add , Deref , DerefMut } ;
55use std:: str:: FromStr ;
66
77use anyhow:: { anyhow, Context } ;
@@ -10,7 +10,7 @@ use bitcoin::address::NetworkUnchecked;
1010use bitcoin:: consensus:: serialize;
1111use bitcoin:: hashes:: { sha256d, Hash } ;
1212use bitcoin:: key:: TapTweak ;
13- use bitcoin:: { Address , AddressType , Block , Network , OutPoint , XOnlyPublicKey } ;
13+ use bitcoin:: { Address , AddressType , Amount , Block , Network , OutPoint , XOnlyPublicKey } ;
1414use borsh:: { BorshDeserialize , BorshSerialize } ;
1515use reth_primitives:: revm_primitives:: FixedBytes ;
1616use serde:: { Deserialize , Serialize } ;
@@ -292,75 +292,75 @@ impl BorshDeserialize for BitcoinAddress {
292292 }
293293}
294294
295- /// A wrapper for bitcoin amount in sats similar to the implementation in [`bitcoin::Amount`].
295+ /// A wrapper for [`bitcoin::Amount`].
296296///
297297/// NOTE: This wrapper has been created so that we can implement `Borsh*` traits on it.
298- #[ derive(
299- Debug ,
300- Clone ,
301- Copy ,
302- Serialize ,
303- Deserialize ,
304- Eq ,
305- PartialEq ,
306- BorshSerialize ,
307- BorshDeserialize ,
308- Arbitrary ,
309- ) ]
310- pub struct BitcoinAmount ( u64 ) ;
311-
312- impl BitcoinAmount {
313- // The zero amount.
314- pub const ZERO : BitcoinAmount = Self ( 0 ) ;
315- /// The maximum value allowed as an amount. Useful for sanity checking.
316- pub const MAX_MONEY : BitcoinAmount = Self :: from_int_btc ( 21_000_000 ) ;
317- /// The minimum value of an amount.
318- pub const MIN : BitcoinAmount = Self :: ZERO ;
319- /// The maximum value of an amount.
320- pub const MAX : BitcoinAmount = Self ( u64:: MAX ) ;
321- /// The number of bytes that an amount contributes to the size of a transaction.
322- pub const SIZE : usize = 8 ; // Serialized length of a u64.
323- // The number of sats in 1 bitcoin.
324- pub const SATS_FACTOR : u64 = 100_000_000 ;
325-
326- /// Get the number of sats in this [`BitcoinAmount`].
327- pub fn to_sat ( & self ) -> u64 {
328- self . 0
329- }
330-
331- /// Create a [`BitcoinAmount`] with sats precision and the given number of sats.
332- pub const fn from_sat ( value : u64 ) -> Self {
333- Self ( value)
334- }
335-
336- /// Convert from a value expressing integer values of bitcoins to a [`BitcoinAmount`]
337- /// in const context.
338- ///
339- /// ## Panics
340- ///
341- /// The function panics if the argument multiplied by the number of sats
342- /// per bitcoin overflows a u64 type.
343- pub const fn from_int_btc ( btc : u64 ) -> Self {
344- match btc. checked_mul ( Self :: SATS_FACTOR ) {
345- Some ( amount) => Self :: from_sat ( amount) ,
346- None => {
347- panic ! ( "number of sats greater than u64::MAX" ) ;
348- }
349- }
298+ #[ derive( Debug , Clone , Copy , Serialize , Deserialize , Eq , PartialEq ) ]
299+ pub struct BitcoinAmount ( Amount ) ;
300+
301+ impl From < Amount > for BitcoinAmount {
302+ fn from ( value : Amount ) -> Self {
303+ BitcoinAmount ( value)
304+ }
305+ }
306+
307+ impl Deref for BitcoinAmount {
308+ type Target = Amount ;
309+
310+ fn deref ( & self ) -> & Self :: Target {
311+ & self . 0
312+ }
313+ }
314+
315+ impl DerefMut for BitcoinAmount {
316+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
317+ & mut self . 0
318+ }
319+ }
320+
321+ impl BorshSerialize for BitcoinAmount {
322+ fn serialize < W : Write > ( & self , writer : & mut W ) -> io:: Result < ( ) > {
323+ let sats = self . 0 . to_sat ( ) ;
324+
325+ borsh:: BorshSerialize :: serialize ( & sats, writer)
326+ }
327+ }
328+
329+ impl BorshDeserialize for BitcoinAmount {
330+ fn deserialize ( buf : & mut & [ u8 ] ) -> io:: Result < Self > {
331+ let sats = borsh:: BorshDeserialize :: deserialize ( buf) ?;
332+
333+ Ok ( BitcoinAmount ( Amount :: from_sat ( sats) ) )
334+ }
335+
336+ fn deserialize_reader < R : Read > ( reader : & mut R ) -> io:: Result < Self > {
337+ let sats = borsh:: BorshDeserialize :: deserialize_reader ( reader) ?;
338+
339+ Ok ( BitcoinAmount ( Amount :: from_sat ( sats) ) )
340+ }
341+ }
342+
343+ impl < ' a > Arbitrary < ' a > for BitcoinAmount {
344+ fn arbitrary ( u : & mut Unstructured < ' a > ) -> arbitrary:: Result < Self > {
345+ // Generate a random u64 value and convert it to Amount
346+ let sats: u64 = u. arbitrary ( ) ?;
347+ Ok ( BitcoinAmount ( Amount :: from_sat ( sats) ) )
350348 }
351349}
352350
353351impl Add for BitcoinAmount {
354352 type Output = BitcoinAmount ;
355353
356354 fn add ( self , rhs : Self ) -> Self :: Output {
357- Self :: from_sat ( self . to_sat ( ) + rhs. to_sat ( ) )
355+ BitcoinAmount ( self . 0 + rhs. 0 )
358356 }
359357}
360358
361359impl Sum for BitcoinAmount {
362360 fn sum < I : Iterator < Item = Self > > ( iter : I ) -> Self {
363- Self :: from_sat ( iter. map ( |amt| amt. to_sat ( ) ) . sum ( ) )
361+ let total_amt = iter. fold ( Amount :: ZERO , |acc, amt| acc + amt. 0 ) ;
362+
363+ BitcoinAmount ( total_amt)
364364 }
365365}
366366
@@ -416,10 +416,7 @@ impl XOnlyPk {
416416
417417#[ cfg( test) ]
418418mod tests {
419- use super :: {
420- BitcoinAddress , BitcoinAmount , BorshDeserialize , BorshSerialize , OutPoint , OutputRef ,
421- XOnlyPk ,
422- } ;
419+ use super :: { BitcoinAddress , BorshDeserialize , BorshSerialize , OutPoint , OutputRef , XOnlyPk } ;
423420 use arbitrary:: { Arbitrary , Unstructured } ;
424421 use bitcoin:: {
425422 hashes:: Hash ,
@@ -558,14 +555,6 @@ mod tests {
558555 ) ;
559556 }
560557
561- #[ test]
562- #[ should_panic( expected = "number of sats greater than u64::MAX" ) ]
563- fn bitcoinamount_should_handle_sats_exceeding_u64_max ( ) {
564- let bitcoins: u64 = u64:: MAX / BitcoinAmount :: SATS_FACTOR + 1 ;
565-
566- BitcoinAmount :: from_int_btc ( bitcoins) ;
567- }
568-
569558 fn get_taproot_address (
570559 secp : & Secp256k1 < All > ,
571560 network : Network ,
0 commit comments