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/res/ethereum/frontier.json b/res/ethereum/frontier.json index 9cb456ce8..43be680d2 100644 --- a/res/ethereum/frontier.json +++ b/res/ethereum/frontier.json @@ -3,7 +3,7 @@ "engineName": "Ethash", "params": { "accountStartNonce": "0x00", - "frontierCompatibilityModeLimit": "0xDBBA0", + "frontierCompatibilityModeLimit": "0xdbba0", "maximumExtraDataSize": "0x20", "tieBreakingGas": false, "minGasLimit": "0x1388", diff --git a/res/ethereum/homestead_test.json b/res/ethereum/homestead_test.json index b11ef9740..1fb5dff80 100644 --- a/res/ethereum/homestead_test.json +++ b/res/ethereum/homestead_test.json @@ -3,7 +3,7 @@ "engineName": "Ethash", "params": { "accountStartNonce": "0x00", - "frontierCompatibilityModeLimit": "0", + "frontierCompatibilityModeLimit": 0, "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "tieBreakingGas": false, diff --git a/res/ethereum/morden.json b/res/ethereum/morden.json index 32fed0cab..cdcf8c7dc 100644 --- a/res/ethereum/morden.json +++ b/res/ethereum/morden.json @@ -3,7 +3,7 @@ "engineName": "Ethash", "params": { "accountStartNonce": "0x0100000", - "frontierCompatibilityModeLimit": "0xDBBA0", + "frontierCompatibilityModeLimit": "0xdbba0", "maximumExtraDataSize": "0x20", "tieBreakingGas": false, "minGasLimit": "0x1388", diff --git a/res/ethereum/tests b/res/ethereum/tests index e838fd909..c670b1d8c 160000 --- a/res/ethereum/tests +++ b/res/ethereum/tests @@ -1 +1 @@ -Subproject commit e838fd90998fc5502d0b7c9427a4c231f9a6953d +Subproject commit c670b1d8c9f09593a6758ab2c099360e16c7c25b diff --git a/src/ethereum/ethash.rs b/src/ethereum/ethash.rs index 019d764df..4736beb92 100644 --- a/src/ethereum/ethash.rs +++ b/src/ethereum/ethash.rs @@ -59,9 +59,14 @@ impl Engine for Ethash { } fn schedule(&self, env_info: &EnvInfo) -> Schedule { + trace!(target: "client", "Creating schedule. param={:?}, fCML={}", self.spec().engine_params.get("frontierCompatibilityModeLimit"), self.u64_param("frontierCompatibilityModeLimit")); match env_info.number < self.u64_param("frontierCompatibilityModeLimit") { - true => Schedule::new_frontier(), - _ => Schedule::new_homestead(), + true => { + Schedule::new_frontier() + }, + _ => { + Schedule::new_homestead() + }, } } @@ -178,12 +183,13 @@ impl Ethash { } } else { + trace!(target: "ethash", "Calculating difficulty parent.difficulty={}, header.timestamp={}, parent.timestamp={}", parent.difficulty, header.timestamp, parent.timestamp); + //block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) let diff_inc = (header.timestamp - parent.timestamp) / 10; if diff_inc <= 1 { parent.difficulty + parent.difficulty / From::from(2048) * From::from(1 - diff_inc) - } - else { - parent.difficulty - parent.difficulty / From::from(2048) * From::from(max(diff_inc - 1, 99)) + } else { + parent.difficulty - parent.difficulty / From::from(2048) * From::from(min(diff_inc - 1, 99)) } }; target = max(min_difficulty, target); 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 f4166eab2..4d342f713 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -16,7 +16,7 @@ pub fn gzip64res_to_json(source: &[u8]) -> Json { Json::from_str(&s).expect("Json is invalid") } -/// Convert JSON value to equivlaent RLP representation. +/// Convert JSON value to equivalent RLP representation. // TODO: handle container types. fn json_to_rlp(json: &Json) -> Bytes { match *json { @@ -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 84ca35058..d56d99491 100644 --- a/src/tests/chain.rs +++ b/src/tests/chain.rs @@ -1,3 +1,6 @@ +use std::env; +use log::{LogLevelFilter}; +use env_logger::LogBuilder; use super::test_common::*; use client::{BlockChainClient,Client}; use pod_state::*; @@ -10,7 +13,24 @@ pub enum ChainEra { Homestead, } +lazy_static! { + static ref LOG_DUMMY: bool = { + let mut builder = LogBuilder::new(); + builder.filter(None, LogLevelFilter::Info); + + if let Ok(log) = env::var("RUST_LOG") { + builder.parse(&log); + } + + if let Ok(_) = builder.init() { + println!("logger initialized"); + } + true + }; +} + pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { + 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(); @@ -35,10 +55,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());