V2.7.2 stable (#11454)

* update classic testnet bootnodes (#11398)

* update classic testnet bootnodes

* Update kotti.json

* Update kotti.json

* Update kotti.json

* Update mordor.json

* verification: fix race same block + misc (#11400)

* ethcore: fix race in verification

* verification: fix some nits

* verification: refactor err type `Kind::create`

* fix: tests

* address grumbles

* address grumbles: don't panic

* fix: export hardcoded sync format (#11416)

* fix: export hardcoded sync format

* address grumbles

* make tests compile with rustc_hex 2.0

* fix grumbles: impl LowerHex for encoded Header

* goerli: replace foundation bootnode (#11433)

* Remove dead bootnodes, add new geth bootnodes (#11441)

* update kvdb-rocksdb to 0.4 (#11442)

* Avoid long state queries when serving GetNodeData requests (#11444)

* Remove dead bootnodes, add new geth bootnodes

* More granular locking when fetching state
Finish GetDataNode requests early if queries take too long

* typo

* Use latest kvdb-rocksdb

* Cleanup

* Update ethcore/sync/src/chain/supplier.rs

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

* Address review grumbles

* Fix compilation

* Address review grumbles

Co-authored-by: Andronik Ordian <write@reusable.software>

* rlp_derive: cleanup (#11446)

* rlp_derive: update syn & co

* rlp_derive: remove dummy_const

* rlp_derive: remove unused attirubutes

* rlp-derive: change authors

* Cargo.lock: cargo update -p kvdb-rocksdb (#11447)

* Cargo.lock: new lockfile format

Manual backport of https://github.com/paritytech/parity-ethereum/pull/11448

* gcc to clang (#11453)

* gcc to clang

test
```
export CC="sccache "$CC
export CXX="sccache "$CXX
```
darwin build
```
CC=clang
CXX=clang
```

* darwin - > default clang

* Bump version and CHANGELOG.md

* chore: remove unused dependencies (#11432)

* fix: compiler warnings

* chore: remove unused dependencies

* Update CHANGELOG.md

* update Cargo.lock

* update CHANGELOG.md

* backwards compatible call_type creation_method (#11450)

* rlp_derive: update syn & co

* rlp_derive: remove dummy_const

* rlp_derive: remove unused attirubutes

* rlp-derive: change authors

* rlp_derive: add rlp(default) attribute

* Revert "Revert "[Trace] Distinguish between `create` and `create2` (#11311)" (#11427)"

This reverts commit 5d4993b0f8.

* trace: backwards compatible call_type and creation_method

* trace: add rlp backward compatibility tests

* cleanup

* i know, i hate backwards compatibility too

* address review grumbles

* update CHANGELOG.md

* just to make sure we don't screw up this again (#11455)

* Update CHANGELOG.md

Co-authored-by: Talha Cross <47772477+soc1c@users.noreply.github.com>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: David <dvdplm@gmail.com>
Co-authored-by: Andronik Ordian <write@reusable.software>
Co-authored-by: Denis S. Soldatov aka General-Beck <general.beck@gmail.com>
This commit is contained in:
s3krit 2020-02-05 17:10:36 +01:00 committed by GitHub
parent 6885be06a4
commit d961010f63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
84 changed files with 3667 additions and 3163 deletions

View File

@ -165,8 +165,6 @@ build-darwin:
variables: variables:
CARGO_TARGET: x86_64-apple-darwin CARGO_TARGET: x86_64-apple-darwin
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
CC: gcc
CXX: g++
script: script:
- scripts/gitlab/build-linux.sh - scripts/gitlab/build-linux.sh
tags: tags:

View File

@ -1,3 +1,25 @@
## Parity-Ethereum [v2.7.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.7.1)
Parity Ethereum v2.7.2-stable is a patch version release of parity-ethereum.
Starting in the 2.7.x series of releases, parity-ethereum is switching to a single `stable` release
track. As a result, any clients that currently receive updates from the `beta`
track should switch to the `stable` track.
Due to database format changes, upgrading from 2.5.x or 2.6.x is one-way only.
The full list of included changes:
* backwards compatible call_type creation_method (#11450 + #11455)
* chore: remove unused dependencies (#11432)
* Cargo.lock: new lockfile format (#11448)
* rlp_derive: cleanup (#11446)
* Avoid long state queries when serving GetNodeData requests (#11444)
* update kvdb-rocksdb to 0.4 (#11442)
* Remove dead bootnodes, add new geth bootnodes (#11441)
* goerli: replace foundation bootnode (#11433)
* fix: export hardcoded sync format (#11416)
* verification: fix race same block + misc (#11400)
* update classic testnet bootnodes (#11398)
* gcc to clang (#11453)
## Parity-Ethereum [v2.7.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.7.1) ## Parity-Ethereum [v2.7.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.7.1)
Parity Ethereum v2.7.1-stable is a patch version release of parity-ethereum. Parity Ethereum v2.7.1-stable is a patch version release of parity-ethereum.
Starting in the 2.7.x series of releases, parity-ethereum is switching to a single `stable` release Starting in the 2.7.x series of releases, parity-ethereum is switching to a single `stable` release

5463
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
description = "Parity Ethereum client" description = "Parity Ethereum client"
name = "parity-ethereum" name = "parity-ethereum"
# NOTE Make sure to update util/version/Cargo.toml as well # NOTE Make sure to update util/version/Cargo.toml as well
version = "2.7.1" version = "2.7.2"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
@ -41,8 +41,8 @@ futures = "0.1"
journaldb = { path = "util/journaldb" } journaldb = { path = "util/journaldb" }
jsonrpc-core = "14.0.3" jsonrpc-core = "14.0.3"
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
kvdb = "0.2" kvdb = "0.3.1"
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"
log = "0.4" log = "0.4"
migration-rocksdb = { path = "util/migration-rocksdb" } migration-rocksdb = { path = "util/migration-rocksdb" }
node-filter = { path = "ethcore/node-filter" } node-filter = { path = "ethcore/node-filter" }

View File

@ -31,9 +31,9 @@ hash-db = "0.15.0"
itertools = "0.5" itertools = "0.5"
journaldb = { path = "../util/journaldb" } journaldb = { path = "../util/journaldb" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
kvdb = "0.2" kvdb = "0.3.1"
kvdb-memorydb = { version = "0.2.0", optional = true } kvdb-memorydb = { version = "0.3.1", optional = true }
kvdb-rocksdb = { version = "0.3.0", optional = true } kvdb-rocksdb = { version = "0.4.1", optional = true }
lazy_static = { version = "1.3", optional = true } lazy_static = { version = "1.3", optional = true }
log = "0.4" log = "0.4"
macros = { path = "../util/macros", optional = true } macros = { path = "../util/macros", optional = true }
@ -78,8 +78,8 @@ ethcore-builtin = { path = "./builtin" }
ethjson = { path = "../json", features = ["test-helpers"] } ethjson = { path = "../json", features = ["test-helpers"] }
parity-crypto = { version = "0.4.2", features = ["publickey"] } parity-crypto = { version = "0.4.2", features = ["publickey"] }
fetch = { path = "../util/fetch" } fetch = { path = "../util/fetch" }
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"
lazy_static = "1.3" lazy_static = "1.3"
machine = { path = "./machine", features = ["test-helpers"] } machine = { path = "./machine", features = ["test-helpers"] }
macros = { path = "../util/macros" } macros = { path = "../util/macros" }

View File

@ -11,5 +11,5 @@ ethereum-types = "0.8.0"
hash-db = "0.15.0" hash-db = "0.15.0"
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
rlp = "0.4" rlp = "0.4"

View File

@ -16,7 +16,7 @@ hash-db = "0.15.0"
journaldb = { path = "../../util/journaldb" } journaldb = { path = "../../util/journaldb" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
lru-cache = "0.1.2" lru-cache = "0.1.2"
memory-db = "0.18.0" memory-db = "0.18.0"
@ -26,7 +26,6 @@ parking_lot = "0.9"
pod = { path = "../pod" } pod = { path = "../pod" }
rlp = "0.4.0" rlp = "0.4.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
trace = { path = "../trace" }
trie-db = "0.18.0" trie-db = "0.18.0"
[dev-dependencies] [dev-dependencies]

View File

@ -16,7 +16,7 @@ ethereum-types = "0.8.0"
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
parity-util-mem = "0.3.0" parity-util-mem = "0.3.0"
itertools = "0.5" itertools = "0.5"
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
parity-bytes = "0.1" parity-bytes = "0.1"
rand = "0.7" rand = "0.7"
@ -32,4 +32,4 @@ env_logger = "0.5"
parity-crypto = { version = "0.4.2", features = ["publickey"] } parity-crypto = { version = "0.4.2", features = ["publickey"] }
rustc-hex = "1.0" rustc-hex = "1.0"
tempdir = "0.3" tempdir = "0.3"
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"

View File

@ -14,10 +14,10 @@ ethereum-types = "0.8.0"
ethjson = { path = "../../json" } ethjson = { path = "../../json" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
log = "0.4" log = "0.4"
macros = { path = "../../util/macros" }
num = { version = "0.1", default-features = false, features = ["bigint"] } num = { version = "0.1", default-features = false, features = ["bigint"] }
parity-bytes = "0.1" parity-bytes = "0.1"
parity-crypto = { version = "0.4.2", features = ["publickey"] } parity-crypto = { version = "0.4.2", features = ["publickey"] }
[dev-dependencies] [dev-dependencies]
hex-literal = "0.2.1" hex-literal = "0.2.1"
macros = { path = "../../util/macros" }

View File

@ -15,7 +15,7 @@ common-types = { path = "../types" }
ethcore-db = { path = "../db" } ethcore-db = { path = "../db" }
ethcore-miner = { path = "../../miner" } ethcore-miner = { path = "../../miner" }
ethereum-types = "0.8.0" ethereum-types = "0.8.0"
kvdb = "0.2" kvdb = "0.3.1"
registrar = { path = "../../util/registrar" } registrar = { path = "../../util/registrar" }
stats = { path = "../../util/stats" } stats = { path = "../../util/stats" }
trace = { path = "../trace" } trace = { path = "../trace" }

View File

@ -10,7 +10,7 @@ edition = "2018"
[dependencies] [dependencies]
common-types = { path = "../types" } common-types = { path = "../types" }
ethereum-types = "0.8.0" ethereum-types = "0.8.0"
kvdb = "0.2" kvdb = "0.3.1"
parity-util-mem = "0.3.0" parity-util-mem = "0.3.0"
parking_lot = "0.9" parking_lot = "0.9"
rlp = "0.4.0" rlp = "0.4.0"

View File

@ -42,7 +42,7 @@ use machine::{
Machine, Machine,
executed_block::ExecutedBlock, executed_block::ExecutedBlock,
}; };
use vm::{EnvInfo, Schedule, CallType, ActionValue}; use vm::{EnvInfo, Schedule, ActionType, ActionValue};
use crate::signer::EngineSigner; use crate::signer::EngineSigner;
@ -82,7 +82,7 @@ pub fn default_system_or_code_call<'a>(machine: &'a Machine, block: &'a mut Exec
Some(ActionValue::Apparent(U256::zero())), Some(ActionValue::Apparent(U256::zero())),
U256::max_value(), U256::max_value(),
Some(data), Some(data),
Some(CallType::StaticCall), Some(ActionType::StaticCall),
) )
}, },
}; };

View File

@ -17,7 +17,7 @@ ethereum-types = "0.8.0"
ethjson = { path = "../../../json" } ethjson = { path = "../../../json" }
executive-state = { path = "../../executive-state" } executive-state = { path = "../../executive-state" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
kvdb = "0.2" kvdb = "0.3.1"
lazy_static = "1.3.0" lazy_static = "1.3.0"
log = "0.4.8" log = "0.4.8"
machine = { path = "../../machine" } machine = { path = "../../machine" }

View File

@ -33,7 +33,7 @@ use ethereum_types::{U256, U512, H256, Address, BigEndianHash};
use vm::{ use vm::{
self, ActionParams, ParamsType, ActionValue, CallType, MessageCallResult, self, ActionParams, ParamsType, ActionValue, ActionType, MessageCallResult,
ContractCreateResult, CreateContractAddress, ReturnData, GasLeft, Schedule, ContractCreateResult, CreateContractAddress, ReturnData, GasLeft, Schedule,
TrapKind, TrapError TrapKind, TrapError
}; };
@ -133,8 +133,8 @@ struct InterpreterParams {
pub value: ActionValue, pub value: ActionValue,
/// Input data. /// Input data.
pub data: Option<Bytes>, pub data: Option<Bytes>,
/// Type of call /// Type of action
pub call_type: CallType, pub action_type: ActionType,
/// Param types encoding /// Param types encoding
pub params_type: ParamsType, pub params_type: ParamsType,
} }
@ -152,7 +152,7 @@ impl From<ActionParams> for InterpreterParams {
gas_price: params.gas_price, gas_price: params.gas_price,
value: params.value, value: params.value,
data: params.data, data: params.data,
call_type: params.call_type, action_type: params.action_type,
params_type: params.params_type, params_type: params.params_type,
} }
} }
@ -532,7 +532,9 @@ impl<Cost: CostType> Interpreter<Cost> {
let init_size = self.stack.pop_back(); let init_size = self.stack.pop_back();
let address_scheme = match instruction { let address_scheme = match instruction {
instructions::CREATE => CreateContractAddress::FromSenderAndNonce, instructions::CREATE => CreateContractAddress::FromSenderAndNonce,
instructions::CREATE2 => CreateContractAddress::FromSenderSaltAndCodeHash(BigEndianHash::from_uint(&self.stack.pop_back())), instructions::CREATE2 => CreateContractAddress::FromSenderSaltAndCodeHash(
BigEndianHash::from_uint(&self.stack.pop_back())
),
_ => unreachable!("instruction can only be CREATE/CREATE2 checked above; qed"), _ => unreachable!("instruction can only be CREATE/CREATE2 checked above; qed"),
}; };
@ -553,7 +555,14 @@ impl<Cost: CostType> Interpreter<Cost> {
let contract_code = self.mem.read_slice(init_off, init_size); let contract_code = self.mem.read_slice(init_off, init_size);
let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, &self.params.code_version, address_scheme, true); let create_result = ext.create(
&create_gas.as_u256(),
&endowment,
contract_code,
&self.params.code_version,
address_scheme,
true,
);
return match create_result { return match create_result {
Ok(ContractCreateResult::Created(address, gas_left)) => { Ok(ContractCreateResult::Created(address, gas_left)) => {
self.stack.push(address_to_u256(address)); self.stack.push(address_to_u256(address));
@ -607,14 +616,14 @@ impl<Cost: CostType> Interpreter<Cost> {
return Err(vm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
let has_balance = ext.balance(&self.params.address)? >= value.expect("value set for all but delegate call; qed"); let has_balance = ext.balance(&self.params.address)? >= value.expect("value set for all but delegate call; qed");
(&self.params.address, &code_address, has_balance, CallType::Call) (&self.params.address, &code_address, has_balance, ActionType::Call)
}, },
instructions::CALLCODE => { instructions::CALLCODE => {
let has_balance = ext.balance(&self.params.address)? >= value.expect("value set for all but delegate call; qed"); let has_balance = ext.balance(&self.params.address)? >= value.expect("value set for all but delegate call; qed");
(&self.params.address, &self.params.address, has_balance, CallType::CallCode) (&self.params.address, &self.params.address, has_balance, ActionType::CallCode)
}, },
instructions::DELEGATECALL => (&self.params.sender, &self.params.address, true, CallType::DelegateCall), instructions::DELEGATECALL => (&self.params.sender, &self.params.address, true, ActionType::DelegateCall),
instructions::STATICCALL => (&self.params.address, &code_address, true, CallType::StaticCall), instructions::STATICCALL => (&self.params.address, &code_address, true, ActionType::StaticCall),
_ => panic!(format!("Unexpected instruction {:?} in CALL branch.", instruction)) _ => panic!(format!("Unexpected instruction {:?} in CALL branch.", instruction))
}; };

View File

@ -47,7 +47,7 @@ mod instructions;
mod tests; mod tests;
pub use vm::{ pub use vm::{
Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext, Schedule, CleanDustMode, EnvInfo, ActionType, ActionParams, Ext,
ContractCreateResult, MessageCallResult, CreateContractAddress, ContractCreateResult, MessageCallResult, CreateContractAddress,
GasLeft, ReturnData GasLeft, ReturnData
}; };

View File

@ -14,7 +14,7 @@ common-types = { path = "../types" }
ethereum-types = "0.8.0" ethereum-types = "0.8.0"
hash-db = "0.15.0" hash-db = "0.15.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4.8" log = "0.4.8"
machine = { path = "../machine" } machine = { path = "../machine" }
trace = { path = "../trace" } trace = { path = "../trace" }

View File

@ -276,7 +276,6 @@ mod tests {
test_helpers::{get_temp_state, get_temp_state_db} test_helpers::{get_temp_state, get_temp_state_db}
}; };
use ethtrie; use ethtrie;
use evm::CallType;
use machine::Machine; use machine::Machine;
use pod::{self, PodAccount, PodState}; use pod::{self, PodAccount, PodState};
use rustc_hex::FromHex; use rustc_hex::FromHex;
@ -324,6 +323,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 77412.into(), gas: 77412.into(),
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
creation_method: Some(trace::CreationMethod::Create),
}), }),
result: trace::Res::Create(trace::CreateResult { result: trace::Res::Create(trace::CreateResult {
gas_used: U256::from(3224), gas_used: U256::from(3224),
@ -381,6 +381,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 78792.into(), gas: 78792.into(),
init: vec![91, 96, 0, 86], init: vec![91, 96, 0, 86],
creation_method: Some(trace::CreationMethod::Create),
}), }),
result: trace::Res::FailedCreate(TraceError::OutOfGas), result: trace::Res::FailedCreate(TraceError::OutOfGas),
subtraces: 0 subtraces: 0
@ -419,7 +420,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(3), gas_used: U256::from(3),
@ -460,7 +461,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(0), gas_used: U256::from(0),
@ -501,7 +502,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 79_000.into(), gas: 79_000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(3000), gas_used: U256::from(3000),
@ -543,7 +544,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(3_721), // in post-eip150 gas_used: U256::from(3_721), // in post-eip150
@ -587,7 +588,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: 724.into(), // in post-eip150 gas_used: 724.into(), // in post-eip150
@ -602,7 +603,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 4096.into(), gas: 4096.into(),
input: vec![], input: vec![],
call_type: CallType::CallCode, call_type: Some(trace::CallType::CallCode).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: 3.into(), gas_used: 3.into(),
@ -646,7 +647,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(736), // in post-eip150 gas_used: U256::from(736), // in post-eip150
@ -661,7 +662,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 32768.into(), gas: 32768.into(),
input: vec![], input: vec![],
call_type: CallType::DelegateCall, call_type: Some(trace::CallType::DelegateCall).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: 18.into(), gas_used: 18.into(),
@ -702,7 +703,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::FailedCall(TraceError::OutOfGas), result: trace::Res::FailedCall(TraceError::OutOfGas),
subtraces: 0, subtraces: 0,
@ -744,7 +745,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(69), gas_used: U256::from(69),
@ -759,7 +760,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 78934.into(), gas: 78934.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(3), gas_used: U256::from(3),
@ -801,7 +802,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(31761), gas_used: U256::from(31761),
@ -816,7 +817,7 @@ mod tests {
value: 69.into(), value: 69.into(),
gas: 2300.into(), gas: 2300.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult::default()), result: trace::Res::Call(trace::CallResult::default()),
}]; }];
@ -855,7 +856,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(31761), gas_used: U256::from(31761),
@ -898,7 +899,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(79_000), gas_used: U256::from(79_000),
@ -913,7 +914,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 78934.into(), gas: 78934.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::FailedCall(TraceError::OutOfGas), result: trace::Res::FailedCall(TraceError::OutOfGas),
}]; }];
@ -954,7 +955,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(135), gas_used: U256::from(135),
@ -969,7 +970,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 78934.into(), gas: 78934.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(69), gas_used: U256::from(69),
@ -984,7 +985,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 78868.into(), gas: 78868.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(3), gas_used: U256::from(3),
@ -1029,7 +1030,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(79_000), gas_used: U256::from(79_000),
@ -1044,7 +1045,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 78934.into(), gas: 78934.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::FailedCall(TraceError::OutOfGas), result: trace::Res::FailedCall(TraceError::OutOfGas),
}, FlatTrace { }, FlatTrace {
@ -1055,7 +1056,7 @@ mod tests {
to: Address::from_low_u64_be(0xc), to: Address::from_low_u64_be(0xc),
value: 0.into(), value: 0.into(),
gas: 78868.into(), gas: 78868.into(),
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -1099,7 +1100,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 79000.into(), gas: 79000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: 3.into(), gas_used: 3.into(),

View File

@ -43,14 +43,14 @@ stats = { path = "../../util/stats" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" } triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" }
kvdb = "0.2" kvdb = "0.3.1"
memory-cache = { path = "../../util/memory-cache" } memory-cache = { path = "../../util/memory-cache" }
journaldb = { path = "../../util/journaldb" } journaldb = { path = "../../util/journaldb" }
verification = { path = "../verification" } verification = { path = "../verification" }
[dev-dependencies] [dev-dependencies]
ethcore = { path = "..", features = ["test-helpers"] } ethcore = { path = "..", features = ["test-helpers"] }
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"
tempdir = "0.3" tempdir = "0.3"
[features] [features]

View File

@ -220,7 +220,7 @@ impl<T: ChainDataFetcher> Client<T> {
/// Import a header to the queue for additional verification. /// Import a header to the queue for additional verification.
pub fn import_header(&self, header: Header) -> EthcoreResult<H256> { pub fn import_header(&self, header: Header) -> EthcoreResult<H256> {
self.queue.import(header).map_err(|(_, e)| e) self.queue.import(header).map_err(|(e, _)| e)
} }
/// Inquire about the status of a given header. /// Inquire about the status of a given header.

View File

@ -26,7 +26,7 @@ use rlp::RlpStream;
use log::trace; use log::trace;
use account_state::{Backend as StateBackend, State, CleanupMode}; use account_state::{Backend as StateBackend, State, CleanupMode};
use evm::{CallType, Finalize, FinalizationResult}; use evm::{ActionType, Finalize, FinalizationResult};
use vm::{ use vm::{
self, EnvInfo, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, self, EnvInfo, CreateContractAddress, ReturnData, CleanDustMode, ActionParams,
ActionValue, Schedule, TrapError, ResumeCall, ResumeCreate ActionValue, Schedule, TrapError, ResumeCall, ResumeCreate
@ -241,7 +241,7 @@ impl<'a> CallCreateExecutive<'a> {
trace!("Executive::call(params={:?}) self.env_info={:?}, parent_static={}", params, info, parent_static_flag); trace!("Executive::call(params={:?}) self.env_info={:?}, parent_static={}", params, info, parent_static_flag);
let gas = params.gas; let gas = params.gas;
let static_flag = parent_static_flag || params.call_type == CallType::StaticCall; let static_flag = parent_static_flag || params.action_type == ActionType::StaticCall;
// if destination is builtin, try to execute it // if destination is builtin, try to execute it
let kind = if let Some(builtin) = machine.builtin(&params.code_address, info.number) { let kind = if let Some(builtin) = machine.builtin(&params.code_address, info.number) {
@ -298,7 +298,7 @@ impl<'a> CallCreateExecutive<'a> {
} }
} else { } else {
if (static_flag && if (static_flag &&
(params.call_type == CallType::StaticCall || params.call_type == CallType::Call)) && (params.action_type == ActionType::StaticCall || params.action_type == ActionType::Call)) &&
params.value.value() > U256::zero() params.value.value() > U256::zero()
{ {
return Err(vm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
@ -909,7 +909,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
code: Some(Arc::new(t.data.clone())), code: Some(Arc::new(t.data.clone())),
code_version: schedule.latest_version, code_version: schedule.latest_version,
data: None, data: None,
call_type: CallType::None, action_type: ActionType::Create,
params_type: vm::ParamsType::Embedded, params_type: vm::ParamsType::Embedded,
}; };
let res = self.create(params, &mut substate, &mut tracer, &mut vm_tracer); let res = self.create(params, &mut substate, &mut tracer, &mut vm_tracer);
@ -932,7 +932,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
code_hash: self.state.code_hash(address)?, code_hash: self.state.code_hash(address)?,
code_version: self.state.code_version(address)?, code_version: self.state.code_version(address)?,
data: Some(t.data.clone()), data: Some(t.data.clone()),
call_type: CallType::Call, action_type: ActionType::Call,
params_type: vm::ParamsType::Separate, params_type: vm::ParamsType::Separate,
}; };
let res = self.call(params, &mut substate, &mut tracer, &mut vm_tracer); let res = self.call(params, &mut substate, &mut tracer, &mut vm_tracer);
@ -1236,7 +1236,7 @@ mod tests {
use parity_crypto::publickey::{Generator, Random}; use parity_crypto::publickey::{Generator, Random};
use evm::{Factory, evm_test, evm_test_ignore}; use evm::{Factory, evm_test, evm_test_ignore};
use macros::vec_into; use macros::vec_into;
use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress}; use vm::{ActionParams, ActionValue, EnvInfo, CreateContractAddress};
use ::trace::{ use ::trace::{
trace, trace,
FlatTrace, Tracer, NoopTracer, ExecutiveTracer, FlatTrace, Tracer, NoopTracer, ExecutiveTracer,
@ -1414,7 +1414,7 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100)); params.value = ActionValue::Transfer(U256::from(100));
params.call_type = CallType::Call; params.action_type = ActionType::Call;
let mut state = get_temp_state(); let mut state = get_temp_state();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
@ -1434,7 +1434,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 100_000.into(), gas: 100_000.into(),
input: vec![], input: vec![],
call_type: CallType::Call call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: 33021.into(), gas_used: 33021.into(),
@ -1449,7 +1449,7 @@ mod tests {
value: 1.into(), value: 1.into(),
gas: 66560.into(), gas: 66560.into(),
input: vec![], input: vec![],
call_type: CallType::Call call_type: Some(trace::CallType::Call).into(),
}), result: trace::Res::Call(trace::CallResult { }), result: trace::Res::Call(trace::CallResult {
gas_used: 600.into(), gas_used: 600.into(),
output: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 17, 133, 165, 197, 233, 252, 84, 97, 40, 8, 151, 126, 232, 245, 72, 178, 37, 141, 49] output: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 17, 133, 165, 197, 233, 252, 84, 97, 40, 8, 151, 126, 232, 245, 72, 178, 37, 141, 49]
@ -1498,7 +1498,7 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100)); params.value = ActionValue::Transfer(U256::from(100));
params.call_type = CallType::Call; params.action_type = ActionType::Call;
let mut state = get_temp_state(); let mut state = get_temp_state();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
@ -1524,7 +1524,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 100000.into(), gas: 100000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(55_248), gas_used: U256::from(55_248),
@ -1537,7 +1537,8 @@ mod tests {
from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(),
value: 23.into(), value: 23.into(),
gas: 67979.into(), gas: 67979.into(),
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85] init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
creation_method: Some(trace::CreationMethod::Create),
}), }),
result: trace::Res::Create(trace::CreateResult { result: trace::Res::Create(trace::CreateResult {
gas_used: U256::from(3224), gas_used: U256::from(3224),
@ -1614,7 +1615,7 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100)); params.value = ActionValue::Transfer(U256::from(100));
params.call_type = CallType::Call; params.action_type = ActionType::Call;
let mut state = get_temp_state(); let mut state = get_temp_state();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
@ -1640,7 +1641,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: 100_000.into(), gas: 100_000.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(trace::CallType::Call).into(),
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(37_033), gas_used: U256::from(37_033),
@ -1653,7 +1654,8 @@ mod tests {
from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(), from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(),
value: 23.into(), value: 23.into(),
gas: 66_917.into(), gas: 66_917.into(),
init: vec![0x60, 0x01, 0x60, 0x00, 0xfd] init: vec![0x60, 0x01, 0x60, 0x00, 0xfd],
creation_method: Some(trace::CreationMethod::Create),
}), }),
result: trace::Res::FailedCreate(vm::Error::Reverted.into()), result: trace::Res::FailedCreate(vm::Error::Reverted.into()),
}]; }];
@ -1711,6 +1713,7 @@ mod tests {
value: 100.into(), value: 100.into(),
gas: params.gas, gas: params.gas,
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
creation_method: Some(trace::CreationMethod::Create),
}), }),
result: trace::Res::Create(trace::CreateResult { result: trace::Res::Create(trace::CreateResult {
gas_used: U256::from(3224), gas_used: U256::from(3224),

View File

@ -29,7 +29,7 @@ use common_types::{
}; };
use trace::{Tracer, VMTracer}; use trace::{Tracer, VMTracer};
use vm::{ use vm::{
self, ActionParams, ActionValue, EnvInfo, CallType, Schedule, self, ActionParams, ActionValue, EnvInfo, ActionType, Schedule,
Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress,
ReturnData, TrapKind ReturnData, TrapKind
}; };
@ -193,7 +193,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
code_hash, code_hash,
code_version, code_version,
data: Some(data.as_bytes().to_vec()), data: Some(data.as_bytes().to_vec()),
call_type: CallType::Call, action_type: ActionType::Call,
params_type: vm::ParamsType::Separate, params_type: vm::ParamsType::Separate,
}; };
@ -241,6 +241,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
} }
}; };
let create_type = match address_scheme {
CreateContractAddress::FromSenderAndNonce => ActionType::Create,
CreateContractAddress::FromSenderSaltAndCodeHash(_) => ActionType::Create2,
CreateContractAddress::FromSenderAndCodeHash => ActionType::Create2,
};
// prepare the params // prepare the params
let params = ActionParams { let params = ActionParams {
code_address: address.clone(), code_address: address.clone(),
@ -254,7 +260,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
code_hash, code_hash,
code_version: *parent_version, code_version: *parent_version,
data: None, data: None,
call_type: CallType::None, action_type: create_type,
params_type: vm::ParamsType::Embedded, params_type: vm::ParamsType::Embedded,
}; };
@ -285,7 +291,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
value: Option<U256>, value: Option<U256>,
data: &[u8], data: &[u8],
code_address: &Address, code_address: &Address,
call_type: CallType, call_type: ActionType,
trap: bool, trap: bool,
) -> ::std::result::Result<MessageCallResult, TrapKind> { ) -> ::std::result::Result<MessageCallResult, TrapKind> {
trace!(target: "externalities", "call"); trace!(target: "externalities", "call");
@ -311,7 +317,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
code_hash, code_hash,
code_version, code_version,
data: Some(data.to_vec()), data: Some(data.to_vec()),
call_type, action_type: call_type,
params_type: vm::ParamsType::Separate, params_type: vm::ParamsType::Separate,
}; };
@ -457,7 +463,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
mod tests { mod tests {
use std::str::FromStr; use std::str::FromStr;
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
use evm::{EnvInfo, Ext, CallType}; use evm::{EnvInfo, Ext, ActionType};
use account_state::State; use account_state::State;
use ethcore::test_helpers::get_temp_state; use ethcore::test_helpers::get_temp_state;
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
@ -591,7 +597,7 @@ mod tests {
Some("0000000000000000000000000000000000000000000000000000000000150000".parse::<U256>().unwrap()), Some("0000000000000000000000000000000000000000000000000000000000150000".parse::<U256>().unwrap()),
&[], &[],
&Address::zero(), &Address::zero(),
CallType::Call, ActionType::Call,
false, false,
).ok().unwrap(); ).ok().unwrap();
} }

