Implement `Block.get_strippedsize()` and `Transaction.get_vsize()`.

This commit is contained in:
Vis Virial 2021-06-28 20:03:42 +09:00
parent abff973e83
commit 4ac9cef9e9
No known key found for this signature in database
GPG Key ID: 7CAA10504DE829B9
2 changed files with 26 additions and 0 deletions

View File

@ -239,6 +239,21 @@ impl Block {
base_size + txs_size 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 /// Get the weight of the block
pub fn get_weight(&self) -> usize { pub fn get_weight(&self) -> usize {
let base_weight = WITNESS_SCALE_FACTOR * (80 + VarInt(self.txdata.len() as u64).len()); 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 // [test] TODO: check the transaction data
assert_eq!(real_decode.get_size(), some_block.len()); 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); 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 // 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 // [test] TODO: check the transaction data
assert_eq!(real_decode.get_size(), segwit_block.len()); assert_eq!(real_decode.get_size(), segwit_block.len());
assert_eq!(real_decode.get_strippedsize(), 4283);
assert_eq!(real_decode.get_weight(), 17168); assert_eq!(real_decode.get_weight(), 17168);
assert!(real_decode.check_witness_commitment()); assert!(real_decode.check_witness_commitment());

View File

@ -426,6 +426,13 @@ impl Transaction {
self.get_scaled_size(1) 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} /// Internal utility function for get_{size,weight}
fn get_scaled_size(&self, scale_factor: usize) -> usize { fn get_scaled_size(&self, scale_factor: usize) -> usize {
let mut input_weight = 0; let mut input_weight = 0;
@ -853,6 +860,7 @@ mod tests {
"a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7".to_string()); "a6eab3c14ab5272a58a5ba91505ba1a4b6d7a3a9fcbd187b6cd99a7b6d548cb7".to_string());
assert_eq!(realtx.get_weight(), tx_bytes.len()*WITNESS_SCALE_FACTOR); assert_eq!(realtx.get_weight(), tx_bytes.len()*WITNESS_SCALE_FACTOR);
assert_eq!(realtx.get_size(), tx_bytes.len()); assert_eq!(realtx.get_size(), tx_bytes.len());
assert_eq!(realtx.get_vsize(), tx_bytes.len());
} }
#[test] #[test]
@ -885,6 +893,7 @@ mod tests {
"80b7d8a82d5d5bf92905b06f2014dd699e03837ca172e3a59d51426ebbe3e7f5".to_string()); "80b7d8a82d5d5bf92905b06f2014dd699e03837ca172e3a59d51426ebbe3e7f5".to_string());
assert_eq!(realtx.get_weight(), 442); assert_eq!(realtx.get_weight(), 442);
assert_eq!(realtx.get_size(), tx_bytes.len()); assert_eq!(realtx.get_size(), tx_bytes.len());
assert_eq!(realtx.get_vsize(), 111);
} }
#[test] #[test]