Skip to content
This repository has been archived by the owner on Oct 14, 2022. It is now read-only.

[WIP] Chain benchmarks and fixes #290

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

119 changes: 117 additions & 2 deletions src/chain/bench/chain_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use criterion::Criterion;
use crypto::*;
use miner::Proof;
use parking_lot::RwLock;
use persistence::PersistentDb;
use patricia_trie::TrieDBMut;
use persistence::{Codec, DbHasher, PersistentDb};
use rand::prelude::*;
use rocksdb::DB;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
Expand Down Expand Up @@ -152,7 +153,6 @@ fn criterion_benchmark(c: &mut Criterion) {
timestamp: Utc::now(),
transactions: Some(Arc::new(RwLock::new(Vec::new()))),
};

block.sign_miner(identity.skey());
block.compute_hash();

Expand Down Expand Up @@ -184,6 +184,121 @@ fn criterion_benchmark(c: &mut Criterion) {
});
});

c.bench_function("append_block with a full TransactionBlock", |b| {
let tmp_dir = tempdir::TempDir::new("db_dir").unwrap();
let path1 = tmp_dir.path().join("1");
let path2 = tmp_dir.path().join("2");

let db1 = Arc::new(DB::open_default(path1.to_str().unwrap()).unwrap());
let per_db = PersistentDb::new(db1, None);

let db2 = Arc::new(DB::open_default(path2.to_str().unwrap()).unwrap());
let db_state = PersistentDb::new(db2, None);

crate::init(per_db.clone(), db_state, true);

let chain = Chain::<PowBlock>::new(per_db, PowBlock::genesis_state(), true);
let chain = ChainRef::<PowBlock>::new(Arc::new(RwLock::new(chain)));
let proof = Proof::test_proof(42);
let identity = Identity::new();
let node_id = NodeId(*identity.pkey());
let collector_address = NormalAddress::random();
let ip = random_socket_addr();
let mut height = 1;

let mut checkpoint_block = CheckpointBlock::new(
chain.canonical_tip().block_hash().unwrap(),
collector_address,
ip,
height,
proof,
node_id.clone(),
);

checkpoint_block.sign_miner(identity.skey());
checkpoint_block.compute_hash();

let mut blocks = Vec::new();
let mut parent_hash = checkpoint_block.block_hash().unwrap();
let (mut db, mut state) = chain.get_db_and_state_root();

// {
// let mut trie = TrieDBMut::<DbHasher, Codec>::from_existing(&mut db, &mut state).unwrap();
// set_account_balance(TestAccount::A.to_perm_address().as_bytes(), 10000000, &mut trie);
// }

for _ in 0..ALLOWED_TXS_BLOCKS {
height += 1;

let transaction_list = get_tx_list_of_size(MAX_TX_SET_SIZE).unwrap();
let state_root = {
// apply all transactions in the list to the state in order to get the state root
{
let mut trie =
TrieDBMut::<DbHasher, Codec>::from_existing(&mut db, &mut state).unwrap();

for tx in transaction_list.iter() {
tx.apply(&mut trie);
}
}
state
};

let mut block = TransactionBlock {
tx_checksums: Some(Vec::<ShortHash>::new()),
pieces_sizes: Some(Vec::<usize>::new()),
height,
parent_hash,
state_root: Some(state_root),
tx_root: Some(ShortHash::NULL_RLP),
hash: None,
miner_id: node_id.clone(),
miner_signature: None,
timestamp: Utc::now(),
transactions: Some(Arc::new(RwLock::new(transaction_list))),
};
block.sign_miner(identity.skey());
block.compute_hash();

let block = Arc::<TransactionBlock>::new(block);
let block = PowBlock::Transaction(block);
let block = Arc::<PowBlock>::new(block);

parent_hash = block.block_hash().unwrap();

blocks.push(block);
}

println!("st");

b.iter(|| {
println!("b1");
let db = test_helpers::init_tempdb();
println!("b2");
let chain = Chain::<PowBlock>::new(db, PowBlock::genesis_state(), true);
println!("b3");
let chain = ChainRef::<PowBlock>::new(Arc::new(RwLock::new(chain)));

println!("b4");
let checkpoint_block = checkpoint_block.clone();
let blocks = blocks.clone();
let block = Arc::<CheckpointBlock>::new(checkpoint_block);
let block = PowBlock::Checkpoint(block);
let block = Arc::<PowBlock>::new(block);

println!("dst1");
chain.append_block(block).unwrap();

println!("dst2");
for block in blocks {
println!("app1");
chain.append_block(block).unwrap();
println!("app2");
}
println!("dn3");
});
});

