Implement `Transaction.get_strippedsize()`.

`Block.get_strippedsize()` is also simplified and optimized.
This commit is contained in:
Vis Virial 2021-06-29 07:34:37 +09:00
parent 1bf9147a6e
commit c9dead410a
No known key found for this signature in database
GPG Key ID: 7CAA10504DE829B9
2 changed files with 37 additions and 9 deletions

View File

@ -245,14 +245,7 @@ impl Block {
/// Get the strippedsize of the block /// Get the strippedsize of the block
pub fn get_strippedsize(&self) -> usize { pub fn get_strippedsize(&self) -> usize {
let txs_size: usize = self.txdata.iter().map(|tx| { let txs_size: usize = self.txdata.iter().map(Transaction::get_strippedsize).sum();
// 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();
self.get_base_size() + txs_size self.get_base_size() + txs_size
} }

View File

@ -433,6 +433,33 @@ impl Transaction {
(weight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR (weight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR
} }
/// Gets the size of this transaction excluding the witness data.
#[inline]
pub fn get_strippedsize(&self) -> usize {
let mut input_size = 0;
for input in &self.input {
input_size += 32 + 4 + 4 + // outpoint (32+4) + nSequence
VarInt(input.script_sig.len() as u64).len() +
input.script_sig.len();
}
let mut output_size = 0;
for output in &self.output {
output_size += 8 + // value
VarInt(output.script_pubkey.len() as u64).len() +
output.script_pubkey.len();
}
let non_input_size =
// version:
4 +
// count varints:
VarInt(self.input.len() as u64).len() +
VarInt(self.output.len() as u64).len() +
output_size +
// lock_time
4;
non_input_size + input_size
}
/// 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;
@ -861,6 +888,7 @@ mod tests {
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()); assert_eq!(realtx.get_vsize(), tx_bytes.len());
assert_eq!(realtx.get_strippedsize(), tx_bytes.len());
} }
#[test] #[test]
@ -891,9 +919,16 @@ mod tests {
"f5864806e3565c34d1b41e716f72609d00b55ea5eac5b924c9719a842ef42206".to_string()); "f5864806e3565c34d1b41e716f72609d00b55ea5eac5b924c9719a842ef42206".to_string());
assert_eq!(format!("{:x}", realtx.wtxid()), assert_eq!(format!("{:x}", realtx.wtxid()),
"80b7d8a82d5d5bf92905b06f2014dd699e03837ca172e3a59d51426ebbe3e7f5".to_string()); "80b7d8a82d5d5bf92905b06f2014dd699e03837ca172e3a59d51426ebbe3e7f5".to_string());
assert_eq!(realtx.get_weight(), 442); const EXPECTED_WEIGHT: usize = 442;
assert_eq!(realtx.get_weight(), EXPECTED_WEIGHT);
assert_eq!(realtx.get_size(), tx_bytes.len()); assert_eq!(realtx.get_size(), tx_bytes.len());
assert_eq!(realtx.get_vsize(), 111); assert_eq!(realtx.get_vsize(), 111);
// Since
// size = stripped_size + witness_size
// weight = WITNESS_SCALE_FACTOR * stripped_size + witness_size
// then,
// stripped_size = (weight - size) / (WITNESS_SCALE_FACTOR - 1)
assert_eq!(realtx.get_strippedsize(), (EXPECTED_WEIGHT - tx_bytes.len()) / (WITNESS_SCALE_FACTOR - 1));
} }
#[test] #[test]