Merge pull request #327 from ethcore/verification-bench
Verification benchmark
This commit is contained in:
commit
a0193c024d
|
@ -75,9 +75,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
name = "bencher"
|
name = "bencher"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chain 0.1.0",
|
"chain 0.1.0",
|
||||||
"db 0.1.0",
|
"db 0.1.0",
|
||||||
"ethcore-devtools 1.3.0",
|
"ethcore-devtools 1.3.0",
|
||||||
|
"network 0.1.0",
|
||||||
"primitives 0.1.0",
|
"primitives 0.1.0",
|
||||||
"test-data 0.1.0",
|
"test-data 0.1.0",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -8,11 +8,13 @@ description = "Parity bitcoin client."
|
||||||
[dependencies]
|
[dependencies]
|
||||||
db = { path = "../db" }
|
db = { path = "../db" }
|
||||||
verification = { path = "../verification" }
|
verification = { path = "../verification" }
|
||||||
|
network = { path = "../network" }
|
||||||
chain = { path = "../chain" }
|
chain = { path = "../chain" }
|
||||||
primitives = { path = "../primitives" }
|
primitives = { path = "../primitives" }
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
test-data = { path = "../test-data" }
|
test-data = { path = "../test-data" }
|
||||||
time = "*"
|
time = "*"
|
||||||
|
byteorder = "0.5"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
|
@ -3,8 +3,12 @@ extern crate chain;
|
||||||
extern crate ethcore_devtools as devtools;
|
extern crate ethcore_devtools as devtools;
|
||||||
extern crate test_data;
|
extern crate test_data;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
extern crate verification;
|
||||||
|
extern crate network;
|
||||||
|
extern crate byteorder;
|
||||||
|
|
||||||
mod database;
|
mod database;
|
||||||
|
mod verifier;
|
||||||
|
|
||||||
use time::{PreciseTime, Duration};
|
use time::{PreciseTime, Duration};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -70,4 +74,5 @@ fn main() {
|
||||||
benchmark!(database::write);
|
benchmark!(database::write);
|
||||||
benchmark!(database::reorg_short);
|
benchmark!(database::reorg_short);
|
||||||
benchmark!(database::write_heavy);
|
benchmark!(database::write_heavy);
|
||||||
|
benchmark!(verifier::main);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> blocks that has <TRANSACTIONS> transaction each with <OUTPUTS> output each,
|
||||||
|
// spending outputs from last <BLOCKS*TRANSACTIONS*OUTPUTS> 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<IndexedBlock> = 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<IndexedBlock> = 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();
|
||||||
|
}
|
|
@ -43,7 +43,6 @@ impl BackwardsCompatibleChainVerifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub fn pow_skip(mut self) -> Self {
|
pub fn pow_skip(mut self) -> Self {
|
||||||
self.skip_pow = true;
|
self.skip_pow = true;
|
||||||
self
|
self
|
||||||
|
|
Loading…
Reference in New Issue