v2.6.4-beta (#11090)

* ethcore/res: activate Istanbul on Ropsten, Görli, Rinkeby, Kovan (#11068)

* ethcore/res: activate Istanbul on Ropsten block 6485846

* ethcore/res: activate Istanbul on Goerli block 1561651

* ethcore/res: use hex values for Istanbul specs

* ethcore/res: fix trailing comma

* ethcore/res: be pedantic about EIP-1283 in Petersburg and Istanbul test specs

* ethcore/res: activate Istanbul on Rinkeby block 5435345

* ethcore/res: activate Istanbul on Kovan block 14111141

* ethcore/res: fix kovan istanbul number to 0xd751a5

* 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`

* [json-spec] make blake2 pricing spec more readable (#11034)

* [json-spec] make blake2 pricing spec more readable

* [ethcore] fix compilation

* Update JSON tests to d4f86ecf4aa7c (#11054)

* new ethereum consensus tests, #10908

* Update JSON tests to 725dbc73a

This PR reverts the controversial changes of the previous PR and skips the failing tests.

Maybe I misunderstand the suggested workaround of putting the fix under `#[cfg(test)]` but it seems odd to run different code in production than we run in tests. Instead here I suggest we skip the failing tests with the argument that we do not wish to fix this issue (at least not at this time) because it does not affect us. If I am wrong, and I likely am, I look forward to hearing why and what a better approach to updating the state tests is.

Branched off https://github.com/paritytech/parity-ethereum/pull/10923

ref #10908

* Update json test commit to 1dc9d20e97165708f7db0bbf2d1a87a6b4285827

* Fail with error message

* Handle missing r, s, v params in json tests
Light cleanup of json test runner

* Include the path to the test file

* Handle new `postState` format: string or map
Sort out tests
Missing docs

* WIP

* Include test-helpers from ethjson

* Sort out new paths

* Remove dead code

* Fix warnings stemming from code called only from macros
Skip failing tests in stRevert/ and stTransactionTest/ (too course a filter!)
Docs and light touch refactorings for readability

* Skip all failing tests

* Document the single-test-skipping madness

* Update tests to latest commit on the `develop` branch

* Rename test skipping types to reflect actual purpose

* Switch to skipping individual tests in currents.json
Add some logging to help debug skipping

* Fix rpc test by curve fitting to new json test source file

* Add refs to all issues for fixing failing&skipped json tests

* Sort out the need for Clone for tests

* [json-tests] populate state from genesis pod state (#11083)

* [json-tests] populate state from genesis pod state

* [json-tests] #11075 is resolved as well

* [json-tests] #11076 hopefully too

* [json-tests] #11077 🎉

* [json-tests] fix trailing comma

* Update ethcore/src/json_tests/chain.rs

Co-Authored-By: Andronik Ordian <write@reusable.software>

* Add issue numbers to TODOs

* Apply @ordians fix for wrong state_root

* Warn on invalid RLP

* Remove the `ci-skip-tests` feature
This commit is contained in:
s3krit
2019-09-26 11:04:00 +02:00
committed by GitHub
parent b7b1484f2e
commit 7ae5d8ebdc
88 changed files with 1283 additions and 1482 deletions

View File

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

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

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

View File

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

View File

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

View File

@@ -18,9 +18,13 @@
use std::fmt;
use std::marker::PhantomData;
use ethereum_types::U256;
use serde::{Deserialize, Deserializer};
use serde::de::{Error, Visitor, IntoDeserializer};
use crate::uint::Uint;
/// Deserializer of empty string values into optionals.
#[derive(Debug, PartialEq, Clone)]
pub enum MaybeEmpty<T> {
@@ -32,7 +36,8 @@ pub enum MaybeEmpty<T> {
impl<'a, T> Deserialize<'a> for MaybeEmpty<T> where T: Deserialize<'a> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'a> {
where D: Deserializer<'a>
{
deserializer.deserialize_any(MaybeEmptyVisitor::new())
}
}
@@ -61,11 +66,10 @@ 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 {
match value.is_empty() {
true => Ok(MaybeEmpty::None),
false => {
T::deserialize(value.into_deserializer()).map(MaybeEmpty::Some)
}
if value.is_empty() {
Ok(MaybeEmpty::None)
} else {
T::deserialize(value.into_deserializer()).map(MaybeEmpty::Some)
}
}
}
@@ -79,13 +83,42 @@ impl<T> Into<Option<T>> for MaybeEmpty<T> {
}
}
#[cfg(test)]
impl From<Uint> for MaybeEmpty<Uint> {
fn from(uint: Uint) -> Self {
MaybeEmpty::Some(uint)
}
}
impl From<MaybeEmpty<Uint>> for U256 {
fn from(maybe: MaybeEmpty<Uint>) -> U256 {
match maybe {
MaybeEmpty::Some(v) => v.0,
MaybeEmpty::None => U256::zero(),
}
}
}
impl From<MaybeEmpty<Uint>> for u64 {
fn from(maybe: MaybeEmpty<Uint>) -> u64 {
match maybe {
MaybeEmpty::Some(v) => v.0.low_u64(),
MaybeEmpty::None => 0u64,
}
}
}
impl Default for MaybeEmpty<Uint> {
fn default() -> Self {
MaybeEmpty::Some(Uint::default())
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use serde_json;
use ethereum_types;
use hash::H256;
use maybe::MaybeEmpty;
use super::MaybeEmpty;
use crate::hash::H256;
#[test]
fn maybe_deserialization() {

View File

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

View File

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

View File

@@ -16,8 +16,9 @@
//! Authority params deserialization.
use uint::Uint;
use crate::uint::Uint;
use super::ValidatorSet;
use serde::Deserialize;
/// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
@@ -40,13 +41,10 @@ pub struct BasicAuthority {
#[cfg(test)]
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 super::{BasicAuthority, Uint};
use ethereum_types::{U256, H160};
use crate::{hash::Address, spec::validator_set::ValidatorSet};
#[test]
fn basic_authority_deserialization() {

View File

@@ -16,10 +16,9 @@
//! Spec builtin deserialization.
use uint::Uint;
use crate::uint::Uint;
use serde::Deserialize;
/// Price per round of Blake2 compression.
pub type Blake2F = u64;
/// Linear pricing.
#[derive(Debug, PartialEq, Deserialize, Clone)]
@@ -69,7 +68,10 @@ pub struct AltBn128Pairing {
#[serde(rename_all = "snake_case")]
pub enum Pricing {
/// Pricing for Blake2 compression function: each call costs the same amount per round.
Blake2F(Blake2F),
Blake2F {
/// Price per round of Blake2 compression function.
gas_per_round: u64,
},
/// Linear pricing.
Linear(Linear),
/// Pricing for modular exponentiation.
@@ -96,9 +98,7 @@ pub struct Builtin {
#[cfg(test)]
mod tests {
use serde_json;
use spec::builtin::{Builtin, Pricing, Linear, Modexp};
use uint::Uint;
use super::{Builtin, Modexp, Linear, Pricing, Uint};
#[test]
fn builtin_deserialization() {
@@ -117,11 +117,11 @@ mod tests {
let s = r#"{
"name": "blake2_f",
"activate_at": "0xffffff",
"pricing": { "blake2_f": 123 }
"pricing": { "blake2_f": { "gas_per_round": 123 } }
}"#;
let deserialized: Builtin = serde_json::from_str(s).unwrap();
assert_eq!(deserialized.name, "blake2_f");
assert_eq!(deserialized.pricing, Pricing::Blake2F(123));
assert_eq!(deserialized.pricing, Pricing::Blake2F { gas_per_round: 123 });
assert!(deserialized.activate_at.is_some());
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,7 +40,7 @@ pub use self::params::Params;
pub use self::spec::{Spec, ForkSpec};
pub use self::seal::{Seal, Ethereum, AuthorityRoundSeal, TendermintSeal};
pub use self::engine::Engine;
pub use self::state::State;
pub use self::state::{State, HashOrMap};
pub use self::ethash::{Ethash, EthashParams, BlockReward};
pub use self::validator_set::ValidatorSet;
pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams};

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,33 +14,60 @@
// 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.
//! Blockchain state deserializer.
use std::collections::BTreeMap;
use hash::Address;
use bytes::Bytes;
use spec::{Account, Builtin};
use crate::{
bytes::Bytes,
hash::{Address, H256},
spec::{Account, Builtin}
};
use serde::Deserialize;
/// Blockchain test state deserializer.
/// Recent JSON tests can be either a map or a hash (represented by a string).
/// See https://github.com/ethereum/tests/issues/637
#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))]
#[derive(Debug, PartialEq, Deserialize)]
#[serde(untagged)]
pub enum HashOrMap {
/// When the `postState` is large, tests sometimes just include the state root of the last
/// successful block here.
Hash(H256),
/// The expected `postState` of a test
Map(BTreeMap<Address, Account>),
}
/// Blockchain state deserializer.
#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))]
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct State(BTreeMap<Address, Account>);
pub struct State(pub HashOrMap);
impl State {
/// Returns all builtins.
pub fn builtins(&self) -> BTreeMap<Address, Builtin> {
self.0
.iter()
.filter_map(|(add, ref acc)| acc.builtin.clone().map(|b| (add.clone(), b)))
.collect()
match &self.0 {
HashOrMap::Hash(_) => BTreeMap::default(),
HashOrMap::Map(map) => {
map.iter().filter_map(|(add, ref acc)| {
acc.builtin.clone().map(|b| (add.clone(), b))
}).collect()
}
}
}
/// Returns all constructors.
pub fn constructors(&self) -> BTreeMap<Address, Bytes> {
self.0
.iter()
.filter_map(|(add, ref acc)| acc.constructor.clone().map(|b| (add.clone(), b)))
.collect()
match &self.0 {
HashOrMap::Hash(_) => BTreeMap::default(),
HashOrMap::Map(map) => {
map.iter().filter_map(|(add, ref acc)| {
acc.constructor.clone().map(|b| (add.clone(), b))
}).collect()
}
}
}
}
@@ -49,6 +76,10 @@ impl IntoIterator for State {
type IntoIter = <BTreeMap<Address, Account> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
if let HashOrMap::Map(m) = self.0 {
m.into_iter()
} else {
BTreeMap::default().into_iter()
}
}
}

View File

@@ -17,8 +17,8 @@
//! Validator set deserialization.
use std::collections::BTreeMap;
use uint::Uint;
use hash::Address;
use crate::{hash::Address, uint::Uint};
use serde::Deserialize;
/// Different ways of specifying validators.
#[derive(Debug, PartialEq, Deserialize)]
@@ -37,12 +37,9 @@ pub enum ValidatorSet {
#[cfg(test)]
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 super::{Address, Uint, ValidatorSet};
use ethereum_types::{H160, U256};
#[test]
fn validator_set_deserialization() {

View File

@@ -14,11 +14,15 @@
// 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 log deserialization.
use hash::{Address, H256, Bloom};
use bytes::Bytes;
//! State deserialization types
/// State test log deserialization.
use crate::{
bytes::Bytes,
hash::{Address, H256, Bloom},
};
use serde::Deserialize;
/// State log deserialization.
#[derive(Debug, PartialEq, Deserialize)]
pub struct Log {
/// Address.
@@ -33,8 +37,7 @@ pub struct Log {
#[cfg(test)]
mod tests {
use serde_json;
use state::Log;
use super::Log;
#[test]
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.
use bytes::Bytes;
use blockchain::header::Header;
use blockchain::transaction::Transaction;
use crate::{bytes::Bytes, transaction::Transaction};
use super::header::Header;
use serde::Deserialize;
/// Blockchain test block deserializer.
#[derive(Debug, PartialEq, Deserialize)]
@@ -40,8 +40,7 @@ impl Block {
#[cfg(test)]
mod tests {
use serde_json;
use blockchain::block::Block;
use super::Block;
#[test]
fn block_deserialization() {
@@ -66,7 +65,7 @@ mod tests {
},
"blocknumber" : "1",
"rlp" : "0xf901fcf901f7a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c5c83ff43741f573a0c9b31d0e56fdd745f4e37d193c4e78544f302777aafcf3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba808456850b7b80a013735ab4156c9b36327224d92e1692fab8fc362f8e0f868c94d421848ef7cd0688931dcc53e5edc514c0c0",
"transactions" : [],
"transaction" : [],
"uncleHeaders" : []
}"#;
let _deserialized: Block = serde_json::from_str(s).unwrap();

View File

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

View File

@@ -14,14 +14,24 @@
// 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 deserialization.
//! Blockchain test deserialization.
use bytes::Bytes;
use hash::H256;
use blockchain::state::State;
use blockchain::header::Header;
use blockchain::block::Block;
use spec::{ForkSpec, Genesis, Seal, Ethereum};
use crate::{
bytes::Bytes,
hash::H256,
spec::{Ethereum, ForkSpec, Genesis, Seal, State}
};
use serde::Deserialize;
pub mod block;
pub mod header;
pub use self::block::Block;
pub use self::header::Header;
/// Type for running `Blockchain` tests
pub type Test = super::tester::GenericTester<String, BlockChain>;
/// Json Block test possible engine kind.
#[derive(Debug, PartialEq, Deserialize)]
@@ -95,8 +105,7 @@ impl BlockChain {
#[cfg(test)]
mod tests {
use serde_json;
use blockchain::blockchain::BlockChain;
use super::BlockChain;
#[test]
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
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain test deserialization.
//! Test structures for JSON deserialization.
pub mod account;
pub mod block;
/// Blockchain test helpers
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;
/// Test primitives
pub mod tester;
/// Transaction test helpers
pub mod transaction;
pub mod test;
pub use self::account::Account;
pub use self::block::Block;
pub use self::blockchain::BlockChain;
pub use self::blockchain::Engine;
pub use self::header::Header;
pub use self::state::State;
pub use self::test::Test;
pub use self::transaction::Transaction;
/// Trie test helpers
pub mod trie;
/// Vm test helpers
pub mod vm {
/// Type for running `vm` tests
pub type Test = super::tester::GenericTester<String, crate::vm::Vm>;
}

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 SkipTests {
/// Block tests
pub block: Vec<SkipBlockchainTest>,
/// State tests
pub state: Vec<SkipStateTest>,
}
/// Block test to skip.
#[derive(Debug, PartialEq, Deserialize)]
pub struct SkipBlockchainTest {
/// 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 SkipStateTest {
/// 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 SkipTests {
/// Empty skip states.
pub fn empty() -> Self {
SkipTests {
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
// 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 uint::Uint;
use bytes::Bytes;
use hash::{Address, H256};
use spec::ForkSpec;
use state::{Env, AccountState, Transaction};
use maybe::MaybeEmpty;
use serde_json::{self, Error};
/// State test deserializer.
#[derive(Debug, PartialEq, Deserialize)]
pub struct Test(BTreeMap<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)
}
}
use serde::Deserialize;
use crate::{
bytes::Bytes,
hash::{Address, H256},
maybe::MaybeEmpty,
uint::Uint,
spec::{ForkSpec, State as AccountState},
transaction::Transaction,
vm::Env
};
/// State test deserialization.
#[derive(Debug, PartialEq, Deserialize)]
@@ -87,12 +72,15 @@ impl MultiTransaction {
pub fn select(&self, indexes: &PostStateIndexes) -> Transaction {
Transaction {
data: self.data[indexes.data as usize].clone(),
gas_limit: self.gas_limit[indexes.gas as usize].clone(),
gas_price: self.gas_price.clone(),
nonce: self.nonce.clone(),
secret: self.secret.clone(),
gas_limit: self.gas_limit[indexes.gas as usize],
gas_price: self.gas_price,
nonce: self.nonce,
to: self.to.clone(),
value: self.value[indexes.value as usize].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,20 @@
//! Transaction test deserialization.
use std::collections::BTreeMap;
use bytes::Bytes;
use hash::Address;
use hash::H256;
use spec::ForkSpec;
use crate::{bytes::Bytes, hash::{Address, H256}, spec::ForkSpec};
use serde::Deserialize;
/// Type for running `Transaction` tests
pub type Test = super::tester::GenericTester<String, TransactionTest>;
/// Transaction test deserialization.
#[derive(Debug, Deserialize)]
pub struct TransactionTest {
/// RLP of the transaction
pub rlp: Bytes,
pub _info: ::serde::de::IgnoredAny,
#[allow(missing_docs)]
pub _info: serde::de::IgnoredAny,
/// State of the transaction after the test runs
#[serde(flatten)]
pub post_state: BTreeMap<ForkSpec, PostState>,
}
@@ -43,8 +47,7 @@ pub struct PostState {
#[cfg(test)]
mod tests {
use serde_json;
use transaction::TransactionTest;
use super::TransactionTest;
#[test]
fn transaction_deserialization() {

View File

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

View File

@@ -16,8 +16,15 @@
//! Trie test deserialization.
use hash::H256;
use trie::Input;
mod 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.
#[derive(Debug, Deserialize, PartialEq)]

View File

@@ -14,14 +14,12 @@
// 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 transaction deserialization.
//! Transaction deserialization.
use uint::Uint;
use bytes::Bytes;
use hash::Address;
use maybe::MaybeEmpty;
use crate::{bytes::Bytes, hash::{Address, H256}, maybe::MaybeEmpty, uint::Uint};
use serde::Deserialize;
/// Transaction test transaction deserialization.
/// Unsigned transaction with signing information deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Transaction {
@@ -38,17 +36,23 @@ pub struct Transaction {
/// Value.
pub value: Uint,
/// R.
pub r: Uint,
#[serde(default)]
pub r: MaybeEmpty<Uint>,
/// S.
pub s: Uint,
#[serde(default)]
pub s: MaybeEmpty<Uint>,
/// V.
pub v: Uint,
#[serde(default)]
pub v: MaybeEmpty<Uint>,
/// Secret
#[serde(rename = "secretKey")]
pub secret: Option<H256>,
}
#[cfg(test)]
mod tests {
use serde_json;
use transaction::Transaction;
use super::{Bytes, H256, MaybeEmpty, Transaction, Uint};
use ethereum_types::{H256 as Eth256, U256};
#[test]
fn transaction_deserialization() {
@@ -57,13 +61,23 @@ mod tests {
"gasLimit" : "0xf388",
"gasPrice" : "0x09184e72a000",
"nonce" : "0x00",
"r" : "0x2c",
"s" : "0x04",
"to" : "",
"v" : "0x1b",
"value" : "0x00"
"value" : "0x00",
"r": "0",
"s": "1",
"v": "2",
"secretKey": "0x0000000000000000000000000000000000000000000000000000000000000000"
}"#;
let _deserialized: Transaction = serde_json::from_str(s).unwrap();
// TODO: validate all fields
let tx: Transaction = serde_json::from_str(s).expect("JSON string is valid");
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()).into());
assert_eq!(tx.s, Uint(U256::one()).into());
assert_eq!(tx.v, Uint(U256::from(2)).into());
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> {
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)
}
/// 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> {
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)]
mod test {
use serde_json;
use super::Uint;
use ethereum_types::U256;
use uint::Uint;
#[test]
fn uint_deserialization() {

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

@@ -0,0 +1,275 @@
// 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, HashOrMap};
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).expect("JSON is valid");
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(
HashOrMap::Map(
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![]),
}
]))
);
assert_eq!(vm.post_state, Some(
State(
HashOrMap::Map(
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())
]),
}]))
)
);
}
#[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,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
}
}