diff --git a/src/blockdata/block.rs b/src/blockdata/block.rs index ce10fdb1..7c259871 100644 --- a/src/blockdata/block.rs +++ b/src/blockdata/block.rs @@ -239,6 +239,21 @@ impl Block { base_size + txs_size } + /// Get the strippedsize of the block + pub fn get_strippedsize(&self) -> usize { + // The size of the header + the size of the varint with the tx count + the txs themselves + let base_size = 80 + VarInt(self.txdata.len() as u64).len(); + let txs_size: usize = self.txdata.iter().map(|tx| { + // size = non_witness_size + witness_size. + let size = tx.get_size(); + // weight = WITNESS_SCALE_FACTOR * non_witness_size + witness_size. + let weight = tx.get_weight(); + // weight - size = (WITNESS_SCALE_FACTOR - 1) * non_witness_size. + (weight - size) / (WITNESS_SCALE_FACTOR - 1) + }).sum(); + base_size + txs_size + } + /// Get the weight of the block pub fn get_weight(&self) -> usize { let base_weight = WITNESS_SCALE_FACTOR * (80 + VarInt(self.txdata.len() as u64).len()); @@ -369,6 +384,7 @@ mod tests { // [test] TODO: check the transaction data assert_eq!(real_decode.get_size(), some_block.len()); + assert_eq!(real_decode.get_strippedsize(), some_block.len()); assert_eq!(real_decode.get_weight(), some_block.len() * 4); // should be also ok for a non-witness block as commitment is optional in that case @@ -403,6 +419,7 @@ mod tests { // [test] TODO: check the transaction data assert_eq!(real_decode.get_size(), segwit_block.len()); + assert_eq!(real_decode.get_strippedsize(), 4283); assert_eq!(real_decode.get_weight(), 17168); assert!(real_decode.check_witness_commitment()); diff --git a/src/blockdata/transaction.rs b/src/blockdata/transaction.rs index f9bc4a21..8906daef 100644 --- a/src/blockdata/transaction.rs +++ b/src/blockdata/transaction.rs @@ -426,6 +426,13 @@ impl Transaction { self.get_scaled_size(1) } + /// Gets the "vsize" of this transaction. Will be `ceil(weight / 4.0)`. + #[inline] + pub fn get_vsize(&self) -> usize { + let weight = self.get_weight(); + (weight / WITNESS_SCALE_FACTOR) + if weight % WITNESS_SCALE_FACTOR == 0 { 0 } else { 1 } + } + /// Internal utility function for get_{size,weight} fn get_scaled_size(&self, scale_factor: usize) -> usize { let mut input_weight = 0; @@ -853,6 +860,7 @@ mod tests { "a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7".to_string()); assert_eq!(realtx.get_weight(), tx_bytes.len()*WITNESS_SCALE_FACTOR); assert_eq!(realtx.get_size(), tx_bytes.len()); + assert_eq!(realtx.get_vsize(), tx_bytes.len()); } #[test] @@ -885,6 +893,7 @@ mod tests { "80b7d8a82d5d5bf92905b06f2014dd699e03837ca172e3a59d51426ebbe3e7f5".to_string()); assert_eq!(realtx.get_weight(), 442); assert_eq!(realtx.get_size(), tx_bytes.len()); + assert_eq!(realtx.get_vsize(), 111); } #[test]