@@ -34,6 +34,7 @@ use crate::hash_types::{Sighash, Txid, Wtxid};
3434use crate :: VarInt ;
3535use crate :: internal_macros:: impl_consensus_encoding;
3636use crate :: parse:: impl_parse_str_through_int;
37+ use super :: Weight ;
3738
3839#[ cfg( doc) ]
3940use crate :: sighash:: { EcdsaSighashType , SchnorrSighashType } ;
@@ -839,8 +840,8 @@ impl Transaction {
839840 /// API. The unsigned transaction encoded within PSBT is always a non-segwit transaction
840841 /// and can therefore avoid this ambiguity.
841842 #[ inline]
842- pub fn weight ( & self ) -> usize {
843- self . scaled_size ( WITNESS_SCALE_FACTOR )
843+ pub fn weight ( & self ) -> Weight {
844+ Weight :: from_wu ( self . scaled_size ( WITNESS_SCALE_FACTOR ) as u64 )
844845 }
845846
846847 /// Returns the regular byte-wise consensus-serialized size of this transaction.
@@ -860,8 +861,8 @@ impl Transaction {
860861 /// [`policy`]: ../policy/mod.rs.html
861862 #[ inline]
862863 pub fn vsize ( & self ) -> usize {
863- let weight = self . weight ( ) ;
864- ( weight + WITNESS_SCALE_FACTOR - 1 ) / WITNESS_SCALE_FACTOR
864+ // No overflow because it's computed from data in memory
865+ self . weight ( ) . to_vbytes_ceil ( ) as usize
865866 }
866867
867868 /// Returns the size of this transaction excluding the witness data.
@@ -1259,7 +1260,7 @@ mod tests {
12591260 "a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7" . to_string( ) ) ;
12601261 assert_eq ! ( format!( "{:x}" , realtx. wtxid( ) ) ,
12611262 "a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7" . to_string( ) ) ;
1262- assert_eq ! ( realtx. weight( ) , tx_bytes. len( ) * WITNESS_SCALE_FACTOR ) ;
1263+ assert_eq ! ( realtx. weight( ) . to_wu ( ) as usize , tx_bytes. len( ) * WITNESS_SCALE_FACTOR ) ;
12631264 assert_eq ! ( realtx. size( ) , tx_bytes. len( ) ) ;
12641265 assert_eq ! ( realtx. vsize( ) , tx_bytes. len( ) ) ;
12651266 assert_eq ! ( realtx. strippedsize( ) , tx_bytes. len( ) ) ;
@@ -1293,7 +1294,7 @@ mod tests {
12931294 "f5864806e3565c34d1b41e716f72609d00b55ea5eac5b924c9719a842ef42206" . to_string( ) ) ;
12941295 assert_eq ! ( format!( "{:x}" , realtx. wtxid( ) ) ,
12951296 "80b7d8a82d5d5bf92905b06f2014dd699e03837ca172e3a59d51426ebbe3e7f5" . to_string( ) ) ;
1296- const EXPECTED_WEIGHT : usize = 442 ;
1297+ const EXPECTED_WEIGHT : Weight = Weight :: from_wu ( 442 ) ;
12971298 assert_eq ! ( realtx. weight( ) , EXPECTED_WEIGHT ) ;
12981299 assert_eq ! ( realtx. size( ) , tx_bytes. len( ) ) ;
12991300 assert_eq ! ( realtx. vsize( ) , 111 ) ;
@@ -1302,12 +1303,12 @@ mod tests {
13021303 // weight = WITNESS_SCALE_FACTOR * stripped_size + witness_size
13031304 // then,
13041305 // stripped_size = (weight - size) / (WITNESS_SCALE_FACTOR - 1)
1305- let expected_strippedsize = ( EXPECTED_WEIGHT - tx_bytes. len ( ) ) / ( WITNESS_SCALE_FACTOR - 1 ) ;
1306+ let expected_strippedsize = ( EXPECTED_WEIGHT . to_wu ( ) as usize - tx_bytes. len ( ) ) / ( WITNESS_SCALE_FACTOR - 1 ) ;
13061307 assert_eq ! ( realtx. strippedsize( ) , expected_strippedsize) ;
13071308 // Construct a transaction without the witness data.
13081309 let mut tx_without_witness = realtx;
13091310 tx_without_witness. input . iter_mut ( ) . for_each ( |input| input. witness . clear ( ) ) ;
1310- assert_eq ! ( tx_without_witness. weight( ) , expected_strippedsize* WITNESS_SCALE_FACTOR ) ;
1311+ assert_eq ! ( tx_without_witness. weight( ) . to_wu ( ) as usize , expected_strippedsize* WITNESS_SCALE_FACTOR ) ;
13111312 assert_eq ! ( tx_without_witness. size( ) , expected_strippedsize) ;
13121313 assert_eq ! ( tx_without_witness. vsize( ) , expected_strippedsize) ;
13131314 assert_eq ! ( tx_without_witness. strippedsize( ) , expected_strippedsize) ;
@@ -1412,7 +1413,7 @@ mod tests {
14121413
14131414 assert_eq ! ( format!( "{:x}" , tx. wtxid( ) ) , "d6ac4a5e61657c4c604dcde855a1db74ec6b3e54f32695d72c5e11c7761ea1b4" ) ;
14141415 assert_eq ! ( format!( "{:x}" , tx. txid( ) ) , "9652aa62b0e748caeec40c4cb7bc17c6792435cc3dfe447dd1ca24f912a1c6ec" ) ;
1415- assert_eq ! ( tx. weight( ) , 2718 ) ;
1416+ assert_eq ! ( tx. weight( ) , Weight :: from_wu ( 2718 ) ) ;
14161417
14171418 // non-segwit tx from my mempool
14181419 let tx_bytes = hex ! (
@@ -1444,7 +1445,7 @@ mod tests {
14441445 fn test_segwit_tx_decode ( ) {
14451446 let tx_bytes = hex ! ( "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3603da1b0e00045503bd5704c7dd8a0d0ced13bb5785010800000000000a636b706f6f6c122f4e696e6a61506f6f6c2f5345475749542fffffffff02b4e5a212000000001976a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac0000000000000000266a24aa21a9edf91c46b49eb8a29089980f02ee6b57e7d63d33b18b4fddac2bcd7db2a39837040120000000000000000000000000000000000000000000000000000000000000000000000000" ) ;
14461447 let tx: Transaction = deserialize ( & tx_bytes) . unwrap ( ) ;
1447- assert_eq ! ( tx. weight( ) , 780 ) ;
1448+ assert_eq ! ( tx. weight( ) , Weight :: from_wu ( 780 ) ) ;
14481449 serde_round_trip ! ( tx) ;
14491450
14501451 let consensus_encoded = serialize ( & tx) ;
@@ -1603,7 +1604,7 @@ mod tests {
16031604 ( false , "0100000001c336895d9fa674f8b1e294fd006b1ac8266939161600e04788c515089991b50a030000006a47304402204213769e823984b31dcb7104f2c99279e74249eacd4246dabcf2575f85b365aa02200c3ee89c84344ae326b637101a92448664a8d39a009c8ad5d147c752cbe112970121028b1b44b4903c9103c07d5a23e3c7cf7aeb0ba45ddbd2cfdce469ab197381f195fdffffff040000000000000000536a4c5058325bb7b7251cf9e36cac35d691bd37431eeea426d42cbdecca4db20794f9a4030e6cb5211fabf887642bcad98c9994430facb712da8ae5e12c9ae5ff314127d33665000bb26c0067000bb0bf00322a50c300000000000017a9145ca04fdc0a6d2f4e3f67cfeb97e438bb6287725f8750c30000000000001976a91423086a767de0143523e818d4273ddfe6d9e4bbcc88acc8465003000000001976a914c95cbacc416f757c65c942f9b6b8a20038b9b12988ac00000000" ) ,
16041605 ] ;
16051606
1606- let empty_transaction_size = Transaction {
1607+ let empty_transaction_weight = Transaction {
16071608 version : 0 ,
16081609 lock_time : absolute:: LockTime :: ZERO ,
16091610 input : vec ! [ ] ,
@@ -1620,12 +1621,12 @@ mod tests {
16201621 let tx: Transaction = deserialize ( Vec :: from_hex ( tx) . unwrap ( ) . as_slice ( ) ) . unwrap ( ) ;
16211622 // The empty tx size doesn't include the segwit marker (`0001`), so, in case of segwit txs,
16221623 // we have to manually add it ourselves
1623- let segwit_marker_size = if * is_segwit { 2 } else { 0 } ;
1624- let calculated_size = empty_transaction_size
1625- + segwit_marker_size
1624+ let segwit_marker_weight = if * is_segwit { 2 } else { 0 } ;
1625+ let calculated_size = empty_transaction_weight . to_wu ( ) as usize
1626+ + segwit_marker_weight
16261627 + tx. input . iter ( ) . fold ( 0 , |sum, i| sum + txin_weight ( i) )
16271628 + tx. output . iter ( ) . fold ( 0 , |sum, o| sum + o. weight ( ) ) ;
1628- assert_eq ! ( calculated_size, tx. weight( ) ) ;
1629+ assert_eq ! ( calculated_size, tx. weight( ) . to_wu ( ) as usize ) ;
16291630 }
16301631 }
16311632}
0 commit comments