Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' into dp/chore/extract-verification
Browse files Browse the repository at this point in the history
* master:
  Run cargo fix on a few of the worst offenders (#10854)
  removed redundant fork choice abstraction (#10849)
  Extract state-db from ethcore (#10858)
  Fix fork choice (#10837)
  Move more code into state-account (#10840)
  Remove compiler warning (#10865)
  [ethash] use static_assertions crate (#10860)
  • Loading branch information
dvdplm committed Jul 9, 2019
2 parents eb57f24 + f53c3e5 commit 2c86e2b
Show file tree
Hide file tree
Showing 79 changed files with 561 additions and 498 deletions.
39 changes: 24 additions & 15 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions ethash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ log = "0.4"
memmap = "0.6"
parking_lot = "0.8"
primal = "0.2.3"
static_assertions = "0.3.3"

[dev-dependencies]
criterion = "0.2"
Expand Down
2 changes: 2 additions & 0 deletions ethash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ extern crate primal;
extern crate crunchy;
#[macro_use]
extern crate log;
#[macro_use]
extern crate static_assertions;

#[cfg(test)]
extern crate rustc_hex;
Expand Down
29 changes: 1 addition & 28 deletions ethash/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,34 +69,7 @@ pub type NodeBytes = [u8; NODE_BYTES];
pub type NodeWords = [u32; NODE_WORDS];
pub type NodeDwords = [u64; NODE_DWORDS];

macro_rules! static_assert_size_eq {
(@inner $a:ty, $b:ty, $($rest:ty),*) => {
fn first() {
static_assert_size_eq!($a, $b);
}

fn second() {
static_assert_size_eq!($b, $($rest),*);
}
};
(@inner $a:ty, $b:ty) => {
unsafe {
let val: $b = ::std::mem::uninitialized();
let _: $a = ::std::mem::transmute(val);
}
};
($($rest:ty),*) => {
static_assert_size_eq!(size_eq: $($rest),*);
};
($name:ident : $($rest:ty),*) => {
#[allow(dead_code)]
fn $name() {
static_assert_size_eq!(@inner $($rest),*);
}
};
}

static_assert_size_eq!(Node, NodeBytes, NodeWords, NodeDwords);
assert_eq_size!(node; Node, NodeBytes, NodeWords, NodeDwords);

#[repr(C)]
pub union Node {
Expand Down
2 changes: 1 addition & 1 deletion ethcore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ethereum-types = "0.6.0"
ethjson = { path = "../json" }
ethkey = { path = "../accounts/ethkey" }
evm = { path = "evm" }
factories = { path = "factories" }
trie-vm-factories = { path = "trie-vm-factories" }
futures = "0.1"
hash-db = "0.12.4"
parity-util-mem = "0.1"
Expand Down
2 changes: 1 addition & 1 deletion ethcore/account-state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ derive_more = "0.15.0"
ethereum-types = "0.6.0"
ethtrie = { package = "patricia-trie-ethereum", path = "../../util/patricia-trie-ethereum" }
evm = { path = "../evm" }
factories = { path = "../factories" }
trie-vm-factories = { path = "../trie-vm-factories" }
hash-db = "0.12.4"
journaldb = { path = "../../util/journaldb" }
keccak-hash = "0.2.0"
Expand Down
2 changes: 1 addition & 1 deletion ethcore/account-state/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use common_types::{
};
use ethereum_types::{Address, H256, U256};
use ethtrie::{TrieDB, Result as TrieResult};
use factories::{Factories, VmFactory};
use trie_vm_factories::{Factories, VmFactory};
use hash_db::HashDB;
use keccak_hash::{KECCAK_EMPTY, KECCAK_NULL_RLP};
use keccak_hasher::KeccakHasher;
Expand Down
2 changes: 1 addition & 1 deletion ethcore/account-state/src/substate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ impl Substate {

#[cfg(test)]
mod tests {
use ethereum_types::Address;
use common_types::log_entry::LogEntry;
use ethereum_types::Address;
use super::Substate;

#[test]
Expand Down
4 changes: 3 additions & 1 deletion ethcore/blockchain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@ blooms-db = { path = "../../util/blooms-db" }
common-types = { path = "../types" }
ethcore-db = { path = "../db" }
ethereum-types = "0.6.0"
keccak-hash = "0.2.0"
parity-util-mem = "0.1"
itertools = "0.5"
kvdb = "0.1"
log = "0.4"
parity-bytes = "0.1"
parking_lot = "0.8"
rand = "0.6"
rayon = "1.0"
rlp = "0.4.0"
rlp_compress = { path = "../../util/rlp-compress" }
rlp_derive = { path = "../../util/rlp-derive" }
triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" }

[dev-dependencies]
env_logger = "0.5"
ethkey = { path = "../../accounts/ethkey" }
keccak-hash = "0.2.0"
rustc-hex = "1.0"
tempdir = "0.3"
kvdb-memorydb = "0.1"
78 changes: 76 additions & 2 deletions ethcore/blockchain/src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,10 @@ impl BlockChain {
///
/// If the tree route verges into pruned or unknown blocks,
/// `None` is returned.
///
/// `is_from_route_finalized` returns whether the `from` part of the
/// route contains a finalized block. This only holds if the two parts (from
/// and to) are on different branches, ie. on 2 different forks.
pub fn tree_route(&self, from: H256, to: H256) -> Option<TreeRoute> {
let mut from_branch = vec![];
let mut is_from_route_finalized = false;
Expand All @@ -723,9 +727,9 @@ impl BlockChain {
// reset from && to to the same level
while from_details.number > to_details.number {
from_branch.push(current_from);
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
current_from = from_details.parent.clone();
from_details = self.block_details(&from_details.parent)?;
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
}

while to_details.number > from_details.number {
Expand All @@ -739,9 +743,9 @@ impl BlockChain {
// move to shared parent
while current_from != current_to {
from_branch.push(current_from);
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
current_from = from_details.parent.clone();
from_details = self.block_details(&from_details.parent)?;
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;

to_branch.push(current_to);
current_to = to_details.parent.clone();
Expand Down Expand Up @@ -2503,4 +2507,74 @@ mod tests {
assert_eq!(bc.epoch_transition_for(fork_hash).unwrap().block_number, 0);
}
}

#[test]
fn tree_rout_with_finalization() {
let genesis = BlockBuilder::genesis();
let a = genesis.add_block();
// First branch
let a1 = a.add_block_with_random_transactions();
let a2 = a1.add_block_with_random_transactions();
let a3 = a2.add_block_with_random_transactions();
// Second branch
let b1 = a.add_block_with_random_transactions();
let b2 = b1.add_block_with_random_transactions();

let a_hash = a.last().hash();
let a1_hash = a1.last().hash();
let a2_hash = a2.last().hash();
let a3_hash = a3.last().hash();
let b2_hash = b2.last().hash();

let bootstrap_chain = |blocks: Vec<&BlockBuilder>| {
let db = new_db();
let bc = new_chain(genesis.last().encoded(), db.clone());
let mut batch = db.key_value().transaction();
for block in blocks {
insert_block_batch(&mut batch, &bc, block.last().encoded(), vec![]);
bc.commit();
}
db.key_value().write(batch).unwrap();
(db, bc)
};

let mark_finalized = |block_hash: H256, db: &Arc<dyn BlockChainDB>, bc: &BlockChain| {
let mut batch = db.key_value().transaction();
bc.mark_finalized(&mut batch, block_hash).unwrap();
bc.commit();
db.key_value().write(batch).unwrap();
};

// Case 1: fork, with finalized common ancestor
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]);
assert_eq!(bc.best_block_hash(), a3_hash);
assert_eq!(bc.block_hash(2).unwrap(), a1_hash);

mark_finalized(a_hash, &db, &bc);
assert!(!bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized);
}

// Case 2: fork with a finalized block on a branch
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]);
assert_eq!(bc.best_block_hash(), a3_hash);
assert_eq!(bc.block_hash(2).unwrap(), a1_hash);

mark_finalized(a2_hash, &db, &bc);
assert!(bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized);
}

// Case 3: no-fork, with a finalized block
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2]);
assert_eq!(bc.best_block_hash(), a2_hash);

mark_finalized(a1_hash, &db, &bc);
assert!(!bc.tree_route(a1_hash, a2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(a2_hash, a1_hash).unwrap().is_from_route_finalized);
}
}
}
33 changes: 31 additions & 2 deletions ethcore/blockchain/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ use ethereum_types::{U256, H256, Bloom};

use common_types::encoded;
use common_types::header::Header;
use common_types::transaction::SignedTransaction;
use common_types::transaction::{SignedTransaction, Transaction, Action};
use common_types::view;
use common_types::views::BlockView;
use keccak_hash::keccak;
use rlp::encode;
use rlp_derive::RlpEncodable;
use triehash_ethereum::ordered_trie_root;

/// Helper structure, used for encoding blocks.
#[derive(Default, Clone, RlpEncodable)]
Expand Down Expand Up @@ -136,6 +138,29 @@ impl BlockBuilder {
})
}

/// Add a block with randomly generated transactions.
#[inline]
pub fn add_block_with_random_transactions(&self) -> Self {
// Maximum of ~50 transactions
let count = rand::random::<u8>() as usize / 5;
let transactions = std::iter::repeat_with(|| {
let data_len = rand::random::<u8>();
let data = std::iter::repeat_with(|| rand::random::<u8>())
.take(data_len as usize)
.collect::<Vec<_>>();
Transaction {
nonce: 0.into(),
gas_price: 0.into(),
gas: 100_000.into(),
action: Action::Create,
value: 100.into(),
data,
}.sign(&keccak("").into(), None)
}).take(count);

self.add_block_with_transactions(transactions)
}

/// Add a block with given transactions.
#[inline]
pub fn add_block_with_transactions<T>(&self, transactions: T) -> Self
Expand Down Expand Up @@ -166,11 +191,15 @@ impl BlockBuilder {
let mut block = Block::default();
let metadata = get_metadata();
let block_number = parent_number + 1;
let transactions = metadata.transactions;
let transactions_root = ordered_trie_root(transactions.iter().map(rlp::encode));

block.header.set_parent_hash(parent_hash);
block.header.set_number(block_number);
block.header.set_log_bloom(metadata.bloom);
block.header.set_difficulty(metadata.difficulty);
block.transactions = metadata.transactions;
block.header.set_transactions_root(transactions_root);
block.transactions = transactions;

parent_hash = block.hash();
parent_number = block_number;
Expand Down
Loading

0 comments on commit 2c86e2b

Please sign in to comment.