From f92a0c8df296c83c69d7a78ba0502153f79744e0 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 17 Mar 2016 11:50:31 +0100 Subject: [PATCH 01/41] rpctest executable --- Cargo.lock | 1 + Cargo.toml | 5 ++ json/src/blockchain/block.rs | 7 +++ json/src/blockchain/blockchain.rs | 12 +++++ json/src/blockchain/mod.rs | 8 ++++ json/src/blockchain/test.rs | 1 + json/src/bytes.rs | 2 +- parity/rpctest.rs | 80 +++++++++++++++++++++++++++++++ 8 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 parity/rpctest.rs diff --git a/Cargo.lock b/Cargo.lock index 79ca26582..1a701042e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,7 @@ dependencies = [ "rpassword 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index fd1d16cff..d00f1ff60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ ethminer = { path = "miner" } ethcore-devtools = { path = "devtools" } ethcore-rpc = { path = "rpc", optional = true } ethjson = { path = "json" } +serde_json = "0.7.0" [features] default = ["rpc"] @@ -40,6 +41,10 @@ travis-nightly = ["ethcore/json-tests", "dev"] path = "parity/main.rs" name = "parity" +[[bin]] +path = "parity/rpctest.rs" +name = "rpctest" + [profile.release] debug = false lto = false diff --git a/json/src/blockchain/block.rs b/json/src/blockchain/block.rs index ed297077c..190102ae5 100644 --- a/json/src/blockchain/block.rs +++ b/json/src/blockchain/block.rs @@ -31,6 +31,13 @@ pub struct Block { uncles: Vec
, } +impl Block { + /// Returns block rlp. + pub fn rlp(&self) -> Vec { + self.rlp.clone().into() + } +} + #[cfg(test)] mod tests { use serde_json; diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs index f6b1259ca..8c67799e1 100644 --- a/json/src/blockchain/blockchain.rs +++ b/json/src/blockchain/blockchain.rs @@ -35,6 +35,18 @@ pub struct BlockChain { pre_state: State, } +impl BlockChain { + /// Returns genesis block rlp. + pub fn genesis_rlp(&self) -> Vec { + self.genesis_rlp.clone().into() + } + + /// Returns blocks rlp. + pub fn blocks_rlp(&self) -> Vec> { + self.blocks.iter().map(|block| block.rlp()).collect() + } +} + #[cfg(test)] mod tests { use serde_json; diff --git a/json/src/blockchain/mod.rs b/json/src/blockchain/mod.rs index 046b2e534..727469ea2 100644 --- a/json/src/blockchain/mod.rs +++ b/json/src/blockchain/mod.rs @@ -23,3 +23,11 @@ pub mod header; pub mod state; pub mod transaction; pub mod test; + +pub use self::account::Account; +pub use self::block::Block; +pub use self::blockchain::BlockChain; +pub use self::header::Header; +pub use self::state::State; +pub use self::test::Test; +pub use self::transaction::Transaction; diff --git a/json/src/blockchain/test.rs b/json/src/blockchain/test.rs index 6097a60e6..6f48a8bc6 100644 --- a/json/src/blockchain/test.rs +++ b/json/src/blockchain/test.rs @@ -21,6 +21,7 @@ use std::ops::Deref; use blockchain::blockchain::BlockChain; /// Blockchain test deserializer. +#[derive(Debug, PartialEq, Deserialize)] pub struct Test(BTreeMap); impl Deref for Test { diff --git a/json/src/bytes.rs b/json/src/bytes.rs index 28b7636d4..061795b40 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -21,7 +21,7 @@ use serde::{Deserialize, Deserializer, Error}; use serde::de::Visitor; /// Lenient bytes json deserialization for test json files. -#[derive(Default, Debug, PartialEq)] +#[derive(Default, Debug, PartialEq, Clone)] pub struct Bytes(Vec); impl Into> for Bytes { diff --git a/parity/rpctest.rs b/parity/rpctest.rs new file mode 100644 index 000000000..182f6dfed --- /dev/null +++ b/parity/rpctest.rs @@ -0,0 +1,80 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +extern crate docopt; +extern crate rustc_serialize; +extern crate serde_json; +extern crate ethjson; + +use std::process; +use std::fs::File; +use std::path::Path; +use docopt::Docopt; + +const USAGE: &'static str = r#" +Parity rpctest client. + By Wood/Paronyan/Kotewicz/Drwięga/Volf. + Copyright 2015, 2016 Ethcore (UK) Limited + +Usage: + parity --json --name +"#; + +#[derive(Debug, RustcDecodable)] +struct Args { + arg_test_file: String, + arg_test_name: String, +} + +struct Configuration { + args: Args, +} + +impl Configuration { + fn parse() -> Self { + Configuration { + args: Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()) + } + } + + fn execute(&self) { + println!("file path: {:?}", self.args.arg_test_file); + println!("test name: {:?}", self.args.arg_test_name); + + let path = Path::new(&self.args.arg_test_file); + let file = File::open(path).unwrap_or_else(|_| { + println!("Cannot open file."); + process::exit(1); + }); + + let tests: ethjson::blockchain::Test = serde_json::from_reader(file).unwrap_or_else(|_| { + println!("Invalid json file."); + process::exit(2); + }); + + let blockchain = tests.get(&self.args.arg_test_name).unwrap_or_else(|| { + println!("Invalid test name."); + process::exit(3); + }); + + + + } +} + +fn main() { + Configuration::parse().execute(); +} From b684bc9ba01d292bf5bfdc4b13fe0eb95525ab0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 17 Mar 2016 12:47:31 +0100 Subject: [PATCH 02/41] Updating sealing when new transactions are received --- miner/src/lib.rs | 2 +- miner/src/miner.rs | 37 +++++++++++++---------- rpc/src/v1/tests/helpers/miner_service.rs | 2 +- sync/src/chain.rs | 9 ++++-- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/miner/src/lib.rs b/miner/src/lib.rs index a431bd44e..d6310eb8a 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -92,7 +92,7 @@ pub trait MinerService : Send + Sync { fn chain_new_blocks(&self, chain: &BlockChainClient, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256]); /// New chain head event. Restart mining operation. - fn prepare_sealing(&self, chain: &BlockChainClient); + fn update_sealing(&self, chain: &BlockChainClient); /// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock. fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex>; diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 6d5b3086e..d177d81ee 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -93,13 +93,28 @@ impl Miner { pub fn set_minimal_gas_price(&self, min_gas_price: U256) { self.transaction_queue.lock().unwrap().set_minimal_gas_price(min_gas_price); } + + /// Prepares new block for sealing including top transactions from queue. + pub fn prepare_sealing(&self, chain: &BlockChainClient) { + let no_of_transactions = 128; + // TODO: should select transactions orm queue according to gas limit of block. + let transactions = self.transaction_queue.lock().unwrap().top_transactions(no_of_transactions); + + let b = chain.prepare_sealing( + self.author(), + self.gas_floor_target(), + self.extra_data(), + transactions, + ); + *self.sealing_block.lock().unwrap() = b; + } } impl MinerService for Miner { fn clear_and_reset(&self, chain: &BlockChainClient) { self.transaction_queue.lock().unwrap().clear(); - self.prepare_sealing(chain); + self.update_sealing(chain); } fn status(&self) -> MinerStatus { @@ -121,18 +136,10 @@ impl MinerService for Miner { transaction_queue.pending_hashes() } - fn prepare_sealing(&self, chain: &BlockChainClient) { - let no_of_transactions = 128; - // TODO: should select transactions orm queue according to gas limit of block. - let transactions = self.transaction_queue.lock().unwrap().top_transactions(no_of_transactions); - - let b = chain.prepare_sealing( - self.author(), - self.gas_floor_target(), - self.extra_data(), - transactions, - ); - *self.sealing_block.lock().unwrap() = b; + fn update_sealing(&self, chain: &BlockChainClient) { + if self.sealing_enabled.load(atomic::Ordering::Relaxed) { + self.prepare_sealing(chain); + } } fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex> { @@ -199,8 +206,6 @@ impl MinerService for Miner { }); } - if self.sealing_enabled.load(atomic::Ordering::Relaxed) { - self.prepare_sealing(chain); - } + self.update_sealing(chain); } } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 3a60bd136..9f38b374b 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -54,7 +54,7 @@ impl MinerService for TestMinerService { fn chain_new_blocks(&self, _chain: &BlockChainClient, _imported: &[H256], _invalid: &[H256], _enacted: &[H256], _retracted: &[H256]) { unimplemented!(); } /// New chain head event. Restart mining operation. - fn prepare_sealing(&self, _chain: &BlockChainClient) { unimplemented!(); } + fn update_sealing(&self, _chain: &BlockChainClient) { unimplemented!(); } /// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock. fn sealing_block(&self, _chain: &BlockChainClient) -> &Mutex> { diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 4f6c2100a..c87dc9535 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -403,7 +403,7 @@ impl ChainSync { self.remove_downloaded_blocks(number + 1); } if self.have_common_block && number < self.current_base_block() + 1 { - // unkown header + // unkown header debug!(target: "sync", "Old block header {:?} ({}) is unknown, restarting sync", hash, number); self.restart(io); return Ok(()); @@ -947,7 +947,10 @@ impl ChainSync { } let chain = io.chain(); let fetch_nonce = |a: &Address| chain.nonce(a); - let _ = self.miner.import_transactions(transactions, fetch_nonce); + let res = self.miner.import_transactions(transactions, fetch_nonce); + if res.is_ok() { + self.miner.update_sealing(io.chain()); + } Ok(()) } @@ -1287,7 +1290,7 @@ impl ChainSync { } pub fn chain_new_head(&mut self, io: &mut SyncIo) { - self.miner.prepare_sealing(io.chain()); + self.miner.update_sealing(io.chain()); } } From 0621da85358e908fc703f75fc4579548adf1c290 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 17 Mar 2016 13:41:11 +0100 Subject: [PATCH 03/41] ethjson spec submodule --- ethcore/res/ethereum/frontier_like_test.json | 2 +- ethcore/res/ethereum/frontier_test.json | 2 +- json/src/hash.rs | 4 + json/src/lib.rs.in | 1 + json/src/spec/account.rs | 44 ++++++++++ json/src/spec/builtin.rs | 47 +++++++++++ json/src/spec/genesis.rs | 67 ++++++++++++++++ json/src/spec/mod.rs | 29 +++++++ json/src/spec/params.rs | 74 +++++++++++++++++ json/src/spec/spec.rs | 84 ++++++++++++++++++++ 10 files changed, 352 insertions(+), 2 deletions(-) create mode 100644 json/src/spec/account.rs create mode 100644 json/src/spec/builtin.rs create mode 100644 json/src/spec/genesis.rs create mode 100644 json/src/spec/mod.rs create mode 100644 json/src/spec/params.rs create mode 100644 json/src/spec/spec.rs diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index 3e4108566..ebfbc2383 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -1,5 +1,5 @@ { - "engineName": "Frontier (Test)", + "name": "Frontier (Test)", "engineName": "Ethash", "params": { "accountStartNonce": "0x00", diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index 8ee1cafd9..227ad1bc3 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -1,5 +1,5 @@ { - "engineName": "Frontier (Test)", + "name": "Frontier (Test)", "engineName": "Ethash", "params": { "accountStartNonce": "0x00", diff --git a/json/src/hash.rs b/json/src/hash.rs index 098f2e7a8..bece68011 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -46,6 +46,10 @@ macro_rules! impl_hash { fn visit_str(&mut self, value: &str) -> Result where E: Error { let value = match value.len() { 0 => $inner::from(0), + 2 if value == "0x" => $inner::from(0), + _ if value.starts_with("0x") => try!($inner::from_str(&value[2..]).map_err(|_| { + Error::custom(format!("Invalid hex value {}.", value).as_ref()) + })), _ => try!($inner::from_str(value).map_err(|_| { Error::custom(format!("Invalid hex value {}.", value).as_ref()) })) diff --git a/json/src/lib.rs.in b/json/src/lib.rs.in index 6d3437811..0d85ce569 100644 --- a/json/src/lib.rs.in +++ b/json/src/lib.rs.in @@ -23,3 +23,4 @@ pub mod hash; pub mod uint; pub mod bytes; pub mod blockchain; +pub mod spec; diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs new file mode 100644 index 000000000..8c98f89d9 --- /dev/null +++ b/json/src/spec/account.rs @@ -0,0 +1,44 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Spec account deserialization. + +use uint::Uint; +use spec::builtin::Builtin; + +/// Spec account. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Account { + builtin: Option, + balance: Option, + nonce: Option, +} + +#[cfg(test)] +mod tests { + use serde_json; + use spec::account::Account; + + #[test] + fn account_deserialization() { + let s = r#"{ + "balance": "1", + "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } + }"#; + let _deserialized: Account = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs new file mode 100644 index 000000000..f49367ecb --- /dev/null +++ b/json/src/spec/builtin.rs @@ -0,0 +1,47 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Spec builtin deserialization. + +/// Linear builin options. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Linear { + base: u64, + word: u64, +} + +/// Spec builtin. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Builtin { + name: String, + linear: Linear, +} + +#[cfg(test)] +mod tests { + use serde_json; + use spec::builtin::Builtin; + + #[test] + fn builtin_deserialization() { + let s = r#"{ + "name": "ecrecover", + "linear": { "base": 3000, "word": 0 } + }"#; + let _deserialized: Builtin = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs new file mode 100644 index 000000000..4c66a9e35 --- /dev/null +++ b/json/src/spec/genesis.rs @@ -0,0 +1,67 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Spec genesis deserialization. + +use uint::Uint; +use hash::{Address, H256}; +use bytes::Bytes; + +/// Spec genesis. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Genesis { + // old seal + nonce: Option, + #[serde(rename="mixHash")] + mix_hash: Option, + + // new seal // TODO: consider moving it to a separate seal structure + #[serde(rename="sealFields")] + seal_fields: Option, + #[serde(rename="sealRlp")] + seal_rlp: Option, + + difficulty: Uint, + author: Address, + timestamp: Uint, + #[serde(rename="parentHash")] + parent_hash: H256, + #[serde(rename="gasLimit")] + gas_limit: Uint, +} + +#[cfg(test)] +mod tests { + use serde_json; + use spec::genesis::Genesis; + + #[test] + fn genesis_deserialization() { + let s = r#"{ + "nonce": "0x0000000000000042", + "difficulty": "0x400000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388", + "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" + }"#; + let _deserialized: Genesis = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/spec/mod.rs b/json/src/spec/mod.rs new file mode 100644 index 000000000..8783563d1 --- /dev/null +++ b/json/src/spec/mod.rs @@ -0,0 +1,29 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Spec deserialization. + +pub mod account; +pub mod builtin; +pub mod genesis; +pub mod params; +pub mod spec; + +pub use self::account::Account; +pub use self::builtin::Builtin; +pub use self::genesis::Genesis; +pub use self::params::Params; +pub use self::spec::Spec; diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs new file mode 100644 index 000000000..e55f7fc48 --- /dev/null +++ b/json/src/spec/params.rs @@ -0,0 +1,74 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Spec params deserialization. + +use uint::Uint; +use hash::Address; + +/// Spec params. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Params { + #[serde(rename="accountStartNonce")] + account_start_nonce: Uint, + #[serde(rename="frontierCompatibilityModeLimit")] + frontier_compatibility_mode_limit: Uint, + #[serde(rename="maximumExtraDataSize")] + maximum_extra_data_size: Uint, + #[serde(rename="tieBreakingGas")] + tie_breaking_gas: bool, + #[serde(rename="minGasLimit")] + min_gas_limit: Uint, + #[serde(rename="gasLimitBoundDivisor")] + gas_limit_bound_divisor: Uint, + #[serde(rename="minimumDifficulty")] + minimum_difficulty: Uint, + #[serde(rename="difficultyBoundDivisor")] + difficulty_bound_divisor: Uint, + #[serde(rename="durationLimit")] + duration_limit: Uint, + #[serde(rename="blockReward")] + block_reward: Uint, + registrar: Address, + #[serde(rename="networkID")] + network_id: Uint, +} + +#[cfg(test)] +mod tests { + use serde_json; + use spec::params::Params; + + #[test] + fn params_deserialization() { + let s = r#"{ + "accountStartNonce": "0x00", + "frontierCompatibilityModeLimit": "0x118c30", + "maximumExtraDataSize": "0x20", + "tieBreakingGas": false, + "minGasLimit": "0x1388", + "gasLimitBoundDivisor": "0x0400", + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "networkID" : "0x1" + }"#; + let _deserialized: Params = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs new file mode 100644 index 000000000..79662b19a --- /dev/null +++ b/json/src/spec/spec.rs @@ -0,0 +1,84 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Spec deserialization. + +use std::collections::BTreeMap; +use hash::Address; +use spec::account::Account; +use spec::params::Params; +use spec::genesis::Genesis; + +/// Spec deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Spec { + name: String, + #[serde(rename="engineName")] + engine_name: String, // TODO: consider making it an enum + params: Params, + genesis: Genesis, + accounts: BTreeMap, +} + +#[cfg(test)] +mod tests { + use serde_json; + use spec::spec::Spec; + + #[test] + fn spec_deserialization() { + let s = r#"{ + "name": "Morden", + "engineName": "Ethash", + "params": { + "accountStartNonce": "0x0100000", + "frontierCompatibilityModeLimit": "0x789b0", + "maximumExtraDataSize": "0x20", + "tieBreakingGas": false, + "minGasLimit": "0x1388", + "gasLimitBoundDivisor": "0x0400", + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "registrar": "", + "networkID" : "0x2" + }, + "genesis": { + "nonce": "0x00006d6f7264656e", + "difficulty": "0x20000", + "mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x2fefd8" + }, + "nodes": [ + "enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303" + ], + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } + } + }"#; + let _deserialized: Spec = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} From 0f889d42222dd33bd1dad28dfc25bd1b6165601f Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 17 Mar 2016 14:03:53 +0100 Subject: [PATCH 04/41] added genesis method to ethjson blockchain --- json/src/blockchain/blockchain.rs | 16 ++++++++++ json/src/blockchain/header.rs | 49 +++++++++++++++++++++---------- json/src/hash.rs | 2 +- json/src/spec/genesis.rs | 29 +++++++++++------- json/src/uint.rs | 2 +- 5 files changed, 70 insertions(+), 28 deletions(-) diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs index 8c67799e1..75d321a4d 100644 --- a/json/src/blockchain/blockchain.rs +++ b/json/src/blockchain/blockchain.rs @@ -20,6 +20,7 @@ use bytes::Bytes; use blockchain::state::State; use blockchain::header::Header; use blockchain::block::Block; +use spec::Genesis; /// Blockchain deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -45,6 +46,21 @@ impl BlockChain { pub fn blocks_rlp(&self) -> Vec> { self.blocks.iter().map(|block| block.rlp()).collect() } + + /// Returns spec compatible genesis struct. + pub fn genesis(&self) -> Genesis { + Genesis { + nonce: Some(self.genesis_block.nonce.clone()), + mix_hash: Some(self.genesis_block.mix_hash.clone()), + seal_fields: None, + seal_rlp: None, + difficulty: self.genesis_block.difficulty, + author: self.genesis_block.author.clone(), + timestamp: self.genesis_block.timestamp, + parent_hash: self.genesis_block.parent_hash.clone(), + gas_limit: self.genesis_block.gas_limit, + } + } } #[cfg(test)] diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs index e97039213..f4ebee01b 100644 --- a/json/src/blockchain/header.rs +++ b/json/src/blockchain/header.rs @@ -23,31 +23,48 @@ use bytes::Bytes; /// Blockchain test header deserializer. #[derive(Debug, PartialEq, Deserialize)] pub struct Header { - bloom: Bloom, - coinbase: Address, - difficulty: Uint, + /// Blocks bloom. + pub bloom: Bloom, + /// Blocks author. + #[serde(rename="coinbase")] + pub author: Address, + /// Difficulty. + pub difficulty: Uint, #[serde(rename="extraData")] - extra_data: Bytes, + /// Extra data. + pub extra_data: Bytes, + /// Gas limit. #[serde(rename="gasLimit")] - gas_limit: Uint, + pub gas_limit: Uint, + /// Gas used. #[serde(rename="gasUsed")] - gas_used: Uint, - hash: H256, + pub gas_used: Uint, + /// Hash. + pub hash: H256, #[serde(rename="mixHash")] - mix_hash: H256, - nonce: H64, - number: Uint, + /// Mix hash. + pub mix_hash: H256, + /// Seal nonce. + pub nonce: H64, + /// Block number. + pub number: Uint, + /// Parent hash. #[serde(rename="parentHash")] - parent_hash: H256, + pub parent_hash: H256, + /// Receipt root. #[serde(rename="receiptTrie")] - receipt_trie: H256, + pub receipt_root: H256, + /// State root. #[serde(rename="stateRoot")] - state_root: H256, - timestamp: Uint, + pub state_root: H256, + /// Timestamp. + pub timestamp: Uint, + /// Transactions root. #[serde(rename="transactionsTrie")] - transactions_trie: H256, + pub transactions_root: H256, + /// Uncles hash. #[serde(rename="uncleHash")] - uncle_hash: H256, + pub uncles_hash: H256, } #[cfg(test)] diff --git a/json/src/hash.rs b/json/src/hash.rs index bece68011..c555b6266 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -25,7 +25,7 @@ use util::hash::{H64 as Hash64, Address as Hash160, H256 as Hash256, H2048 as Ha macro_rules! impl_hash { ($name: ident, $inner: ident) => { /// Lenient hash json deserialization for test json files. - #[derive(Default, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] + #[derive(Default, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)] pub struct $name($inner); impl Into<$inner> for $name { diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs index 4c66a9e35..a8b5b30e3 100644 --- a/json/src/spec/genesis.rs +++ b/json/src/spec/genesis.rs @@ -17,30 +17,39 @@ //! Spec genesis deserialization. use uint::Uint; -use hash::{Address, H256}; +use hash::{H64, Address, H256}; use bytes::Bytes; /// Spec genesis. #[derive(Debug, PartialEq, Deserialize)] pub struct Genesis { // old seal - nonce: Option, + /// Seal nonce. + pub nonce: Option, #[serde(rename="mixHash")] - mix_hash: Option, + /// Seal mix hash. + pub mix_hash: Option, // new seal // TODO: consider moving it to a separate seal structure #[serde(rename="sealFields")] - seal_fields: Option, + /// Number of seal fields. + pub seal_fields: Option, #[serde(rename="sealRlp")] - seal_rlp: Option, + /// Seal rlp. + pub seal_rlp: Option, - difficulty: Uint, - author: Address, - timestamp: Uint, + /// Difficulty. + pub difficulty: Uint, + /// Block author. + pub author: Address, + /// Block timestamp. + pub timestamp: Uint, + /// Parent hash. #[serde(rename="parentHash")] - parent_hash: H256, + pub parent_hash: H256, + /// Gas limit. #[serde(rename="gasLimit")] - gas_limit: Uint, + pub gas_limit: Uint, } #[cfg(test)] diff --git a/json/src/uint.rs b/json/src/uint.rs index 41e717277..2d24c3f7e 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -22,7 +22,7 @@ use serde::de::Visitor; use util::numbers::{U256, Uint as U}; /// Lenient uint json deserialization for test json files. -#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] pub struct Uint(U256); impl Into for Uint { From 1f03ae54d69f1982ee6d2f6e82d599aaa9b16817 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 17 Mar 2016 15:15:10 +0100 Subject: [PATCH 05/41] moved ethcores spec to its own module, added genesis --- Cargo.lock | 1 + ethcore/Cargo.toml | 1 + ethcore/src/lib.rs | 1 + ethcore/src/spec/genesis.rs | 91 +++++++++++++++++++++++++++++++ ethcore/src/spec/mod.rs | 22 ++++++++ ethcore/src/{ => spec}/spec.rs | 32 ++++++++++- json/src/blockchain/blockchain.rs | 5 ++ json/src/blockchain/header.rs | 2 +- json/src/spec/genesis.rs | 17 +++++- json/src/uint.rs | 6 ++ 10 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 ethcore/src/spec/genesis.rs create mode 100644 ethcore/src/spec/mod.rs rename ethcore/src/{ => spec}/spec.rs (92%) diff --git a/Cargo.lock b/Cargo.lock index 1a701042e..daf0501ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,6 +216,7 @@ dependencies = [ "ethash 1.1.0", "ethcore-devtools 1.1.0", "ethcore-util 1.1.0", + "ethjson 0.1.0", "heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 1d16cc34a..cf75949f1 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -21,6 +21,7 @@ clippy = { version = "0.0.50", optional = true } crossbeam = "0.1.5" lazy_static = "0.1" ethcore-devtools = { path = "../devtools" } +ethjson = { path = "../json" } [features] jit = ["evmjit"] diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 572cda2fa..662dea641 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -83,6 +83,7 @@ extern crate time; extern crate env_logger; extern crate num_cpus; extern crate crossbeam; +extern crate ethjson; #[cfg(test)] extern crate ethcore_devtools as devtools; #[cfg(feature = "jit" )] extern crate evmjit; diff --git a/ethcore/src/spec/genesis.rs b/ethcore/src/spec/genesis.rs new file mode 100644 index 000000000..686e8f6d1 --- /dev/null +++ b/ethcore/src/spec/genesis.rs @@ -0,0 +1,91 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use util::rlp::*; +use util::numbers::{Uint, U256}; +use util::hash::{H64, Address, H256}; +use ethjson; + +/// Genesis seal type. +pub enum Seal { + /// Classic ethereum seal. + Ethereum { + /// Seal nonce. + nonce: H64, + /// Seal mix hash. + mix_hash: H256, + }, + /// Generic seal. + Generic { + /// Number of seal fields. + fields: usize, + /// Seal rlp. + rlp: Vec, + }, +} + +/// Genesis components. +pub struct Genesis { + /// Seal. + pub seal: Seal, + /// Difficulty. + pub difficulty: U256, + /// Author. + pub author: Address, + /// Timestamp. + pub timestamp: u64, + /// Parent hash. + pub parent_hash: H256, + /// Gas limit. + pub gas_limit: U256, + /// Transactions root. + pub transactions_root: H256, + /// Receipts root. + pub receipts_root: H256, + /// State root. + pub state_root: Option, + /// Gas used. + pub gas_used: U256, + /// Extra data. + pub extra_data: Vec, +} + +impl From for Genesis { + fn from(g: ethjson::spec::Genesis) -> Self { + Genesis { + seal: match (g.nonce, g.mix_hash) { + (Some(nonce), Some(mix_hash)) => Seal::Ethereum { + nonce: nonce.into(), + mix_hash: mix_hash.into(), + }, + _ => Seal::Generic { + fields: g.seal_fields.unwrap(), + rlp: g.seal_rlp.unwrap().into(), + } + }, + difficulty: g.difficulty.into(), + author: g.author.into(), + timestamp: g.timestamp.into(), + parent_hash: g.parent_hash.into(), + gas_limit: g.gas_limit.into(), + transactions_root: g.transactions_root.map_or_else(|| SHA3_NULL_RLP.clone(), Into::into), + receipts_root: g.receipts_root.map_or_else(|| SHA3_NULL_RLP.clone(), Into::into), + state_root: g.state_root.map(Into::into), + gas_used: g.gas_used.map_or_else(U256::zero, Into::into), + extra_data: g.extra_data.map_or_else(Vec::new, Into::into), + } + } +} diff --git a/ethcore/src/spec/mod.rs b/ethcore/src/spec/mod.rs new file mode 100644 index 000000000..e9c7a0356 --- /dev/null +++ b/ethcore/src/spec/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Blockchain params. + +mod genesis; +pub mod spec; + +pub use self::spec::*; diff --git a/ethcore/src/spec.rs b/ethcore/src/spec/spec.rs similarity index 92% rename from ethcore/src/spec.rs rename to ethcore/src/spec/spec.rs index 2208350cc..c7e2e4e9f 100644 --- a/ethcore/src/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -21,6 +21,8 @@ use engine::*; use pod_state::*; use null_engine::*; use account_db::*; +use ethereum; +use super::genesis::{Seal as GenesisSeal, Genesis}; /// Convert JSON value to equivalent RLP representation. // TODO: handle container types. @@ -106,7 +108,7 @@ impl Spec { pub fn to_engine(self) -> Result, Error> { match self.engine_name.as_ref() { "NullEngine" => Ok(NullEngine::new_boxed(self)), - "Ethash" => Ok(super::ethereum::Ethash::new_boxed(self)), + "Ethash" => Ok(ethereum::Ethash::new_boxed(self)), _ => Err(Error::UnknownEngineName(self.engine_name.clone())) } } @@ -197,6 +199,32 @@ impl Spec { self.state_root_memo = RwLock::new(genesis.find("stateRoot").and_then(|_| Some(H256::from_json(&genesis["stateRoot"])))); } + /// Overwrite the genesis components. + pub fn overwrite_genesis_params(&mut self, g: Genesis) { + let (seal_fields, seal_rlp) = match g.seal { + GenesisSeal::Generic { fields, rlp } => (fields, rlp), + GenesisSeal::Ethereum { nonce, mix_hash } => { + let mut s = RlpStream::new(); + s.append(&mix_hash); + s.append(&nonce); + (2, s.out()) + } + }; + + self.parent_hash = g.parent_hash; + self.transactions_root = g.transactions_root; + self.receipts_root = g.receipts_root; + self.author = g.author; + self.difficulty = g.difficulty; + self.gas_limit = g.gas_limit; + self.gas_used = g.gas_used; + self.timestamp = g.timestamp; + self.extra_data = g.extra_data; + self.seal_fields = seal_fields; + self.seal_rlp = seal_rlp; + self.state_root_memo = RwLock::new(g.state_root); + } + /// Alter the value of the genesis state. pub fn set_genesis_state(&mut self, s: PodState) { self.genesis_state = s; @@ -304,7 +332,7 @@ impl Spec { } /// Create a new Spec which conforms to the Morden chain except that it's a NullEngine consensus. - pub fn new_test() -> Spec { Self::from_json_utf8(include_bytes!("../res/null_morden.json")) } + pub fn new_test() -> Spec { Self::from_json_utf8(include_bytes!("../../res/null_morden.json")) } } #[cfg(test)] diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs index 75d321a4d..d9e879ae9 100644 --- a/json/src/blockchain/blockchain.rs +++ b/json/src/blockchain/blockchain.rs @@ -59,6 +59,11 @@ impl BlockChain { timestamp: self.genesis_block.timestamp, parent_hash: self.genesis_block.parent_hash.clone(), gas_limit: self.genesis_block.gas_limit, + transactions_root: Some(self.genesis_block.transactions_root.clone()), + receipts_root: Some(self.genesis_block.receipts_root.clone()), + state_root: Some(self.genesis_block.state_root.clone()), + gas_used: Some(self.genesis_block.gas_used), + extra_data: Some(self.genesis_block.extra_data.clone()), } } } diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs index f4ebee01b..ece6d6359 100644 --- a/json/src/blockchain/header.rs +++ b/json/src/blockchain/header.rs @@ -53,7 +53,7 @@ pub struct Header { pub parent_hash: H256, /// Receipt root. #[serde(rename="receiptTrie")] - pub receipt_root: H256, + pub receipts_root: H256, /// State root. #[serde(rename="stateRoot")] pub state_root: H256, diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs index a8b5b30e3..a2b484397 100644 --- a/json/src/spec/genesis.rs +++ b/json/src/spec/genesis.rs @@ -33,7 +33,7 @@ pub struct Genesis { // new seal // TODO: consider moving it to a separate seal structure #[serde(rename="sealFields")] /// Number of seal fields. - pub seal_fields: Option, + pub seal_fields: Option, #[serde(rename="sealRlp")] /// Seal rlp. pub seal_rlp: Option, @@ -50,6 +50,21 @@ pub struct Genesis { /// Gas limit. #[serde(rename="gasLimit")] pub gas_limit: Uint, + /// Transactions root. + #[serde(rename="transactionsRoot")] + pub transactions_root: Option, + /// Receipts root. + #[serde(rename="receiptsRoot")] + pub receipts_root: Option, + /// State root. + #[serde(rename="stateRoot")] + pub state_root: Option, + /// Gas used. + #[serde(rename="gasUsed")] + pub gas_used: Option, + /// Extra data. + #[serde(rename="extraData")] + pub extra_data: Option, } #[cfg(test)] diff --git a/json/src/uint.rs b/json/src/uint.rs index 2d24c3f7e..f6eae80e4 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -31,6 +31,12 @@ impl Into for Uint { } } +impl Into for Uint { + fn into(self) -> u64 { + u64::from(self.0) + } +} + impl Deserialize for Uint { fn deserialize(deserializer: &mut D) -> Result where D: Deserializer { From c695b83e52329a4f0cca8a53e482ab4bb295b307 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 17 Mar 2016 15:51:40 +0100 Subject: [PATCH 06/41] new way of loading PodState --- ethcore/src/lib.rs | 2 +- ethcore/src/pod_account.rs | 16 ++++++++++++++++ ethcore/src/pod_state.rs | 14 +++++++++++++- ethcore/src/spec/mod.rs | 1 + json/src/blockchain/account.rs | 17 +++++++++++------ json/src/blockchain/blockchain.rs | 15 ++++++++++----- json/src/blockchain/state.rs | 4 ++-- parity/rpctest.rs | 12 ++++++++++++ 8 files changed, 66 insertions(+), 15 deletions(-) diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 662dea641..dfa321639 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -101,13 +101,13 @@ pub mod spec; pub mod transaction; pub mod views; pub mod receipt; +pub mod pod_state; mod common; mod basic_types; #[macro_use] mod evm; mod env_info; mod pod_account; -mod pod_state; mod account_diff; mod state_diff; mod engine; diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index d2690051c..8f38326ca 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -17,6 +17,7 @@ use util::*; use account::*; use account_db::*; +use ethjson; #[derive(Debug,Clone,PartialEq,Eq)] /// An account, expressed as Plain-Old-Data (hence the name). @@ -73,6 +74,21 @@ impl PodAccount { } } +impl From for PodAccount { + fn from(a: ethjson::blockchain::Account) -> Self { + PodAccount { + balance: a.balance.into(), + nonce: a.nonce.into(), + code: a.code.into(), + storage: a.storage.into_iter().fold(BTreeMap::new(), |mut acc, (key, value)| { + let key: U256 = key.into(); + acc.insert(H256::from(key), value.into()); + acc + }) + } + } +} + impl fmt::Display for PodAccount { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "(bal={}; nonce={}; code={} bytes, #{}; storage={} items)", self.balance, self.nonce, self.code.len(), self.code.sha3(), self.storage.len()) diff --git a/ethcore/src/pod_state.rs b/ethcore/src/pod_state.rs index b873249ac..5782803ef 100644 --- a/ethcore/src/pod_state.rs +++ b/ethcore/src/pod_state.rs @@ -14,11 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! State of all accounts in the system expressed in Plain Old Data. + use util::*; use pod_account::*; +use ethjson; -#[derive(Debug,Clone,PartialEq,Eq,Default)] /// State of all accounts in the system expressed in Plain Old Data. +#[derive(Debug,Clone,PartialEq,Eq,Default)] pub struct PodState (BTreeMap); impl PodState { @@ -64,6 +67,15 @@ impl FromJson for PodState { } } +impl From for PodState { + fn from(s: ethjson::blockchain::State) -> PodState { + PodState(s.0.into_iter().fold(BTreeMap::new(), |mut acc, (key, value)| { + acc.insert(key.into(), PodAccount::from(value)); + acc + })) + } +} + impl fmt::Display for PodState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for (add, acc) in &self.0 { diff --git a/ethcore/src/spec/mod.rs b/ethcore/src/spec/mod.rs index e9c7a0356..b85165d89 100644 --- a/ethcore/src/spec/mod.rs +++ b/ethcore/src/spec/mod.rs @@ -20,3 +20,4 @@ mod genesis; pub mod spec; pub use self::spec::*; +pub use self::genesis::Genesis; diff --git a/json/src/blockchain/account.rs b/json/src/blockchain/account.rs index eb6f0a1dd..990c024c7 100644 --- a/json/src/blockchain/account.rs +++ b/json/src/blockchain/account.rs @@ -19,14 +19,19 @@ use std::collections::BTreeMap; use uint::Uint; use bytes::Bytes; +use hash::H256; /// Blockchain test account deserializer. -#[derive(Debug, PartialEq, Deserialize)] +#[derive(Debug, PartialEq, Deserialize, Clone)] pub struct Account { - balance: Uint, - code: Bytes, - nonce: Uint, - storage: BTreeMap, + /// Balance. + pub balance: Uint, + /// Code. + pub code: Bytes, + /// Nonce. + pub nonce: Uint, + /// Storage. + pub storage: BTreeMap, } #[cfg(test)] @@ -35,7 +40,7 @@ mod tests { use blockchain::account::Account; #[test] - fn header_deserialization() { + fn account_deserialization() { let s = r#"{ "balance" : "0x09184e72a078", "code" : "0x600140600155", diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs index d9e879ae9..4783819e5 100644 --- a/json/src/blockchain/blockchain.rs +++ b/json/src/blockchain/blockchain.rs @@ -25,15 +25,20 @@ use spec::Genesis; /// Blockchain deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct BlockChain { + /// Genesis block header. #[serde(rename="genesisBlockHeader")] - genesis_block: Header, + pub genesis_block: Header, + /// Genesis block rlp. #[serde(rename="genesisRLP")] - genesis_rlp: Bytes, - blocks: Vec, + pub genesis_rlp: Bytes, + /// Blocks. + pub blocks: Vec, + /// Post state. #[serde(rename="postState")] - post_state: State, + pub post_state: State, + /// Pre state. #[serde(rename="pre")] - pre_state: State, + pub pre_state: State, } impl BlockChain { diff --git a/json/src/blockchain/state.rs b/json/src/blockchain/state.rs index 2af0dbf21..51e77e95e 100644 --- a/json/src/blockchain/state.rs +++ b/json/src/blockchain/state.rs @@ -22,8 +22,8 @@ use hash::Address; use blockchain::account::Account; /// Blockchain test state deserializer. -#[derive(Debug, PartialEq, Deserialize)] -pub struct State(BTreeMap); +#[derive(Debug, PartialEq, Deserialize, Clone)] +pub struct State(pub BTreeMap); impl Deref for State { type Target = BTreeMap; diff --git a/parity/rpctest.rs b/parity/rpctest.rs index 182f6dfed..ca12eed93 100644 --- a/parity/rpctest.rs +++ b/parity/rpctest.rs @@ -18,11 +18,15 @@ extern crate docopt; extern crate rustc_serialize; extern crate serde_json; extern crate ethjson; +extern crate ethcore; use std::process; use std::fs::File; use std::path::Path; use docopt::Docopt; +use ethcore::spec::Genesis; +use ethcore::pod_state::PodState; +use ethcore::ethereum; const USAGE: &'static str = r#" Parity rpctest client. @@ -70,7 +74,15 @@ impl Configuration { process::exit(3); }); + let genesis = Genesis::from(blockchain.genesis()); + let state = PodState::from(blockchain.pre_state.clone()); + let mut spec = ethereum::new_frontier_test(); + spec.set_genesis_state(state); + spec.overwrite_genesis_params(genesis); + assert!(spec.is_state_root_valid()); + //let temp = RandomTempPath::new(); + //spec. } } From 7ae60056b21e9ca42c3b977af995f6f365a2072b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 17 Mar 2016 15:49:29 +0100 Subject: [PATCH 07/41] Common error handling --- ethcore/src/error.rs | 4 ++++ miner/src/lib.rs | 2 +- miner/src/miner.rs | 2 +- miner/src/transaction_queue.rs | 28 +++++++++++++++------------- rpc/src/v1/impls/eth.rs | 2 +- sync/src/chain.rs | 3 ++- 6 files changed, 24 insertions(+), 17 deletions(-) diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 482a8de01..1b01ec9c9 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -65,6 +65,10 @@ pub enum ExecutionError { #[derive(Debug)] /// Errors concerning transaction processing. pub enum TransactionError { + /// Transaction is already imported to the queue + AlreadyImported, + /// Transaction is not valid anymore (state already has higher nonce) + Old, /// Transaction's gas price is below threshold. InsufficientGasPrice { /// Minimal expected gas price diff --git a/miner/src/lib.rs b/miner/src/lib.rs index c70caad66..b79a13e24 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -79,7 +79,7 @@ pub trait MinerService : Send + Sync { fn status(&self) -> MinerStatus; /// Imports transactions to transaction queue. - fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Result<(), Error> + fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails; /// Returns hashes of transactions currently in pending diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 9d3613085..865bad10c 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -128,7 +128,7 @@ impl MinerService for Miner { } } - fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Result<(), Error> + fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { let mut transaction_queue = self.transaction_queue.lock().unwrap(); transaction_queue.add_all(transactions, fetch_account) diff --git a/miner/src/transaction_queue.rs b/miner/src/transaction_queue.rs index a1fc20b0f..b34cee6f5 100644 --- a/miner/src/transaction_queue.rs +++ b/miner/src/transaction_queue.rs @@ -317,12 +317,12 @@ impl TransactionQueue { } /// Adds all signed transactions to queue to be verified and imported - pub fn add_all(&mut self, txs: Vec, fetch_account: T) -> Result<(), Error> + pub fn add_all(&mut self, txs: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { - for tx in txs.into_iter() { - try!(self.add(tx, &fetch_account)); - } - Ok(()) + + txs.into_iter() + .map(|tx| self.add(tx, &fetch_account)) + .collect() } /// Add signed transaction to queue to be verified and imported @@ -357,8 +357,7 @@ impl TransactionQueue { })); } - self.import_tx(vtx, account.nonce); - Ok(()) + self.import_tx(vtx, account.nonce).map_err(Error::Transaction) } /// Removes all transactions identified by hashes given in slice @@ -515,12 +514,14 @@ impl TransactionQueue { /// /// It ignores transactions that has already been imported (same `hash`) and replaces the transaction /// iff `(address, nonce)` is the same but `gas_price` is higher. - fn import_tx(&mut self, tx: VerifiedTransaction, state_nonce: U256) { + /// + /// Returns `true` when transaction was imported successfuly + fn import_tx(&mut self, tx: VerifiedTransaction, state_nonce: U256) -> Result<(), TransactionError> { if self.by_hash.get(&tx.hash()).is_some() { // Transaction is already imported. trace!(target: "miner", "Dropping already imported transaction: {:?}", tx.hash()); - return; + return Err(TransactionError::AlreadyImported); } @@ -537,11 +538,11 @@ impl TransactionQueue { // We have a gap - put to future Self::replace_transaction(tx, next_nonce, &mut self.future, &mut self.by_hash); self.future.enforce_limit(&mut self.by_hash); - return; + return Ok(()); } else if nonce < state_nonce { // Droping transaction trace!(target: "miner", "Dropping old transaction: {:?} (nonce: {} < {})", tx.hash(), nonce, next_nonce); - return; + return Err(TransactionError::Old); } Self::replace_transaction(tx, state_nonce, &mut self.current, &mut self.by_hash); @@ -551,6 +552,7 @@ impl TransactionQueue { self.current.enforce_limit(&mut self.by_hash); trace!(target: "miner", "status: {:?}", self.status()); + Ok(()) } /// Replaces transaction in given set (could be `future` or `current`). @@ -952,7 +954,7 @@ mod test { let fetch_last_nonce = |_a: &Address| AccountDetails{ nonce: last_nonce, balance: !U256::zero() }; // when - txq.add(tx, &fetch_last_nonce).unwrap(); + txq.add(tx, &fetch_last_nonce).unwrap_err(); // then let stats = txq.status(); @@ -972,7 +974,7 @@ mod test { assert_eq!(txq.status().pending, 0); // when - txq.add(tx2.clone(), &nonce).unwrap(); + txq.add(tx2.clone(), &nonce).unwrap_err(); // then let stats = txq.status(); diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 7ecfb86de..5cd1b2966 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -385,7 +385,7 @@ impl Eth for EthClient nonce: client.nonce(a), balance: client.balance(a), }); - match import { + match import.into_iter().collect::, _>>() { Ok(_) => to_value(&hash), Err(e) => { warn!("Error sending transaction: {:?}", e); diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 8e8d4623c..044de613c 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -951,7 +951,8 @@ impl ChainSync { balance: chain.balance(a), }; let res = self.miner.import_transactions(transactions, fetch_account); - if res.is_ok() { + let any_transaction_imported = res.into_iter().any(|r| r.is_ok()); + if any_transaction_imported { self.miner.update_sealing(io.chain()); } Ok(()) From 2dc314f99373d68beb4fb0f7f10003de28aca48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 17 Mar 2016 17:19:46 +0100 Subject: [PATCH 08/41] Removing update_seal when new transactions arrives --- rpc/src/v1/tests/helpers/miner_service.rs | 2 +- sync/src/chain.rs | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index ca4151ba7..ad9dcaedd 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -48,7 +48,7 @@ impl MinerService for TestMinerService { } /// Imports transactions to transaction queue. - fn import_transactions(&self, _transactions: Vec, _fetch_account: T) -> Result<(), Error> + fn import_transactions(&self, _transactions: Vec, _fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { unimplemented!(); } /// Returns hashes of transactions currently in pending diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 044de613c..1d87e5e20 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -950,11 +950,7 @@ impl ChainSync { nonce: chain.nonce(a), balance: chain.balance(a), }; - let res = self.miner.import_transactions(transactions, fetch_account); - let any_transaction_imported = res.into_iter().any(|r| r.is_ok()); - if any_transaction_imported { - self.miner.update_sealing(io.chain()); - } + let _ = self.miner.import_transactions(transactions, fetch_account); Ok(()) } From 3e6d0602ea86fb664f2704a97aea5f452ed6bfbf Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 17 Mar 2016 23:58:30 +0100 Subject: [PATCH 09/41] running rpc tests --- parity/rpctest.rs | 57 ++++++++++++++++++++++++++++++++++++++--- rpc/src/v1/mod.rs | 3 +-- rpc/src/v1/tests/mod.rs | 6 ++++- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/parity/rpctest.rs b/parity/rpctest.rs index ca12eed93..d972a779e 100644 --- a/parity/rpctest.rs +++ b/parity/rpctest.rs @@ -14,19 +14,32 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +extern crate ctrlc; extern crate docopt; extern crate rustc_serialize; extern crate serde_json; extern crate ethjson; +extern crate ethcore_util as util; extern crate ethcore; +extern crate ethcore_devtools as devtools; +extern crate ethcore_rpc as rpc; +use std::collections::HashMap; +use std::sync::{Arc, Mutex, Condvar}; use std::process; use std::fs::File; use std::path::Path; use docopt::Docopt; +use ctrlc::CtrlC; use ethcore::spec::Genesis; use ethcore::pod_state::PodState; use ethcore::ethereum; +use ethcore::client::{BlockChainClient, Client, ClientConfig}; +use devtools::RandomTempPath; +use util::io::IoChannel; +use rpc::v1::tests::helpers::{TestSyncProvider, Config as SyncConfig, TestMinerService, TestAccountProvider}; +use rpc::v1::{Eth, EthClient}; +use util::panics::MayPanic; const USAGE: &'static str = r#" Parity rpctest client. @@ -34,13 +47,22 @@ Parity rpctest client. Copyright 2015, 2016 Ethcore (UK) Limited Usage: - parity --json --name + parity --json --name [options] + parity --help + +Options: + --jsonrpc-addr HOST Specify the hostname portion of the JSONRPC API + server [default: 127.0.0.1]. + --jsonrpc-port PORT Specify the port portion of the JSONRPC API server + [default: 8545]. "#; #[derive(Debug, RustcDecodable)] struct Args { arg_test_file: String, arg_test_name: String, + flag_jsonrpc_addr: String, + flag_jsonrpc_port: u16, } struct Configuration { @@ -81,8 +103,37 @@ impl Configuration { spec.overwrite_genesis_params(genesis); assert!(spec.is_state_root_valid()); - //let temp = RandomTempPath::new(); - //spec. + let temp = RandomTempPath::new(); + { + let client: Arc = Client::new(ClientConfig::default(), spec, temp.as_path(), IoChannel::disconnected()).unwrap(); + for b in &blockchain.blocks_rlp() { + let _ = client.import_block(b.clone()); + client.flush_queue(); + client.import_verified_blocks(&IoChannel::disconnected()); + } + let sync = Arc::new(TestSyncProvider::new(SyncConfig { + protocol_version: 65, + num_peers: 120 + })); + + let miner = Arc::new(TestMinerService::default()); + let accounts = Arc::new(TestAccountProvider::new(HashMap::new())); + let server = rpc::RpcServer::new(); + server.add_delegate(EthClient::new(&client, &sync, &accounts, &miner).to_delegate()); + + let url = format!("{}:{}", self.args.flag_jsonrpc_addr, self.args.flag_jsonrpc_port); + let panic_handler = server.start_http(url.as_ref(), "*", 1); + let exit = Arc::new(Condvar::new()); + + let e = exit.clone(); + CtrlC::set_handler(move || { e.notify_all(); }); + + let e = exit.clone(); + panic_handler.on_panic(move |_reason| { e.notify_all(); }); + + let mutex = Mutex::new(()); + let _ = exit.wait(mutex.lock().unwrap()).unwrap(); + } } } diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index b82a20e89..c81f58156 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -23,8 +23,7 @@ mod impls; mod types; mod helpers; -#[cfg(test)] -mod tests; +pub mod tests; pub use self::traits::{Web3, Eth, EthFilter, Personal, Net}; pub use self::impls::*; diff --git a/rpc/src/v1/tests/mod.rs b/rpc/src/v1/tests/mod.rs index 21085a0fd..7a6340ce1 100644 --- a/rpc/src/v1/tests/mod.rs +++ b/rpc/src/v1/tests/mod.rs @@ -16,8 +16,12 @@ //!TODO: load custom blockchain state and test +pub mod helpers; +#[cfg(test)] mod eth; +#[cfg(test)] mod net; +#[cfg(test)] mod web3; -mod helpers; +#[cfg(test)] mod personal; From 0dc1ddef9a3620509a7dde77e0d966226522fc5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 18 Mar 2016 13:59:11 +0100 Subject: [PATCH 10/41] Flipping sealing_enabled flag after no requests for sealing_block for some time --- ethcore/src/client/test_client.rs | 6 ++-- miner/src/miner.rs | 58 +++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 83511b1cc..f5c54b705 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -218,11 +218,11 @@ impl BlockChainClient for TestBlockChainClient { } fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec) -> Option { - unimplemented!() + None } - fn try_seal(&self, _block: ClosedBlock, _seal: Vec) -> Result { - unimplemented!() + fn try_seal(&self, block: ClosedBlock, _seal: Vec) -> Result { + Err(block) } fn block_header(&self, id: BlockId) -> Option { diff --git a/miner/src/miner.rs b/miner/src/miner.rs index dc1f9bcff..e90473600 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -34,6 +34,7 @@ pub struct Miner { // for sealing... sealing_enabled: AtomicBool, + sealing_block_last_request: Mutex, sealing_block: Mutex>, gas_floor_target: RwLock, author: RwLock
, @@ -46,6 +47,7 @@ impl Default for Miner { Miner { transaction_queue: Mutex::new(TransactionQueue::new()), sealing_enabled: AtomicBool::new(false), + sealing_block_last_request: Mutex::new(0), sealing_block: Mutex::new(None), gas_floor_target: RwLock::new(U256::zero()), author: RwLock::new(Address::default()), @@ -110,6 +112,8 @@ impl Miner { } } +const SEALING_TIMEOUT_IN_BLOCKS : u64 = 5; + impl MinerService for Miner { fn clear_and_reset(&self, chain: &BlockChainClient) { @@ -139,7 +143,17 @@ impl MinerService for Miner { } fn update_sealing(&self, chain: &BlockChainClient) { - if self.sealing_enabled.load(atomic::Ordering::Relaxed) { + let should_disable_sealing = { + let current_no = chain.chain_info().best_block_number; + let last_request = self.sealing_block_last_request.lock().unwrap(); + + current_no - *last_request > SEALING_TIMEOUT_IN_BLOCKS + }; + + if should_disable_sealing { + self.sealing_enabled.store(false, atomic::Ordering::Relaxed); + *self.sealing_block.lock().unwrap() = None; + } else if self.sealing_enabled.load(atomic::Ordering::Relaxed) { self.prepare_sealing(chain); } } @@ -147,9 +161,10 @@ impl MinerService for Miner { fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex> { if self.sealing_block.lock().unwrap().is_none() { self.sealing_enabled.store(true, atomic::Ordering::Relaxed); - // TODO: Above should be on a timer that resets after two blocks have arrived without being asked for. + self.prepare_sealing(chain); } + *self.sealing_block_last_request.lock().unwrap() = chain.chain_info().best_block_number; &self.sealing_block } @@ -228,3 +243,42 @@ impl MinerService for Miner { self.update_sealing(chain); } } + +#[cfg(test)] +mod tests { + + use MinerService; + use super::{Miner}; + use ethcore::client::{TestBlockChainClient, EachBlockWith}; + + // TODO [ToDr] To uncomment client is cleaned from mining stuff. + #[ignore] + #[test] + fn should_prepare_block_to_seal() { + // given + let client = TestBlockChainClient::default(); + let miner = Miner::default(); + + // when + let res = miner.sealing_block(&client); + + // then + assert!(res.lock().unwrap().is_some(), "Expected closed block"); + } + + #[test] + fn should_reset_seal_after_couple_of_blocks() { + // given + let client = TestBlockChainClient::default(); + let miner = Miner::default(); + let res = miner.sealing_block(&client); + // TODO [ToDr] Uncomment after fixing TestBlockChainClient + // assert!(res.lock().unwrap().is_some(), "Expected closed block"); + + // when + client.add_blocks(10, EachBlockWith::Uncle); + + // then + assert!(res.lock().unwrap().is_none(), "Expected to remove sealed block"); + } +} From ae3e6d7fe8214755f8a77540e635ae529008b452 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 18:08:28 +0100 Subject: [PATCH 11/41] fixed name of rpctest executable in rpctest --help --- parity/rpctest.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parity/rpctest.rs b/parity/rpctest.rs index d972a779e..fc4e2983f 100644 --- a/parity/rpctest.rs +++ b/parity/rpctest.rs @@ -47,8 +47,8 @@ Parity rpctest client. Copyright 2015, 2016 Ethcore (UK) Limited Usage: - parity --json --name [options] - parity --help + rpctest --json --name [options] + rpctest --help Options: --jsonrpc-addr HOST Specify the hostname portion of the JSONRPC API From 79b8dd829d07cccf644b96db76a03a6770d7d8ff Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 18:16:22 +0100 Subject: [PATCH 12/41] fixed compilation with --release flag --- parity/rpctest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/rpctest.rs b/parity/rpctest.rs index fc4e2983f..4fd31b134 100644 --- a/parity/rpctest.rs +++ b/parity/rpctest.rs @@ -36,7 +36,7 @@ use ethcore::pod_state::PodState; use ethcore::ethereum; use ethcore::client::{BlockChainClient, Client, ClientConfig}; use devtools::RandomTempPath; -use util::io::IoChannel; +use util::IoChannel; use rpc::v1::tests::helpers::{TestSyncProvider, Config as SyncConfig, TestMinerService, TestAccountProvider}; use rpc::v1::{Eth, EthClient}; use util::panics::MayPanic; From 3b8c6a1ab2df30580c6f627c8b7dcc7e5f6454e9 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 19:08:57 +0100 Subject: [PATCH 13/41] linear -> pricing --- ethcore/res/ethereum/frontier.json | 8 +++---- ethcore/res/ethereum/frontier_like_test.json | 8 +++---- ethcore/res/ethereum/frontier_test.json | 8 +++---- ethcore/res/ethereum/homestead_test.json | 8 +++---- ethcore/res/ethereum/morden.json | 8 +++---- ethcore/res/ethereum/olympic.json | 8 +++---- ethcore/res/null_morden.json | 8 +++---- json/src/spec/account.rs | 2 +- json/src/spec/builtin.rs | 23 +++++++++++++++++--- json/src/spec/spec.rs | 8 +++---- 10 files changed, 53 insertions(+), 36 deletions(-) diff --git a/ethcore/res/ethereum/frontier.json b/ethcore/res/ethereum/frontier.json index cd66ad3f1..7a1662d8c 100644 --- a/ethcore/res/ethereum/frontier.json +++ b/ethcore/res/ethereum/frontier.json @@ -33,10 +33,10 @@ "enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@parity-node-zero.ethcore.io:30303" ], "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { "balance": "1337000000000000000000" }, diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index ebfbc2383..803e593be 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -26,9 +26,9 @@ "gasLimit": "0x1388" }, "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } } + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } } } } diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index 227ad1bc3..f1a75881a 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -26,9 +26,9 @@ "gasLimit": "0x1388" }, "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } } + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } } } } diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index 1fb5dff80..8f13eb042 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -26,9 +26,9 @@ "gasLimit": "0x1388" }, "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } } + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } } } } diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index e9f8e0e99..a5230acf4 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -29,10 +29,10 @@ "enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303" ], "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } } diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index b3dfc1ed8..872877429 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -26,10 +26,10 @@ "gasLimit": "0x2fefd8" }, "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, "e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, "b9c015918bdaba24b4ff057a92a3873d6eb201be": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, diff --git a/ethcore/res/null_morden.json b/ethcore/res/null_morden.json index 46507ff95..49795c337 100644 --- a/ethcore/res/null_morden.json +++ b/ethcore/res/null_morden.json @@ -26,10 +26,10 @@ "gasLimit": "0x2fefd8" }, "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } } diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs index 8c98f89d9..f4cce3fc8 100644 --- a/json/src/spec/account.rs +++ b/json/src/spec/account.rs @@ -36,7 +36,7 @@ mod tests { fn account_deserialization() { let s = r#"{ "balance": "1", - "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } + "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }"#; let _deserialized: Account = serde_json::from_str(s).unwrap(); // TODO: validate all fields diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index f49367ecb..24f83b1d6 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -16,18 +16,35 @@ //! Spec builtin deserialization. -/// Linear builin options. +use serde::de::{Deserialize, Deserializer}; + +/// Linear pricing. #[derive(Debug, PartialEq, Deserialize)] pub struct Linear { base: u64, word: u64, } +/// Pricing variants. +#[derive(Debug, PartialEq)] +pub enum Pricing { + /// Linear pricing. + Linear(Linear), +} + +impl Deserialize for Pricing { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + Deserialize::deserialize(deserializer).map(Pricing::Linear) + } +} + + /// Spec builtin. #[derive(Debug, PartialEq, Deserialize)] pub struct Builtin { name: String, - linear: Linear, + pricing: Pricing, } #[cfg(test)] @@ -39,7 +56,7 @@ mod tests { fn builtin_deserialization() { let s = r#"{ "name": "ecrecover", - "linear": { "base": 3000, "word": 0 } + "pricing": { "base": 3000, "word": 0 } }"#; let _deserialized: Builtin = serde_json::from_str(s).unwrap(); // TODO: validate all fields diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index 79662b19a..0d17d0829 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -71,10 +71,10 @@ mod tests { "enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303" ], "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } }"#; From 1c9cc6167db33d507fdd3413fc44057573aeb486 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 19:16:46 +0100 Subject: [PATCH 14/41] updated rpc helpers docs --- rpc/src/v1/tests/helpers/account_provider.rs | 3 +++ rpc/src/v1/tests/helpers/external_miner.rs | 1 + rpc/src/v1/tests/helpers/miner_service.rs | 5 +++++ rpc/src/v1/tests/helpers/sync_provider.rs | 7 +++++++ 4 files changed, 16 insertions(+) diff --git a/rpc/src/v1/tests/helpers/account_provider.rs b/rpc/src/v1/tests/helpers/account_provider.rs index ce5b76b44..9cbf853ae 100644 --- a/rpc/src/v1/tests/helpers/account_provider.rs +++ b/rpc/src/v1/tests/helpers/account_provider.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Test implementation of account provider. + use std::sync::RwLock; use std::collections::HashMap; use std::io; @@ -42,6 +44,7 @@ impl TestAccount { /// Test account provider. pub struct TestAccountProvider { accounts: RwLock>, + /// Added accounts passwords. pub adds: RwLock>, } diff --git a/rpc/src/v1/tests/helpers/external_miner.rs b/rpc/src/v1/tests/helpers/external_miner.rs index a5111b302..ef3714440 100644 --- a/rpc/src/v1/tests/helpers/external_miner.rs +++ b/rpc/src/v1/tests/helpers/external_miner.rs @@ -26,6 +26,7 @@ pub struct TestExternalMiner { } impl TestExternalMiner { + /// Creates new external miner. pub fn new(hashrates: Arc>>) -> Self { TestExternalMiner { hashrates: hashrates, diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 44b94ac14..bc8d35f46 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Test implementation of miner service. + use util::{Address, H256, Bytes}; use util::standard::*; use ethcore::error::Error; @@ -22,8 +24,11 @@ use ethcore::block::ClosedBlock; use ethcore::transaction::SignedTransaction; use ethminer::{MinerService, MinerStatus, AccountDetails}; +/// Test miner service. pub struct TestMinerService { + /// Imported transactions. pub imported_transactions: RwLock>, + /// Latest closed block. pub latest_closed_block: Mutex>, } diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index 5b4b5b099..222c4c7b9 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -14,15 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Test implementation of SyncProvider. + use ethsync::{SyncProvider, SyncStatus, SyncState}; use std::sync::{RwLock}; +/// TestSyncProvider config. pub struct Config { + /// Protocol version. pub protocol_version: u8, + /// Number of peers. pub num_peers: usize, } +/// Test sync provider. pub struct TestSyncProvider { + /// Sync status. pub status: RwLock, } From 839cecd2daae568276f82422ae50149cc254917e Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 19:31:31 +0100 Subject: [PATCH 15/41] fixed od builting parsing --- ethcore/src/builtin.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index 5589a2525..fbf123ec7 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -19,7 +19,7 @@ use crypto::sha2::Sha256; use crypto::ripemd160::Ripemd160; use crypto::digest::Digest; -/// Definition of a contract whose implementation is built-in. +/// Definition of a contract whose implementation is built-in. pub struct Builtin { /// The gas cost of running this built-in for the given size of input data. pub cost: Box U256>, // TODO: U256 should be bignum. @@ -63,11 +63,11 @@ impl Builtin { /// Create a builtin from JSON. /// - /// JSON must be of the form `{ "name": "identity", "linear": {"base": 10, "word": 20} }`. + /// JSON must be of the form `{ "name": "identity", "pricing": {"base": 10, "word": 20} }`. pub fn from_json(json: &Json) -> Option { // NICE: figure out a more convenient means of handing errors here. if let Json::String(ref name) = json["name"] { - if let Json::Object(ref o) = json["linear"] { + if let Json::Object(ref o) = json["pricing"] { if let Json::U64(ref word) = o["word"] { if let Json::U64(ref base) = o["base"] { return Self::from_named_linear(&name[..], *base as usize, *word as usize); From e4ec80941c171a6687c63b6e23e8fb7eaf74c48b Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 20:17:25 +0100 Subject: [PATCH 16/41] fixed failing builin test --- ethcore/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index fbf123ec7..0e857335e 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -274,7 +274,7 @@ fn from_named_linear() { #[test] fn from_json() { - let text = "{ \"name\": \"identity\", \"linear\": {\"base\": 10, \"word\": 20} }"; + let text = "{ \"name\": \"identity\", \"pricing\": {\"base\": 10, \"word\": 20} }"; let json = Json::from_str(text).unwrap(); let b = Builtin::from_json(&json).unwrap(); assert_eq!((*b.cost)(0), U256::from(10)); From 48be70e4a8789152f764449a6de574fbc0d93245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 18 Mar 2016 20:45:07 +0100 Subject: [PATCH 17/41] Fixing ethminer doctest --- miner/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/miner/src/lib.rs b/miner/src/lib.rs index b79a13e24..ca25e3993 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -45,7 +45,6 @@ //! assert_eq!(miner.status().transactions_in_pending_queue, 0); //! //! // Check block for sealing -//! miner.prepare_sealing(client.deref()); //! assert!(miner.sealing_block(client.deref()).lock().unwrap().is_some()); //! } //! ``` From 79aa8570d0fd6f3293a21fe54a9a9892312efba3 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 22:54:36 +0100 Subject: [PATCH 18/41] pricing { linear: {} } --- ethcore/res/ethereum/frontier.json | 8 ++++---- ethcore/res/ethereum/frontier_like_test.json | 8 ++++---- ethcore/res/ethereum/frontier_test.json | 8 ++++---- ethcore/res/ethereum/homestead_test.json | 8 ++++---- ethcore/res/ethereum/morden.json | 8 ++++---- ethcore/res/ethereum/olympic.json | 8 ++++---- ethcore/res/null_morden.json | 8 ++++---- ethcore/src/builtin.rs | 10 ++++++---- json/src/spec/account.rs | 2 +- json/src/spec/builtin.rs | 15 +++------------ json/src/spec/spec.rs | 8 ++++---- 11 files changed, 42 insertions(+), 49 deletions(-) diff --git a/ethcore/res/ethereum/frontier.json b/ethcore/res/ethereum/frontier.json index 7a1662d8c..8f9209179 100644 --- a/ethcore/res/ethereum/frontier.json +++ b/ethcore/res/ethereum/frontier.json @@ -33,10 +33,10 @@ "enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@parity-node-zero.ethcore.io:30303" ], "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { "balance": "1337000000000000000000" }, diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index 803e593be..49b39cde7 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -26,9 +26,9 @@ "gasLimit": "0x1388" }, "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } } + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, } } diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index f1a75881a..79f47b2e6 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -26,9 +26,9 @@ "gasLimit": "0x1388" }, "accounts": { - "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } } + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, } } diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index 8f13eb042..0f0e630dd 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -26,9 +26,9 @@ "gasLimit": "0x1388" }, "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } } + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } } } diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index a5230acf4..2cf4785db 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -29,10 +29,10 @@ "enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303" ], "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } } diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index 872877429..365a8167c 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -26,10 +26,10 @@ "gasLimit": "0x2fefd8" }, "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, "e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, "b9c015918bdaba24b4ff057a92a3873d6eb201be": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, diff --git a/ethcore/res/null_morden.json b/ethcore/res/null_morden.json index 49795c337..70b48fbdb 100644 --- a/ethcore/res/null_morden.json +++ b/ethcore/res/null_morden.json @@ -26,10 +26,10 @@ "gasLimit": "0x2fefd8" }, "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } } diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index 0e857335e..2ee8e24b1 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -68,9 +68,11 @@ impl Builtin { // NICE: figure out a more convenient means of handing errors here. if let Json::String(ref name) = json["name"] { if let Json::Object(ref o) = json["pricing"] { - if let Json::U64(ref word) = o["word"] { - if let Json::U64(ref base) = o["base"] { - return Self::from_named_linear(&name[..], *base as usize, *word as usize); + if let Json::Object(ref o) = o["linear"] { + if let Json::U64(ref word) = o["word"] { + if let Json::U64(ref base) = o["base"] { + return Self::from_named_linear(&name[..], *base as usize, *word as usize); + } } } } @@ -274,7 +276,7 @@ fn from_named_linear() { #[test] fn from_json() { - let text = "{ \"name\": \"identity\", \"pricing\": {\"base\": 10, \"word\": 20} }"; + let text = r#"{"name": "identity", "pricing": {"linear": {"base": 10, "word": 20}}}"#; let json = Json::from_str(text).unwrap(); let b = Builtin::from_json(&json).unwrap(); assert_eq!((*b.cost)(0), U256::from(10)); diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs index f4cce3fc8..1440b1bdc 100644 --- a/json/src/spec/account.rs +++ b/json/src/spec/account.rs @@ -36,7 +36,7 @@ mod tests { fn account_deserialization() { let s = r#"{ "balance": "1", - "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } + "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }"#; let _deserialized: Account = serde_json::from_str(s).unwrap(); // TODO: validate all fields diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index 24f83b1d6..21f8a2ac1 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -16,8 +16,6 @@ //! Spec builtin deserialization. -use serde::de::{Deserialize, Deserializer}; - /// Linear pricing. #[derive(Debug, PartialEq, Deserialize)] pub struct Linear { @@ -26,20 +24,13 @@ pub struct Linear { } /// Pricing variants. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Deserialize)] pub enum Pricing { /// Linear pricing. + #[serde(rename="linear")] Linear(Linear), } -impl Deserialize for Pricing { - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer { - Deserialize::deserialize(deserializer).map(Pricing::Linear) - } -} - - /// Spec builtin. #[derive(Debug, PartialEq, Deserialize)] pub struct Builtin { @@ -56,7 +47,7 @@ mod tests { fn builtin_deserialization() { let s = r#"{ "name": "ecrecover", - "pricing": { "base": 3000, "word": 0 } + "pricing": { "linear": { "base": 3000, "word": 0 } } }"#; let _deserialized: Builtin = serde_json::from_str(s).unwrap(); // TODO: validate all fields diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index 0d17d0829..2dd4ac486 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -71,10 +71,10 @@ mod tests { "enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303" ], "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } }"#; From ef297dbec7ef35cbc3a8d853a2adbbc299e07a04 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 22:57:26 +0100 Subject: [PATCH 19/41] removed warnings by adding missing documentation --- rpc/src/v1/tests/helpers/account_provider.rs | 1 + rpc/src/v1/tests/helpers/external_miner.rs | 1 + rpc/src/v1/tests/helpers/mod.rs | 2 ++ rpc/src/v1/tests/helpers/sync_provider.rs | 1 + 4 files changed, 5 insertions(+) diff --git a/rpc/src/v1/tests/helpers/account_provider.rs b/rpc/src/v1/tests/helpers/account_provider.rs index 9cbf853ae..614aba346 100644 --- a/rpc/src/v1/tests/helpers/account_provider.rs +++ b/rpc/src/v1/tests/helpers/account_provider.rs @@ -33,6 +33,7 @@ pub struct TestAccount { } impl TestAccount { + /// Creates new test account. pub fn new(password: &str) -> Self { TestAccount { unlocked: false, diff --git a/rpc/src/v1/tests/helpers/external_miner.rs b/rpc/src/v1/tests/helpers/external_miner.rs index ef3714440..1799c36c5 100644 --- a/rpc/src/v1/tests/helpers/external_miner.rs +++ b/rpc/src/v1/tests/helpers/external_miner.rs @@ -22,6 +22,7 @@ use v1::helpers::ExternalMinerService; /// Test ExternalMinerService; pub struct TestExternalMiner { + /// External miners hashrates. pub hashrates: Arc>> } diff --git a/rpc/src/v1/tests/helpers/mod.rs b/rpc/src/v1/tests/helpers/mod.rs index fc652e7d6..c9db61f6d 100644 --- a/rpc/src/v1/tests/helpers/mod.rs +++ b/rpc/src/v1/tests/helpers/mod.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +//! Test rpc services. + mod account_provider; mod sync_provider; mod miner_service; diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index 222c4c7b9..48b4f55a9 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -34,6 +34,7 @@ pub struct TestSyncProvider { } impl TestSyncProvider { + /// Creates new sync provider. pub fn new(config: Config) -> Self { TestSyncProvider { status: RwLock::new(SyncStatus { From a76aad2e1218017881f94db8f2ddc73240027cd8 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 18 Mar 2016 23:56:51 +0100 Subject: [PATCH 20/41] fixed invalid json files --- ethcore/res/ethereum/frontier_like_test.json | 2 +- ethcore/res/ethereum/frontier_test.json | 2 +- ethcore/res/ethereum/olympic.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index 49b39cde7..376b369c4 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -29,6 +29,6 @@ "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } } } diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index 79f47b2e6..92e8f5877 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -29,6 +29,6 @@ "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } } } diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index 365a8167c..0cc2e6a57 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -29,7 +29,7 @@ "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, "e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, "b9c015918bdaba24b4ff057a92a3873d6eb201be": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, From 906e9b395ec3739db3b3ce11ba6e54f46499a9c8 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 11:02:44 +0100 Subject: [PATCH 21/41] fixed parsing blockchain file, added default account to rpc tests --- ethcore/src/pod_account.rs | 3 ++- json/src/blockchain/account.rs | 2 +- parity/rpctest.rs | 10 +++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index 8f38326ca..387679da9 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -82,7 +82,8 @@ impl From for PodAccount { code: a.code.into(), storage: a.storage.into_iter().fold(BTreeMap::new(), |mut acc, (key, value)| { let key: U256 = key.into(); - acc.insert(H256::from(key), value.into()); + let value: U256 = value.into(); + acc.insert(H256::from(key), H256::from(value)); acc }) } diff --git a/json/src/blockchain/account.rs b/json/src/blockchain/account.rs index 990c024c7..1c51f2b74 100644 --- a/json/src/blockchain/account.rs +++ b/json/src/blockchain/account.rs @@ -31,7 +31,7 @@ pub struct Account { /// Nonce. pub nonce: Uint, /// Storage. - pub storage: BTreeMap, + pub storage: BTreeMap, } #[cfg(test)] diff --git a/parity/rpctest.rs b/parity/rpctest.rs index 4fd31b134..dba188474 100644 --- a/parity/rpctest.rs +++ b/parity/rpctest.rs @@ -37,9 +37,10 @@ use ethcore::ethereum; use ethcore::client::{BlockChainClient, Client, ClientConfig}; use devtools::RandomTempPath; use util::IoChannel; -use rpc::v1::tests::helpers::{TestSyncProvider, Config as SyncConfig, TestMinerService, TestAccountProvider}; +use rpc::v1::tests::helpers::{TestSyncProvider, Config as SyncConfig, TestMinerService, TestAccountProvider, TestAccount}; use rpc::v1::{Eth, EthClient}; use util::panics::MayPanic; +use util::hash::Address; const USAGE: &'static str = r#" Parity rpctest client. @@ -86,8 +87,9 @@ impl Configuration { process::exit(1); }); - let tests: ethjson::blockchain::Test = serde_json::from_reader(file).unwrap_or_else(|_| { + let tests: ethjson::blockchain::Test = serde_json::from_reader(file).unwrap_or_else(|err| { println!("Invalid json file."); + println!("{:?}", err); process::exit(2); }); @@ -117,7 +119,9 @@ impl Configuration { })); let miner = Arc::new(TestMinerService::default()); - let accounts = Arc::new(TestAccountProvider::new(HashMap::new())); + let mut accs = HashMap::new(); + accs.insert(Address::from(1), TestAccount::new("test")); + let accounts = Arc::new(TestAccountProvider::new(accs)); let server = rpc::RpcServer::new(); server.add_delegate(EthClient::new(&client, &sync, &accounts, &miner).to_delegate()); From 52dbcd8152d30b260442e3db6750112d3b4b32cf Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 11:44:36 +0100 Subject: [PATCH 22/41] rpc tests, now 421 passing / 116 failing --- rpc/src/v1/impls/eth.rs | 3 ++- rpc/src/v1/types/block.rs | 6 ++++-- rpc/src/v1/types/bytes.rs | 9 +-------- rpc/src/v1/types/transaction.rs | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 5cd1b2966..2306f937d 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -103,6 +103,7 @@ impl EthClient timestamp: U256::from(view.timestamp()), difficulty: view.difficulty(), total_difficulty: total_difficulty, + nonce: view.seal().get(1).map_or_else(H64::zero, |r| H64::from_slice(r)), uncles: vec![], transactions: { if include_txs { @@ -111,7 +112,7 @@ impl EthClient BlockTransactions::Hashes(block_view.transaction_hashes()) } }, - extra_data: Bytes::default() + extra_data: Bytes::new(view.extra_data()) }; to_value(&block) }, diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index 2457efcf8..a7b75a561 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -63,6 +63,7 @@ pub struct Block { pub difficulty: U256, #[serde(rename="totalDifficulty")] pub total_difficulty: U256, + pub nonce: H64, pub uncles: Vec, pub transactions: BlockTransactions } @@ -78,7 +79,7 @@ mod tests { fn test_serialize_block_transactions() { let t = BlockTransactions::Full(vec![Transaction::default()]); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x00"}]"#); + assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x"}]"#); let t = BlockTransactions::Hashes(vec![H256::default()]); let serialized = serde_json::to_string(&t).unwrap(); @@ -104,11 +105,12 @@ mod tests { timestamp: U256::default(), difficulty: U256::default(), total_difficulty: U256::default(), + nonce: H64::default(), uncles: vec![], transactions: BlockTransactions::Hashes(vec![]) }; let serialized = serde_json::to_string(&block).unwrap(); - assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","author":"0x0000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","number":"0x00","gasUsed":"0x00","gasLimit":"0x00","extraData":"0x00","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x00","difficulty":"0x00","totalDifficulty":"0x00","uncles":[],"transactions":[]}"#); + assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","author":"0x0000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","number":"0x00","gasUsed":"0x00","gasLimit":"0x00","extraData":"0x","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x00","difficulty":"0x00","totalDifficulty":"0x00","nonce":"0x0000000000000000","uncles":[],"transactions":[]}"#); } } diff --git a/rpc/src/v1/types/bytes.rs b/rpc/src/v1/types/bytes.rs index 0b14c30e8..8c47806f8 100644 --- a/rpc/src/v1/types/bytes.rs +++ b/rpc/src/v1/types/bytes.rs @@ -20,7 +20,7 @@ use serde::de::Visitor; use util::common::FromHex; /// Wrapper structure around vector of bytes. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default)] pub struct Bytes(Vec); impl Bytes { @@ -31,13 +31,6 @@ impl Bytes { pub fn to_vec(self) -> Vec { let Bytes(x) = self; x } } -impl Default for Bytes { - fn default() -> Self { - // default serialized value is 0x00 - Bytes(vec![0]) - } -} - impl Serialize for Bytes { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 232cf0bf3..d809d19b4 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -67,7 +67,7 @@ mod tests { fn test_transaction_serialize() { let t = Transaction::default(); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x00"}"#); + assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x"}"#); } } From e5c6579a8cc2eb083aa0128095d0c458be36468a Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 12:23:48 +0100 Subject: [PATCH 23/41] next batch of rpc fixes, 103 still failing --- parity/rpctest.rs | 3 ++- rpc/src/v1/impls/eth.rs | 18 +++++++++--------- rpc/src/v1/tests/helpers/miner_service.rs | 2 +- rpc/src/v1/types/block.rs | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/parity/rpctest.rs b/parity/rpctest.rs index dba188474..6cc747959 100644 --- a/parity/rpctest.rs +++ b/parity/rpctest.rs @@ -38,7 +38,7 @@ use ethcore::client::{BlockChainClient, Client, ClientConfig}; use devtools::RandomTempPath; use util::IoChannel; use rpc::v1::tests::helpers::{TestSyncProvider, Config as SyncConfig, TestMinerService, TestAccountProvider, TestAccount}; -use rpc::v1::{Eth, EthClient}; +use rpc::v1::{Eth, EthClient, EthFilter, EthFilterClient}; use util::panics::MayPanic; use util::hash::Address; @@ -124,6 +124,7 @@ impl Configuration { let accounts = Arc::new(TestAccountProvider::new(accs)); let server = rpc::RpcServer::new(); server.add_delegate(EthClient::new(&client, &sync, &accounts, &miner).to_delegate()); + server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate()); let url = format!("{}:{}", self.args.flag_jsonrpc_addr, self.args.flag_jsonrpc_port); let panic_handler = server.start_http(url.as_ref(), "*", 1); diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 2306f937d..9b2588670 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -104,7 +104,7 @@ impl EthClient difficulty: view.difficulty(), total_difficulty: total_difficulty, nonce: view.seal().get(1).map_or_else(H64::zero, |r| H64::from_slice(r)), - uncles: vec![], + uncles: block_view.uncle_hashes(), transactions: { if include_txs { BlockTransactions::Full(block_view.localized_transactions().into_iter().map(From::from).collect()) @@ -230,8 +230,8 @@ impl Eth for EthClient fn block_transaction_count_by_hash(&self, params: Params) -> Result { from_params::<(H256,)>(params) .and_then(|(hash,)| // match - to_value(&take_weak!(self.client).block(BlockId::Hash(hash)) - .map_or_else(U256::zero, |bytes| U256::from(BlockView::new(&bytes).transactions_count())))) + take_weak!(self.client).block(BlockId::Hash(hash)) + .map_or(Ok(Value::Null), |bytes| to_value(&U256::from(BlockView::new(&bytes).transactions_count())))) } fn block_transaction_count_by_number(&self, params: Params) -> Result { @@ -240,24 +240,24 @@ impl Eth for EthClient BlockNumber::Pending => to_value( &U256::from(take_weak!(self.miner).status().transactions_in_pending_block) ), - _ => to_value(&take_weak!(self.client).block(block_number.into()) - .map_or_else(U256::zero, |bytes| U256::from(BlockView::new(&bytes).transactions_count()))) + _ => take_weak!(self.client).block(block_number.into()) + .map_or(Ok(Value::Null), |bytes| to_value(&U256::from(BlockView::new(&bytes).transactions_count()))) }) } fn block_uncles_count_by_hash(&self, params: Params) -> Result { from_params::<(H256,)>(params) .and_then(|(hash,)| - to_value(&take_weak!(self.client).block(BlockId::Hash(hash)) - .map_or_else(U256::zero, |bytes| U256::from(BlockView::new(&bytes).uncles_count())))) + take_weak!(self.client).block(BlockId::Hash(hash)) + .map_or(Ok(Value::Null), |bytes| to_value(&U256::from(BlockView::new(&bytes).uncles_count())))) } fn block_uncles_count_by_number(&self, params: Params) -> Result { from_params::<(BlockNumber,)>(params) .and_then(|(block_number,)| match block_number { BlockNumber::Pending => to_value(&U256::from(0)), - _ => to_value(&take_weak!(self.client).block(block_number.into()) - .map_or_else(U256::zero, |bytes| U256::from(BlockView::new(&bytes).uncles_count()))) + _ => take_weak!(self.client).block(block_number.into()) + .map_or(Ok(Value::Null), |bytes| to_value(&U256::from(BlockView::new(&bytes).uncles_count()))) }) } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 22e210392..7f07341bf 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -57,7 +57,7 @@ impl MinerService for TestMinerService { where T: Fn(&Address) -> AccountDetails { unimplemented!(); } /// Returns hashes of transactions currently in pending - fn pending_transactions_hashes(&self) -> Vec { unimplemented!(); } + fn pending_transactions_hashes(&self) -> Vec { vec![] } /// Removes all transactions from the queue and restart mining operation. fn clear_and_reset(&self, _chain: &BlockChainClient) { unimplemented!(); } diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index a7b75a561..ac334dd2b 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -64,7 +64,7 @@ pub struct Block { #[serde(rename="totalDifficulty")] pub total_difficulty: U256, pub nonce: H64, - pub uncles: Vec, + pub uncles: Vec, pub transactions: BlockTransactions } From 693a3b07398f1bda8ba9c0d024f420ff88bb4e3d Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 12:55:36 +0100 Subject: [PATCH 24/41] fixed failing eth rpc tests --- rpc/src/v1/tests/eth.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 389de103b..a5f318350 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -224,7 +224,7 @@ fn rpc_eth_block_transaction_count_by_hash() { "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#; assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); } @@ -264,7 +264,7 @@ fn rpc_eth_uncle_count_by_block_hash() { "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#; assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); } From bc5df9c90882c9bb3713a998848a85c164d4dc16 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 14:29:09 +0100 Subject: [PATCH 25/41] added output to execution result --- ethcore/src/executive.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 782063cb2..a00d9a85d 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -60,7 +60,9 @@ pub struct Executed { /// eg. sender creates contract A and A in constructor creates contract B /// /// B creation ends first, and it will be the first element of the vector. - pub contracts_created: Vec
+ pub contracts_created: Vec
, + /// Transaction output. + pub output: Bytes, } /// Transaction execution result. @@ -145,7 +147,7 @@ impl<'a> Executive<'a> { let mut substate = Substate::new(); - let res = match t.action { + let (gas_left, output) = match t.action { Action::Create => { let new_address = contract_address(&sender, &nonce); let params = ActionParams { @@ -159,7 +161,7 @@ impl<'a> Executive<'a> { code: Some(t.data.clone()), data: None, }; - self.create(params, &mut substate) + (self.create(params, &mut substate), vec![]) }, Action::Call(ref address) => { let params = ActionParams { @@ -175,12 +177,12 @@ impl<'a> Executive<'a> { }; // TODO: move output upstream let mut out = vec![]; - self.call(params, &mut substate, BytesRef::Flexible(&mut out)) + (self.call(params, &mut substate, BytesRef::Flexible(&mut out)), out) } }; // finalize here! - Ok(try!(self.finalize(t, substate, res))) + Ok(try!(self.finalize(t, substate, gas_left, output))) } fn exec_vm(&mut self, params: ActionParams, unconfirmed_substate: &mut Substate, output_policy: OutputPolicy) -> evm::Result { @@ -286,7 +288,7 @@ impl<'a> Executive<'a> { } /// Finalizes the transaction (does refunds and suicides). - fn finalize(&mut self, t: &SignedTransaction, substate: Substate, result: evm::Result) -> ExecutionResult { + fn finalize(&mut self, t: &SignedTransaction, substate: Substate, result: evm::Result, output: Bytes) -> ExecutionResult { let schedule = self.engine.schedule(self.info); // refunds from SSTORE nonzero -> zero @@ -326,7 +328,8 @@ impl<'a> Executive<'a> { refunded: U256::zero(), cumulative_gas_used: self.info.gas_used + t.gas, logs: vec![], - contracts_created: vec![] + contracts_created: vec![], + output: output, }) }, _ => { @@ -337,6 +340,7 @@ impl<'a> Executive<'a> { cumulative_gas_used: self.info.gas_used + gas_used, logs: substate.logs, contracts_created: substate.contracts_created, + output: output, }) }, } From 2face3f938209c97c2442ba6d8ac9beb02517c36 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 18:13:14 +0100 Subject: [PATCH 26/41] use ethjson module to load chain json tests --- ethcore/src/block.rs | 2 +- ethcore/src/json_tests/chain.rs | 29 ++++++++++++++--------------- ethcore/src/pod_state.rs | 2 +- json/src/blockchain/account.rs | 1 - json/src/blockchain/block.rs | 6 +++--- json/src/blockchain/blockchain.rs | 11 +++++------ json/src/blockchain/test.rs | 10 ++++++++++ json/src/bytes.rs | 8 ++------ 8 files changed, 36 insertions(+), 33 deletions(-) diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index d4aa35445..e53cbfd61 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -438,7 +438,7 @@ mod tests { open_block.push_uncle(uncle1_header).unwrap(); open_block.push_uncle(uncle2_header).unwrap(); let b = open_block.close().seal(engine.deref(), vec![]).unwrap(); - + let orig_bytes = b.rlp_bytes(); let orig_db = b.drain(); diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 89bd5da2b..5e2d51594 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -16,18 +16,18 @@ use super::test_common::*; use client::{BlockChainClient, Client, ClientConfig}; -use pod_state::*; use block::Block; use ethereum; use tests::helpers::*; use devtools::*; +use spec::Genesis; pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { init_log(); - let json = Json::from_str(::std::str::from_utf8(json_data).unwrap()).expect("Json is invalid"); + let tests = ethjson::blockchain::Test.load(json_data).unwrap(); let mut failed = Vec::new(); - for (name, test) in json.as_object().unwrap() { + for (name, blockchain) in tests.deref() { let mut fail = false; { let mut fail_unless = |cond: bool| if !cond && !fail { @@ -39,37 +39,36 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { flush!(" - {}...", name); - let blocks: Vec<(Bytes, bool)> = test["blocks"].as_array().unwrap().iter().map(|e| (xjson!(&e["rlp"]), e.find("blockHeader").is_some())).collect(); let mut spec = match era { ChainEra::Frontier => ethereum::new_frontier_test(), ChainEra::Homestead => ethereum::new_homestead_test(), }; - let s = PodState::from_json(test.find("pre").unwrap()); - spec.set_genesis_state(s); - spec.overwrite_genesis(test.find("genesisBlockHeader").unwrap()); + + let genesis = Genesis::from(blockchain.genesis()); + let state = From::from(blockchain.pre_state.clone()); + spec.set_genesis_state(state); + spec.overwrite_genesis_params(genesis); 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(ClientConfig::default(), 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() { + for b in &blockchain.blocks_rlp() { if Block::is_good(&b) { let _ = client.import_block(b.clone()); + client.flush_queue(); + client.import_verified_blocks(&IoChannel::disconnected()); } - client.flush_queue(); - let imported_ok = client.import_verified_blocks(&IoChannel::disconnected()) > 0; - assert_eq!(imported_ok, is_valid); } - fail_unless(client.chain_info().best_block_hash == H256::from_json(&test["lastblockhash"])); + fail_unless(client.chain_info().best_block_hash == blockchain.best_block.clone().into()); } } + if !fail { flushln!("ok"); } } + println!("!!! {:?} tests from failed.", failed.len()); failed } diff --git a/ethcore/src/pod_state.rs b/ethcore/src/pod_state.rs index 5782803ef..7ebfed78b 100644 --- a/ethcore/src/pod_state.rs +++ b/ethcore/src/pod_state.rs @@ -21,7 +21,7 @@ use pod_account::*; use ethjson; /// State of all accounts in the system expressed in Plain Old Data. -#[derive(Debug,Clone,PartialEq,Eq,Default)] +#[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct PodState (BTreeMap); impl PodState { diff --git a/json/src/blockchain/account.rs b/json/src/blockchain/account.rs index 1c51f2b74..ca69409fc 100644 --- a/json/src/blockchain/account.rs +++ b/json/src/blockchain/account.rs @@ -19,7 +19,6 @@ use std::collections::BTreeMap; use uint::Uint; use bytes::Bytes; -use hash::H256; /// Blockchain test account deserializer. #[derive(Debug, PartialEq, Deserialize, Clone)] diff --git a/json/src/blockchain/block.rs b/json/src/blockchain/block.rs index 190102ae5..03522a2c9 100644 --- a/json/src/blockchain/block.rs +++ b/json/src/blockchain/block.rs @@ -24,11 +24,11 @@ use blockchain::transaction::Transaction; #[derive(Debug, PartialEq, Deserialize)] pub struct Block { #[serde(rename="blockHeader")] - header: Header, + header: Option
, rlp: Bytes, - transactions: Vec, + transactions: Option>, #[serde(rename="uncleHeaders")] - uncles: Vec
, + uncles: Option>, } impl Block { diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs index 4783819e5..98392b983 100644 --- a/json/src/blockchain/blockchain.rs +++ b/json/src/blockchain/blockchain.rs @@ -17,6 +17,7 @@ //! Blockchain deserialization. use bytes::Bytes; +use hash::H256; use blockchain::state::State; use blockchain::header::Header; use blockchain::block::Block; @@ -30,7 +31,7 @@ pub struct BlockChain { pub genesis_block: Header, /// Genesis block rlp. #[serde(rename="genesisRLP")] - pub genesis_rlp: Bytes, + pub genesis_rlp: Option, /// Blocks. pub blocks: Vec, /// Post state. @@ -39,14 +40,12 @@ pub struct BlockChain { /// Pre state. #[serde(rename="pre")] pub pre_state: State, + /// Hash of best block. + #[serde(rename="lastblockhash")] + pub best_block: H256 } impl BlockChain { - /// Returns genesis block rlp. - pub fn genesis_rlp(&self) -> Vec { - self.genesis_rlp.clone().into() - } - /// Returns blocks rlp. pub fn blocks_rlp(&self) -> Vec> { self.blocks.iter().map(|block| block.rlp()).collect() diff --git a/json/src/blockchain/test.rs b/json/src/blockchain/test.rs index 6f48a8bc6..1a6a63a71 100644 --- a/json/src/blockchain/test.rs +++ b/json/src/blockchain/test.rs @@ -18,6 +18,9 @@ use std::collections::BTreeMap; use std::ops::Deref; +use std::io::Read; +use serde_json; +use serde_json::Error; use blockchain::blockchain::BlockChain; /// Blockchain test deserializer. @@ -31,3 +34,10 @@ impl Deref for Test { &self.0 } } + +impl Test { + /// Loads test from json. + pub fn load(reader: R) -> Result where R: Read { + serde_json::from_reader(reader) + } +} diff --git a/json/src/bytes.rs b/json/src/bytes.rs index 061795b40..6ccae51d7 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -46,12 +46,8 @@ impl Visitor for BytesVisitor { let v = match value.len() { 0 => vec![], 2 if value.starts_with("0x") => vec![], - _ if value.starts_with("0x") => try!(FromHex::from_hex(&value[2..]).map_err(|_| { - Error::custom(format!("Invalid hex value {}.", value).as_ref()) - })), - _ => try!(FromHex::from_hex(value).map_err(|_| { - Error::custom(format!("Invalid hex value {}.", value).as_ref()) - })) + _ if value.starts_with("0x") => FromHex::from_hex(&value[2..]).unwrap_or(vec![]), + _ => FromHex::from_hex(value).unwrap_or(vec![]), }; Ok(Bytes(v)) } From 24cb15ef2ea1988bac40085a8cfa364d7a3b5f2e Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 18:38:02 +0100 Subject: [PATCH 27/41] fixed missing import --- ethcore/src/json_tests/chain.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 5e2d51594..a2e6a5659 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -21,10 +21,11 @@ use ethereum; use tests::helpers::*; use devtools::*; use spec::Genesis; +use ethjson; pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { init_log(); - let tests = ethjson::blockchain::Test.load(json_data).unwrap(); + let tests = ethjson::blockchain::Test::load(json_data).unwrap(); let mut failed = Vec::new(); for (name, blockchain) in tests.deref() { From 40f20de7aa22570a2f2f32697d31d284e6326675 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 18:46:28 +0100 Subject: [PATCH 28/41] test ethjson module on travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5d6de65c2..f7ac723e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: global: # GH_TOKEN - secure: bumJASbZSU8bxJ0EyPUJmu16AiV9EXOpyOj86Jlq/Ty9CfwGqsSXt96uDyE+OUJf34RUFQMsw0nk37/zC4lcn6kqk2wpuH3N/o85Zo/cVZY/NusBWLQqtT5VbYWsV+u2Ua4Tmmsw8yVYQhYwU2ZOejNpflL+Cs9XGgORp1L+/gMRMC2y5Se6ZhwnKPQlRJ8LGsG1dzjQULxzADIt3/zuspNBS8a2urJwlHfGMkvHDoUWCviP/GXoSqw3TZR7FmKyxE19I8n9+iSvm9+oZZquvcgfUxMHn8Gq/b44UbPvjtFOg2yam4xdWXF/RyWCHdc/R9EHorSABeCbefIsm+zcUF3/YQxwpSxM4IZEeH2rTiC7dcrsKw3XsO16xFQz5YI5Bay+CT/wTdMmJd7DdYz7Dyf+pOvcM9WOf/zorxYWSBOMYy0uzbusU2iyIghQ82s7E/Ahg+WARtPgkuTLSB5aL1oCTBKHqQscMr7lo5Ti6RpWLxEdTQMBznc+bMr+6dEtkEcG9zqc6cE9XX+ox3wTU6+HVMfQ1ltCntJ4UKcw3A6INEbw9wgocQa812CIASQ2fE+SCAbz6JxBjIAlFUnD1lUB7S8PdMPwn9plfQgKQ2A5YZqg6FnBdf0rQXIJYxQWKHXj/rBHSUCT0tHACDlzTA+EwWggvkP5AGIxRxm8jhw= - - TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer" + - TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer -p ethjson" - ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}" - KCOV_FEATURES="" - KCOV_CMD="./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /usr/,/.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov" @@ -70,6 +70,7 @@ after_success: | $KCOV_CMD target/debug/deps/ethsync-* && $KCOV_CMD target/debug/deps/ethcore_rpc-* && $KCOV_CMD target/debug/deps/ethminer-* && + $KCOV_CMD target/debug/deps/ethjson-* && $KCOV_CMD target/debug/parity-* && [ $TRAVIS_BRANCH = master ] && [ $TRAVIS_PULL_REQUEST = false ] && From da027e93cf8e9c33727bfb1ef7634de517da05e4 Mon Sep 17 00:00:00 2001 From: arkpar Date: Sat, 19 Mar 2016 20:58:42 +0100 Subject: [PATCH 29/41] Auto detect available port --- ethcore/src/service.rs | 2 +- util/src/network/host.rs | 93 +++++++++++++++++++++---------------- util/src/network/mod.rs | 2 +- util/src/network/service.rs | 21 +++++++-- util/src/network/session.rs | 2 +- util/src/network/tests.rs | 20 ++++---- 6 files changed, 80 insertions(+), 60 deletions(-) diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index bcfe7724f..95a891198 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -146,7 +146,7 @@ mod tests { fn it_can_be_started() { let spec = get_test_spec(); let temp_path = RandomTempPath::new(); - let service = ClientService::start(ClientConfig::default(), spec, NetworkConfiguration::new_with_port(40456), &temp_path.as_path()); + let service = ClientService::start(ClientConfig::default(), spec, NetworkConfiguration::new_local(), &temp_path.as_path()); assert!(service.is_ok()); } } diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 02c576424..6baf0cf76 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -105,6 +105,14 @@ impl NetworkConfiguration { config.listen_address = Some(SocketAddr::from_str(&format!("0.0.0.0:{}", port)).unwrap()); config } + + /// Create new default configuration for localhost-only connection with random port (usefull for testing) + pub fn new_local() -> NetworkConfiguration { + let mut config = NetworkConfiguration::new(); + config.listen_address = Some(SocketAddr::from_str("127.0.0.1:0").unwrap()); + config.nat_enabled = false; + config + } } // Tokens @@ -269,12 +277,12 @@ pub struct HostInfo { pub protocol_version: u32, /// Client identifier pub client_version: String, - /// TCP connection port. - pub listen_port: u16, /// Registered capabilities (handlers) pub capabilities: Vec, + /// Local address + discovery port + pub local_endpoint: NodeEndpoint, /// Public address + discovery port - public_endpoint: NodeEndpoint, + pub public_endpoint: Option, } impl HostInfo { @@ -307,7 +315,7 @@ struct ProtocolTimer { /// Root IO handler. Manages protocol handlers, IO timers and network connections. pub struct Host where Message: Send + Sync + Clone { pub info: RwLock, - tcp_listener: Mutex>, + tcp_listener: Mutex, handshakes: Arc>>, sessions: Arc>>, discovery: Mutex>, @@ -321,13 +329,12 @@ pub struct Host where Message: Send + Sync + Clone { impl Host where Message: Send + Sync + Clone { /// Create a new instance - pub fn new(config: NetworkConfiguration) -> Host { - let listen_address = match config.listen_address { + pub fn new(config: NetworkConfiguration) -> Result, UtilError> { + let mut listen_address = match config.listen_address { None => SocketAddr::from_str("0.0.0.0:30304").unwrap(), Some(addr) => addr, }; - let udp_port = config.udp_port.unwrap_or(listen_address.port()); let keys = if let Some(ref secret) = config.use_secret { KeyPair::from_secret(secret.clone()).unwrap() } else { @@ -342,7 +349,12 @@ impl Host where Message: Send + Sync + Clone { |s| KeyPair::from_secret(s).expect("Error creating node secret key")) }; let path = config.config_path.clone(); + // Setup the server socket + let tcp_listener = try!(TcpListener::bind(&listen_address)); + listen_address = SocketAddr::new(listen_address.ip(), try!(tcp_listener.local_addr()).port()); + let udp_port = config.udp_port.unwrap_or(listen_address.port()); let local_endpoint = NodeEndpoint { address: listen_address, udp_port: udp_port }; + let mut host = Host:: { info: RwLock::new(HostInfo { keys: keys, @@ -350,12 +362,12 @@ impl Host where Message: Send + Sync + Clone { nonce: H256::random(), protocol_version: PROTOCOL_VERSION, client_version: version(), - listen_port: 0, capabilities: Vec::new(), - public_endpoint: local_endpoint, // will be replaced by public once it is resolved + public_endpoint: None, + local_endpoint: local_endpoint, }), discovery: Mutex::new(None), - tcp_listener: Mutex::new(None), + tcp_listener: Mutex::new(tcp_listener), handshakes: Arc::new(RwLock::new(Slab::new_starting_at(FIRST_HANDSHAKE, MAX_HANDSHAKES))), sessions: Arc::new(RwLock::new(Slab::new_starting_at(FIRST_SESSION, MAX_SESSIONS))), nodes: RwLock::new(NodeTable::new(path)), @@ -365,14 +377,12 @@ impl Host where Message: Send + Sync + Clone { stats: Arc::new(NetworkStats::default()), pinned_nodes: Vec::new(), }; - let port = listen_address.port(); - host.info.write().unwrap().deref_mut().listen_port = port; let boot_nodes = host.info.read().unwrap().config.boot_nodes.clone(); for n in boot_nodes { host.add_node(&n); } - host + Ok(host) } pub fn stats(&self) -> Arc { @@ -397,50 +407,50 @@ impl Host where Message: Send + Sync + Clone { self.info.read().unwrap().client_version.clone() } - pub fn client_url(&self) -> String { - format!("{}", Node::new(self.info.read().unwrap().id().clone(), self.info.read().unwrap().public_endpoint.clone())) + pub fn external_url(&self) -> Option { + self.info.read().unwrap().public_endpoint.as_ref().map(|e| format!("{}", Node::new(self.info.read().unwrap().id().clone(), e.clone()))) } - fn init_public_interface(&self, io: &IoContext>) { + pub fn local_url(&self) -> String { + let r = format!("{}", Node::new(self.info.read().unwrap().id().clone(), self.info.read().unwrap().local_endpoint.clone())); + println!("{}", r); + r + } + + fn init_public_interface(&self, io: &IoContext>) -> Result<(), UtilError> { io.clear_timer(INIT_PUBLIC).unwrap(); - let mut tcp_listener = self.tcp_listener.lock().unwrap(); - if tcp_listener.is_some() { - return; + if self.info.read().unwrap().public_endpoint.is_some() { + return Ok(()); } - // public_endpoint in host info contains local adderss at this point - let listen_address = self.info.read().unwrap().public_endpoint.address.clone(); - let udp_port = self.info.read().unwrap().config.udp_port.unwrap_or(listen_address.port()); + let local_endpoint = self.info.read().unwrap().local_endpoint.clone(); let public_address = self.info.read().unwrap().config.public_address.clone(); let public_endpoint = match public_address { None => { - let public_address = select_public_address(listen_address.port()); - let local_endpoint = NodeEndpoint { address: public_address, udp_port: udp_port }; + let public_address = select_public_address(local_endpoint.address.port()); + let public_endpoint = NodeEndpoint { address: public_address, udp_port: local_endpoint.udp_port }; if self.info.read().unwrap().config.nat_enabled { match map_external_address(&local_endpoint) { Some(endpoint) => { - info!("NAT mappped to external address {}", endpoint.address); + info!("NAT mapped to external address {}", endpoint.address); endpoint }, - None => local_endpoint + None => public_endpoint } } else { - local_endpoint + public_endpoint } } - Some(addr) => NodeEndpoint { address: addr, udp_port: udp_port } + Some(addr) => NodeEndpoint { address: addr, udp_port: local_endpoint.udp_port } }; - // Setup the server socket - *tcp_listener = Some(TcpListener::bind(&listen_address).unwrap()); - self.info.write().unwrap().public_endpoint = public_endpoint.clone(); - io.register_stream(TCP_ACCEPT).expect("Error registering TCP listener"); - info!("Public node URL: {}", self.client_url()); + self.info.write().unwrap().public_endpoint = Some(public_endpoint.clone()); + info!("Public node URL: {}", self.external_url().unwrap()); // Initialize discovery. let discovery = { let info = self.info.read().unwrap(); if info.config.discovery_enabled && !info.config.pin { - Some(Discovery::new(&info.keys, listen_address.clone(), public_endpoint, DISCOVERY)) + Some(Discovery::new(&info.keys, public_endpoint.address.clone(), public_endpoint, DISCOVERY)) } else { None } }; @@ -454,6 +464,8 @@ impl Host where Message: Send + Sync + Clone { io.register_timer(DISCOVERY_ROUND, 300).expect("Error registering discovery timer"); *self.discovery.lock().unwrap().deref_mut() = Some(discovery); } + try!(io.register_stream(TCP_ACCEPT)); + Ok(()) } fn maintain_network(&self, io: &IoContext>) { @@ -567,7 +579,7 @@ impl Host where Message: Send + Sync + Clone { fn accept(&self, io: &IoContext>) { trace!(target: "network", "Accepting incoming connection"); loop { - let socket = match self.tcp_listener.lock().unwrap().as_ref().unwrap().accept() { + let socket = match self.tcp_listener.lock().unwrap().accept() { Ok(None) => break, Ok(Some((sock, _addr))) => sock, Err(e) => { @@ -861,7 +873,8 @@ impl IoHandler> for Host where Messa fn timeout(&self, io: &IoContext>, token: TimerToken) { match token { IDLE => self.maintain_network(io), - INIT_PUBLIC => self.init_public_interface(io), + INIT_PUBLIC => self.init_public_interface(io).unwrap_or_else(|e| + warn!("Error initializing public interface: {:?}", e)), FIRST_SESSION ... LAST_SESSION => self.connection_timeout(token, io), FIRST_HANDSHAKE ... LAST_HANDSHAKE => self.connection_timeout(token, io), DISCOVERY_REFRESH => { @@ -945,7 +958,7 @@ impl IoHandler> for Host where Messa } } DISCOVERY => self.discovery.lock().unwrap().as_ref().unwrap().register_socket(event_loop).expect("Error registering discovery socket"), - TCP_ACCEPT => event_loop.register(self.tcp_listener.lock().unwrap().as_ref().unwrap(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error registering stream"), + TCP_ACCEPT => event_loop.register(self.tcp_listener.lock().unwrap().deref(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error registering stream"), _ => warn!("Unexpected stream registration") } } @@ -986,7 +999,7 @@ impl IoHandler> for Host where Messa } } DISCOVERY => self.discovery.lock().unwrap().as_ref().unwrap().update_registration(event_loop).expect("Error reregistering discovery socket"), - TCP_ACCEPT => event_loop.reregister(self.tcp_listener.lock().unwrap().as_ref().unwrap(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error reregistering stream"), + TCP_ACCEPT => event_loop.reregister(self.tcp_listener.lock().unwrap().deref(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error reregistering stream"), _ => warn!("Unexpected stream update") } } @@ -1054,6 +1067,6 @@ fn host_client_url() { let mut config = NetworkConfiguration::new(); let key = h256_from_hex("6f7b0d801bc7b5ce7bbd930b84fd0369b3eb25d09be58d64ba811091046f3aa2"); config.use_secret = Some(key); - let host: Host = Host::new(config); - assert!(host.client_url().starts_with("enode://101b3ef5a4ea7a1c7928e24c4c75fd053c235d7b80c22ae5c03d145d0ac7396e2a4ffff9adee3133a7b05044a5cee08115fd65145e5165d646bde371010d803c@")); + let host: Host = Host::new(config).unwrap(); + assert!(host.local_url().starts_with("enode://101b3ef5a4ea7a1c7928e24c4c75fd053c235d7b80c22ae5c03d145d0ac7396e2a4ffff9adee3133a7b05044a5cee08115fd65145e5165d646bde371010d803c@")); } diff --git a/util/src/network/mod.rs b/util/src/network/mod.rs index 50645f2be..29f3d166c 100644 --- a/util/src/network/mod.rs +++ b/util/src/network/mod.rs @@ -56,7 +56,7 @@ //! } //! //! fn main () { -//! let mut service = NetworkService::::start(NetworkConfiguration::new_with_port(40412)).expect("Error creating network service"); +//! let mut service = NetworkService::::start(NetworkConfiguration::new_local()).expect("Error creating network service"); //! service.register_protocol(Arc::new(MyHandler), "myproto", &[1u8]); //! //! // Wait for quit condition diff --git a/util/src/network/service.rs b/util/src/network/service.rs index 7b9388e85..49957f7e7 100644 --- a/util/src/network/service.rs +++ b/util/src/network/service.rs @@ -28,6 +28,7 @@ use io::*; pub struct NetworkService where Message: Send + Sync + Clone + 'static { io_service: IoService>, host_info: String, + host: Arc>, stats: Arc, panic_handler: Arc } @@ -39,15 +40,16 @@ impl NetworkService where Message: Send + Sync + Clone + 'stat let mut io_service = try!(IoService::>::start()); panic_handler.forward_from(&io_service); - let host = Arc::new(Host::new(config)); + let host = Arc::new(try!(Host::new(config))); let stats = host.stats().clone(); let host_info = host.client_version(); - try!(io_service.register_handler(host)); + try!(io_service.register_handler(host.clone())); Ok(NetworkService { io_service: io_service, host_info: host_info, stats: stats, - panic_handler: panic_handler + panic_handler: panic_handler, + host: host, }) } @@ -71,12 +73,21 @@ impl NetworkService where Message: Send + Sync + Clone + 'stat &mut self.io_service } - /// Returns underlying io service. + /// Returns network statistics. pub fn stats(&self) -> &NetworkStats { &self.stats } -} + /// Returns external url if available. + pub fn external_url(&self) -> Option { + self.host.external_url() + } + + /// Returns external url if available. + pub fn local_url(&self) -> String { + self.host.local_url() + } +} impl MayPanic for NetworkService where Message: Send + Sync + Clone + 'static { fn on_panic(&self, closure: F) where F: OnPanicListener { diff --git a/util/src/network/session.rs b/util/src/network/session.rs index 2f30d7376..7dbcc4229 100644 --- a/util/src/network/session.rs +++ b/util/src/network/session.rs @@ -315,7 +315,7 @@ impl Session { .append(&host.protocol_version) .append(&host.client_version) .append(&host.capabilities) - .append(&host.listen_port) + .append(&host.local_endpoint.address.port()) .append(host.id()); self.connection.send_packet(&rlp.out()) } diff --git a/util/src/network/tests.rs b/util/src/network/tests.rs index f8ef588f6..0493475ce 100644 --- a/util/src/network/tests.rs +++ b/util/src/network/tests.rs @@ -97,21 +97,19 @@ impl NetworkProtocolHandler for TestProtocol { #[test] fn net_service() { - let mut service = NetworkService::::start(NetworkConfiguration::new_with_port(40414)).expect("Error creating network service"); + let mut service = NetworkService::::start(NetworkConfiguration::new_local()).expect("Error creating network service"); service.register_protocol(Arc::new(TestProtocol::new(false)), "myproto", &[1u8]).unwrap(); } #[test] fn net_connect() { let key1 = KeyPair::create().unwrap(); - let mut config1 = NetworkConfiguration::new_with_port(30354); + let mut config1 = NetworkConfiguration::new_local(); config1.use_secret = Some(key1.secret().clone()); - config1.nat_enabled = false; config1.boot_nodes = vec![ ]; - let mut config2 = NetworkConfiguration::new_with_port(30355); - config2.boot_nodes = vec![ format!("enode://{}@127.0.0.1:30354", key1.public().hex()) ]; - config2.nat_enabled = false; let mut service1 = NetworkService::::start(config1).unwrap(); + let mut config2 = NetworkConfiguration::new_local(); + config2.boot_nodes = vec![ service1.local_url() ]; let mut service2 = NetworkService::::start(config2).unwrap(); let handler1 = TestProtocol::register(&mut service1, false); let handler2 = TestProtocol::register(&mut service2, false); @@ -125,14 +123,12 @@ fn net_connect() { #[test] fn net_disconnect() { let key1 = KeyPair::create().unwrap(); - let mut config1 = NetworkConfiguration::new_with_port(30364); + let mut config1 = NetworkConfiguration::new_local(); config1.use_secret = Some(key1.secret().clone()); - config1.nat_enabled = false; config1.boot_nodes = vec![ ]; - let mut config2 = NetworkConfiguration::new_with_port(30365); - config2.boot_nodes = vec![ format!("enode://{}@127.0.0.1:30364", key1.public().hex()) ]; - config2.nat_enabled = false; let mut service1 = NetworkService::::start(config1).unwrap(); + let mut config2 = NetworkConfiguration::new_local(); + config2.boot_nodes = vec![ service1.local_url() ]; let mut service2 = NetworkService::::start(config2).unwrap(); let handler1 = TestProtocol::register(&mut service1, false); let handler2 = TestProtocol::register(&mut service2, true); @@ -145,7 +141,7 @@ fn net_disconnect() { #[test] fn net_timeout() { - let config = NetworkConfiguration::new_with_port(30346); + let config = NetworkConfiguration::new_local(); let mut service = NetworkService::::start(config).unwrap(); let handler = TestProtocol::register(&mut service, false); while !handler.got_timeout() { From 521f2a14331e60b0f40f4cd64b31b3b2fada7665 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 21:37:11 +0100 Subject: [PATCH 30/41] implemented eth_call --- ethcore/src/client/client.rs | 25 +++++++++++++++++++++++++ ethcore/src/client/mod.rs | 5 ++++- ethcore/src/client/test_client.rs | 6 ++++++ ethcore/src/views.rs | 3 +++ rpc/src/v1/impls/eth.rs | 20 ++++++++++++++++++++ util/bigint/src/uint.rs | 11 +++++++++++ 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index c62364dce..a0538d8de 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -37,6 +37,8 @@ use log_entry::LocalizedLogEntry; use block_queue::{BlockQueue, BlockQueueInfo}; use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute}; use client::{BlockId, TransactionId, ClientConfig, BlockChainClient}; +use env_info::EnvInfo; +use executive::{Executive, Executed}; pub use blockchain::CacheSize as BlockChainCacheSize; /// General block status @@ -385,6 +387,29 @@ impl Client where V: Verifier { } impl BlockChainClient for Client where V: Verifier { + fn call(&self, t: &SignedTransaction) -> Result { + let header = self.block_header(BlockId::Latest).unwrap(); + let view = HeaderView::new(&header); + let last_hashes = self.build_last_hashes(view.hash()); + let env_info = EnvInfo { + number: view.number(), + author: view.author(), + timestamp: view.timestamp(), + difficulty: view.difficulty(), + last_hashes: last_hashes, + gas_used: U256::zero(), + gas_limit: U256::max_value(), + }; + // that's just a copy of the state. + let mut state = self.state(); + let sender = try!(t.sender()); + let balance = state.balance(&sender); + // give the sender max balance + state.sub_balance(&sender, &balance); + state.add_balance(&sender, &U256::max_value()); + Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t) + } + // TODO [todr] Should be moved to miner crate eventually. fn try_seal(&self, block: ClosedBlock, seal: Vec) -> Result { block.try_seal(self.engine.deref().deref(), seal) diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 198e918f7..4a3208eb8 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -37,7 +37,8 @@ use header::BlockNumber; use transaction::{LocalizedTransaction, SignedTransaction}; use log_entry::LocalizedLogEntry; use filter::Filter; -use error::{ImportResult}; +use error::{ImportResult, Error}; +use executive::Executed; /// Blockchain database client. Owns and manages a blockchain and a block queue. pub trait BlockChainClient : Sync + Send { @@ -118,5 +119,7 @@ pub trait BlockChainClient : Sync + Send { /// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error. fn try_seal(&self, block: ClosedBlock, seal: Vec) -> Result; + /// Makes a non-persistent transaction call. + fn call(&self, t: &SignedTransaction) -> Result; } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 9150a5f55..5d51368de 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -29,6 +29,8 @@ use error::{ImportResult}; use block_queue::BlockQueueInfo; use block::{SealedBlock, ClosedBlock}; +use executive::Executed; +use error::Error; /// Test client. pub struct TestBlockChainClient { @@ -182,6 +184,10 @@ impl TestBlockChainClient { } impl BlockChainClient for TestBlockChainClient { + fn call(&self, t: &SignedTransaction) -> Result { + unimplemented!() + } + fn block_total_difficulty(&self, _id: BlockId) -> Option { Some(U256::zero()) } diff --git a/ethcore/src/views.rs b/ethcore/src/views.rs index 745cbff2c..11e26eb5f 100644 --- a/ethcore/src/views.rs +++ b/ethcore/src/views.rs @@ -256,6 +256,9 @@ impl<'a> HeaderView<'a> { } } + /// Returns header hash. + pub fn hash(&self) -> H256 { self.sha3() } + /// Returns raw rlp. pub fn rlp(&self) -> &Rlp<'a> { &self.rlp } diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 5cd1b2966..7fa12295d 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -397,6 +397,26 @@ impl Eth for EthClient } }) } + + fn call(&self, params: Params) -> Result { + from_params::<(TransactionRequest, BlockNumber)>(params) + .and_then(|(transaction_request, _block_number)| { + let accounts = take_weak!(self.accounts); + match accounts.account_secret(&transaction_request.from) { + Ok(secret) => { + let client = take_weak!(self.client); + + let transaction: EthTransaction = transaction_request.into(); + let signed_transaction = transaction.sign(&secret); + + to_value(&client.call(&signed_transaction) + .map(|e| Bytes::new(e.output)) + .unwrap_or(Bytes::default())) + }, + Err(_) => { to_value(&Bytes::default()) } + } + }) + } } /// Eth filter rpc implementation. diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index d185750c2..7bc6007ed 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -490,6 +490,8 @@ pub trait Uint: Sized + Default + FromStr + From + fmt::Debug + fmt::Displa fn zero() -> Self; /// Returns new instance equalling one. fn one() -> Self; + /// Returns the largest value that can be represented by this integer type. + fn max_value() -> Self; /// Error type for converting from a decimal string. type FromDecStrErr; @@ -647,6 +649,15 @@ macro_rules! construct_uint { From::from(1u64) } + #[inline] + fn max_value() -> Self { + let mut result = [0; $n_words]; + for i in 0..$n_words { + result[i] = u64::max_value(); + } + $name(result) + } + /// Fast exponentation by squaring /// https://en.wikipedia.org/wiki/Exponentiation_by_squaring fn pow(self, expon: Self) -> Self { From cabccf9ef59d7f83d74009be0dce8ee902de74a9 Mon Sep 17 00:00:00 2001 From: arkpar Date: Sat, 19 Mar 2016 22:19:59 +0100 Subject: [PATCH 31/41] Test URL logged --- util/src/network/ip_utils.rs | 1 + util/src/network/tests.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/util/src/network/ip_utils.rs b/util/src/network/ip_utils.rs index b37a47064..27ff29737 100644 --- a/util/src/network/ip_utils.rs +++ b/util/src/network/ip_utils.rs @@ -208,6 +208,7 @@ fn can_select_public_address() { assert!(pub_address.port() == 40477); } +#[ignore] #[test] fn can_map_external_address_or_fail() { let pub_address = select_public_address(40478); diff --git a/util/src/network/tests.rs b/util/src/network/tests.rs index 0493475ce..8df3b4028 100644 --- a/util/src/network/tests.rs +++ b/util/src/network/tests.rs @@ -103,12 +103,14 @@ fn net_service() { #[test] fn net_connect() { + ::log::init_log(); let key1 = KeyPair::create().unwrap(); let mut config1 = NetworkConfiguration::new_local(); config1.use_secret = Some(key1.secret().clone()); config1.boot_nodes = vec![ ]; let mut service1 = NetworkService::::start(config1).unwrap(); let mut config2 = NetworkConfiguration::new_local(); + info!("net_connect: local URL: {}", service1.local_url()); config2.boot_nodes = vec![ service1.local_url() ]; let mut service2 = NetworkService::::start(config2).unwrap(); let handler1 = TestProtocol::register(&mut service1, false); From b9623e6c5bbb60abbd6eed92453d0595e2ea106d Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 19 Mar 2016 23:27:50 +0100 Subject: [PATCH 32/41] improvements to build, updated dependencies, moved rpctest to its own submodule --- Cargo.lock | 131 ++++++++++--------- Cargo.toml | 6 - json/Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- rpc/rpctest/Cargo.toml | 17 +++ parity/rpctest.rs => rpc/rpctest/src/main.rs | 0 6 files changed, 87 insertions(+), 71 deletions(-) create mode 100644 rpc/rpctest/Cargo.toml rename parity/rpctest.rs => rpc/rpctest/src/main.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index aa4f0a902..56bd823c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,6 @@ dependencies = [ "ethcore-devtools 1.1.0", "ethcore-rpc 1.1.0", "ethcore-util 1.1.0", - "ethjson 0.1.0", "ethminer 1.1.0", "ethsync 1.1.0", "fdlimit 0.1.0", @@ -20,7 +19,6 @@ dependencies = [ "rpassword 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -43,10 +41,10 @@ dependencies = [ [[package]] name = "aster" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -54,7 +52,7 @@ name = "bigint" version = "0.1.0" dependencies = [ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -141,7 +139,7 @@ source = "git+https://github.com/tomusdrw/rust-ctrlc.git#f4927770f89eca80ec25091 dependencies = [ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -165,7 +163,7 @@ name = "docopt" version = "0.6.78" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "regex 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.58 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -181,7 +179,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -218,7 +216,7 @@ dependencies = [ "ethcore-devtools 1.1.0", "ethcore-util 1.1.0", "ethjson 0.1.0", - "heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -244,14 +242,14 @@ dependencies = [ "ethcore-util 1.1.0", "ethminer 1.1.0", "ethsync 1.1.0", - "jsonrpc-core 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -268,7 +266,7 @@ dependencies = [ "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)", "ethcore-devtools 1.1.0", - "heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "igd 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "json-tests 0.1.0", @@ -297,9 +295,9 @@ dependencies = [ "ethcore-util 1.1.0", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -325,7 +323,7 @@ dependencies = [ "ethcore 1.1.0", "ethcore-util 1.1.0", "ethminer 1.1.0", - "heapsize 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", @@ -355,11 +353,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "heapsize" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -391,27 +388,27 @@ dependencies = [ "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hyper" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cookie 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -422,7 +419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.58 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", "xmltree 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -442,23 +439,23 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hyper 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -466,7 +463,7 @@ name = "kernel32-sys" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -498,7 +495,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "librocksdb-sys" version = "0.2.3" -source = "git+https://github.com/arkpar/rust-rocksdb.git#ebb602fc74b4067f9f51310bdc0401b8e59b7156" +source = "git+https://github.com/arkpar/rust-rocksdb.git#ae44ef33ed1358ffc79aa05ed77839d555daba33" dependencies = [ "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -533,6 +530,14 @@ dependencies = [ "serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mime" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio" version = "0.5.0" @@ -542,11 +547,11 @@ dependencies = [ "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -555,20 +560,20 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "net2" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -667,20 +672,20 @@ dependencies = [ [[package]] name = "quasi" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quasi_codegen" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aster 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -703,7 +708,7 @@ dependencies = [ [[package]] name = "regex" -version = "0.1.56" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -720,7 +725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rocksdb" version = "0.4.3" -source = "git+https://github.com/arkpar/rust-rocksdb.git#ebb602fc74b4067f9f51310bdc0401b8e59b7156" +source = "git+https://github.com/arkpar/rust-rocksdb.git#ae44ef33ed1358ffc79aa05ed77839d555daba33" dependencies = [ "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "librocksdb-sys 0.2.3 (git+https://github.com/arkpar/rust-rocksdb.git)", @@ -734,7 +739,7 @@ dependencies = [ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -790,14 +795,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_codegen" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aster 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_codegen 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -837,18 +842,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syntex" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syntex_syntax" -version = "0.29.1" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -867,7 +872,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -885,7 +890,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -921,7 +926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicase" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -992,7 +997,7 @@ dependencies = [ [[package]] name = "winapi" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1005,7 +1010,7 @@ name = "ws2_32-sys" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 62a3c31c7..e468799ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,8 +27,6 @@ ethsync = { path = "sync" } ethminer = { path = "miner" } ethcore-devtools = { path = "devtools" } ethcore-rpc = { path = "rpc", optional = true } -ethjson = { path = "json" } -serde_json = "0.7.0" [features] default = ["rpc"] @@ -41,10 +39,6 @@ travis-nightly = ["ethcore/json-tests", "dev"] path = "parity/main.rs" name = "parity" -[[bin]] -path = "parity/rpctest.rs" -name = "rpctest" - [profile.release] debug = false lto = false diff --git a/json/Cargo.toml b/json/Cargo.toml index 91f8b8431..7887f2cea 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -14,7 +14,7 @@ clippy = { version = "0.0.54", optional = true } [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } -syntex = "0.29.0" +syntex = "0.30.0" [features] default = ["serde_codegen"] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index ca8004728..c28f598fd 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -26,7 +26,7 @@ clippy = { version = "0.0.54", optional = true } [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } -syntex = "0.29.0" +syntex = "0.30.0" [features] default = ["serde_codegen"] diff --git a/rpc/rpctest/Cargo.toml b/rpc/rpctest/Cargo.toml new file mode 100644 index 000000000..5b8f7f845 --- /dev/null +++ b/rpc/rpctest/Cargo.toml @@ -0,0 +1,17 @@ +[package] +description = "Rpc test client." +name = "rpctest" +version = "1.1.0" +license = "GPL-3.0" +authors = ["Ethcore "] + +[dependencies] +ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" } +docopt = "0.6" +rustc-serialize = "0.3" +ethcore = { path = "../../ethcore" } +ethcore-devtools = { path = "../../devtools" } +ethcore-rpc = { path = ".." } +ethcore-util = { path = "../../util" } +ethjson = { path = "../../json" } +serde_json = "0.7.0" diff --git a/parity/rpctest.rs b/rpc/rpctest/src/main.rs similarity index 100% rename from parity/rpctest.rs rename to rpc/rpctest/src/main.rs From 387d0743e6b3a4a408ddd9331dafb779f2b72b00 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 19 Mar 2016 23:51:24 +0100 Subject: [PATCH 33/41] Allow 0x prefix for --author. --- parity/main.rs | 4 ++-- util/src/hash.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index c7e534993..56e70cf2a 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -46,6 +46,7 @@ use env_logger::LogBuilder; use ctrlc::CtrlC; use util::*; use util::panics::{MayPanic, ForwardPanic, PanicHandler}; +use util::keys::store::*; use ethcore::spec::*; use ethcore::client::*; use ethcore::service::{ClientService, NetSyncMessage}; @@ -55,7 +56,6 @@ use ethminer::{Miner, MinerService}; use docopt::Docopt; use daemonize::Daemonize; use number_prefix::{binary_prefix, Standalone, Prefixed}; -use util::keys::store::*; fn die_with_message(msg: &str) -> ! { println!("ERROR: {}", msg); @@ -315,7 +315,7 @@ impl Configuration { fn author(&self) -> Address { let d = self.args.flag_etherbase.as_ref().unwrap_or(&self.args.flag_author); - Address::from_str(d).unwrap_or_else(|_| { + Address::from_str(clean_0x(d)).unwrap_or_else(|_| { die!("{}: Invalid address for --author. Must be 40 hex characters, without the 0x at the beginning.", d) }) } diff --git a/util/src/hash.rs b/util/src/hash.rs index fce0720d1..b7fddbe8b 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -63,7 +63,8 @@ pub trait FixedHash: Sized + BytesConvertable + Populatable + FromStr + Default fn low_u64(&self) -> u64; } -fn clean_0x(s: &str) -> &str { +/// Return `s` without the `0x` at the beginning of it, if any. +pub fn clean_0x(s: &str) -> &str { if s.len() >= 2 && &s[0..2] == "0x" { &s[2..] } else { From fef8237701406bcdaee0fafe5d280fb15e2ecf5d Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 20 Mar 2016 10:07:50 +0100 Subject: [PATCH 34/41] fixes after merge --- ethcore/src/client/client.rs | 2 +- ethcore/src/client/test_client.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index bdc829159..1d34bf158 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -407,7 +407,7 @@ impl BlockChainClient for Client where V: Verifier { // give the sender max balance state.sub_balance(&sender, &balance); state.add_balance(&sender, &U256::max_value()); - Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t) + Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t, false) } // TODO [todr] Should be moved to miner crate eventually. diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 5d51368de..db4be61bc 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -184,7 +184,7 @@ impl TestBlockChainClient { } impl BlockChainClient for TestBlockChainClient { - fn call(&self, t: &SignedTransaction) -> Result { + fn call(&self, _t: &SignedTransaction) -> Result { unimplemented!() } From c611566a3e45440cfdf9af028f9ef4433309ad0b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 20 Mar 2016 10:19:21 +0100 Subject: [PATCH 35/41] Listen on all interfaces for JSONRPC by default. --- parity/main.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 56e70cf2a..39f5dcc82 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -105,8 +105,9 @@ Networking Options: API and Console Options: -j --jsonrpc Enable the JSON-RPC API sever. - --jsonrpc-addr HOST Specify the hostname portion of the JSONRPC API - server [default: 127.0.0.1]. + --jsonrpc-interface IP Specify the hostname portion of the JSONRPC API + server, IP should be an interface's IP address, or + all (all interfaces) or local [default: all]. --jsonrpc-port PORT Specify the port portion of the JSONRPC API server [default: 8545]. --jsonrpc-cors URL Specify CORS header for JSON-RPC API responses @@ -149,7 +150,7 @@ Geth-compatibility Options: --nodekey KEY Equivalent to --node-key KEY. --nodiscover Equivalent to --no-discovery. --rpc Equivalent to --jsonrpc. - --rpcaddr HOST Equivalent to --jsonrpc-addr HOST. + --rpcaddr IP Equivalent to --jsonrpc-interface IP. --rpcport PORT Equivalent to --jsonrpc-port PORT. --rpcapi APIS Equivalent to --jsonrpc-apis APIS. --rpccorsdomain URL Equivalent to --jsonrpc-cors URL. @@ -188,7 +189,7 @@ struct Args { flag_cache_max_size: usize, flag_queue_max_size: usize, flag_jsonrpc: bool, - flag_jsonrpc_addr: String, + flag_jsonrpc_interface: String, flag_jsonrpc_port: u16, flag_jsonrpc_cors: String, flag_jsonrpc_apis: String, @@ -523,7 +524,11 @@ impl Configuration { // Setup rpc if self.args.flag_jsonrpc || self.args.flag_rpc { let url = format!("{}:{}", - self.args.flag_rpcaddr.as_ref().unwrap_or(&self.args.flag_jsonrpc_addr), + match self.args.flag_rpcaddr.as_ref().unwrap_or(&self.args.flag_jsonrpc_interface).as_str() { + "all" => "0.0.0.0", + "local" => "127.0.0.1", + x => x, + }, self.args.flag_rpcport.unwrap_or(self.args.flag_jsonrpc_port) ); SocketAddr::from_str(&url).unwrap_or_else(|_| die!("{}: Invalid JSONRPC listen host/port given.", url)); From 7c6f0e472d8feaa3642e886cb3bbea8e340171d9 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 20 Mar 2016 10:29:21 +0100 Subject: [PATCH 36/41] implementation of eth_estimateGas --- rpc/src/v1/impls/eth.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 3daa6275c..c66f04355 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -418,6 +418,26 @@ impl Eth for EthClient } }) } + + fn estimate_gas(&self, params: Params) -> Result { + from_params::<(TransactionRequest, BlockNumber)>(params) + .and_then(|(transaction_request, _block_number)| { + let accounts = take_weak!(self.accounts); + match accounts.account_secret(&transaction_request.from) { + Ok(secret) => { + let client = take_weak!(self.client); + + let transaction: EthTransaction = transaction_request.into(); + let signed_transaction = transaction.sign(&secret); + + to_value(&client.call(&signed_transaction) + .map(|e| e.gas_used) + .unwrap_or(U256::zero())) + }, + Err(_) => { to_value(&U256::zero()) } + } + }) + } } /// Eth filter rpc implementation. From 05a9c163298a94b00cbd4c45e3bb7f27b02a651f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 20 Mar 2016 10:34:34 +0100 Subject: [PATCH 37/41] JSONRPC interface defaults to local. Please enter the commit message for your changes. Lines starting --- parity/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/main.rs b/parity/main.rs index 39f5dcc82..e029124c4 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -107,7 +107,7 @@ API and Console Options: -j --jsonrpc Enable the JSON-RPC API sever. --jsonrpc-interface IP Specify the hostname portion of the JSONRPC API server, IP should be an interface's IP address, or - all (all interfaces) or local [default: all]. + all (all interfaces) or local [default: local]. --jsonrpc-port PORT Specify the port portion of the JSONRPC API server [default: 8545]. --jsonrpc-cors URL Specify CORS header for JSON-RPC API responses From d536d206430df58a46fa9b41079a6884151261d9 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 20 Mar 2016 10:36:44 +0100 Subject: [PATCH 38/41] fixed indentation --- rpc/src/v1/impls/eth.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 3daa6275c..34a0c2f45 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -410,9 +410,11 @@ impl Eth for EthClient let transaction: EthTransaction = transaction_request.into(); let signed_transaction = transaction.sign(&secret); - to_value(&client.call(&signed_transaction) - .map(|e| Bytes::new(e.output)) - .unwrap_or(Bytes::default())) + let output = client.call(&signed_transaction) + .map(|e| Bytes::new(e.output)) + .unwrap_or(Bytes::default()); + + to_value(&output) }, Err(_) => { to_value(&Bytes::default()) } } From aa47d944e165c196f6f3237ad3aad05a68110d32 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 20 Mar 2016 11:34:19 +0100 Subject: [PATCH 39/41] implemented rpc eth_estimateGas method, added tests for rpc eth_call and eth_estimateGas --- ethcore/src/client/mod.rs | 2 +- ethcore/src/client/test_client.rs | 10 ++- ethcore/src/executive.rs | 2 +- rpc/src/v1/impls/eth.rs | 8 ++- rpc/src/v1/tests/eth.rs | 74 +++++++++++++++++--- rpc/src/v1/tests/helpers/account_provider.rs | 4 +- rpc/src/v1/types/transaction_request.rs | 25 +++++++ 7 files changed, 107 insertions(+), 18 deletions(-) diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 4a3208eb8..9663ab62b 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -25,6 +25,7 @@ pub use self::client::*; pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig}; pub use self::ids::{BlockId, TransactionId}; pub use self::test_client::{TestBlockChainClient, EachBlockWith}; +pub use executive::Executed; use std::collections::HashSet; use util::bytes::Bytes; @@ -38,7 +39,6 @@ use transaction::{LocalizedTransaction, SignedTransaction}; use log_entry::LocalizedLogEntry; use filter::Filter; use error::{ImportResult, Error}; -use executive::Executed; /// Blockchain database client. Owns and manages a blockchain and a block queue. pub trait BlockChainClient : Sync + Send { diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index db4be61bc..ad73234b3 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -50,6 +50,8 @@ pub struct TestBlockChainClient { pub storage: RwLock>, /// Code. pub code: RwLock>, + /// Execution result. + pub execution_result: RwLock>, } #[derive(Clone)] @@ -84,12 +86,18 @@ impl TestBlockChainClient { balances: RwLock::new(HashMap::new()), storage: RwLock::new(HashMap::new()), code: RwLock::new(HashMap::new()), + execution_result: RwLock::new(None), }; client.add_blocks(1, EachBlockWith::Nothing); // add genesis block client.genesis_hash = client.last_hash.read().unwrap().clone(); client } + /// Set the execution result. + pub fn set_execution_result(&self, result: Executed) { + *self.execution_result.write().unwrap() = Some(result); + } + /// Set the balance of account `address` to `balance`. pub fn set_balance(&self, address: Address, balance: U256) { self.balances.write().unwrap().insert(address, balance); @@ -185,7 +193,7 @@ impl TestBlockChainClient { impl BlockChainClient for TestBlockChainClient { fn call(&self, _t: &SignedTransaction) -> Result { - unimplemented!() + Ok(self.execution_result.read().unwrap().clone().unwrap()) } fn block_total_difficulty(&self, _id: BlockId) -> Option { diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index d02f58815..1fbef7345 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -37,7 +37,7 @@ pub fn contract_address(address: &Address, nonce: &U256) -> Address { } /// Transaction execution receipt. -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone)] pub struct Executed { /// Gas paid up front for execution of transaction. pub gas: U256, diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 01625e9f9..a99a912f8 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -432,9 +432,11 @@ impl Eth for EthClient let transaction: EthTransaction = transaction_request.into(); let signed_transaction = transaction.sign(&secret); - to_value(&client.call(&signed_transaction) - .map(|e| e.gas_used) - .unwrap_or(U256::zero())) + let gas_used = client.call(&signed_transaction) + .map(|e| e.gas_used + e.refunded) + .unwrap_or(U256::zero()); + + to_value(&gas_used) }, Err(_) => { to_value(&U256::zero()) } } diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index a5f318350..72235b390 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -18,8 +18,8 @@ use std::collections::HashMap; use std::sync::{Arc, RwLock}; use jsonrpc_core::IoHandler; use util::hash::{Address, H256}; -use util::numbers::U256; -use ethcore::client::{TestBlockChainClient, EachBlockWith}; +use util::numbers::{Uint, U256}; +use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed}; use v1::{Eth, EthClient}; use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config, TestMinerService, TestExternalMiner}; @@ -299,9 +299,69 @@ fn rpc_eth_code() { } #[test] -#[ignore] fn rpc_eth_call() { - unimplemented!() + let tester = EthTester::default(); + tester.client.set_execution_result(Executed { + gas: U256::zero(), + gas_used: U256::from(0xff30), + refunded: U256::from(0x5), + cumulative_gas_used: U256::zero(), + logs: vec![], + contracts_created: vec![], + output: vec![0x12, 0x34, 0xff], + trace: None, + }); + + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_call", + "params": [{ + "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }, + "latest"], + "id": 1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":"0x1234ff","id":1}"#; + + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); +} + +#[test] +fn rpc_eth_estimate_gas() { + let tester = EthTester::default(); + tester.client.set_execution_result(Executed { + gas: U256::zero(), + gas_used: U256::from(0xff30), + refunded: U256::from(0x5), + cumulative_gas_used: U256::zero(), + logs: vec![], + contracts_created: vec![], + output: vec![0x12, 0x34, 0xff], + trace: None, + }); + + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_estimateGas", + "params": [{ + "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }, + "latest"], + "id": 1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#; + + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } #[test] @@ -322,12 +382,6 @@ fn rpc_eth_sign() { unimplemented!() } -#[test] -#[ignore] -fn rpc_eth_estimate_gas() { - unimplemented!() -} - #[test] fn rpc_eth_compilers() { let request = r#"{"jsonrpc": "2.0", "method": "eth_getCompilers", "params": [], "id": 1}"#; diff --git a/rpc/src/v1/tests/helpers/account_provider.rs b/rpc/src/v1/tests/helpers/account_provider.rs index 614aba346..6ef6e2b59 100644 --- a/rpc/src/v1/tests/helpers/account_provider.rs +++ b/rpc/src/v1/tests/helpers/account_provider.rs @@ -19,7 +19,7 @@ use std::sync::RwLock; use std::collections::HashMap; use std::io; -use util::hash::{Address, H256}; +use util::hash::{Address, H256, FixedHash}; use util::crypto::{Secret, Signature}; use util::keys::store::{AccountProvider, SigningError, EncryptedHashMapError}; @@ -83,7 +83,7 @@ impl AccountProvider for TestAccountProvider { } fn account_secret(&self, _account: &Address) -> Result { - unimplemented!() + Ok(Secret::random()) } fn sign(&self, _account: &Address, _message: &H256) -> Result { diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index d40402ab5..ed4dc19a2 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -46,6 +46,8 @@ impl Into for TransactionRequest { #[cfg(test)] mod tests { + use std::str::FromStr; + use rustc_serialize::hex::FromHex; use serde_json; use util::numbers::{Uint, U256}; use util::hash::Address; @@ -121,6 +123,29 @@ mod tests { }); } + #[test] + fn transaction_request_deserialize2() { + let s = r#"{ + "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }"#; + let deserialized: TransactionRequest = serde_json::from_str(s).unwrap(); + + assert_eq!(deserialized, TransactionRequest { + from: Address::from_str("b60e8dd61c5d32be8058bb8eb970870f07233155").unwrap(), + to: Some(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + gas_price: Some(U256::from_str("9184e72a000").unwrap()), + gas: Some(U256::from_str("76c0").unwrap()), + value: Some(U256::from_str("9184e72a").unwrap()), + data: Some(Bytes::new("d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675".from_hex().unwrap())), + nonce: None + }); + } + #[test] fn transaction_request_deserialize_empty() { let s = r#"{"from":"0x0000000000000000000000000000000000000001"}"#; From 2ec40604d923a4b0bd837bab51fd56b98c923a8a Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Sun, 20 Mar 2016 12:12:58 +0100 Subject: [PATCH 40/41] Revert "Auto detect available port" --- ethcore/src/service.rs | 2 +- util/src/network/host.rs | 93 ++++++++++++++++-------------------- util/src/network/ip_utils.rs | 1 - util/src/network/mod.rs | 2 +- util/src/network/service.rs | 21 ++------ util/src/network/session.rs | 2 +- util/src/network/tests.rs | 22 +++++---- 7 files changed, 60 insertions(+), 83 deletions(-) diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index 95a891198..bcfe7724f 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -146,7 +146,7 @@ mod tests { fn it_can_be_started() { let spec = get_test_spec(); let temp_path = RandomTempPath::new(); - let service = ClientService::start(ClientConfig::default(), spec, NetworkConfiguration::new_local(), &temp_path.as_path()); + let service = ClientService::start(ClientConfig::default(), spec, NetworkConfiguration::new_with_port(40456), &temp_path.as_path()); assert!(service.is_ok()); } } diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 6baf0cf76..02c576424 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -105,14 +105,6 @@ impl NetworkConfiguration { config.listen_address = Some(SocketAddr::from_str(&format!("0.0.0.0:{}", port)).unwrap()); config } - - /// Create new default configuration for localhost-only connection with random port (usefull for testing) - pub fn new_local() -> NetworkConfiguration { - let mut config = NetworkConfiguration::new(); - config.listen_address = Some(SocketAddr::from_str("127.0.0.1:0").unwrap()); - config.nat_enabled = false; - config - } } // Tokens @@ -277,12 +269,12 @@ pub struct HostInfo { pub protocol_version: u32, /// Client identifier pub client_version: String, + /// TCP connection port. + pub listen_port: u16, /// Registered capabilities (handlers) pub capabilities: Vec, - /// Local address + discovery port - pub local_endpoint: NodeEndpoint, /// Public address + discovery port - pub public_endpoint: Option, + public_endpoint: NodeEndpoint, } impl HostInfo { @@ -315,7 +307,7 @@ struct ProtocolTimer { /// Root IO handler. Manages protocol handlers, IO timers and network connections. pub struct Host where Message: Send + Sync + Clone { pub info: RwLock, - tcp_listener: Mutex, + tcp_listener: Mutex>, handshakes: Arc>>, sessions: Arc>>, discovery: Mutex>, @@ -329,12 +321,13 @@ pub struct Host where Message: Send + Sync + Clone { impl Host where Message: Send + Sync + Clone { /// Create a new instance - pub fn new(config: NetworkConfiguration) -> Result, UtilError> { - let mut listen_address = match config.listen_address { + pub fn new(config: NetworkConfiguration) -> Host { + let listen_address = match config.listen_address { None => SocketAddr::from_str("0.0.0.0:30304").unwrap(), Some(addr) => addr, }; + let udp_port = config.udp_port.unwrap_or(listen_address.port()); let keys = if let Some(ref secret) = config.use_secret { KeyPair::from_secret(secret.clone()).unwrap() } else { @@ -349,12 +342,7 @@ impl Host where Message: Send + Sync + Clone { |s| KeyPair::from_secret(s).expect("Error creating node secret key")) }; let path = config.config_path.clone(); - // Setup the server socket - let tcp_listener = try!(TcpListener::bind(&listen_address)); - listen_address = SocketAddr::new(listen_address.ip(), try!(tcp_listener.local_addr()).port()); - let udp_port = config.udp_port.unwrap_or(listen_address.port()); let local_endpoint = NodeEndpoint { address: listen_address, udp_port: udp_port }; - let mut host = Host:: { info: RwLock::new(HostInfo { keys: keys, @@ -362,12 +350,12 @@ impl Host where Message: Send + Sync + Clone { nonce: H256::random(), protocol_version: PROTOCOL_VERSION, client_version: version(), + listen_port: 0, capabilities: Vec::new(), - public_endpoint: None, - local_endpoint: local_endpoint, + public_endpoint: local_endpoint, // will be replaced by public once it is resolved }), discovery: Mutex::new(None), - tcp_listener: Mutex::new(tcp_listener), + tcp_listener: Mutex::new(None), handshakes: Arc::new(RwLock::new(Slab::new_starting_at(FIRST_HANDSHAKE, MAX_HANDSHAKES))), sessions: Arc::new(RwLock::new(Slab::new_starting_at(FIRST_SESSION, MAX_SESSIONS))), nodes: RwLock::new(NodeTable::new(path)), @@ -377,12 +365,14 @@ impl Host where Message: Send + Sync + Clone { stats: Arc::new(NetworkStats::default()), pinned_nodes: Vec::new(), }; + let port = listen_address.port(); + host.info.write().unwrap().deref_mut().listen_port = port; let boot_nodes = host.info.read().unwrap().config.boot_nodes.clone(); for n in boot_nodes { host.add_node(&n); } - Ok(host) + host } pub fn stats(&self) -> Arc { @@ -407,50 +397,50 @@ impl Host where Message: Send + Sync + Clone { self.info.read().unwrap().client_version.clone() } - pub fn external_url(&self) -> Option { - self.info.read().unwrap().public_endpoint.as_ref().map(|e| format!("{}", Node::new(self.info.read().unwrap().id().clone(), e.clone()))) + pub fn client_url(&self) -> String { + format!("{}", Node::new(self.info.read().unwrap().id().clone(), self.info.read().unwrap().public_endpoint.clone())) } - pub fn local_url(&self) -> String { - let r = format!("{}", Node::new(self.info.read().unwrap().id().clone(), self.info.read().unwrap().local_endpoint.clone())); - println!("{}", r); - r - } - - fn init_public_interface(&self, io: &IoContext>) -> Result<(), UtilError> { + fn init_public_interface(&self, io: &IoContext>) { io.clear_timer(INIT_PUBLIC).unwrap(); - if self.info.read().unwrap().public_endpoint.is_some() { - return Ok(()); + let mut tcp_listener = self.tcp_listener.lock().unwrap(); + if tcp_listener.is_some() { + return; } - let local_endpoint = self.info.read().unwrap().local_endpoint.clone(); + // public_endpoint in host info contains local adderss at this point + let listen_address = self.info.read().unwrap().public_endpoint.address.clone(); + let udp_port = self.info.read().unwrap().config.udp_port.unwrap_or(listen_address.port()); let public_address = self.info.read().unwrap().config.public_address.clone(); let public_endpoint = match public_address { None => { - let public_address = select_public_address(local_endpoint.address.port()); - let public_endpoint = NodeEndpoint { address: public_address, udp_port: local_endpoint.udp_port }; + let public_address = select_public_address(listen_address.port()); + let local_endpoint = NodeEndpoint { address: public_address, udp_port: udp_port }; if self.info.read().unwrap().config.nat_enabled { match map_external_address(&local_endpoint) { Some(endpoint) => { - info!("NAT mapped to external address {}", endpoint.address); + info!("NAT mappped to external address {}", endpoint.address); endpoint }, - None => public_endpoint + None => local_endpoint } } else { - public_endpoint + local_endpoint } } - Some(addr) => NodeEndpoint { address: addr, udp_port: local_endpoint.udp_port } + Some(addr) => NodeEndpoint { address: addr, udp_port: udp_port } }; - self.info.write().unwrap().public_endpoint = Some(public_endpoint.clone()); - info!("Public node URL: {}", self.external_url().unwrap()); + // Setup the server socket + *tcp_listener = Some(TcpListener::bind(&listen_address).unwrap()); + self.info.write().unwrap().public_endpoint = public_endpoint.clone(); + io.register_stream(TCP_ACCEPT).expect("Error registering TCP listener"); + info!("Public node URL: {}", self.client_url()); // Initialize discovery. let discovery = { let info = self.info.read().unwrap(); if info.config.discovery_enabled && !info.config.pin { - Some(Discovery::new(&info.keys, public_endpoint.address.clone(), public_endpoint, DISCOVERY)) + Some(Discovery::new(&info.keys, listen_address.clone(), public_endpoint, DISCOVERY)) } else { None } }; @@ -464,8 +454,6 @@ impl Host where Message: Send + Sync + Clone { io.register_timer(DISCOVERY_ROUND, 300).expect("Error registering discovery timer"); *self.discovery.lock().unwrap().deref_mut() = Some(discovery); } - try!(io.register_stream(TCP_ACCEPT)); - Ok(()) } fn maintain_network(&self, io: &IoContext>) { @@ -579,7 +567,7 @@ impl Host where Message: Send + Sync + Clone { fn accept(&self, io: &IoContext>) { trace!(target: "network", "Accepting incoming connection"); loop { - let socket = match self.tcp_listener.lock().unwrap().accept() { + let socket = match self.tcp_listener.lock().unwrap().as_ref().unwrap().accept() { Ok(None) => break, Ok(Some((sock, _addr))) => sock, Err(e) => { @@ -873,8 +861,7 @@ impl IoHandler> for Host where Messa fn timeout(&self, io: &IoContext>, token: TimerToken) { match token { IDLE => self.maintain_network(io), - INIT_PUBLIC => self.init_public_interface(io).unwrap_or_else(|e| - warn!("Error initializing public interface: {:?}", e)), + INIT_PUBLIC => self.init_public_interface(io), FIRST_SESSION ... LAST_SESSION => self.connection_timeout(token, io), FIRST_HANDSHAKE ... LAST_HANDSHAKE => self.connection_timeout(token, io), DISCOVERY_REFRESH => { @@ -958,7 +945,7 @@ impl IoHandler> for Host where Messa } } DISCOVERY => self.discovery.lock().unwrap().as_ref().unwrap().register_socket(event_loop).expect("Error registering discovery socket"), - TCP_ACCEPT => event_loop.register(self.tcp_listener.lock().unwrap().deref(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error registering stream"), + TCP_ACCEPT => event_loop.register(self.tcp_listener.lock().unwrap().as_ref().unwrap(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error registering stream"), _ => warn!("Unexpected stream registration") } } @@ -999,7 +986,7 @@ impl IoHandler> for Host where Messa } } DISCOVERY => self.discovery.lock().unwrap().as_ref().unwrap().update_registration(event_loop).expect("Error reregistering discovery socket"), - TCP_ACCEPT => event_loop.reregister(self.tcp_listener.lock().unwrap().deref(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error reregistering stream"), + TCP_ACCEPT => event_loop.reregister(self.tcp_listener.lock().unwrap().as_ref().unwrap(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error reregistering stream"), _ => warn!("Unexpected stream update") } } @@ -1067,6 +1054,6 @@ fn host_client_url() { let mut config = NetworkConfiguration::new(); let key = h256_from_hex("6f7b0d801bc7b5ce7bbd930b84fd0369b3eb25d09be58d64ba811091046f3aa2"); config.use_secret = Some(key); - let host: Host = Host::new(config).unwrap(); - assert!(host.local_url().starts_with("enode://101b3ef5a4ea7a1c7928e24c4c75fd053c235d7b80c22ae5c03d145d0ac7396e2a4ffff9adee3133a7b05044a5cee08115fd65145e5165d646bde371010d803c@")); + let host: Host = Host::new(config); + assert!(host.client_url().starts_with("enode://101b3ef5a4ea7a1c7928e24c4c75fd053c235d7b80c22ae5c03d145d0ac7396e2a4ffff9adee3133a7b05044a5cee08115fd65145e5165d646bde371010d803c@")); } diff --git a/util/src/network/ip_utils.rs b/util/src/network/ip_utils.rs index 27ff29737..b37a47064 100644 --- a/util/src/network/ip_utils.rs +++ b/util/src/network/ip_utils.rs @@ -208,7 +208,6 @@ fn can_select_public_address() { assert!(pub_address.port() == 40477); } -#[ignore] #[test] fn can_map_external_address_or_fail() { let pub_address = select_public_address(40478); diff --git a/util/src/network/mod.rs b/util/src/network/mod.rs index 29f3d166c..50645f2be 100644 --- a/util/src/network/mod.rs +++ b/util/src/network/mod.rs @@ -56,7 +56,7 @@ //! } //! //! fn main () { -//! let mut service = NetworkService::::start(NetworkConfiguration::new_local()).expect("Error creating network service"); +//! let mut service = NetworkService::::start(NetworkConfiguration::new_with_port(40412)).expect("Error creating network service"); //! service.register_protocol(Arc::new(MyHandler), "myproto", &[1u8]); //! //! // Wait for quit condition diff --git a/util/src/network/service.rs b/util/src/network/service.rs index 49957f7e7..7b9388e85 100644 --- a/util/src/network/service.rs +++ b/util/src/network/service.rs @@ -28,7 +28,6 @@ use io::*; pub struct NetworkService where Message: Send + Sync + Clone + 'static { io_service: IoService>, host_info: String, - host: Arc>, stats: Arc, panic_handler: Arc } @@ -40,16 +39,15 @@ impl NetworkService where Message: Send + Sync + Clone + 'stat let mut io_service = try!(IoService::>::start()); panic_handler.forward_from(&io_service); - let host = Arc::new(try!(Host::new(config))); + let host = Arc::new(Host::new(config)); let stats = host.stats().clone(); let host_info = host.client_version(); - try!(io_service.register_handler(host.clone())); + try!(io_service.register_handler(host)); Ok(NetworkService { io_service: io_service, host_info: host_info, stats: stats, - panic_handler: panic_handler, - host: host, + panic_handler: panic_handler }) } @@ -73,22 +71,13 @@ impl NetworkService where Message: Send + Sync + Clone + 'stat &mut self.io_service } - /// Returns network statistics. + /// Returns underlying io service. pub fn stats(&self) -> &NetworkStats { &self.stats } - - /// Returns external url if available. - pub fn external_url(&self) -> Option { - self.host.external_url() - } - - /// Returns external url if available. - pub fn local_url(&self) -> String { - self.host.local_url() - } } + impl MayPanic for NetworkService where Message: Send + Sync + Clone + 'static { fn on_panic(&self, closure: F) where F: OnPanicListener { self.panic_handler.on_panic(closure); diff --git a/util/src/network/session.rs b/util/src/network/session.rs index 7dbcc4229..2f30d7376 100644 --- a/util/src/network/session.rs +++ b/util/src/network/session.rs @@ -315,7 +315,7 @@ impl Session { .append(&host.protocol_version) .append(&host.client_version) .append(&host.capabilities) - .append(&host.local_endpoint.address.port()) + .append(&host.listen_port) .append(host.id()); self.connection.send_packet(&rlp.out()) } diff --git a/util/src/network/tests.rs b/util/src/network/tests.rs index 8df3b4028..f8ef588f6 100644 --- a/util/src/network/tests.rs +++ b/util/src/network/tests.rs @@ -97,21 +97,21 @@ impl NetworkProtocolHandler for TestProtocol { #[test] fn net_service() { - let mut service = NetworkService::::start(NetworkConfiguration::new_local()).expect("Error creating network service"); + let mut service = NetworkService::::start(NetworkConfiguration::new_with_port(40414)).expect("Error creating network service"); service.register_protocol(Arc::new(TestProtocol::new(false)), "myproto", &[1u8]).unwrap(); } #[test] fn net_connect() { - ::log::init_log(); let key1 = KeyPair::create().unwrap(); - let mut config1 = NetworkConfiguration::new_local(); + let mut config1 = NetworkConfiguration::new_with_port(30354); config1.use_secret = Some(key1.secret().clone()); + config1.nat_enabled = false; config1.boot_nodes = vec![ ]; + let mut config2 = NetworkConfiguration::new_with_port(30355); + config2.boot_nodes = vec![ format!("enode://{}@127.0.0.1:30354", key1.public().hex()) ]; + config2.nat_enabled = false; let mut service1 = NetworkService::::start(config1).unwrap(); - let mut config2 = NetworkConfiguration::new_local(); - info!("net_connect: local URL: {}", service1.local_url()); - config2.boot_nodes = vec![ service1.local_url() ]; let mut service2 = NetworkService::::start(config2).unwrap(); let handler1 = TestProtocol::register(&mut service1, false); let handler2 = TestProtocol::register(&mut service2, false); @@ -125,12 +125,14 @@ fn net_connect() { #[test] fn net_disconnect() { let key1 = KeyPair::create().unwrap(); - let mut config1 = NetworkConfiguration::new_local(); + let mut config1 = NetworkConfiguration::new_with_port(30364); config1.use_secret = Some(key1.secret().clone()); + config1.nat_enabled = false; config1.boot_nodes = vec![ ]; + let mut config2 = NetworkConfiguration::new_with_port(30365); + config2.boot_nodes = vec![ format!("enode://{}@127.0.0.1:30364", key1.public().hex()) ]; + config2.nat_enabled = false; let mut service1 = NetworkService::::start(config1).unwrap(); - let mut config2 = NetworkConfiguration::new_local(); - config2.boot_nodes = vec![ service1.local_url() ]; let mut service2 = NetworkService::::start(config2).unwrap(); let handler1 = TestProtocol::register(&mut service1, false); let handler2 = TestProtocol::register(&mut service2, true); @@ -143,7 +145,7 @@ fn net_disconnect() { #[test] fn net_timeout() { - let config = NetworkConfiguration::new_local(); + let config = NetworkConfiguration::new_with_port(30346); let mut service = NetworkService::::start(config).unwrap(); let handler = TestProtocol::register(&mut service, false); while !handler.got_timeout() { From ef10c6f6377955bbc709755632f21f5cb0451124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sun, 20 Mar 2016 12:18:41 +0100 Subject: [PATCH 41/41] Avoiding possible overflow when block number gets smaller. --- miner/src/miner.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 699848337..e1b314d57 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -161,8 +161,8 @@ impl MinerService for Miner { let should_disable_sealing = { let current_no = chain.chain_info().best_block_number; let last_request = self.sealing_block_last_request.lock().unwrap(); - - current_no - *last_request > SEALING_TIMEOUT_IN_BLOCKS + let is_greater = current_no > *last_request; + is_greater && current_no - *last_request > SEALING_TIMEOUT_IN_BLOCKS }; if should_disable_sealing {