Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
badb04502f | ||
|
|
a44fad04fa | ||
|
|
7ae5d8ebdc |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,4 +1,15 @@
|
||||
## Parity-Ethereum [v2.6.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.3)
|
||||
## Parity-Ethereum [v2.6.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.3)
|
||||
|
||||
Parity Ethereum v2.6.4-stable is a patch release that adds the block numbers for activating the Istanbul hardfork on test networks: Ropsten, Görli, Rinkeby and Kovan.
|
||||
|
||||
A full list of included changes:
|
||||
|
||||
* ethcore/res: activate Istanbul on Ropsten, Görli, Rinkeby, Kovan (#11068)
|
||||
* cleanup json crate (#11027)
|
||||
* [json-spec] make blake2 pricing spec more readable (#11034)
|
||||
* Update JSON tests to d4f86ecf4aa7c (#11054)
|
||||
|
||||
## Parity-Ethereum [v2.6.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.3)
|
||||
|
||||
Parity Ethereum v2.6.3-stable is a patch release that improves security, stability and performance.
|
||||
|
||||
|
||||
14
Cargo.lock
generated
14
Cargo.lock
generated
@@ -1317,9 +1317,9 @@ name = "ethjson"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.89 (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.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -2613,7 +2613,7 @@ dependencies = [
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic_hook 0.1.0",
|
||||
"parity-ethereum 2.6.3",
|
||||
"parity-ethereum 2.6.4",
|
||||
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2660,7 +2660,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-ethereum"
|
||||
version = "2.6.3"
|
||||
version = "2.6.4"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2713,7 +2713,7 @@ dependencies = [
|
||||
"parity-runtime 0.1.0",
|
||||
"parity-updater 1.12.0",
|
||||
"parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-version 2.6.3",
|
||||
"parity-version 2.6.4",
|
||||
"parity-whisper 0.1.0",
|
||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2856,7 +2856,7 @@ dependencies = [
|
||||
"parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-runtime 0.1.0",
|
||||
"parity-updater 1.12.0",
|
||||
"parity-version 2.6.3",
|
||||
"parity-version 2.6.4",
|
||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2955,7 +2955,7 @@ dependencies = [
|
||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.12.0",
|
||||
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-version 2.6.3",
|
||||
"parity-version 2.6.4",
|
||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2980,7 +2980,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-version"
|
||||
version = "2.6.3"
|
||||
version = "2.6.4"
|
||||
dependencies = [
|
||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity-ethereum"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "2.6.3"
|
||||
version = "2.6.4"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
@@ -92,7 +92,6 @@ default = ["accounts"]
|
||||
accounts = ["ethcore-accounts", "parity-rpc/accounts"]
|
||||
miner-debug = ["ethcore/miner-debug"]
|
||||
json-tests = ["ethcore/json-tests"]
|
||||
ci-skip-tests = ["ethcore/ci-skip-tests"]
|
||||
test-heavy = ["ethcore/test-heavy"]
|
||||
evm-debug = ["ethcore/evm-debug"]
|
||||
evm-debug-tests = ["ethcore/evm-debug-tests"]
|
||||
|
||||
@@ -78,6 +78,8 @@ blooms-db = { path = "../util/blooms-db" }
|
||||
criterion = "0.2"
|
||||
env_logger = "0.5"
|
||||
ethcore-accounts = { path = "../accounts" }
|
||||
ethjson = { path = "../json", features = ["test-helpers"] }
|
||||
ethkey = { path = "../accounts/ethkey" }
|
||||
fetch = { path = "../util/fetch" }
|
||||
kvdb-rocksdb = "0.1.3"
|
||||
parity-runtime = { path = "../util/runtime" }
|
||||
@@ -109,8 +111,6 @@ evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
|
||||
slow-blocks = []
|
||||
# Run JSON consensus tests.
|
||||
json-tests = ["env_logger", "test-helpers", "to-pod-full"]
|
||||
# Skip JSON consensus tests with pending issues.
|
||||
ci-skip-tests = []
|
||||
# Run memory/cpu heavy tests.
|
||||
test-heavy = []
|
||||
# Compile test helpers
|
||||
|
||||
@@ -218,8 +218,8 @@ impl Builtin {
|
||||
impl From<ethjson::spec::Builtin> for Builtin {
|
||||
fn from(b: ethjson::spec::Builtin) -> Self {
|
||||
let pricer: Box<dyn Pricer> = match b.pricing {
|
||||
ethjson::spec::Pricing::Blake2F(cost_per_round) => {
|
||||
Box::new(cost_per_round)
|
||||
ethjson::spec::Pricing::Blake2F { gas_per_round } => {
|
||||
Box::new(gas_per_round)
|
||||
},
|
||||
ethjson::spec::Pricing::Linear(linear) => {
|
||||
Box::new(Linear {
|
||||
|
||||
@@ -82,21 +82,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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::Account> for PodAccount {
|
||||
fn from(a: ethjson::spec::Account) -> Self {
|
||||
PodAccount {
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
"eip1052Transition": "0x0",
|
||||
"eip1283Transition": "0x0",
|
||||
"eip1283DisableTransition": "0x0",
|
||||
"eip1283ReenableTransition": "0x17d433",
|
||||
"eip1344Transition": "0x17d433",
|
||||
"eip1706Transition": "0x17d433",
|
||||
"eip1884Transition": "0x17d433",
|
||||
"eip2028Transition": "0x17d433",
|
||||
"gasLimitBoundDivisor": "0x400",
|
||||
"maxCodeSize": "0x6000",
|
||||
"maxCodeSizeTransition": "0x0",
|
||||
@@ -126,7 +131,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_add",
|
||||
"activate_at": "0x00",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x17d433",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 500,
|
||||
@@ -140,7 +145,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_mul",
|
||||
"activate_at": "0x00",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x17d433",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 40000,
|
||||
@@ -154,7 +159,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_pairing",
|
||||
"activate_at": "0x00",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x17d433",
|
||||
"pricing": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 100000,
|
||||
@@ -166,7 +171,16 @@
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000009": {
|
||||
"balance": "0x1"
|
||||
"balance": "0x1",
|
||||
"builtin": {
|
||||
"name": "blake2_f",
|
||||
"activate_at": "0x17d433",
|
||||
"pricing": {
|
||||
"blake2_f": {
|
||||
"gas_per_round": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x000000000000000000000000000000000000000a": {
|
||||
"balance": "0x1"
|
||||
|
||||
120
ethcore/res/ethereum/istanbul_test.json
Normal file
120
ethcore/res/ethereum/istanbul_test.json
Normal file
@@ -0,0 +1,120 @@
|
||||
{
|
||||
"name": "Istanbul (test)",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x1BC16D674EC80000",
|
||||
"homesteadTransition": "0x0",
|
||||
"eip100bTransition": "0x0",
|
||||
"difficultyBombDelays": {
|
||||
"0": 5000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"accountStartNonce": "0x00",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x1",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0x0",
|
||||
"eip150Transition": "0x0",
|
||||
"eip160Transition": "0x0",
|
||||
"eip161abcTransition": "0x0",
|
||||
"eip161dTransition": "0x0",
|
||||
"eip140Transition": "0x0",
|
||||
"eip211Transition": "0x0",
|
||||
"eip214Transition": "0x0",
|
||||
"eip155Transition": "0x0",
|
||||
"eip658Transition": "0x0",
|
||||
"eip145Transition": "0x0",
|
||||
"eip1014Transition": "0x0",
|
||||
"eip1052Transition": "0x0",
|
||||
"eip1283Transition": "0x0",
|
||||
"eip1283DisableTransition": "0x0",
|
||||
"eip1283ReenableTransition": "0x0",
|
||||
"eip1344Transition": "0x0",
|
||||
"eip1706Transition": "0x0",
|
||||
"eip1884Transition": "0x0",
|
||||
"eip2028Transition": "0x0"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x400000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
|
||||
"gasLimit": "0x1388"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
"0000000000000000000000000000000000000006": {
|
||||
"builtin": {
|
||||
"name": "alt_bn128_add",
|
||||
"activate_at": "0x00",
|
||||
"eip1108_transition": "0x0",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 500,
|
||||
"eip1108_transition_price": 150
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000007": {
|
||||
"builtin": {
|
||||
"name": "alt_bn128_mul",
|
||||
"activate_at": "0x00",
|
||||
"eip1108_transition": "0x0",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 40000,
|
||||
"eip1108_transition_price": 6000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000008": {
|
||||
"builtin": {
|
||||
"name": "alt_bn128_pairing",
|
||||
"activate_at": "0x00",
|
||||
"eip1108_transition": "0x0",
|
||||
"pricing": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 100000,
|
||||
"pair": 80000,
|
||||
"eip1108_transition_base": 45000,
|
||||
"eip1108_transition_pair": 34000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000009": {
|
||||
"builtin": {
|
||||
"name": "blake2_f",
|
||||
"activate_at": "0x00",
|
||||
"pricing": {
|
||||
"blake2_f": {
|
||||
"gas_per_round": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,11 @@
|
||||
"eip1052Transition": "0x8c6180",
|
||||
"eip1283Transition": "0x8c6180",
|
||||
"eip1283DisableTransition": "0x9c7b61",
|
||||
"eip1283ReenableTransition": "0xd751a5",
|
||||
"eip1344Transition": "0xd751a5",
|
||||
"eip1706Transition": "0xd751a5",
|
||||
"eip1884Transition": "0xd751a5",
|
||||
"eip2028Transition": "0xd751a5",
|
||||
"kip4Transition": "0x8c6180",
|
||||
"kip6Transition": "0x8c6180"
|
||||
},
|
||||
@@ -5344,7 +5349,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_add",
|
||||
"activate_at": "0x4d50f8",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0xd751a5",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 500,
|
||||
@@ -5357,7 +5362,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_mul",
|
||||
"activate_at": "0x4d50f8",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0xd751a5",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 40000,
|
||||
@@ -5370,7 +5375,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_pairing",
|
||||
"activate_at": "0x4d50f8",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0xd751a5",
|
||||
"pricing": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 100000,
|
||||
@@ -5381,6 +5386,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000009": {
|
||||
"builtin": {
|
||||
"name": "blake2_f",
|
||||
"activate_at": "0xd751a5",
|
||||
"pricing": {
|
||||
"blake2_f": {
|
||||
"gas_per_round": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x00521965e7bd230323c423d96c657db5b79d099f": {
|
||||
"balance": "1606938044258990275541962092341162602522202993782792835301376"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
"eip1052Transition": "0x37db77",
|
||||
"eip1283Transition": "0x37db77",
|
||||
"eip1283DisableTransition": "0x41efd2",
|
||||
"eip1283ReenableTransition": "0x52efd1",
|
||||
"eip1344Transition": "0x52efd1",
|
||||
"eip1706Transition": "0x52efd1",
|
||||
"eip1884Transition": "0x52efd1",
|
||||
"eip2028Transition": "0x52efd1",
|
||||
"gasLimitBoundDivisor": "0x400",
|
||||
"maxCodeSize": "0x6000",
|
||||
"maxCodeSizeTransition": "0x0",
|
||||
@@ -120,7 +125,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_add",
|
||||
"activate_at": "0xfcc25",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x52efd1",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 500,
|
||||
@@ -133,7 +138,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_mul",
|
||||
"activate_at": "0xfcc25",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x52efd1",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 40000,
|
||||
@@ -146,7 +151,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_pairing",
|
||||
"activate_at": "0xfcc25",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x52efd1",
|
||||
"pricing": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 100000,
|
||||
@@ -158,7 +163,16 @@
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000009": {
|
||||
"balance": "0x1"
|
||||
"balance": "0x1",
|
||||
"builtin": {
|
||||
"name": "blake2_f",
|
||||
"activate_at": "0x52efd1",
|
||||
"pricing": {
|
||||
"blake2_f": {
|
||||
"gas_per_round": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x000000000000000000000000000000000000000a": {
|
||||
"balance": "0x1"
|
||||
|
||||
@@ -45,7 +45,12 @@
|
||||
"eip1014Transition": "0x408b70",
|
||||
"eip1052Transition": "0x408b70",
|
||||
"eip1283Transition": "0x408b70",
|
||||
"eip1283DisableTransition": "0x4b5e82"
|
||||
"eip1283DisableTransition": "0x4b5e82",
|
||||
"eip1283ReenableTransition": "0x62f756",
|
||||
"eip1344Transition": "0x62f756",
|
||||
"eip1706Transition": "0x62f756",
|
||||
"eip1884Transition": "0x62f756",
|
||||
"eip2028Transition": "0x62f756"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@@ -2735,7 +2740,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_add",
|
||||
"activate_at": "0x19f0a0",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x62f756",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 500,
|
||||
@@ -2750,7 +2755,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_mul",
|
||||
"activate_at": "0x19f0a0",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x62f756",
|
||||
"pricing": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 40000,
|
||||
@@ -2765,7 +2770,7 @@
|
||||
"builtin": {
|
||||
"name": "alt_bn128_pairing",
|
||||
"activate_at": "0x19f0a0",
|
||||
"eip1108_transition": "0x7fffffffffffff",
|
||||
"eip1108_transition": "0x62f756",
|
||||
"pricing": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 100000,
|
||||
@@ -2777,7 +2782,16 @@
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000009": {
|
||||
"balance": "0x1"
|
||||
"balance": "0x1",
|
||||
"builtin": {
|
||||
"name": "blake2_f",
|
||||
"activate_at": "0x62f756",
|
||||
"pricing": {
|
||||
"blake2_f": {
|
||||
"gas_per_round": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x000000000000000000000000000000000000000a": {
|
||||
"balance": "0x0"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"eip145Transition": "0x0",
|
||||
"eip1014Transition": "0x0",
|
||||
"eip1052Transition": "0x0",
|
||||
"eip1283Transition": "0x0",
|
||||
"eip1283DisableTransition": "0x0"
|
||||
},
|
||||
"genesis": {
|
||||
|
||||
Submodule ethcore/res/ethereum/tests updated: 725dbc73a5...d4f86ecf4a
@@ -1,4 +1,57 @@
|
||||
{
|
||||
"block": [],
|
||||
"state": []
|
||||
"block": [
|
||||
{
|
||||
"reference": "Issue https://github.com/paritytech/parity-ethereum/issues/11073 (also see https://github.com/paritytech/parity-ethereum/pull/10923)",
|
||||
"failing": "stRevertTest",
|
||||
"subtests": [
|
||||
"RevertPrecompiledTouch_d0g0v0_Byzantium",
|
||||
"RevertPrecompiledTouch_d0g0v0_Constantinople",
|
||||
"RevertPrecompiledTouch_d0g0v0_ConstantinopleFix",
|
||||
"RevertPrecompiledTouch_d0g0v0_EIP158",
|
||||
"RevertPrecompiledTouch_d3g0v0_ConstantinopleFix",
|
||||
"RevertPrecompiledTouchCC_d0g0v0_Byzantium",
|
||||
"RevertPrecompiledTouchCC_d0g0v0_Constantinople",
|
||||
"RevertPrecompiledTouchCC_d0g0v0_EIP158",
|
||||
"RevertPrecompiledTouchDC_d0g0v0_Byzantium",
|
||||
"RevertPrecompiledTouchDC_d0g0v0_Constantinople",
|
||||
"RevertPrecompiledTouchDC_d0g0v0_EIP158",
|
||||
"RevertPrecompiledTouchExactOOG_d7g1v0_ConstantinopleFix",
|
||||
"RevertPrecompiledTouchExactOOG_d31g1v0_ConstantinopleFix",
|
||||
"RevertPrecompiledTouch_storage_d3g0v0_ConstantinopleFix",
|
||||
"RevertPrecompiledTouch_storage_d0g0v0_ConstantinopleFix"
|
||||
]
|
||||
}
|
||||
],
|
||||
"state": [
|
||||
{
|
||||
"reference": "Issue https://github.com/paritytech/parity-ethereum/issues/11078 (also see https://github.com/paritytech/parity-ethereum/pull/10923)",
|
||||
"failing": "stRevertTest",
|
||||
"subtests": {
|
||||
"RevertPrecompiledTouch_storage": {
|
||||
"subnumbers": ["1", "2"],
|
||||
"chain": "St. Peter's (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "Issue https://github.com/paritytech/parity-ethereum/issues/11079 (also see https://github.com/paritytech/parity-ethereum/pull/10923)",
|
||||
"failing": "stRevertTest",
|
||||
"subtests": {
|
||||
"RevertPrecompiledTouchExactOOG": {
|
||||
"subnumbers": ["61", "64"],
|
||||
"chain": "St. Peter's (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "Issue https://github.com/paritytech/parity-ethereum/issues/11080 (also see https://github.com/paritytech/parity-ethereum/pull/10923)",
|
||||
"failing": "stRevertTest",
|
||||
"subtests": {
|
||||
"RevertPrecompiledTouch": {
|
||||
"subnumbers": ["1", "2"],
|
||||
"chain": "St. Peter's (test)"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()),
|
||||
ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()),
|
||||
ForkSpec::ConstantinopleFix => Some(ethereum::new_constantinople_fix_test()),
|
||||
ForkSpec::Istanbul => Some(ethereum::new_istanbul_test()),
|
||||
ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()),
|
||||
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
|
||||
}
|
||||
|
||||
@@ -166,6 +166,9 @@ pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/
|
||||
/// Create a new Foundation St. Peter's (Contantinople Fix) era spec.
|
||||
pub fn new_constantinople_fix_test() -> Spec { load(None, include_bytes!("../../res/ethereum/st_peters_test.json")) }
|
||||
|
||||
/// Create a new Foundation Istanbul era spec.
|
||||
pub fn new_istanbul_test() -> Spec { load(None, include_bytes!("../../res/ethereum/istanbul_test.json")) }
|
||||
|
||||
/// Create a new Musicoin-MCIP3-era spec.
|
||||
pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../../res/ethereum/mcip3_test.json")) }
|
||||
|
||||
|
||||
@@ -18,49 +18,49 @@ use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use client::{EvmTestClient, Client, ClientConfig, ChainInfo, ImportBlock};
|
||||
use spec::Genesis;
|
||||
use ethjson;
|
||||
use ethjson::test_helpers::blockchain;
|
||||
use miner::Miner;
|
||||
use io::IoChannel;
|
||||
use test_helpers;
|
||||
use verification::queue::kind::blocks::Unverified;
|
||||
use verification::VerifierType;
|
||||
use super::SKIP_TEST_STATE;
|
||||
use verification::{VerifierType, queue::kind::BlockLike, queue::kind::blocks::Unverified};
|
||||
use super::SKIP_TESTS;
|
||||
use super::HookType;
|
||||
|
||||
/// Run chain jsontests on a given folder.
|
||||
pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) {
|
||||
::json_tests::test_common::run_test_path(p, skip, json_chain_test, h)
|
||||
}
|
||||
|
||||
/// Run chain jsontests on a given file.
|
||||
pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
|
||||
::json_tests::test_common::run_test_file(p, json_chain_test, h)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn skip_test(name: &String) -> bool {
|
||||
SKIP_TEST_STATE.block.iter().any(|block_test|block_test.subtests.contains(name))
|
||||
SKIP_TESTS
|
||||
.block
|
||||
.iter()
|
||||
.any(|block_test|block_test.subtests.contains(name))
|
||||
}
|
||||
|
||||
pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
|
||||
#[allow(dead_code)]
|
||||
pub fn json_chain_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
|
||||
let _ = ::env_logger::try_init();
|
||||
let tests = ethjson::blockchain::Test::load(json_data).unwrap();
|
||||
let tests = blockchain::Test::load(json_data)
|
||||
.expect(&format!("Could not parse JSON chain test data from {}", path.display()));
|
||||
let mut failed = Vec::new();
|
||||
|
||||
for (name, blockchain) in tests.into_iter() {
|
||||
if skip_test(&name) {
|
||||
println!(" - {} | {:?} Ignoring tests because in skip list", name, blockchain.network);
|
||||
println!(" - {} | {:?}: SKIPPED", name, blockchain.network);
|
||||
continue;
|
||||
}
|
||||
|
||||
start_stop_hook(&name, HookType::OnStart);
|
||||
|
||||
let mut fail = false;
|
||||
{
|
||||
let mut fail_unless = |cond: bool| if !cond && !fail {
|
||||
failed.push(name.clone());
|
||||
flushln!("FAIL");
|
||||
fail = true;
|
||||
true
|
||||
} else {false};
|
||||
let mut fail_unless = |cond: bool| {
|
||||
if !cond && !fail {
|
||||
failed.push(name.clone());
|
||||
flushln!("FAIL");
|
||||
fail = true;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
flush!(" - {}...", name);
|
||||
|
||||
@@ -68,7 +68,7 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
|
||||
let mut spec = match EvmTestClient::spec_from_json(&blockchain.network) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
println!(" - {} | {:?} Ignoring tests because of missing spec", name, blockchain.network);
|
||||
println!(" - {} | {:?} Ignoring tests because of missing chainspec", name, blockchain.network);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
@@ -77,30 +77,44 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
|
||||
let state = From::from(blockchain.pre_state.clone());
|
||||
spec.set_genesis_state(state).expect("Failed to overwrite genesis state");
|
||||
spec.overwrite_genesis_params(genesis);
|
||||
assert!(spec.is_state_root_valid());
|
||||
// assert!(spec.is_state_root_valid());
|
||||
spec
|
||||
};
|
||||
|
||||
{
|
||||
let db = test_helpers::new_db();
|
||||
let mut config = ClientConfig::default();
|
||||
if ethjson::blockchain::Engine::NoProof == blockchain.engine {
|
||||
if ethjson::test_helpers::blockchain::Engine::NoProof == blockchain.engine {
|
||||
config.verifier_type = VerifierType::CanonNoSeal;
|
||||
config.check_seal = false;
|
||||
}
|
||||
config.history = 8;
|
||||
config.queue.verifier_settings.num_verifiers = 1;
|
||||
let client = Client::new(
|
||||
config,
|
||||
&spec,
|
||||
db,
|
||||
Arc::new(Miner::new_for_tests(&spec, None)),
|
||||
IoChannel::disconnected(),
|
||||
).unwrap();
|
||||
).expect("Failed to instantiate a new Client");
|
||||
|
||||
for b in blockchain.blocks_rlp() {
|
||||
if let Ok(block) = Unverified::from_rlp(b) {
|
||||
let _ = client.import_block(block);
|
||||
client.flush_queue();
|
||||
client.import_verified_blocks();
|
||||
let bytes_len = b.len();
|
||||
let block = Unverified::from_rlp(b);
|
||||
match block {
|
||||
Ok(block) => {
|
||||
let num = block.header.number();
|
||||
let hash = block.hash();
|
||||
trace!(target: "json-tests", "{} – Importing {} bytes. Block #{}/{}", name, bytes_len, num, hash);
|
||||
let res = client.import_block(block);
|
||||
if let Err(e) = res {
|
||||
warn!(target: "json-tests", "{} – Error importing block #{}/{}: {:?}", name, num, hash, e);
|
||||
}
|
||||
client.flush_queue();
|
||||
},
|
||||
Err(decoder_err) => {
|
||||
warn!(target: "json-tests", "Error decoding test block: {:?} ({} bytes)", decoder_err, bytes_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
fail_unless(client.chain_info().best_block_hash == blockchain.best_block.into());
|
||||
@@ -109,24 +123,31 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
|
||||
|
||||
if !fail {
|
||||
flushln!("ok");
|
||||
} else {
|
||||
flushln!("fail");
|
||||
}
|
||||
|
||||
start_stop_hook(&name, HookType::OnStop);
|
||||
}
|
||||
|
||||
println!("!!! {:?} tests from failed.", failed.len());
|
||||
if failed.len() > 0 {
|
||||
println!("!!! {:?} tests failed.", failed.len());
|
||||
}
|
||||
failed
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod block_tests {
|
||||
use std::path::Path;
|
||||
|
||||
use super::json_chain_test;
|
||||
use json_tests::HookType;
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
json_chain_test(json_data, h)
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
json_chain_test(path, json_data, h)
|
||||
}
|
||||
|
||||
//todo[dvdplm] do these tests match all folders in `res/` or are there tests we're missing?
|
||||
//Issue: https://github.com/paritytech/parity-ethereum/issues/11085
|
||||
declare_test!{BlockchainTests_bcBlockGasLimitTest, "BlockchainTests/bcBlockGasLimitTest"}
|
||||
declare_test!{BlockchainTests_bcExploitTest, "BlockchainTests/bcExploitTest"}
|
||||
declare_test!{BlockchainTests_bcForgedTest, "BlockchainTests/bcForgedTest"}
|
||||
@@ -173,7 +194,12 @@ mod block_tests {
|
||||
declare_test!{BlockchainTests_GeneralStateTest_stRandom2, "BlockchainTests/GeneralStateTests/stRandom2/"}
|
||||
declare_test!{BlockchainTests_GeneralStateTest_stRecursiveCreate, "BlockchainTests/GeneralStateTests/stRecursiveCreate/"}
|
||||
declare_test!{BlockchainTests_GeneralStateTest_stRefundTest, "BlockchainTests/GeneralStateTests/stRefundTest/"}
|
||||
declare_test!{BlockchainTests_GeneralStateTest_stReturnDataTest, "BlockchainTests/GeneralStateTests/stReturnDataTest/"}
|
||||
declare_test!{ BlockchainTests_GeneralStateTest_stReturnDataTest, "BlockchainTests/GeneralStateTests/stReturnDataTest/"}
|
||||
// todo[dvdplm]:
|
||||
// "RevertPrecompiledTouch_storage" contains 4 tests, only two fails
|
||||
// "RevertPrecompiledTouchExactOOG" contains a ton of tests, only two fails
|
||||
// "RevertPrecompiledTouch" has 4 tests, 2 failures
|
||||
// Ignored in currents.json, issue: https://github.com/paritytech/parity-ethereum/issues/11073
|
||||
declare_test!{BlockchainTests_GeneralStateTest_stRevertTest, "BlockchainTests/GeneralStateTests/stRevertTest/"}
|
||||
declare_test!{BlockchainTests_GeneralStateTest_stShift, "BlockchainTests/GeneralStateTests/stShift/"}
|
||||
declare_test!{BlockchainTests_GeneralStateTest_stSolidityTest, "BlockchainTests/GeneralStateTests/stSolidityTest/"}
|
||||
|
||||
@@ -14,16 +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/>.
|
||||
|
||||
use ethjson;
|
||||
use types::header::Header;
|
||||
use std::path::Path;
|
||||
|
||||
use ethereum_types::U256;
|
||||
use ethjson::test_helpers::difficulty::DifficultyTest;
|
||||
use types::header::Header;
|
||||
use spec::Spec;
|
||||
|
||||
use super::HookType;
|
||||
|
||||
pub fn json_difficulty_test<H: FnMut(&str, HookType)>(json_data: &[u8], spec: Spec, start_stop_hook: &mut H) -> Vec<String> {
|
||||
let _ = ::env_logger::try_init();
|
||||
let tests = ethjson::test::DifficultyTest::load(json_data).unwrap();
|
||||
pub fn json_difficulty_test<H: FnMut(&str, HookType)>(
|
||||
path: &Path,
|
||||
json_data: &[u8],
|
||||
spec: Spec,
|
||||
start_stop_hook: &mut H
|
||||
) -> Vec<String> {
|
||||
let _ = env_logger::try_init();
|
||||
let tests = DifficultyTest::load(json_data)
|
||||
.expect(&format!("Could not parse JSON difficulty test data from {}", path.display()));
|
||||
let engine = &spec.engine;
|
||||
|
||||
for (name, test) in tests.into_iter() {
|
||||
@@ -54,29 +62,28 @@ pub fn json_difficulty_test<H: FnMut(&str, HookType)>(json_data: &[u8], spec: Sp
|
||||
|
||||
macro_rules! difficulty_json_test {
|
||||
( $spec:ident ) => {
|
||||
use std::path::Path;
|
||||
use super::json_difficulty_test;
|
||||
use tempdir::TempDir;
|
||||
use json_tests::HookType;
|
||||
|
||||
use super::json_difficulty_test;
|
||||
use tempdir::TempDir;
|
||||
use json_tests::HookType;
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
let tempdir = TempDir::new("").unwrap();
|
||||
json_difficulty_test(json_data, ::ethereum::$spec(&tempdir.path()), h)
|
||||
}
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
let tempdir = TempDir::new("").unwrap();
|
||||
json_difficulty_test(path, json_data, ::ethereum::$spec(&tempdir.path()), h)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! difficulty_json_test_nopath {
|
||||
( $spec:ident ) => {
|
||||
use std::path::Path;
|
||||
|
||||
use super::json_difficulty_test;
|
||||
use json_tests::HookType;
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
json_difficulty_test(json_data, ::ethereum::$spec(), h)
|
||||
}
|
||||
use super::json_difficulty_test;
|
||||
use json_tests::HookType;
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
json_difficulty_test(path, json_data, ::ethereum::$spec(), h)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -230,16 +230,22 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
|
||||
}
|
||||
}
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
let vms = VMType::all();
|
||||
vms
|
||||
.iter()
|
||||
.flat_map(|vm| do_json_test_for(vm, json_data, h))
|
||||
.flat_map(|vm| do_json_test_for(path, vm, json_data, h))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn do_json_test_for<H: FnMut(&str, HookType)>(vm_type: &VMType, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
|
||||
let tests = ethjson::vm::Test::load(json_data).unwrap();
|
||||
fn do_json_test_for<H: FnMut(&str, HookType)>(
|
||||
path: &Path,
|
||||
vm_type: &VMType,
|
||||
json_data: &[u8],
|
||||
start_stop_hook: &mut H
|
||||
) -> Vec<String> {
|
||||
let tests = ethjson::test_helpers::vm::Test::load(json_data)
|
||||
.expect(&format!("Could not parse JSON executive test data from {}", path.display()));
|
||||
let mut failed = Vec::new();
|
||||
|
||||
for (name, vm) in tests.into_iter() {
|
||||
@@ -331,15 +337,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() {
|
||||
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_balance = try_fail!(state.balance(&address));
|
||||
let found_nonce = try_fail!(state.nonce(&address));
|
||||
|
||||
fail_unless(found_code.as_ref().map_or_else(|| code.is_empty(), |c| &**c == &code), "code is incorrect");
|
||||
fail_unless(found_balance == account.balance.into(), "balance is incorrect");
|
||||
fail_unless(found_nonce == account.nonce.into(), "nonce is incorrect");
|
||||
for (k, v) in account.storage {
|
||||
fail_unless(account.balance.as_ref().map_or(false, |b| b.0 == found_balance), "balance is incorrect");
|
||||
fail_unless(account.nonce.as_ref().map_or(false, |n| n.0 == found_nonce), "nonce is incorrect");
|
||||
for (k, v) in account.storage.expect("test should have storage") {
|
||||
let key: U256 = k.into();
|
||||
let value: U256 = v.into();
|
||||
let found_storage = try_fail!(state.storage_at(&address, &BigEndianHash::from_uint(&key)));
|
||||
|
||||
@@ -30,17 +30,7 @@ mod skip;
|
||||
mod difficulty;
|
||||
|
||||
pub use self::test_common::HookType;
|
||||
|
||||
pub use self::transaction::run_test_path as run_transaction_test_path;
|
||||
pub use self::transaction::run_test_file as run_transaction_test_file;
|
||||
pub use self::executive::run_test_path as run_executive_test_path;
|
||||
pub use self::executive::run_test_file as run_executive_test_file;
|
||||
pub use self::state::run_test_path as run_state_test_path;
|
||||
pub use self::state::run_test_file as run_state_test_file;
|
||||
pub use self::chain::run_test_path as run_chain_test_path;
|
||||
pub use self::chain::run_test_file as run_chain_test_file;
|
||||
pub use self::trie::run_generic_test_path as run_generic_trie_test_path;
|
||||
pub use self::trie::run_generic_test_file as run_generic_trie_test_file;
|
||||
pub use self::trie::run_secure_test_path as run_secure_trie_test_path;
|
||||
pub use self::trie::run_secure_test_file as run_secure_trie_test_file;
|
||||
use self::skip::SKIP_TEST_STATE;
|
||||
|
||||
use self::skip::SKIP_TESTS;
|
||||
|
||||
@@ -14,21 +14,30 @@
|
||||
// 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 tests to skip.
|
||||
//! State or blockchain tests to skip.
|
||||
//!
|
||||
//! Looks in the `ethereum/tests/test-issues/currents.json` file. This file contains two
|
||||
//! collections, `block` and `state`, each with a different format to specify single tests to skip.
|
||||
//!
|
||||
//! To skip a blockchain test, add a JSON object to the `block` array, where `failing` names the
|
||||
//! leaf folder with the tests to skip. The `subtests` array contains the names of the tests to skip.
|
||||
//! Note that this does not handle duplicate folder names, e.g. `ValidBlocks/funTests/` and
|
||||
//! `Something/funTests` would both be matched when `failing` is set to `funTests`.
|
||||
//!
|
||||
//! To skip a state test, add a JSON object to the `state` array. The `failing` works like for block
|
||||
//! tests, but the `subtests` key is an object on the form:
|
||||
//! "testName": {"subnumbers": [INDEX_OF_SKIPPED_SUBTESTS | "*"], "chain": "Blockchain name (informational)"}`
|
||||
//!
|
||||
//! Use the `reference` key to point to the github issue tracking to solution to the problem.
|
||||
//!
|
||||
//! Note: the `declare_test!` macro can also be use to skip tests, but skips entire files rather
|
||||
//! than single tests.
|
||||
|
||||
use ethjson;
|
||||
use ethjson::test_helpers::skip::SkipTests;
|
||||
|
||||
#[cfg(feature="ci-skip-tests")]
|
||||
lazy_static!{
|
||||
pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = {
|
||||
lazy_static! {
|
||||
pub static ref SKIP_TESTS: SkipTests = {
|
||||
let skip_data = include_bytes!("../../res/ethereum/tests-issues/currents.json");
|
||||
ethjson::test::SkipStates::load(&skip_data[..]).expect("No invalid json allowed")
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature="ci-skip-tests"))]
|
||||
lazy_static!{
|
||||
pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = {
|
||||
ethjson::test::SkipStates::empty()
|
||||
SkipTests::load(&skip_data[..]).expect("JSON from disk is valid")
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,34 +22,31 @@ use client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess};
|
||||
use ethjson;
|
||||
use types::transaction::SignedTransaction;
|
||||
use vm::EnvInfo;
|
||||
use super::SKIP_TEST_STATE;
|
||||
use super::SKIP_TESTS;
|
||||
use super::HookType;
|
||||
|
||||
/// Run state jsontests on a given folder.
|
||||
pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) {
|
||||
::json_tests::test_common::run_test_path(p, skip, json_chain_test, h)
|
||||
}
|
||||
|
||||
/// Run state jsontests on a given file.
|
||||
pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
|
||||
::json_tests::test_common::run_test_file(p, json_chain_test, h)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn skip_test(subname: &str, chain: &String, number: usize) -> bool {
|
||||
SKIP_TEST_STATE.state.iter().any(|state_test|{
|
||||
trace!(target: "json-tests", "[state, skip_test] subname: '{}', chain: '{}', number: {}", subname, chain, number);
|
||||
SKIP_TESTS.state.iter().any(|state_test|{
|
||||
if let Some(subtest) = state_test.subtests.get(subname) {
|
||||
trace!(target: "json-tests", "[state, skip_test] Maybe skipping {:?}", subtest);
|
||||
chain == &subtest.chain &&
|
||||
(subtest.subnumbers[0] == "*"
|
||||
|| subtest.subnumbers.contains(&number.to_string()))
|
||||
(
|
||||
subtest.subnumbers[0] == "*" ||
|
||||
subtest.subnumbers.contains(&number.to_string())
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
|
||||
#[allow(dead_code)]
|
||||
pub fn json_chain_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
|
||||
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)
|
||||
.expect(&format!("Could not parse JSON state test data from {}", path.display()));
|
||||
let mut failed = Vec::new();
|
||||
|
||||
for (name, test) in tests.into_iter() {
|
||||
@@ -65,7 +62,7 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
|
||||
let spec = match EvmTestClient::spec_from_json(&spec_name) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
println!(" - {} | {:?} Ignoring tests because of missing spec", name, spec_name);
|
||||
println!(" - {} | {:?} Ignoring tests because of missing chainspec", name, spec_name);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
@@ -73,7 +70,7 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
|
||||
for (i, state) in states.into_iter().enumerate() {
|
||||
let info = format!(" - {} | {:?} ({}/{}) ...", name, spec_name, i + 1, total);
|
||||
if skip_test(&name, &spec.name, i + 1) {
|
||||
println!("{} in skip list : SKIPPED", info);
|
||||
println!("{}: SKIPPED", info);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -123,11 +120,13 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
|
||||
|
||||
#[cfg(test)]
|
||||
mod state_tests {
|
||||
use std::path::Path;
|
||||
|
||||
use super::json_chain_test;
|
||||
use json_tests::HookType;
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
json_chain_test(json_data, h)
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], h: &mut H) -> Vec<String> {
|
||||
json_chain_test(path, json_data, h)
|
||||
}
|
||||
|
||||
declare_test!{GeneralStateTest_stArgsZeroOneBalance, "GeneralStateTests/stArgsZeroOneBalance/"}
|
||||
@@ -164,6 +163,15 @@ mod state_tests {
|
||||
declare_test!{GeneralStateTest_stRecursiveCreate, "GeneralStateTests/stRecursiveCreate/"}
|
||||
declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"}
|
||||
declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"}
|
||||
// todo[dvdplm]:
|
||||
// "RevertPrecompiledTouch_storage" contains 4 tests, only two fails
|
||||
// "RevertPrecompiledTouchExactOOG" contains a ton of tests, only two fails
|
||||
// "RevertPrecompiledTouch" has 4 tests, 2 failures
|
||||
// Ignored in `currents.json`.
|
||||
// Issues:
|
||||
// https://github.com/paritytech/parity-ethereum/issues/11078
|
||||
// https://github.com/paritytech/parity-ethereum/issues/11079
|
||||
// https://github.com/paritytech/parity-ethereum/issues/11080
|
||||
declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"}
|
||||
declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"}
|
||||
declare_test!{GeneralStateTest_stShift, "GeneralStateTests/stShift/"}
|
||||
|
||||
@@ -30,43 +30,61 @@ pub enum HookType {
|
||||
OnStop
|
||||
}
|
||||
|
||||
/// Run all tests under the given path (except for the test files named in the skip list) using the
|
||||
/// provided runner function.
|
||||
pub fn run_test_path<H: FnMut(&str, HookType)>(
|
||||
p: &Path, skip: &[&'static str],
|
||||
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
path: &Path,
|
||||
skip: &[&'static str],
|
||||
runner: fn(path: &Path, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
start_stop_hook: &mut H
|
||||
) {
|
||||
if !skip.is_empty() {
|
||||
// todo[dvdplm] it's really annoying to have to use flushln here. Should be `info!(target:
|
||||
// "json-tests", …)`. Issue https://github.com/paritytech/parity-ethereum/issues/11084
|
||||
flushln!("[run_test_path] Skipping tests in {}: {:?}", path.display(), skip);
|
||||
}
|
||||
let mut errors = Vec::new();
|
||||
run_test_path_inner(p, skip, runner, start_stop_hook, &mut errors);
|
||||
run_test_path_inner(path, skip, runner, start_stop_hook, &mut errors);
|
||||
let empty: [String; 0] = [];
|
||||
assert_eq!(errors, empty);
|
||||
assert_eq!(errors, empty, "\nThere were {} tests in '{}' that failed.", errors.len(), path.display());
|
||||
}
|
||||
|
||||
fn run_test_path_inner<H: FnMut(&str, HookType)>(
|
||||
p: &Path, skip: &[&'static str],
|
||||
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
p: &Path,
|
||||
skip: &[&'static str],
|
||||
runner: fn(path: &Path, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
start_stop_hook: &mut H,
|
||||
errors: &mut Vec<String>
|
||||
) {
|
||||
let path = Path::new(p);
|
||||
let s: HashSet<OsString> = skip.iter().map(|s| {
|
||||
let extension = path.extension().and_then(|s| s.to_str());
|
||||
let skip_list: HashSet<OsString> = skip.iter().map(|s| {
|
||||
let mut os: OsString = s.into();
|
||||
os.push(".json");
|
||||
os
|
||||
}).collect();
|
||||
let extension = path.extension().and_then(|s| s.to_str());
|
||||
|
||||
if path.is_dir() {
|
||||
for p in read_dir(path).unwrap().filter_map(|e| {
|
||||
let e = e.unwrap();
|
||||
if s.contains(&e.file_name()) {
|
||||
None
|
||||
} else {
|
||||
Some(e.path())
|
||||
}}) {
|
||||
run_test_path_inner(&p, skip, runner, start_stop_hook, errors);
|
||||
trace!(target: "json-tests", "running tests contained in '{}'", path.display());
|
||||
let test_files = read_dir(path)
|
||||
.expect("Directory exists on disk")
|
||||
.filter_map(|dir_entry| {
|
||||
let dir_entry = dir_entry.expect("Entry in directory listing exists");
|
||||
if skip_list.contains(&dir_entry.file_name()) {
|
||||
debug!(target: "json-tests", "'{:?}' is on the skip list.", dir_entry.file_name());
|
||||
None
|
||||
} else {
|
||||
Some(dir_entry.path())
|
||||
}
|
||||
});
|
||||
for test_file in test_files {
|
||||
run_test_path_inner(&test_file, skip, runner, start_stop_hook, errors);
|
||||
}
|
||||
} else if extension == Some("swp") || extension == None {
|
||||
trace!(target: "json-tests", "ignoring '{}', extension {:?} – Junk?", path.display(), extension);
|
||||
// Ignore junk
|
||||
} else {
|
||||
trace!(target: "json-tests", "running tests in '{}'", path.display());
|
||||
let mut path = p.to_path_buf();
|
||||
path.set_extension("json");
|
||||
run_test_file_append(&path, runner, start_stop_hook, errors)
|
||||
@@ -75,7 +93,7 @@ fn run_test_path_inner<H: FnMut(&str, HookType)>(
|
||||
|
||||
fn run_test_file_append<H: FnMut(&str, HookType)>(
|
||||
path: &Path,
|
||||
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
runner: fn(path: &Path, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
start_stop_hook: &mut H,
|
||||
errors: &mut Vec<String>
|
||||
) {
|
||||
@@ -85,12 +103,12 @@ fn run_test_file_append<H: FnMut(&str, HookType)>(
|
||||
Err(_) => panic!("Error opening test file at: {:?}", path),
|
||||
};
|
||||
file.read_to_end(&mut data).expect("Error reading test file");
|
||||
errors.append(&mut runner(&data, start_stop_hook));
|
||||
errors.append(&mut runner(&path, &data, start_stop_hook));
|
||||
}
|
||||
|
||||
pub fn run_test_file<H: FnMut(&str, HookType)>(
|
||||
path: &Path,
|
||||
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
runner: fn(path: &Path, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
|
||||
start_stop_hook: &mut H
|
||||
) {
|
||||
let mut data = Vec::new();
|
||||
@@ -99,7 +117,7 @@ pub fn run_test_file<H: FnMut(&str, HookType)>(
|
||||
Err(_) => panic!("Error opening test file at: {:?}", path),
|
||||
};
|
||||
file.read_to_end(&mut data).expect("Error reading test file");
|
||||
let results = runner(&data, start_stop_hook);
|
||||
let results = runner(&path, &data, start_stop_hook);
|
||||
let empty: [String; 0] = [];
|
||||
assert_eq!(results, empty);
|
||||
}
|
||||
@@ -107,11 +125,25 @@ pub fn run_test_file<H: FnMut(&str, HookType)>(
|
||||
#[cfg(test)]
|
||||
macro_rules! test {
|
||||
($name: expr, $skip: expr) => {
|
||||
::json_tests::test_common::run_test_path(::std::path::Path::new(concat!("res/ethereum/tests/", $name)), &$skip, do_json_test, &mut |_, _| ());
|
||||
::json_tests::test_common::run_test_path(
|
||||
::std::path::Path::new(concat!("res/ethereum/tests/", $name)),
|
||||
&$skip,
|
||||
do_json_test,
|
||||
&mut |_, _| ()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Declares a test
|
||||
/// Declares a test:
|
||||
///
|
||||
/// declare_test!(test_name, "path/to/folder/with/tests");
|
||||
///
|
||||
/// Declares a test but skip the named test files inside the folder (no extension):
|
||||
///
|
||||
/// declare_test!(skip => ["a-test-file", "other-test-file"], test_name, "path/to/folder/with/tests");
|
||||
///
|
||||
/// NOTE: a skipped test is considered a passing test as far as `cargo test` is concerned. Normally
|
||||
/// one test corresponds to a folder full of test files, each of which may contain many tests.
|
||||
#[macro_export]
|
||||
macro_rules! declare_test {
|
||||
(skip => $arr: expr, $id: ident, $name: expr) => {
|
||||
|
||||
@@ -23,22 +23,14 @@ use types::header::Header;
|
||||
use types::transaction::UnverifiedTransaction;
|
||||
use transaction_ext::Transaction;
|
||||
|
||||
/// Run transaction jsontests on a given folder.
|
||||
pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) {
|
||||
::json_tests::test_common::run_test_path(p, skip, do_json_test, h)
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
|
||||
// Block number used to run the tests.
|
||||
// Make sure that all the specified features are activated.
|
||||
const BLOCK_NUMBER: u64 = 0x6ffffffffffffe;
|
||||
|
||||
/// Run transaction jsontests on a given file.
|
||||
pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
|
||||
::json_tests::test_common::run_test_file(p, do_json_test, h)
|
||||
}
|
||||
|
||||
// Block number used to run the tests.
|
||||
// Make sure that all the specified features are activated.
|
||||
const BLOCK_NUMBER: u64 = 0x6ffffffffffffe;
|
||||
|
||||
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)
|
||||
.expect(&format!("Could not parse JSON transaction test data from {}", path.display()));
|
||||
let mut failed = Vec::new();
|
||||
for (name, test) in tests.into_iter() {
|
||||
start_stop_hook(&name, HookType::OnStart);
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use ethjson;
|
||||
use trie::{TrieFactory, TrieSpec};
|
||||
use ethtrie::RlpCodec;
|
||||
@@ -21,13 +23,10 @@ use ethereum_types::H256;
|
||||
|
||||
use super::HookType;
|
||||
|
||||
pub use self::generic::run_test_path as run_generic_test_path;
|
||||
pub use self::generic::run_test_file as run_generic_test_file;
|
||||
pub use self::secure::run_test_path as run_secure_test_path;
|
||||
pub use self::secure::run_test_file as run_secure_test_file;
|
||||
|
||||
fn test_trie<H: FnMut(&str, HookType)>(json: &[u8], trie: TrieSpec, start_stop_hook: &mut H) -> Vec<String> {
|
||||
let tests = ethjson::trie::Test::load(json).unwrap();
|
||||
#[allow(dead_code)]
|
||||
fn test_trie<H: FnMut(&str, HookType)>(path: &Path, json: &[u8], trie: TrieSpec, start_stop_hook: &mut H) -> Vec<String> {
|
||||
let tests = ethjson::test_helpers::trie::Test::load(json)
|
||||
.expect(&format!("Could not parse JSON trie test data from {}", path.display()));
|
||||
let factory = TrieFactory::<_, RlpCodec>::new(trie);
|
||||
let mut result = vec![];
|
||||
|
||||
@@ -65,18 +64,9 @@ mod generic {
|
||||
|
||||
use super::HookType;
|
||||
|
||||
/// Run generic trie jsontests on a given folder.
|
||||
pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) {
|
||||
::json_tests::test_common::run_test_path(p, skip, do_json_test, h)
|
||||
}
|
||||
|
||||
/// Run generic trie jsontests on a given file.
|
||||
pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
|
||||
::json_tests::test_common::run_test_file(p, do_json_test, h)
|
||||
}
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(json: &[u8], h: &mut H) -> Vec<String> {
|
||||
super::test_trie(json, TrieSpec::Generic, h)
|
||||
#[allow(dead_code)]
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json: &[u8], h: &mut H) -> Vec<String> {
|
||||
super::test_trie(path, json, TrieSpec::Generic, h)
|
||||
}
|
||||
|
||||
declare_test!{TrieTests_trietest, "TrieTests/trietest"}
|
||||
@@ -89,18 +79,9 @@ mod secure {
|
||||
|
||||
use super::HookType;
|
||||
|
||||
/// Run secure trie jsontests on a given folder.
|
||||
pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) {
|
||||
::json_tests::test_common::run_test_path(p, skip, do_json_test, h)
|
||||
}
|
||||
|
||||
/// Run secure trie jsontests on a given file.
|
||||
pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
|
||||
::json_tests::test_common::run_test_file(p, do_json_test, h)
|
||||
}
|
||||
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(json: &[u8], h: &mut H) -> Vec<String> {
|
||||
super::test_trie(json, TrieSpec::Secure, h)
|
||||
#[allow(dead_code)]
|
||||
fn do_json_test<H: FnMut(&str, HookType)>(path: &Path, json: &[u8], h: &mut H) -> Vec<String> {
|
||||
super::test_trie(path, json, TrieSpec::Secure, h)
|
||||
}
|
||||
|
||||
declare_test!{TrieTests_hex_encoded_secure, "TrieTests/hex_encoded_securetrie_test"}
|
||||
|
||||
@@ -40,13 +40,6 @@ impl PodState {
|
||||
pub fn drain(self) -> BTreeMap<Address, PodAccount> { self.0 }
|
||||
}
|
||||
|
||||
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 {
|
||||
fn from(s: ethjson::spec::State) -> PodState {
|
||||
let state: BTreeMap<_,_> = s.into_iter()
|
||||
|
||||
@@ -20,6 +20,7 @@ use hash::KECCAK_NULL_RLP;
|
||||
use spec::seal::Seal;
|
||||
|
||||
/// Genesis components.
|
||||
#[derive(Debug)]
|
||||
pub struct Genesis {
|
||||
/// Seal.
|
||||
pub seal: Seal,
|
||||
|
||||
@@ -21,6 +21,7 @@ use ethereum_types::{H64, H256, H520};
|
||||
use ethjson;
|
||||
|
||||
/// Classic ethereum seal.
|
||||
#[derive(Debug)]
|
||||
pub struct Ethereum {
|
||||
/// Seal nonce.
|
||||
pub nonce: H64,
|
||||
@@ -37,6 +38,7 @@ impl Into<Generic> for Ethereum {
|
||||
}
|
||||
|
||||
/// AuthorityRound seal.
|
||||
#[derive(Debug)]
|
||||
pub struct AuthorityRound {
|
||||
/// Seal step.
|
||||
pub step: usize,
|
||||
@@ -45,6 +47,7 @@ pub struct AuthorityRound {
|
||||
}
|
||||
|
||||
/// Tendermint seal.
|
||||
#[derive(Debug)]
|
||||
pub struct Tendermint {
|
||||
/// Seal round.
|
||||
pub round: usize,
|
||||
@@ -73,9 +76,11 @@ impl Into<Generic> for Tendermint {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Generic(pub Vec<u8>);
|
||||
|
||||
/// Genesis seal type.
|
||||
#[derive(Debug)]
|
||||
pub enum Seal {
|
||||
/// Classic ethereum seal.
|
||||
Ethereum(Ethereum),
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::io::Read;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use bytes::Bytes;
|
||||
use bytes::{Bytes, ToPretty};
|
||||
use ethereum_types::{H256, Bloom, U256, Address};
|
||||
use ethjson;
|
||||
use hash::{KECCAK_NULL_RLP, keccak};
|
||||
@@ -691,53 +691,58 @@ impl Spec {
|
||||
|
||||
let (root, db) = {
|
||||
let mut state = State::from_existing(db, root, start_nonce, factories.clone())?;
|
||||
if self.constructors.is_empty() {
|
||||
state.populate_from(self.genesis_state.clone());
|
||||
let _ = state.commit()?;
|
||||
} else {
|
||||
|
||||
// Execute contract constructors.
|
||||
let env_info = EnvInfo {
|
||||
number: 0,
|
||||
author: self.author,
|
||||
timestamp: self.timestamp,
|
||||
difficulty: self.difficulty,
|
||||
last_hashes: Default::default(),
|
||||
gas_used: U256::zero(),
|
||||
gas_limit: U256::max_value(),
|
||||
};
|
||||
|
||||
let from = Address::zero();
|
||||
for &(ref address, ref constructor) in self.constructors.iter() {
|
||||
trace!(target: "spec", "run_constructors: Creating a contract at {}.", address);
|
||||
trace!(target: "spec", " .. root before = {}", state.root());
|
||||
let params = ActionParams {
|
||||
code_address: address.clone(),
|
||||
code_hash: Some(keccak(constructor)),
|
||||
address: address.clone(),
|
||||
sender: from.clone(),
|
||||
origin: from.clone(),
|
||||
gas: U256::max_value(),
|
||||
gas_price: Default::default(),
|
||||
value: ActionValue::Transfer(Default::default()),
|
||||
code: Some(Arc::new(constructor.clone())),
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
params_type: ParamsType::Embedded,
|
||||
// Execute contract constructors.
|
||||
let env_info = EnvInfo {
|
||||
number: 0,
|
||||
author: self.author,
|
||||
timestamp: self.timestamp,
|
||||
difficulty: self.difficulty,
|
||||
last_hashes: Default::default(),
|
||||
gas_used: U256::zero(),
|
||||
gas_limit: U256::max_value(),
|
||||
};
|
||||
|
||||
let mut substate = Substate::new();
|
||||
let from = Address::zero();
|
||||
for &(ref address, ref constructor) in self.constructors.iter() {
|
||||
trace!(target: "spec", "run_constructors: Creating a contract at {}.", address);
|
||||
trace!(target: "spec", " .. root before = {}", state.root());
|
||||
let params = ActionParams {
|
||||
code_address: address.clone(),
|
||||
code_hash: Some(keccak(constructor)),
|
||||
address: address.clone(),
|
||||
sender: from.clone(),
|
||||
origin: from.clone(),
|
||||
gas: U256::max_value(),
|
||||
gas_price: Default::default(),
|
||||
value: ActionValue::Transfer(Default::default()),
|
||||
code: Some(Arc::new(constructor.clone())),
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
params_type: ParamsType::Embedded,
|
||||
};
|
||||
|
||||
{
|
||||
let machine = self.engine.machine();
|
||||
let schedule = machine.schedule(env_info.number);
|
||||
let mut exec = Executive::new(&mut state, &env_info, &machine, &schedule);
|
||||
if let Err(e) = exec.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) {
|
||||
warn!(target: "spec", "Genesis constructor execution at {} failed: {}.", address, e);
|
||||
let mut substate = Substate::new();
|
||||
|
||||
{
|
||||
let machine = self.engine.machine();
|
||||
let schedule = machine.schedule(env_info.number);
|
||||
let mut exec = Executive::new(&mut state, &env_info, &machine, &schedule);
|
||||
if let Err(e) = exec.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) {
|
||||
warn!(target: "spec", "Genesis constructor execution at {} failed: {}.", address, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = state.commit() {
|
||||
warn!(target: "spec", "Genesis constructor trie commit at {} failed: {}.", address, e);
|
||||
}
|
||||
if let Err(e) = state.commit() {
|
||||
warn!(target: "spec", "Genesis constructor trie commit at {} failed: {}.", address, e);
|
||||
}
|
||||
|
||||
trace!(target: "spec", " .. root after = {}", state.root());
|
||||
trace!(target: "spec", " .. root after = {}", state.root());
|
||||
}
|
||||
}
|
||||
|
||||
state.drop()
|
||||
|
||||
@@ -2608,7 +2608,7 @@ mod tests {
|
||||
fn should_not_panic_on_state_diff_with_storage() {
|
||||
let mut state = get_temp_state();
|
||||
let a = Address::from_low_u64_be(0xa);
|
||||
state.init_code(&a, b"abcdefg".to_vec()).unwrap();;
|
||||
state.init_code(&a, b"abcdefg".to_vec()).unwrap();
|
||||
state.add_balance(&a, &256.into(), CleanupMode::NoEmpty).unwrap();
|
||||
state.set_storage(&a, H256::from_low_u64_be(0xb), H256::from_low_u64_be(0xc).into()).unwrap();
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ impl Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ethjson::state::Transaction> for SignedTransaction {
|
||||
fn from(t: ethjson::state::Transaction) -> Self {
|
||||
impl From<ethjson::transaction::Transaction> for SignedTransaction {
|
||||
fn from(t: ethjson::transaction::Transaction) -> Self {
|
||||
let to: Option<ethjson::hash::Address> = t.to.into();
|
||||
let secret = t.secret.map(|s| Secret::from(s.0));
|
||||
let tx = Transaction {
|
||||
|
||||
@@ -14,7 +14,7 @@ docopt = "1.0"
|
||||
env_logger = "0.5"
|
||||
ethcore = { path = "../ethcore", features = ["test-helpers", "json-tests", "to-pod-full"] }
|
||||
ethereum-types = "0.6.0"
|
||||
ethjson = { path = "../json" }
|
||||
ethjson = { path = "../json", features = ["test-helpers"] }
|
||||
evm = { path = "../ethcore/evm" }
|
||||
panic_hook = { path = "../util/panic-hook" }
|
||||
parity-bytes = "0.1"
|
||||
|
||||
@@ -174,7 +174,7 @@ fn run_stats_jsontests_vm(args: Args) {
|
||||
}
|
||||
|
||||
fn run_state_test(args: Args) {
|
||||
use ethjson::state::test::Test;
|
||||
use ethjson::test_helpers::state::Test;
|
||||
|
||||
let file = args.arg_file.expect("FILE is required");
|
||||
let mut file = match fs::File::open(&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 = []
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
@@ -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;
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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() {
|
||||
@@ -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() {
|
||||
23
json/src/test_helpers/difficulty.rs
Normal file
23
json/src/test_helpers/difficulty.rs
Normal 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>;
|
||||
@@ -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>;
|
||||
}
|
||||
58
json/src/test_helpers/skip.rs
Normal file
58
json/src/test_helpers/skip.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
27
json/src/test_helpers/tester.rs
Normal file
27
json/src/test_helpers/tester.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
@@ -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() {
|
||||
@@ -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)]
|
||||
@@ -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())));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
275
json/src/vm.rs
Normal 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)));
|
||||
}
|
||||
}
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,7 @@ ethcore = { path = "../ethcore", features = ["test-helpers"] }
|
||||
ethcore-accounts = { path = "../accounts" }
|
||||
ethcore-io = { path = "../util/io" }
|
||||
ethcore-network = { path = "../util/network" }
|
||||
ethjson = { path = "../json", features = ["test-helpers"] }
|
||||
fake-fetch = { path = "../util/fake-fetch" }
|
||||
macros = { path = "../util/macros" }
|
||||
pretty_assertions = "0.1"
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! rpc integration tests.
|
||||
use std::env;
|
||||
use std::sync::Arc;
|
||||
|
||||
use std::{env, sync::Arc};
|
||||
|
||||
use accounts::AccountProvider;
|
||||
use ethcore::client::{BlockChainClient, Client, ClientConfig, ChainInfo, ImportBlock};
|
||||
@@ -27,7 +27,7 @@ use ethcore::test_helpers;
|
||||
use ethcore::verification::VerifierType;
|
||||
use ethcore::verification::queue::kind::blocks::Unverified;
|
||||
use ethereum_types::{Address, H256, U256};
|
||||
use ethjson::blockchain::BlockChain;
|
||||
use ethjson::test_helpers::blockchain::BlockChain;
|
||||
use ethjson::spec::ForkSpec;
|
||||
use io::IoChannel;
|
||||
use miner::external::ExternalMiner;
|
||||
@@ -84,7 +84,7 @@ struct EthTester {
|
||||
impl EthTester {
|
||||
fn from_chain(chain: &BlockChain) -> Self {
|
||||
|
||||
let tester = if ::ethjson::blockchain::Engine::NoProof == chain.engine {
|
||||
let tester = if ethjson::test_helpers::blockchain::Engine::NoProof == chain.engine {
|
||||
let mut config = ClientConfig::default();
|
||||
config.verifier_type = VerifierType::CanonNoSeal;
|
||||
config.check_seal = false;
|
||||
@@ -174,13 +174,13 @@ impl EthTester {
|
||||
|
||||
#[test]
|
||||
fn harness_works() {
|
||||
let chain: BlockChain = extract_chain!("BlockchainTests/bcWalletTest/wallet2outOf3txs");
|
||||
let chain: BlockChain = extract_chain!("BlockchainTests/ValidBlocks/bcWalletTest/wallet2outOf3txs");
|
||||
let _ = EthTester::from_chain(&chain);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eth_get_balance() {
|
||||
let chain = extract_chain!("BlockchainTests/bcWalletTest/wallet2outOf3txs");
|
||||
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcWalletTest/wallet2outOf3txs");
|
||||
let tester = EthTester::from_chain(&chain);
|
||||
// final account state
|
||||
let req_latest = r#"{
|
||||
@@ -206,7 +206,7 @@ fn eth_get_balance() {
|
||||
|
||||
#[test]
|
||||
fn eth_get_proof() {
|
||||
let chain = extract_chain!("BlockchainTests/bcWalletTest/wallet2outOf3txs");
|
||||
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcWalletTest/wallet2outOf3txs");
|
||||
let tester = EthTester::from_chain(&chain);
|
||||
// final account state
|
||||
let req_latest = r#"{
|
||||
@@ -233,7 +233,7 @@ fn eth_get_proof() {
|
||||
|
||||
#[test]
|
||||
fn eth_block_number() {
|
||||
let chain = extract_chain!("BlockchainTests/bcGasPricerTest/RPC_API_Test");
|
||||
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcGasPricerTest/RPC_API_Test");
|
||||
let tester = EthTester::from_chain(&chain);
|
||||
let req_number = r#"{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -248,7 +248,7 @@ fn eth_block_number() {
|
||||
|
||||
#[test]
|
||||
fn eth_get_block() {
|
||||
let chain = extract_chain!("BlockchainTests/bcGasPricerTest/RPC_API_Test");
|
||||
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcGasPricerTest/RPC_API_Test");
|
||||
let tester = EthTester::from_chain(&chain);
|
||||
let req_block = r#"{"method":"eth_getBlockByNumber","params":["0x0",false],"id":1,"jsonrpc":"2.0"}"#;
|
||||
|
||||
@@ -258,13 +258,13 @@ fn eth_get_block() {
|
||||
|
||||
#[test]
|
||||
fn eth_get_block_by_hash() {
|
||||
let chain = extract_chain!("BlockchainTests/bcGasPricerTest/RPC_API_Test");
|
||||
let chain = extract_chain!("BlockchainTests/ValidBlocks/bcGasPricerTest/RPC_API_Test");
|
||||
let tester = EthTester::from_chain(&chain);
|
||||
|
||||
// We're looking for block number 4 from "RPC_API_Test_Frontier"
|
||||
let req_block = r#"{"method":"eth_getBlockByHash","params":["0xaddb9e39795e9e041c936b88a2577802569f34afded0948707b074caa3163a87",false],"id":1,"jsonrpc":"2.0"}"#;
|
||||
let req_block = r#"{"method":"eth_getBlockByHash","params":["0x75e65fb3bbf5f53afe26dcc72df6a95b0e8ca5f1c450145d8c3915bd0308b75b",false],"id":1,"jsonrpc":"2.0"}"#;
|
||||
|
||||
let res_block = r#"{"jsonrpc":"2.0","result":{"author":"0x8888f1f195afa192cfee860698584c030f4c9db1","difficulty":"0x20080","extraData":"0x","gasLimit":"0x1dd7ea0","gasUsed":"0x5458","hash":"0xaddb9e39795e9e041c936b88a2577802569f34afded0948707b074caa3163a87","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8888f1f195afa192cfee860698584c030f4c9db1","mixHash":"0x713b0b31f6e72d8cb7367eaf59447ea531f209fc80e6379edd9f8d3bb73931c4","nonce":"0x4534b406bc23b86d","number":"0x4","parentHash":"0x17567aa5995b703736e32972289d68af50543acc4d56d37e8ad1fea7252cac4a","receiptsRoot":"0x7ed8026cf72ed0e98e6fd53ab406e51ffd34397d9da0052494ff41376fda7b5f","sealFields":["0xa0713b0b31f6e72d8cb7367eaf59447ea531f209fc80e6379edd9f8d3bb73931c4","0x884534b406bc23b86d"],"sha3Uncles":"0xe588a44b3e320e72e70b32b531f3ac0d432e756120135ae8fe5fa10895196b40","size":"0x661","stateRoot":"0x68805721294e365020aca15ed56c360d9dc2cf03cbeff84c9b84b8aed023bfb5","timestamp":"0x5bbdf772","totalDifficulty":"0xa00c0","transactions":["0xb094b9dc356dbb8b256402c6d5709288066ad6a372c90c9c516f14277545fd58"],"transactionsRoot":"0x97a593d8d7e15b57f5c6bb25bc6c325463ef99f874bc08a78656c3ab5cb23262","uncles":["0x86b48f5186c4b0882d3dca7977aa37840008832ef092f8ef797019dc74bfa8c7","0x2da9d062c11d536f0f1cc2a4e0111597c79926958d0fc26ae1a2d07d1a3bf47d"]},"id":1}"#;
|
||||
let res_block = r#"{"jsonrpc":"2.0","result":{"author":"0x8888f1f195afa192cfee860698584c030f4c9db1","difficulty":"0x20000","extraData":"0x","gasLimit":"0x1dd7ea0","gasUsed":"0x5458","hash":"0x75e65fb3bbf5f53afe26dcc72df6a95b0e8ca5f1c450145d8c3915bd0308b75b","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8888f1f195afa192cfee860698584c030f4c9db1","mixHash":"0x55553aaef7ee28e3aea539eb784e8cc26646911a19126c242ac682c3fcf22041","nonce":"0xca2904e50ca47ace","number":"0x4","parentHash":"0x58849f66c0ca60054468725cf173b72a2769807152c625aa02e71d67ab2eaed5","receiptsRoot":"0x7ed8026cf72ed0e98e6fd53ab406e51ffd34397d9da0052494ff41376fda7b5f","sealFields":["0xa055553aaef7ee28e3aea539eb784e8cc26646911a19126c242ac682c3fcf22041","0x88ca2904e50ca47ace"],"sha3Uncles":"0x0dbc9711185574f2eee337af18d08c0afe85490304c6bb16b443991b552c5e2c","size":"0x661","stateRoot":"0x68805721294e365020aca15ed56c360d9dc2cf03cbeff84c9b84b8aed023bfb5","timestamp":"0x5c477134","totalDifficulty":"0xa0000","transactions":["0xb094b9dc356dbb8b256402c6d5709288066ad6a372c90c9c516f14277545fd58"],"transactionsRoot":"0x97a593d8d7e15b57f5c6bb25bc6c325463ef99f874bc08a78656c3ab5cb23262","uncles":["0x51b0d7366382926a4f83191af19cb4aa894f6fd9bd1bda6c04de3d5af70eddba","0x9263e0be8311eb79db96171fad3fdd70317bbbdc4081ad6b04c60335db65a3bb"]},"id":1}"#;
|
||||
assert_eq!(tester.handler.handle_request_sync(req_block).unwrap(), res_block);
|
||||
}
|
||||
|
||||
@@ -510,6 +510,6 @@ fn starting_nonce_test() {
|
||||
assert_eq!(r#"{"jsonrpc":"2.0","result":"0x100","id":15}"#, &sample);
|
||||
}
|
||||
|
||||
register_test!(eth_transaction_count_1, verify_transaction_counts, "BlockchainTests/bcWalletTest/wallet2outOf3txs");
|
||||
register_test!(eth_transaction_count_2, verify_transaction_counts, "BlockchainTests/bcTotalDifficultyTest/sideChainWithMoreTransactions");
|
||||
register_test!(eth_transaction_count_3, verify_transaction_counts, "BlockchainTests/bcGasPricerTest/RPC_API_Test");
|
||||
register_test!(eth_transaction_count_1, verify_transaction_counts, "BlockchainTests/ValidBlocks/bcWalletTest/wallet2outOf3txs");
|
||||
register_test!(eth_transaction_count_2, verify_transaction_counts, "BlockchainTests/ValidBlocks/bcTotalDifficultyTest/sideChainWithMoreTransactions");
|
||||
register_test!(eth_transaction_count_3, verify_transaction_counts, "BlockchainTests/ValidBlocks/bcGasPricerTest/RPC_API_Test");
|
||||
|
||||
@@ -32,7 +32,7 @@ macro_rules! extract_chain {
|
||||
(iter $file:expr) => {{
|
||||
const RAW_DATA: &'static [u8] =
|
||||
include_bytes!(concat!("../../../../ethcore/res/ethereum/tests/", $file, ".json"));
|
||||
::ethjson::blockchain::Test::load(RAW_DATA).unwrap().into_iter()
|
||||
ethjson::test_helpers::blockchain::Test::load(RAW_DATA).unwrap().into_iter()
|
||||
}};
|
||||
|
||||
($file:expr) => {{
|
||||
|
||||
@@ -5,7 +5,7 @@ echo "________Running test-linux.sh________"
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
FEATURES="json-tests,ci-skip-tests"
|
||||
FEATURES="json-tests"
|
||||
OPTIONS="--release"
|
||||
#use nproc `linux only
|
||||
THREADS=$(nproc)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[package]
|
||||
name = "parity-version"
|
||||
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
|
||||
version = "2.6.3"
|
||||
version = "2.6.4"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user