diff --git a/Cargo.lock b/Cargo.lock index fff7d286..0625b8ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,9 +75,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "bencher" version = "0.1.0" dependencies = [ + "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "chain 0.1.0", "db 0.1.0", "ethcore-devtools 1.3.0", + "network 0.1.0", "primitives 0.1.0", "test-data 0.1.0", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/bencher/Cargo.toml b/bencher/Cargo.toml index 0aec1566..3c1521a3 100644 --- a/bencher/Cargo.toml +++ b/bencher/Cargo.toml @@ -8,11 +8,13 @@ description = "Parity bitcoin client." [dependencies] db = { path = "../db" } verification = { path = "../verification" } +network = { path = "../network" } chain = { path = "../chain" } primitives = { path = "../primitives" } ethcore-devtools = { path = "../devtools" } test-data = { path = "../test-data" } time = "*" +byteorder = "0.5" [[bin]] path = "src/main.rs" diff --git a/bencher/src/main.rs b/bencher/src/main.rs index e37f119e..bd177364 100644 --- a/bencher/src/main.rs +++ b/bencher/src/main.rs @@ -3,8 +3,12 @@ extern crate chain; extern crate ethcore_devtools as devtools; extern crate test_data; extern crate time; +extern crate verification; +extern crate network; +extern crate byteorder; mod database; +mod verifier; use time::{PreciseTime, Duration}; use std::io::Write; @@ -70,4 +74,5 @@ fn main() { benchmark!(database::write); benchmark!(database::reorg_short); benchmark!(database::write_heavy); + benchmark!(verifier::main); } diff --git a/bencher/src/verifier.rs b/bencher/src/verifier.rs new file mode 100644 index 00000000..5628ce02 --- /dev/null +++ b/bencher/src/verifier.rs @@ -0,0 +1,100 @@ +use std::sync::Arc; +use devtools::RandomTempPath; +use db::{Storage, BlockStapler, IndexedBlock}; +use verification::{BackwardsCompatibleChainVerifier as ChainVerifier, Verify}; +use network::Magic; +use test_data; +use byteorder::{LittleEndian, ByteOrder}; + +use super::Benchmark; + +// 1. write BLOCKS_INITIAL blocks with 1 transaction each +// 2. verify blocks that has transaction each with output each, +// spending outputs from last blocks +pub fn main(benchmark: &mut Benchmark) { + // params + const BLOCKS_INITIAL: usize = 200200; + const BLOCKS: usize = 10; + const TRANSACTIONS: usize = 2000; + const OUTPUTS: usize = 10; + + benchmark.samples(BLOCKS); + + assert!(BLOCKS_INITIAL - 100 > BLOCKS * OUTPUTS * TRANSACTIONS, + "There will be not enough initial blocks to continue this bench"); + + // test setup + let path = RandomTempPath::create_dir(); + + let genesis = test_data::genesis(); + + let mut rolling_hash = genesis.hash(); + let mut blocks: Vec = Vec::new(); + + for x in 0..BLOCKS_INITIAL { + let mut coinbase_nonce = [0u8;8]; + LittleEndian::write_u64(&mut coinbase_nonce[..], x as u64); + let next_block = test_data::block_builder() + .transaction() + .input() + .coinbase() + .signature_bytes(coinbase_nonce.to_vec().into()) + .build() + .output().value(5000000000).build() + .build() + .merkled_header() + .parent(rolling_hash.clone()) + .nonce(x as u32) + .build() + .build(); + rolling_hash = next_block.hash(); + blocks.push(next_block.into()); + } + + { + let store = Arc::new(Storage::new(path.as_path()).unwrap()); + store.insert_block(&genesis).unwrap(); + for block in blocks.iter() { store.insert_indexed_block(block).unwrap(); } + } + + let mut verification_blocks: Vec = Vec::new(); + for b in 0..BLOCKS { + let mut coinbase_nonce = [0u8;8]; + LittleEndian::write_u64(&mut coinbase_nonce[..], (b + BLOCKS_INITIAL) as u64); + let mut builder = test_data::block_builder() + .transaction() + .input().coinbase().signature_bytes(coinbase_nonce.to_vec().into()).build() + .output().value(5000000000).build() + .build(); + + for t in 0..TRANSACTIONS { + let mut tx_builder = builder.transaction(); + + for o in 0..OUTPUTS { + let parent_hash = blocks[(b*TRANSACTIONS*OUTPUTS + t * OUTPUTS + o)].transactions[0].hash.clone(); + + tx_builder = tx_builder + .input() + .hash(parent_hash) + .index(0) + .build() + } + + builder = tx_builder.output().value(5000000000000).build().build() + } + + verification_blocks.push(builder.merkled_header().parent(rolling_hash.clone()).build().build().into()); + } + + + let store = Arc::new(Storage::new(path.as_path()).unwrap()); + + let chain_verifier = ChainVerifier::new(store.clone(), Magic::Mainnet).pow_skip(); + + // bench + benchmark.start(); + for block in verification_blocks.iter() { + chain_verifier.verify(block).unwrap(); + } + benchmark.stop(); +} diff --git a/verification/src/chain_verifier.rs b/verification/src/chain_verifier.rs index 8501a9dc..eb1d8ea1 100644 --- a/verification/src/chain_verifier.rs +++ b/verification/src/chain_verifier.rs @@ -43,7 +43,6 @@ impl BackwardsCompatibleChainVerifier { } } - #[cfg(test)] pub fn pow_skip(mut self) -> Self { self.skip_pow = true; self