diff --git a/Cargo.toml b/Cargo.toml index 872e1e675..eef261317 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ ethash = { path = "ethash" } num_cpus = "0.2" clippy = "0.0.37" crossbeam = "0.1.5" +lazy_static = "0.1" [features] jit = ["evmjit"] diff --git a/src/lib.rs b/src/lib.rs index 8dd02b3bc..e084635dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,6 +91,8 @@ extern crate evmjit; #[macro_use] extern crate ethcore_util as util; extern crate crossbeam; +#[macro_use] +extern crate lazy_static; // NOTE: Add doc parser exception for these pub declarations. diff --git a/src/spec.rs b/src/spec.rs index 77073eedd..4d342f713 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -77,6 +77,10 @@ pub struct Spec { pub gas_used: U256, /// TODO [Gav Wood] Please document me pub timestamp: u64, + /// Transactions root of the genesis block. Should be SHA3_NULL_RLP. + pub transactions_root: H256, + /// Receipts root of the genesis block. Should be SHA3_NULL_RLP. + pub receipts_root: H256, /// TODO [arkpar] Please document me pub extra_data: Bytes, /// TODO [Gav Wood] Please document me @@ -120,11 +124,11 @@ impl Spec { timestamp: self.timestamp, number: 0, author: self.author.clone(), - transactions_root: SHA3_NULL_RLP.clone(), + transactions_root: self.transactions_root.clone(), uncles_hash: RlpStream::new_list(0).out().sha3(), extra_data: self.extra_data.clone(), state_root: self.state_root().clone(), - receipts_root: SHA3_NULL_RLP.clone(), + receipts_root: self.receipts_root.clone(), log_bloom: H2048::new().clone(), gas_used: self.gas_used.clone(), gas_limit: self.gas_limit.clone(), @@ -172,6 +176,8 @@ impl Spec { }; self.parent_hash = H256::from_json(&genesis["parentHash"]); + self.transactions_root = genesis.find("transactionsTrie").and_then(|_| Some(H256::from_json(&genesis["transactionsTrie"]))).unwrap_or(SHA3_NULL_RLP.clone()); + self.receipts_root = genesis.find("receiptTrie").and_then(|_| Some(H256::from_json(&genesis["receiptTrie"]))).unwrap_or(SHA3_NULL_RLP.clone()); self.author = Address::from_json(&genesis["coinbase"]); self.difficulty = U256::from_json(&genesis["difficulty"]); self.gas_limit = U256::from_json(&genesis["gasLimit"]); @@ -248,6 +254,8 @@ impl FromJson for Spec { gas_limit: U256::from_str(&genesis["gasLimit"].as_string().unwrap()[2..]).unwrap(), gas_used: U256::from(0u8), timestamp: u64::from_str(&genesis["timestamp"].as_string().unwrap()[2..]).unwrap(), + transactions_root: SHA3_NULL_RLP.clone(), + receipts_root: SHA3_NULL_RLP.clone(), extra_data: genesis["extraData"].as_string().unwrap()[2..].from_hex().unwrap(), genesis_state: state, seal_fields: seal_fields, diff --git a/src/tests/chain.rs b/src/tests/chain.rs index 48b176508..e260deddc 100644 --- a/src/tests/chain.rs +++ b/src/tests/chain.rs @@ -13,19 +13,22 @@ pub enum ChainEra { Homestead, } -fn setup_log() { - let mut builder = LogBuilder::new(); - builder.filter(None, LogLevelFilter::Info); +lazy_static! { + static ref LOG_DUMMY: bool = { + let mut builder = LogBuilder::new(); + builder.filter(None, LogLevelFilter::Info); - if env::var("RUST_LOG").is_ok() { - builder.parse(&env::var("RUST_LOG").unwrap()); - } + if env::var("RUST_LOG").is_ok() { + builder.parse(&env::var("RUST_LOG").unwrap()); + } - builder.init().unwrap(); + builder.init().unwrap(); + true + }; } pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { - setup_log(); + let _ = LOG_DUMMY.deref(); let json = Json::from_str(::std::str::from_utf8(json_data).unwrap()).expect("Json is invalid"); let mut failed = Vec::new(); @@ -50,10 +53,13 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { spec.set_genesis_state(s); spec.overwrite_genesis(test.find("genesisBlockHeader").unwrap()); assert!(spec.is_state_root_valid()); + let genesis_hash = spec.genesis_header().hash(); + assert_eq!(genesis_hash, H256::from_json(&test.find("genesisBlockHeader").unwrap()["hash"])); let temp = RandomTempPath::new(); { let client = Client::new(spec, temp.as_path(), IoChannel::disconnected()).unwrap(); + assert_eq!(client.chain_info().best_block_hash, genesis_hash); for (b, is_valid) in blocks.into_iter() { if Block::is_good(&b) { let _ = client.import_block(b.clone());