// c.bench_function("append_block with a full TransactionBlock", |b| {
// let db1 = test_helpers::init_tempdb();
// let db2 = test_helpers::init_tempdb();
Expand Down
128 changes: 124 additions & 4 deletions src/chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ impl<B: Block> ChainRef<B> {
pub fn get_db_and_state_root(&self) -> (PersistentDb, ShortHash) {
let chain = self.chain.read();
(
chain.db.clone(),
chain.canonical_tip_state.inner_ref().state_root().clone(),
chain.canonical_tip_state.inner_ref().state_db(),
chain.canonical_tip_state.inner_ref().state_root(),
)
}

Expand Down Expand Up @@ -1604,7 +1604,7 @@ impl<B: Block> Chain<B> {

// Process orphans
self.process_orphans(height + 1);

Ok(())
} else {
if self.orphan_pool.len() >= B::MAX_ORPHANS {
Expand Down Expand Up @@ -2216,6 +2216,10 @@ pub mod tests {
unimplemented!();
}

fn state_db(&self) -> PersistentDb {
unimplemented!();
}

fn get_account_nonce(&self, address: &Address) -> Option<u64> {
unimplemented!();
}
Expand Down Expand Up @@ -9347,4 +9351,120 @@ pub mod tests {
true
}
}
}

use patricia_trie::{Trie, TrieDB, TrieDBMut, TrieMut};
use persistence::{Codec, DbHasher, PersistentDb};
use crate::block::Block;
use crate::pow_chain::block::*;
use crate::pow_chain::chain::*;
use crate::pow_chain::PowChainState;
use crate::pow_chain::checkpoint_block::*;
use crate::pow_chain::transaction_block::*;

use triomphe::Arc;
use account::normal::NormalAddress;
use miner::Proof;
use criterion::Criterion;
use rand::prelude::*;
use crypto::*;
use rocksdb::DB;
use parking_lot::RwLock;
use chrono::prelude::*;
use transactions::*;
use constants::*;

#[test]
fn triedb_insert() {
let tmp_dir = tempdir::TempDir::new("db_dir").unwrap();
let path1 = tmp_dir.path().join("1");
let path2 = tmp_dir.path().join("2");

let db1 = Arc::new(DB::open_default(path1.to_str().unwrap()).unwrap());
let per_db = PersistentDb::new(db1, None);

let db2 = Arc::new(DB::open_default(path2.to_str().unwrap()).unwrap());
let db_state = PersistentDb::new(db2, None);

crate::init(per_db.clone(), db_state, true);

let chain = Chain::<PowBlock>::new(per_db, PowBlock::genesis_state(), true);
let chain = ChainRef::<PowBlock>::new(Arc::new(RwLock::new(chain)));

let proof = Proof::test_proof(42);
let identity = Identity::new();
let node_id = NodeId(*identity.pkey());
let collector_address = NormalAddress::random();
let mut thread_rng = rand::thread_rng();
let addr = IpAddr::V4(Ipv4Addr::new(thread_rng.gen(), thread_rng.gen(), thread_rng.gen(), thread_rng.gen()));
let ip = SocketAddr::new(addr, 44034);
let mut height = 1;

let mut checkpoint_block = CheckpointBlock::new(
chain.canonical_tip().block_hash().unwrap(),
collector_address,
ip,
height,
proof,
node_id.clone(),
);

checkpoint_block.sign_miner(identity.skey());
checkpoint_block.compute_hash();

let mut blocks = Vec::new();
let mut parent_hash = checkpoint_block.block_hash().unwrap();
let (mut db, mut state) = chain.get_db_and_state_root();
for _ in 0..ALLOWED_TXS_BLOCKS {
height += 1;

let transaction_list = get_tx_list_of_size(MAX_TX_SET_SIZE).unwrap();
let state_root = {
// apply all transactions in the list to the state in order to get the state root
{
let mut trie = TrieDBMut::<DbHasher, Codec>::from_existing(
&mut db, &mut state).unwrap();

for tx in transaction_list.iter() {
tx.apply(&mut trie);
}
}
state
};

let mut block = TransactionBlock {
tx_checksums: Some(Vec::<ShortHash>::new()),
pieces_sizes: Some(Vec::<usize>::new()),
height: height,
parent_hash: parent_hash,
state_root: Some(state_root),
tx_root: Some(ShortHash::NULL_RLP),
hash: None,
miner_id: node_id.clone(),
miner_signature: None,
timestamp: Utc::now(),
transactions: Some(Arc::new(RwLock::new(transaction_list))),
};

block.sign_miner(identity.skey());
block.compute_hash();

let block = Arc::<TransactionBlock>::new(block);
let block = PowBlock::Transaction(block);
let block = Arc::<PowBlock>::new(block);

parent_hash = block.block_hash().unwrap();

blocks.push(block);
}

let block = Arc::<CheckpointBlock>::new(checkpoint_block);
let block = PowBlock::Checkpoint(block);
let block = Arc::<PowBlock>::new(block);

chain.append_block(block).unwrap();

for block in blocks {
chain.append_block(block).unwrap();
}
}
}
8 changes: 6 additions & 2 deletions src/chain/src/pow_chain/chain_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,18 @@ impl StateInterface for PowChainState {
self.state_root.clone()
}

