Enhance pmt_tests execution time

pmt_tests with different tx counts were  executed in a single test, not taking advantage of the parallelism provided by unit tests.
A macro was added to define a unit test per transaction count.
This commit is contained in:
hrouis 2022-08-31 11:49:46 +02:00
parent 5e67419b14
commit f924e1451e
1 changed files with 77 additions and 64 deletions

View File

@ -532,22 +532,36 @@ mod tests {
use crate::util::merkleblock::{MerkleBlock, PartialMerkleTree}; use crate::util::merkleblock::{MerkleBlock, PartialMerkleTree};
use crate::Block; use crate::Block;
#[test] /// accepts `pmt_test_$num`
fn pmt_tests() { fn pmt_test_from_name(name: &str) {
let mut rng = thread_rng(); pmt_test(name[9..].parse().unwrap())
let tx_counts = vec![1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095]; }
for num_tx in tx_counts { macro_rules! pmt_tests {
($($name:ident),* $(,)?) => {
$(
#[test]
fn $name() {
pmt_test_from_name(stringify!($name));
}
)*
}
}
pmt_tests!(pmt_test_1, pmt_test_4, pmt_test_7, pmt_test_17, pmt_test_56, pmt_test_100,
pmt_test_127, pmt_test_256, pmt_test_312, pmt_test_513, pmt_test_1000, pmt_test_4095);
fn pmt_test(tx_count: usize) {
let mut rng = thread_rng();
// Create some fake tx ids // Create some fake tx ids
let txids = (1..num_tx + 1) // change to `1..=num_tx` when min Rust >= 1.26.0 let tx_ids = (1..=tx_count)
.map(|i| Txid::from_hex(&format!("{:064x}", i)).unwrap()) .map(|i| Txid::from_hex(&format!("{:064x}", i)).unwrap())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Calculate the merkle root and height // Calculate the merkle root and height
let hashes = txids.iter().map(|t| t.as_hash()); let hashes = tx_ids.iter().map(|t| t.as_hash());
let merkle_root_1: TxMerkleNode = bitcoin_merkle_root(hashes).expect("hashes is not empty").into(); let merkle_root_1: TxMerkleNode = bitcoin_merkle_root(hashes).expect("hashes is not empty").into();
let mut height = 1; let mut height = 1;
let mut ntx = num_tx; let mut ntx = tx_count;
while ntx > 1 { while ntx > 1 {
ntx = (ntx + 1) / 2; ntx = (ntx + 1) / 2;
height += 1; height += 1;
@ -555,9 +569,9 @@ mod tests {
// Check with random subsets with inclusion chances 1, 1/2, 1/4, ..., 1/128 // Check with random subsets with inclusion chances 1, 1/2, 1/4, ..., 1/128
for att in 1..15 { for att in 1..15 {
let mut matches = vec![false; num_tx]; let mut matches = vec![false; tx_count];
let mut match_txid1 = vec![]; let mut match_txid1 = vec![];
for j in 0..num_tx { for j in 0..tx_count {
// Generate `att / 2` random bits // Generate `att / 2` random bits
let rand_bits = match att / 2 { let rand_bits = match att / 2 {
0 => 0, 0 => 0,
@ -567,16 +581,16 @@ mod tests {
matches[j] = include; matches[j] = include;
if include { if include {
match_txid1.push(txids[j]); match_txid1.push(tx_ids[j]);
}; };
} }
// Build the partial merkle tree // Build the partial merkle tree
let pmt1 = PartialMerkleTree::from_txids(&txids, &matches); let pmt1 = PartialMerkleTree::from_txids(&tx_ids, &matches);
let serialized = serialize(&pmt1); let serialized = serialize(&pmt1);
// Verify PartialMerkleTree's size guarantees // Verify PartialMerkleTree's size guarantees
let n = min(num_tx, 1 + match_txid1.len() * height); let n = min(tx_count, 1 + match_txid1.len() * height);
assert!(serialized.len() <= 10 + (258 * n + 7) / 8); assert!(serialized.len() <= 10 + (258 * n + 7) / 8);
// Deserialize into a tester copy // Deserialize into a tester copy
@ -609,7 +623,6 @@ mod tests {
} }
} }
} }
}
#[test] #[test]
fn pmt_malleability() { fn pmt_malleability() {