cleanup json crate (#11027)

* [json]: cleanup

write something here....

* nit: commit new/moved files

* nit: remove needless features

* nits

* fix(grumbles): use explicit import `DifficultyTest`

* fix(grumbles): remove needless type hints

* fix(grumble): docs `from -> used by`

Co-Authored-By: David <dvdplm@gmail.com>

* fix(grumbles): use explicit `imports`

* fix(grumble): merge `tx` and `tx_with_signing_info`

* fix(grumbles): resolve introduced `TODO's`
This commit is contained in:
Niklas Adolfsson 2019-09-10 20:46:50 +02:00 committed by David
parent fc9a2933af
commit d311bebaee
70 changed files with 671 additions and 1361 deletions

2
Cargo.lock generated
View File

@ -1511,9 +1511,9 @@ name = "ethjson"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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 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)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View File

@ -79,7 +79,7 @@ engine = { path = "./engine", features = ["test-helpers"] }
env_logger = "0.5" env_logger = "0.5"
ethash = { path = "../ethash" } ethash = { path = "../ethash" }
ethcore-accounts = { path = "../accounts" } ethcore-accounts = { path = "../accounts" }
ethjson = { path = "../json" } ethjson = { path = "../json", features = ["test-helpers"] }
ethkey = { path = "../accounts/ethkey" } ethkey = { path = "../accounts/ethkey" }
fetch = { path = "../util/fetch" } fetch = { path = "../util/fetch" }
kvdb-memorydb = "0.1" kvdb-memorydb = "0.1"
@ -89,7 +89,6 @@ machine = { path = "./machine", features = ["test-helpers"] }
macros = { path = "../util/macros" } macros = { path = "../util/macros" }
null-engine = { path = "./engines/null-engine" } null-engine = { path = "./engines/null-engine" }
parity-runtime = { path = "../util/runtime" } parity-runtime = { path = "../util/runtime" }
pod = { path = "pod" }
rlp_compress = { path = "../util/rlp-compress" } rlp_compress = { path = "../util/rlp-compress" }
rustc-hex = "1" rustc-hex = "1"
serde_json = "1.0" serde_json = "1.0"

View File