View File

@ -34,7 +34,7 @@ use common_types::{
errors::{EngineError, EthcoreError as Error}, errors::{EngineError, EthcoreError as Error},
transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction}, transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction},
}; };
use vm::{CallType, ActionParams, ActionValue, ParamsType}; use vm::{ActionType, ActionParams, ActionValue, ParamsType};
use vm::{EnvInfo, Schedule}; use vm::{EnvInfo, Schedule};
use account_state::CleanupMode; use account_state::CleanupMode;
@ -141,7 +141,7 @@ impl Machine {
value: Option<ActionValue>, value: Option<ActionValue>,
gas: U256, gas: U256,
data: Option<Vec<u8>>, data: Option<Vec<u8>>,
call_type: Option<CallType>, action_type: Option<ActionType>,
) -> Result<Vec<u8>, Error> { ) -> Result<Vec<u8>, Error> {
let env_info = { let env_info = {
let mut env_info = block.env_info(); let mut env_info = block.env_info();
@ -163,7 +163,7 @@ impl Machine {
code_hash, code_hash,
code_version: 0.into(), code_version: 0.into(),
data, data,
call_type: call_type.unwrap_or(CallType::Call), action_type: action_type.unwrap_or(ActionType::Call),
params_type: ParamsType::Separate, params_type: ParamsType::Separate,
}; };
let schedule = self.schedule(env_info.number); let schedule = self.schedule(env_info.number);

View File

@ -22,7 +22,7 @@ lru-cache = "0.1"
[dev-dependencies] [dev-dependencies]
ethcore = { path = "..", features = ["test-helpers"] } ethcore = { path = "..", features = ["test-helpers"] }
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"
ethcore-io = { path = "../../util/io" } ethcore-io = { path = "../../util/io" }
spec = { path = "../spec" } spec = { path = "../spec" }
tempdir = "0.3" tempdir = "0.3"

View File

@ -15,7 +15,7 @@ hash-db = "0.15.0"
itertools = "0.8" itertools = "0.8"
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
parity-bytes = "0.1.0" parity-bytes = "0.1.0"
rlp = "0.4" rlp = "0.4"

View File

@ -26,7 +26,7 @@ parity-util-mem = "0.3.0"
hash-db = "0.15.0" hash-db = "0.15.0"
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
machine = { path = "../machine" } machine = { path = "../machine" }
journaldb = { path = "../../util/journaldb" } journaldb = { path = "../../util/journaldb" }

View File

@ -4770,32 +4770,14 @@
"enode://4afb3a9137a88267c02651052cf6fb217931b8c78ee058bb86643542a4e2e0a8d24d47d871654e1b78a276c363f3c1bc89254a973b00adc359c9e9a48f140686@144.217.139.5:30303", "enode://4afb3a9137a88267c02651052cf6fb217931b8c78ee058bb86643542a4e2e0a8d24d47d871654e1b78a276c363f3c1bc89254a973b00adc359c9e9a48f140686@144.217.139.5:30303",
"enode://c16d390b32e6eb1c312849fe12601412313165df1a705757d671296f1ac8783c5cff09eab0118ac1f981d7148c85072f0f26407e5c68598f3ad49209fade404d@139.99.51.203:30303", "enode://c16d390b32e6eb1c312849fe12601412313165df1a705757d671296f1ac8783c5cff09eab0118ac1f981d7148c85072f0f26407e5c68598f3ad49209fade404d@139.99.51.203:30303",
"enode://4faf867a2e5e740f9b874e7c7355afee58a2d1ace79f7b692f1d553a1134eddbeb5f9210dd14dc1b774a46fd5f063a8bc1fa90579e13d9d18d1f59bac4a4b16b@139.99.160.213:30303", "enode://4faf867a2e5e740f9b874e7c7355afee58a2d1ace79f7b692f1d553a1134eddbeb5f9210dd14dc1b774a46fd5f063a8bc1fa90579e13d9d18d1f59bac4a4b16b@139.99.160.213:30303",
"enode://6a868ced2dec399c53f730261173638a93a40214cf299ccf4d42a76e3fa54701db410669e8006347a4b3a74fa090bb35af0320e4bc8d04cf5b7f582b1db285f5@163.172.131.191:30303", "enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303",
"enode://66a483383882a518fcc59db6c017f9cd13c71261f13c8d7e67ed43adbbc82a932d88d2291f59be577e9425181fc08828dc916fdd053af935a9491edf9d6006ba@212.47.247.103:30303", "enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303",
"enode://cd6611461840543d5b9c56fbf088736154c699c43973b3a1a32390cf27106f87e58a818a606ccb05f3866de95a4fe860786fea71bf891ea95f234480d3022aa3@163.172.157.114:30303", "enode://ca6de62fce278f96aea6ec5a2daadb877e51651247cb96ee310a318def462913b653963c155a0ef6c7d50048bba6e6cea881130857413d9f50a621546b590758@34.255.23.113:30303",
"enode://1d1f7bcb159d308eb2f3d5e32dc5f8786d714ec696bb2f7e3d982f9bcd04c938c139432f13aadcaf5128304a8005e8606aebf5eebd9ec192a1471c13b5e31d49@138.201.223.35:30303", "enode://279944d8dcd428dffaa7436f25ca0ca43ae19e7bcf94a8fb7d1641651f92d121e972ac2e8f381414b80cc8e5555811c2ec6e1a99bb009b3f53c4c69923e11bd8@35.158.244.151:30303",
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", "enode://8499da03c47d637b20eee24eec3c356c9a2e6148d6fe25ca195c7949ab8ec2c03e3556126b0d7ed644675e78c4318b08691b7b57de10e5f0d40d05b09238fa0a@52.187.207.27:30303",
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303", "enode://103858bdb88756c71f15e9b5e09b56dc1be52f0a5021d46301dbbfb7e130029cc9d0d6f73f693bc29b665770fff7da4d34f3c6379fe12721b5d7a0bcb5ca1fc1@191.234.162.198:30303",
"enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303", "enode://715171f50508aba88aecd1250af392a45a330af91d7b90701c436b618c86aaa1589c9184561907bebbb56439b8f8787bc01f49a7c77276c58c1b09822d75e8e8@52.231.165.108:30303",
"enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303", "enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303"
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
"enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303",
"enode://0cc5f5ffb5d9098c8b8c62325f3797f56509bff942704687b6530992ac706e2cb946b90a34f1f19548cd3c7baccbcaea354531e5983c7d1bc0dee16ce4b6440b@40.118.3.223:30305",
"enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30308",
"enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30309",
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303",
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
"enode://2c9059f05c352b29d559192fe6bca272d965c9f2290632a2cfda7f83da7d2634f3ec45ae3a72c54dd4204926fb8082dcf9686e0d7504257541c86fc8569bcf4b@163.172.171.38:30303",
"enode://efe4f2493f4aff2d641b1db8366b96ddacfe13e7a6e9c8f8f8cf49f9cdba0fdf3258d8c8f8d0c5db529f8123c8f1d95f36d54d590ca1bb366a5818b9a4ba521c@163.172.187.252:30303",
"enode://bcc7240543fe2cf86f5e9093d05753dd83343f8fda7bf0e833f65985c73afccf8f981301e13ef49c4804491eab043647374df1c4adf85766af88a624ecc3330e@136.243.154.244:30303",
"enode://ed4227681ca8c70beb2277b9e870353a9693f12e7c548c35df6bca6a956934d6f659999c2decb31f75ce217822eefca149ace914f1cbe461ed5a2ebaf9501455@88.212.206.70:30303",
"enode://cadc6e573b6bc2a9128f2f635ac0db3353e360b56deef239e9be7e7fce039502e0ec670b595f6288c0d2116812516ad6b6ff8d5728ff45eba176989e40dead1e@37.128.191.230:30303",
"enode://595a9a06f8b9bc9835c8723b6a82105aea5d55c66b029b6d44f229d6d135ac3ecdd3e9309360a961ea39d7bee7bac5d03564077a4e08823acc723370aace65ec@46.20.235.22:30303",
"enode://029178d6d6f9f8026fc0bc17d5d1401aac76ec9d86633bba2320b5eed7b312980c0a210b74b20c4f9a8b0b2bf884b111fa9ea5c5f916bb9bbc0e0c8640a0f56c@216.158.85.185:30303",
"enode://fdd1b9bb613cfbc200bba17ce199a9490edc752a833f88d4134bf52bb0d858aa5524cb3ec9366c7a4ef4637754b8b15b5dc913e4ed9fdb6022f7512d7b63f181@212.47.247.103:30303",
"enode://cc26c9671dffd3ee8388a7c8c5b601ae9fe75fc0a85cedb72d2dd733d5916fad1d4f0dcbebad5f9518b39cc1f96ba214ab36a7fa5103aaf17294af92a89f227b@52.79.241.155:30303",
"enode://140872ce4eee37177fbb7a3c3aa4aaebe3f30bdbf814dd112f6c364fc2e325ba2b6a942f7296677adcdf753c33170cb4999d2573b5ff7197b4c1868f25727e45@52.78.149.82:30303"
], ],
"accounts": { "accounts": {
"0x0000000000000000000000000000000000000001": { "0x0000000000000000000000000000000000000001": {

View File

@ -55,7 +55,7 @@
"nodes": [ "nodes": [
"enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303", "enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303",
"enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303", "enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303",
"enode://573b6607cd59f241e30e4c4943fd50e99e2b6f42f9bd5ca111659d309c06741247f4f1e93843ad3e8c8c18b6e2d94c161b7ef67479b3938780a97134b618b5ce@52.56.136.200:30303", "enode://a61215641fb8714a373c80edbfa0ea8878243193f57c96eeb44d0bc019ef295abd4e044fd619bfc4c59731a73fb79afe84e9ab6da0c743ceb479cbb6d263fa91@3.11.147.67:30303",
"enode://67913271d14f445689e8310270c304d42f268428f2de7a4ac0275bea97690e021df6f549f462503ff4c7a81d9dd27288867bbfa2271477d0911378b8944fae55@157.230.239.163:30303", "enode://67913271d14f445689e8310270c304d42f268428f2de7a4ac0275bea97690e021df6f549f462503ff4c7a81d9dd27288867bbfa2271477d0911378b8944fae55@157.230.239.163:30303",
"enode://a87685902a0622e9cf18c68e73a0ea45156ec53e857ef049b185a9db2296ca04d776417bf1901c0b4eacb5b26271d8694e88e3f17c20d49eb77e1a41ab26b5b3@51.141.78.53:30303", "enode://a87685902a0622e9cf18c68e73a0ea45156ec53e857ef049b185a9db2296ca04d776417bf1901c0b4eacb5b26271d8694e88e3f17c20d49eb77e1a41ab26b5b3@51.141.78.53:30303",
"enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303", "enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303",

View File

@ -54,7 +54,8 @@
"enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303", "enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303",
"enode://93c94e999be5dd854c5d82a7cf5c14822973b5d9badb56ad4974586ec4d4f1995c815af795c20bb6e0a6226d3ee55808435c4dc89baf94ee581141b064d19dfc@80.187.116.161:25720", "enode://93c94e999be5dd854c5d82a7cf5c14822973b5d9badb56ad4974586ec4d4f1995c815af795c20bb6e0a6226d3ee55808435c4dc89baf94ee581141b064d19dfc@80.187.116.161:25720",
"enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303", "enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303",
"enode://b477ca6d507a3f57070783eb62ba838847635f8b1a0cbffb8b7f8173f5894cf550f0225a5c279341e2d862a606e778b57180a4f1db3db78c51eadcfa4fdc6963@40.68.240.160:30303" "enode://b477ca6d507a3f57070783eb62ba838847635f8b1a0cbffb8b7f8173f5894cf550f0225a5c279341e2d862a606e778b57180a4f1db3db78c51eadcfa4fdc6963@40.68.240.160:30303",
"enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.158.191.43:37956"
], ],
"accounts": { "accounts": {
"0x0000000000000000000000000000000000000000": { "0x0000000000000000000000000000000000000000": {

View File

@ -59,14 +59,16 @@
"gasLimit":"0x2fefd8" "gasLimit":"0x2fefd8"
}, },
"nodes":[ "nodes":[
"enode://03b133f731049e3f7be827339c3759be92778c05e54a1847d178c0fdb56fa168aa1e7e61fc77791a7afdd0328a00318f73c01212eb3f3bbe919f5ce8f5b4a314@192.227.105.4:32000",
"enode://06fdbeb591d26f53b2e7250025fe955ca013431ded930920cf1e3cd1f0c920e9a5e727949d209bc25a07288327b525279b11c5551315c50ff0db483e69fc159b@34.218.225.178:32000",
"enode://1813e90a0afdd7c1e4892c5376960e3577a9e6c5a4f86fa405a405c7421a4a1608248d77cc90333842f13d8954d82113dec480cfb76b4fef8cb475157cf4d5f2@10.28.224.3:30000",
"enode://2b69a3926f36a7748c9021c34050be5e0b64346225e477fe7377070f6289bd363b2be73a06010fd516e6ea3ee90778dd0399bc007bb1281923a79374f842675a@51.15.116.226:30303", "enode://2b69a3926f36a7748c9021c34050be5e0b64346225e477fe7377070f6289bd363b2be73a06010fd516e6ea3ee90778dd0399bc007bb1281923a79374f842675a@51.15.116.226:30303",
"enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.158.191.43:38556",
"enode://5a1399e6ba3268721dd7656530cd81230dbeb950570c6e3ec2a45effc50c032f66633c5eaaa1a49c51ba1849db37a7bef6e402779ad12dc9943f117e058d7760@34.69.121.227:30303",
"enode://03b133f731049e3f7be827339c3759be92778c05e54a1847d178c0fdb56fa168aa1e7e61fc77791a7afdd0328a00318f73c01212eb3f3bbe919f5ce8f5b4a314@192.227.105.4:32000",
"enode://621e28e529146fd501709194885f50540c494f1a2985d1fb4ec8769226b5cb0b0d1a11545926077821474c2767cdd87888ead8a2509a2c9069dd5584e4b1c3b8@10.28.223.8:30000", "enode://621e28e529146fd501709194885f50540c494f1a2985d1fb4ec8769226b5cb0b0d1a11545926077821474c2767cdd87888ead8a2509a2c9069dd5584e4b1c3b8@10.28.223.8:30000",
"enode://2592745efd35b4be443b8ee25fd2099de132e037951f9f6d3e8805e0a78f213537f71264b973f1a83a57372f57bbe6acac8d6ae678f39393221c045ccbe3b18c@51.15.116.226:30304",
"enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.15.116.226:30303", "enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.15.116.226:30303",
"enode://f840b007500f50c98ea6f9c9e56dabf4690bbbbb7036d43682c531204341aff8315013547e5bee54117eb22bd3603585ae6bf713d9fa710659533fcab65d5b84@35.238.101.58:30000", "enode://f840b007500f50c98ea6f9c9e56dabf4690bbbbb7036d43682c531204341aff8315013547e5bee54117eb22bd3603585ae6bf713d9fa710659533fcab65d5b84@35.238.101.58:30303",
"enode://19eda672030ad5debb98c9069b3e99d12438b96506325d9f3f82d76c5f8ce4942d345f41700a5223900e75ad48e76713b74c1b694d67a10c2112540035922256@35.238.101.58:30000" "enode://1813e90a0afdd7c1e4892c5376960e3577a9e6c5a4f86fa405a405c7421a4a1608248d77cc90333842f13d8954d82113dec480cfb76b4fef8cb475157cf4d5f2@10.28.224.3:30000",
"enode://06fdbeb591d26f53b2e7250025fe955ca013431ded930920cf1e3cd1f0c920e9a5e727949d209bc25a07288327b525279b11c5551315c50ff0db483e69fc159b@34.218.225.178:32000"
], ],
"accounts":{ "accounts":{
"0x0000000000000000000000000000000000000001":{ "0x0000000000000000000000000000000000000001":{

View File

@ -14,7 +14,7 @@ ethcore-io = { path = "../../util/io" }
ethcore-private-tx = { path = "../private-tx" } ethcore-private-tx = { path = "../private-tx" }
ethcore-sync = { path = "../sync" } ethcore-sync = { path = "../sync" }
ethereum-types = "0.8.0" ethereum-types = "0.8.0"
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
snapshot = { path = "../snapshot" } snapshot = { path = "../snapshot" }
spec = { path = "../spec" } spec = { path = "../spec" }
@ -23,5 +23,5 @@ trace-time = "0.1"
[dev-dependencies] [dev-dependencies]
ethcore = { path = "..", features = ["test-helpers"] } ethcore = { path = "..", features = ["test-helpers"] }
ethcore-db = { path = "../db" } ethcore-db = { path = "../db" }
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"
tempdir = "0.3" tempdir = "0.3"

View File

@ -29,7 +29,7 @@ itertools = "0.5"
journaldb = { path = "../../util/journaldb" } journaldb = { path = "../../util/journaldb" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4.8" log = "0.4.8"
num_cpus = "1.10.1" num_cpus = "1.10.1"
rand = "0.7" rand = "0.7"
@ -53,7 +53,7 @@ ethabi-contract = "9.0.0"
ethabi-derive = "9.0.1" ethabi-derive = "9.0.1"
ethcore = { path = "..", features = ["test-helpers"] } ethcore = { path = "..", features = ["test-helpers"] }
ethkey = { path = "../../accounts/ethkey" } ethkey = { path = "../../accounts/ethkey" }
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"
lazy_static = { version = "1.3" } lazy_static = { version = "1.3" }
spec = { path = "../spec" } spec = { path = "../spec" }
tempdir = "0.3" tempdir = "0.3"

View File

@ -23,8 +23,8 @@ hash-db = "0.15.0"
journaldb = { path = "../../../util/journaldb" } journaldb = { path = "../../../util/journaldb" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../../util/keccak-hasher" } keccak-hasher = { path = "../../../util/keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"
log = "0.4.8" log = "0.4.8"
parking_lot = "0.9" parking_lot = "0.9"
parity-crypto = { version = "0.4.2", features = ["publickey"] } parity-crypto = { version = "0.4.2", features = ["publickey"] }

View File

@ -25,7 +25,7 @@ hash-db = "0.15.0"
instant-seal = { path = "../engines/instant-seal" } instant-seal = { path = "../engines/instant-seal" }
journaldb = { path = "../../util/journaldb" } journaldb = { path = "../../util/journaldb" }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"
log = "0.4.8" log = "0.4.8"
machine = { path = "../machine" } machine = { path = "../machine" }
null-engine = { path = "../engines/null-engine" } null-engine = { path = "../engines/null-engine" }

View File

@ -52,7 +52,7 @@ use pod::PodState;
use rlp::{Rlp, RlpStream}; use rlp::{Rlp, RlpStream};
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
use trie_vm_factories::Factories; use trie_vm_factories::Factories;
use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType}; use vm::{EnvInfo, ActionType, ActionValue, ActionParams, ParamsType};
use crate::{ use crate::{
Genesis, Genesis,
@ -163,7 +163,7 @@ fn run_constructors<T: Backend>(
value: ActionValue::Transfer(Default::default()), value: ActionValue::Transfer(Default::default()),
code: Some(Arc::new(constructor.clone())), code: Some(Arc::new(constructor.clone())),
data: None, data: None,
call_type: CallType::None, action_type: ActionType::Create,
params_type: ParamsType::Embedded, params_type: ParamsType::Embedded,
}; };
@ -250,9 +250,10 @@ impl From<ethjson::spec::HardcodedSync> for SpecHardcodedSync {
impl fmt::Display for SpecHardcodedSync { impl fmt::Display for SpecHardcodedSync {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "{{")?; writeln!(f, "{{")?;
writeln!(f, r#"header": "{:?},"#, self.header)?; writeln!(f, r#""header": "{:x}","#, self.header)?;
writeln!(f, r#"total_difficulty": "{:?},"#, self.total_difficulty)?; writeln!(f, r#""totalDifficulty": "{:?}""#, self.total_difficulty)?;
writeln!(f, r#"chts": {:#?}"#, self.chts.iter().map(|x| format!(r#"{:?}"#, x)).collect::<Vec<_>>())?; // TODO: #11415 - fix trailing comma for CHTs
writeln!(f, r#""CHTs": {:#?}"#, self.chts.iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>())?;
writeln!(f, "}}") writeln!(f, "}}")
} }
} }

View File

@ -262,7 +262,7 @@ impl Importer {
let block_queue = BlockQueue::new( let block_queue = BlockQueue::new(
config.queue.clone(), config.queue.clone(),
engine.clone(), engine.clone(),
message_channel.clone(), message_channel,
config.verifier_type.verifying_seal() config.verifier_type.verifying_seal()
); );
@ -404,11 +404,11 @@ impl Importer {
let verify_external_result = engine.verify_block_external(&header); let verify_external_result = engine.verify_block_external(&header);
if let Err(e) = verify_external_result { if let Err(e) = verify_external_result {
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
return Err(e.into()); return Err(e);
}; };
// Enact Verified Block // Enact Verified Block
let last_hashes = client.build_last_hashes(header.parent_hash()); let last_hashes = client.build_last_hashes(*header.parent_hash());
let db = client.state_db.read().boxed_clone_canon(header.parent_hash()); let db = client.state_db.read().boxed_clone_canon(header.parent_hash());
let is_epoch_begin = chain.epoch_transition(parent.number(), *header.parent_hash()).is_some(); let is_epoch_begin = chain.epoch_transition(parent.number(), *header.parent_hash()).is_some();
@ -428,7 +428,7 @@ impl Importer {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
return Err(e.into()); return Err(e);
} }
}; };
@ -444,7 +444,7 @@ impl Importer {
// Final Verification // Final Verification
if let Err(e) = verification::verify_block_final(&header, &locked_block.header) { if let Err(e) = verification::verify_block_final(&header, &locked_block.header) {
warn!(target: "client", "Stage 5 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); warn!(target: "client", "Stage 5 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
return Err(e.into()); return Err(e);
} }
let pending = self.check_epoch_end_signal( let pending = self.check_epoch_end_signal(
@ -562,14 +562,14 @@ impl Importer {
a a
}).collect(); }).collect();
let route = chain.insert_block(&mut batch, block_data, receipts.clone(), ExtrasInsert { let route = chain.insert_block(&mut batch, block_data, receipts, ExtrasInsert {
fork_choice, fork_choice,
is_finalized, is_finalized,
}); });
client.tracedb.read().import(&mut batch, TraceImportRequest { client.tracedb.read().import(&mut batch, TraceImportRequest {
traces: traces.into(), traces: traces.into(),
block_hash: hash.clone(), block_hash: *hash,
block_number: number, block_number: number,
enacted: route.enacted.clone(), enacted: route.enacted.clone(),
retracted: route.retracted.len() retracted: route.retracted.len()
@ -619,10 +619,10 @@ impl Importer {
Proof::WithState(with_state) => { Proof::WithState(with_state) => {
let env_info = EnvInfo { let env_info = EnvInfo {
number: header.number(), number: header.number(),
author: header.author().clone(), author: *header.author(),
timestamp: header.timestamp(), timestamp: header.timestamp(),
difficulty: header.difficulty().clone(), difficulty: *header.difficulty(),
last_hashes: client.build_last_hashes(header.parent_hash()), last_hashes: client.build_last_hashes(*header.parent_hash()),
gas_used: U256::default(), gas_used: U256::default(),
gas_limit: u64::max_value().into(), gas_limit: u64::max_value().into(),
}; };
@ -636,7 +636,7 @@ impl Importer {
let mut state = State::from_existing( let mut state = State::from_existing(
backend, backend,
header.state_root().clone(), *header.state_root(),
self.engine.account_start_nonce(header.number()), self.engine.account_start_nonce(header.number()),
client.factories.clone(), client.factories.clone(),
).expect("state known to be available for just-imported block; qed"); ).expect("state known to be available for just-imported block; qed");
@ -669,7 +669,7 @@ impl Importer {
debug!(target: "client", "Block {} signals epoch end.", hash); debug!(target: "client", "Block {} signals epoch end.", hash);
Ok(Some(PendingTransition { proof: proof })) Ok(Some(PendingTransition { proof }))
}, },
EpochChange::No => Ok(None), EpochChange::No => Ok(None),
EpochChange::Unsure(_) => { EpochChange::Unsure(_) => {
@ -777,7 +777,7 @@ impl Client {
chain: RwLock::new(chain), chain: RwLock::new(chain),
tracedb, tracedb,
engine, engine,
pruning: config.pruning.clone(), pruning: config.pruning,
snapshotting_at: AtomicU64::new(0), snapshotting_at: AtomicU64::new(0),
db: RwLock::new(db.clone()), db: RwLock::new(db.clone()),
state_db: RwLock::new(state_db), state_db: RwLock::new(state_db),
@ -824,7 +824,7 @@ impl Client {
chain.insert_epoch_transition(&mut batch, 0, EpochTransition { chain.insert_epoch_transition(&mut batch, 0, EpochTransition {
block_hash: gh.hash(), block_hash: gh.hash(),
block_number: 0, block_number: 0,
proof: proof, proof,
}); });
client.db.read().key_value().write_buffered(batch); client.db.read().key_value().write_buffered(batch);
@ -901,17 +901,17 @@ impl Client {
author: header.author(), author: header.author(),
timestamp: header.timestamp(), timestamp: header.timestamp(),
difficulty: header.difficulty(), difficulty: header.difficulty(),
last_hashes: self.build_last_hashes(&header.parent_hash()), last_hashes: self.build_last_hashes(header.parent_hash()),
gas_used: U256::default(), gas_used: U256::default(),
gas_limit: header.gas_limit(), gas_limit: header.gas_limit(),
} }
}) })
} }
fn build_last_hashes(&self, parent_hash: &H256) -> Arc<LastHashes> { fn build_last_hashes(&self, parent_hash: H256) -> Arc<LastHashes> {
{ {
let hashes = self.last_hashes.read(); let hashes = self.last_hashes.read();
if hashes.front().map_or(false, |h| h == parent_hash) { if hashes.front().map_or(false, |h| h == &parent_hash) {
let mut res = Vec::from(hashes.clone()); let mut res = Vec::from(hashes.clone());
res.resize(256, H256::zero()); res.resize(256, H256::zero());
return Arc::new(res); return Arc::new(res);
@ -919,12 +919,12 @@ impl Client {
} }
let mut last_hashes = LastHashes::new(); let mut last_hashes = LastHashes::new();
last_hashes.resize(256, H256::zero()); last_hashes.resize(256, H256::zero());
last_hashes[0] = parent_hash.clone(); last_hashes[0] = parent_hash;
let chain = self.chain.read(); let chain = self.chain.read();
for i in 0..255 { for i in 0..255 {
match chain.block_details(&last_hashes[i]) { match chain.block_details(&last_hashes[i]) {
Some(details) => { Some(details) => {
last_hashes[i + 1] = details.parent.clone(); last_hashes[i + 1] = details.parent;
}, },
None => break, None => break,
} }
@ -941,7 +941,7 @@ impl Client {
let call = |a, d| { let call = |a, d| {
let tx = self.contract_call_tx(id, a, d); let tx = self.contract_call_tx(id, a, d);
let (result, items) = self.prove_transaction(tx, id) let (result, items) = self.prove_transaction(tx, id)
.ok_or_else(|| format!("Unable to make call. State unavailable?"))?; .ok_or_else(|| "Unable to make call. State unavailable?".to_string())?;
let items = items.into_iter().map(|x| x.to_vec()).collect(); let items = items.into_iter().map(|x| x.to_vec()).collect();
Ok((result, items)) Ok((result, items))
@ -1296,7 +1296,11 @@ impl DatabaseRestore for Client {
impl BlockChainReset for Client { impl BlockChainReset for Client {
fn reset(&self, num: u32) -> Result<(), String> { fn reset(&self, num: u32) -> Result<(), String> {
if num as u64 > self.pruning_history() { if num as u64 > self.pruning_history() {
return Err(format!("Attempting to reset the chain {} blocks back failed: state is pruned (max available: {})", num, self.pruning_history()).into()) return Err(
format!("Attempting to reset the chain {} blocks back failed: state is pruned (max available: {})",
num,
self.pruning_history()
));
} else if num == 0 { } else if num == 0 {
return Err("0 is an invalid number of blocks to reset".into()) return Err("0 is an invalid number of blocks to reset".into())
} }
@ -1450,26 +1454,28 @@ impl ImportBlock for Client {
} }
let raw = if self.importer.block_queue.is_empty() { let raw = if self.importer.block_queue.is_empty() {
Some(( Some((unverified.bytes.clone(), *unverified.header.difficulty()))
unverified.bytes.clone(), } else {
unverified.header.hash(), None
*unverified.header.difficulty(), };
))
} else { None };
match self.importer.block_queue.import(unverified) { match self.importer.block_queue.import(unverified) {
Ok(hash) => { Ok(hash) => {
if let Some((raw, hash, difficulty)) = raw { if let Some((bytes, difficulty)) = raw {
self.notify(move |n| n.block_pre_import(&raw, &hash, &difficulty)); self.notify(move |n| n.block_pre_import(&bytes, &hash, &difficulty));
} }
Ok(hash) Ok(hash)
}, },
// we only care about block errors (not import errors) // we only care about block errors (not import errors)
Err((block, EthcoreError::Block(err))) => { Err((EthcoreError::Block(e), Some(input))) => {
self.importer.bad_blocks.report(block.bytes, format!("{:?}", err)); self.importer.bad_blocks.report(input.bytes, e.to_string());
return Err(EthcoreError::Block(err)) Err(EthcoreError::Block(e))
}, },
Err((_, e)) => Err(e), Err((EthcoreError::Block(e), None)) => {
error!(target: "client", "BlockError {} detected but it was missing raw_bytes of the block", e);
Err(EthcoreError::Block(e))
}
Err((e, _input)) => Err(e),
} }
} }
@ -1497,10 +1503,10 @@ impl Call for Client {
fn call(&self, transaction: &SignedTransaction, analytics: CallAnalytics, state: &mut Self::State, header: &Header) -> Result<Executed, CallError> { fn call(&self, transaction: &SignedTransaction, analytics: CallAnalytics, state: &mut Self::State, header: &Header) -> Result<Executed, CallError> {
let env_info = EnvInfo { let env_info = EnvInfo {
number: header.number(), number: header.number(),
author: header.author().clone(), author: *header.author(),
timestamp: header.timestamp(), timestamp: header.timestamp(),
difficulty: header.difficulty().clone(), difficulty: *header.difficulty(),
last_hashes: self.build_last_hashes(header.parent_hash()), last_hashes: self.build_last_hashes(*header.parent_hash()),
gas_used: U256::default(), gas_used: U256::default(),
gas_limit: U256::max_value(), gas_limit: U256::max_value(),
}; };
@ -1512,10 +1518,10 @@ impl Call for Client {
fn call_many(&self, transactions: &[(SignedTransaction, CallAnalytics)], state: &mut Self::State, header: &Header) -> Result<Vec<Executed>, CallError> { fn call_many(&self, transactions: &[(SignedTransaction, CallAnalytics)], state: &mut Self::State, header: &Header) -> Result<Vec<Executed>, CallError> {
let mut env_info = EnvInfo { let mut env_info = EnvInfo {
number: header.number(), number: header.number(),
author: header.author().clone(), author: *header.author(),
timestamp: header.timestamp(), timestamp: header.timestamp(),
difficulty: header.difficulty().clone(), difficulty: *header.difficulty(),
last_hashes: self.build_last_hashes(header.parent_hash()), last_hashes: self.build_last_hashes(*header.parent_hash()),
gas_used: U256::default(), gas_used: U256::default(),
gas_limit: U256::max_value(), gas_limit: U256::max_value(),
}; };
@ -1539,10 +1545,10 @@ impl Call for Client {
let env_info = EnvInfo { let env_info = EnvInfo {
number: header.number(), number: header.number(),
author: header.author().clone(), author: *header.author(),
timestamp: header.timestamp(), timestamp: header.timestamp(),
difficulty: header.difficulty().clone(), difficulty: *header.difficulty(),
last_hashes: self.build_last_hashes(header.parent_hash()), last_hashes: self.build_last_hashes(*header.parent_hash()),
gas_used: U256::default(), gas_used: U256::default(),
gas_limit: max, gas_limit: max,
}; };
@ -1634,7 +1640,7 @@ impl BlockChainClient for Client {
let address = self.transaction_address(id).ok_or_else(|| CallError::TransactionNotFound)?; let address = self.transaction_address(id).ok_or_else(|| CallError::TransactionNotFound)?;
let block = BlockId::Hash(address.block_hash); let block = BlockId::Hash(address.block_hash);
const PROOF: &'static str = "The transaction address contains a valid index within block; qed"; const PROOF: &str = "The transaction address contains a valid index within block; qed";
Ok(self.replay_block_transactions(block, analytics)?.nth(address.index).expect(PROOF).1) Ok(self.replay_block_transactions(block, analytics)?.nth(address.index).expect(PROOF).1)
} }
@ -1645,8 +1651,8 @@ impl BlockChainClient for Client {
let txs = body.transactions(); let txs = body.transactions();
let engine = self.engine.clone(); let engine = self.engine.clone();
const PROOF: &'static str = "Transactions fetched from blockchain; blockchain transactions are valid; qed"; const PROOF: &str = "Transactions fetched from blockchain; blockchain transactions are valid; qed";
const EXECUTE_PROOF: &'static str = "Transaction replayed; qed"; const EXECUTE_PROOF: &str = "Transaction replayed; qed";
Ok(Box::new(txs.into_iter() Ok(Box::new(txs.into_iter()
.map(move |t| { .map(move |t| {
@ -1660,9 +1666,7 @@ impl BlockChainClient for Client {
} }
fn mode(&self) -> Mode { fn mode(&self) -> Mode {
let r = self.mode.lock().clone().into(); self.mode.lock().clone()
trace!(target: "mode", "Asked for mode = {:?}. returning {:?}", &*self.mode.lock(), r);
r
} }
fn queue_info(&self) -> BlockQueueInfo { fn queue_info(&self) -> BlockQueueInfo {
@ -1682,7 +1686,7 @@ impl BlockChainClient for Client {
} }
{ {
let mut mode = self.mode.lock(); let mut mode = self.mode.lock();
*mode = new_mode.clone().into(); *mode = new_mode.clone();
trace!(target: "mode", "Mode now {:?}", &*mode); trace!(target: "mode", "Mode now {:?}", &*mode);
if let Some(ref mut f) = *self.on_user_defaults_change.lock() { if let Some(ref mut f) = *self.on_user_defaults_change.lock() {
trace!(target: "mode", "Making callback..."); trace!(target: "mode", "Making callback...");
@ -1972,17 +1976,17 @@ impl BlockChainClient for Client {
// pending logs themselves). // pending logs themselves).
let from = match self.block_number_ref(&filter.from_block) { let from = match self.block_number_ref(&filter.from_block) {
Some(val) if val <= chain.best_block_number() => val, Some(val) if val <= chain.best_block_number() => val,
_ => return Err(filter.from_block.clone()), _ => return Err(filter.from_block),
}; };
let to = match self.block_number_ref(&filter.to_block) { let to = match self.block_number_ref(&filter.to_block) {
Some(val) if val <= chain.best_block_number() => val, Some(val) if val <= chain.best_block_number() => val,
_ => return Err(filter.to_block.clone()), _ => return Err(filter.to_block),
}; };
// If from is greater than to, then the current bloom filter behavior is to just return empty // If from is greater than to, then the current bloom filter behavior is to just return empty
// result. There's no point to continue here. // result. There's no point to continue here.
if from > to { if from > to {
return Err(filter.to_block.clone()); return Err(filter.to_block);
} }
chain.blocks_with_bloom(&filter.bloom_possibilities(), from, to) chain.blocks_with_bloom(&filter.bloom_possibilities(), from, to)
@ -1993,7 +1997,7 @@ impl BlockChainClient for Client {
// Otherwise, we use a slower version that finds a link between from_block and to_block. // Otherwise, we use a slower version that finds a link between from_block and to_block.
let from_hash = match Self::block_hash(&chain, filter.from_block) { let from_hash = match Self::block_hash(&chain, filter.from_block) {
Some(val) => val, Some(val) => val,
None => return Err(filter.from_block.clone()), None => return Err(filter.from_block),
}; };
let from_number = match chain.block_number(&from_hash) { let from_number = match chain.block_number(&from_hash) {
Some(val) => val, Some(val) => val,
@ -2001,7 +2005,7 @@ impl BlockChainClient for Client {
}; };
let to_hash = match Self::block_hash(&chain, filter.to_block) { let to_hash = match Self::block_hash(&chain, filter.to_block) {
Some(val) => val, Some(val) => val,
None => return Err(filter.to_block.clone()), None => return Err(filter.to_block),
}; };
let blooms = filter.bloom_possibilities(); let blooms = filter.bloom_possibilities();
@ -2103,7 +2107,7 @@ impl BlockChainClient for Client {
} }
fn last_hashes(&self) -> LastHashes { fn last_hashes(&self) -> LastHashes {
(*self.build_last_hashes(&self.chain.read().best_block_hash())).clone() self.build_last_hashes(self.chain.read().best_block_hash()).to_vec()
} }
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>> { fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>> {
@ -2338,7 +2342,7 @@ impl PrepareOpenBlock for Client {
self.tracedb.read().tracing_enabled(), self.tracedb.read().tracing_enabled(),
self.state_db.read().boxed_clone_canon(&h), self.state_db.read().boxed_clone_canon(&h),
&best_header, &best_header,
self.build_last_hashes(&h), self.build_last_hashes(h),
author, author,
gas_range_target, gas_range_target,
extra_data, extra_data,
@ -2388,7 +2392,7 @@ impl ImportSealedBlock for Client {
block.rlp_bytes(), block.rlp_bytes(),
format!("Detected an issue with locally sealed block: {}", e), format!("Detected an issue with locally sealed block: {}", e),
); );
return Err(e.into()); return Err(e);
} }
// scope for self.import_lock // scope for self.import_lock
@ -2517,12 +2521,12 @@ impl ProvingBlockChainClient for Client {
_ => return None, _ => return None,
}; };
env_info.gas_limit = transaction.gas.clone(); env_info.gas_limit = transaction.gas;
let mut jdb = self.state_db.read().journal_db().boxed_clone(); let mut jdb = self.state_db.read().journal_db().boxed_clone();
executive_state::prove_transaction_virtual( executive_state::prove_transaction_virtual(
jdb.as_hash_db_mut(), jdb.as_hash_db_mut(),
header.state_root().clone(), header.state_root(),
&transaction, &transaction,
self.engine.machine(), self.engine.machine(),
&env_info, &env_info,
@ -2758,12 +2762,12 @@ fn transaction_receipt(
from: sender, from: sender,
to: match tx.action { to: match tx.action {
Action::Create => None, Action::Create => None,
Action::Call(ref address) => Some(address.clone().into()) Action::Call(ref address) => Some(*address)
}, },
transaction_hash: transaction_hash, transaction_hash,
transaction_index: transaction_index, transaction_index,
block_hash: block_hash, block_hash,
block_number: block_number, block_number,
cumulative_gas_used: receipt.gas_used, cumulative_gas_used: receipt.gas_used,
gas_used: receipt.gas_used - prior_gas_used, gas_used: receipt.gas_used - prior_gas_used,
contract_address: match tx.action { contract_address: match tx.action {
@ -2772,10 +2776,10 @@ fn transaction_receipt(
}, },
logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry { logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry {
entry: log, entry: log,
block_hash: block_hash, block_hash,
block_number: block_number, block_number,
transaction_hash: transaction_hash, transaction_hash,
transaction_index: transaction_index, transaction_index,
transaction_log_index: i, transaction_log_index: i,
log_index: prior_no_of_logs + i, log_index: prior_no_of_logs + i,
}).collect(), }).collect(),
@ -2921,8 +2925,8 @@ mod tests {
let tx1 = raw_tx.clone().sign(secret, None); let tx1 = raw_tx.clone().sign(secret, None);
let transaction = LocalizedTransaction { let transaction = LocalizedTransaction {
signed: tx1.clone().into(), signed: tx1.clone().into(),
block_number: block_number, block_number,
block_hash: block_hash, block_hash,
transaction_index: 1, transaction_index: 1,
cached_sender: Some(tx1.sender()), cached_sender: Some(tx1.sender()),
}; };
@ -2937,7 +2941,7 @@ mod tests {
}]; }];
let receipt = Receipt { let receipt = Receipt {
outcome: TransactionOutcome::StateRoot(state_root), outcome: TransactionOutcome::StateRoot(state_root),
gas_used: gas_used, gas_used,
log_bloom: Default::default(), log_bloom: Default::default(),
logs: logs.clone(), logs: logs.clone(),
}; };

View File

@ -20,7 +20,7 @@ use super::test_common::*;
use account_state::{Backend as StateBackend, State}; use account_state::{Backend as StateBackend, State};
use evm::Finalize; use evm::Finalize;
use vm::{ use vm::{
self, ActionParams, CallType, Schedule, Ext, self, ActionParams, ActionType, Schedule, Ext,
ContractCreateResult, EnvInfo, MessageCallResult, ContractCreateResult, EnvInfo, MessageCallResult,
CreateContractAddress, ReturnData, CreateContractAddress, ReturnData,
}; };
@ -172,7 +172,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
value: Option<U256>, value: Option<U256>,
data: &[u8], data: &[u8],
_code_address: &Address, _code_address: &Address,
_call_type: CallType, _call_type: ActionType,
_trap: bool _trap: bool
) -> Result<MessageCallResult, vm::TrapKind> { ) -> Result<MessageCallResult, vm::TrapKind> {
self.callcreates.push(CallCreate { self.callcreates.push(CallCreate {

View File

@ -18,7 +18,7 @@
use std::sync::Arc; use std::sync::Arc;
use hash::keccak; use hash::keccak;
use vm::{EnvInfo, ActionParams, ActionValue, CallType, ParamsType}; use vm::{EnvInfo, ActionParams, ActionValue, ActionType, ParamsType};
use evm::Factory; use evm::Factory;
use machine::{ use machine::{
executive::Executive, executive::Executive,
@ -62,7 +62,7 @@ fn test_blockhash_eip210(factory: Factory) {
code_hash: Some(blockhash_contract_code_hash), code_hash: Some(blockhash_contract_code_hash),
code_version: 0.into(), code_version: 0.into(),
data: Some(H256::from_low_u64_be(i - 1).as_bytes().to_vec()), data: Some(H256::from_low_u64_be(i - 1).as_bytes().to_vec()),
call_type: CallType::Call, action_type: ActionType::Call,
params_type: ParamsType::Separate, params_type: ParamsType::Separate,
}; };
let schedule = machine.schedule(env_info.number); let schedule = machine.schedule(env_info.number);
@ -86,7 +86,7 @@ fn test_blockhash_eip210(factory: Factory) {
code_hash: Some(get_prev_hash_code_hash), code_hash: Some(get_prev_hash_code_hash),
code_version: 0.into(), code_version: 0.into(),
data: None, data: None,
call_type: CallType::Call, action_type: ActionType::Call,
params_type: ParamsType::Separate, params_type: ParamsType::Separate,
}; };
let schedule = machine.schedule(env_info.number); let schedule = machine.schedule(env_info.number);

View File

@ -16,7 +16,7 @@ hash-db = "0.15.0"
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
keccak-hasher = { path = "../../util/keccak-hasher" } keccak-hasher = { path = "../../util/keccak-hasher" }
journaldb = { path = "../../util/journaldb" } journaldb = { path = "../../util/journaldb" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4.6" log = "0.4.6"
lru-cache = "0.1.2" lru-cache = "0.1.2"
memory-cache = { path = "../../util/memory-cache" } memory-cache = { path = "../../util/memory-cache" }

View File

@ -40,7 +40,7 @@ env_logger = "0.5"
engine = { path = "../engine" } engine = { path = "../engine" }
ethcore = { path = "..", features = ["test-helpers"] } ethcore = { path = "..", features = ["test-helpers"] }
ethcore-io = { path = "../../util/io", features = ["mio"] } ethcore-io = { path = "../../util/io", features = ["mio"] }
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"
machine = { path = "../machine" } machine = { path = "../machine" }
rand_xorshift = "0.2" rand_xorshift = "0.2"
rustc-hex = "1.0" rustc-hex = "1.0"

View File

@ -162,7 +162,12 @@ pub const PAR_PROTOCOL_VERSION_4: (u8, u8) = (4, 0x20);
pub const MAX_BODIES_TO_SEND: usize = 256; pub const MAX_BODIES_TO_SEND: usize = 256;
pub const MAX_HEADERS_TO_SEND: usize = 512; pub const MAX_HEADERS_TO_SEND: usize = 512;
/// Maximum number of "entries" to include in a GetDataNode request.
pub const MAX_NODE_DATA_TO_SEND: usize = 1024; pub const MAX_NODE_DATA_TO_SEND: usize = 1024;
/// Maximum allowed duration for serving a batch GetNodeData request.
const MAX_NODE_DATA_TOTAL_DURATION: Duration = Duration::from_secs(2);
/// Maximum allowed duration for serving a single GetNodeData request.
const MAX_NODE_DATA_SINGLE_DURATION: Duration = Duration::from_millis(100);
pub const MAX_RECEIPTS_HEADERS_TO_SEND: usize = 256; pub const MAX_RECEIPTS_HEADERS_TO_SEND: usize = 256;
const MIN_PEERS_PROPAGATION: usize = 4; const MIN_PEERS_PROPAGATION: usize = 4;
const MAX_PEERS_PROPAGATION: usize = 128; const MAX_PEERS_PROPAGATION: usize = 128;

View File

@ -15,13 +15,14 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::cmp; use std::cmp;
use std::time::{Duration, Instant};
use crate::sync_io::SyncIo; use crate::sync_io::SyncIo;
use bytes::Bytes; use bytes::Bytes;
use enum_primitive::FromPrimitive; use enum_primitive::FromPrimitive;
use ethereum_types::H256; use ethereum_types::H256;
use log::{debug, trace}; use log::{debug, trace, warn};
use network::{self, PeerId}; use network::{self, PeerId};
use parking_lot::RwLock; use parking_lot::RwLock;
use rlp::{Rlp, RlpStream}; use rlp::{Rlp, RlpStream};
@ -56,6 +57,8 @@ use super::{
MAX_BODIES_TO_SEND, MAX_BODIES_TO_SEND,
MAX_HEADERS_TO_SEND, MAX_HEADERS_TO_SEND,
MAX_NODE_DATA_TO_SEND, MAX_NODE_DATA_TO_SEND,
MAX_NODE_DATA_TOTAL_DURATION,
MAX_NODE_DATA_SINGLE_DURATION,
MAX_RECEIPTS_HEADERS_TO_SEND, MAX_RECEIPTS_HEADERS_TO_SEND,
}; };
@ -258,9 +261,9 @@ impl SyncSupplier {
/// Respond to GetNodeData request /// Respond to GetNodeData request
fn return_node_data(io: &dyn SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { fn return_node_data(io: &dyn SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult {
let payload_soft_limit = io.payload_soft_limit(); let payload_soft_limit = io.payload_soft_limit(); // 4Mb
let mut count = r.item_count().unwrap_or(0); let mut count = r.item_count().unwrap_or(0);
trace!(target: "sync", "{} -> GetNodeData: {} entries", peer_id, count); trace!(target: "sync", "{} -> GetNodeData: {} entries requested", peer_id, count);
if count == 0 { if count == 0 {
debug!(target: "sync", "Empty GetNodeData request, ignoring."); debug!(target: "sync", "Empty GetNodeData request, ignoring.");
return Ok(None); return Ok(None);
@ -269,10 +272,20 @@ impl SyncSupplier {
let mut added = 0usize; let mut added = 0usize;
let mut data = Vec::new(); let mut data = Vec::new();
let mut total_bytes = 0; let mut total_bytes = 0;
let mut total_elpsd = Duration::from_secs(0);
for i in 0..count { for i in 0..count {
if let Some(node) = io.chain().state_data(&r.val_at::<H256>(i)?) { let hash = &r.val_at(i)?;
let elpsd = Instant::now();
let state = io.chain().state_data(hash);
total_elpsd += elpsd.elapsed();
if elpsd.elapsed() > MAX_NODE_DATA_SINGLE_DURATION || total_elpsd > MAX_NODE_DATA_TOTAL_DURATION {
warn!(target: "sync", "{} -> GetNodeData: item {}/{} slow state fetch for hash {:?}; took {:?}",
peer_id, i, count, hash, elpsd);
break;
}
if let Some(node) = state {
total_bytes += node.len(); total_bytes += node.len();
// Check that the packet won't be oversized
if total_bytes > payload_soft_limit { if total_bytes > payload_soft_limit {
break; break;
} }
@ -280,7 +293,8 @@ impl SyncSupplier {
added += 1; added += 1;
} }
} }
trace!(target: "sync", "{} -> GetNodeData: return {} entries", peer_id, added); trace!(target: "sync", "{} -> GetNodeData: returning {}/{} entries ({} bytes total in {:?})",
peer_id, added, count, total_bytes, total_elpsd);
let mut rlp = RlpStream::new_list(added); let mut rlp = RlpStream::new_list(added);
for d in data { for d in data {
rlp.append(&d); rlp.append(&d);
@ -540,7 +554,7 @@ mod test {
let rlp_result = result.unwrap(); let rlp_result = result.unwrap();
assert!(rlp_result.is_some()); assert!(rlp_result.is_some());
// the length of one rlp-encoded hashe // the length of one rlp-encoded hash
let rlp = rlp_result.unwrap().1.out(); let rlp = rlp_result.unwrap().1.out();
let rlp = Rlp::new(&rlp); let rlp = Rlp::new(&rlp);
assert_eq!(Ok(1), rlp.item_count()); assert_eq!(Ok(1), rlp.item_count());

View File

@ -234,7 +234,7 @@ impl Fetcher {
} }
// state transition not triggered until drain is finished. // state transition not triggered until drain is finished.
(SyncRound::Fetch(self)) SyncRound::Fetch(self)
} }
} }
} }

View File

@ -11,7 +11,7 @@ ethcore-blockchain = { path = "../blockchain" }
ethcore-db = { path = "../db" } ethcore-db = { path = "../db" }
ethereum-types = "0.8.0" ethereum-types = "0.8.0"
evm = { path = "../evm" } evm = { path = "../evm" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
parity-bytes = "0.1.0" parity-bytes = "0.1.0"
parity-util-mem = "0.3.0" parity-util-mem = "0.3.0"

View File

@ -374,13 +374,12 @@ mod tests {
use ethcore::test_helpers::new_db; use ethcore::test_helpers::new_db;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use evm::CallType;
use kvdb::DBTransaction; use kvdb::DBTransaction;
use crate::{ use crate::{
BlockNumber, Config, TraceDB, Database as TraceDatabase, ImportRequest, DatabaseExtras, BlockNumber, Config, TraceDB, Database as TraceDatabase, ImportRequest, DatabaseExtras,
Filter, LocalizedTrace, AddressesFilter, TraceError, Filter, LocalizedTrace, AddressesFilter, TraceError,
trace::{Call, Action, Res}, trace::{Call, CallType, Action, Res},
flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces} flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces}
}; };
@ -465,7 +464,7 @@ mod tests {
value: 3.into(), value: 3.into(),
gas: 4.into(), gas: 4.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(CallType::Call).into(),
}), }),
result: Res::FailedCall(TraceError::OutOfGas), result: Res::FailedCall(TraceError::OutOfGas),
}])]), }])]),
@ -487,7 +486,7 @@ mod tests {
value: 3.into(), value: 3.into(),
gas: 4.into(), gas: 4.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(CallType::Call).into(),
}), }),
result: Res::FailedCall(TraceError::OutOfGas), result: Res::FailedCall(TraceError::OutOfGas),
}])]), }])]),
@ -506,7 +505,7 @@ mod tests {
value: U256::from(3), value: U256::from(3),
gas: U256::from(4), gas: U256::from(4),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(CallType::Call).into(),
}), }),
result: Res::FailedCall(TraceError::OutOfGas), result: Res::FailedCall(TraceError::OutOfGas),
trace_address: vec![], trace_address: vec![],

View File

@ -125,10 +125,9 @@ impl Filter {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ethereum_types::{Address, Bloom, BloomInput}; use ethereum_types::{Address, Bloom, BloomInput};
use evm::CallType;
use crate::{ use crate::{
Filter, AddressesFilter, TraceError, RewardType, Filter, AddressesFilter, TraceError, RewardType,
trace::{Action, Call, Res, Create, CreateResult, Suicide, Reward}, trace::{Action, Call, CallType, Res, Create, CreationMethod, CreateResult, Suicide, Reward},
flat::FlatTrace, flat::FlatTrace,
}; };
@ -273,7 +272,7 @@ mod tests {
value: 3.into(), value: 3.into(),
gas: 4.into(), gas: 4.into(),
input: vec![0x5], input: vec![0x5],
call_type: CallType::Call, call_type: Some(CallType::Call).into(),
}), }),
result: Res::FailedCall(TraceError::OutOfGas), result: Res::FailedCall(TraceError::OutOfGas),
trace_address: vec![0].into_iter().collect(), trace_address: vec![0].into_iter().collect(),
@ -294,6 +293,7 @@ mod tests {
value: 3.into(), value: 3.into(),
gas: 4.into(), gas: 4.into(),
init: vec![0x5], init: vec![0x5],
creation_method: Some(CreationMethod::Create),
}), }),
result: Res::Create(CreateResult { result: Res::Create(CreateResult {
gas_used: 10.into(), gas_used: 10.into(),
@ -413,6 +413,7 @@ mod tests {
gas: 4.into(), gas: 4.into(),
init: vec![0x5], init: vec![0x5],
value: 3.into(), value: 3.into(),
creation_method: Some(CreationMethod::Create),
}), }),
result: Res::FailedCall(TraceError::BadInstruction), result: Res::FailedCall(TraceError::BadInstruction),
trace_address: vec![].into_iter().collect(), trace_address: vec![].into_iter().collect(),

View File

@ -123,9 +123,8 @@ mod tests {
use rlp::*; use rlp::*;
use crate::{ use crate::{
FlatBlockTraces, FlatTransactionTraces, FlatTrace, FlatBlockTraces, FlatTransactionTraces, FlatTrace,
trace::{Action, Res, CallResult, Call, Suicide, Reward, RewardType} trace::{Action, Res, CallResult, Call, CallType, Suicide, Reward, RewardType}
}; };
use evm::CallType;
#[test] #[test]
fn encode_flat_transaction_traces() { fn encode_flat_transaction_traces() {
@ -162,7 +161,7 @@ mod tests {
value: "3627e8f712373c0000".parse().unwrap(), value: "3627e8f712373c0000".parse().unwrap(),
gas: 0x03e8.into(), gas: 0x03e8.into(),
input: vec![], input: vec![],
call_type: CallType::Call, call_type: Some(CallType::Call).into(),
}), }),
result: Res::Call(CallResult { result: Res::Call(CallResult {
gas_used: 0.into(), gas_used: 0.into(),
@ -179,7 +178,7 @@ mod tests {
value: 0.into(), value: 0.into(),
gas: 0x010c78.into(), gas: 0x010c78.into(),
input: vec![0x41, 0xc0, 0xe1, 0xb5], input: vec![0x41, 0xc0, 0xe1, 0xb5],
call_type: CallType::Call, call_type: Some(CallType::Call).into(),
}), }),
result: Res::Call(CallResult { result: Res::Call(CallResult {
gas_used: 0x0127.into(), gas_used: 0x0127.into(),

View File

@ -16,12 +16,19 @@
//! Tracing data types. //! Tracing data types.
// ================== NOTE ========================
// IF YOU'RE ADDING A FIELD TO A STRUCT WITH
// RLP ENCODING, MAKE SURE IT'S DONE IN A BACKWARDS
// COMPATIBLE WAY!
// ================== NOTE ========================
use std::convert::TryFrom;
use ethereum_types::{U256, Address, Bloom, BloomInput}; use ethereum_types::{U256, Address, Bloom, BloomInput};
use parity_bytes::Bytes; use parity_bytes::Bytes;
use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable}; use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable};
use rlp_derive::{RlpEncodable, RlpDecodable}; use rlp_derive::{RlpEncodable, RlpDecodable};
use vm::ActionParams; use vm::ActionParams;
use evm::CallType; use evm::ActionType;
use super::error::Error; use super::error::Error;
/// `Call` result. /// `Call` result.
@ -33,6 +40,33 @@ pub struct CallResult {
pub output: Bytes, pub output: Bytes,
} }
/// `Call` type. Distinguish between different types of contract interactions.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CallType {
/// Call
Call,
/// Call code
CallCode,
/// Delegate call
DelegateCall,
/// Static call
StaticCall,
}
impl TryFrom<ActionType> for CallType {
type Error = &'static str;
fn try_from(action_type: ActionType) -> Result<Self, Self::Error> {
match action_type {
ActionType::Call => Ok(CallType::Call),
ActionType::CallCode => Ok(CallType::CallCode),
ActionType::DelegateCall => Ok(CallType::DelegateCall),
ActionType::StaticCall => Ok(CallType::StaticCall),
ActionType::Create => Err("Create cannot be converted to CallType"),
ActionType::Create2 => Err("Create2 cannot be converted to CallType"),
}
}
}
/// `Create` result. /// `Create` result.
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
pub struct CreateResult { pub struct CreateResult {
@ -51,6 +85,49 @@ impl CreateResult {
} }
} }
/// `Create` method. Distinguish between use of `CREATE` and `CREATE2` opcodes in an action.
#[derive(Debug, Clone, PartialEq)]
pub enum CreationMethod {
/// Create
Create,
/// Create2
Create2,
}
impl TryFrom<ActionType> for CreationMethod {
type Error = &'static str;
fn try_from(action_type: ActionType) -> Result<Self, Self::Error> {
match action_type {
ActionType::Call => Err("Call cannot be converted to CreationMethod"),
ActionType::CallCode => Err("CallCode cannot be converted to CreationMethod"),
ActionType::DelegateCall => Err("DelegateCall cannot be converted to CreationMethod"),
ActionType::StaticCall => Err("StaticCall cannot be converted to CreationMethod"),
ActionType::Create => Ok(CreationMethod::Create),
ActionType::Create2 => Ok(CreationMethod::Create2),
}
}
}
impl Encodable for CreationMethod {
fn rlp_append(&self, s: &mut RlpStream) {
let v = match *self {
CreationMethod::Create => 0u32,
CreationMethod::Create2 => 1,
};
Encodable::rlp_append(&v, s);
}
}
impl Decodable for CreationMethod {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.as_val().and_then(|v| Ok(match v {
0u32 => CreationMethod::Create,
1 => CreationMethod::Create2,
_ => return Err(DecoderError::Custom("Invalid value of CreationMethod item")),
}))
}
}
/// Description of a _call_ action, either a `CALL` operation or a message transaction. /// Description of a _call_ action, either a `CALL` operation or a message transaction.
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
pub struct Call { pub struct Call {
@ -65,19 +142,96 @@ pub struct Call {
/// The input data provided to the call. /// The input data provided to the call.
pub input: Bytes, pub input: Bytes,
/// The type of the call. /// The type of the call.
pub call_type: CallType, pub call_type: BackwardsCompatibleCallType,
}
/// This is essentially an `Option<CallType>`, but with a custom
/// `rlp` en/de-coding which preserves backwards compatibility with
/// the older encodings used in parity-ethereum versions < 2.7 and 2.7.0.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct BackwardsCompatibleCallType(pub Option<CallType>);
impl From<Option<CallType>> for BackwardsCompatibleCallType {
fn from(option: Option<CallType>) -> Self {
BackwardsCompatibleCallType(option)
}
}
// Encoding is the same as `CallType_v2_6_x`.
impl Encodable for BackwardsCompatibleCallType {
fn rlp_append(&self, s: &mut RlpStream) {
let v = match self.0 {
None => 0u32,
Some(CallType::Call) => 1,
Some(CallType::CallCode) => 2,
Some(CallType::DelegateCall) => 3,
Some(CallType::StaticCall) => 4,
};
Encodable::rlp_append(&v, s);
}
}
// Try to decode it as `CallType_v2_6_x` first, and then as `Option<CallType_v2_7_0>`.
impl Decodable for BackwardsCompatibleCallType {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
if rlp.is_data() {
rlp.as_val().and_then(|v| Ok(match v {
0u32 => None,
1 => Some(CallType::Call),
2 => Some(CallType::CallCode),
3 => Some(CallType::DelegateCall),
4 => Some(CallType::StaticCall),
_ => return Err(DecoderError::Custom("Invalid value of CallType item")),
}.into()))
} else {
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq)]
enum CallType_v2_7_0 {
Call,
CallCode,
DelegateCall,
StaticCall,
}
impl Decodable for CallType_v2_7_0 {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.as_val().and_then(|v| Ok(match v {
0u32 => CallType_v2_7_0::Call,
1 => CallType_v2_7_0::CallCode,
2 => CallType_v2_7_0::DelegateCall,
3 => CallType_v2_7_0::StaticCall,
_ => return Err(DecoderError::Custom("Invalid value of CallType item")),
}))
}
}
impl From<CallType_v2_7_0> for CallType {
fn from(old_call_type: CallType_v2_7_0) -> Self {
match old_call_type {
CallType_v2_7_0::Call => Self::Call,
CallType_v2_7_0::CallCode => Self::CallCode,
CallType_v2_7_0::DelegateCall => Self::DelegateCall,
CallType_v2_7_0::StaticCall => Self::StaticCall,
}
}
}
let optional: Option<CallType_v2_7_0> = Decodable::decode(rlp)?;
Ok(optional.map(Into::into).into())
}
}
} }
impl From<ActionParams> for Call { impl From<ActionParams> for Call {
fn from(p: ActionParams) -> Self { fn from(p: ActionParams) -> Self {
match p.call_type { match p.action_type {
CallType::DelegateCall | CallType::CallCode => Call { ActionType::DelegateCall | ActionType::CallCode => Call {
from: p.address, from: p.address,
to: p.code_address, to: p.code_address,
value: p.value.value(), value: p.value.value(),
gas: p.gas, gas: p.gas,
input: p.data.unwrap_or_else(Vec::new), input: p.data.unwrap_or_else(Vec::new),
call_type: p.call_type, call_type: CallType::try_from(p.action_type).ok().into(),
}, },
_ => Call { _ => Call {
from: p.sender, from: p.sender,
@ -85,7 +239,7 @@ impl From<ActionParams> for Call {
value: p.value.value(), value: p.value.value(),
gas: p.gas, gas: p.gas,
input: p.data.unwrap_or_else(Vec::new), input: p.data.unwrap_or_else(Vec::new),
call_type: p.call_type, call_type: CallType::try_from(p.action_type).ok().into(),
}, },
} }
} }
@ -113,6 +267,9 @@ pub struct Create {
pub gas: U256, pub gas: U256,
/// The init code. /// The init code.
pub init: Bytes, pub init: Bytes,
/// Creation method (CREATE vs CREATE2).
#[rlp(default)]
pub creation_method: Option<CreationMethod>,
} }
impl From<ActionParams> for Create { impl From<ActionParams> for Create {
@ -122,6 +279,7 @@ impl From<ActionParams> for Create {
value: p.value.value(), value: p.value.value(),
gas: p.gas, gas: p.gas,
init: p.code.map_or_else(Vec::new, |c| (*c).clone()), init: p.code.map_or_else(Vec::new, |c| (*c).clone()),
creation_method: CreationMethod::try_from(p.action_type).ok().into(),
} }
} }
} }
@ -429,3 +587,132 @@ pub struct VMTrace {
/// Thre is a 1:1 correspondance between these and a CALL/CREATE/CALLCODE/DELEGATECALL instruction. /// Thre is a 1:1 correspondance between these and a CALL/CREATE/CALLCODE/DELEGATECALL instruction.
pub subs: Vec<VMTrace>, pub subs: Vec<VMTrace>,
} }
#[cfg(test)]
mod tests {
use rlp::{RlpStream, Encodable};
use rlp_derive::{RlpEncodable, RlpDecodable};
use super::{Address, Bytes, Call, CallType, Create, CreationMethod, U256};
#[test]
fn test_call_type_backwards_compatibility() {
// Call type in version < 2.7.
#[derive(Debug, Clone, PartialEq, RlpEncodable)]
struct OldCall {
from: Address,
to: Address,
value: U256,
gas: U256,
input: Bytes,
call_type: OldCallType,
}
// CallType type in version < 2.7.
#[allow(dead_code)]
#[derive(Debug, PartialEq, Clone)]
enum OldCallType {
None,
Call,
CallCode,
DelegateCall,
StaticCall,
}
// CallType rlp encoding in version < 2.7.
impl Encodable for OldCallType {
fn rlp_append(&self, s: &mut RlpStream) {
let v = match *self {
OldCallType::None => 0u32,
OldCallType::Call => 1,
OldCallType::CallCode => 2,
OldCallType::DelegateCall => 3,
OldCallType::StaticCall => 4,
};
Encodable::rlp_append(&v, s);
}
}
let old_call = OldCall {
from: Address::from_low_u64_be(1),
to: Address::from_low_u64_be(2),
value: U256::from(3),
gas: U256::from(4),
input: vec![5],
call_type: OldCallType::DelegateCall,
};
let old_encoded = rlp::encode(&old_call);
let new_call = Call {
from: Address::from_low_u64_be(1),
to: Address::from_low_u64_be(2),
value: U256::from(3),
gas: U256::from(4),
input: vec![5],
call_type: Some(CallType::DelegateCall).into(),
};
// `old_call` should be deserialized successfully into `new_call`
assert_eq!(rlp::decode(&old_encoded), Ok(new_call.clone()));
// test a roundtrip with `Some` `call_type`
let new_encoded = rlp::encode(&new_call);
assert_eq!(rlp::decode(&new_encoded), Ok(new_call));
// test a roundtrip with `None` `call_type`
let none_call = Call {
from: Address::from_low_u64_be(1),
to: Address::from_low_u64_be(2),
value: U256::from(3),
gas: U256::from(4),
input: vec![5],
call_type: None.into(),
};
let none_encoded = rlp::encode(&none_call);
assert_eq!(rlp::decode(&none_encoded), Ok(none_call));
}
#[test]
fn test_creation_method_backwards_compatibility() {
// Create type in version < 2.7.
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
struct OldCreate {
from: Address,
value: U256,
gas: U256,
init: Bytes,
}
let old_create = OldCreate {
from: Address::from_low_u64_be(1),
value: U256::from(3),
gas: U256::from(4),
init: vec![5],
};
let old_encoded = rlp::encode(&old_create);
let new_create = Create {
from: Address::from_low_u64_be(1),
value: U256::from(3),
gas: U256::from(4),
init: vec![5],
creation_method: None,
};
// `old_create` should be deserialized successfully into `new_create`
assert_eq!(rlp::decode(&old_encoded), Ok(new_create.clone()));
// test a roundtrip with `None` `creation_method`
let new_encoded = rlp::encode(&new_create);
assert_eq!(rlp::decode(&new_encoded), Ok(new_create));
// test a roundtrip with `Some` `creation_method`
let some_create = Create {
from: Address::from_low_u64_be(1),
value: U256::from(3),
gas: U256::from(4),
init: vec![5],
creation_method: Some(CreationMethod::Create2),
};
let some_encoded = rlp::encode(&some_create);
assert_eq!(rlp::decode(&some_encoded), Ok(some_create));
}
}

View File

@ -22,7 +22,7 @@ unexpected = { path = "../../util/unexpected" }
vm = { path = "../vm"} vm = { path = "../vm"}
[dev-dependencies] [dev-dependencies]
rustc-hex = "1.0" rustc-hex = "2.0"
[features] [features]
test-helpers = [] test-helpers = []

View File

@ -26,7 +26,7 @@
use block::Block as FullBlock; use block::Block as FullBlock;
use ethereum_types::{H256, Bloom, U256, Address}; use ethereum_types::{H256, Bloom, U256, Address};
use hash::keccak; use hash::keccak;
use header::{Header as FullHeader}; use header::Header as FullHeader;
use parity_util_mem::MallocSizeOf; use parity_util_mem::MallocSizeOf;
use rlp::{self, Rlp, RlpStream}; use rlp::{self, Rlp, RlpStream};
use transaction::UnverifiedTransaction; use transaction::UnverifiedTransaction;
@ -60,6 +60,15 @@ impl Header {
pub fn into_inner(self) -> Vec<u8> { self.0 } pub fn into_inner(self) -> Vec<u8> { self.0 }
} }
impl std::fmt::LowerHex for Header {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for byte in &self.0 {
write!(f, "{:02x}", byte)?;
}
Ok(())
}
}
// forwarders to borrowed view. // forwarders to borrowed view.
impl Header { impl Header {
/// Returns the header hash. /// Returns the header hash.

View File

@ -21,7 +21,7 @@ use derive_more::{Display, From};
use ethereum_types::{U256, U512}; use ethereum_types::{U256, U512};
use ethtrie::TrieError; use ethtrie::TrieError;
use parity_snappy::InvalidInput; use parity_snappy::InvalidInput;
use parity_crypto::publickey::{Error as EthPublicKeyCryptoError}; use parity_crypto::publickey::Error as EthPublicKeyCryptoError;
use errors::{BlockError, EngineError, ImportError, SnapshotError}; use errors::{BlockError, EngineError, ImportError, SnapshotError};
use transaction::Error as TransactionError; use transaction::Error as TransactionError;

View File

@ -377,11 +377,11 @@ mod tests {
#[test] #[test]
fn test_header_seal_fields() { fn test_header_seal_fields() {
// that's rlp of block header created with ethash engine. // that's rlp of block header created with ethash engine.
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); let header_rlp: Vec<u8> = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); let mix_hash: Vec<u8> = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let mix_hash_decoded = "a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); let mix_hash_decoded: Vec<u8> = "a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); let nonce: Vec<u8> = "88ab4e252a7e8c2a23".from_hex().unwrap();
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap(); let nonce_decoded: Vec<u8> = "ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = rlp::decode(&header_rlp).expect("error decoding header"); let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
let seal_fields = header.seal.clone(); let seal_fields = header.seal.clone();
@ -398,7 +398,7 @@ mod tests {
#[test] #[test]
fn decode_and_encode_header() { fn decode_and_encode_header() {
// that's rlp of block header created with ethash engine. // that's rlp of block header created with ethash engine.
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); let header_rlp: Vec<u8> = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = rlp::decode(&header_rlp).expect("error decoding header"); let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
let encoded_header = rlp::encode(&header); let encoded_header = rlp::encode(&header);
@ -410,7 +410,7 @@ mod tests {
fn reject_header_with_large_timestamp() { fn reject_header_with_large_timestamp() {
// that's rlp of block header created with ethash engine. // that's rlp of block header created with ethash engine.
// The encoding contains a large timestamp (295147905179352825856) // The encoding contains a large timestamp (295147905179352825856)
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d891000000000000000000080a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); let header_rlp: Vec<u8> = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d891000000000000000000080a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
// This should fail decoding timestamp // This should fail decoding timestamp
let header: Result<Header, _> = rlp::decode(&header_rlp); let header: Result<Header, _> = rlp::decode(&header_rlp);

View File

@ -42,8 +42,8 @@ extern crate derive_more;
extern crate keccak_hash as hash; extern crate keccak_hash as hash;
extern crate parity_bytes as bytes; extern crate parity_bytes as bytes;
extern crate patricia_trie_ethereum as ethtrie; extern crate patricia_trie_ethereum as ethtrie;
extern crate rlp;
extern crate parity_snappy; extern crate parity_snappy;
extern crate rlp;
extern crate unexpected; extern crate unexpected;
#[macro_use] #[macro_use]
@ -51,12 +51,12 @@ extern crate rlp_derive;
extern crate parity_util_mem; extern crate parity_util_mem;
extern crate parity_util_mem as malloc_size_of; extern crate parity_util_mem as malloc_size_of;
#[macro_use]
pub mod views;
#[cfg(test)] #[cfg(test)]
extern crate rustc_hex; extern crate rustc_hex;
#[macro_use]
pub mod views;
pub mod account_diff; pub mod account_diff;
pub mod ancestry_action; pub mod ancestry_action;
pub mod basic_account; pub mod basic_account;

View File

@ -170,13 +170,15 @@ pub struct LocalizedReceipt {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr;
use super::{Receipt, TransactionOutcome, Address, H256}; use super::{Receipt, TransactionOutcome, Address, H256};
use log_entry::LogEntry; use log_entry::LogEntry;
use std::str::FromStr; use rustc_hex::FromHex;
#[test] #[test]
fn test_no_state_root() { fn test_no_state_root() {
let expected = ::rustc_hex::FromHex::from_hex("f9014183040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); let expected: Vec<u8> = FromHex::from_hex("f9014183040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap();
let r = Receipt::new( let r = Receipt::new(
TransactionOutcome::Unknown, TransactionOutcome::Unknown,
0x40cae.into(), 0x40cae.into(),
@ -191,7 +193,7 @@ mod tests {
#[test] #[test]
fn test_basic() { fn test_basic() {
let expected = ::rustc_hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); let expected: Vec<u8> = FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap();
let r = Receipt::new( let r = Receipt::new(
TransactionOutcome::StateRoot(H256::from_str("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee").unwrap()), TransactionOutcome::StateRoot(H256::from_str("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee").unwrap()),
0x40cae.into(), 0x40cae.into(),
@ -201,15 +203,15 @@ mod tests {
data: vec![0u8; 32] data: vec![0u8; 32]
}] }]
); );
let encoded = ::rlp::encode(&r); let encoded = rlp::encode(&r);
assert_eq!(&encoded[..], &expected[..]); assert_eq!(&encoded[..], &expected[..]);
let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed"); let decoded: Receipt = rlp::decode(&encoded).expect("decoding receipt failed");
assert_eq!(decoded, r); assert_eq!(decoded, r);
} }
#[test] #[test]
fn test_status_code() { fn test_status_code() {
let expected = ::rustc_hex::FromHex::from_hex("f901428083040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); let expected: Vec<u8> = FromHex::from_hex("f901428083040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap();
let r = Receipt::new( let r = Receipt::new(
TransactionOutcome::StatusCode(0), TransactionOutcome::StatusCode(0),
0x40cae.into(), 0x40cae.into(),
@ -219,9 +221,9 @@ mod tests {
data: vec![0u8; 32] data: vec![0u8; 32]
}] }]
); );
let encoded = ::rlp::encode(&r); let encoded = rlp::encode(&r);
assert_eq!(&encoded[..], &expected[..]); assert_eq!(&encoded[..], &expected[..]);
let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed"); let decoded: Receipt = rlp::decode(&encoded).expect("decoding receipt failed");
assert_eq!(decoded, r); assert_eq!(decoded, r);
} }
} }

View File

@ -548,14 +548,16 @@ impl From<SignedTransaction> for PendingTransaction {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr;
use super::*; use super::*;
use ethereum_types::{U256, Address}; use ethereum_types::{U256, Address};
use hash::keccak; use hash::keccak;
use std::str::FromStr; use rustc_hex::FromHex;
#[test] #[test]
fn sender_test() { fn sender_test() {
let bytes = ::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap(); let bytes: Vec<u8> = FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap();
let t: UnverifiedTransaction = rlp::decode(&bytes).expect("decoding UnverifiedTransaction failed"); let t: UnverifiedTransaction = rlp::decode(&bytes).expect("decoding UnverifiedTransaction failed");
assert_eq!(t.data, b""); assert_eq!(t.data, b"");
assert_eq!(t.gas, U256::from(0x5208u64)); assert_eq!(t.gas, U256::from(0x5208u64));
@ -675,11 +677,9 @@ mod tests {
#[test] #[test]
fn should_agree_with_vitalik() { fn should_agree_with_vitalik() {
use rustc_hex::FromHex;
let test_vector = |tx_data: &str, address: &'static str| { let test_vector = |tx_data: &str, address: &'static str| {
let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap()).expect("decoding tx data failed"); let bytes = rlp::decode(&tx_data.from_hex::<Vec<u8>>().unwrap()).expect("decoding tx data failed");
let signed = SignedTransaction::new(signed).unwrap(); let signed = SignedTransaction::new(bytes).unwrap();
assert_eq!(signed.sender(), Address::from_str(&address[2..]).unwrap()); assert_eq!(signed.sender(), Address::from_str(&address[2..]).unwrap());
println!("chainid: {:?}", signed.chain_id()); println!("chainid: {:?}", signed.chain_id());
}; };

View File

@ -183,7 +183,7 @@ mod tests {
#[test] #[test]
fn test_block_view() { fn test_block_view() {
// that's rlp of block created with ethash engine. // that's rlp of block created with ethash engine.
let rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap(); let rlp: Vec<u8> = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap();
let view = view!(BlockView, &rlp); let view = view!(BlockView, &rlp);
assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap()); assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap());

View File

@ -167,7 +167,7 @@ mod tests {
#[test] #[test]
fn test_block_view() { fn test_block_view() {
// that's rlp of block created with ethash engine. // that's rlp of block created with ethash engine.
let rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap(); let rlp: Vec<u8> = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap();
let body = block_to_body(&rlp); let body = block_to_body(&rlp);
let view = view!(BodyView, &body); let view = view!(BodyView, &body);
assert_eq!(view.transactions_count(), 1); assert_eq!(view.transactions_count(), 1);

View File

@ -127,9 +127,9 @@ mod tests {
#[test] #[test]
fn test_header_view() { fn test_header_view() {
// that's rlp of block header created with ethash engine. // that's rlp of block header created with ethash engine.
let rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); let rlp: Vec<u8> = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); let mix_hash: Vec<u8> = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); let nonce: Vec<u8> = "88ab4e252a7e8c2a23".from_hex().unwrap();
let view = view!(HeaderView, &rlp); let view = view!(HeaderView, &rlp);
assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap()); assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap());

View File

@ -90,14 +90,14 @@ mod tests {
#[test] #[test]
fn test_transaction_view() { fn test_transaction_view() {
let rlp = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap(); let rlp: Vec<u8> = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap();
let view = view!(TransactionView, &rlp); let view = view!(TransactionView, &rlp);
assert_eq!(view.nonce(), 0.into()); assert_eq!(view.nonce(), 0.into());
assert_eq!(view.gas_price(), 1.into()); assert_eq!(view.gas_price(), 1.into());
assert_eq!(view.gas(), 0x61a8.into()); assert_eq!(view.gas(), 0x61a8.into());
assert_eq!(view.value(), 0xa.into()); assert_eq!(view.value(), 0xa.into());
assert_eq!(view.data(), "0000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()); assert_eq!(view.data(), "0000000000000000000000000000000000000000000000000000000000".from_hex::<Vec<u8>>().unwrap());
assert_eq!(view.r(), "48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353".into()); assert_eq!(view.r(), "48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353".into());
assert_eq!(view.s(), "efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".into()); assert_eq!(view.s(), "efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".into());
assert_eq!(view.v(), 0x1b); assert_eq!(view.v(), 0x1b);

View File

@ -62,7 +62,14 @@ pub trait Kind: 'static + Sized + Send + Sync {
type Verified: Sized + Send + BlockLike + MallocSizeOf; type Verified: Sized + Send + BlockLike + MallocSizeOf;
/// Attempt to create the `Unverified` item from the input. /// Attempt to create the `Unverified` item from the input.
fn create(input: Self::Input, engine: &dyn Engine, check_seal: bool) -> Result<Self::Unverified, (Self::Input, Error)>; ///
/// The return type is quite complex because in some scenarios the input
/// is needed (typically for BlockError) to get the raw block bytes without cloning them
fn create(
input: Self::Input,
engine: &dyn Engine,
check_seal: bool
) -> Result<Self::Unverified, (Error, Option<Self::Input>)>;
/// Attempt to verify the `Unverified` item using the given engine. /// Attempt to verify the `Unverified` item using the given engine.
fn verify(unverified: Self::Unverified, engine: &dyn Engine, check_seal: bool) -> Result<Self::Verified, Error>; fn verify(unverified: Self::Unverified, engine: &dyn Engine, check_seal: bool) -> Result<Self::Verified, Error>;
@ -91,16 +98,20 @@ pub mod blocks {
type Unverified = Unverified; type Unverified = Unverified;
type Verified = PreverifiedBlock; type Verified = PreverifiedBlock;
fn create(input: Self::Input, engine: &dyn Engine, check_seal: bool) -> Result<Self::Unverified, (Self::Input, Error)> { fn create(
input: Self::Input,
engine: &dyn Engine,
check_seal: bool
) -> Result<Self::Unverified, (Error, Option<Self::Input>)> {
match verify_block_basic(&input, engine, check_seal) { match verify_block_basic(&input, engine, check_seal) {
Ok(()) => Ok(input), Ok(()) => Ok(input),
Err(Error::Block(BlockError::TemporarilyInvalid(oob))) => { Err(Error::Block(BlockError::TemporarilyInvalid(oob))) => {
debug!(target: "client", "Block received too early {}: {:?}", input.hash(), oob); debug!(target: "client", "Block received too early {}: {:?}", input.hash(), oob);
Err((input, BlockError::TemporarilyInvalid(oob).into())) Err((BlockError::TemporarilyInvalid(oob).into(), Some(input)))
}, },
Err(e) => { Err(e) => {
warn!(target: "client", "Stage 1 block verification failed for {}: {:?}", input.hash(), e); warn!(target: "client", "Stage 1 block verification failed for {}: {:?}", input.hash(), e);
Err((input, e)) Err((e, Some(input)))
} }
} }
} }
@ -127,11 +138,11 @@ pub mod blocks {
} }
fn parent_hash(&self) -> H256 { fn parent_hash(&self) -> H256 {
self.header.parent_hash().clone() *self.header.parent_hash()
} }
fn difficulty(&self) -> U256 { fn difficulty(&self) -> U256 {
self.header.difficulty().clone() *self.header.difficulty()
} }
} }
@ -145,11 +156,11 @@ pub mod blocks {
} }
fn parent_hash(&self) -> H256 { fn parent_hash(&self) -> H256 {
self.header.parent_hash().clone() *self.header.parent_hash()
} }
fn difficulty(&self) -> U256 { fn difficulty(&self) -> U256 {
self.header.difficulty().clone() *self.header.difficulty()
} }
} }
} }
@ -170,8 +181,8 @@ pub mod headers {
impl BlockLike for Header { impl BlockLike for Header {
fn hash(&self) -> H256 { self.hash() } fn hash(&self) -> H256 { self.hash() }
fn raw_hash(&self) -> H256 { self.hash() } fn raw_hash(&self) -> H256 { self.hash() }
fn parent_hash(&self) -> H256 { self.parent_hash().clone() } fn parent_hash(&self) -> H256 { *self.parent_hash() }
fn difficulty(&self) -> U256 { self.difficulty().clone() } fn difficulty(&self) -> U256 { *self.difficulty() }
} }
/// A mode for verifying headers. /// A mode for verifying headers.
@ -182,19 +193,23 @@ pub mod headers {
type Unverified = Header; type Unverified = Header;
type Verified = Header; type Verified = Header;
fn create(input: Self::Input, engine: &dyn Engine, check_seal: bool) -> Result<Self::Unverified, (Self::Input, Error)> { fn create(
input: Self::Input,
engine: &dyn Engine,
check_seal: bool
) -> Result<Self::Unverified, (Error, Option<Self::Input>)> {
let res = verify_header_params(&input, engine, check_seal) let res = verify_header_params(&input, engine, check_seal)
.and_then(|_| verify_header_time(&input)); .and_then(|_| verify_header_time(&input));
match res { match res {
Ok(_) => Ok(input), Ok(_) => Ok(input),
Err(err) => Err((input, err)) Err(e) => Err((e, Some(input))),
} }
} }
fn verify(unverified: Self::Unverified, engine: &dyn Engine, check_seal: bool) -> Result<Self::Verified, Error> { fn verify(unverified: Self::Unverified, engine: &dyn Engine, check_seal: bool) -> Result<Self::Verified, Error> {
match check_seal { match check_seal {
true => engine.verify_block_unordered(&unverified,).map(|_| unverified), true => engine.verify_block_unordered(&unverified).map(|_| unverified),
false => Ok(unverified), false => Ok(unverified),
} }
} }

View File

@ -467,30 +467,33 @@ impl<K: Kind, C> VerificationQueue<K, C> {
} }
/// Add a block to the queue. /// Add a block to the queue.
pub fn import(&self, input: K::Input) -> Result<H256, (K::Input, Error)> { //
// TODO: #11403 - rework `EthcoreError::Block` to include raw bytes of the error cause
pub fn import(&self, input: K::Input) -> Result<H256, (Error, Option<K::Input>)> {
let hash = input.hash(); let hash = input.hash();
let raw_hash = input.raw_hash(); let raw_hash = input.raw_hash();
{ {
if self.processing.read().contains_key(&hash) { if self.processing.read().contains_key(&hash) {
return Err((input, Error::Import(ImportError::AlreadyQueued).into())); return Err((Error::Import(ImportError::AlreadyQueued), Some(input)));
} }
let mut bad = self.verification.bad.lock(); let mut bad = self.verification.bad.lock();
if bad.contains(&hash) || bad.contains(&raw_hash) { if bad.contains(&hash) || bad.contains(&raw_hash) {
return Err((input, Error::Import(ImportError::KnownBad).into())); return Err((Error::Import(ImportError::KnownBad), Some(input)));
} }
if bad.contains(&input.parent_hash()) { if bad.contains(&input.parent_hash()) {
bad.insert(hash); bad.insert(hash);
return Err((input, Error::Import(ImportError::KnownBad).into())); return Err((Error::Import(ImportError::KnownBad), Some(input)));
} }
} }
match K::create(input, &*self.engine, self.verification.check_seal) { match K::create(input, &*self.engine, self.verification.check_seal) {
Ok(item) => { Ok(item) => {
if self.processing.write().insert(hash, item.difficulty()).is_some() {
return Err((Error::Import(ImportError::AlreadyQueued), None));
}
self.verification.sizes.unverified.fetch_add(item.malloc_size_of(), AtomicOrdering::SeqCst); self.verification.sizes.unverified.fetch_add(item.malloc_size_of(), AtomicOrdering::SeqCst);
self.processing.write().insert(hash, item.difficulty());
{ {
let mut td = self.total_difficulty.write(); let mut td = self.total_difficulty.write();
*td = *td + item.difficulty(); *td = *td + item.difficulty();
@ -499,7 +502,7 @@ impl<K: Kind, C> VerificationQueue<K, C> {
self.more_to_verify.notify_all(); self.more_to_verify.notify_all();
Ok(hash) Ok(hash)
}, },
Err((input, err)) => { Err((err, input)) => {
match err { match err {
// Don't mark future blocks as bad. // Don't mark future blocks as bad.
Error::Block(BlockError::TemporarilyInvalid(_)) => {}, Error::Block(BlockError::TemporarilyInvalid(_)) => {},
@ -517,7 +520,7 @@ impl<K: Kind, C> VerificationQueue<K, C> {
self.verification.bad.lock().insert(hash); self.verification.bad.lock().insert(hash);
} }
} }
Err((input, err)) Err((err, input))
} }
} }
} }
@ -582,7 +585,7 @@ impl<K: Kind, C> VerificationQueue<K, C> {
let count = cmp::min(max, verified.len()); let count = cmp::min(max, verified.len());
let result = verified.drain(..count).collect::<Vec<_>>(); let result = verified.drain(..count).collect::<Vec<_>>();
let drained_size = result.iter().map(MallocSizeOfExt::malloc_size_of).fold(0, |a, c| a + c); let drained_size = result.iter().map(MallocSizeOfExt::malloc_size_of).sum();
self.verification.sizes.verified.fetch_sub(drained_size, AtomicOrdering::SeqCst); self.verification.sizes.verified.fetch_sub(drained_size, AtomicOrdering::SeqCst);
self.ready_signal.reset(); self.ready_signal.reset();
@ -636,7 +639,7 @@ impl<K: Kind, C> VerificationQueue<K, C> {
/// Get the total difficulty of all the blocks in the queue. /// Get the total difficulty of all the blocks in the queue.
pub fn total_difficulty(&self) -> U256 { pub fn total_difficulty(&self) -> U256 {
self.total_difficulty.read().clone() *self.total_difficulty.read()
} }
/// Get the current number of working verifiers. /// Get the current number of working verifiers.
@ -806,9 +809,9 @@ mod tests {
let duplicate_import = queue.import(new_unverified(get_good_dummy_block())); let duplicate_import = queue.import(new_unverified(get_good_dummy_block()));
match duplicate_import { match duplicate_import {
Err((_, e)) => { Err(e) => {
match e { match e {
EthcoreError::Import(ImportError::AlreadyQueued) => {}, (EthcoreError::Import(ImportError::AlreadyQueued), _) => {},
_ => { panic!("must return AlreadyQueued error"); } _ => { panic!("must return AlreadyQueued error"); }
} }
} }

View File

@ -20,7 +20,7 @@ use bytes::Bytes;
use hash::{keccak, KECCAK_EMPTY}; use hash::{keccak, KECCAK_EMPTY};
use ethjson; use ethjson;
use call_type::CallType; use action_type::ActionType;
use std::sync::Arc; use std::sync::Arc;
@ -88,8 +88,8 @@ pub struct ActionParams {
pub code_version: U256, pub code_version: U256,
/// Input data. /// Input data.
pub data: Option<Bytes>, pub data: Option<Bytes>,
/// Type of call /// Type of action (e.g. CALL, DELEGATECALL, CREATE, etc.)
pub call_type: CallType, pub action_type: ActionType,
/// Param types encoding /// Param types encoding
pub params_type: ParamsType, pub params_type: ParamsType,
} }
@ -109,7 +109,7 @@ impl Default for ActionParams {
code: None, code: None,
code_version: U256::zero(), code_version: U256::zero(),
data: None, data: None,
call_type: CallType::None, action_type: ActionType::Create,
params_type: ParamsType::Separate, params_type: ParamsType::Separate,
} }
} }
@ -130,7 +130,7 @@ impl From<ethjson::vm::Transaction> for ActionParams {
gas: t.gas.into(), gas: t.gas.into(),
gas_price: t.gas_price.into(), gas_price: t.gas_price.into(),
value: ActionValue::Transfer(t.value.into()), value: ActionValue::Transfer(t.value.into()),
call_type: match address.is_zero() { true => CallType::None, false => CallType::Call }, // TODO @debris is this correct? action_type: ActionType::Call,
params_type: ParamsType::Separate, params_type: ParamsType::Separate,
} }
} }

View File

@ -14,47 +14,51 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! EVM call types. //! EVM action types.
use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp};
/// The type of the call-like instruction. /// The type of the instruction.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum CallType { pub enum ActionType {
/// Not a CALL. /// CREATE.
None, Create,
/// CALL. /// CALL.
Call, Call,
/// CALLCODE. /// CALLCODE.
CallCode, CallCode,
/// DELEGATECALL. /// DELEGATECALL.
DelegateCall, DelegateCall,
/// STATICCALL /// STATICCALL.
StaticCall, StaticCall,
/// CREATE2.
Create2
} }
impl Encodable for CallType { impl Encodable for ActionType {
fn rlp_append(&self, s: &mut RlpStream) { fn rlp_append(&self, s: &mut RlpStream) {
let v = match *self { let v = match *self {
CallType::None => 0u32, ActionType::Create => 0u32,
CallType::Call => 1, ActionType::Call => 1,
CallType::CallCode => 2, ActionType::CallCode => 2,
CallType::DelegateCall => 3, ActionType::DelegateCall => 3,
CallType::StaticCall => 4, ActionType::StaticCall => 4,
ActionType::Create2 => 5,
}; };
Encodable::rlp_append(&v, s); Encodable::rlp_append(&v, s);
} }
} }
impl Decodable for CallType { impl Decodable for ActionType {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> { fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.as_val().and_then(|v| Ok(match v { rlp.as_val().and_then(|v| Ok(match v {
0u32 => CallType::None, 0u32 => ActionType::Create,
1 => CallType::Call, 1 => ActionType::Call,
2 => CallType::CallCode, 2 => ActionType::CallCode,
3 => CallType::DelegateCall, 3 => ActionType::DelegateCall,
4 => CallType::StaticCall, 4 => ActionType::StaticCall,
_ => return Err(DecoderError::Custom("Invalid value of CallType item")), 5 => ActionType::Create2,
_ => return Err(DecoderError::Custom("Invalid value of ActionType item")),
})) }))
} }
} }
@ -62,11 +66,11 @@ impl Decodable for CallType {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rlp::*; use rlp::*;
use super::CallType; use super::ActionType;
#[test] #[test]
fn encode_call_type() { fn encode_call_type() {
let ct = CallType::Call; let ct = ActionType::Call;
let mut s = RlpStream::new_list(2); let mut s = RlpStream::new_list(2);
s.append(&ct); s.append(&ct);
@ -78,9 +82,9 @@ mod tests {
#[test] #[test]
fn should_encode_and_decode_call_type() { fn should_encode_and_decode_call_type() {
let original = CallType::Call; let original = ActionType::Call;
let encoded = encode(&original); let encoded = encode(&original);
let decoded = decode(&encoded).expect("failure decoding CallType"); let decoded = decode(&encoded).expect("failure decoding ActionType");
assert_eq!(original, decoded); assert_eq!(original, decoded);
} }
} }

View File

@ -19,7 +19,7 @@
use std::sync::Arc; use std::sync::Arc;
use ethereum_types::{U256, H256, Address}; use ethereum_types::{U256, H256, Address};
use bytes::Bytes; use bytes::Bytes;
use call_type::CallType; use action_type::ActionType;
use env_info::EnvInfo; use env_info::EnvInfo;
use schedule::Schedule; use schedule::Schedule;
use return_data::ReturnData; use return_data::ReturnData;
@ -115,7 +115,7 @@ pub trait Ext {
value: Option<U256>, value: Option<U256>,
data: &[u8], data: &[u8],
code_address: &Address, code_address: &Address,
call_type: CallType, call_type: ActionType,
trap: bool trap: bool
) -> ::std::result::Result<MessageCallResult, TrapKind>; ) -> ::std::result::Result<MessageCallResult, TrapKind>;

View File

@ -24,7 +24,7 @@ extern crate keccak_hash as hash;
extern crate patricia_trie_ethereum as ethtrie; extern crate patricia_trie_ethereum as ethtrie;
mod action_params; mod action_params;
mod call_type; mod action_type;
mod env_info; mod env_info;
mod schedule; mod schedule;
mod ext; mod ext;
@ -34,7 +34,7 @@ mod error;
pub mod tests; pub mod tests;
pub use action_params::{ActionParams, ActionValue, ParamsType}; pub use action_params::{ActionParams, ActionValue, ParamsType};
pub use call_type::CallType; pub use action_type::ActionType;
pub use env_info::{EnvInfo, LastHashes}; pub use env_info::{EnvInfo, LastHashes};
pub use schedule::{Schedule, VersionedSchedule, CleanDustMode, WasmCosts}; pub use schedule::{Schedule, VersionedSchedule, CleanDustMode, WasmCosts};
pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress}; pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress};

View File

@ -20,7 +20,7 @@ use std::collections::{HashMap, HashSet};
use ethereum_types::{U256, H256, Address}; use ethereum_types::{U256, H256, Address};
use bytes::Bytes; use bytes::Bytes;
use { use {
CallType, Schedule, EnvInfo, ActionType, Schedule, EnvInfo,
ReturnData, Ext, ContractCreateResult, MessageCallResult, ReturnData, Ext, ContractCreateResult, MessageCallResult,
CreateContractAddress, Result, GasLeft, CreateContractAddress, Result, GasLeft,
}; };
@ -185,7 +185,7 @@ impl Ext for FakeExt {
value: Option<U256>, value: Option<U256>,
data: &[u8], data: &[u8],
code_address: &Address, code_address: &Address,
_call_type: CallType, _call_type: ActionType,
_trap: bool, _trap: bool,
) -> ::std::result::Result<MessageCallResult, TrapKind> { ) -> ::std::result::Result<MessageCallResult, TrapKind> {
self.calls.insert(FakeCall { self.calls.insert(FakeCall {

View File

@ -16,7 +16,7 @@
use std::cmp; use std::cmp;
use ethereum_types::{BigEndianHash, U256, H256, Address}; use ethereum_types::{BigEndianHash, U256, H256, Address};
use vm::{self, CallType}; use vm::{self, ActionType};
use wasmi::{self, MemoryRef, RuntimeArgs, RuntimeValue, Error as InterpreterError, Trap, TrapKind}; use wasmi::{self, MemoryRef, RuntimeArgs, RuntimeValue, Error as InterpreterError, Trap, TrapKind};
use super::panic_payload; use super::panic_payload;
@ -384,7 +384,7 @@ impl<'a> Runtime<'a> {
fn do_call( fn do_call(
&mut self, &mut self,
use_val: bool, use_val: bool,
call_type: CallType, call_type: ActionType,
args: RuntimeArgs, args: RuntimeArgs,
) )
-> Result<RuntimeValue> -> Result<RuntimeValue>
@ -445,8 +445,8 @@ impl<'a> Runtime<'a> {
let call_result = self.ext.call( let call_result = self.ext.call(
&gas.into(), &gas.into(),
match call_type { CallType::DelegateCall => &self.context.sender, _ => &self.context.address }, match call_type { ActionType::DelegateCall => &self.context.sender, _ => &self.context.address },
match call_type { CallType::Call | CallType::StaticCall => &address, _ => &self.context.address }, match call_type { ActionType::Call | ActionType::StaticCall => &address, _ => &self.context.address },
val, val,
&payload, &payload,
&address, &address,
@ -487,17 +487,17 @@ impl<'a> Runtime<'a> {
/// Message call /// Message call
fn ccall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> { fn ccall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> {
self.do_call(true, CallType::Call, args) self.do_call(true, ActionType::Call, args)
} }
/// Delegate call /// Delegate call
fn dcall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> { fn dcall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> {
self.do_call(false, CallType::DelegateCall, args) self.do_call(false, ActionType::DelegateCall, args)
} }
/// Static call /// Static call
fn scall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> { fn scall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> {
self.do_call(false, CallType::StaticCall, args) self.do_call(false, ActionType::StaticCall, args)
} }
fn return_address_ptr(&mut self, ptr: u32, val: Address) -> Result<()> fn return_address_ptr(&mut self, ptr: u32, val: Address) -> Result<()>

View File

@ -45,7 +45,7 @@ use ethereum_types::{U256, Address};
use ethcore::{json_tests, test_helpers::TrieSpec}; use ethcore::{json_tests, test_helpers::TrieSpec};
use spec; use spec;
use serde::Deserialize; use serde::Deserialize;
use vm::{ActionParams, CallType}; use vm::{ActionParams, ActionType};
mod info; mod info;
mod display; mod display;
@ -314,7 +314,7 @@ fn run_call<T: Informant>(args: Args, informant: T) {
} }
let mut params = ActionParams::default(); let mut params = ActionParams::default();
params.call_type = if code.is_none() { CallType::Call } else { CallType::None }; params.action_type = if code.is_none() { ActionType::Call } else { ActionType::Create };
params.code = code.map(Arc::new); params.code = code.map(Arc::new);
params.code_address = to; params.code_address = to;
params.address = to; params.address = to;

View File

@ -9,7 +9,6 @@ edition = "2018"
[dependencies] [dependencies]
client-traits = { path = "../ethcore/client-traits" } client-traits = { path = "../ethcore/client-traits" }
common-types = { path = "../ethcore/types" } common-types = { path = "../ethcore/types" }
ethcore = { path = "../ethcore" }
bytes = { package = "parity-bytes", version = "0.1"} bytes = { package = "parity-bytes", version = "0.1"}
ethereum-types = "0.8.0" ethereum-types = "0.8.0"
jsonrpc-core = "14.0.3" jsonrpc-core = "14.0.3"

View File

@ -8,7 +8,7 @@ edition = "2018"
[dependencies] [dependencies]
common-types = { path = "../../ethcore/types" } common-types = { path = "../../ethcore/types" }
ethcore-io = { path = "../../util/io" } ethcore-io = { path = "../../util/io" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
rlp = "0.4.0" rlp = "0.4.0"
serde = "1.0" serde = "1.0"
@ -18,4 +18,4 @@ serde_json = "1.0"
[dev-dependencies] [dev-dependencies]
ethkey = { path = "../../accounts/ethkey" } ethkey = { path = "../../accounts/ethkey" }
parity-crypto = { version = "0.4.2", features = ["publickey"] } parity-crypto = { version = "0.4.2", features = ["publickey"] }
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"

View File

@ -23,7 +23,7 @@ use ethcore::test_helpers::TestBlockChainClient;
use ethereum_types::{Address, H256}; use ethereum_types::{Address, H256};
use types::transaction::CallError; use types::transaction::CallError;
use vm::CallType; use trace::trace::CallType;
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;
use v1::tests::helpers::{TestMinerService}; use v1::tests::helpers::{TestMinerService};
@ -44,7 +44,7 @@ fn io() -> Tester {
value: 0x1.into(), value: 0x1.into(),
gas: 0x100.into(), gas: 0x100.into(),
input: vec![1, 2, 3], input: vec![1, 2, 3],
call_type: CallType::Call, call_type: Some(CallType::Call).into(),
}), }),
result: Res::None, result: Res::None,
subtraces: 0, subtraces: 0,

View File

@ -24,7 +24,6 @@ use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use types::account_diff; use types::account_diff;
use types::state_diff; use types::state_diff;
use vm;
use v1::types::Bytes; use v1::types::Bytes;
@ -214,6 +213,7 @@ impl From<state_diff::StateDiff> for StateDiff {
/// Create response /// Create response
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Create { pub struct Create {
/// Sender /// Sender
from: H160, from: H160,
@ -223,6 +223,9 @@ pub struct Create {
gas: U256, gas: U256,
/// Initialization code /// Initialization code
init: Bytes, init: Bytes,
// Create Type
#[serde(skip_serializing_if="Option::is_none")]
creation_method: Option<CreationMethod>,
} }
impl From<trace::Create> for Create { impl From<trace::Create> for Create {
@ -232,6 +235,7 @@ impl From<trace::Create> for Create {
value: c.value, value: c.value,
gas: c.gas, gas: c.gas,
init: Bytes::new(c.init), init: Bytes::new(c.init),
creation_method: c.creation_method.map(|c| c.into()),
} }
} }
} }
@ -240,8 +244,6 @@ impl From<trace::Create> for Create {
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum CallType { pub enum CallType {
/// None
None,
/// Call /// Call
Call, Call,
/// Call code /// Call code
@ -252,14 +254,32 @@ pub enum CallType {
StaticCall, StaticCall,
} }
impl From<vm::CallType> for CallType { impl From<trace::CallType> for CallType {
fn from(c: vm::CallType) -> Self { fn from(c: trace::CallType) -> Self {
match c { match c {
vm::CallType::None => CallType::None, trace::CallType::Call => CallType::Call,
vm::CallType::Call => CallType::Call, trace::CallType::CallCode => CallType::CallCode,
vm::CallType::CallCode => CallType::CallCode, trace::CallType::DelegateCall => CallType::DelegateCall,
vm::CallType::DelegateCall => CallType::DelegateCall, trace::CallType::StaticCall => CallType::StaticCall,
vm::CallType::StaticCall => CallType::StaticCall, }
}
}
/// Create type.
#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum CreationMethod {
/// Create
Create,
/// Create2
Create2,
}
impl From<trace::CreationMethod> for CreationMethod {
fn from(c: trace::CreationMethod) -> Self {
match c {
trace::CreationMethod::Create => CreationMethod::Create,
trace::CreationMethod::Create2 => CreationMethod::Create2,
} }
} }
} }
@ -279,18 +299,19 @@ pub struct Call {
/// Input data /// Input data
input: Bytes, input: Bytes,
/// The type of the call. /// The type of the call.
call_type: CallType, call_type: Option<CallType>,
} }
impl From<trace::Call> for Call { impl From<trace::Call> for Call {
fn from(c: trace::Call) -> Self { fn from(c: trace::Call) -> Self {
let optional: Option<trace::CallType> = c.call_type.0;
Call { Call {
from: c.from, from: c.from,
to: c.to, to: c.to,
value: c.value, value: c.value,
gas: c.gas, gas: c.gas,
input: c.input.into(), input: c.input.into(),
call_type: c.call_type.into(), call_type: optional.map(|c| c.into()),
} }
} }
} }
@ -681,7 +702,7 @@ mod tests {
value: 6.into(), value: 6.into(),
gas: 7.into(), gas: 7.into(),
input: Bytes::new(vec![0x12, 0x34]), input: Bytes::new(vec![0x12, 0x34]),
call_type: CallType::Call, call_type: Some(CallType::Call),
}), }),
result: Res::Call(CallResult { result: Res::Call(CallResult {
gas_used: 8.into(), gas_used: 8.into(),
@ -707,7 +728,7 @@ mod tests {
value: 6.into(), value: 6.into(),
gas: 7.into(), gas: 7.into(),
input: Bytes::new(vec![0x12, 0x34]), input: Bytes::new(vec![0x12, 0x34]),
call_type: CallType::Call, call_type: Some(CallType::Call),
}), }),
result: Res::FailedCall(TraceError::OutOfGas), result: Res::FailedCall(TraceError::OutOfGas),
trace_address: vec![10], trace_address: vec![10],
@ -729,6 +750,7 @@ mod tests {
value: 6.into(), value: 6.into(),
gas: 7.into(), gas: 7.into(),
init: Bytes::new(vec![0x12, 0x34]), init: Bytes::new(vec![0x12, 0x34]),
creation_method: Some(CreationMethod::Create).into(),
}), }),
result: Res::Create(CreateResult { result: Res::Create(CreateResult {
gas_used: 8.into(), gas_used: 8.into(),
@ -743,7 +765,7 @@ mod tests {
block_hash: H256::from_low_u64_be(14), block_hash: H256::from_low_u64_be(14),
}; };
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"type":"create","action":{"from":"0x0000000000000000000000000000000000000004","value":"0x6","gas":"0x7","init":"0x1234"},"result":{"gasUsed":"0x8","code":"0x5678","address":"0x00000000000000000000000000000000000000ff"},"traceAddress":[10],"subtraces":1,"transactionPosition":11,"transactionHash":"0x000000000000000000000000000000000000000000000000000000000000000c","blockNumber":13,"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#); assert_eq!(serialized, r#"{"type":"create","action":{"from":"0x0000000000000000000000000000000000000004","value":"0x6","gas":"0x7","init":"0x1234","creationMethod":"create"},"result":{"gasUsed":"0x8","code":"0x5678","address":"0x00000000000000000000000000000000000000ff"},"traceAddress":[10],"subtraces":1,"transactionPosition":11,"transactionHash":"0x000000000000000000000000000000000000000000000000000000000000000c","blockNumber":13,"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#);
} }
#[test] #[test]
@ -754,6 +776,7 @@ mod tests {
value: 6.into(), value: 6.into(),
gas: 7.into(), gas: 7.into(),
init: Bytes::new(vec![0x12, 0x34]), init: Bytes::new(vec![0x12, 0x34]),
creation_method: Some(CreationMethod::Create).into(),
}), }),
result: Res::FailedCreate(TraceError::OutOfGas), result: Res::FailedCreate(TraceError::OutOfGas),
trace_address: vec![10], trace_address: vec![10],
@ -764,7 +787,7 @@ mod tests {
block_hash: H256::from_low_u64_be(14), block_hash: H256::from_low_u64_be(14),
}; };
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"type":"create","action":{"from":"0x0000000000000000000000000000000000000004","value":"0x6","gas":"0x7","init":"0x1234"},"error":"Out of gas","traceAddress":[10],"subtraces":1,"transactionPosition":11,"transactionHash":"0x000000000000000000000000000000000000000000000000000000000000000c","blockNumber":13,"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#); assert_eq!(serialized, r#"{"type":"create","action":{"from":"0x0000000000000000000000000000000000000004","value":"0x6","gas":"0x7","init":"0x1234","creationMethod":"create"},"error":"Out of gas","traceAddress":[10],"subtraces":1,"transactionPosition":11,"transactionHash":"0x000000000000000000000000000000000000000000000000000000000000000c","blockNumber":13,"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#);
} }
#[test] #[test]

View File

@ -5,8 +5,8 @@ echo "________Running test-linux.sh________"
set -e # fail on any error set -e # fail on any error
set -u # treat unset variables as error set -u # treat unset variables as error
export CC="sccache gcc" export CC="sccache "$CC
export CXX="sccache g++" export CXX="sccache "$CXX
FEATURES="json-tests" FEATURES="json-tests"
OPTIONS="--release" OPTIONS="--release"

View File

@ -15,8 +15,8 @@ ethkey = { path = "../accounts/ethkey", optional = true }
futures = "0.1" futures = "0.1"
hyper = { version = "0.12", default-features = false } hyper = { version = "0.12", default-features = false }
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
kvdb = "0.2" kvdb = "0.3.1"
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"
lazy_static = "1.0" lazy_static = "1.0"
log = "0.4" log = "0.4"
parity-bytes = "0.1" parity-bytes = "0.1"
@ -38,4 +38,4 @@ jsonrpc-server-utils = "14.0.3"
[dev-dependencies] [dev-dependencies]
env_logger = "0.5" env_logger = "0.5"
tempdir = "0.3" tempdir = "0.3"
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"

View File

@ -11,11 +11,11 @@ license = "GPL-3.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
rustc-hex = "2.0.1"
arrayref = "0.3.5" arrayref = "0.3.5"
[dev-dependencies] [dev-dependencies]
criterion = "0.3" criterion = "0.3"
rustc-hex = "2.0.1"
[[bench]] [[bench]]
name = "bench" name = "bench"

View File

@ -12,7 +12,7 @@ ethereum-types = "0.8.0"
hash-db = "0.15.0" hash-db = "0.15.0"
malloc_size_of = { version = "0.3.0", package = "parity-util-mem" } malloc_size_of = { version = "0.3.0", package = "parity-util-mem" }
keccak-hasher = { path = "../keccak-hasher" } keccak-hasher = { path = "../keccak-hasher" }
kvdb = "0.2" kvdb = "0.3.1"
log = "0.4" log = "0.4"
memory-db = "0.18.0" memory-db = "0.18.0"
parking_lot = "0.9" parking_lot = "0.9"
@ -22,4 +22,4 @@ rlp = "0.4.0"
[dev-dependencies] [dev-dependencies]
env_logger = "0.5" env_logger = "0.5"
keccak-hash = "0.4.0" keccak-hash = "0.4.0"
kvdb-memorydb = "0.2.0" kvdb-memorydb = "0.3.1"

View File

@ -20,6 +20,7 @@ use std::{
collections::{HashMap, hash_map::Entry}, collections::{HashMap, hash_map::Entry},
io, io,
sync::Arc, sync::Arc,
time::Duration,
}; };
use ethereum_types::H256; use ethereum_types::H256;
@ -279,11 +280,22 @@ impl JournalDB for OverlayRecentDB {
fn earliest_era(&self) -> Option<u64> { self.journal_overlay.read().earliest_era } fn earliest_era(&self) -> Option<u64> { self.journal_overlay.read().earliest_era }
fn state(&self, key: &H256) -> Option<Bytes> { fn state(&self, key: &H256) -> Option<Bytes> {
let journal_overlay = self.journal_overlay.read();
let key = to_short_key(key); let key = to_short_key(key);
journal_overlay.backing_overlay.get(&key, EMPTY_PREFIX) // Hold the read lock for shortest possible amount of time.
let maybe_state_data = {
let journal_overlay = self.journal_overlay.read();
journal_overlay
.backing_overlay
.get(&key, EMPTY_PREFIX)
.or_else(|| journal_overlay.pending_overlay.get(&key).map(|d| d.clone())) .or_else(|| journal_overlay.pending_overlay.get(&key).map(|d| d.clone()))
.or_else(|| self.backing.get_by_prefix(self.column, &key[0..DB_PREFIX_LEN]).map(|b| b.to_vec())) };
maybe_state_data.or_else(|| {
let pkey = &key[..DB_PREFIX_LEN];
self.backing
.get_by_prefix(self.column, &pkey)
.map(|b| b.to_vec())
})
} }
fn journal_under(&mut self, batch: &mut DBTransaction, now: u64, id: &H256) -> io::Result<u32> { fn journal_under(&mut self, batch: &mut DBTransaction, now: u64, id: &H256) -> io::Result<u32> {

View File

@ -6,8 +6,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
log = "0.4" log = "0.4"
macros = { path = "../macros" } macros = { path = "../macros" }
kvdb = "0.2" kvdb = "0.3.1"
kvdb-rocksdb = "0.3.0" kvdb-rocksdb = "0.4.1"
[dev-dependencies] [dev-dependencies]
tempdir = "0.3" tempdir = "0.3"

View File

@ -40,11 +40,11 @@ use crate::handshake::Handshake;
const ENCRYPTED_HEADER_LEN: usize = 32; const ENCRYPTED_HEADER_LEN: usize = 32;
const RECEIVE_PAYLOAD: Duration = Duration::from_secs(30); const RECEIVE_PAYLOAD: Duration = Duration::from_secs(30);
pub const MAX_PAYLOAD_SIZE: usize = (1 << 24) - 1; pub const MAX_PAYLOAD_SIZE: usize = (1 << 24) - 1; // 16Mb
/// Network responses should try not to go over this limit. /// Network responses should try not to go over this limit.
/// This should be lower than MAX_PAYLOAD_SIZE /// This should be lower than MAX_PAYLOAD_SIZE
pub const PAYLOAD_SOFT_LIMIT: usize = (1 << 22) - 1; pub const PAYLOAD_SOFT_LIMIT: usize = (1 << 22) - 1; // 4Mb
pub trait GenericSocket : Read + Write { pub trait GenericSocket : Read + Write {
} }

View File

@ -1,16 +1,17 @@
[package] [package]
name = "rlp_derive" name = "rlp_derive"
version = "0.1.0" version = "0.1.0"
authors = ["debris <marek.kotewicz@gmail.com>"] authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[lib] [lib]
name = "rlp_derive" name = "rlp_derive"
proc-macro = true proc-macro = true
[dependencies] [dependencies]
syn = "0.15" syn = "1.0.14"
quote = "0.6" quote = "1.0.2"
proc-macro2 = "0.4" proc-macro2 = "1.0.8"
[dev-dependencies] [dev-dependencies]
rlp = "0.4.0" rlp = "0.4.0"

View File

@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use syn; use proc_macro2::TokenStream;
use proc_macro2::{TokenStream, Span}; use quote::quote;
struct ParseQuotes { struct ParseQuotes {
single: TokenStream, single: TokenStream,
@ -45,10 +45,19 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream {
_ => panic!("#[derive(RlpDecodable)] is only defined for structs."), _ => panic!("#[derive(RlpDecodable)] is only defined for structs."),
}; };
let stmts: Vec<_> = body.fields.iter().enumerate().map(decodable_field_map).collect(); let mut default_attribute_encountered = false;
let stmts: Vec<_> = body
.fields
.iter()
.enumerate()
.map(|(i, field)| decodable_field(
i,
field,
decodable_parse_quotes(),
&mut default_attribute_encountered,
)).collect();
let name = &ast.ident; let name = &ast.ident;
let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site());
let impl_block = quote! { let impl_block = quote! {
impl rlp::Decodable for #name { impl rlp::Decodable for #name {
fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> { fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
@ -62,8 +71,7 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream {
}; };
quote! { quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] const _: () = {
const #dummy_const: () = {
extern crate rlp; extern crate rlp;
#impl_block #impl_block
}; };
@ -80,7 +88,13 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
let fields: Vec<_> = body.fields.iter().collect(); let fields: Vec<_> = body.fields.iter().collect();
if fields.len() == 1 { if fields.len() == 1 {
let field = fields.first().expect("fields.len() == 1; qed"); let field = fields.first().expect("fields.len() == 1; qed");
decodable_field(0, field, decodable_wrapper_parse_quotes()) let mut default_attribute_encountered = false;
decodable_field(
0,
field,
decodable_wrapper_parse_quotes(),
&mut default_attribute_encountered,
)
} else { } else {
panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.") panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.")
} }
@ -88,7 +102,6 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident; let name = &ast.ident;
let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site());
let impl_block = quote! { let impl_block = quote! {
impl rlp::Decodable for #name { impl rlp::Decodable for #name {
fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> { fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
@ -102,19 +115,19 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
}; };
quote! { quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] const _: () = {
const #dummy_const: () = {
extern crate rlp; extern crate rlp;
#impl_block #impl_block
}; };
} }
} }
fn decodable_field_map(tuple: (usize, &syn::Field)) -> TokenStream { fn decodable_field(
decodable_field(tuple.0, tuple.1, decodable_parse_quotes()) index: usize,
} field: &syn::Field,
quotes: ParseQuotes,
fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> TokenStream { default_attribute_encountered: &mut bool,
) -> TokenStream {
let id = match field.ident { let id = match field.ident {
Some(ref ident) => quote! { #ident }, Some(ref ident) => quote! { #ident },
None => { None => {
@ -123,28 +136,58 @@ fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> Tok
} }
}; };
let index = index - *default_attribute_encountered as usize;
let index = quote! { #index }; let index = quote! { #index };
let single = quotes.single; let single = quotes.single;
let list = quotes.list; let list = quotes.list;
let attributes = &field.attrs;
let default = if let Some(attr) = attributes.iter().find(|attr| attr.path.is_ident("rlp")) {
if *default_attribute_encountered {
panic!("only 1 #[rlp(default)] attribute is allowed in a struct")
}
match attr.parse_args() {
Ok(proc_macro2::TokenTree::Ident(ident)) if ident.to_string() == "default" => {},
_ => panic!("only #[rlp(default)] attribute is supported"),
}
*default_attribute_encountered = true;
true
} else {
false
};
match field.ty { match field.ty {
syn::Type::Path(ref path) => { syn::Type::Path(ref path) => {
let ident = &path.path.segments.first().expect("there must be at least 1 segment").value().ident; let ident = &path
if &ident.to_string() == "Vec" { .path
.segments
.first()
.expect("there must be at least 1 segment")
.ident;
let ident_type = ident.to_string();
if &ident_type == "Vec" {
if quotes.takes_index { if quotes.takes_index {
if default {
quote! { #id: #list(#index).unwrap_or_default(), }
} else {
quote! { #id: #list(#index)?, } quote! { #id: #list(#index)?, }
}
} else { } else {
quote! { #id: #list()?, } quote! { #id: #list()?, }
} }
} else { } else {
if quotes.takes_index { if quotes.takes_index {
if default {
quote! { #id: #single(#index).unwrap_or_default(), }
} else {
quote! { #id: #single(#index)?, } quote! { #id: #single(#index)?, }
}
} else { } else {
quote! { #id: #single()?, } quote! { #id: #single()?, }
} }
} }
}, }
_ => panic!("rlp_derive not supported"), _ => panic!("rlp_derive not supported"),
} }
} }

View File

@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use syn; use proc_macro2::TokenStream;
use proc_macro2::{TokenStream, Span}; use quote::quote;
pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream { pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream {
let body = match ast.data { let body = match ast.data {
@ -23,12 +23,16 @@ pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream {
_ => panic!("#[derive(RlpEncodable)] is only defined for structs."), _ => panic!("#[derive(RlpEncodable)] is only defined for structs."),
}; };
let stmts: Vec<_> = body.fields.iter().enumerate().map(encodable_field_map).collect(); let stmts: Vec<_> = body
.fields
.iter()
.enumerate()
.map(|(i, field)| encodable_field(i, field))
.collect();
let name = &ast.ident; let name = &ast.ident;
let stmts_len = stmts.len(); let stmts_len = stmts.len();
let stmts_len = quote! { #stmts_len }; let stmts_len = quote! { #stmts_len };
let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_ENCODABLE_FOR_{}", name), Span::call_site());
let impl_block = quote! { let impl_block = quote! {
impl rlp::Encodable for #name { impl rlp::Encodable for #name {
fn rlp_append(&self, stream: &mut rlp::RlpStream) { fn rlp_append(&self, stream: &mut rlp::RlpStream) {
@ -39,8 +43,7 @@ pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream {
}; };
quote! { quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] const _: () = {
const #dummy_const: () = {
extern crate rlp; extern crate rlp;
#impl_block #impl_block
}; };
@ -65,7 +68,6 @@ pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident; let name = &ast.ident;
let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_ENCODABLE_FOR_{}", name), Span::call_site());
let impl_block = quote! { let impl_block = quote! {
impl rlp::Encodable for #name { impl rlp::Encodable for #name {
fn rlp_append(&self, stream: &mut rlp::RlpStream) { fn rlp_append(&self, stream: &mut rlp::RlpStream) {
@ -75,18 +77,13 @@ pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
}; };
quote! { quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] const _: () = {
const #dummy_const: () = {
extern crate rlp; extern crate rlp;
#impl_block #impl_block
}; };
} }
} }
fn encodable_field_map(tuple: (usize, &syn::Field)) -> TokenStream {
encodable_field(tuple.0, tuple.1)
}
fn encodable_field(index: usize, field: &syn::Field) -> TokenStream { fn encodable_field(index: usize, field: &syn::Field) -> TokenStream {
let ident = match field.ident { let ident = match field.ident {
Some(ref ident) => quote! { #ident }, Some(ref ident) => quote! { #ident },
@ -100,24 +97,38 @@ fn encodable_field(index: usize, field: &syn::Field) -> TokenStream {
match field.ty { match field.ty {
syn::Type::Path(ref path) => { syn::Type::Path(ref path) => {
let top_segment = path.path.segments.first().expect("there must be at least 1 segment"); let top_segment = path
let ident = &top_segment.value().ident; .path
.segments
.first()
.expect("there must be at least 1 segment");
let ident = &top_segment.ident;
if &ident.to_string() == "Vec" { if &ident.to_string() == "Vec" {
let inner_ident = match top_segment.value().arguments { let inner_ident = match top_segment.arguments {
syn::PathArguments::AngleBracketed(ref angle) => { syn::PathArguments::AngleBracketed(ref angle) => {
let ty = angle.args.first().expect("Vec has only one angle bracketed type; qed"); let ty = angle
match **ty.value() { .args
syn::GenericArgument::Type(syn::Type::Path(ref path)) => &path.path.segments.first().expect("there must be at least 1 segment").value().ident, .first()
.expect("Vec has only one angle bracketed type; qed");
match *ty {
syn::GenericArgument::Type(syn::Type::Path(ref path)) => {
&path
.path
.segments
.first()
.expect("there must be at least 1 segment")
.ident
}
_ => panic!("rlp_derive not supported"), _ => panic!("rlp_derive not supported"),
} }
}, }
_ => unreachable!("Vec has only one angle bracketed type; qed"), _ => unreachable!("Vec has only one angle bracketed type; qed"),
}; };
quote! { stream.append_list::<#inner_ident, _>(&#id); } quote! { stream.append_list::<#inner_ident, _>(&#id); }
} else { } else {
quote! { stream.append(&#id); } quote! { stream.append(&#id); }
} }
}, }
_ => panic!("rlp_derive not supported"), _ => panic!("rlp_derive not supported"),
} }
} }

View File

@ -15,19 +15,15 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
extern crate proc_macro; extern crate proc_macro;
extern crate proc_macro2;
extern crate syn;
#[macro_use]
extern crate quote;
mod en;
mod de; mod de;
mod en;
use proc_macro::TokenStream;
use en::{impl_encodable, impl_encodable_wrapper};
use de::{impl_decodable, impl_decodable_wrapper}; use de::{impl_decodable, impl_decodable_wrapper};
use en::{impl_encodable, impl_encodable_wrapper};
use proc_macro::TokenStream;
#[proc_macro_derive(RlpEncodable)] #[proc_macro_derive(RlpEncodable, attributes(rlp))]
pub fn encodable(input: TokenStream) -> TokenStream { pub fn encodable(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap(); let ast = syn::parse(input).unwrap();
let gen = impl_encodable(&ast); let gen = impl_encodable(&ast);
@ -41,7 +37,7 @@ pub fn encodable_wrapper(input: TokenStream) -> TokenStream {
gen.into() gen.into()
} }
#[proc_macro_derive(RlpDecodable)] #[proc_macro_derive(RlpDecodable, attributes(rlp))]
pub fn decodable(input: TokenStream) -> TokenStream { pub fn decodable(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap(); let ast = syn::parse(input).unwrap();
let gen = impl_decodable(&ast); let gen = impl_decodable(&ast);

View File

@ -14,11 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
extern crate rlp; use rlp::{decode, encode};
#[macro_use] use rlp_derive::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
extern crate rlp_derive;
use rlp::{encode, decode};
#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)] #[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
struct Foo { struct Foo {
@ -32,9 +29,7 @@ struct FooWrapper {
#[test] #[test]
fn test_encode_foo() { fn test_encode_foo() {
let foo = Foo { let foo = Foo { a: "cat".into() };
a: "cat".into(),
};
let expected = vec![0xc4, 0x83, b'c', b'a', b't']; let expected = vec![0xc4, 0x83, b'c', b'a', b't'];
let out = encode(&foo); let out = encode(&foo);
@ -46,9 +41,7 @@ fn test_encode_foo() {
#[test] #[test]
fn test_encode_foo_wrapper() { fn test_encode_foo_wrapper() {
let foo = FooWrapper { let foo = FooWrapper { a: "cat".into() };
a: "cat".into(),
};
let expected = vec![0x83, b'c', b'a', b't']; let expected = vec![0x83, b'c', b'a', b't'];
let out = encode(&foo); let out = encode(&foo);
@ -57,3 +50,30 @@ fn test_encode_foo_wrapper() {
let decoded = decode(&expected).expect("decode failure"); let decoded = decode(&expected).expect("decode failure");
assert_eq!(foo, decoded); assert_eq!(foo, decoded);
} }
#[test]
fn test_encode_foo_default() {
#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
struct FooDefault {
a: String,
/// It works with other attributes.
#[rlp(default)]
b: Option<Vec<u8>>,
}
let attack_of = String::from("clones");
let foo = Foo { a: attack_of.clone() };
let expected = vec![0xc7, 0x86, b'c', b'l', b'o', b'n', b'e', b's'];
let out = encode(&foo);
assert_eq!(out, expected);
let foo_default = FooDefault { a: attack_of.clone(), b: None };
let decoded = decode(&expected).expect("default failure");
assert_eq!(foo_default, decoded);
let foo_some = FooDefault { a: attack_of.clone(), b: Some(vec![1, 2, 3]) };
let out = encode(&foo_some);
assert_eq!(decode(&out), Ok(foo_some));
}

View File

@ -3,7 +3,7 @@
[package] [package]
name = "parity-version" name = "parity-version"
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
version = "2.7.1" version = "2.7.2"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"