From be9d1fbd321dcca724740e83adca616b4f0c0d22 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 6 Sep 2019 15:25:43 +0200 Subject: [PATCH 01/10] [json]: cleanup write something here.... --- Cargo.lock | 1 - ethcore/Cargo.toml | 6 +- ethcore/pod/Cargo.toml | 4 + ethcore/pod/src/account.rs | 16 -- ethcore/pod/src/state.rs | 7 - ethcore/spec/Cargo.toml | 6 + ethcore/src/json_tests/chain.rs | 4 +- ethcore/src/json_tests/difficulty.rs | 8 +- ethcore/src/json_tests/executive.rs | 16 +- ethcore/src/json_tests/skip.rs | 12 +- ethcore/src/json_tests/state.rs | 2 +- ethcore/src/json_tests/transaction.rs | 2 +- ethcore/src/json_tests/trie.rs | 2 +- ethcore/types/src/transaction/transaction.rs | 32 +-- evmbin/Cargo.toml | 1 + evmbin/src/main.rs | 6 +- json/Cargo.toml | 7 +- json/src/blockchain/account.rs | 57 ----- json/src/blockchain/block.rs | 75 ------- json/src/blockchain/blockchain.rs | 204 ------------------ json/src/blockchain/header.rs | 93 -------- json/src/blockchain/mod.rs | 34 --- json/src/blockchain/state.rs | 34 --- json/src/blockchain/test.rs | 43 ---- json/src/blockchain/transaction.rs | 34 --- json/src/bytes.rs | 9 +- json/src/hash.rs | 4 +- json/src/lib.rs | 22 +- json/src/maybe.rs | 15 +- json/src/spec/account.rs | 12 +- json/src/spec/authority_round.rs | 12 +- json/src/spec/basic_authority.rs | 12 +- json/src/spec/builtin.rs | 7 +- json/src/spec/clique.rs | 1 + json/src/spec/engine.rs | 4 +- json/src/spec/ethash.rs | 14 +- json/src/spec/genesis.rs | 22 +- json/src/spec/hardcoded_sync.rs | 10 +- json/src/spec/instant_seal.rs | 2 + json/src/spec/null_engine.rs | 7 +- json/src/spec/params.rs | 19 +- json/src/spec/seal.rs | 11 +- json/src/spec/spec.rs | 7 +- json/src/spec/state.rs | 16 +- json/src/spec/validator_set.rs | 9 +- json/src/state/log.rs | 52 ----- json/src/state/mod.rs | 29 --- json/src/state/state.rs | 156 -------------- json/src/state/test.rs | 215 ------------------- json/src/state/transaction.rs | 64 ------ json/src/test/mod.rs | 118 ---------- json/src/transaction/mod.rs | 25 --- json/src/transaction/test.rs | 43 ---- json/src/transaction/transaction.rs | 69 ------ json/src/transaction/txtest.rs | 83 ------- json/src/trie/input.rs | 156 -------------- json/src/trie/mod.rs | 25 --- json/src/trie/test.rs | 43 ---- json/src/trie/trie.rs | 30 --- json/src/uint.rs | 5 +- json/src/vm/call.rs | 84 -------- json/src/vm/env.rs | 58 ----- json/src/vm/mod.rs | 29 --- json/src/vm/test.rs | 43 ---- json/src/vm/transaction.rs | 67 ------ json/src/vm/vm.rs | 113 ---------- rpc/Cargo.toml | 3 +- rpc/src/v1/tests/eth.rs | 8 +- rpc/src/v1/tests/mod.rs | 2 +- 69 files changed, 174 insertions(+), 2267 deletions(-) delete mode 100644 json/src/blockchain/account.rs delete mode 100644 json/src/blockchain/block.rs delete mode 100644 json/src/blockchain/blockchain.rs delete mode 100644 json/src/blockchain/header.rs delete mode 100644 json/src/blockchain/mod.rs delete mode 100644 json/src/blockchain/state.rs delete mode 100644 json/src/blockchain/test.rs delete mode 100644 json/src/blockchain/transaction.rs delete mode 100644 json/src/state/log.rs delete mode 100644 json/src/state/mod.rs delete mode 100644 json/src/state/state.rs delete mode 100644 json/src/state/test.rs delete mode 100644 json/src/state/transaction.rs delete mode 100644 json/src/test/mod.rs delete mode 100644 json/src/transaction/mod.rs delete mode 100644 json/src/transaction/test.rs delete mode 100644 json/src/transaction/transaction.rs delete mode 100644 json/src/transaction/txtest.rs delete mode 100644 json/src/trie/input.rs delete mode 100644 json/src/trie/mod.rs delete mode 100644 json/src/trie/test.rs delete mode 100644 json/src/trie/trie.rs delete mode 100644 json/src/vm/call.rs delete mode 100644 json/src/vm/env.rs delete mode 100644 json/src/vm/mod.rs delete mode 100644 json/src/vm/test.rs delete mode 100644 json/src/vm/transaction.rs delete mode 100644 json/src/vm/vm.rs diff --git a/Cargo.lock b/Cargo.lock index ee93d28f5b7..edae1d5a67a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1513,7 +1513,6 @@ dependencies = [ "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index a6ff42a9106..4965d5859b3 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -20,7 +20,7 @@ ethabi = "8.0" ethabi-contract = "8.0" ethabi-derive = "8.0" ethash = { path = "../ethash", optional = true } -ethjson = { path = "../json", optional = true } +ethjson = { path = "../json", features = ["test-helpers"], optional = true } ethkey = { path = "../accounts/ethkey", optional = true } ethcore-blockchain = { path = "./blockchain" } ethcore-call-contract = { path = "./call-contract" } @@ -79,7 +79,7 @@ engine = { path = "./engine", features = ["test-helpers"] } env_logger = "0.5" ethash = { path = "../ethash" } ethcore-accounts = { path = "../accounts" } -ethjson = { path = "../json" } +ethjson = { path = "../json", features = ["test-helpers"] } ethkey = { path = "../accounts/ethkey" } fetch = { path = "../util/fetch" } kvdb-memorydb = "0.1" @@ -89,7 +89,7 @@ machine = { path = "./machine", features = ["test-helpers"] } macros = { path = "../util/macros" } null-engine = { path = "./engines/null-engine" } parity-runtime = { path = "../util/runtime" } -pod = { path = "pod" } +pod = { path = "pod", features = ["test-helpers"] } rlp_compress = { path = "../util/rlp-compress" } rustc-hex = "1" serde_json = "1.0" diff --git a/ethcore/pod/Cargo.toml b/ethcore/pod/Cargo.toml index c695b2533cc..ad5d76c052d 100644 --- a/ethcore/pod/Cargo.toml +++ b/ethcore/pod/Cargo.toml @@ -25,4 +25,8 @@ trie-db = "0.15.0" triehash = { package = "triehash-ethereum", version = "0.2", path = "../../util/triehash-ethereum" } [dev-dependencies] +ethjson = { path = "../../json", features = ["test-helpers"] } macros = { path = "../../util/macros" } + +[features] +test-helpers = [] diff --git a/ethcore/pod/src/account.rs b/ethcore/pod/src/account.rs index 42f5abf7416..517adad95b1 100644 --- a/ethcore/pod/src/account.rs +++ b/ethcore/pod/src/account.rs @@ -85,22 +85,6 @@ impl PodAccount { } } -impl From for PodAccount { - fn from(a: ethjson::blockchain::Account) -> Self { - PodAccount { - balance: a.balance.into(), - nonce: a.nonce.into(), - code: Some(a.code.into()), - storage: a.storage.into_iter().map(|(key, value)| { - let key: U256 = key.into(); - let value: U256 = value.into(); - (BigEndianHash::from_uint(&key), BigEndianHash::from_uint(&value)) - }).collect(), - version: a.version.into(), - } - } -} - impl From for PodAccount { fn from(a: ethjson::spec::Account) -> Self { PodAccount { diff --git a/ethcore/pod/src/state.rs b/ethcore/pod/src/state.rs index f83ecc07c7b..e626d54b596 100644 --- a/ethcore/pod/src/state.rs +++ b/ethcore/pod/src/state.rs @@ -46,13 +46,6 @@ impl PodState { } } -impl From for PodState { - fn from(s: ethjson::blockchain::State) -> PodState { - let state = s.into_iter().map(|(addr, acc)| (addr.into(), PodAccount::from(acc))).collect(); - PodState(state) - } -} - impl From for PodState { fn from(s: ethjson::spec::State) -> PodState { let state: BTreeMap<_,_> = s.into_iter() diff --git a/ethcore/spec/Cargo.toml b/ethcore/spec/Cargo.toml index 03e16765b3c..426336294e8 100644 --- a/ethcore/spec/Cargo.toml +++ b/ethcore/spec/Cargo.toml @@ -38,4 +38,10 @@ vm = { path = "../vm" } [dev-dependencies] ethcore = { path = "..", features = ["test-helpers"] } env_logger = "0.5" +pod = { path = "../pod", features = ["test-helpers"] } tempdir = "0.3.7" + +[features] +test-helpers = [ + "pod/test-helpers" +] diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 28e1f567319..352379deaf7 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -44,7 +44,7 @@ fn skip_test(name: &String) -> bool { pub fn json_chain_test(json_data: &[u8], start_stop_hook: &mut H) -> Vec { let _ = ::env_logger::try_init(); - let tests = ethjson::blockchain::Test::load(json_data).unwrap(); + let tests = ethjson::test_helpers::blockchain::Test::load(json_data).unwrap(); let mut failed = Vec::new(); for (name, blockchain) in tests.into_iter() { @@ -84,7 +84,7 @@ pub fn json_chain_test(json_data: &[u8], start_stop_ho { let db = test_helpers::new_db(); let mut config = ClientConfig::default(); - if ethjson::blockchain::Engine::NoProof == blockchain.engine { + if ethjson::test_helpers::blockchain::Engine::NoProof == blockchain.engine { config.verifier_type = VerifierType::CanonNoSeal; config.check_seal = false; } diff --git a/ethcore/src/json_tests/difficulty.rs b/ethcore/src/json_tests/difficulty.rs index 399803bcb35..dc5161a42e4 100644 --- a/ethcore/src/json_tests/difficulty.rs +++ b/ethcore/src/json_tests/difficulty.rs @@ -21,9 +21,13 @@ use spec::Spec; use super::HookType; -pub fn json_difficulty_test(json_data: &[u8], spec: Spec, start_stop_hook: &mut H) -> Vec { +pub fn json_difficulty_test( + json_data: &[u8], + spec: Spec, + start_stop_hook: &mut H +) -> Vec { let _ = ::env_logger::try_init(); - let tests = ethjson::test::DifficultyTest::load(json_data).unwrap(); + let tests = ethjson::test_helpers::difficulty::DifficultyTest::load(json_data).unwrap(); let engine = &spec.engine; for (name, test) in tests.into_iter() { diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 2ce13f6f0aa..2d32de534d8 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -243,8 +243,12 @@ fn do_json_test(json_data: &[u8], h: &mut H) -> Vec(vm_type: &VMType, json_data: &[u8], start_stop_hook: &mut H) -> Vec { - let tests = ethjson::vm::Test::load(json_data).unwrap(); +fn do_json_test_for( + vm_type: &VMType, + json_data: &[u8], + start_stop_hook: &mut H +) -> Vec { + let tests = ethjson::test_helpers::vm::Test::load(json_data).unwrap(); let mut failed = Vec::new(); for (name, vm) in tests.into_iter() { @@ -336,15 +340,15 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8] for (address, account) in vm.post_state.unwrap().into_iter() { let address = address.into(); - let code: Vec = account.code.into(); + let code: Vec = account.code.expect("code is missing from json; test should have code").into(); let found_code = try_fail!(state.code(&address)); let found_balance = try_fail!(state.balance(&address)); let found_nonce = try_fail!(state.nonce(&address)); fail_unless(found_code.as_ref().map_or_else(|| code.is_empty(), |c| &**c == &code), "code is incorrect"); - fail_unless(found_balance == account.balance.into(), "balance is incorrect"); - fail_unless(found_nonce == account.nonce.into(), "nonce is incorrect"); - for (k, v) in account.storage { + fail_unless(account.balance.as_ref().map_or(false, |b| b.0 == found_balance), "balance is incorrect"); + fail_unless(account.nonce.as_ref().map_or(false, |n| n.0 == found_nonce), "nonce is incorrect"); + for (k, v) in account.storage.expect("test should have storage") { let key: U256 = k.into(); let value: U256 = v.into(); let found_storage = try_fail!(state.storage_at(&address, &BigEndianHash::from_uint(&key))); diff --git a/ethcore/src/json_tests/skip.rs b/ethcore/src/json_tests/skip.rs index b6ef9795f69..792b9614b1b 100644 --- a/ethcore/src/json_tests/skip.rs +++ b/ethcore/src/json_tests/skip.rs @@ -16,19 +16,19 @@ //! State tests to skip. -use ethjson; +use ethjson::test_helpers::skip::SkipStates; #[cfg(feature="ci-skip-tests")] -lazy_static!{ - pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = { +lazy_static! { + pub static ref SKIP_TEST_STATE: SkipStates = { let skip_data = include_bytes!("../../res/ethereum/tests-issues/currents.json"); - ethjson::test::SkipStates::load(&skip_data[..]).expect("No invalid json allowed") + SkipStates::load(&skip_data[..]).expect("No invalid json allowed") }; } #[cfg(not(feature="ci-skip-tests"))] lazy_static!{ - pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = { - ethjson::test::SkipStates::empty() + pub static ref SKIP_TEST_STATE: SkipStates = { + SkipStates::empty() }; } diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index dc2714fba4f..24a001b8abe 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -49,7 +49,7 @@ fn skip_test(subname: &str, chain: &String, number: usize) -> bool { pub fn json_chain_test(json_data: &[u8], start_stop_hook: &mut H) -> Vec { let _ = ::env_logger::try_init(); - let tests = ethjson::state::test::Test::load(json_data).unwrap(); + let tests = ethjson::test_helpers::state::Test::load(json_data).unwrap(); let mut failed = Vec::new(); for (name, test) in tests.into_iter() { diff --git a/ethcore/src/json_tests/transaction.rs b/ethcore/src/json_tests/transaction.rs index 149aa6786e9..19bd428e994 100644 --- a/ethcore/src/json_tests/transaction.rs +++ b/ethcore/src/json_tests/transaction.rs @@ -41,7 +41,7 @@ pub fn run_test_file(p: &Path, h: &mut H) { const BLOCK_NUMBER: u64 = 0x6ffffffffffffe; fn do_json_test(json_data: &[u8], start_stop_hook: &mut H) -> Vec { - let tests = ethjson::transaction::Test::load(json_data).unwrap(); + let tests = ethjson::test_helpers::transaction::Test::load(json_data).unwrap(); let mut failed = Vec::new(); for (name, test) in tests.into_iter() { start_stop_hook(&name, HookType::OnStart); diff --git a/ethcore/src/json_tests/trie.rs b/ethcore/src/json_tests/trie.rs index 232cc15fc5b..899c7c7d7a0 100644 --- a/ethcore/src/json_tests/trie.rs +++ b/ethcore/src/json_tests/trie.rs @@ -26,7 +26,7 @@ pub use self::secure::run_test_path as run_secure_test_path; pub use self::secure::run_test_file as run_secure_test_file; fn test_trie(json: &[u8], trie: TrieSpec, start_stop_hook: &mut H) -> Vec { - let tests = ethjson::trie::Test::load(json).unwrap(); + let tests = ethjson::test_helpers::trie::Test::load(json).unwrap(); let factory = TrieFactory::new(trie, ethtrie::Layout); let mut result = vec![]; diff --git a/ethcore/types/src/transaction/transaction.rs b/ethcore/types/src/transaction/transaction.rs index e1139dc1faf..09fdae184aa 100644 --- a/ethcore/types/src/transaction/transaction.rs +++ b/ethcore/types/src/transaction/transaction.rs @@ -134,20 +134,20 @@ impl Transaction { } } -impl From for SignedTransaction { - fn from(t: ethjson::state::Transaction) -> Self { - let to: Option = t.to.into(); +impl From for SignedTransaction { + fn from(t: ethjson::transaction::TransactionWithSigningInfo) -> Self { + let to: Option = t.transaction.to.into(); let secret = t.secret.map(|s| Secret::from(s.0)); let tx = Transaction { - nonce: t.nonce.into(), - gas_price: t.gas_price.into(), - gas: t.gas_limit.into(), + nonce: t.transaction.nonce.into(), + gas_price: t.transaction.gas_price.into(), + gas: t.transaction.gas_limit.into(), action: match to { Some(to) => Action::Call(to.into()), None => Action::Create }, - value: t.value.into(), - data: t.data.into(), + value: t.transaction.value.into(), + data: t.transaction.data.into(), }; match secret { Some(s) => tx.sign(&s, None), @@ -156,20 +156,20 @@ impl From for SignedTransaction { } } -impl From for UnverifiedTransaction { - fn from(t: ethjson::transaction::Transaction) -> Self { - let to: Option = t.to.into(); +impl From for UnverifiedTransaction { + fn from(t: ethjson::transaction::TransactionWithSigningInfo) -> Self { + let to: Option = t.transaction.to.into(); UnverifiedTransaction { unsigned: Transaction { - nonce: t.nonce.into(), - gas_price: t.gas_price.into(), - gas: t.gas_limit.into(), + nonce: t.transaction.nonce.into(), + gas_price: t.transaction.gas_price.into(), + gas: t.transaction.gas_limit.into(), action: match to { Some(to) => Action::Call(to.into()), None => Action::Create }, - value: t.value.into(), - data: t.data.into(), + value: t.transaction.value.into(), + data: t.transaction.data.into(), }, r: t.r.into(), s: t.s.into(), diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index 5f2819ec2ee..d08e1029e2b 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -31,6 +31,7 @@ vm = { path = "../ethcore/vm" } [dev-dependencies] criterion = "0.3" tempdir = "0.3" +pod = { path = "../ethcore/pod", features = ["test-helpers"] } [features] evm-debug = ["ethcore/evm-debug-tests"] diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index 78036c60f36..eceeb995524 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -122,7 +122,7 @@ fn main() { } fn run_state_test(args: Args) { - use ethjson::state::test::Test; + use ethjson::test_helpers::state::Test; // Parse the specified state test JSON file provided to the command `state-test `. let file = args.arg_file.expect("PATH to a state test JSON file is required"); @@ -443,8 +443,8 @@ fn die(msg: T) -> ! { mod tests { use common_types::transaction; use docopt::Docopt; - use ethcore::{TrieSpec}; - use ethjson::state::test::{State}; + use ethcore::TrieSpec; + use ethjson::test_helpers::state::State; use serde::Deserialize; use super::{Args, USAGE, Address, run_call}; diff --git a/json/Cargo.toml b/json/Cargo.toml index 175155e9d41..de65388534f 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -3,10 +3,13 @@ description = "Parity Ethereum JSON Deserialization" name = "ethjson" version = "0.1.0" authors = ["Parity Technologies "] +edition = "2018" [dependencies] ethereum-types = "0.6.0" rustc-hex = "1.0" -serde = "1.0" +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_derive = "1.0" + +[features] +test-helpers = [] diff --git a/json/src/blockchain/account.rs b/json/src/blockchain/account.rs deleted file mode 100644 index 535992ae01f..00000000000 --- a/json/src/blockchain/account.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain test account deserializer. - -use std::collections::BTreeMap; -use uint::Uint; -use bytes::Bytes; - -/// Blockchain test account deserializer. -#[derive(Debug, PartialEq, Deserialize, Clone)] -pub struct Account { - /// Balance. - pub balance: Uint, - /// Code. - pub code: Bytes, - /// Nonce. - pub nonce: Uint, - /// Storage. - pub storage: BTreeMap, - /// Version. - #[serde(default)] - pub version: Uint, -} - -#[cfg(test)] -mod tests { - use serde_json; - use blockchain::account::Account; - - #[test] - fn account_deserialization() { - let s = r#"{ - "balance" : "0x09184e72a078", - "code" : "0x600140600155", - "nonce" : "0x00", - "storage" : { - "0x01" : "0x9a10c2b5bb8f3c602e674006d9b21f09167df57c87a78a5ce96d4159ecb76520" - } - }"#; - let _deserialized: Account = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/blockchain/block.rs b/json/src/blockchain/block.rs deleted file mode 100644 index 23ba5300dc2..00000000000 --- a/json/src/blockchain/block.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain test block deserializer. - -use bytes::Bytes; -use blockchain::header::Header; -use blockchain::transaction::Transaction; - -/// Blockchain test block deserializer. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Block { - #[serde(rename = "blockHeader")] - header: Option
, - rlp: Bytes, - transactions: Option>, - #[serde(rename = "uncleHeaders")] - uncles: Option>, -} - -impl Block { - /// Returns block rlp. - pub fn rlp(&self) -> Vec { - self.rlp.clone().into() - } -} - -#[cfg(test)] -mod tests { - use serde_json; - use blockchain::block::Block; - - #[test] - fn block_deserialization() { - let s = r#"{ - "blockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "0x020000", - "extraData" : "0x", - "gasLimit" : "0x2fefba", - "gasUsed" : "0x00", - "hash" : "65ebf1b97fb89b14680267e0723d69267ec4bf9a96d4a60ffcb356ae0e81c18f", - "mixHash" : "13735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd06", - "nonce" : "931dcc53e5edc514", - "number" : "0x01", - "parentHash" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3", - "timestamp" : "0x56850b7b", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "blocknumber" : "1", - "rlp" : "0xf901fcf901f7a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba808456850b7b80a013735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd0688931dcc53e5edc514c0c0", - "transactions" : [], - "uncleHeaders" : [] - }"#; - let _deserialized: Block = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/blockchain/blockchain.rs b/json/src/blockchain/blockchain.rs deleted file mode 100644 index b92336f793a..00000000000 --- a/json/src/blockchain/blockchain.rs +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain deserialization. - -use bytes::Bytes; -use hash::H256; -use blockchain::state::State; -use blockchain::header::Header; -use blockchain::block::Block; -use spec::{ForkSpec, Genesis, Seal, Ethereum}; - -/// Json Block test possible engine kind. -#[derive(Debug, PartialEq, Deserialize)] -pub enum Engine { - /// Default (old) behaviour. - Ethash, - /// No check of block's difficulty and nonce for tests. - NoProof, -} - -impl Default for Engine { - fn default() -> Self { - Engine::Ethash - } -} - -/// Blockchain deserialization. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct BlockChain { - /// Genesis block header. - #[serde(rename = "genesisBlockHeader")] - pub genesis_block: Header, - /// Genesis block rlp. - #[serde(rename = "genesisRLP")] - pub genesis_rlp: Option, - /// Blocks. - pub blocks: Vec, - /// Post state. - pub post_state: State, - /// Pre state. - #[serde(rename = "pre")] - pub pre_state: State, - /// Hash of best block. - #[serde(rename = "lastblockhash")] - pub best_block: H256, - /// Network. - pub network: ForkSpec, - #[serde(default)] - #[serde(rename="sealEngine")] - /// Engine - pub engine: Engine, -} - -impl BlockChain { - /// Returns blocks rlp. - 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 { - seal: Seal::Ethereum(Ethereum { - nonce: self.genesis_block.nonce.clone(), - mix_hash: self.genesis_block.mix_hash.clone(), - }), - difficulty: self.genesis_block.difficulty, - author: Some(self.genesis_block.author.clone()), - timestamp: Some(self.genesis_block.timestamp), - parent_hash: Some(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()), - } - } -} - -#[cfg(test)] -mod tests { - use serde_json; - use blockchain::blockchain::BlockChain; - - #[test] - fn blockchain_deserialization() { - let s = r#"{ - "blocks" : [{ - "blockHeader" : { - "bloom" : "00000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000040000000000000000000000000000000000000000000000000000000", - "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "0x020000", - "extraData" : "0x0102030405060708091011121314151617181920212223242526272829303132", - "gasLimit" : "0x2fefba", - "gasUsed" : "0x560b", - "hash" : "06b5b1742bde29468510c92641f36b719c61b3fc3e9a21c92a23978f4f7faa2a", - "mixHash" : "5266ca43e81d25925a9ba573c3e4f9180bc076d316d90e63c6f8708b272f5ce2", - "nonce" : "59ba4daed1898e21", - "number" : "0x01", - "parentHash" : "f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524d", - "receiptTrie" : "c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296", - "stateRoot" : "bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bf", - "timestamp" : "0x56850c2c", - "transactionsTrie" : "498785da562aa0c5dd5937cf15f22139b0b1bcf3b4fc48986e1bb1dae9292796", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "rlp" : "0xf90285f90219a0f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bfa0498785da562aa0c5dd5937cf15f22139b0b1bcf3b4fc48986e1bb1dae9292796a0c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefba82560b8456850c2ca00102030405060708091011121314151617181920212223242526272829303132a05266ca43e81d25925a9ba573c3e4f9180bc076d316d90e63c6f8708b272f5ce28859ba4daed1898e21f866f864800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d8785012a05f200801ca0ee0b9ec878fbd4258a9473199d8ecc32996a20c323c004e79e0cda20e0418ce3a04e6bc63927d1510bab54f37e46fa036faf4b2c465d271920d9afea1fadf7bd21c0", - "transactions" : [ - { - "data" : "0x00", - "gasLimit" : "0xc350", - "gasPrice" : "0x0a", - "nonce" : "0x00", - "r" : "0xee0b9ec878fbd4258a9473199d8ecc32996a20c323c004e79e0cda20e0418ce3", - "s" : "0x4e6bc63927d1510bab54f37e46fa036faf4b2c465d271920d9afea1fadf7bd21", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v" : "0x1c", - "value" : "0x012a05f200" - } - ], - "uncleHeaders" : [ - ] - }], - "network" : "Frontier", - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "0x020000", - "extraData" : "0x42", - "gasLimit" : "0x2fefd8", - "gasUsed" : "0x00", - "hash" : "f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524d", - "mixHash" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "nonce" : "0102030405060708", - "number" : "0x00", - "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7", - "timestamp" : "0x54c98c81", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", - "lastblockhash" : "06b5b1742bde29468510c92641f36b719c61b3fc3e9a21c92a23978f4f7faa2a", - "postState" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x012a05f264", - "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", - "nonce" : "0x00", - "storage" : { - } - }, - "8888f1f195afa192cfee860698584c030f4c9db1" : { - "balance" : "0x4563918244f75c6e", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x012a029592", - "code" : "0x", - "nonce" : "0x01", - "storage" : { - } - } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x64", - "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", - "nonce" : "0x00", - "storage" : { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x02540be400", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - } - } - }"#; - let _deserialized: BlockChain = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/blockchain/header.rs b/json/src/blockchain/header.rs deleted file mode 100644 index 8de5b16edb6..00000000000 --- a/json/src/blockchain/header.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain test header deserializer. - -use hash::{H64, Address, H256, Bloom}; -use uint::Uint; -use bytes::Bytes; - -/// Blockchain test header deserializer. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Header { - /// Blocks bloom. - pub bloom: Bloom, - /// Blocks author. - #[serde(rename = "coinbase")] - pub author: Address, - /// Difficulty. - pub difficulty: Uint, - /// Extra data. - pub extra_data: Bytes, - /// Gas limit. - pub gas_limit: Uint, - /// Gas used. - pub gas_used: Uint, - /// Hash. - pub hash: H256, - /// Mix hash. - pub mix_hash: H256, - /// Seal nonce. - pub nonce: H64, - /// Block number. - pub number: Uint, - /// Parent hash. - pub parent_hash: H256, - /// Receipt root. - #[serde(rename = "receiptTrie")] - pub receipts_root: H256, - /// State root. - pub state_root: H256, - /// Timestamp. - pub timestamp: Uint, - /// Transactions root. - #[serde(rename = "transactionsTrie")] - pub transactions_root: H256, - /// Uncles hash. - #[serde(rename = "uncleHash")] - pub uncles_hash: H256, -} - -#[cfg(test)] -mod tests { - use serde_json; - use blockchain::header::Header; - - #[test] - fn header_deserialization() { - let s = r#"{ - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "0x020000", - "extraData" : "0x", - "gasLimit" : "0x2fefba", - "gasUsed" : "0x00", - "hash" : "65ebf1b97fb89b14680267e0723d69267ec4bf9a96d4a60ffcb356ae0e81c18f", - "mixHash" : "13735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd06", - "nonce" : "931dcc53e5edc514", - "number" : "0x01", - "parentHash" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3", - "timestamp" : "0x56850b7b", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }"#; - let _deserialized: Header = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/blockchain/mod.rs b/json/src/blockchain/mod.rs deleted file mode 100644 index 0a3b162e95f..00000000000 --- a/json/src/blockchain/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain test deserialization. - -pub mod account; -pub mod block; -pub mod blockchain; -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::blockchain::Engine; -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/state.rs b/json/src/blockchain/state.rs deleted file mode 100644 index e108c937f8a..00000000000 --- a/json/src/blockchain/state.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain test state deserializer. - -use std::collections::BTreeMap; -use hash::Address; -use blockchain::account::Account; - -/// Blockchain test state deserializer. -#[derive(Debug, PartialEq, Deserialize, Clone)] -pub struct State(BTreeMap); - -impl IntoIterator for State { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} diff --git a/json/src/blockchain/test.rs b/json/src/blockchain/test.rs deleted file mode 100644 index d773aa3b510..00000000000 --- a/json/src/blockchain/test.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain test deserializer. - -use std::collections::BTreeMap; -use std::io::Read; -use serde_json; -use serde_json::Error; -use blockchain::blockchain::BlockChain; - -/// Blockchain test deserializer. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Test(BTreeMap); - -impl IntoIterator for Test { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -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/blockchain/transaction.rs b/json/src/blockchain/transaction.rs deleted file mode 100644 index 4e519f394ee..00000000000 --- a/json/src/blockchain/transaction.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Blockchain test transaction deserialization. - -use uint::Uint; -use bytes::Bytes; - -/// Blockchain test transaction deserialization. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Transaction { - data: Bytes, - gas_limit: Uint, - gas_price: Uint, - nonce: Uint, - r: Uint, - s: Uint, - v: Uint, - value: Uint -} diff --git a/json/src/bytes.rs b/json/src/bytes.rs index 5956cd4286b..711e921851d 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -63,10 +63,10 @@ impl FromStr for Bytes { 2 if value.starts_with("0x") => vec![], _ if value.starts_with("0x") && value.len() % 2 == 1 => { let v = "0".to_owned() + &value[2..]; - FromHex::from_hex(v.as_str()).unwrap_or(vec![]) + FromHex::from_hex(v.as_str()).unwrap_or_default() }, - _ if value.starts_with("0x") => FromHex::from_hex(&value[2..]).unwrap_or(vec![]), - _ => FromHex::from_hex(value).unwrap_or(vec![]), + _ if value.starts_with("0x") => FromHex::from_hex(&value[2..]).unwrap_or_default(), + _ => FromHex::from_hex(value).unwrap_or_default(), }; Ok(Bytes(v)) @@ -100,8 +100,7 @@ impl<'a> Visitor<'a> for BytesVisitor { #[cfg(test)] mod test { - use serde_json; - use bytes::Bytes; + use super::*; #[test] fn bytes_deserialization() { diff --git a/json/src/hash.rs b/json/src/hash.rs index 3e364b950e2..d724b4c9617 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -94,10 +94,8 @@ impl_hash!(Bloom, Hash2048); #[cfg(test)] mod test { + use super::*; use std::str::FromStr; - use serde_json; - use ethereum_types; - use hash::H256; #[test] fn hash_deserialization() { diff --git a/json/src/lib.rs b/json/src/lib.rs index af5d93edfa6..37480d3d137 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -14,20 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -extern crate rustc_hex; -extern crate serde; -extern crate serde_json; -extern crate ethereum_types; -#[macro_use] extern crate serde_derive; +#![warn(missing_docs)] + +//! JSON deserialization library -pub mod hash; -pub mod uint; pub mod bytes; -pub mod blockchain; +pub mod hash; +pub mod maybe; pub mod spec; -pub mod trie; +pub mod uint; pub mod vm; -pub mod maybe; -pub mod state; pub mod transaction; -pub mod test; +pub mod state; + +#[cfg(any(test, feature = "test-helpers"))] +pub mod test_helpers; diff --git a/json/src/maybe.rs b/json/src/maybe.rs index 4fd2ca60e49..fd5a88dd519 100644 --- a/json/src/maybe.rs +++ b/json/src/maybe.rs @@ -61,11 +61,10 @@ impl<'a, T> Visitor<'a> for MaybeEmptyVisitor where T: Deserialize<'a> { } fn visit_string(self, value: String) -> Result where E: Error { - match value.is_empty() { - true => Ok(MaybeEmpty::None), - false => { - T::deserialize(value.into_deserializer()).map(MaybeEmpty::Some) - } + if value.is_empty() { + Ok(MaybeEmpty::None) + } else { + T::deserialize(value.into_deserializer()).map(MaybeEmpty::Some) } } } @@ -81,11 +80,9 @@ impl Into> for MaybeEmpty { #[cfg(test)] mod tests { + use super::*; use std::str::FromStr; - use serde_json; - use ethereum_types; - use hash::H256; - use maybe::MaybeEmpty; + use crate::hash::H256; #[test] fn maybe_deserialization() { diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs index 7e849a6bcff..1267eaf64e7 100644 --- a/json/src/spec/account.rs +++ b/json/src/spec/account.rs @@ -17,11 +17,12 @@ //! Spec account deserialization. use std::collections::BTreeMap; -use uint::Uint; -use bytes::Bytes; -use spec::builtin::Builtin; + +use crate::{bytes::Bytes, spec::builtin::Builtin, uint::Uint}; +use serde::Deserialize; /// Spec account. +#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))] #[derive(Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] pub struct Account { @@ -50,12 +51,9 @@ impl Account { #[cfg(test)] mod tests { + use super::*; use std::collections::BTreeMap; - use serde_json; - use spec::account::Account; use ethereum_types::U256; - use uint::Uint; - use bytes::Bytes; #[test] fn account_balance_missing_not_empty() { diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 615cc4ca546..4549b2369ae 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -39,9 +39,8 @@ //! ``` use std::collections::BTreeMap; -use hash::Address; -use uint::Uint; -use bytes::Bytes; +use crate::{bytes::Bytes, hash::Address, uint::Uint}; +use serde::Deserialize; use super::ValidatorSet; /// Authority params deserialization. @@ -108,12 +107,9 @@ pub struct AuthorityRound { #[cfg(test)] mod tests { + use super::*; use ethereum_types::{U256, H160}; - use uint::Uint; - use serde_json; - use hash::Address; - use spec::validator_set::ValidatorSet; - use spec::authority_round::AuthorityRound; + use crate::spec::{validator_set::ValidatorSet, authority_round::AuthorityRound}; use std::str::FromStr; #[test] diff --git a/json/src/spec/basic_authority.rs b/json/src/spec/basic_authority.rs index c21333a12ce..8f8c10fc4aa 100644 --- a/json/src/spec/basic_authority.rs +++ b/json/src/spec/basic_authority.rs @@ -16,8 +16,9 @@ //! Authority params deserialization. -use uint::Uint; +use crate::uint::Uint; use super::ValidatorSet; +use serde::Deserialize; /// Authority params deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -40,12 +41,11 @@ pub struct BasicAuthority { #[cfg(test)] mod tests { - use serde_json; - use uint::Uint; + use super::*; use ethereum_types::{U256, H160}; - use hash::Address; - use spec::basic_authority::BasicAuthority; - use spec::validator_set::ValidatorSet; + use crate::hash::Address; + use crate::spec::basic_authority::BasicAuthority; + use crate::spec::validator_set::ValidatorSet; use std::str::FromStr; #[test] diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index 20ebbc3c636..d4aa7af7fbb 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -16,7 +16,8 @@ //! Spec builtin deserialization. -use uint::Uint; +use crate::uint::Uint; +use serde::Deserialize; /// Price per round of Blake2 compression. pub type Blake2F = u64; @@ -96,9 +97,7 @@ pub struct Builtin { #[cfg(test)] mod tests { - use serde_json; - use spec::builtin::{Builtin, Pricing, Linear, Modexp}; - use uint::Uint; + use super::*; #[test] fn builtin_deserialization() { diff --git a/json/src/spec/clique.rs b/json/src/spec/clique.rs index cef0ebfb81a..a7cbff9d49c 100644 --- a/json/src/spec/clique.rs +++ b/json/src/spec/clique.rs @@ -17,6 +17,7 @@ //! Clique params deserialization. use std::num::NonZeroU64; +use serde::Deserialize; /// Clique params deserialization. #[derive(Debug, PartialEq, Deserialize)] diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index cfa1d8cafd1..a356f256261 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -17,6 +17,7 @@ //! Engine deserialization. use super::{Ethash, BasicAuthority, AuthorityRound, NullEngine, InstantSeal, Clique}; +use serde::Deserialize; /// Engine deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -40,8 +41,7 @@ pub enum Engine { #[cfg(test)] mod tests { - use serde_json; - use spec::Engine; + use super::*; #[test] fn engine_deserialization() { diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index c9748c94459..5b12473dd3e 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -17,9 +17,12 @@ //! Ethash params deserialization. use std::collections::BTreeMap; -use uint::{self, Uint}; -use bytes::Bytes; -use hash::Address; +use crate::{ + bytes::Bytes, + uint::{self, Uint}, + hash::Address +}; +use serde::Deserialize; /// Deserializable doppelganger of block rewards for EthashParams #[derive(Clone, Debug, PartialEq, Deserialize)] @@ -110,11 +113,8 @@ pub struct Ethash { #[cfg(test)] mod tests { - use serde_json; - use uint::Uint; + use super::*; use ethereum_types::{H160, U256}; - use hash::Address; - use spec::ethash::{Ethash, EthashParams, BlockReward}; use std::str::FromStr; #[test] diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs index 6c6def199af..5d5505930bf 100644 --- a/json/src/spec/genesis.rs +++ b/json/src/spec/genesis.rs @@ -16,10 +16,13 @@ //! Spec genesis deserialization. -use uint::{Uint, self}; -use hash::{Address, H256}; -use bytes::Bytes; -use spec::Seal; +use crate::{ + bytes::Bytes, + hash::{Address, H256}, + spec::Seal, + uint::{Uint, self}, +}; +use serde::Deserialize; /// Spec genesis. #[derive(Debug, PartialEq, Deserialize)] @@ -53,13 +56,12 @@ pub struct Genesis { #[cfg(test)] mod tests { - use serde_json; - use bytes::Bytes; - use uint::Uint; + use super::*; + use crate::{ + hash::H64, + spec::{Ethereum, Seal} + }; use ethereum_types::{U256, H160, H64 as Eth64, H256 as Eth256}; - use hash::{H64, H256, Address}; - use spec::genesis::Genesis; - use spec::{Ethereum, Seal}; use std::str::FromStr; #[test] diff --git a/json/src/spec/hardcoded_sync.rs b/json/src/spec/hardcoded_sync.rs index eed3dac65e0..5d297d57d51 100644 --- a/json/src/spec/hardcoded_sync.rs +++ b/json/src/spec/hardcoded_sync.rs @@ -16,9 +16,8 @@ //! Spec hardcoded synchronization deserialization for the light client. -use hash::H256; -use uint::Uint; -use bytes::Bytes; +use crate::{bytes::Bytes, hash::H256, uint::Uint}; +use serde::Deserialize; /// Spec hardcoded sync. #[derive(Debug, PartialEq, Deserialize)] @@ -36,11 +35,8 @@ pub struct HardcodedSync { #[cfg(test)] mod tests { - use serde_json; - use uint::Uint; + use super::*; use ethereum_types::{U256, H256 as Eth256}; - use hash::H256; - use spec::hardcoded_sync::HardcodedSync; use std::str::FromStr; #[test] diff --git a/json/src/spec/instant_seal.rs b/json/src/spec/instant_seal.rs index 2f1ad33e9bc..ce03322992b 100644 --- a/json/src/spec/instant_seal.rs +++ b/json/src/spec/instant_seal.rs @@ -16,6 +16,8 @@ //! Instant seal engine params deserialization. +use serde::Deserialize; + /// Instant seal engine params deserialization. #[derive(Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] diff --git a/json/src/spec/null_engine.rs b/json/src/spec/null_engine.rs index 37ade47832f..1413a3e4051 100644 --- a/json/src/spec/null_engine.rs +++ b/json/src/spec/null_engine.rs @@ -16,7 +16,8 @@ //! Null engine params deserialization. -use uint::Uint; +use crate::uint::Uint; +use serde::Deserialize; /// Authority params deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -39,10 +40,8 @@ pub struct NullEngine { #[cfg(test)] mod tests { - use serde_json; - use uint::Uint; - use ethereum_types::U256; use super::*; + use ethereum_types::U256; #[test] fn null_engine_deserialization() { diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 58adbd6a468..29ebeab1553 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -16,9 +16,12 @@ //! Spec params deserialization. -use uint::{self, Uint}; -use hash::{H256, Address}; -use bytes::Bytes; +use crate::{ + bytes::Bytes, + hash::{H256, Address}, + uint::{self, Uint} +}; +use serde::Deserialize; /// Spec params. #[derive(Debug, PartialEq, Deserialize)] @@ -140,18 +143,16 @@ pub struct Params { #[cfg(test)] mod tests { - use serde_json; - use uint::Uint; + use super::*; use ethereum_types::U256; - use spec::params::Params; #[test] fn params_deserialization() { let s = r#"{ "maximumExtraDataSize": "0x20", - "networkID" : "0x1", - "chainID" : "0x15", - "subprotocolName" : "exp", + "networkID": "0x1", + "chainID": "0x15", + "subprotocolName": "exp", "minGasLimit": "0x1388", "accountStartNonce": "0x01", "gasLimitBoundDivisor": "0x20", diff --git a/json/src/spec/seal.rs b/json/src/spec/seal.rs index 67238a5f5c0..d79dfbda0af 100644 --- a/json/src/spec/seal.rs +++ b/json/src/spec/seal.rs @@ -16,9 +16,8 @@ //! Spec seal deserialization. -use hash::*; -use uint::Uint; -use bytes::Bytes; +use crate::{bytes::Bytes, hash::{H64, H256, H520}, uint::Uint}; +use serde::Deserialize; /// Ethereum seal. #[derive(Debug, PartialEq, Deserialize)] @@ -70,12 +69,10 @@ pub enum Seal { #[cfg(test)] mod tests { + use super::*; use serde_json; - use hash::*; - use bytes::Bytes; - use uint::Uint; use ethereum_types::{U256, H64 as Eth64, H256 as Eth256, H520 as Eth520}; - use spec::{Ethereum, AuthorityRoundSeal, TendermintSeal, Seal}; + use crate::spec::{Ethereum, AuthorityRoundSeal, TendermintSeal, Seal}; use std::str::FromStr; #[test] diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index 68824cad99b..9f4955add81 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -17,9 +17,9 @@ //! Spec deserialization. use std::io::Read; -use serde_json; +use crate::spec::{Params, Genesis, Engine, State, HardcodedSync}; +use serde::Deserialize; use serde_json::Error; -use spec::{Params, Genesis, Engine, State, HardcodedSync}; /// Fork spec definition #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)] @@ -69,8 +69,7 @@ impl Spec { #[cfg(test)] mod tests { - use serde_json; - use spec::spec::Spec; + use super::*; #[test] fn should_error_on_unknown_fields() { diff --git a/json/src/spec/state.rs b/json/src/spec/state.rs index e8a8663672e..df9b09ce28b 100644 --- a/json/src/spec/state.rs +++ b/json/src/spec/state.rs @@ -14,14 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -//! Blockchain test state deserializer. +//! Blockchain state deserializer. use std::collections::BTreeMap; -use hash::Address; -use bytes::Bytes; -use spec::{Account, Builtin}; - -/// Blockchain test state deserializer. +use crate::{ + bytes::Bytes, + hash::Address, + spec::{Account, Builtin} +}; +use serde::Deserialize; + +/// Blockchain state deserializer. +#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))] #[derive(Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] pub struct State(BTreeMap); diff --git a/json/src/spec/validator_set.rs b/json/src/spec/validator_set.rs index 4de1d3aa0b5..aac17000df2 100644 --- a/json/src/spec/validator_set.rs +++ b/json/src/spec/validator_set.rs @@ -17,8 +17,8 @@ //! Validator set deserialization. use std::collections::BTreeMap; -use uint::Uint; -use hash::Address; +use crate::{hash::Address, uint::Uint}; +use serde::Deserialize; /// Different ways of specifying validators. #[derive(Debug, PartialEq, Deserialize)] @@ -37,11 +37,8 @@ pub enum ValidatorSet { #[cfg(test)] mod tests { - use serde_json; - use uint::Uint; + use super::*; use ethereum_types::{H160, U256}; - use hash::Address; - use spec::validator_set::ValidatorSet; use std::str::FromStr; #[test] diff --git a/json/src/state/log.rs b/json/src/state/log.rs deleted file mode 100644 index 1a0dda5295a..00000000000 --- a/json/src/state/log.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! State test log deserialization. -use hash::{Address, H256, Bloom}; -use bytes::Bytes; - -/// State test log deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Log { - /// Address. - pub address: Address, - /// Topics. - pub topics: Vec, - /// Data. - pub data: Bytes, - /// Bloom. - pub bloom: Bloom, -} - -#[cfg(test)] -mod tests { - use serde_json; - use state::Log; - - #[test] - fn log_deserialization() { - let s = r#"{ - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "topics" : [ - "0000000000000000000000000000000000000000000000000000000000000000" - ] - }"#; - let _deserialized: Log = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/state/mod.rs b/json/src/state/mod.rs deleted file mode 100644 index 8c2ac287535..00000000000 --- a/json/src/state/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! State test deserialization. - -pub mod state; -pub mod transaction; -pub mod test; -pub mod log; - -pub use self::state::State; -pub use self::transaction::Transaction; -pub use self::test::Test; -pub use self::log::Log; -pub use vm::Env as Env; -pub use blockchain::State as AccountState; diff --git a/json/src/state/state.rs b/json/src/state/state.rs deleted file mode 100644 index f25dabec798..00000000000 --- a/json/src/state/state.rs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! State test deserialization. - -use bytes::Bytes; -use hash::H256; -use state::{Env, AccountState, Transaction, Log}; - -/// State test deserialization. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct State { - /// Environment. - pub env: Env, - /// Output. - #[serde(rename = "out")] - pub output: Bytes, - /// Pre state. - #[serde(rename = "pre")] - pub pre_state: AccountState, - /// Post state. - #[serde(rename = "post")] - pub post_state: AccountState, - /// Post state root. - pub post_state_root: H256, - /// Transaction. - pub transaction: Transaction, - /// Logs. - pub logs: Vec -} - -#[cfg(test)] -mod tests { - use serde_json; - use state::State; - - #[test] - fn state_deserialization() { - let s = r#"{ - "env" : { - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "0x0100", - "currentGasLimit" : "0x01c9c380", - "currentNumber" : "0x00", - "currentTimestamp" : "0x01", - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" - }, - "logs" : [ - ], - "out" : "0x", - "post" : { - "1000000000000000000000000000000000000000" : { - "balance" : "0x0de0b6b3a763ffff", - "code" : "0x6040600060406000600173100000000000000000000000000000000000000162055730f1600055", - "nonce" : "0x00", - "storage" : { - "0x00" : "0x01" - } - }, - "1000000000000000000000000000000000000001" : { - "balance" : "0x0de0b6b3a763ffff", - "code" : "0x604060006040600060027310000000000000000000000000000000000000026203d090f1600155", - "nonce" : "0x00", - "storage" : { - "0x01" : "0x01" - } - }, - "1000000000000000000000000000000000000002" : { - "balance" : "0x02", - "code" : "0x600160025533600455346007553060e6553260e8553660ec553860ee553a60f055", - "nonce" : "0x00", - "storage" : { - "0x02" : "0x01", - "0x04" : "0x1000000000000000000000000000000000000001", - "0x07" : "0x02", - "0xe6" : "0x1000000000000000000000000000000000000002", - "0xe8" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0xec" : "0x40", - "0xee" : "0x21", - "0xf0" : "0x01" - } - }, - "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { - "balance" : "0x039455", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x0de0b6b3a7606bab", - "code" : "0x", - "nonce" : "0x01", - "storage" : { - } - } - }, - "postStateRoot" : "8f8ed2aed2973e159fa5486f47c6ebf15c5058f8e2350286b84b569bc6ce2d25", - "pre" : { - "1000000000000000000000000000000000000000" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x6040600060406000600173100000000000000000000000000000000000000162055730f1600055", - "nonce" : "0x00", - "storage" : { - } - }, - "1000000000000000000000000000000000000001" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x604060006040600060027310000000000000000000000000000000000000026203d090f1600155", - "nonce" : "0x00", - "storage" : { - } - }, - "1000000000000000000000000000000000000002" : { - "balance" : "0x00", - "code" : "0x600160025533600455346007553060e6553260e8553660ec553860ee553a60f055", - "nonce" : "0x00", - "storage" : { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - } - }, - "transaction" : { - "data" : "", - "gasLimit" : "0x2dc6c0", - "gasPrice" : "0x01", - "nonce" : "0x00", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "1000000000000000000000000000000000000000", - "value" : "0x00" - } - }"#; - let _deserialized: State = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/state/test.rs b/json/src/state/test.rs deleted file mode 100644 index b8e5f35f694..00000000000 --- a/json/src/state/test.rs +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! General test deserialization. - -use std::io::Read; -use std::collections::BTreeMap; -use uint::Uint; -use bytes::Bytes; -use hash::{Address, H256}; -use spec::ForkSpec; -use state::{Env, AccountState, Transaction}; -use maybe::MaybeEmpty; -use serde_json::{self, Error}; - -/// State test deserializer. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Test(BTreeMap); - -impl IntoIterator for Test { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl Test { - /// Loads test from json. - pub fn load(reader: R) -> Result where R: Read { - serde_json::from_reader(reader) - } -} - -/// State test deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct State { - /// Environment. - pub env: Env, - /// Pre state. - #[serde(rename = "pre")] - pub pre_state: AccountState, - /// Post state. - #[serde(rename = "post")] - pub post_states: BTreeMap>, - /// Transaction. - pub transaction: MultiTransaction, -} - -/// State test transaction deserialization. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct MultiTransaction { - /// Transaction data set. - pub data: Vec, - /// Gas limit set. - pub gas_limit: Vec, - /// Gas price. - pub gas_price: Uint, - /// Nonce. - pub nonce: Uint, - /// Secret key. - #[serde(rename = "secretKey")] - pub secret: Option, - /// To. - pub to: MaybeEmpty
, - /// Value set. - pub value: Vec, -} - -impl MultiTransaction { - /// Build transaction with given indexes. - pub fn select(&self, indexes: &PostStateIndexes) -> Transaction { - Transaction { - data: self.data[indexes.data as usize].clone(), - gas_limit: self.gas_limit[indexes.gas as usize].clone(), - gas_price: self.gas_price.clone(), - nonce: self.nonce.clone(), - secret: self.secret.clone(), - to: self.to.clone(), - value: self.value[indexes.value as usize].clone(), - } - } -} - -/// State test indexes deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct PostStateIndexes { - /// Index into transaction data set. - pub data: u64, - /// Index into transaction gas limit set. - pub gas: u64, - /// Index into transaction value set. - pub value: u64, -} - -/// State test indexed state result deserialization. -#[derive(Debug, PartialEq, Deserialize)] -pub struct PostStateResult { - /// Post state hash - pub hash: H256, - /// Indexes - pub indexes: PostStateIndexes, -} - -#[cfg(test)] -mod tests { - use serde_json; - use super::{MultiTransaction, State}; - - #[test] - fn multi_transaction_deserialization() { - let s = r#"{ - "data": [ "" ], - "gasLimit": [ "0x2dc6c0", "0x222222" ], - "gasPrice": "0x01", - "nonce": "0x00", - "secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to": "1000000000000000000000000000000000000000", - "value": [ "0x00", "0x01", "0x02" ] - }"#; - let _deserialized: MultiTransaction = serde_json::from_str(s).unwrap(); - } - - #[test] - fn state_deserialization() { - let s = r#"{ - "env": { - "currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty": "0x0100", - "currentGasLimit": "0x01c9c380", - "currentNumber": "0x00", - "currentTimestamp": "0x01", - "previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" - }, - "post": { - "EIP150": [ - { - "hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f", - "indexes": { "data": 0, "gas": 0, "value": 0 } - }, - { - "hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764", - "indexes": { "data": 0, "gas": 0, "value": 1 } - } - ], - "EIP158": [ - { - "hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f", - "indexes": { "data": 0, "gas": 0, "value": 0 } - }, - { - "hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764", - "indexes": { "data": 0, "gas": 0, "value": 1 } - } - ] - }, - "pre": { - "1000000000000000000000000000000000000000": { - "balance": "0x0de0b6b3a7640000", - "code": "0x6040600060406000600173100000000000000000000000000000000000000162055730f1600055", - "nonce": "0x00", - "storage": { - } - }, - "1000000000000000000000000000000000000001": { - "balance": "0x0de0b6b3a7640000", - "code": "0x604060006040600060027310000000000000000000000000000000000000026203d090f1600155", - "nonce": "0x00", - "storage": { - } - }, - "1000000000000000000000000000000000000002": { - "balance": "0x00", - "code": "0x600160025533600455346007553060e6553260e8553660ec553860ee553a60f055", - "nonce": "0x00", - "storage": { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { - "balance": "0x0de0b6b3a7640000", - "code": "0x", - "nonce": "0x00", - "storage": { - } - } - }, - "transaction": { - "data": [ "" ], - "gasLimit": [ "285000", "100000", "6000" ], - "gasPrice": "0x01", - "nonce": "0x00", - "secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to": "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value": [ "10", "0" ] - } - }"#; - let _deserialized: State = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/state/transaction.rs b/json/src/state/transaction.rs deleted file mode 100644 index 693b976994e..00000000000 --- a/json/src/state/transaction.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! State test transaction deserialization. - -use uint::Uint; -use bytes::Bytes; -use hash::{Address, H256}; -use maybe::MaybeEmpty; - -/// State test transaction deserialization. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Transaction { - /// Transaction data. - pub data: Bytes, - /// Gas limit. - pub gas_limit: Uint, - /// Gas price. - pub gas_price: Uint, - /// Nonce. - pub nonce: Uint, - /// Secret key. - #[serde(rename = "secretKey")] - pub secret: Option, - /// To. - pub to: MaybeEmpty
, - /// Value. - pub value: Uint, -} - -#[cfg(test)] -mod tests { - use serde_json; - use state::Transaction; - - #[test] - fn transaction_deserialization() { - let s = r#"{ - "data" : "", - "gasLimit" : "0x2dc6c0", - "gasPrice" : "0x01", - "nonce" : "0x00", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "1000000000000000000000000000000000000000", - "value" : "0x00" - }"#; - let _deserialized: Transaction = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/test/mod.rs b/json/src/test/mod.rs deleted file mode 100644 index 355d30d69fc..00000000000 --- a/json/src/test/mod.rs +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Additional test structures deserialization. - -use std::collections::BTreeMap; -use std::io::Read; -use serde_json; -use serde_json::Error; -use hash::H256; -use uint::Uint; - -/// Blockchain test header deserializer. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct DifficultyTestCase { - /// Parent timestamp. - pub parent_timestamp: Uint, - /// Parent difficulty. - pub parent_difficulty: Uint, - /// Parent uncle hash. - pub parent_uncles: H256, - /// Current timestamp. - pub current_timestamp: Uint, - /// Current difficulty. - pub current_difficulty: Uint, - /// Current block number. - pub current_block_number: Uint, -} - -/// Blockchain test deserializer. -#[derive(Debug, PartialEq, Deserialize)] -pub struct DifficultyTest(BTreeMap); - -impl IntoIterator for DifficultyTest { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl DifficultyTest { - /// Loads test from json. - pub fn load(reader: R) -> Result where R: Read { - serde_json::from_reader(reader) - } -} - -/// Test to skip (only if issue ongoing) -#[derive(Debug, PartialEq, Deserialize)] -pub struct SkipStates { - /// Block tests - pub block: Vec, - /// State tests - pub state: Vec, - -} - -/// Block test to skip. -#[derive(Debug, PartialEq, Deserialize)] -pub struct BlockSkipStates { - /// Issue reference. - pub reference: String, - /// Test failing name. - pub failing: String, - /// Items failing for the test. - pub subtests: Vec, -} - -/// State test to skip. -#[derive(Debug, PartialEq, Deserialize)] -pub struct StateSkipStates { - /// Issue reference. - pub reference: String, - /// Test failing name. - pub failing: String, - /// Items failing for the test. - pub subtests: BTreeMap -} - -/// State subtest to skip. -#[derive(Debug, PartialEq, Deserialize)] -pub struct StateSkipSubStates { - /// State test number of this item. Or '*' for all state. - pub subnumbers: Vec, - /// Chain for this items. - pub chain: String, -} - -impl SkipStates { - /// Loads skip states from json. - pub fn load(reader: R) -> Result where R: Read { - serde_json::from_reader(reader) - } - - /// Empty skip states. - pub fn empty() -> Self { - SkipStates { - block: Vec::new(), - state: Vec::new(), - } - } -} diff --git a/json/src/transaction/mod.rs b/json/src/transaction/mod.rs deleted file mode 100644 index f845fe3340a..00000000000 --- a/json/src/transaction/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Transaction test deserialization. - -mod transaction; -mod txtest; -mod test; - -pub use self::transaction::Transaction; -pub use self::txtest::TransactionTest; -pub use self::test::Test; diff --git a/json/src/transaction/test.rs b/json/src/transaction/test.rs deleted file mode 100644 index ee9d4110f1f..00000000000 --- a/json/src/transaction/test.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! TransactionTest test deserializer. - -use std::collections::BTreeMap; -use std::io::Read; -use serde_json; -use serde_json::Error; -use transaction::TransactionTest; - -/// TransactionTest test deserializer. -#[derive(Debug, Deserialize)] -pub struct Test(BTreeMap); - -impl IntoIterator for Test { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -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/transaction/transaction.rs b/json/src/transaction/transaction.rs deleted file mode 100644 index 718d3080bd2..00000000000 --- a/json/src/transaction/transaction.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Transaction test transaction deserialization. - -use uint::Uint; -use bytes::Bytes; -use hash::Address; -use maybe::MaybeEmpty; - -/// Transaction test transaction deserialization. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Transaction { - /// Transaction data. - pub data: Bytes, - /// Gas limit. - pub gas_limit: Uint, - /// Gas price. - pub gas_price: Uint, - /// Nonce. - pub nonce: Uint, - /// To. - pub to: MaybeEmpty
, - /// Value. - pub value: Uint, - /// R. - pub r: Uint, - /// S. - pub s: Uint, - /// V. - pub v: Uint, -} - -#[cfg(test)] -mod tests { - use serde_json; - use transaction::Transaction; - - #[test] - fn transaction_deserialization() { - let s = r#"{ - "data" : "0x", - "gasLimit" : "0xf388", - "gasPrice" : "0x09184e72a000", - "nonce" : "0x00", - "r" : "0x2c", - "s" : "0x04", - "to" : "", - "v" : "0x1b", - "value" : "0x00" - }"#; - let _deserialized: Transaction = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/transaction/txtest.rs b/json/src/transaction/txtest.rs deleted file mode 100644 index e72e5f60bfa..00000000000 --- a/json/src/transaction/txtest.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Transaction test deserialization. - -use std::collections::BTreeMap; -use bytes::Bytes; -use hash::Address; -use hash::H256; -use spec::ForkSpec; - -/// Transaction test deserialization. -#[derive(Debug, Deserialize)] -pub struct TransactionTest { - pub rlp: Bytes, - pub _info: ::serde::de::IgnoredAny, - #[serde(flatten)] - pub post_state: BTreeMap, -} - -/// TransactionTest post state. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(deny_unknown_fields)] -pub struct PostState { - /// Transaction sender. - pub sender: Option
, - /// Transaction hash. - pub hash: Option, -} - -#[cfg(test)] -mod tests { - use serde_json; - use transaction::TransactionTest; - - #[test] - fn transaction_deserialization() { - let s = r#"{ - "Byzantium" : { - "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5", - "sender" : "2ea991808ba979ba103147edfd72304ebd95c028" - }, - "Constantinople" : { - "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5", - "sender" : "2ea991808ba979ba103147edfd72304ebd95c028" - }, - "EIP150" : { - }, - "EIP158" : { - "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5", - "sender" : "2ea991808ba979ba103147edfd72304ebd95c028" - }, - "Frontier" : { - }, - "Homestead" : { - }, - "_info" : { - "comment" : "", - "filledwith" : "cpp-1.3.0+commit.1829957d.Linux.g++", - "lllcversion" : "Version: 0.4.18-develop.2017.10.11+commit.81f9f86c.Linux.g++", - "source" : "src/TransactionTestsFiller/ttVValue/V_equals37Filler.json", - "sourceHash" : "89ef69312d4c0b4e3742da501263d23d2a64f180258ac93940997ac6a17b9b19" - }, - "rlp" : "0xf865808698852840a46f82d6d894095e7baea6a6c7c4c2dfeb977efac326af552d87808025a098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa01887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" - }"#; - - let _deserialized: TransactionTest = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/trie/input.rs b/json/src/trie/input.rs deleted file mode 100644 index 4c56c10d7cd..00000000000 --- a/json/src/trie/input.rs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Trie test input deserialization. - -use std::fmt; -use std::collections::BTreeMap; -use std::str::FromStr; -use bytes::Bytes; -use serde::{Deserialize, Deserializer}; -use serde::de::{Error as ErrorTrait, Visitor, MapAccess, SeqAccess}; - -/// Trie test input. -#[derive(Debug, PartialEq)] -pub struct Input { - /// Input params. - pub data: BTreeMap>, -} - -impl<'a> Deserialize<'a> for Input { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'a> - { - deserializer.deserialize_any(InputVisitor) - } -} - -struct InputVisitor; - -impl<'a> Visitor<'a> for InputVisitor { - type Value = Input; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a map of bytes into bytes") - } - - fn visit_map(self, mut visitor: V) -> Result where V: MapAccess<'a> { - let mut result = BTreeMap::new(); - - loop { - let key_str: Option = visitor.next_key()?; - let key = match key_str { - Some(ref k) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?, - Some(k) => Bytes::new(k.into_bytes()), - None => { break; } - }; - - let val_str: Option = visitor.next_value()?; - let val = match val_str { - Some(ref v) if v.starts_with("0x") => Some(Bytes::from_str(v).map_err(V::Error::custom)?), - Some(v) => Some(Bytes::new(v.into_bytes())), - None => None, - }; - - result.insert(key, val); - } - - let input = Input { - data: result - }; - - Ok(input) - } - - fn visit_seq(self, mut visitor: V) -> Result where V: SeqAccess<'a> { - let mut result = BTreeMap::new(); - - loop { - let keyval: Option>> = visitor.next_element()?; - let keyval = match keyval { - Some(k) => k, - _ => { break; }, - }; - - if keyval.len() != 2 { - return Err(V::Error::custom("Invalid key value pair.")); - } - - let ref key_str: Option = keyval[0]; - let ref val_str: Option = keyval[1]; - - let key = match *key_str { - Some(ref k) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?, - Some(ref k) => Bytes::new(k.clone().into_bytes()), - None => { break; } - }; - - let val = match *val_str { - Some(ref v) if v.starts_with("0x") => Some(Bytes::from_str(v).map_err(V::Error::custom)?), - Some(ref v) => Some(Bytes::new(v.clone().into_bytes())), - None => None, - }; - - result.insert(key, val); - } - - let input = Input { - data: result - }; - - Ok(input) - } -} - -#[cfg(test)] -mod tests { - use std::collections::BTreeMap; - use serde_json; - use bytes::Bytes; - use super::Input; - - #[test] - fn input_deserialization_from_map() { - let s = r#"{ - "0x0045" : "0x0123456789", - "be" : "e", - "0x0a" : null - }"#; - - let input: Input = serde_json::from_str(s).unwrap(); - let mut map = BTreeMap::new(); - map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89]))); - map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65]))); - map.insert(Bytes::new(vec![0x0a]), None); - assert_eq!(input.data, map); - } - - #[test] - fn input_deserialization_from_array() { - let s = r#"[ - ["0x0045", "0x0123456789"], - ["be", "e"], - ["0x0a", null] - ]"#; - - let input: Input = serde_json::from_str(s).unwrap(); - let mut map = BTreeMap::new(); - map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89]))); - map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65]))); - map.insert(Bytes::new(vec![0x0a]), None); - assert_eq!(input.data, map); - } -} diff --git a/json/src/trie/mod.rs b/json/src/trie/mod.rs deleted file mode 100644 index 68fec087617..00000000000 --- a/json/src/trie/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Trie test deserialization. - -mod input; -mod trie; -mod test; - -pub use self::input::Input; -pub use self::trie::Trie; -pub use self::test::Test; diff --git a/json/src/trie/test.rs b/json/src/trie/test.rs deleted file mode 100644 index 39876da0a16..00000000000 --- a/json/src/trie/test.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! TransactionTest test deserializer. - -use std::collections::BTreeMap; -use std::io::Read; -use serde_json; -use serde_json::Error; -use trie::Trie; - -/// TransactionTest test deserializer. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Test(BTreeMap); - -impl IntoIterator for Test { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -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/trie/trie.rs b/json/src/trie/trie.rs deleted file mode 100644 index 756e54f4351..00000000000 --- a/json/src/trie/trie.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Trie test deserialization. - -use hash::H256; -use trie::Input; - -/// Trie test deserialization. -#[derive(Debug, Deserialize, PartialEq)] -pub struct Trie { - /// Trie test input. - #[serde(rename = "in")] - pub input: Input, - /// Trie root hash. - pub root: H256, -} diff --git a/json/src/uint.rs b/json/src/uint.rs index 3428fd56c40..b0c58cc8dcb 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -92,6 +92,7 @@ impl<'a> Visitor<'a> for UintVisitor { } } +/// Deserialize and validate that the value is non-zero pub fn validate_non_zero<'de, D>(d: D) -> Result where D: Deserializer<'de> { let value = Uint::deserialize(d)?; @@ -102,6 +103,7 @@ pub fn validate_non_zero<'de, D>(d: D) -> Result where D: Deseri Ok(value) } +/// Deserialize and validate that the value is non-zero pub fn validate_optional_non_zero<'de, D>(d: D) -> Result, D::Error> where D: Deserializer<'de> { let value: Option = Option::deserialize(d)?; @@ -116,9 +118,8 @@ pub fn validate_optional_non_zero<'de, D>(d: D) -> Result, D::Error #[cfg(test)] mod test { - use serde_json; + use super::*; use ethereum_types::U256; - use uint::Uint; #[test] fn uint_deserialization() { diff --git a/json/src/vm/call.rs b/json/src/vm/call.rs deleted file mode 100644 index aa75862f0dd..00000000000 --- a/json/src/vm/call.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Vm call deserialization. - -use bytes::Bytes; -use hash::Address; -use uint::Uint; -use maybe::MaybeEmpty; - -/// Vm call deserialization. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Call { - /// Call data. - pub data: Bytes, - /// Call destination. - pub destination: MaybeEmpty
, - /// Gas limit. - pub gas_limit: Uint, - /// Call value. - pub value: Uint, -} - -#[cfg(test)] -mod tests { - use serde_json; - use vm::Call; - use ethereum_types::{U256, H160 as Hash160}; - use uint::Uint; - use hash::Address; - use maybe::MaybeEmpty; - use std::str::FromStr; - - #[test] - fn call_deserialization_empty_dest() { - let s = r#"{ - "data" : "0x1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff", - "destination" : "", - "gasLimit" : "0x1748766aa5", - "value" : "0x00" - }"#; - let call: Call = serde_json::from_str(s).unwrap(); - - assert_eq!(&call.data[..], - &[0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77, - 0x88, 0x88, 0x99, 0x99, 0x00, 0x00, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0xdd, 0xdd, - 0xee, 0xee, 0xff, 0xff]); - - assert_eq!(call.destination, MaybeEmpty::None); - assert_eq!(call.gas_limit, Uint(U256::from(0x1748766aa5u64))); - assert_eq!(call.value, Uint(U256::from(0))); - } - - #[test] - fn call_deserialization_full_dest() { - let s = r#"{ - "data" : "0x1234", - "destination" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c", - "gasLimit" : "0x1748766aa5", - "value" : "0x00" - }"#; - - let call: Call = serde_json::from_str(s).unwrap(); - - assert_eq!(&call.data[..], &[0x12, 0x34]); - assert_eq!(call.destination, MaybeEmpty::Some(Address(Hash160::from_str("5a39ed1020c04d4d84539975b893a4e7c53eab6c").unwrap()))); - assert_eq!(call.gas_limit, Uint(U256::from(0x1748766aa5u64))); - assert_eq!(call.value, Uint(U256::from(0))); - } -} diff --git a/json/src/vm/env.rs b/json/src/vm/env.rs deleted file mode 100644 index e06812c0a87..00000000000 --- a/json/src/vm/env.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Vm environment. -use hash::Address; -use uint::Uint; - -/// Vm environment. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Env { - /// Address. - #[serde(rename = "currentCoinbase")] - pub author: Address, - /// Difficulty - #[serde(rename = "currentDifficulty")] - pub difficulty: Uint, - /// Gas limit. - #[serde(rename = "currentGasLimit")] - pub gas_limit: Uint, - /// Number. - #[serde(rename = "currentNumber")] - pub number: Uint, - /// Timestamp. - #[serde(rename = "currentTimestamp")] - pub timestamp: Uint, -} - -#[cfg(test)] -mod tests { - use serde_json; - use vm::Env; - - #[test] - fn env_deserialization() { - let s = r#"{ - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "0x0100", - "currentGasLimit" : "0x0f4240", - "currentNumber" : "0x00", - "currentTimestamp" : "0x01" - }"#; - let _deserialized: Env = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/json/src/vm/mod.rs b/json/src/vm/mod.rs deleted file mode 100644 index d8f99e20021..00000000000 --- a/json/src/vm/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Vm test loader. - -pub mod env; -pub mod transaction; -pub mod vm; -pub mod call; -pub mod test; - -pub use self::env::Env; -pub use self::transaction::Transaction; -pub use self::vm::Vm; -pub use self::call::Call; -pub use self::test::Test; diff --git a/json/src/vm/test.rs b/json/src/vm/test.rs deleted file mode 100644 index 9dfe814ae82..00000000000 --- a/json/src/vm/test.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Vm test deserializer. - -use std::collections::BTreeMap; -use std::io::Read; -use serde_json; -use serde_json::Error; -use vm::Vm; - -/// Vm test deserializer. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Test(BTreeMap); - -impl IntoIterator for Test { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -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/vm/transaction.rs b/json/src/vm/transaction.rs deleted file mode 100644 index 10ca308df37..00000000000 --- a/json/src/vm/transaction.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Executed transaction. -use hash::Address; -use uint::Uint; -use bytes::Bytes; - -/// Executed transaction. -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Transaction { - /// Contract address. - pub address: Address, - /// Transaction sender. - #[serde(rename = "caller")] - pub sender: Address, - /// Contract code. - pub code: Bytes, - /// Input data. - pub data: Bytes, - /// Gas. - pub gas: Uint, - /// Gas price. - pub gas_price: Uint, - /// Transaction origin. - pub origin: Address, - /// Sent value. - pub value: Uint, - /// Contract code version. - #[serde(default)] - pub code_version: Uint, -} - -#[cfg(test)] -mod tests { - use serde_json; - use vm::Transaction; - - #[test] - fn transaction_deserialization() { - let s = r#"{ - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", - "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", - "data" : "0x", - "gas" : "0x0186a0", - "gasPrice" : "0x5af3107a4000", - "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", - "value" : "0x0de0b6b3a7640000" - }"#; - let _deserialized: Transaction = serde_json::from_str(s).unwrap(); - } -} diff --git a/json/src/vm/vm.rs b/json/src/vm/vm.rs deleted file mode 100644 index 1fbb937cb7f..00000000000 --- a/json/src/vm/vm.rs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . - -//! Vm execution env. - -use bytes::Bytes; -use uint::Uint; -use hash::H256; -use blockchain::State; -use vm::{Transaction, Call, Env}; - -/// Represents vm execution environment before and after execution of transaction. -#[derive(Debug, PartialEq, Deserialize)] -pub struct Vm { - /// Contract calls made internaly by executed transaction. - #[serde(rename = "callcreates")] - pub calls: Option>, - /// Env info. - pub env: Env, - /// Executed transaction - #[serde(rename = "exec")] - pub transaction: Transaction, - /// Gas left after transaction execution. - #[serde(rename = "gas")] - pub gas_left: Option, - /// Hash of logs created during execution of transaction. - pub logs: Option, - /// Transaction output. - #[serde(rename = "out")] - pub output: Option, - /// Post execution vm state. - #[serde(rename = "post")] - pub post_state: Option, - /// Pre execution vm state. - #[serde(rename = "pre")] - pub pre_state: State, -} - -impl Vm { - /// Returns true if transaction execution run out of gas. - pub fn out_of_gas(&self) -> bool { - self.calls.is_none() - } -} - -#[cfg(test)] -mod tests { - use serde_json; - use vm::Vm; - - #[test] - fn vm_deserialization() { - let s = r#"{ - "callcreates" : [ - ], - "env" : { - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "0x0100", - "currentGasLimit" : "0x0f4240", - "currentNumber" : "0x00", - "currentTimestamp" : "0x01" - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", - "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", - "data" : "0x", - "gas" : "0x0186a0", - "gasPrice" : "0x5af3107a4000", - "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", - "value" : "0x0de0b6b3a7640000" - }, - "gas" : "0x013874", - "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "out" : "0x", - "network" : "Frontier", - "post" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", - "nonce" : "0x00", - "storage" : { - "0x00" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - } - } - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", - "nonce" : "0x00", - "storage" : { - } - } - } - }"#; - let _deserialized: Vm = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } -} diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index aa555d75fdf..f7f25d9b75d 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -75,9 +75,10 @@ ethcore = { path = "../ethcore", features = ["test-helpers"] } ethcore-accounts = { path = "../accounts" } ethcore-io = { path = "../util/io" } ethcore-network = { path = "../util/network" } +ethjson = { path = "../json", features = ["test-helpers"] } fake-fetch = { path = "../util/fake-fetch" } macros = { path = "../util/macros" } -spec = { path = "../ethcore/spec" } +spec = { path = "../ethcore/spec", features = ["test-helpers"] } pretty_assertions = "0.1" transaction-pool = "2.0" verification = { path = "../ethcore/verification" } diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 062acb10d29..56d46d02f73 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -15,8 +15,8 @@ // along with Parity Ethereum. If not, see . //! rpc integration tests. -use std::env; -use std::sync::Arc; + +use std::{env, sync::Arc}; use accounts::AccountProvider; use client_traits::{BlockChainClient, ChainInfo, ImportBlock}; @@ -26,7 +26,7 @@ use spec::{Genesis, Spec, self}; use ethcore::test_helpers; use verification::VerifierType; use ethereum_types::{Address, H256, U256}; -use ethjson::blockchain::BlockChain; +use ethjson::test_helpers::blockchain::BlockChain; use ethjson::spec::ForkSpec; use io::IoChannel; use miner::external::ExternalMiner; @@ -85,7 +85,7 @@ struct EthTester { impl EthTester { fn from_chain(chain: &BlockChain) -> Self { - let tester = if ::ethjson::blockchain::Engine::NoProof == chain.engine { + let tester = if ethjson::test_helpers::blockchain::Engine::NoProof == chain.engine { let mut config = ClientConfig::default(); config.verifier_type = VerifierType::CanonNoSeal; config.check_seal = false; diff --git a/rpc/src/v1/tests/mod.rs b/rpc/src/v1/tests/mod.rs index 83f9dca905f..76e89e8bc09 100644 --- a/rpc/src/v1/tests/mod.rs +++ b/rpc/src/v1/tests/mod.rs @@ -32,7 +32,7 @@ macro_rules! extract_chain { (iter $file:expr) => {{ const RAW_DATA: &'static [u8] = include_bytes!(concat!("../../../../ethcore/res/ethereum/tests/", $file, ".json")); - ::ethjson::blockchain::Test::load(RAW_DATA).unwrap().into_iter() + ethjson::test_helpers::blockchain::Test::load(RAW_DATA).unwrap().into_iter() }}; ($file:expr) => {{ From aa6a7b8a0f41861f6392594ce07a759bfc1b8845 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 6 Sep 2019 15:39:06 +0200 Subject: [PATCH 02/10] nit: commit new/moved files --- json/src/state.rs | 55 +++++ json/src/test_helpers/blockchain/block.rs | 74 +++++++ json/src/test_helpers/blockchain/header.rs | 95 ++++++++ json/src/test_helpers/blockchain/mod.rs | 213 ++++++++++++++++++ json/src/test_helpers/difficulty.rs | 23 ++ json/src/test_helpers/mod.rs | 37 ++++ json/src/test_helpers/skip.rs | 58 +++++ json/src/test_helpers/state.rs | 208 ++++++++++++++++++ json/src/test_helpers/tester.rs | 27 +++ json/src/test_helpers/transaction.rs | 83 +++++++ json/src/test_helpers/trie/input.rs | 153 +++++++++++++ json/src/test_helpers/trie/mod.rs | 37 ++++ json/src/transaction.rs | 94 ++++++++ json/src/vm.rs | 242 +++++++++++++++++++++ 14 files changed, 1399 insertions(+) create mode 100644 json/src/state.rs create mode 100644 json/src/test_helpers/blockchain/block.rs create mode 100644 json/src/test_helpers/blockchain/header.rs create mode 100644 json/src/test_helpers/blockchain/mod.rs create mode 100644 json/src/test_helpers/difficulty.rs create mode 100644 json/src/test_helpers/mod.rs create mode 100644 json/src/test_helpers/skip.rs create mode 100644 json/src/test_helpers/state.rs create mode 100644 json/src/test_helpers/tester.rs create mode 100644 json/src/test_helpers/transaction.rs create mode 100644 json/src/test_helpers/trie/input.rs create mode 100644 json/src/test_helpers/trie/mod.rs create mode 100644 json/src/transaction.rs create mode 100644 json/src/vm.rs diff --git a/json/src/state.rs b/json/src/state.rs new file mode 100644 index 00000000000..2f778b57319 --- /dev/null +++ b/json/src/state.rs @@ -0,0 +1,55 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! State deserialization types + +use crate::{ + bytes::Bytes, + hash::{Address, H256, Bloom}, +}; +use serde::Deserialize; + +/// State log deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Log { + /// Address. + pub address: Address, + /// Topics. + pub topics: Vec, + /// Data. + pub data: Bytes, + /// Bloom. + pub bloom: Bloom, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn log_deserialization() { + let s = r#"{ + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "topics" : [ + "0000000000000000000000000000000000000000000000000000000000000000" + ] + }"#; + let _deserialized: Log = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/test_helpers/blockchain/block.rs b/json/src/test_helpers/blockchain/block.rs new file mode 100644 index 00000000000..cb1b04312d0 --- /dev/null +++ b/json/src/test_helpers/blockchain/block.rs @@ -0,0 +1,74 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Blockchain test block deserializer. + +use crate::{bytes::Bytes, transaction::Transaction}; +use super::header::Header; +use serde::Deserialize; + +/// Blockchain test block deserializer. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Block { + #[serde(rename = "blockHeader")] + header: Option
, + rlp: Bytes, + transactions: Option>, + #[serde(rename = "uncleHeaders")] + uncles: Option>, +} + +impl Block { + /// Returns block rlp. + pub fn rlp(&self) -> Vec { + self.rlp.clone().into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn block_deserialization() { + let s = r#"{ + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "65ebf1b97fb89b14680267e0723d69267ec4bf9a96d4a60ffcb356ae0e81c18f", + "mixHash" : "13735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd06", + "nonce" : "931dcc53e5edc514", + "number" : "0x01", + "parentHash" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3", + "timestamp" : "0x56850b7b", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "1", + "rlp" : "0xf901fcf901f7a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba808456850b7b80a013735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd0688931dcc53e5edc514c0c0", + "transaction" : [], + "uncleHeaders" : [] + }"#; + let _deserialized: Block = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/test_helpers/blockchain/header.rs b/json/src/test_helpers/blockchain/header.rs new file mode 100644 index 00000000000..78916338c0d --- /dev/null +++ b/json/src/test_helpers/blockchain/header.rs @@ -0,0 +1,95 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Blockchain test header deserializer. + +use crate::{ + bytes::Bytes, + hash::{H64, Address, H256, Bloom}, + uint::Uint +}; +use serde::Deserialize; + +/// Blockchain test header deserializer. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Header { + /// Blocks bloom. + pub bloom: Bloom, + /// Blocks author. + #[serde(rename = "coinbase")] + pub author: Address, + /// Difficulty. + pub difficulty: Uint, + /// Extra data. + pub extra_data: Bytes, + /// Gas limit. + pub gas_limit: Uint, + /// Gas used. + pub gas_used: Uint, + /// Hash. + pub hash: H256, + /// Mix hash. + pub mix_hash: H256, + /// Seal nonce. + pub nonce: H64, + /// Block number. + pub number: Uint, + /// Parent hash. + pub parent_hash: H256, + /// Receipt root. + #[serde(rename = "receiptTrie")] + pub receipts_root: H256, + /// State root. + pub state_root: H256, + /// Timestamp. + pub timestamp: Uint, + /// Transactions root. + #[serde(rename = "transactionsTrie")] + pub transactions_root: H256, + /// Uncles hash. + #[serde(rename = "uncleHash")] + pub uncles_hash: H256, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn header_deserialization() { + let s = r#"{ + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "65ebf1b97fb89b14680267e0723d69267ec4bf9a96d4a60ffcb356ae0e81c18f", + "mixHash" : "13735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd06", + "nonce" : "931dcc53e5edc514", + "number" : "0x01", + "parentHash" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3", + "timestamp" : "0x56850b7b", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }"#; + let _deserialized: Header = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/test_helpers/blockchain/mod.rs b/json/src/test_helpers/blockchain/mod.rs new file mode 100644 index 00000000000..593531d1989 --- /dev/null +++ b/json/src/test_helpers/blockchain/mod.rs @@ -0,0 +1,213 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Blockchain test deserialization. + +use crate::{ + bytes::Bytes, + hash::H256, + spec::{Ethereum, ForkSpec, Genesis, Seal, State} + +}; +use serde::Deserialize; + +pub mod block; +pub mod header; + +pub use self::block::Block; +pub use self::header::Header; + +/// Type for running `Blockchain` tests +pub type Test = super::tester::GenericTester; + +/// Json Block test possible engine kind. +#[derive(Debug, PartialEq, Deserialize)] +pub enum Engine { + /// Default (old) behaviour. + Ethash, + /// No check of block's difficulty and nonce for tests. + NoProof, +} + +impl Default for Engine { + fn default() -> Self { + Engine::Ethash + } +} + +/// Blockchain deserialization. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BlockChain { + /// Genesis block header. + #[serde(rename = "genesisBlockHeader")] + pub genesis_block: Header, + /// Genesis block rlp. + #[serde(rename = "genesisRLP")] + pub genesis_rlp: Option, + /// Blocks. + pub blocks: Vec, + /// Post state. + pub post_state: State, + /// Pre state. + #[serde(rename = "pre")] + pub pre_state: State, + /// Hash of best block. + #[serde(rename = "lastblockhash")] + pub best_block: H256, + /// Network. + pub network: ForkSpec, + #[serde(default)] + #[serde(rename="sealEngine")] + /// Engine + pub engine: Engine, +} + +impl BlockChain { + /// Returns blocks rlp. + 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 { + seal: Seal::Ethereum(Ethereum { + nonce: self.genesis_block.nonce.clone(), + mix_hash: self.genesis_block.mix_hash.clone(), + }), + difficulty: self.genesis_block.difficulty, + author: Some(self.genesis_block.author.clone()), + timestamp: Some(self.genesis_block.timestamp), + parent_hash: Some(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()), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn blockchain_deserialization() { + let s = r#"{ + "blocks" : [{ + "blockHeader" : { + "bloom" : "00000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000040000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x0102030405060708091011121314151617181920212223242526272829303132", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x560b", + "hash" : "06b5b1742bde29468510c92641f36b719c61b3fc3e9a21c92a23978f4f7faa2a", + "mixHash" : "5266ca43e81d25925a9ba573c3e4f9180bc076d316d90e63c6f8708b272f5ce2", + "nonce" : "59ba4daed1898e21", + "number" : "0x01", + "parentHash" : "f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524d", + "receiptTrie" : "c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296", + "stateRoot" : "bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bf", + "timestamp" : "0x56850c2c", + "transactionsTrie" : "498785da562aa0c5dd5937cf15f22139b0b1bcf3b4fc48986e1bb1dae9292796", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "rlp" : "0xf90285f90219a0f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bfa0498785da562aa0c5dd5937cf15f22139b0b1bcf3b4fc48986e1bb1dae9292796a0c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefba82560b8456850c2ca00102030405060708091011121314151617181920212223242526272829303132a05266ca43e81d25925a9ba573c3e4f9180bc076d316d90e63c6f8708b272f5ce28859ba4daed1898e21f866f864800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d8785012a05f200801ca0ee0b9ec878fbd4258a9473199d8ecc32996a20c323c004e79e0cda20e0418ce3a04e6bc63927d1510bab54f37e46fa036faf4b2c465d271920d9afea1fadf7bd21c0", + "transactions" : [ + { + "data" : "0x00", + "gasLimit" : "0xc350", + "gasPrice" : "0x0a", + "nonce" : "0x00", + "r" : "0xee0b9ec878fbd4258a9473199d8ecc32996a20c323c004e79e0cda20e0418ce3", + "s" : "0x4e6bc63927d1510bab54f37e46fa036faf4b2c465d271920d9afea1fadf7bd21", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1c", + "value" : "0x012a05f200" + } + ], + "uncleHeaders" : [ + ] + }], + "network" : "Frontier", + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "f052d217bd5275a5177a3c3b7debdfe2670f1c8394b2965ccd5c1883cc1a524d", + "mixHash" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0102030405060708", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", + "lastblockhash" : "06b5b1742bde29468510c92641f36b719c61b3fc3e9a21c92a23978f4f7faa2a", + "postState" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x012a05f264", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x4563918244f75c6e", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x012a029592", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x64", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }"#; + let _deserialized: BlockChain = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/test_helpers/difficulty.rs b/json/src/test_helpers/difficulty.rs new file mode 100644 index 00000000000..023966c6a22 --- /dev/null +++ b/json/src/test_helpers/difficulty.rs @@ -0,0 +1,23 @@ +use crate::{hash::H256, uint::Uint}; +use serde::Deserialize; + +/// Blockchain test header deserializer. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct DifficultyTestCase { + /// Parent timestamp. + pub parent_timestamp: Uint, + /// Parent difficulty. + pub parent_difficulty: Uint, + /// Parent uncle hash. + pub parent_uncles: H256, + /// Current timestamp. + pub current_timestamp: Uint, + /// Current difficulty. + pub current_difficulty: Uint, + /// Current block number. + pub current_block_number: Uint, +} + +/// Type for running `Difficulty` tests +pub type DifficultyTest = super::tester::GenericTester; diff --git a/json/src/test_helpers/mod.rs b/json/src/test_helpers/mod.rs new file mode 100644 index 00000000000..095738a0c48 --- /dev/null +++ b/json/src/test_helpers/mod.rs @@ -0,0 +1,37 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Test structures for JSON deserialization. + +/// Blockchain test helpers +pub mod blockchain; +/// Difficulty test helpers +pub mod difficulty; +/// Tests to skip helpers +pub mod skip; +/// State test helpers +pub mod state; +/// Test primitives +pub mod tester; +/// Transaction test helpers +pub mod transaction; +/// Trie test helpers +pub mod trie; +/// Vm test helpers +pub mod vm { + /// Type for running `vm` tests + pub type Test = super::tester::GenericTester; +} diff --git a/json/src/test_helpers/skip.rs b/json/src/test_helpers/skip.rs new file mode 100644 index 00000000000..3245fb1c3ba --- /dev/null +++ b/json/src/test_helpers/skip.rs @@ -0,0 +1,58 @@ +use std::collections::BTreeMap; +use serde::Deserialize; + +/// Test to skip (only if issue ongoing) +#[derive(Debug, PartialEq, Deserialize)] +pub struct SkipStates { + /// Block tests + pub block: Vec, + /// State tests + pub state: Vec, + +} + +/// Block test to skip. +#[derive(Debug, PartialEq, Deserialize)] +pub struct BlockSkipStates { + /// Issue reference. + pub reference: String, + /// Test failing name. + pub failing: String, + /// Items failing for the test. + pub subtests: Vec, +} + +/// State test to skip. +#[derive(Debug, PartialEq, Deserialize)] +pub struct StateSkipStates { + /// Issue reference. + pub reference: String, + /// Test failing name. + pub failing: String, + /// Items failing for the test. + pub subtests: BTreeMap +} + +/// State subtest to skip. +#[derive(Debug, PartialEq, Deserialize)] +pub struct StateSkipSubStates { + /// State test number of this item. Or '*' for all state. + pub subnumbers: Vec, + /// Chain for this items. + pub chain: String, +} + +impl SkipStates { + /// Empty skip states. + pub fn empty() -> Self { + SkipStates { + block: Vec::new(), + state: Vec::new(), + } + } + + /// Loads test from json. + pub fn load(reader: R) -> Result where R: std::io::Read { + serde_json::from_reader(reader) + } +} diff --git a/json/src/test_helpers/state.rs b/json/src/test_helpers/state.rs new file mode 100644 index 00000000000..d16c11e2b58 --- /dev/null +++ b/json/src/test_helpers/state.rs @@ -0,0 +1,208 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! State test deserialization. + +// pub mod state; +// pub mod transaction; + +/// Type for running `State` tests +pub type Test = super::tester::GenericTester; + +use std::collections::BTreeMap; +use serde::Deserialize; +use crate::{ + bytes::Bytes, + hash::{Address, H256}, + maybe::MaybeEmpty, + uint::Uint, + spec::{ForkSpec, State as AccountState}, + transaction::{Transaction, TransactionWithSigningInfo}, + vm::Env +}; + +/// State test deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct State { + /// Environment. + pub env: Env, + /// Pre state. + #[serde(rename = "pre")] + pub pre_state: AccountState, + /// Post state. + #[serde(rename = "post")] + pub post_states: BTreeMap>, + /// Transaction. + pub transaction: MultiTransaction, +} + +/// State test transaction deserialization. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MultiTransaction { + /// Transaction data set. + pub data: Vec, + /// Gas limit set. + pub gas_limit: Vec, + /// Gas price. + pub gas_price: Uint, + /// Nonce. + pub nonce: Uint, + /// Secret key. + #[serde(rename = "secretKey")] + pub secret: Option, + /// To. + pub to: MaybeEmpty
, + /// Value set. + pub value: Vec, +} + +impl MultiTransaction { + /// Build transaction with given indexes. + pub fn select(&self, indexes: &PostStateIndexes) -> TransactionWithSigningInfo { + TransactionWithSigningInfo { + transaction: Transaction { + data: self.data[indexes.data as usize].clone(), + gas_limit: self.gas_limit[indexes.gas as usize].clone(), + gas_price: self.gas_price.clone(), + nonce: self.nonce.clone(), + to: self.to.clone(), + value: self.value[indexes.value as usize].clone(), + }, + r: Default::default(), + s: Default::default(), + v: Default::default(), + secret: self.secret.clone(), + } + } +} + +/// State test indexes deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct PostStateIndexes { + /// Index into transaction data set. + pub data: u64, + /// Index into transaction gas limit set. + pub gas: u64, + /// Index into transaction value set. + pub value: u64, +} + +/// State test indexed state result deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct PostStateResult { + /// Post state hash + pub hash: H256, + /// Indexes + pub indexes: PostStateIndexes, +} + +#[cfg(test)] +mod tests { + use serde_json; + use super::{MultiTransaction, State}; + + #[test] + fn multi_transaction_deserialization() { + let s = r#"{ + "data": [ "" ], + "gasLimit": [ "0x2dc6c0", "0x222222" ], + "gasPrice": "0x01", + "nonce": "0x00", + "secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to": "1000000000000000000000000000000000000000", + "value": [ "0x00", "0x01", "0x02" ] + }"#; + let _deserialized: MultiTransaction = serde_json::from_str(s).unwrap(); + } + + #[test] + fn state_deserialization() { + let s = r#"{ + "env": { + "currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty": "0x0100", + "currentGasLimit": "0x01c9c380", + "currentNumber": "0x00", + "currentTimestamp": "0x01", + "previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "post": { + "EIP150": [ + { + "hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f", + "indexes": { "data": 0, "gas": 0, "value": 0 } + }, + { + "hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764", + "indexes": { "data": 0, "gas": 0, "value": 1 } + } + ], + "EIP158": [ + { + "hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f", + "indexes": { "data": 0, "gas": 0, "value": 0 } + }, + { + "hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764", + "indexes": { "data": 0, "gas": 0, "value": 1 } + } + ] + }, + "pre": { + "1000000000000000000000000000000000000000": { + "balance": "0x0de0b6b3a7640000", + "code": "0x6040600060406000600173100000000000000000000000000000000000000162055730f1600055", + "nonce": "0x00", + "storage": { + } + }, + "1000000000000000000000000000000000000001": { + "balance": "0x0de0b6b3a7640000", + "code": "0x604060006040600060027310000000000000000000000000000000000000026203d090f1600155", + "nonce": "0x00", + "storage": { + } + }, + "1000000000000000000000000000000000000002": { + "balance": "0x00", + "code": "0x600160025533600455346007553060e6553260e8553660ec553860ee553a60f055", + "nonce": "0x00", + "storage": { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x0de0b6b3a7640000", + "code": "0x", + "nonce": "0x00", + "storage": { + } + } + }, + "transaction": { + "data": [ "" ], + "gasLimit": [ "285000", "100000", "6000" ], + "gasPrice": "0x01", + "nonce": "0x00", + "secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to": "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value": [ "10", "0" ] + } + }"#; + let _deserialized: State = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/test_helpers/tester.rs b/json/src/test_helpers/tester.rs new file mode 100644 index 00000000000..610f5972304 --- /dev/null +++ b/json/src/test_helpers/tester.rs @@ -0,0 +1,27 @@ +use std::collections::BTreeMap; +use serde::Deserialize; +use serde::de::DeserializeOwned; + +/// A genric wrapper over a `BTreeMap` for tests +#[derive(Deserialize)] +pub struct GenericTester(BTreeMap); + +impl IntoIterator for GenericTester { + type Item = as IntoIterator>::Item; + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl GenericTester +where + T: DeserializeOwned + Ord, + U: DeserializeOwned +{ + /// Loads test from json. + pub fn load(reader: R) -> Result where R: std::io::Read { + serde_json::from_reader(reader) + } +} diff --git a/json/src/test_helpers/transaction.rs b/json/src/test_helpers/transaction.rs new file mode 100644 index 00000000000..ddddea54769 --- /dev/null +++ b/json/src/test_helpers/transaction.rs @@ -0,0 +1,83 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Transaction test deserialization. + +use std::collections::BTreeMap; +use crate::{bytes::Bytes, hash::{Address, H256}, spec::ForkSpec}; +use serde::Deserialize; + +/// Type for running `Transaction` tests +pub type Test = super::tester::GenericTester; + +/// Transaction test deserialization. +#[derive(Debug, Deserialize)] +pub struct TransactionTest { + pub rlp: Bytes, + pub _info: serde::de::IgnoredAny, + #[serde(flatten)] + pub post_state: BTreeMap, +} + +/// TransactionTest post state. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct PostState { + /// Transaction sender. + pub sender: Option
, + /// Transaction hash. + pub hash: Option, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn transaction_deserialization() { + let s = r#"{ + "Byzantium" : { + "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5", + "sender" : "2ea991808ba979ba103147edfd72304ebd95c028" + }, + "Constantinople" : { + "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5", + "sender" : "2ea991808ba979ba103147edfd72304ebd95c028" + }, + "EIP150" : { + }, + "EIP158" : { + "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5", + "sender" : "2ea991808ba979ba103147edfd72304ebd95c028" + }, + "Frontier" : { + }, + "Homestead" : { + }, + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.1829957d.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.10.11+commit.81f9f86c.Linux.g++", + "source" : "src/TransactionTestsFiller/ttVValue/V_equals37Filler.json", + "sourceHash" : "89ef69312d4c0b4e3742da501263d23d2a64f180258ac93940997ac6a17b9b19" + }, + "rlp" : "0xf865808698852840a46f82d6d894095e7baea6a6c7c4c2dfeb977efac326af552d87808025a098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa01887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + }"#; + + let _deserialized: TransactionTest = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/test_helpers/trie/input.rs b/json/src/test_helpers/trie/input.rs new file mode 100644 index 00000000000..616cbaaf67c --- /dev/null +++ b/json/src/test_helpers/trie/input.rs @@ -0,0 +1,153 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Trie test input deserialization. + +use std::fmt; +use std::collections::BTreeMap; +use std::str::FromStr; +use crate::bytes::Bytes; +use serde::{Deserialize, Deserializer}; +use serde::de::{Error as ErrorTrait, Visitor, MapAccess, SeqAccess}; + +/// Trie test input. +#[derive(Debug, PartialEq)] +pub struct Input { + /// Input params. + pub data: BTreeMap>, +} + +impl<'a> Deserialize<'a> for Input { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'a> + { + deserializer.deserialize_any(InputVisitor) + } +} + +struct InputVisitor; + +impl<'a> Visitor<'a> for InputVisitor { + type Value = Input; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a map of bytes into bytes") + } + + fn visit_map(self, mut visitor: V) -> Result where V: MapAccess<'a> { + let mut result = BTreeMap::new(); + + loop { + let key_str: Option = visitor.next_key()?; + let key = match key_str { + Some(ref k) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?, + Some(k) => Bytes::new(k.into_bytes()), + None => { break; } + }; + + let val_str: Option = visitor.next_value()?; + let val = match val_str { + Some(ref v) if v.starts_with("0x") => Some(Bytes::from_str(v).map_err(V::Error::custom)?), + Some(v) => Some(Bytes::new(v.into_bytes())), + None => None, + }; + + result.insert(key, val); + } + + let input = Input { + data: result + }; + + Ok(input) + } + + fn visit_seq(self, mut visitor: V) -> Result where V: SeqAccess<'a> { + let mut result = BTreeMap::new(); + + loop { + let keyval: Option>> = visitor.next_element()?; + let keyval = match keyval { + Some(k) => k, + _ => { break; }, + }; + + if keyval.len() != 2 { + return Err(V::Error::custom("Invalid key value pair.")); + } + + let key_str: &Option = &keyval[0]; + let val_str: &Option = &keyval[1]; + + let key = match *key_str { + Some(ref k) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?, + Some(ref k) => Bytes::new(k.clone().into_bytes()), + None => { break; } + }; + + let val = match *val_str { + Some(ref v) if v.starts_with("0x") => Some(Bytes::from_str(v).map_err(V::Error::custom)?), + Some(ref v) => Some(Bytes::new(v.clone().into_bytes())), + None => None, + }; + + result.insert(key, val); + } + + let input = Input { + data: result + }; + + Ok(input) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn input_deserialization_from_map() { + let s = r#"{ + "0x0045" : "0x0123456789", + "be" : "e", + "0x0a" : null + }"#; + + let input: Input = serde_json::from_str(s).unwrap(); + let mut map = BTreeMap::new(); + map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89]))); + map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65]))); + map.insert(Bytes::new(vec![0x0a]), None); + assert_eq!(input.data, map); + } + + #[test] + fn input_deserialization_from_array() { + let s = r#"[ + ["0x0045", "0x0123456789"], + ["be", "e"], + ["0x0a", null] + ]"#; + + let input: Input = serde_json::from_str(s).unwrap(); + let mut map = BTreeMap::new(); + map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89]))); + map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65]))); + map.insert(Bytes::new(vec![0x0a]), None); + assert_eq!(input.data, map); + } +} diff --git a/json/src/test_helpers/trie/mod.rs b/json/src/test_helpers/trie/mod.rs new file mode 100644 index 00000000000..fbcf910d04c --- /dev/null +++ b/json/src/test_helpers/trie/mod.rs @@ -0,0 +1,37 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Trie test deserialization. + +mod input; + +pub use self::input::Input; + +/// Type from `trie` tests +pub type Test = super::tester::GenericTester; + +use serde::Deserialize; +use crate::hash::H256; + +/// Trie test deserialization. +#[derive(Debug, Deserialize, PartialEq)] +pub struct Trie { + /// Trie test input. + #[serde(rename = "in")] + pub input: Input, + /// Trie root hash. + pub root: H256, +} diff --git a/json/src/transaction.rs b/json/src/transaction.rs new file mode 100644 index 00000000000..5f6a827b952 --- /dev/null +++ b/json/src/transaction.rs @@ -0,0 +1,94 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Transaction deserialization. + +use crate::{bytes::Bytes, hash::{Address, H256}, maybe::MaybeEmpty, uint::Uint}; +use serde::Deserialize; + +/// Plain transaction deserialization. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Transaction { + /// Transaction data. + pub data: Bytes, + /// Gas limit. + pub gas_limit: Uint, + /// Gas price. + pub gas_price: Uint, + /// Nonce. + pub nonce: Uint, + /// To. + pub to: MaybeEmpty
, + /// Value. + pub value: Uint, +} + +/// Unsigned transaction with signing information deserialization +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TransactionWithSigningInfo { + /// Transaction + pub transaction: Transaction, + /// R. + pub r: Uint, + /// S. + pub s: Uint, + /// V. + pub v: Uint, + /// Secret + #[serde(rename = "secretKey")] + pub secret: Option, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn transaction_deserialization() { + let s = r#"{ + "data" : "0x", + "gasLimit" : "0xf388", + "gasPrice" : "0x09184e72a000", + "nonce" : "0x00", + "to" : "", + "value" : "0x00" + }"#; + let _deserialized: Transaction = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } + + #[test] + fn transaction_with_signing_info_deserialization() { + let s = r#"{ + "transaction": { + "data" : "0x", + "gasLimit" : "0xf388", + "gasPrice" : "0x09184e72a000", + "nonce" : "0x00", + "to" : "", + "value" : "0x00" + }, + "r": 0, + "s": 1, + "v": 2, + "secretKey": "0x0000000000000000000000000000000000000000000000000000000000000000" + }"#; + let _deserialized: TransactionWithSigningInfo = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} diff --git a/json/src/vm.rs b/json/src/vm.rs new file mode 100644 index 00000000000..9125721545a --- /dev/null +++ b/json/src/vm.rs @@ -0,0 +1,242 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Vm json deserialization + +use crate::{ + bytes::Bytes, + hash::{Address, H256}, + maybe::MaybeEmpty, + spec::State, + uint::Uint, +}; +use serde::Deserialize; + +/// Represents vm execution environment before and after execution of transaction. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Vm { + /// Contract calls made internaly by executed transaction. + #[serde(rename = "callcreates")] + pub calls: Option>, + /// Env info. + pub env: Env, + /// Executed transaction + #[serde(rename = "exec")] + pub transaction: Transaction, + /// Gas left after transaction execution. + #[serde(rename = "gas")] + pub gas_left: Option, + /// Hash of logs created during execution of transaction. + pub logs: Option, + /// Transaction output. + #[serde(rename = "out")] + pub output: Option, + /// Post execution vm state. + #[serde(rename = "post")] + pub post_state: Option, + /// Pre execution vm state. + #[serde(rename = "pre")] + pub pre_state: State, +} + +impl Vm { + /// Returns true if transaction execution run out of gas. + pub fn out_of_gas(&self) -> bool { + self.calls.is_none() + } +} + +/// Call deserialization. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Call { + /// Call data. + pub data: Bytes, + /// Call destination. + pub destination: MaybeEmpty
, + /// Gas limit. + pub gas_limit: Uint, + /// Call value. + pub value: Uint, +} + +/// Executed transaction. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Transaction { + /// Contract address. + pub address: Address, + /// Transaction sender. + #[serde(rename = "caller")] + pub sender: Address, + /// Contract code. + pub code: Bytes, + /// Input data. + pub data: Bytes, + /// Gas. + pub gas: Uint, + /// Gas price. + pub gas_price: Uint, + /// Transaction origin. + pub origin: Address, + /// Sent value. + pub value: Uint, + /// Contract code version. + #[serde(default)] + pub code_version: Uint, +} + +/// Environment. +#[derive(Debug, PartialEq, Deserialize)] +pub struct Env { + /// Address. + #[serde(rename = "currentCoinbase")] + pub author: Address, + /// Difficulty + #[serde(rename = "currentDifficulty")] + pub difficulty: Uint, + /// Gas limit. + #[serde(rename = "currentGasLimit")] + pub gas_limit: Uint, + /// Number. + #[serde(rename = "currentNumber")] + pub number: Uint, + /// Timestamp. + #[serde(rename = "currentTimestamp")] + pub timestamp: Uint, +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use super::*; + use ethereum_types::{U256, H160 as Hash160}; + + #[test] + fn vm_deserialization() { + let s = r#"{ + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", + "data" : "0x", + "gas" : "0x0186a0", + "gasPrice" : "0x5af3107a4000", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "gas" : "0x013874", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "network" : "Frontier", + "post" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + } + } + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", + "nonce" : "0x00", + "storage" : { + } + } + } + }"#; + let _deserialized: Vm = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } + + #[test] + fn call_deserialization_empty_dest() { + let s = r#"{ + "data" : "0x1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff", + "destination" : "", + "gasLimit" : "0x1748766aa5", + "value" : "0x00" + }"#; + let call: Call = serde_json::from_str(s).unwrap(); + + assert_eq!(&call.data[..], + &[0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77, + 0x88, 0x88, 0x99, 0x99, 0x00, 0x00, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0xdd, 0xdd, + 0xee, 0xee, 0xff, 0xff]); + + assert_eq!(call.destination, MaybeEmpty::None); + assert_eq!(call.gas_limit, Uint(U256::from(0x1748766aa5u64))); + assert_eq!(call.value, Uint(U256::from(0))); + } + + #[test] + fn call_deserialization_full_dest() { + let s = r#"{ + "data" : "0x1234", + "destination" : "5a39ed1020c04d4d84539975b893a4e7c53eab6c", + "gasLimit" : "0x1748766aa5", + "value" : "0x00" + }"#; + + let call: Call = serde_json::from_str(s).unwrap(); + + assert_eq!(&call.data[..], &[0x12, 0x34]); + assert_eq!(call.destination, MaybeEmpty::Some(Address(Hash160::from_str("5a39ed1020c04d4d84539975b893a4e7c53eab6c").unwrap()))); + assert_eq!(call.gas_limit, Uint(U256::from(0x1748766aa5u64))); + assert_eq!(call.value, Uint(U256::from(0))); + } + + #[test] + fn transaction_deserialization() { + let s = r#"{ + "address": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller": "cd1722f2947def4cf144679da39c4c32bdc35681", + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", + "data": "0x", + "gas": "0x0186a0", + "gasPrice": "0x5af3107a4000", + "origin": "cd1722f2947def4cf144679da39c4c32bdc35681", + "value": "0x0de0b6b3a7640000" + }"#; + let _deserialized: Transaction = serde_json::from_str(s).unwrap(); + } + + #[test] + fn env_deserialization() { + let s = r#"{ + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }"#; + let _deserialized: Env = serde_json::from_str(s).unwrap(); + // TODO: validate all fields + } +} From b9cd7a6e325e42f3216272c0cfc46d28aba57269 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 6 Sep 2019 15:39:39 +0200 Subject: [PATCH 03/10] nit: remove needless features --- ethcore/Cargo.toml | 1 - ethcore/pod/Cargo.toml | 4 ---- ethcore/spec/Cargo.toml | 6 ------ evmbin/Cargo.toml | 1 - rpc/Cargo.toml | 2 +- 5 files changed, 1 insertion(+), 13 deletions(-) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 4965d5859b3..427aff4a795 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -89,7 +89,6 @@ machine = { path = "./machine", features = ["test-helpers"] } macros = { path = "../util/macros" } null-engine = { path = "./engines/null-engine" } parity-runtime = { path = "../util/runtime" } -pod = { path = "pod", features = ["test-helpers"] } rlp_compress = { path = "../util/rlp-compress" } rustc-hex = "1" serde_json = "1.0" diff --git a/ethcore/pod/Cargo.toml b/ethcore/pod/Cargo.toml index ad5d76c052d..c695b2533cc 100644 --- a/ethcore/pod/Cargo.toml +++ b/ethcore/pod/Cargo.toml @@ -25,8 +25,4 @@ trie-db = "0.15.0" triehash = { package = "triehash-ethereum", version = "0.2", path = "../../util/triehash-ethereum" } [dev-dependencies] -ethjson = { path = "../../json", features = ["test-helpers"] } macros = { path = "../../util/macros" } - -[features] -test-helpers = [] diff --git a/ethcore/spec/Cargo.toml b/ethcore/spec/Cargo.toml index 426336294e8..03e16765b3c 100644 --- a/ethcore/spec/Cargo.toml +++ b/ethcore/spec/Cargo.toml @@ -38,10 +38,4 @@ vm = { path = "../vm" } [dev-dependencies] ethcore = { path = "..", features = ["test-helpers"] } env_logger = "0.5" -pod = { path = "../pod", features = ["test-helpers"] } tempdir = "0.3.7" - -[features] -test-helpers = [ - "pod/test-helpers" -] diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index d08e1029e2b..5f2819ec2ee 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -31,7 +31,6 @@ vm = { path = "../ethcore/vm" } [dev-dependencies] criterion = "0.3" tempdir = "0.3" -pod = { path = "../ethcore/pod", features = ["test-helpers"] } [features] evm-debug = ["ethcore/evm-debug-tests"] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index f7f25d9b75d..f332dbe7ad1 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -78,7 +78,7 @@ ethcore-network = { path = "../util/network" } ethjson = { path = "../json", features = ["test-helpers"] } fake-fetch = { path = "../util/fake-fetch" } macros = { path = "../util/macros" } -spec = { path = "../ethcore/spec", features = ["test-helpers"] } +spec = { path = "../ethcore/spec" } pretty_assertions = "0.1" transaction-pool = "2.0" verification = { path = "../ethcore/verification" } From b18a10579993fec1b71e8a0df1ea7a322af6aec0 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 6 Sep 2019 15:50:14 +0200 Subject: [PATCH 04/10] nits --- ethcore/Cargo.toml | 2 +- json/src/lib.rs | 4 ++-- json/src/test_helpers/state.rs | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 427aff4a795..782af50ba18 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -20,7 +20,7 @@ ethabi = "8.0" ethabi-contract = "8.0" ethabi-derive = "8.0" ethash = { path = "../ethash", optional = true } -ethjson = { path = "../json", features = ["test-helpers"], optional = true } +ethjson = { path = "../json", optional = true } ethkey = { path = "../accounts/ethkey", optional = true } ethcore-blockchain = { path = "./blockchain" } ethcore-call-contract = { path = "./call-contract" } diff --git a/json/src/lib.rs b/json/src/lib.rs index 37480d3d137..39cf728cbbc 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -#![warn(missing_docs)] - //! JSON deserialization library +#![warn(missing_docs)] + pub mod bytes; pub mod hash; pub mod maybe; diff --git a/json/src/test_helpers/state.rs b/json/src/test_helpers/state.rs index d16c11e2b58..49e5ce90713 100644 --- a/json/src/test_helpers/state.rs +++ b/json/src/test_helpers/state.rs @@ -16,9 +16,6 @@ //! State test deserialization. -// pub mod state; -// pub mod transaction; - /// Type for running `State` tests pub type Test = super::tester::GenericTester; From cbfcd8e1ed890a234ea7eaa1c1c3c36191a6fd46 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 9 Sep 2019 09:48:25 +0200 Subject: [PATCH 05/10] fix(grumbles): use explicit import `DifficultyTest` --- ethcore/src/json_tests/difficulty.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ethcore/src/json_tests/difficulty.rs b/ethcore/src/json_tests/difficulty.rs index dc5161a42e4..bc7738db061 100644 --- a/ethcore/src/json_tests/difficulty.rs +++ b/ethcore/src/json_tests/difficulty.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use ethjson; -use types::header::Header; use ethereum_types::U256; +use ethjson::test_helpers::difficulty::DifficultyTest; +use types::header::Header; use spec::Spec; use super::HookType; @@ -26,8 +26,8 @@ pub fn json_difficulty_test( spec: Spec, start_stop_hook: &mut H ) -> Vec { - let _ = ::env_logger::try_init(); - let tests = ethjson::test_helpers::difficulty::DifficultyTest::load(json_data).unwrap(); + let _ = env_logger::try_init(); + let tests = DifficultyTest::load(json_data).unwrap(); let engine = &spec.engine; for (name, test) in tests.into_iter() { From 797da9ac5062d7c91bf21cdfbd5251ecedd90c46 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 9 Sep 2019 09:53:41 +0200 Subject: [PATCH 06/10] fix(grumbles): remove needless type hints --- json/src/test_helpers/trie/input.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/json/src/test_helpers/trie/input.rs b/json/src/test_helpers/trie/input.rs index 616cbaaf67c..5a7533dc791 100644 --- a/json/src/test_helpers/trie/input.rs +++ b/json/src/test_helpers/trie/input.rs @@ -89,8 +89,8 @@ impl<'a> Visitor<'a> for InputVisitor { return Err(V::Error::custom("Invalid key value pair.")); } - let key_str: &Option = &keyval[0]; - let val_str: &Option = &keyval[1]; + let key_str = &keyval[0]; + let val_str = &keyval[1]; let key = match *key_str { Some(ref k) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?, From e91bca9b4256080f5c3d1ad4e47b073129f1dc65 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 9 Sep 2019 10:31:16 +0200 Subject: [PATCH 07/10] fix(grumble): docs `from -> used by` Co-Authored-By: David --- json/src/test_helpers/trie/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json/src/test_helpers/trie/mod.rs b/json/src/test_helpers/trie/mod.rs index fbcf910d04c..29bb55531bf 100644 --- a/json/src/test_helpers/trie/mod.rs +++ b/json/src/test_helpers/trie/mod.rs @@ -20,7 +20,7 @@ mod input; pub use self::input::Input; -/// Type from `trie` tests +/// Type used by `trie` tests pub type Test = super::tester::GenericTester; use serde::Deserialize; From 6877c6a81a1a418ed6528d6cc31cc8dd52249733 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 9 Sep 2019 11:39:49 +0200 Subject: [PATCH 08/10] fix(grumbles): use explicit `imports` --- json/src/bytes.rs | 5 ++--- json/src/hash.rs | 2 +- json/src/maybe.rs | 2 +- json/src/spec/account.rs | 3 +-- json/src/spec/authority_round.rs | 2 +- json/src/spec/basic_authority.rs | 8 +++----- json/src/spec/builtin.rs | 2 +- json/src/spec/clique.rs | 7 +++---- json/src/spec/engine.rs | 2 +- json/src/spec/ethash.rs | 6 ++++-- json/src/spec/genesis.rs | 6 +++--- json/src/spec/hardcoded_sync.rs | 4 ++-- json/src/spec/null_engine.rs | 2 +- json/src/spec/params.rs | 2 +- json/src/spec/seal.rs | 6 ++---- json/src/spec/spec.rs | 2 +- json/src/spec/validator_set.rs | 4 ++-- json/src/state.rs | 2 +- json/src/test_helpers/blockchain/block.rs | 2 +- json/src/test_helpers/blockchain/header.rs | 2 +- json/src/test_helpers/blockchain/mod.rs | 2 +- json/src/test_helpers/transaction.rs | 2 +- json/src/test_helpers/trie/input.rs | 2 +- json/src/transaction.rs | 2 +- json/src/uint.rs | 2 +- json/src/vm.rs | 2 +- 26 files changed, 39 insertions(+), 44 deletions(-) diff --git a/json/src/bytes.rs b/json/src/bytes.rs index 711e921851d..8934e9c0ece 100644 --- a/json/src/bytes.rs +++ b/json/src/bytes.rs @@ -100,7 +100,7 @@ impl<'a> Visitor<'a> for BytesVisitor { #[cfg(test)] mod test { - use super::*; + use super::Bytes; #[test] fn bytes_deserialization() { @@ -117,8 +117,7 @@ mod test { #[test] fn bytes_into() { - let bytes = Bytes(vec![0xff, 0x11]); - let v: Vec = bytes.into(); + let v: Vec = Bytes(vec![0xff, 0x11]).into(); assert_eq!(vec![0xff, 0x11], v); } } diff --git a/json/src/hash.rs b/json/src/hash.rs index d724b4c9617..d6cef24cb89 100644 --- a/json/src/hash.rs +++ b/json/src/hash.rs @@ -94,7 +94,7 @@ impl_hash!(Bloom, Hash2048); #[cfg(test)] mod test { - use super::*; + use super::H256; use std::str::FromStr; #[test] diff --git a/json/src/maybe.rs b/json/src/maybe.rs index fd5a88dd519..2273555b31d 100644 --- a/json/src/maybe.rs +++ b/json/src/maybe.rs @@ -80,8 +80,8 @@ impl Into> for MaybeEmpty { #[cfg(test)] mod tests { - use super::*; use std::str::FromStr; + use super::MaybeEmpty; use crate::hash::H256; #[test] diff --git a/json/src/spec/account.rs b/json/src/spec/account.rs index 1267eaf64e7..6d722ea2385 100644 --- a/json/src/spec/account.rs +++ b/json/src/spec/account.rs @@ -51,8 +51,7 @@ impl Account { #[cfg(test)] mod tests { - use super::*; - use std::collections::BTreeMap; + use super::{Account, Bytes, BTreeMap, Uint}; use ethereum_types::U256; #[test] diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 4549b2369ae..0a31203f62f 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -107,7 +107,7 @@ pub struct AuthorityRound { #[cfg(test)] mod tests { - use super::*; + use super::{Address, Uint}; use ethereum_types::{U256, H160}; use crate::spec::{validator_set::ValidatorSet, authority_round::AuthorityRound}; use std::str::FromStr; diff --git a/json/src/spec/basic_authority.rs b/json/src/spec/basic_authority.rs index 8f8c10fc4aa..2925cbdde3a 100644 --- a/json/src/spec/basic_authority.rs +++ b/json/src/spec/basic_authority.rs @@ -41,12 +41,10 @@ pub struct BasicAuthority { #[cfg(test)] mod tests { - use super::*; - use ethereum_types::{U256, H160}; - use crate::hash::Address; - use crate::spec::basic_authority::BasicAuthority; - use crate::spec::validator_set::ValidatorSet; use std::str::FromStr; + use super::{BasicAuthority, Uint}; + use ethereum_types::{U256, H160}; + use crate::{hash::Address, spec::validator_set::ValidatorSet}; #[test] fn basic_authority_deserialization() { diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index d4aa7af7fbb..6c17cdb6dd2 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -97,7 +97,7 @@ pub struct Builtin { #[cfg(test)] mod tests { - use super::*; + use super::{Builtin, Modexp, Linear, Pricing, Uint}; #[test] fn builtin_deserialization() { diff --git a/json/src/spec/clique.rs b/json/src/spec/clique.rs index a7cbff9d49c..4d2c4a99f2f 100644 --- a/json/src/spec/clique.rs +++ b/json/src/spec/clique.rs @@ -22,9 +22,9 @@ use serde::Deserialize; /// Clique params deserialization. #[derive(Debug, PartialEq, Deserialize)] pub struct CliqueParams { - /// period as defined in EIP + /// period as defined in EIP 225 pub period: Option, - /// epoch length as defined in EIP + /// epoch length as defined in EIP 225 pub epoch: Option } @@ -37,8 +37,7 @@ pub struct Clique { #[cfg(test)] mod tests { - use serde_json; - use super::*; + use super::{Clique, NonZeroU64}; #[test] fn clique_deserialization() { diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index a356f256261..1ef517208cd 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -41,7 +41,7 @@ pub enum Engine { #[cfg(test)] mod tests { - use super::*; + use super::Engine; #[test] fn engine_deserialization() { diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index 5b12473dd3e..eee44d02bf1 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -29,7 +29,9 @@ use serde::Deserialize; #[serde(deny_unknown_fields)] #[serde(untagged)] pub enum BlockReward { + /// Single block reward Single(Uint), + /// Several block rewards Multi(BTreeMap), } @@ -113,9 +115,9 @@ pub struct Ethash { #[cfg(test)] mod tests { - use super::*; - use ethereum_types::{H160, U256}; use std::str::FromStr; + use super::{Address, BlockReward, Ethash, EthashParams, Uint}; + use ethereum_types::{H160, U256}; #[test] fn ethash_deserialization() { diff --git a/json/src/spec/genesis.rs b/json/src/spec/genesis.rs index 5d5505930bf..69ce6597ca6 100644 --- a/json/src/spec/genesis.rs +++ b/json/src/spec/genesis.rs @@ -20,7 +20,7 @@ use crate::{ bytes::Bytes, hash::{Address, H256}, spec::Seal, - uint::{Uint, self}, + uint::{self, Uint}, }; use serde::Deserialize; @@ -56,13 +56,13 @@ pub struct Genesis { #[cfg(test)] mod tests { - use super::*; + use std::str::FromStr; + use super::{Address, Bytes, Genesis, H256, Uint}; use crate::{ hash::H64, spec::{Ethereum, Seal} }; use ethereum_types::{U256, H160, H64 as Eth64, H256 as Eth256}; - use std::str::FromStr; #[test] fn genesis_deserialization() { diff --git a/json/src/spec/hardcoded_sync.rs b/json/src/spec/hardcoded_sync.rs index 5d297d57d51..3b53365cb4e 100644 --- a/json/src/spec/hardcoded_sync.rs +++ b/json/src/spec/hardcoded_sync.rs @@ -35,9 +35,9 @@ pub struct HardcodedSync { #[cfg(test)] mod tests { - use super::*; - use ethereum_types::{U256, H256 as Eth256}; use std::str::FromStr; + use super::{H256, HardcodedSync, Uint}; + use ethereum_types::{U256, H256 as Eth256}; #[test] fn hardcoded_sync_deserialization() { diff --git a/json/src/spec/null_engine.rs b/json/src/spec/null_engine.rs index 1413a3e4051..2e9b74c48f6 100644 --- a/json/src/spec/null_engine.rs +++ b/json/src/spec/null_engine.rs @@ -40,7 +40,7 @@ pub struct NullEngine { #[cfg(test)] mod tests { - use super::*; + use super::{NullEngine, Uint}; use ethereum_types::U256; #[test] diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 29ebeab1553..f2907654942 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -143,7 +143,7 @@ pub struct Params { #[cfg(test)] mod tests { - use super::*; + use super::{Params, Uint}; use ethereum_types::U256; #[test] diff --git a/json/src/spec/seal.rs b/json/src/spec/seal.rs index d79dfbda0af..04d6c2f5cd1 100644 --- a/json/src/spec/seal.rs +++ b/json/src/spec/seal.rs @@ -69,11 +69,9 @@ pub enum Seal { #[cfg(test)] mod tests { - use super::*; - use serde_json; - use ethereum_types::{U256, H64 as Eth64, H256 as Eth256, H520 as Eth520}; - use crate::spec::{Ethereum, AuthorityRoundSeal, TendermintSeal, Seal}; use std::str::FromStr; + use super::{AuthorityRoundSeal, Bytes, Ethereum, H64, H256, H520, TendermintSeal, Seal, Uint}; + use ethereum_types::{U256, H64 as Eth64, H256 as Eth256, H520 as Eth520}; #[test] fn seal_deserialization() { diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index 9f4955add81..0fcfff37852 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -69,7 +69,7 @@ impl Spec { #[cfg(test)] mod tests { - use super::*; + use super::Spec; #[test] fn should_error_on_unknown_fields() { diff --git a/json/src/spec/validator_set.rs b/json/src/spec/validator_set.rs index aac17000df2..5dcc5558e60 100644 --- a/json/src/spec/validator_set.rs +++ b/json/src/spec/validator_set.rs @@ -37,9 +37,9 @@ pub enum ValidatorSet { #[cfg(test)] mod tests { - use super::*; - use ethereum_types::{H160, U256}; use std::str::FromStr; + use super::{Address, Uint, ValidatorSet}; + use ethereum_types::{H160, U256}; #[test] fn validator_set_deserialization() { diff --git a/json/src/state.rs b/json/src/state.rs index 2f778b57319..da05b1f68ac 100644 --- a/json/src/state.rs +++ b/json/src/state.rs @@ -37,7 +37,7 @@ pub struct Log { #[cfg(test)] mod tests { - use super::*; + use super::Log; #[test] fn log_deserialization() { diff --git a/json/src/test_helpers/blockchain/block.rs b/json/src/test_helpers/blockchain/block.rs index cb1b04312d0..e219fb7bfe8 100644 --- a/json/src/test_helpers/blockchain/block.rs +++ b/json/src/test_helpers/blockchain/block.rs @@ -40,7 +40,7 @@ impl Block { #[cfg(test)] mod tests { - use super::*; + use super::Block; #[test] fn block_deserialization() { diff --git a/json/src/test_helpers/blockchain/header.rs b/json/src/test_helpers/blockchain/header.rs index 78916338c0d..b1144934211 100644 --- a/json/src/test_helpers/blockchain/header.rs +++ b/json/src/test_helpers/blockchain/header.rs @@ -67,7 +67,7 @@ pub struct Header { #[cfg(test)] mod tests { - use super::*; + use super::Header; #[test] fn header_deserialization() { diff --git a/json/src/test_helpers/blockchain/mod.rs b/json/src/test_helpers/blockchain/mod.rs index 593531d1989..3aac3e8a047 100644 --- a/json/src/test_helpers/blockchain/mod.rs +++ b/json/src/test_helpers/blockchain/mod.rs @@ -105,7 +105,7 @@ impl BlockChain { #[cfg(test)] mod tests { - use super::*; + use super::BlockChain; #[test] fn blockchain_deserialization() { diff --git a/json/src/test_helpers/transaction.rs b/json/src/test_helpers/transaction.rs index ddddea54769..9cfeb032b83 100644 --- a/json/src/test_helpers/transaction.rs +++ b/json/src/test_helpers/transaction.rs @@ -44,7 +44,7 @@ pub struct PostState { #[cfg(test)] mod tests { - use super::*; + use super::TransactionTest; #[test] fn transaction_deserialization() { diff --git a/json/src/test_helpers/trie/input.rs b/json/src/test_helpers/trie/input.rs index 5a7533dc791..01d223b59a1 100644 --- a/json/src/test_helpers/trie/input.rs +++ b/json/src/test_helpers/trie/input.rs @@ -117,7 +117,7 @@ impl<'a> Visitor<'a> for InputVisitor { #[cfg(test)] mod tests { - use super::*; + use super::{BTreeMap, Bytes, Input}; #[test] fn input_deserialization_from_map() { diff --git a/json/src/transaction.rs b/json/src/transaction.rs index 5f6a827b952..0e0a8de79b7 100644 --- a/json/src/transaction.rs +++ b/json/src/transaction.rs @@ -56,7 +56,7 @@ pub struct TransactionWithSigningInfo { #[cfg(test)] mod tests { - use super::*; + use super::{Transaction, TransactionWithSigningInfo}; #[test] fn transaction_deserialization() { diff --git a/json/src/uint.rs b/json/src/uint.rs index b0c58cc8dcb..8cba3f1ddef 100644 --- a/json/src/uint.rs +++ b/json/src/uint.rs @@ -118,7 +118,7 @@ pub fn validate_optional_non_zero<'de, D>(d: D) -> Result, D::Error #[cfg(test)] mod test { - use super::*; + use super::Uint; use ethereum_types::U256; #[test] diff --git a/json/src/vm.rs b/json/src/vm.rs index 9125721545a..dc8bb8241cd 100644 --- a/json/src/vm.rs +++ b/json/src/vm.rs @@ -122,7 +122,7 @@ pub struct Env { #[cfg(test)] mod tests { use std::str::FromStr; - use super::*; + use super::{Address, Call, Env, MaybeEmpty, Transaction, Uint, Vm}; use ethereum_types::{U256, H160 as Hash160}; #[test] From 7bbd397b3960bde5d48b08b012daebb6fac0b11b Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 9 Sep 2019 13:45:41 +0200 Subject: [PATCH 09/10] fix(grumble): merge `tx` and `tx_with_signing_info` --- ethcore/types/src/transaction/transaction.rs | 32 ++++++++++---------- json/src/test_helpers/state.rs | 20 ++++++------ json/src/transaction.rs | 32 +++----------------- 3 files changed, 29 insertions(+), 55 deletions(-) diff --git a/ethcore/types/src/transaction/transaction.rs b/ethcore/types/src/transaction/transaction.rs index 09fdae184aa..6e99dc42951 100644 --- a/ethcore/types/src/transaction/transaction.rs +++ b/ethcore/types/src/transaction/transaction.rs @@ -134,20 +134,20 @@ impl Transaction { } } -impl From for SignedTransaction { - fn from(t: ethjson::transaction::TransactionWithSigningInfo) -> Self { - let to: Option = t.transaction.to.into(); +impl From for SignedTransaction { + fn from(t: ethjson::transaction::Transaction) -> Self { + let to: Option = t.to.into(); let secret = t.secret.map(|s| Secret::from(s.0)); let tx = Transaction { - nonce: t.transaction.nonce.into(), - gas_price: t.transaction.gas_price.into(), - gas: t.transaction.gas_limit.into(), + nonce: t.nonce.into(), + gas_price: t.gas_price.into(), + gas: t.gas_limit.into(), action: match to { Some(to) => Action::Call(to.into()), None => Action::Create }, - value: t.transaction.value.into(), - data: t.transaction.data.into(), + value: t.value.into(), + data: t.data.into(), }; match secret { Some(s) => tx.sign(&s, None), @@ -156,20 +156,20 @@ impl From for SignedTransactio } } -impl From for UnverifiedTransaction { - fn from(t: ethjson::transaction::TransactionWithSigningInfo) -> Self { - let to: Option = t.transaction.to.into(); +impl From for UnverifiedTransaction { + fn from(t: ethjson::transaction::Transaction) -> Self { + let to: Option = t.to.into(); UnverifiedTransaction { unsigned: Transaction { - nonce: t.transaction.nonce.into(), - gas_price: t.transaction.gas_price.into(), - gas: t.transaction.gas_limit.into(), + nonce: t.nonce.into(), + gas_price: t.gas_price.into(), + gas: t.gas_limit.into(), action: match to { Some(to) => Action::Call(to.into()), None => Action::Create }, - value: t.transaction.value.into(), - data: t.transaction.data.into(), + value: t.value.into(), + data: t.data.into(), }, r: t.r.into(), s: t.s.into(), diff --git a/json/src/test_helpers/state.rs b/json/src/test_helpers/state.rs index 49e5ce90713..f86257dfa5c 100644 --- a/json/src/test_helpers/state.rs +++ b/json/src/test_helpers/state.rs @@ -27,7 +27,7 @@ use crate::{ maybe::MaybeEmpty, uint::Uint, spec::{ForkSpec, State as AccountState}, - transaction::{Transaction, TransactionWithSigningInfo}, + transaction::Transaction, vm::Env }; @@ -69,16 +69,14 @@ pub struct MultiTransaction { impl MultiTransaction { /// Build transaction with given indexes. - pub fn select(&self, indexes: &PostStateIndexes) -> TransactionWithSigningInfo { - TransactionWithSigningInfo { - transaction: Transaction { - data: self.data[indexes.data as usize].clone(), - gas_limit: self.gas_limit[indexes.gas as usize].clone(), - gas_price: self.gas_price.clone(), - nonce: self.nonce.clone(), - to: self.to.clone(), - value: self.value[indexes.value as usize].clone(), - }, + pub fn select(&self, indexes: &PostStateIndexes) -> Transaction { + Transaction { + data: self.data[indexes.data as usize].clone(), + gas_limit: self.gas_limit[indexes.gas as usize], + gas_price: self.gas_price, + nonce: self.nonce, + to: self.to.clone(), + value: self.value[indexes.value as usize], r: Default::default(), s: Default::default(), v: Default::default(), diff --git a/json/src/transaction.rs b/json/src/transaction.rs index 0e0a8de79b7..b051ff86876 100644 --- a/json/src/transaction.rs +++ b/json/src/transaction.rs @@ -19,7 +19,7 @@ use crate::{bytes::Bytes, hash::{Address, H256}, maybe::MaybeEmpty, uint::Uint}; use serde::Deserialize; -/// Plain transaction deserialization. +/// Unsigned transaction with signing information deserialization. #[derive(Debug, PartialEq, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Transaction { @@ -35,14 +35,6 @@ pub struct Transaction { pub to: MaybeEmpty
, /// Value. pub value: Uint, -} - -/// Unsigned transaction with signing information deserialization -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TransactionWithSigningInfo { - /// Transaction - pub transaction: Transaction, /// R. pub r: Uint, /// S. @@ -56,7 +48,7 @@ pub struct TransactionWithSigningInfo { #[cfg(test)] mod tests { - use super::{Transaction, TransactionWithSigningInfo}; + use super::Transaction; #[test] fn transaction_deserialization() { @@ -66,29 +58,13 @@ mod tests { "gasPrice" : "0x09184e72a000", "nonce" : "0x00", "to" : "", - "value" : "0x00" - }"#; - let _deserialized: Transaction = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } - - #[test] - fn transaction_with_signing_info_deserialization() { - let s = r#"{ - "transaction": { - "data" : "0x", - "gasLimit" : "0xf388", - "gasPrice" : "0x09184e72a000", - "nonce" : "0x00", - "to" : "", - "value" : "0x00" - }, + "value" : "0x00", "r": 0, "s": 1, "v": 2, "secretKey": "0x0000000000000000000000000000000000000000000000000000000000000000" }"#; - let _deserialized: TransactionWithSigningInfo = serde_json::from_str(s).unwrap(); + let _deserialized: Transaction = serde_json::from_str(s).unwrap(); // TODO: validate all fields } } From 4837348687875fab22e86a80a68f937d12b3bdfd Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 10 Sep 2019 11:49:19 +0200 Subject: [PATCH 10/10] fix(grumbles): resolve introduced `TODO's` --- Cargo.lock | 1 + json/Cargo.toml | 3 ++ json/src/spec/state.rs | 8 +++- json/src/transaction.rs | 16 +++++-- json/src/vm.rs | 98 +++++++++++++++++++++++++++-------------- 5 files changed, 88 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index edae1d5a67a..94e62f23d0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1511,6 +1511,7 @@ name = "ethjson" version = "0.1.0" dependencies = [ "ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "macros 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/json/Cargo.toml b/json/Cargo.toml index de65388534f..4fe094d98ef 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -11,5 +11,8 @@ rustc-hex = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +[dev-dependencies] +macros = { path = "../util/macros" } + [features] test-helpers = [] diff --git a/json/src/spec/state.rs b/json/src/spec/state.rs index df9b09ce28b..fd50a864f1a 100644 --- a/json/src/spec/state.rs +++ b/json/src/spec/state.rs @@ -24,8 +24,14 @@ use crate::{ }; use serde::Deserialize; +/// Blockchain state deserializer for tests +#[cfg(any(test, feature = "test-helpers"))] +#[derive(Clone, Debug, PartialEq, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct State(pub BTreeMap); + /// Blockchain state deserializer. -#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))] +#[cfg(not(any(test, feature = "test-helpers")))] #[derive(Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] pub struct State(BTreeMap); diff --git a/json/src/transaction.rs b/json/src/transaction.rs index b051ff86876..84a496c5a6f 100644 --- a/json/src/transaction.rs +++ b/json/src/transaction.rs @@ -48,7 +48,8 @@ pub struct Transaction { #[cfg(test)] mod tests { - use super::Transaction; + use super::{Bytes, H256, MaybeEmpty, Transaction, Uint}; + use ethereum_types::{H256 as Eth256, U256}; #[test] fn transaction_deserialization() { @@ -64,7 +65,16 @@ mod tests { "v": 2, "secretKey": "0x0000000000000000000000000000000000000000000000000000000000000000" }"#; - let _deserialized: Transaction = serde_json::from_str(s).unwrap(); - // TODO: validate all fields + let tx: Transaction = serde_json::from_str(s).unwrap(); + assert_eq!(tx.data, Bytes::new(Vec::new())); + assert_eq!(tx.gas_limit, Uint(U256::from(0xf388))); + assert_eq!(tx.gas_price, Uint(U256::from(0x09184e72a000_u64))); + assert_eq!(tx.nonce, Uint(U256::zero())); + assert_eq!(tx.to, MaybeEmpty::None); + assert_eq!(tx.value, Uint(U256::zero())); + assert_eq!(tx.r, Uint(U256::zero())); + assert_eq!(tx.s, Uint(U256::one())); + assert_eq!(tx.v, Uint(U256::from(2))); + assert_eq!(tx.secret, Some(H256(Eth256::zero()))); } } diff --git a/json/src/vm.rs b/json/src/vm.rs index dc8bb8241cd..f4bc791c124 100644 --- a/json/src/vm.rs +++ b/json/src/vm.rs @@ -121,9 +121,18 @@ pub struct Env { #[cfg(test)] mod tests { - use std::str::FromStr; - use super::{Address, Call, Env, MaybeEmpty, Transaction, Uint, Vm}; - use ethereum_types::{U256, H160 as Hash160}; + use std::{ + collections::BTreeMap, + str::FromStr + }; + use super::{Address, Bytes, Call, Env, H256, MaybeEmpty, State, Transaction, Uint, Vm}; + + use crate::spec::Account; + use ethereum_types::{U256, H160 as Hash160, H256 as Hash256}; + use macros::map; + use rustc_hex::FromHex; + + const TEST_CODE: &str = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055"; #[test] fn vm_deserialization() { @@ -150,7 +159,6 @@ mod tests { "gas" : "0x013874", "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "out" : "0x", - "network" : "Frontier", "post" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "0x0de0b6b3a7640000", @@ -171,8 +179,58 @@ mod tests { } } }"#; - let _deserialized: Vm = serde_json::from_str(s).unwrap(); - // TODO: validate all fields + let vm: Vm = serde_json::from_str(s).unwrap(); + assert_eq!(vm.calls, Some(Vec::new())); + assert_eq!(vm.env, Env { + author: Address(Hash160::from_str("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap()), + difficulty: Uint(0x0100.into()), + gas_limit: Uint(0x0f4240.into()), + number: Uint(0.into()), + timestamp: Uint(1.into()) + }); + assert_eq!(vm.transaction, Transaction { + address: Address(Hash160::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap()), + sender: Address(Hash160::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap()), + code: Bytes::new(TEST_CODE.from_hex().unwrap()), + code_version: Uint(0.into()), + data: Bytes::new(Vec::new()), + gas: Uint(0x0186a0.into()), + gas_price: Uint(0x5af3107a4000_u64.into()), + origin: Address(Hash160::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap()), + value: Uint(0x0de0b6b3a7640000_u64.into()) + }); + assert_eq!(vm.gas_left, Some(Uint(0x013874.into()))); + assert_eq!( + vm.logs, + Some(H256(Hash256::from_str("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").unwrap())) + ); + assert_eq!(vm.output, Some(Bytes::new(Vec::new()))); + assert_eq!(vm.pre_state, State(map![ + Address(Hash160::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap()) => Account { + builtin: None, + balance: Some(Uint(0x0de0b6b3a7640000_u64.into())), + code: Some(Bytes::new(TEST_CODE.from_hex().unwrap())), + constructor: None, + nonce: Some(Uint(0.into())), + storage: Some(map![]), + version: None, + }]) + ); + assert_eq!(vm.post_state, Some( + State(map![ + Address(Hash160::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap()) => Account { + builtin: None, + balance: Some(Uint(0x0de0b6b3a7640000_u64.into())), + code: Some(Bytes::new(TEST_CODE.from_hex().unwrap())), + constructor: None, + nonce: Some(Uint(0.into())), + storage: Some(map![ + Uint(0.into()) => Uint(U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap()) + ]), + version: None, + }]) + ) + ); } #[test] @@ -211,32 +269,4 @@ mod tests { assert_eq!(call.gas_limit, Uint(U256::from(0x1748766aa5u64))); assert_eq!(call.value, Uint(U256::from(0))); } - - #[test] - fn transaction_deserialization() { - let s = r#"{ - "address": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "caller": "cd1722f2947def4cf144679da39c4c32bdc35681", - "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055", - "data": "0x", - "gas": "0x0186a0", - "gasPrice": "0x5af3107a4000", - "origin": "cd1722f2947def4cf144679da39c4c32bdc35681", - "value": "0x0de0b6b3a7640000" - }"#; - let _deserialized: Transaction = serde_json::from_str(s).unwrap(); - } - - #[test] - fn env_deserialization() { - let s = r#"{ - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "0x0100", - "currentGasLimit" : "0x0f4240", - "currentNumber" : "0x00", - "currentTimestamp" : "0x01" - }"#; - let _deserialized: Env = serde_json::from_str(s).unwrap(); - // TODO: validate all fields - } }