pub fn var_uint_size(val: usize) -> usize {
if val <= 0xfc {
1
} else if val <= 0xffff {
3
} else if val <= 0xffff_ffff {
5
} else {
9
}
}
pub fn transaction_input_size(script_size: usize) -> usize {
32 + 4 + var_uint_size(script_size) + script_size + 4
}
pub fn transaction_output_size(script_size: usize) -> usize {
var_uint_size(script_size) + script_size + 8
}
pub fn transaction_size(input_script_lengths: &[usize], output_script_lengths: &[usize]) -> usize {
4 + var_uint_size(input_script_lengths.len())
+ input_script_lengths
.iter()
.map(|&s| transaction_input_size(s))
.sum::<usize>()
+ var_uint_size(output_script_lengths.len())
+ output_script_lengths
.iter()
.map(|&s| transaction_output_size(s))
.sum::<usize>()
+ 4
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_var_uint_size_small() {
assert_eq!(var_uint_size(0), 1);
assert_eq!(var_uint_size(0xfc), 1);
}
#[test]
fn test_var_uint_size_medium() {
assert_eq!(var_uint_size(0xfd), 3);
assert_eq!(var_uint_size(0xffff), 3);
}
#[test]
fn test_var_uint_size_large() {
assert_eq!(var_uint_size(0x10000), 5);
assert_eq!(var_uint_size(0xffff_ffff), 5);
}
#[test]
fn test_transaction_input_size_p2pkh() {
assert_eq!(transaction_input_size(108), 149);
}
#[test]
fn test_transaction_output_size_p2pkh() {
assert_eq!(transaction_output_size(25), 34);
}
#[test]
fn test_transaction_size_single_p2pkh() {
let size = transaction_size(&[108], &[25]);
assert_eq!(size, 193);
}
#[test]
fn test_transaction_size_multiple_io() {
let size = transaction_size(&[108, 108], &[25, 25]);
assert_eq!(size, 376);
}
}