fn state_db(&self) -> PersistentDb {
self.db.clone()
}

fn get_account_nonce(&self, address: &Address) -> Option<u64> {
let trie = TrieDB::<DbHasher, Codec>::new(&self.db, &self.state_root).unwrap();

// Calculate nonce key
//
// The key of a nonce has the following format:
// `<account-address>.n`
let nonce_key = [address.as_bytes(), &b".n"[..]].concat();
// `<account-address>.N`
let nonce_key = [address.as_bytes(), &b".N"[..]].concat();
let encoded_nonce = trie.get(&nonce_key).ok()??;

Some(decode_be_u64!(encoded_nonce).unwrap())
Expand Down
4 changes: 4 additions & 0 deletions src/chain/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crypto::ShortHash;
use std::fmt::Debug;
use transactions::Tx;
use triomphe::Arc;
use persistence::PersistentDb;

#[derive(Clone, Debug, PartialEq, Copy)]
pub enum OrphanType {
Expand Down Expand Up @@ -125,6 +126,9 @@ pub trait StateInterface {
/// Returns the current state root that is stored in the state
fn state_root(&self) -> ShortHash;

/// Return the current state db that is stored in the state
fn state_db(&self) -> PersistentDb;

/// Returns the nonce of the account with the given address
/// if it exists.
fn get_account_nonce(&self, address: &Address) -> Option<u64>;
Expand Down
14 changes: 14 additions & 0 deletions src/transactions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ triomphe = { git = "https://github.com/octavonce/triomphe" }
[dev-dependencies]
tempfile = "3.0.5"
test-helpers = { path = "../util/test-helpers" }
criterion = "0.2.1"
rocksdb = "0.13.0"

[dev-dependencies.miner]
features = ["test"]
path = "../miner"

[dev-dependencies.transactions]
features = ["test"]
path = "../transactions"

[dev-dependencies.chain]
features = ["test"]
path = "../chain"

[features]
test = []
Loading