blvm-consensus 0.1.21

Bitcoin Commons BLVM: Direct mathematical implementation of Bitcoin consensus rules from the Orange Paper
Documentation
use blvm_consensus::block::{connect_block, BlockValidationContext};
use blvm_consensus::segwit::Witness;
use blvm_consensus::{types::Network, Block, BlockHeader, Transaction, UtxoSet};
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn create_test_block() -> Block {
    Block {
        header: BlockHeader {
            version: 1,
            prev_block_hash: [0; 32],
            merkle_root: [0; 32],
            timestamp: 1234567890,
            bits: 0x1d00ffff,
            nonce: 0,
        },
        transactions: vec![Transaction {
            version: 1,
            inputs: vec![].into(),
            outputs: vec![].into(),
            lock_time: 0,
        }]
        .into(),
    }
}

fn benchmark_connect_block(c: &mut Criterion) {
    let block = create_test_block();
    let utxo_set = UtxoSet::default();
    let witnesses: Vec<Vec<Witness>> = block
        .transactions
        .iter()
        .map(|tx| vec![Vec::new(); tx.inputs.len()])
        .collect();

    let ctx = BlockValidationContext::for_network(Network::Mainnet);
    c.bench_function("connect_block", |b| {
        b.iter(|| {
            let _result = connect_block(
                black_box(&block),
                black_box(&witnesses),
                black_box(utxo_set.clone()),
                black_box(0),
                &ctx,
            );
            // Ignore errors for benchmarking (they're expected for invalid test data)
        })
    });
}

fn benchmark_connect_block_multi_tx(c: &mut Criterion) {
    let mut transactions = vec![Transaction {
        version: 1,
        inputs: vec![].into(),
        outputs: vec![].into(),
        lock_time: 0,
    }];

    // Add 10 regular transactions
    for _ in 0..10 {
        transactions.push(Transaction {
            version: 1,
            inputs: vec![].into(),
            outputs: vec![].into(),
            lock_time: 0,
        });
    }

    let block = Block {
        header: BlockHeader {
            version: 1,
            prev_block_hash: [0; 32],
            merkle_root: [0; 32],
            timestamp: 1234567890,
            bits: 0x1d00ffff,
            nonce: 0,
        },
        transactions: transactions.into(),
    };

    let utxo_set = UtxoSet::default();
    let witnesses: Vec<Vec<Witness>> = block
        .transactions
        .iter()
        .map(|tx| vec![Vec::new(); tx.inputs.len()])
        .collect();

    let ctx = BlockValidationContext::for_network(Network::Mainnet);
    c.bench_function("connect_block_multi_tx", |b| {
        b.iter(|| {
            let _result = connect_block(
                black_box(&block),
                black_box(&witnesses),
                black_box(utxo_set.clone()),
                black_box(0),
                &ctx,
            );
            // Ignore errors for benchmarking
        })
    });
}

criterion_group!(
    benches,
    benchmark_connect_block,
    benchmark_connect_block_multi_tx
);
criterion_main!(benches);