@ -85,22 +85,6 @@ impl PodAccount {
} }
} }
impl From<ethjson::blockchain::Account> 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<ethjson::spec::Account> for PodAccount { impl From<ethjson::spec::Account> for PodAccount {
fn from(a: ethjson::spec::Account) -> Self { fn from(a: ethjson::spec::Account) -> Self {
PodAccount { PodAccount {

View File

@ -46,13 +46,6 @@ impl PodState {
} }
} }
impl From<ethjson::blockchain::State> 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<ethjson::spec::State> for PodState { impl From<ethjson::spec::State> for PodState {
fn from(s: ethjson::spec::State) -> PodState { fn from(s: ethjson::spec::State) -> PodState {
let state: BTreeMap<_,_> = s.into_iter() let state: BTreeMap<_,_> = s.into_iter()

View File

@ -44,7 +44,7 @@ fn skip_test(name: &String) -> bool {
pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> { pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
let _ = ::env_logger::try_init(); 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(); let mut failed = Vec::new();
for (name, blockchain) in tests.into_iter() { for (name, blockchain) in tests.into_iter() {
@ -84,7 +84,7 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
{ {
let db = test_helpers::new_db(); let db = test_helpers::new_db();
let mut config = ClientConfig::default(); 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.verifier_type = VerifierType::CanonNoSeal;
config.check_seal = false; config.check_seal = false;
} }

View File

@ -14,16 +14,20 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use ethjson;
use types::header::Header;
use ethereum_types::U256; use ethereum_types::U256;
use ethjson::test_helpers::difficulty::DifficultyTest;
use types::header::Header;
use spec::Spec; use spec::Spec;
use super::HookType; use super::HookType;
pub fn json_difficulty_test<H: FnMut(&str, HookType)>(json_data: &[u8], spec: Spec, start_stop_hook: &mut H) -> Vec<String> { pub fn json_difficulty_test<H: FnMut(&str, HookType)>(
let _ = ::env_logger::try_init(); json_data: &[u8],
let tests = ethjson::test::DifficultyTest::load(json_data).unwrap(); spec: Spec,
start_stop_hook: &mut H
) -> Vec<String> {
let _ = env_logger::try_init();
let tests = DifficultyTest::load(json_data).unwrap();
let engine = &spec.engine; let engine = &spec.engine;
for (name, test) in tests.into_iter() { for (name, test) in tests.into_iter() {

View File

@ -243,8 +243,12 @@ fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<St
.collect() .collect()
} }
fn do_json_test_for<H: FnMut(&str, HookType)>(vm_type: &VMType, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> { fn do_json_test_for<H: FnMut(&str, HookType)>(
let tests = ethjson::vm::Test::load(json_data).unwrap(); vm_type: &VMType,
json_data: &[u8],
start_stop_hook: &mut H
) -> Vec<String> {
let tests = ethjson::test_helpers::vm::Test::load(json_data).unwrap();
let mut failed = Vec::new(); let mut failed = Vec::new();
for (name, vm) in tests.into_iter() { for (name, vm) in tests.into_iter() {
@ -336,15 +340,15 @@ fn do_json_test_for<H: FnMut(&str, HookType)>(vm_type: &VMType, json_data: &[u8]
for (address, account) in vm.post_state.unwrap().into_iter() { for (address, account) in vm.post_state.unwrap().into_iter() {
let address = address.into(); let address = address.into();
let code: Vec<u8> = account.code.into(); let code: Vec<u8> = account.code.expect("code is missing from json; test should have code").into();
let found_code = try_fail!(state.code(&address)); let found_code = try_fail!(state.code(&address));
let found_balance = try_fail!(state.balance(&address)); let found_balance = try_fail!(state.balance(&address));
let found_nonce = try_fail!(state.nonce(&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_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(account.balance.as_ref().map_or(false, |b| b.0 == found_balance), "balance is incorrect");
fail_unless(found_nonce == account.nonce.into(), "nonce 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 { for (k, v) in account.storage.expect("test should have storage") {
let key: U256 = k.into(); let key: U256 = k.into();
let value: U256 = v.into(); let value: U256 = v.into();
let found_storage = try_fail!(state.storage_at(&address, &BigEndianHash::from_uint(&key))); let found_storage = try_fail!(state.storage_at(&address, &BigEndianHash::from_uint(&key)));

View File

@ -16,19 +16,19 @@
//! State tests to skip. //! State tests to skip.
use ethjson; use ethjson::test_helpers::skip::SkipStates;
#[cfg(feature="ci-skip-tests")] #[cfg(feature="ci-skip-tests")]
lazy_static!{ lazy_static! {
pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = { pub static ref SKIP_TEST_STATE: SkipStates = {
let skip_data = include_bytes!("../../res/ethereum/tests-issues/currents.json"); 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"))] #[cfg(not(feature="ci-skip-tests"))]
lazy_static!{ lazy_static!{
pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = { pub static ref SKIP_TEST_STATE: SkipStates = {
ethjson::test::SkipStates::empty() SkipStates::empty()
}; };
} }

View File

@ -49,7 +49,7 @@ fn skip_test(subname: &str, chain: &String, number: usize) -> bool {
pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> { pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
let _ = ::env_logger::try_init(); 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(); let mut failed = Vec::new();
for (name, test) in tests.into_iter() { for (name, test) in tests.into_iter() {

View File

@ -41,7 +41,7 @@ pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
const BLOCK_NUMBER: u64 = 0x6ffffffffffffe; const BLOCK_NUMBER: u64 = 0x6ffffffffffffe;
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> { fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
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(); let mut failed = Vec::new();
for (name, test) in tests.into_iter() { for (name, test) in tests.into_iter() {
start_stop_hook(&name, HookType::OnStart); start_stop_hook(&name, HookType::OnStart);

View File

@ -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; pub use self::secure::run_test_file as run_secure_test_file;
fn test_trie<H: FnMut(&str, HookType)>(json: &[u8], trie: TrieSpec, start_stop_hook: &mut H) -> Vec<String> { fn test_trie<H: FnMut(&str, HookType)>(json: &[u8], trie: TrieSpec, start_stop_hook: &mut H) -> Vec<String> {
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 factory = TrieFactory::new(trie, ethtrie::Layout);
let mut result = vec![]; let mut result = vec![];

View File

@ -134,8 +134,8 @@ impl Transaction {
} }
} }
impl From<ethjson::state::Transaction> for SignedTransaction { impl From<ethjson::transaction::Transaction> for SignedTransaction {
fn from(t: ethjson::state::Transaction) -> Self { fn from(t: ethjson::transaction::Transaction) -> Self {
let to: Option<ethjson::hash::Address> = t.to.into(); let to: Option<ethjson::hash::Address> = t.to.into();
let secret = t.secret.map(|s| Secret::from(s.0)); let secret = t.secret.map(|s| Secret::from(s.0));
let tx = Transaction { let tx = Transaction {

View File

@ -122,7 +122,7 @@ fn main() {
} }
fn run_state_test(args: Args) { 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 <file>`. // Parse the specified state test JSON file provided to the command `state-test <file>`.
let file = args.arg_file.expect("PATH to a state test JSON file is required"); let file = args.arg_file.expect("PATH to a state test JSON file is required");
@ -443,8 +443,8 @@ fn die<T: fmt::Display>(msg: T) -> ! {
mod tests { mod tests {
use common_types::transaction; use common_types::transaction;
use docopt::Docopt; use docopt::Docopt;
use ethcore::{TrieSpec}; use ethcore::TrieSpec;
use ethjson::state::test::{State}; use ethjson::test_helpers::state::State;
use serde::Deserialize; use serde::Deserialize;
use super::{Args, USAGE, Address, run_call}; use super::{Args, USAGE, Address, run_call};

View File

@ -3,10 +3,16 @@ description = "Parity Ethereum JSON Deserialization"
name = "ethjson" name = "ethjson"
version = "0.1.0" version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies] [dependencies]
ethereum-types = "0.6.0" ethereum-types = "0.6.0"
rustc-hex = "1.0" rustc-hex = "1.0"
serde = "1.0" serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
serde_derive = "1.0"
[dev-dependencies]
macros = { path = "../util/macros" }
[features]
test-helpers = []

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<Uint, Uint>,
/// 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
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<Address, Account>);
impl IntoIterator for State {
type Item = <BTreeMap<Address, Account> as IntoIterator>::Item;
type IntoIter = <BTreeMap<Address, Account> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<String, BlockChain>);
impl IntoIterator for Test {
type Item = <BTreeMap<String, BlockChain> as IntoIterator>::Item;
type IntoIter = <BTreeMap<String, BlockChain> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Test {
/// Loads test from json.
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
serde_json::from_reader(reader)
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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
}

View File

@ -63,10 +63,10 @@ impl FromStr for Bytes {
2 if value.starts_with("0x") => vec![], 2 if value.starts_with("0x") => vec![],
_ if value.starts_with("0x") && value.len() % 2 == 1 => { _ if value.starts_with("0x") && value.len() % 2 == 1 => {
let v = "0".to_owned() + &value[2..]; 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![]), _ if value.starts_with("0x") => FromHex::from_hex(&value[2..]).unwrap_or_default(),
_ => FromHex::from_hex(value).unwrap_or(vec![]), _ => FromHex::from_hex(value).unwrap_or_default(),
}; };
Ok(Bytes(v)) Ok(Bytes(v))
@ -100,8 +100,7 @@ impl<'a> Visitor<'a> for BytesVisitor {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use serde_json; use super::Bytes;
use bytes::Bytes;
#[test] #[test]
fn bytes_deserialization() { fn bytes_deserialization() {
@ -118,8 +117,7 @@ mod test {
#[test] #[test]
fn bytes_into() { fn bytes_into() {
let bytes = Bytes(vec![0xff, 0x11]); let v: Vec<u8> = Bytes(vec![0xff, 0x11]).into();
let v: Vec<u8> = bytes.into();
assert_eq!(vec![0xff, 0x11], v); assert_eq!(vec![0xff, 0x11], v);
} }
} }

View File

@ -94,10 +94,8 @@ impl_hash!(Bloom, Hash2048);
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::H256;
use std::str::FromStr; use std::str::FromStr;
use serde_json;
use ethereum_types;
use hash::H256;
#[test] #[test]
fn hash_deserialization() { fn hash_deserialization() {

View File

@ -14,20 +14,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
extern crate rustc_hex; //! JSON deserialization library
extern crate serde;
extern crate serde_json; #![warn(missing_docs)]
extern crate ethereum_types;
#[macro_use] extern crate serde_derive;
pub mod hash;
pub mod uint;
pub mod bytes; pub mod bytes;
pub mod blockchain; pub mod hash;
pub mod spec;
pub mod trie;
pub mod vm;
pub mod maybe; pub mod maybe;
pub mod state; pub mod spec;
pub mod uint;
pub mod vm;
pub mod transaction; pub mod transaction;
pub mod test; pub mod state;
#[cfg(any(test, feature = "test-helpers"))]
pub mod test_helpers;

View File

@ -61,13 +61,12 @@ impl<'a, T> Visitor<'a> for MaybeEmptyVisitor<T> where T: Deserialize<'a> {
} }
fn visit_string<E>(self, value: String) -> Result<Self::Value, E> where E: Error { fn visit_string<E>(self, value: String) -> Result<Self::Value, E> where E: Error {
match value.is_empty() { if value.is_empty() {
true => Ok(MaybeEmpty::None), Ok(MaybeEmpty::None)
false => { } else {
T::deserialize(value.into_deserializer()).map(MaybeEmpty::Some) T::deserialize(value.into_deserializer()).map(MaybeEmpty::Some)
} }
} }
}
} }
impl<T> Into<Option<T>> for MaybeEmpty<T> { impl<T> Into<Option<T>> for MaybeEmpty<T> {
@ -82,10 +81,8 @@ impl<T> Into<Option<T>> for MaybeEmpty<T> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr; use std::str::FromStr;
use serde_json; use super::MaybeEmpty;
use ethereum_types; use crate::hash::H256;
use hash::H256;
use maybe::MaybeEmpty;
#[test] #[test]
fn maybe_deserialization() { fn maybe_deserialization() {

View File

@ -17,11 +17,12 @@
//! Spec account deserialization. //! Spec account deserialization.
use std::collections::BTreeMap; use std::collections::BTreeMap;
use uint::Uint;
use bytes::Bytes; use crate::{bytes::Bytes, spec::builtin::Builtin, uint::Uint};
use spec::builtin::Builtin; use serde::Deserialize;
/// Spec account. /// Spec account.
#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))]
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct Account { pub struct Account {
@ -50,12 +51,8 @@ impl Account {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::BTreeMap; use super::{Account, Bytes, BTreeMap, Uint};
use serde_json;
use spec::account::Account;
use ethereum_types::U256; use ethereum_types::U256;
use uint::Uint;
use bytes::Bytes;
#[test] #[test]
fn account_balance_missing_not_empty() { fn account_balance_missing_not_empty() {

View File

@ -39,9 +39,8 @@
//! ``` //! ```
use std::collections::BTreeMap; use std::collections::BTreeMap;
use hash::Address; use crate::{bytes::Bytes, hash::Address, uint::Uint};
use uint::Uint; use serde::Deserialize;
use bytes::Bytes;
use super::ValidatorSet; use super::ValidatorSet;
/// Authority params deserialization. /// Authority params deserialization.
@ -108,12 +107,9 @@ pub struct AuthorityRound {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Address, Uint};
use ethereum_types::{U256, H160}; use ethereum_types::{U256, H160};
use uint::Uint; use crate::spec::{validator_set::ValidatorSet, authority_round::AuthorityRound};
use serde_json;
use hash::Address;
use spec::validator_set::ValidatorSet;
use spec::authority_round::AuthorityRound;
use std::str::FromStr; use std::str::FromStr;
#[test] #[test]

View File

@ -16,8 +16,9 @@
//! Authority params deserialization. //! Authority params deserialization.
use uint::Uint; use crate::uint::Uint;
use super::ValidatorSet; use super::ValidatorSet;
use serde::Deserialize;
/// Authority params deserialization. /// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -40,13 +41,10 @@ pub struct BasicAuthority {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json;
use uint::Uint;
use ethereum_types::{U256, H160};
use hash::Address;
use spec::basic_authority::BasicAuthority;
use spec::validator_set::ValidatorSet;
use std::str::FromStr; use std::str::FromStr;
use super::{BasicAuthority, Uint};
use ethereum_types::{U256, H160};
use crate::{hash::Address, spec::validator_set::ValidatorSet};
#[test] #[test]
fn basic_authority_deserialization() { fn basic_authority_deserialization() {

View File

@ -16,7 +16,8 @@
//! Spec builtin deserialization. //! Spec builtin deserialization.
use uint::Uint; use crate::uint::Uint;
use serde::Deserialize;
/// Linear pricing. /// Linear pricing.
@ -97,9 +98,7 @@ pub struct Builtin {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::{Builtin, Modexp, Linear, Pricing, Uint};
use spec::builtin::{Builtin, Pricing, Linear, Modexp};
use uint::Uint;
#[test] #[test]
fn builtin_deserialization() { fn builtin_deserialization() {

View File

@ -17,13 +17,14 @@
//! Clique params deserialization. //! Clique params deserialization.
use std::num::NonZeroU64; use std::num::NonZeroU64;
use serde::Deserialize;
/// Clique params deserialization. /// Clique params deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
pub struct CliqueParams { pub struct CliqueParams {
/// period as defined in EIP /// period as defined in EIP 225
pub period: Option<u64>, pub period: Option<u64>,
/// epoch length as defined in EIP /// epoch length as defined in EIP 225
pub epoch: Option<NonZeroU64> pub epoch: Option<NonZeroU64>
} }
@ -36,8 +37,7 @@ pub struct Clique {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::{Clique, NonZeroU64};
use super::*;
#[test] #[test]
fn clique_deserialization() { fn clique_deserialization() {

View File

@ -17,6 +17,7 @@
//! Engine deserialization. //! Engine deserialization.
use super::{Ethash, BasicAuthority, AuthorityRound, NullEngine, InstantSeal, Clique}; use super::{Ethash, BasicAuthority, AuthorityRound, NullEngine, InstantSeal, Clique};
use serde::Deserialize;
/// Engine deserialization. /// Engine deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -40,8 +41,7 @@ pub enum Engine {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::Engine;
use spec::Engine;
#[test] #[test]
fn engine_deserialization() { fn engine_deserialization() {

View File

@ -17,16 +17,21 @@
//! Ethash params deserialization. //! Ethash params deserialization.
use std::collections::BTreeMap; use std::collections::BTreeMap;
use uint::{self, Uint}; use crate::{
use bytes::Bytes; bytes::Bytes,
use hash::Address; uint::{self, Uint},
hash::Address
};
use serde::Deserialize;
/// Deserializable doppelganger of block rewards for EthashParams /// Deserializable doppelganger of block rewards for EthashParams
#[derive(Clone, Debug, PartialEq, Deserialize)] #[derive(Clone, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
#[serde(untagged)] #[serde(untagged)]
pub enum BlockReward { pub enum BlockReward {
/// Single block reward
Single(Uint), Single(Uint),
/// Several block rewards
Multi(BTreeMap<Uint, Uint>), Multi(BTreeMap<Uint, Uint>),
} }
@ -110,12 +115,9 @@ pub struct Ethash {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json;
use uint::Uint;
use ethereum_types::{H160, U256};
use hash::Address;
use spec::ethash::{Ethash, EthashParams, BlockReward};
use std::str::FromStr; use std::str::FromStr;
use super::{Address, BlockReward, Ethash, EthashParams, Uint};
use ethereum_types::{H160, U256};
#[test] #[test]
fn ethash_deserialization() { fn ethash_deserialization() {

View File

@ -16,10 +16,13 @@
//! Spec genesis deserialization. //! Spec genesis deserialization.
use uint::{Uint, self}; use crate::{
use hash::{Address, H256}; bytes::Bytes,
use bytes::Bytes; hash::{Address, H256},
use spec::Seal; spec::Seal,
uint::{self, Uint},
};
use serde::Deserialize;
/// Spec genesis. /// Spec genesis.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -53,14 +56,13 @@ pub struct Genesis {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json;
use bytes::Bytes;
use uint::Uint;
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; 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};
#[test] #[test]
fn genesis_deserialization() { fn genesis_deserialization() {

View File

@ -16,9 +16,8 @@
//! Spec hardcoded synchronization deserialization for the light client. //! Spec hardcoded synchronization deserialization for the light client.
use hash::H256; use crate::{bytes::Bytes, hash::H256, uint::Uint};
use uint::Uint; use serde::Deserialize;
use bytes::Bytes;
/// Spec hardcoded sync. /// Spec hardcoded sync.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -36,12 +35,9 @@ pub struct HardcodedSync {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json;
use uint::Uint;
use ethereum_types::{U256, H256 as Eth256};
use hash::H256;
use spec::hardcoded_sync::HardcodedSync;
use std::str::FromStr; use std::str::FromStr;
use super::{H256, HardcodedSync, Uint};
use ethereum_types::{U256, H256 as Eth256};
#[test] #[test]
fn hardcoded_sync_deserialization() { fn hardcoded_sync_deserialization() {

View File

@ -16,6 +16,8 @@
//! Instant seal engine params deserialization. //! Instant seal engine params deserialization.
use serde::Deserialize;
/// Instant seal engine params deserialization. /// Instant seal engine params deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]

View File

@ -16,7 +16,8 @@
//! Null engine params deserialization. //! Null engine params deserialization.
use uint::Uint; use crate::uint::Uint;
use serde::Deserialize;
/// Authority params deserialization. /// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -39,10 +40,8 @@ pub struct NullEngine {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::{NullEngine, Uint};
use uint::Uint;
use ethereum_types::U256; use ethereum_types::U256;
use super::*;
#[test] #[test]
fn null_engine_deserialization() { fn null_engine_deserialization() {

View File

@ -16,9 +16,12 @@
//! Spec params deserialization. //! Spec params deserialization.
use uint::{self, Uint}; use crate::{
use hash::{H256, Address}; bytes::Bytes,
use bytes::Bytes; hash::{H256, Address},
uint::{self, Uint}
};
use serde::Deserialize;
/// Spec params. /// Spec params.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -140,18 +143,16 @@ pub struct Params {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::{Params, Uint};
use uint::Uint;
use ethereum_types::U256; use ethereum_types::U256;
use spec::params::Params;
#[test] #[test]
fn params_deserialization() { fn params_deserialization() {
let s = r#"{ let s = r#"{
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"networkID" : "0x1", "networkID": "0x1",
"chainID" : "0x15", "chainID": "0x15",
"subprotocolName" : "exp", "subprotocolName": "exp",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"accountStartNonce": "0x01", "accountStartNonce": "0x01",
"gasLimitBoundDivisor": "0x20", "gasLimitBoundDivisor": "0x20",

View File

@ -16,9 +16,8 @@
//! Spec seal deserialization. //! Spec seal deserialization.
use hash::*; use crate::{bytes::Bytes, hash::{H64, H256, H520}, uint::Uint};
use uint::Uint; use serde::Deserialize;
use bytes::Bytes;
/// Ethereum seal. /// Ethereum seal.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -70,13 +69,9 @@ pub enum Seal {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
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 std::str::FromStr; 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] #[test]
fn seal_deserialization() { fn seal_deserialization() {

View File

@ -17,9 +17,9 @@
//! Spec deserialization. //! Spec deserialization.
use std::io::Read; use std::io::Read;
use serde_json; use crate::spec::{Params, Genesis, Engine, State, HardcodedSync};
use serde::Deserialize;
use serde_json::Error; use serde_json::Error;
use spec::{Params, Genesis, Engine, State, HardcodedSync};
/// Fork spec definition /// Fork spec definition
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)]
@ -70,8 +70,7 @@ impl Spec {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::Spec;
use spec::spec::Spec;
#[test] #[test]
fn should_error_on_unknown_fields() { fn should_error_on_unknown_fields() {

View File

@ -14,14 +14,24 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain test state deserializer. //! Blockchain state deserializer.
use std::collections::BTreeMap; use std::collections::BTreeMap;
use hash::Address; use crate::{
use bytes::Bytes; bytes::Bytes,
use spec::{Account, Builtin}; hash::Address,
spec::{Account, Builtin}
};
use serde::Deserialize;
/// Blockchain test state deserializer. /// 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<Address, Account>);
/// Blockchain state deserializer.
#[cfg(not(any(test, feature = "test-helpers")))]
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct State(BTreeMap<Address, Account>); pub struct State(BTreeMap<Address, Account>);

View File

@ -17,8 +17,8 @@
//! Validator set deserialization. //! Validator set deserialization.
use std::collections::BTreeMap; use std::collections::BTreeMap;
use uint::Uint; use crate::{hash::Address, uint::Uint};
use hash::Address; use serde::Deserialize;
/// Different ways of specifying validators. /// Different ways of specifying validators.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -37,12 +37,9 @@ pub enum ValidatorSet {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json;
use uint::Uint;
use ethereum_types::{H160, U256};
use hash::Address;
use spec::validator_set::ValidatorSet;
use std::str::FromStr; use std::str::FromStr;
use super::{Address, Uint, ValidatorSet};
use ethereum_types::{H160, U256};
#[test] #[test]
fn validator_set_deserialization() { fn validator_set_deserialization() {

View File

@ -14,11 +14,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! State test log deserialization. //! State deserialization types
use hash::{Address, H256, Bloom};
use bytes::Bytes;
/// State test log deserialization. use crate::{
bytes::Bytes,
hash::{Address, H256, Bloom},
};
use serde::Deserialize;
/// State log deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
pub struct Log { pub struct Log {
/// Address. /// Address.
@ -33,8 +37,7 @@ pub struct Log {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::Log;
use state::Log;
#[test] #[test]
fn log_deserialization() { fn log_deserialization() {

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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;

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<Log>
}
#[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
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<H256>,
/// To.
pub to: MaybeEmpty<Address>,
/// 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
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<String, DifficultyTestCase>);
impl IntoIterator for DifficultyTest {
type Item = <BTreeMap<String, DifficultyTestCase> as IntoIterator>::Item;
type IntoIter = <BTreeMap<String, DifficultyTestCase> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl DifficultyTest {
/// Loads test from json.
pub fn load<R>(reader: R) -> Result<Self, Error> 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<BlockSkipStates>,
/// State tests
pub state: Vec<StateSkipStates>,
}
/// 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<String>,
}
/// 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<String, StateSkipSubStates>
}
/// State subtest to skip.
#[derive(Debug, PartialEq, Deserialize)]
pub struct StateSkipSubStates {
/// State test number of this item. Or '*' for all state.
pub subnumbers: Vec<String>,
/// Chain for this items.
pub chain: String,
}
impl SkipStates {
/// Loads skip states from json.
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
serde_json::from_reader(reader)
}
/// Empty skip states.
pub fn empty() -> Self {
SkipStates {
block: Vec::new(),
state: Vec::new(),
}
}
}

View File

@ -16,9 +16,9 @@
//! Blockchain test block deserializer. //! Blockchain test block deserializer.
use bytes::Bytes; use crate::{bytes::Bytes, transaction::Transaction};
use blockchain::header::Header; use super::header::Header;
use blockchain::transaction::Transaction; use serde::Deserialize;
/// Blockchain test block deserializer. /// Blockchain test block deserializer.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -40,8 +40,7 @@ impl Block {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::Block;
use blockchain::block::Block;
#[test] #[test]
fn block_deserialization() { fn block_deserialization() {
@ -66,7 +65,7 @@ mod tests {
}, },
"blocknumber" : "1", "blocknumber" : "1",
"rlp" : "0xf901fcf901f7a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba808456850b7b80a013735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd0688931dcc53e5edc514c0c0", "rlp" : "0xf901fcf901f7a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba808456850b7b80a013735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd0688931dcc53e5edc514c0c0",
"transactions" : [], "transaction" : [],
"uncleHeaders" : [] "uncleHeaders" : []
}"#; }"#;
let _deserialized: Block = serde_json::from_str(s).unwrap(); let _deserialized: Block = serde_json::from_str(s).unwrap();

View File

@ -16,9 +16,12 @@
//! Blockchain test header deserializer. //! Blockchain test header deserializer.
use hash::{H64, Address, H256, Bloom}; use crate::{
use uint::Uint; bytes::Bytes,
use bytes::Bytes; hash::{H64, Address, H256, Bloom},
uint::Uint
};
use serde::Deserialize;
/// Blockchain test header deserializer. /// Blockchain test header deserializer.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -64,8 +67,7 @@ pub struct Header {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::Header;
use blockchain::header::Header;
#[test] #[test]
fn header_deserialization() { fn header_deserialization() {

View File

@ -14,14 +14,24 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain deserialization. //! Blockchain test deserialization.
use bytes::Bytes; use crate::{
use hash::H256; bytes::Bytes,
use blockchain::state::State; hash::H256,
use blockchain::header::Header; spec::{Ethereum, ForkSpec, Genesis, Seal, State}
use blockchain::block::Block;
use spec::{ForkSpec, Genesis, Seal, Ethereum}; };
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<String, BlockChain>;
/// Json Block test possible engine kind. /// Json Block test possible engine kind.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -95,8 +105,7 @@ impl BlockChain {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::BlockChain;
use blockchain::blockchain::BlockChain;
#[test] #[test]
fn blockchain_deserialization() { fn blockchain_deserialization() {

View File

@ -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<String, DifficultyTestCase>;

View File

@ -14,21 +14,24 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain test deserialization. //! Test structures for JSON deserialization.
pub mod account; /// Blockchain test helpers
pub mod block;
pub mod blockchain; pub mod blockchain;
pub mod header; /// Difficulty test helpers
pub mod difficulty;
/// Tests to skip helpers
pub mod skip;
/// State test helpers
pub mod state; pub mod state;
/// Test primitives
pub mod tester;
/// Transaction test helpers
pub mod transaction; pub mod transaction;
pub mod test; /// Trie test helpers
pub mod trie;
pub use self::account::Account; /// Vm test helpers
pub use self::block::Block; pub mod vm {
pub use self::blockchain::BlockChain; /// Type for running `vm` tests
pub use self::blockchain::Engine; pub type Test = super::tester::GenericTester<String, crate::vm::Vm>;
pub use self::header::Header; }
pub use self::state::State;
pub use self::test::Test;
pub use self::transaction::Transaction;

View File

@ -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<BlockSkipStates>,
/// State tests
pub state: Vec<StateSkipStates>,
}
/// 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<String>,
}
/// 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<String, StateSkipSubStates>
}
/// State subtest to skip.
#[derive(Debug, PartialEq, Deserialize)]
pub struct StateSkipSubStates {
/// State test number of this item. Or '*' for all state.
pub subnumbers: Vec<String>,
/// 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<R>(reader: R) -> Result<Self, serde_json::Error> where R: std::io::Read {
serde_json::from_reader(reader)
}
}

View File

@ -14,37 +14,22 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! General test deserialization. //! State test deserialization.
/// Type for running `State` tests
pub type Test = super::tester::GenericTester<String, State>;
use std::io::Read;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use uint::Uint; use serde::Deserialize;
use bytes::Bytes; use crate::{
use hash::{Address, H256}; bytes::Bytes,
use spec::ForkSpec; hash::{Address, H256},
use state::{Env, AccountState, Transaction}; maybe::MaybeEmpty,
use maybe::MaybeEmpty; uint::Uint,
use serde_json::{self, Error}; spec::{ForkSpec, State as AccountState},
transaction::Transaction,
/// State test deserializer. vm::Env
#[derive(Debug, PartialEq, Deserialize)] };
pub struct Test(BTreeMap<String, State>);
impl IntoIterator for Test {
type Item = <BTreeMap<String, State> as IntoIterator>::Item;
type IntoIter = <BTreeMap<String, State> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Test {
/// Loads test from json.
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
serde_json::from_reader(reader)
}
}
/// State test deserialization. /// State test deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
@ -87,12 +72,15 @@ impl MultiTransaction {
pub fn select(&self, indexes: &PostStateIndexes) -> Transaction { pub fn select(&self, indexes: &PostStateIndexes) -> Transaction {
Transaction { Transaction {
data: self.data[indexes.data as usize].clone(), data: self.data[indexes.data as usize].clone(),
gas_limit: self.gas_limit[indexes.gas as usize].clone(), gas_limit: self.gas_limit[indexes.gas as usize],
gas_price: self.gas_price.clone(), gas_price: self.gas_price,
nonce: self.nonce.clone(), nonce: self.nonce,
secret: self.secret.clone(),
to: self.to.clone(), to: self.to.clone(),
value: self.value[indexes.value as usize].clone(), value: self.value[indexes.value as usize],
r: Default::default(),
s: Default::default(),
v: Default::default(),
secret: self.secret.clone(),
} }
} }
} }

View File

@ -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<T: Ord, U>(BTreeMap<T, U>);
impl<T: Ord, U> IntoIterator for GenericTester<T, U> {
type Item = <BTreeMap<T, U> as IntoIterator>::Item;
type IntoIter = <BTreeMap<T, U> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<T, U> GenericTester<T, U>
where
T: DeserializeOwned + Ord,
U: DeserializeOwned
{
/// Loads test from json.
pub fn load<R>(reader: R) -> Result<Self, serde_json::Error> where R: std::io::Read {
serde_json::from_reader(reader)
}
}

View File

@ -17,16 +17,17 @@
//! Transaction test deserialization. //! Transaction test deserialization.
use std::collections::BTreeMap; use std::collections::BTreeMap;
use bytes::Bytes; use crate::{bytes::Bytes, hash::{Address, H256}, spec::ForkSpec};
use hash::Address; use serde::Deserialize;
use hash::H256;
use spec::ForkSpec; /// Type for running `Transaction` tests
pub type Test = super::tester::GenericTester<String, TransactionTest>;
/// Transaction test deserialization. /// Transaction test deserialization.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct TransactionTest { pub struct TransactionTest {
pub rlp: Bytes, pub rlp: Bytes,
pub _info: ::serde::de::IgnoredAny, pub _info: serde::de::IgnoredAny,
#[serde(flatten)] #[serde(flatten)]
pub post_state: BTreeMap<ForkSpec, PostState>, pub post_state: BTreeMap<ForkSpec, PostState>,
} }
@ -43,8 +44,7 @@ pub struct PostState {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::TransactionTest;
use transaction::TransactionTest;
#[test] #[test]
fn transaction_deserialization() { fn transaction_deserialization() {

View File

@ -19,7 +19,7 @@
use std::fmt; use std::fmt;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::str::FromStr; use std::str::FromStr;
use bytes::Bytes; use crate::bytes::Bytes;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde::de::{Error as ErrorTrait, Visitor, MapAccess, SeqAccess}; use serde::de::{Error as ErrorTrait, Visitor, MapAccess, SeqAccess};
@ -89,8 +89,8 @@ impl<'a> Visitor<'a> for InputVisitor {
return Err(V::Error::custom("Invalid key value pair.")); return Err(V::Error::custom("Invalid key value pair."));
} }
let ref key_str: Option<String> = keyval[0]; let key_str = &keyval[0];
let ref val_str: Option<String> = keyval[1]; let val_str = &keyval[1];
let key = match *key_str { 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) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?,
@ -117,10 +117,7 @@ impl<'a> Visitor<'a> for InputVisitor {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::BTreeMap; use super::{BTreeMap, Bytes, Input};
use serde_json;
use bytes::Bytes;
use super::Input;
#[test] #[test]
fn input_deserialization_from_map() { fn input_deserialization_from_map() {

View File

@ -16,8 +16,15 @@
//! Trie test deserialization. //! Trie test deserialization.
use hash::H256; mod input;
use trie::Input;
pub use self::input::Input;
/// Type used by `trie` tests
pub type Test = super::tester::GenericTester<String, Trie>;
use serde::Deserialize;
use crate::hash::H256;
/// Trie test deserialization. /// Trie test deserialization.
#[derive(Debug, Deserialize, PartialEq)] #[derive(Debug, Deserialize, PartialEq)]

View File

@ -14,14 +14,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Transaction test transaction deserialization. //! Transaction deserialization.
use uint::Uint; use crate::{bytes::Bytes, hash::{Address, H256}, maybe::MaybeEmpty, uint::Uint};
use bytes::Bytes; use serde::Deserialize;
use hash::Address;
use maybe::MaybeEmpty;
/// Transaction test transaction deserialization. /// Unsigned transaction with signing information deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Transaction { pub struct Transaction {
@ -43,12 +41,15 @@ pub struct Transaction {
pub s: Uint, pub s: Uint,
/// V. /// V.
pub v: Uint, pub v: Uint,
/// Secret
#[serde(rename = "secretKey")]
pub secret: Option<H256>,
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json; use super::{Bytes, H256, MaybeEmpty, Transaction, Uint};
use transaction::Transaction; use ethereum_types::{H256 as Eth256, U256};
#[test] #[test]
fn transaction_deserialization() { fn transaction_deserialization() {
@ -57,13 +58,23 @@ mod tests {
"gasLimit" : "0xf388", "gasLimit" : "0xf388",
"gasPrice" : "0x09184e72a000", "gasPrice" : "0x09184e72a000",
"nonce" : "0x00", "nonce" : "0x00",
"r" : "0x2c",
"s" : "0x04",
"to" : "", "to" : "",
"v" : "0x1b", "value" : "0x00",
"value" : "0x00" "r": 0,
"s": 1,
"v": 2,
"secretKey": "0x0000000000000000000000000000000000000000000000000000000000000000"
}"#; }"#;
let _deserialized: Transaction = serde_json::from_str(s).unwrap(); let tx: Transaction = serde_json::from_str(s).unwrap();
// TODO: validate all fields 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())));
} }
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
//! Transaction test deserialization.
mod transaction;
mod txtest;
mod test;
pub use self::transaction::Transaction;
pub use self::txtest::TransactionTest;
pub use self::test::Test;

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<String, TransactionTest>);
impl IntoIterator for Test {
type Item = <BTreeMap<String, TransactionTest> as IntoIterator>::Item;
type IntoIter = <BTreeMap<String, TransactionTest> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Test {
/// Loads test from json.
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
serde_json::from_reader(reader)
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! Trie test deserialization.
mod input;
mod trie;
mod test;
pub use self::input::Input;
pub use self::trie::Trie;
pub use self::test::Test;

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<String, Trie>);
impl IntoIterator for Test {
type Item = <BTreeMap<String, Trie> as IntoIterator>::Item;
type IntoIter = <BTreeMap<String, Trie> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Test {
/// Loads test from json.
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
serde_json::from_reader(reader)
}
}

View File

@ -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<Uint, D::Error> where D: Deserializer<'de> { pub fn validate_non_zero<'de, D>(d: D) -> Result<Uint, D::Error> where D: Deserializer<'de> {
let value = Uint::deserialize(d)?; let value = Uint::deserialize(d)?;
@ -102,6 +103,7 @@ pub fn validate_non_zero<'de, D>(d: D) -> Result<Uint, D::Error> where D: Deseri
Ok(value) Ok(value)
} }
/// Deserialize and validate that the value is non-zero
pub fn validate_optional_non_zero<'de, D>(d: D) -> Result<Option<Uint>, D::Error> where D: Deserializer<'de> { pub fn validate_optional_non_zero<'de, D>(d: D) -> Result<Option<Uint>, D::Error> where D: Deserializer<'de> {
let value: Option<Uint> = Option::deserialize(d)?; let value: Option<Uint> = Option::deserialize(d)?;
@ -116,9 +118,8 @@ pub fn validate_optional_non_zero<'de, D>(d: D) -> Result<Option<Uint>, D::Error
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use serde_json; use super::Uint;
use ethereum_types::U256; use ethereum_types::U256;
use uint::Uint;
#[test] #[test]
fn uint_deserialization() { fn uint_deserialization() {

272
json/src/vm.rs Normal file
View File

@ -0,0 +1,272 @@
// 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 <http://www.gnu.org/licenses/>.
//! 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<Vec<Call>>,
/// 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<Uint>,
/// Hash of logs created during execution of transaction.
pub logs: Option<H256>,
/// Transaction output.
#[serde(rename = "out")]
pub output: Option<Bytes>,
/// Post execution vm state.
#[serde(rename = "post")]
pub post_state: Option<State>,
/// 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<Address>,
/// 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::{
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() {
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",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055",
"nonce" : "0x00",
"storage" : {
"0x00" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055",
"nonce" : "0x00",
"storage" : {
}
}
}
}"#;
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]
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)));
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<Address>,
/// 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)));
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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;

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<String, Vm>);
impl IntoIterator for Test {
type Item = <BTreeMap<String, Vm> as IntoIterator>::Item;
type IntoIter = <BTreeMap<String, Vm> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Test {
/// Loads test from json.
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
serde_json::from_reader(reader)
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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<Vec<Call>>,
/// 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<Uint>,
/// Hash of logs created during execution of transaction.
pub logs: Option<H256>,
/// Transaction output.
#[serde(rename = "out")]
pub output: Option<Bytes>,
/// Post execution vm state.
#[serde(rename = "post")]
pub post_state: Option<State>,
/// 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
}
}

View File

@ -75,6 +75,7 @@ ethcore = { path = "../ethcore", features = ["test-helpers"] }
ethcore-accounts = { path = "../accounts" } ethcore-accounts = { path = "../accounts" }
ethcore-io = { path = "../util/io" } ethcore-io = { path = "../util/io" }
ethcore-network = { path = "../util/network" } ethcore-network = { path = "../util/network" }
ethjson = { path = "../json", features = ["test-helpers"] }
fake-fetch = { path = "../util/fake-fetch" } fake-fetch = { path = "../util/fake-fetch" }
macros = { path = "../util/macros" } macros = { path = "../util/macros" }
spec = { path = "../ethcore/spec" } spec = { path = "../ethcore/spec" }

View File

@ -15,8 +15,8 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! rpc integration tests. //! rpc integration tests.
use std::env;
use std::sync::Arc; use std::{env, sync::Arc};
use accounts::AccountProvider; use accounts::AccountProvider;
use client_traits::{BlockChainClient, ChainInfo, ImportBlock}; use client_traits::{BlockChainClient, ChainInfo, ImportBlock};
@ -26,7 +26,7 @@ use spec::{Genesis, Spec, self};
use ethcore::test_helpers; use ethcore::test_helpers;
use verification::VerifierType; use verification::VerifierType;
use ethereum_types::{Address, H256, U256}; use ethereum_types::{Address, H256, U256};
use ethjson::blockchain::BlockChain; use ethjson::test_helpers::blockchain::BlockChain;
use ethjson::spec::ForkSpec; use ethjson::spec::ForkSpec;
use io::IoChannel; use io::IoChannel;
use miner::external::ExternalMiner; use miner::external::ExternalMiner;
@ -85,7 +85,7 @@ struct EthTester {
impl EthTester { impl EthTester {
fn from_chain(chain: &BlockChain) -> Self { 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(); let mut config = ClientConfig::default();
config.verifier_type = VerifierType::CanonNoSeal; config.verifier_type = VerifierType::CanonNoSeal;
config.check_seal = false; config.check_seal = false;

View File

@ -32,7 +32,7 @@ macro_rules! extract_chain {
(iter $file:expr) => {{ (iter $file:expr) => {{
const RAW_DATA: &'static [u8] = const RAW_DATA: &'static [u8] =
include_bytes!(concat!("../../../../ethcore/res/ethereum/tests/", $file, ".json")); 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) => {{ ($file:expr) => {{