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:
parent
6885be06a4
commit
d961010f63
@ -165,8 +165,6 @@ build-darwin:
|
||||
variables:
|
||||
CARGO_TARGET: x86_64-apple-darwin
|
||||
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
script:
|
||||
- scripts/gitlab/build-linux.sh
|
||||
tags:
|
||||
|
22
CHANGELOG.md
22
CHANGELOG.md
@ -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-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
|
||||
|
5463
Cargo.lock
generated
5463
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity-ethereum"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "2.7.1"
|
||||
version = "2.7.2"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
@ -41,8 +41,8 @@ futures = "0.1"
|
||||
journaldb = { path = "util/journaldb" }
|
||||
jsonrpc-core = "14.0.3"
|
||||
keccak-hash = "0.4.0"
|
||||
kvdb = "0.2"
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb = "0.3.1"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
log = "0.4"
|
||||
migration-rocksdb = { path = "util/migration-rocksdb" }
|
||||
node-filter = { path = "ethcore/node-filter" }
|
||||
|
@ -31,9 +31,9 @@ hash-db = "0.15.0"
|
||||
itertools = "0.5"
|
||||
journaldb = { path = "../util/journaldb" }
|
||||
keccak-hash = "0.4.0"
|
||||
kvdb = "0.2"
|
||||
kvdb-memorydb = { version = "0.2.0", optional = true }
|
||||
kvdb-rocksdb = { version = "0.3.0", optional = true }
|
||||
kvdb = "0.3.1"
|
||||
kvdb-memorydb = { version = "0.3.1", optional = true }
|
||||
kvdb-rocksdb = { version = "0.4.1", optional = true }
|
||||
lazy_static = { version = "1.3", optional = true }
|
||||
log = "0.4"
|
||||
macros = { path = "../util/macros", optional = true }
|
||||
@ -78,8 +78,8 @@ ethcore-builtin = { path = "./builtin" }
|
||||
ethjson = { path = "../json", features = ["test-helpers"] }
|
||||
parity-crypto = { version = "0.4.2", features = ["publickey"] }
|
||||
fetch = { path = "../util/fetch" }
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
lazy_static = "1.3"
|
||||
machine = { path = "./machine", features = ["test-helpers"] }
|
||||
macros = { path = "../util/macros" }
|
||||
|
@ -11,5 +11,5 @@ ethereum-types = "0.8.0"
|
||||
hash-db = "0.15.0"
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
rlp = "0.4"
|
||||
|
@ -16,7 +16,7 @@ hash-db = "0.15.0"
|
||||
journaldb = { path = "../../util/journaldb" }
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
lru-cache = "0.1.2"
|
||||
memory-db = "0.18.0"
|
||||
@ -26,7 +26,6 @@ parking_lot = "0.9"
|
||||
pod = { path = "../pod" }
|
||||
rlp = "0.4.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
trace = { path = "../trace" }
|
||||
trie-db = "0.18.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -16,7 +16,7 @@ ethereum-types = "0.8.0"
|
||||
keccak-hash = "0.4.0"
|
||||
parity-util-mem = "0.3.0"
|
||||
itertools = "0.5"
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
parity-bytes = "0.1"
|
||||
rand = "0.7"
|
||||
@ -32,4 +32,4 @@ env_logger = "0.5"
|
||||
parity-crypto = { version = "0.4.2", features = ["publickey"] }
|
||||
rustc-hex = "1.0"
|
||||
tempdir = "0.3"
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
|
@ -14,10 +14,10 @@ ethereum-types = "0.8.0"
|
||||
ethjson = { path = "../../json" }
|
||||
keccak-hash = "0.4.0"
|
||||
log = "0.4"
|
||||
macros = { path = "../../util/macros" }
|
||||
num = { version = "0.1", default-features = false, features = ["bigint"] }
|
||||
parity-bytes = "0.1"
|
||||
parity-crypto = { version = "0.4.2", features = ["publickey"] }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.2.1"
|
||||
macros = { path = "../../util/macros" }
|
||||
|
@ -15,7 +15,7 @@ common-types = { path = "../types" }
|
||||
ethcore-db = { path = "../db" }
|
||||
ethcore-miner = { path = "../../miner" }
|
||||
ethereum-types = "0.8.0"
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
registrar = { path = "../../util/registrar" }
|
||||
stats = { path = "../../util/stats" }
|
||||
trace = { path = "../trace" }
|
||||
|
@ -10,7 +10,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
common-types = { path = "../types" }
|
||||
ethereum-types = "0.8.0"
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
parity-util-mem = "0.3.0"
|
||||
parking_lot = "0.9"
|
||||
rlp = "0.4.0"
|
||||
|
@ -42,7 +42,7 @@ use machine::{
|
||||
Machine,
|
||||
executed_block::ExecutedBlock,
|
||||
};
|
||||
use vm::{EnvInfo, Schedule, CallType, ActionValue};
|
||||
use vm::{EnvInfo, Schedule, ActionType, ActionValue};
|
||||
|
||||
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())),
|
||||
U256::max_value(),
|
||||
Some(data),
|
||||
Some(CallType::StaticCall),
|
||||
Some(ActionType::StaticCall),
|
||||
)
|
||||
},
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ ethereum-types = "0.8.0"
|
||||
ethjson = { path = "../../../json" }
|
||||
executive-state = { path = "../../executive-state" }
|
||||
keccak-hash = "0.4.0"
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
lazy_static = "1.3.0"
|
||||
log = "0.4.8"
|
||||
machine = { path = "../../machine" }
|
||||
|
@ -33,7 +33,7 @@ use ethereum_types::{U256, U512, H256, Address, BigEndianHash};
|
||||
|
||||
|
||||
use vm::{
|
||||
self, ActionParams, ParamsType, ActionValue, CallType, MessageCallResult,
|
||||
self, ActionParams, ParamsType, ActionValue, ActionType, MessageCallResult,
|
||||
ContractCreateResult, CreateContractAddress, ReturnData, GasLeft, Schedule,
|
||||
TrapKind, TrapError
|
||||
};
|
||||
@ -133,8 +133,8 @@ struct InterpreterParams {
|
||||
pub value: ActionValue,
|
||||
/// Input data.
|
||||
pub data: Option<Bytes>,
|
||||
/// Type of call
|
||||
pub call_type: CallType,
|
||||
/// Type of action
|
||||
pub action_type: ActionType,
|
||||
/// Param types encoding
|
||||
pub params_type: ParamsType,
|
||||
}
|
||||
@ -152,7 +152,7 @@ impl From<ActionParams> for InterpreterParams {
|
||||
gas_price: params.gas_price,
|
||||
value: params.value,
|
||||
data: params.data,
|
||||
call_type: params.call_type,
|
||||
action_type: params.action_type,
|
||||
params_type: params.params_type,
|
||||
}
|
||||
}
|
||||
@ -532,7 +532,9 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
let init_size = self.stack.pop_back();
|
||||
let address_scheme = match instruction {
|
||||
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"),
|
||||
};
|
||||
|
||||
@ -553,7 +555,14 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
|
||||
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 {
|
||||
Ok(ContractCreateResult::Created(address, gas_left)) => {
|
||||
self.stack.push(address_to_u256(address));
|
||||
@ -607,14 +616,14 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
return Err(vm::Error::MutableCallInStaticContext);
|
||||
}
|
||||
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 => {
|
||||
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::STATICCALL => (&self.params.address, &code_address, true, CallType::StaticCall),
|
||||
instructions::DELEGATECALL => (&self.params.sender, &self.params.address, true, ActionType::DelegateCall),
|
||||
instructions::STATICCALL => (&self.params.address, &code_address, true, ActionType::StaticCall),
|
||||
_ => panic!(format!("Unexpected instruction {:?} in CALL branch.", instruction))
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ mod instructions;
|
||||
mod tests;
|
||||
|
||||
pub use vm::{
|
||||
Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext,
|
||||
Schedule, CleanDustMode, EnvInfo, ActionType, ActionParams, Ext,
|
||||
ContractCreateResult, MessageCallResult, CreateContractAddress,
|
||||
GasLeft, ReturnData
|
||||
};
|
||||
|
@ -14,7 +14,7 @@ common-types = { path = "../types" }
|
||||
ethereum-types = "0.8.0"
|
||||
hash-db = "0.15.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4.8"
|
||||
machine = { path = "../machine" }
|
||||
trace = { path = "../trace" }
|
||||
|
@ -276,7 +276,6 @@ mod tests {
|
||||
test_helpers::{get_temp_state, get_temp_state_db}
|
||||
};
|
||||
use ethtrie;
|
||||
use evm::CallType;
|
||||
use machine::Machine;
|
||||
use pod::{self, PodAccount, PodState};
|
||||
use rustc_hex::FromHex;
|
||||
@ -324,6 +323,7 @@ mod tests {
|
||||
value: 100.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],
|
||||
creation_method: Some(trace::CreationMethod::Create),
|
||||
}),
|
||||
result: trace::Res::Create(trace::CreateResult {
|
||||
gas_used: U256::from(3224),
|
||||
@ -381,6 +381,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 78792.into(),
|
||||
init: vec![91, 96, 0, 86],
|
||||
creation_method: Some(trace::CreationMethod::Create),
|
||||
}),
|
||||
result: trace::Res::FailedCreate(TraceError::OutOfGas),
|
||||
subtraces: 0
|
||||
@ -419,7 +420,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(3),
|
||||
@ -460,7 +461,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(0),
|
||||
@ -501,7 +502,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 79_000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(3000),
|
||||
@ -543,7 +544,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(3_721), // in post-eip150
|
||||
@ -587,7 +588,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 724.into(), // in post-eip150
|
||||
@ -602,7 +603,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 4096.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::CallCode,
|
||||
call_type: Some(trace::CallType::CallCode).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 3.into(),
|
||||
@ -646,7 +647,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(736), // in post-eip150
|
||||
@ -661,7 +662,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 32768.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::DelegateCall,
|
||||
call_type: Some(trace::CallType::DelegateCall).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 18.into(),
|
||||
@ -702,7 +703,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::FailedCall(TraceError::OutOfGas),
|
||||
subtraces: 0,
|
||||
@ -744,7 +745,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(69),
|
||||
@ -759,7 +760,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 78934.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(3),
|
||||
@ -801,7 +802,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(31761),
|
||||
@ -816,7 +817,7 @@ mod tests {
|
||||
value: 69.into(),
|
||||
gas: 2300.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult::default()),
|
||||
}];
|
||||
@ -855,7 +856,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(31761),
|
||||
@ -898,7 +899,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(79_000),
|
||||
@ -913,7 +914,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 78934.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::FailedCall(TraceError::OutOfGas),
|
||||
}];
|
||||
@ -954,7 +955,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(135),
|
||||
@ -969,7 +970,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 78934.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(69),
|
||||
@ -984,7 +985,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 78868.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(3),
|
||||
@ -1029,7 +1030,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(79_000),
|
||||
@ -1044,7 +1045,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 78934.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::FailedCall(TraceError::OutOfGas),
|
||||
}, FlatTrace {
|
||||
@ -1055,7 +1056,7 @@ mod tests {
|
||||
to: Address::from_low_u64_be(0xc),
|
||||
value: 0.into(),
|
||||
gas: 78868.into(),
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
input: vec![],
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
@ -1099,7 +1100,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 79000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 3.into(),
|
||||
|
@ -43,14 +43,14 @@ stats = { path = "../../util/stats" }
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
memory-cache = { path = "../../util/memory-cache" }
|
||||
journaldb = { path = "../../util/journaldb" }
|
||||
verification = { path = "../verification" }
|
||||
|
||||
[dev-dependencies]
|
||||
ethcore = { path = "..", features = ["test-helpers"] }
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
tempdir = "0.3"
|
||||
|
||||
[features]
|
||||
|
@ -220,7 +220,7 @@ impl<T: ChainDataFetcher> Client<T> {
|
||||
|
||||
/// Import a header to the queue for additional verification.
|
||||
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.
|
||||
|
@ -26,7 +26,7 @@ use rlp::RlpStream;
|
||||
use log::trace;
|
||||
|
||||
use account_state::{Backend as StateBackend, State, CleanupMode};
|
||||
use evm::{CallType, Finalize, FinalizationResult};
|
||||
use evm::{ActionType, Finalize, FinalizationResult};
|
||||
use vm::{
|
||||
self, EnvInfo, CreateContractAddress, ReturnData, CleanDustMode, ActionParams,
|
||||
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);
|
||||
|
||||
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
|
||||
let kind = if let Some(builtin) = machine.builtin(¶ms.code_address, info.number) {
|
||||
@ -298,7 +298,7 @@ impl<'a> CallCreateExecutive<'a> {
|
||||
}
|
||||
} else {
|
||||
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()
|
||||
{
|
||||
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_version: schedule.latest_version,
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
action_type: ActionType::Create,
|
||||
params_type: vm::ParamsType::Embedded,
|
||||
};
|
||||
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_version: self.state.code_version(address)?,
|
||||
data: Some(t.data.clone()),
|
||||
call_type: CallType::Call,
|
||||
action_type: ActionType::Call,
|
||||
params_type: vm::ParamsType::Separate,
|
||||
};
|
||||
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 evm::{Factory, evm_test, evm_test_ignore};
|
||||
use macros::vec_into;
|
||||
use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress};
|
||||
use vm::{ActionParams, ActionValue, EnvInfo, CreateContractAddress};
|
||||
use ::trace::{
|
||||
trace,
|
||||
FlatTrace, Tracer, NoopTracer, ExecutiveTracer,
|
||||
@ -1414,7 +1414,7 @@ mod tests {
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.value = ActionValue::Transfer(U256::from(100));
|
||||
params.call_type = CallType::Call;
|
||||
params.action_type = ActionType::Call;
|
||||
let mut state = get_temp_state();
|
||||
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
|
||||
let info = EnvInfo::default();
|
||||
@ -1434,7 +1434,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 100_000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 33021.into(),
|
||||
@ -1449,7 +1449,7 @@ mod tests {
|
||||
value: 1.into(),
|
||||
gas: 66560.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}), result: trace::Res::Call(trace::CallResult {
|
||||
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]
|
||||
@ -1498,7 +1498,7 @@ mod tests {
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.value = ActionValue::Transfer(U256::from(100));
|
||||
params.call_type = CallType::Call;
|
||||
params.action_type = ActionType::Call;
|
||||
let mut state = get_temp_state();
|
||||
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
|
||||
let info = EnvInfo::default();
|
||||
@ -1524,7 +1524,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 100000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(55_248),
|
||||
@ -1537,7 +1537,8 @@ mod tests {
|
||||
from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(),
|
||||
value: 23.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 {
|
||||
gas_used: U256::from(3224),
|
||||
@ -1614,7 +1615,7 @@ mod tests {
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.value = ActionValue::Transfer(U256::from(100));
|
||||
params.call_type = CallType::Call;
|
||||
params.action_type = ActionType::Call;
|
||||
let mut state = get_temp_state();
|
||||
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
|
||||
let info = EnvInfo::default();
|
||||
@ -1640,7 +1641,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
gas: 100_000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(trace::CallType::Call).into(),
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(37_033),
|
||||
@ -1653,7 +1654,8 @@ mod tests {
|
||||
from: Address::from_str("b010143a42d5980c7e5ef0e4a4416dc098a4fed3").unwrap(),
|
||||
value: 23.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()),
|
||||
}];
|
||||
@ -1711,6 +1713,7 @@ mod tests {
|
||||
value: 100.into(),
|
||||
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],
|
||||
creation_method: Some(trace::CreationMethod::Create),
|
||||
}),
|
||||
result: trace::Res::Create(trace::CreateResult {
|
||||
gas_used: U256::from(3224),
|
||||
|
@ -29,7 +29,7 @@ use common_types::{
|
||||
};
|
||||
use trace::{Tracer, VMTracer};
|
||||
use vm::{
|
||||
self, ActionParams, ActionValue, EnvInfo, CallType, Schedule,
|
||||
self, ActionParams, ActionValue, EnvInfo, ActionType, Schedule,
|
||||
Ext, ContractCreateResult, MessageCallResult, CreateContractAddress,
|
||||
ReturnData, TrapKind
|
||||
};
|
||||
@ -193,7 +193,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
||||
code_hash,
|
||||
code_version,
|
||||
data: Some(data.as_bytes().to_vec()),
|
||||
call_type: CallType::Call,
|
||||
action_type: ActionType::Call,
|
||||
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
|
||||
let params = ActionParams {
|
||||
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_version: *parent_version,
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
action_type: create_type,
|
||||
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>,
|
||||
data: &[u8],
|
||||
code_address: &Address,
|
||||
call_type: CallType,
|
||||
call_type: ActionType,
|
||||
trap: bool,
|
||||
) -> ::std::result::Result<MessageCallResult, TrapKind> {
|
||||
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_version,
|
||||
data: Some(data.to_vec()),
|
||||
call_type,
|
||||
action_type: call_type,
|
||||
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 {
|
||||
use std::str::FromStr;
|
||||
use ethereum_types::{U256, Address};
|
||||
use evm::{EnvInfo, Ext, CallType};
|
||||
use evm::{EnvInfo, Ext, ActionType};
|
||||
use account_state::State;
|
||||
use ethcore::test_helpers::get_temp_state;
|
||||
use trace::{NoopTracer, NoopVMTracer};
|
||||
@ -591,7 +597,7 @@ mod tests {
|
||||
Some("0000000000000000000000000000000000000000000000000000000000150000".parse::<U256>().unwrap()),
|
||||
&[],
|
||||
&Address::zero(),
|
||||
CallType::Call,
|
||||
ActionType::Call,
|
||||
false,
|
||||
).ok().unwrap();
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ use common_types::{
|
||||
errors::{EngineError, EthcoreError as Error},
|
||||
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 account_state::CleanupMode;
|
||||
@ -141,7 +141,7 @@ impl Machine {
|
||||
value: Option<ActionValue>,
|
||||
gas: U256,
|
||||
data: Option<Vec<u8>>,
|
||||
call_type: Option<CallType>,
|
||||
action_type: Option<ActionType>,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let env_info = {
|
||||
let mut env_info = block.env_info();
|
||||
@ -163,7 +163,7 @@ impl Machine {
|
||||
code_hash,
|
||||
code_version: 0.into(),
|
||||
data,
|
||||
call_type: call_type.unwrap_or(CallType::Call),
|
||||
action_type: action_type.unwrap_or(ActionType::Call),
|
||||
params_type: ParamsType::Separate,
|
||||
};
|
||||
let schedule = self.schedule(env_info.number);
|
||||
|
@ -22,7 +22,7 @@ lru-cache = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
ethcore = { path = "..", features = ["test-helpers"] }
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
spec = { path = "../spec" }
|
||||
tempdir = "0.3"
|
||||
|
@ -15,7 +15,7 @@ hash-db = "0.15.0"
|
||||
itertools = "0.8"
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
parity-bytes = "0.1.0"
|
||||
rlp = "0.4"
|
||||
|
@ -26,7 +26,7 @@ parity-util-mem = "0.3.0"
|
||||
hash-db = "0.15.0"
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
machine = { path = "../machine" }
|
||||
journaldb = { path = "../../util/journaldb" }
|
||||
|
@ -4770,32 +4770,14 @@
|
||||
"enode://4afb3a9137a88267c02651052cf6fb217931b8c78ee058bb86643542a4e2e0a8d24d47d871654e1b78a276c363f3c1bc89254a973b00adc359c9e9a48f140686@144.217.139.5:30303",
|
||||
"enode://c16d390b32e6eb1c312849fe12601412313165df1a705757d671296f1ac8783c5cff09eab0118ac1f981d7148c85072f0f26407e5c68598f3ad49209fade404d@139.99.51.203:30303",
|
||||
"enode://4faf867a2e5e740f9b874e7c7355afee58a2d1ace79f7b692f1d553a1134eddbeb5f9210dd14dc1b774a46fd5f063a8bc1fa90579e13d9d18d1f59bac4a4b16b@139.99.160.213:30303",
|
||||
"enode://6a868ced2dec399c53f730261173638a93a40214cf299ccf4d42a76e3fa54701db410669e8006347a4b3a74fa090bb35af0320e4bc8d04cf5b7f582b1db285f5@163.172.131.191:30303",
|
||||
"enode://66a483383882a518fcc59db6c017f9cd13c71261f13c8d7e67ed43adbbc82a932d88d2291f59be577e9425181fc08828dc916fdd053af935a9491edf9d6006ba@212.47.247.103:30303",
|
||||
"enode://cd6611461840543d5b9c56fbf088736154c699c43973b3a1a32390cf27106f87e58a818a606ccb05f3866de95a4fe860786fea71bf891ea95f234480d3022aa3@163.172.157.114:30303",
|
||||
"enode://1d1f7bcb159d308eb2f3d5e32dc5f8786d714ec696bb2f7e3d982f9bcd04c938c139432f13aadcaf5128304a8005e8606aebf5eebd9ec192a1471c13b5e31d49@138.201.223.35:30303",
|
||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
||||
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303",
|
||||
"enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303",
|
||||
"enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138: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"
|
||||
"enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303",
|
||||
"enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303",
|
||||
"enode://ca6de62fce278f96aea6ec5a2daadb877e51651247cb96ee310a318def462913b653963c155a0ef6c7d50048bba6e6cea881130857413d9f50a621546b590758@34.255.23.113:30303",
|
||||
"enode://279944d8dcd428dffaa7436f25ca0ca43ae19e7bcf94a8fb7d1641651f92d121e972ac2e8f381414b80cc8e5555811c2ec6e1a99bb009b3f53c4c69923e11bd8@35.158.244.151:30303",
|
||||
"enode://8499da03c47d637b20eee24eec3c356c9a2e6148d6fe25ca195c7949ab8ec2c03e3556126b0d7ed644675e78c4318b08691b7b57de10e5f0d40d05b09238fa0a@52.187.207.27:30303",
|
||||
"enode://103858bdb88756c71f15e9b5e09b56dc1be52f0a5021d46301dbbfb7e130029cc9d0d6f73f693bc29b665770fff7da4d34f3c6379fe12721b5d7a0bcb5ca1fc1@191.234.162.198:30303",
|
||||
"enode://715171f50508aba88aecd1250af392a45a330af91d7b90701c436b618c86aaa1589c9184561907bebbb56439b8f8787bc01f49a7c77276c58c1b09822d75e8e8@52.231.165.108:30303",
|
||||
"enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0x0000000000000000000000000000000000000001": {
|
||||
|
@ -55,7 +55,7 @@
|
||||
"nodes": [
|
||||
"enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254: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://a87685902a0622e9cf18c68e73a0ea45156ec53e857ef049b185a9db2296ca04d776417bf1901c0b4eacb5b26271d8694e88e3f17c20d49eb77e1a41ab26b5b3@51.141.78.53:30303",
|
||||
"enode://ae8658da8d255d1992c3ec6e62e11d6e1c5899aa1566504bc1ff96a0c9c8bd44838372be643342553817f5cc7d78f1c83a8093dee13d77b3b0a583c050c81940@18.232.185.151:30303",
|
||||
|
@ -54,7 +54,8 @@
|
||||
"enode://06333009fc9ef3c9e174768e495722a7f98fe7afd4660542e983005f85e556028410fd03278944f44cfe5437b1750b5e6bd1738f700fe7da3626d52010d2954c@51.141.15.254:30303",
|
||||
"enode://93c94e999be5dd854c5d82a7cf5c14822973b5d9badb56ad4974586ec4d4f1995c815af795c20bb6e0a6226d3ee55808435c4dc89baf94ee581141b064d19dfc@80.187.116.161:25720",
|
||||
"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": {
|
||||
"0x0000000000000000000000000000000000000000": {
|
||||
|
@ -59,14 +59,16 @@
|
||||
"gasLimit":"0x2fefd8"
|
||||
},
|
||||
"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://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://2592745efd35b4be443b8ee25fd2099de132e037951f9f6d3e8805e0a78f213537f71264b973f1a83a57372f57bbe6acac8d6ae678f39393221c045ccbe3b18c@51.15.116.226:30304",
|
||||
"enode://a59e33ccd2b3e52d578f1fbd70c6f9babda2650f0760d6ff3b37742fdcdfdb3defba5d56d315b40c46b70198c7621e63ffa3f987389c7118634b0fefbbdfa7fd@51.15.116.226:30303",
|
||||
"enode://f840b007500f50c98ea6f9c9e56dabf4690bbbbb7036d43682c531204341aff8315013547e5bee54117eb22bd3603585ae6bf713d9fa710659533fcab65d5b84@35.238.101.58:30000",
|
||||
"enode://19eda672030ad5debb98c9069b3e99d12438b96506325d9f3f82d76c5f8ce4942d345f41700a5223900e75ad48e76713b74c1b694d67a10c2112540035922256@35.238.101.58:30000"
|
||||
"enode://f840b007500f50c98ea6f9c9e56dabf4690bbbbb7036d43682c531204341aff8315013547e5bee54117eb22bd3603585ae6bf713d9fa710659533fcab65d5b84@35.238.101.58:30303",
|
||||
"enode://1813e90a0afdd7c1e4892c5376960e3577a9e6c5a4f86fa405a405c7421a4a1608248d77cc90333842f13d8954d82113dec480cfb76b4fef8cb475157cf4d5f2@10.28.224.3:30000",
|
||||
"enode://06fdbeb591d26f53b2e7250025fe955ca013431ded930920cf1e3cd1f0c920e9a5e727949d209bc25a07288327b525279b11c5551315c50ff0db483e69fc159b@34.218.225.178:32000"
|
||||
],
|
||||
"accounts":{
|
||||
"0x0000000000000000000000000000000000000001":{
|
||||
|
@ -14,7 +14,7 @@ ethcore-io = { path = "../../util/io" }
|
||||
ethcore-private-tx = { path = "../private-tx" }
|
||||
ethcore-sync = { path = "../sync" }
|
||||
ethereum-types = "0.8.0"
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
snapshot = { path = "../snapshot" }
|
||||
spec = { path = "../spec" }
|
||||
@ -23,5 +23,5 @@ trace-time = "0.1"
|
||||
[dev-dependencies]
|
||||
ethcore = { path = "..", features = ["test-helpers"] }
|
||||
ethcore-db = { path = "../db" }
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
tempdir = "0.3"
|
||||
|
@ -29,7 +29,7 @@ itertools = "0.5"
|
||||
journaldb = { path = "../../util/journaldb" }
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4.8"
|
||||
num_cpus = "1.10.1"
|
||||
rand = "0.7"
|
||||
@ -53,7 +53,7 @@ ethabi-contract = "9.0.0"
|
||||
ethabi-derive = "9.0.1"
|
||||
ethcore = { path = "..", features = ["test-helpers"] }
|
||||
ethkey = { path = "../../accounts/ethkey" }
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
lazy_static = { version = "1.3" }
|
||||
spec = { path = "../spec" }
|
||||
tempdir = "0.3"
|
||||
|
@ -23,8 +23,8 @@ hash-db = "0.15.0"
|
||||
journaldb = { path = "../../../util/journaldb" }
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../../util/keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb = "0.3.1"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
log = "0.4.8"
|
||||
parking_lot = "0.9"
|
||||
parity-crypto = { version = "0.4.2", features = ["publickey"] }
|
||||
|
@ -25,7 +25,7 @@ hash-db = "0.15.0"
|
||||
instant-seal = { path = "../engines/instant-seal" }
|
||||
journaldb = { path = "../../util/journaldb" }
|
||||
keccak-hash = "0.4.0"
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
log = "0.4.8"
|
||||
machine = { path = "../machine" }
|
||||
null-engine = { path = "../engines/null-engine" }
|
||||
|
@ -52,7 +52,7 @@ use pod::PodState;
|
||||
use rlp::{Rlp, RlpStream};
|
||||
use trace::{NoopTracer, NoopVMTracer};
|
||||
use trie_vm_factories::Factories;
|
||||
use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType};
|
||||
use vm::{EnvInfo, ActionType, ActionValue, ActionParams, ParamsType};
|
||||
|
||||
use crate::{
|
||||
Genesis,
|
||||
@ -163,7 +163,7 @@ fn run_constructors<T: Backend>(
|
||||
value: ActionValue::Transfer(Default::default()),
|
||||
code: Some(Arc::new(constructor.clone())),
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
action_type: ActionType::Create,
|
||||
params_type: ParamsType::Embedded,
|
||||
};
|
||||
|
||||
@ -250,9 +250,10 @@ impl From<ethjson::spec::HardcodedSync> for SpecHardcodedSync {
|
||||
impl fmt::Display for SpecHardcodedSync {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "{{")?;
|
||||
writeln!(f, r#"header": "{:?},"#, self.header)?;
|
||||
writeln!(f, r#"total_difficulty": "{:?},"#, self.total_difficulty)?;
|
||||
writeln!(f, r#"chts": {:#?}"#, self.chts.iter().map(|x| format!(r#"{:?}"#, x)).collect::<Vec<_>>())?;
|
||||
writeln!(f, r#""header": "{:x}","#, self.header)?;
|
||||
writeln!(f, r#""totalDifficulty": "{:?}""#, self.total_difficulty)?;
|
||||
// TODO: #11415 - fix trailing comma for CHTs
|
||||
writeln!(f, r#""CHTs": {:#?}"#, self.chts.iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>())?;
|
||||
writeln!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ impl Importer {
|
||||
let block_queue = BlockQueue::new(
|
||||
config.queue.clone(),
|
||||
engine.clone(),
|
||||
message_channel.clone(),
|
||||
message_channel,
|
||||
config.verifier_type.verifying_seal()
|
||||
);
|
||||
|
||||
@ -404,11 +404,11 @@ impl Importer {
|
||||
let verify_external_result = engine.verify_block_external(&header);
|
||||
if let Err(e) = verify_external_result {
|
||||
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
|
||||
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 is_epoch_begin = chain.epoch_transition(parent.number(), *header.parent_hash()).is_some();
|
||||
@ -428,7 +428,7 @@ impl Importer {
|
||||
Ok(b) => b,
|
||||
Err(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
|
||||
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);
|
||||
return Err(e.into());
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
let pending = self.check_epoch_end_signal(
|
||||
@ -562,14 +562,14 @@ impl Importer {
|
||||
a
|
||||
}).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,
|
||||
is_finalized,
|
||||
});
|
||||
|
||||
client.tracedb.read().import(&mut batch, TraceImportRequest {
|
||||
traces: traces.into(),
|
||||
block_hash: hash.clone(),
|
||||
block_hash: *hash,
|
||||
block_number: number,
|
||||
enacted: route.enacted.clone(),
|
||||
retracted: route.retracted.len()
|
||||
@ -619,10 +619,10 @@ impl Importer {
|
||||
Proof::WithState(with_state) => {
|
||||
let env_info = EnvInfo {
|
||||
number: header.number(),
|
||||
author: header.author().clone(),
|
||||
author: *header.author(),
|
||||
timestamp: header.timestamp(),
|
||||
difficulty: header.difficulty().clone(),
|
||||
last_hashes: client.build_last_hashes(header.parent_hash()),
|
||||
difficulty: *header.difficulty(),
|
||||
last_hashes: client.build_last_hashes(*header.parent_hash()),
|
||||
gas_used: U256::default(),
|
||||
gas_limit: u64::max_value().into(),
|
||||
};
|
||||
@ -636,7 +636,7 @@ impl Importer {
|
||||
|
||||
let mut state = State::from_existing(
|
||||
backend,
|
||||
header.state_root().clone(),
|
||||
*header.state_root(),
|
||||
self.engine.account_start_nonce(header.number()),
|
||||
client.factories.clone(),
|
||||
).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);
|
||||
|
||||
Ok(Some(PendingTransition { proof: proof }))
|
||||
Ok(Some(PendingTransition { proof }))
|
||||
},
|
||||
EpochChange::No => Ok(None),
|
||||
EpochChange::Unsure(_) => {
|
||||
@ -777,7 +777,7 @@ impl Client {
|
||||
chain: RwLock::new(chain),
|
||||
tracedb,
|
||||
engine,
|
||||
pruning: config.pruning.clone(),
|
||||
pruning: config.pruning,
|
||||
snapshotting_at: AtomicU64::new(0),
|
||||
db: RwLock::new(db.clone()),
|
||||
state_db: RwLock::new(state_db),
|
||||
@ -824,7 +824,7 @@ impl Client {
|
||||
chain.insert_epoch_transition(&mut batch, 0, EpochTransition {
|
||||
block_hash: gh.hash(),
|
||||
block_number: 0,
|
||||
proof: proof,
|
||||
proof,
|
||||
});
|
||||
|
||||
client.db.read().key_value().write_buffered(batch);
|
||||
@ -901,17 +901,17 @@ impl Client {
|
||||
author: header.author(),
|
||||
timestamp: header.timestamp(),
|
||||
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_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();
|
||||
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());
|
||||
res.resize(256, H256::zero());
|
||||
return Arc::new(res);
|
||||
@ -919,12 +919,12 @@ impl Client {
|
||||
}
|
||||
let mut last_hashes = LastHashes::new();
|
||||
last_hashes.resize(256, H256::zero());
|
||||
last_hashes[0] = parent_hash.clone();
|
||||
last_hashes[0] = parent_hash;
|
||||
let chain = self.chain.read();
|
||||
for i in 0..255 {
|
||||
match chain.block_details(&last_hashes[i]) {
|
||||
Some(details) => {
|
||||
last_hashes[i + 1] = details.parent.clone();
|
||||
last_hashes[i + 1] = details.parent;
|
||||
},
|
||||
None => break,
|
||||
}
|
||||
@ -941,7 +941,7 @@ impl Client {
|
||||
let call = |a, d| {
|
||||
let tx = self.contract_call_tx(id, a, d);
|
||||
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();
|
||||
Ok((result, items))
|
||||
@ -1296,7 +1296,11 @@ impl DatabaseRestore for Client {
|
||||
impl BlockChainReset for Client {
|
||||
fn reset(&self, num: u32) -> Result<(), String> {
|
||||
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 {
|
||||
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() {
|
||||
Some((
|
||||
unverified.bytes.clone(),
|
||||
unverified.header.hash(),
|
||||
*unverified.header.difficulty(),
|
||||
))
|
||||
} else { None };
|
||||
Some((unverified.bytes.clone(), *unverified.header.difficulty()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match self.importer.block_queue.import(unverified) {
|
||||
Ok(hash) => {
|
||||
if let Some((raw, hash, difficulty)) = raw {
|
||||
self.notify(move |n| n.block_pre_import(&raw, &hash, &difficulty));
|
||||
if let Some((bytes, difficulty)) = raw {
|
||||
self.notify(move |n| n.block_pre_import(&bytes, &hash, &difficulty));
|
||||
}
|
||||
Ok(hash)
|
||||
},
|
||||
// we only care about block errors (not import errors)
|
||||
Err((block, EthcoreError::Block(err))) => {
|
||||
self.importer.bad_blocks.report(block.bytes, format!("{:?}", err));
|
||||
return Err(EthcoreError::Block(err))
|
||||
Err((EthcoreError::Block(e), Some(input))) => {
|
||||
self.importer.bad_blocks.report(input.bytes, e.to_string());
|
||||
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> {
|
||||
let env_info = EnvInfo {
|
||||
number: header.number(),
|
||||
author: header.author().clone(),
|
||||
author: *header.author(),
|
||||
timestamp: header.timestamp(),
|
||||
difficulty: header.difficulty().clone(),
|
||||
last_hashes: self.build_last_hashes(header.parent_hash()),
|
||||
difficulty: *header.difficulty(),
|
||||
last_hashes: self.build_last_hashes(*header.parent_hash()),
|
||||
gas_used: U256::default(),
|
||||
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> {
|
||||
let mut env_info = EnvInfo {
|
||||
number: header.number(),
|
||||
author: header.author().clone(),
|
||||
author: *header.author(),
|
||||
timestamp: header.timestamp(),
|
||||
difficulty: header.difficulty().clone(),
|
||||
last_hashes: self.build_last_hashes(header.parent_hash()),
|
||||
difficulty: *header.difficulty(),
|
||||
last_hashes: self.build_last_hashes(*header.parent_hash()),
|
||||
gas_used: U256::default(),
|
||||
gas_limit: U256::max_value(),
|
||||
};
|
||||
@ -1539,10 +1545,10 @@ impl Call for Client {
|
||||
|
||||
let env_info = EnvInfo {
|
||||
number: header.number(),
|
||||
author: header.author().clone(),
|
||||
author: *header.author(),
|
||||
timestamp: header.timestamp(),
|
||||
difficulty: header.difficulty().clone(),
|
||||
last_hashes: self.build_last_hashes(header.parent_hash()),
|
||||
difficulty: *header.difficulty(),
|
||||
last_hashes: self.build_last_hashes(*header.parent_hash()),
|
||||
gas_used: U256::default(),
|
||||
gas_limit: max,
|
||||
};
|
||||
@ -1634,7 +1640,7 @@ impl BlockChainClient for Client {
|
||||
let address = self.transaction_address(id).ok_or_else(|| CallError::TransactionNotFound)?;
|
||||
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)
|
||||
}
|
||||
|
||||
@ -1645,8 +1651,8 @@ impl BlockChainClient for Client {
|
||||
let txs = body.transactions();
|
||||
let engine = self.engine.clone();
|
||||
|
||||
const PROOF: &'static str = "Transactions fetched from blockchain; blockchain transactions are valid; qed";
|
||||
const EXECUTE_PROOF: &'static str = "Transaction replayed; qed";
|
||||
const PROOF: &str = "Transactions fetched from blockchain; blockchain transactions are valid; qed";
|
||||
const EXECUTE_PROOF: &str = "Transaction replayed; qed";
|
||||
|
||||
Ok(Box::new(txs.into_iter()
|
||||
.map(move |t| {
|
||||
@ -1660,9 +1666,7 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn mode(&self) -> Mode {
|
||||
let r = self.mode.lock().clone().into();
|
||||
trace!(target: "mode", "Asked for mode = {:?}. returning {:?}", &*self.mode.lock(), r);
|
||||
r
|
||||
self.mode.lock().clone()
|
||||
}
|
||||
|
||||
fn queue_info(&self) -> BlockQueueInfo {
|
||||
@ -1682,7 +1686,7 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
{
|
||||
let mut mode = self.mode.lock();
|
||||
*mode = new_mode.clone().into();
|
||||
*mode = new_mode.clone();
|
||||
trace!(target: "mode", "Mode now {:?}", &*mode);
|
||||
if let Some(ref mut f) = *self.on_user_defaults_change.lock() {
|
||||
trace!(target: "mode", "Making callback...");
|
||||
@ -1972,17 +1976,17 @@ impl BlockChainClient for Client {
|
||||
// pending logs themselves).
|
||||
let from = match self.block_number_ref(&filter.from_block) {
|
||||
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) {
|
||||
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
|
||||
// result. There's no point to continue here.
|
||||
if from > to {
|
||||
return Err(filter.to_block.clone());
|
||||
return Err(filter.to_block);
|
||||
}
|
||||
|
||||
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.
|
||||
let from_hash = match Self::block_hash(&chain, filter.from_block) {
|
||||
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) {
|
||||
Some(val) => val,
|
||||
@ -2001,7 +2005,7 @@ impl BlockChainClient for Client {
|
||||
};
|
||||
let to_hash = match Self::block_hash(&chain, filter.to_block) {
|
||||
Some(val) => val,
|
||||
None => return Err(filter.to_block.clone()),
|
||||
None => return Err(filter.to_block),
|
||||
};
|
||||
|
||||
let blooms = filter.bloom_possibilities();
|
||||
@ -2103,7 +2107,7 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
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>> {
|
||||
@ -2338,7 +2342,7 @@ impl PrepareOpenBlock for Client {
|
||||
self.tracedb.read().tracing_enabled(),
|
||||
self.state_db.read().boxed_clone_canon(&h),
|
||||
&best_header,
|
||||
self.build_last_hashes(&h),
|
||||
self.build_last_hashes(h),
|
||||
author,
|
||||
gas_range_target,
|
||||
extra_data,
|
||||
@ -2388,7 +2392,7 @@ impl ImportSealedBlock for Client {
|
||||
block.rlp_bytes(),
|
||||
format!("Detected an issue with locally sealed block: {}", e),
|
||||
);
|
||||
return Err(e.into());
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
// scope for self.import_lock
|
||||
@ -2517,12 +2521,12 @@ impl ProvingBlockChainClient for Client {
|
||||
_ => 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();
|
||||
|
||||
executive_state::prove_transaction_virtual(
|
||||
jdb.as_hash_db_mut(),
|
||||
header.state_root().clone(),
|
||||
header.state_root(),
|
||||
&transaction,
|
||||
self.engine.machine(),
|
||||
&env_info,
|
||||
@ -2758,12 +2762,12 @@ fn transaction_receipt(
|
||||
from: sender,
|
||||
to: match tx.action {
|
||||
Action::Create => None,
|
||||
Action::Call(ref address) => Some(address.clone().into())
|
||||
Action::Call(ref address) => Some(*address)
|
||||
},
|
||||
transaction_hash: transaction_hash,
|
||||
transaction_index: transaction_index,
|
||||
block_hash: block_hash,
|
||||
block_number: block_number,
|
||||
transaction_hash,
|
||||
transaction_index,
|
||||
block_hash,
|
||||
block_number,
|
||||
cumulative_gas_used: receipt.gas_used,
|
||||
gas_used: receipt.gas_used - prior_gas_used,
|
||||
contract_address: match tx.action {
|
||||
@ -2772,10 +2776,10 @@ fn transaction_receipt(
|
||||
},
|
||||
logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry {
|
||||
entry: log,
|
||||
block_hash: block_hash,
|
||||
block_number: block_number,
|
||||
transaction_hash: transaction_hash,
|
||||
transaction_index: transaction_index,
|
||||
block_hash,
|
||||
block_number,
|
||||
transaction_hash,
|
||||
transaction_index,
|
||||
transaction_log_index: i,
|
||||
log_index: prior_no_of_logs + i,
|
||||
}).collect(),
|
||||
@ -2921,8 +2925,8 @@ mod tests {
|
||||
let tx1 = raw_tx.clone().sign(secret, None);
|
||||
let transaction = LocalizedTransaction {
|
||||
signed: tx1.clone().into(),
|
||||
block_number: block_number,
|
||||
block_hash: block_hash,
|
||||
block_number,
|
||||
block_hash,
|
||||
transaction_index: 1,
|
||||
cached_sender: Some(tx1.sender()),
|
||||
};
|
||||
@ -2937,7 +2941,7 @@ mod tests {
|
||||
}];
|
||||
let receipt = Receipt {
|
||||
outcome: TransactionOutcome::StateRoot(state_root),
|
||||
gas_used: gas_used,
|
||||
gas_used,
|
||||
log_bloom: Default::default(),
|
||||
logs: logs.clone(),
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ use super::test_common::*;
|
||||
use account_state::{Backend as StateBackend, State};
|
||||
use evm::Finalize;
|
||||
use vm::{
|
||||
self, ActionParams, CallType, Schedule, Ext,
|
||||
self, ActionParams, ActionType, Schedule, Ext,
|
||||
ContractCreateResult, EnvInfo, MessageCallResult,
|
||||
CreateContractAddress, ReturnData,
|
||||
};
|
||||
@ -172,7 +172,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
|
||||
value: Option<U256>,
|
||||
data: &[u8],
|
||||
_code_address: &Address,
|
||||
_call_type: CallType,
|
||||
_call_type: ActionType,
|
||||
_trap: bool
|
||||
) -> Result<MessageCallResult, vm::TrapKind> {
|
||||
self.callcreates.push(CallCreate {
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
use hash::keccak;
|
||||
use vm::{EnvInfo, ActionParams, ActionValue, CallType, ParamsType};
|
||||
use vm::{EnvInfo, ActionParams, ActionValue, ActionType, ParamsType};
|
||||
use evm::Factory;
|
||||
use machine::{
|
||||
executive::Executive,
|
||||
@ -62,7 +62,7 @@ fn test_blockhash_eip210(factory: Factory) {
|
||||
code_hash: Some(blockhash_contract_code_hash),
|
||||
code_version: 0.into(),
|
||||
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,
|
||||
};
|
||||
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_version: 0.into(),
|
||||
data: None,
|
||||
call_type: CallType::Call,
|
||||
action_type: ActionType::Call,
|
||||
params_type: ParamsType::Separate,
|
||||
};
|
||||
let schedule = machine.schedule(env_info.number);
|
||||
|
@ -16,7 +16,7 @@ hash-db = "0.15.0"
|
||||
keccak-hash = "0.4.0"
|
||||
keccak-hasher = { path = "../../util/keccak-hasher" }
|
||||
journaldb = { path = "../../util/journaldb" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4.6"
|
||||
lru-cache = "0.1.2"
|
||||
memory-cache = { path = "../../util/memory-cache" }
|
||||
|
@ -40,7 +40,7 @@ env_logger = "0.5"
|
||||
engine = { path = "../engine" }
|
||||
ethcore = { path = "..", features = ["test-helpers"] }
|
||||
ethcore-io = { path = "../../util/io", features = ["mio"] }
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
machine = { path = "../machine" }
|
||||
rand_xorshift = "0.2"
|
||||
rustc-hex = "1.0"
|
||||
|
@ -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_HEADERS_TO_SEND: usize = 512;
|
||||
/// Maximum number of "entries" to include in a GetDataNode request.
|
||||
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;
|
||||
const MIN_PEERS_PROPAGATION: usize = 4;
|
||||
const MAX_PEERS_PROPAGATION: usize = 128;
|
||||
|
@ -15,13 +15,14 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::cmp;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::sync_io::SyncIo;
|
||||
|
||||
use bytes::Bytes;
|
||||
use enum_primitive::FromPrimitive;
|
||||
use ethereum_types::H256;
|
||||
use log::{debug, trace};
|
||||
use log::{debug, trace, warn};
|
||||
use network::{self, PeerId};
|
||||
use parking_lot::RwLock;
|
||||
use rlp::{Rlp, RlpStream};
|
||||
@ -56,6 +57,8 @@ use super::{
|
||||
MAX_BODIES_TO_SEND,
|
||||
MAX_HEADERS_TO_SEND,
|
||||
MAX_NODE_DATA_TO_SEND,
|
||||
MAX_NODE_DATA_TOTAL_DURATION,
|
||||
MAX_NODE_DATA_SINGLE_DURATION,
|
||||
MAX_RECEIPTS_HEADERS_TO_SEND,
|
||||
};
|
||||
|
||||
@ -258,9 +261,9 @@ impl SyncSupplier {
|
||||
|
||||
/// Respond to GetNodeData request
|
||||
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);
|
||||
trace!(target: "sync", "{} -> GetNodeData: {} entries", peer_id, count);
|
||||
trace!(target: "sync", "{} -> GetNodeData: {} entries requested", peer_id, count);
|
||||
if count == 0 {
|
||||
debug!(target: "sync", "Empty GetNodeData request, ignoring.");
|
||||
return Ok(None);
|
||||
@ -269,10 +272,20 @@ impl SyncSupplier {
|
||||
let mut added = 0usize;
|
||||
let mut data = Vec::new();
|
||||
let mut total_bytes = 0;
|
||||
let mut total_elpsd = Duration::from_secs(0);
|
||||
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();
|
||||
// Check that the packet won't be oversized
|
||||
if total_bytes > payload_soft_limit {
|
||||
break;
|
||||
}
|
||||
@ -280,7 +293,8 @@ impl SyncSupplier {
|
||||
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);
|
||||
for d in data {
|
||||
rlp.append(&d);
|
||||
@ -540,7 +554,7 @@ mod test {
|
||||
let rlp_result = result.unwrap();
|
||||
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::new(&rlp);
|
||||
assert_eq!(Ok(1), rlp.item_count());
|
||||
|
@ -234,7 +234,7 @@ impl Fetcher {
|
||||
}
|
||||
|
||||
// state transition not triggered until drain is finished.
|
||||
(SyncRound::Fetch(self))
|
||||
SyncRound::Fetch(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ ethcore-blockchain = { path = "../blockchain" }
|
||||
ethcore-db = { path = "../db" }
|
||||
ethereum-types = "0.8.0"
|
||||
evm = { path = "../evm" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
parity-bytes = "0.1.0"
|
||||
parity-util-mem = "0.3.0"
|
||||
|
@ -374,13 +374,12 @@ mod tests {
|
||||
|
||||
use ethcore::test_helpers::new_db;
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use evm::CallType;
|
||||
use kvdb::DBTransaction;
|
||||
|
||||
use crate::{
|
||||
BlockNumber, Config, TraceDB, Database as TraceDatabase, ImportRequest, DatabaseExtras,
|
||||
Filter, LocalizedTrace, AddressesFilter, TraceError,
|
||||
trace::{Call, Action, Res},
|
||||
trace::{Call, CallType, Action, Res},
|
||||
flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces}
|
||||
};
|
||||
|
||||
@ -465,7 +464,7 @@ mod tests {
|
||||
value: 3.into(),
|
||||
gas: 4.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call).into(),
|
||||
}),
|
||||
result: Res::FailedCall(TraceError::OutOfGas),
|
||||
}])]),
|
||||
@ -487,7 +486,7 @@ mod tests {
|
||||
value: 3.into(),
|
||||
gas: 4.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call).into(),
|
||||
}),
|
||||
result: Res::FailedCall(TraceError::OutOfGas),
|
||||
}])]),
|
||||
@ -506,7 +505,7 @@ mod tests {
|
||||
value: U256::from(3),
|
||||
gas: U256::from(4),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call).into(),
|
||||
}),
|
||||
result: Res::FailedCall(TraceError::OutOfGas),
|
||||
trace_address: vec![],
|
||||
|
@ -125,10 +125,9 @@ impl Filter {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ethereum_types::{Address, Bloom, BloomInput};
|
||||
use evm::CallType;
|
||||
use crate::{
|
||||
Filter, AddressesFilter, TraceError, RewardType,
|
||||
trace::{Action, Call, Res, Create, CreateResult, Suicide, Reward},
|
||||
trace::{Action, Call, CallType, Res, Create, CreationMethod, CreateResult, Suicide, Reward},
|
||||
flat::FlatTrace,
|
||||
};
|
||||
|
||||
@ -273,7 +272,7 @@ mod tests {
|
||||
value: 3.into(),
|
||||
gas: 4.into(),
|
||||
input: vec![0x5],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call).into(),
|
||||
}),
|
||||
result: Res::FailedCall(TraceError::OutOfGas),
|
||||
trace_address: vec![0].into_iter().collect(),
|
||||
@ -294,6 +293,7 @@ mod tests {
|
||||
value: 3.into(),
|
||||
gas: 4.into(),
|
||||
init: vec![0x5],
|
||||
creation_method: Some(CreationMethod::Create),
|
||||
}),
|
||||
result: Res::Create(CreateResult {
|
||||
gas_used: 10.into(),
|
||||
@ -413,6 +413,7 @@ mod tests {
|
||||
gas: 4.into(),
|
||||
init: vec![0x5],
|
||||
value: 3.into(),
|
||||
creation_method: Some(CreationMethod::Create),
|
||||
}),
|
||||
result: Res::FailedCall(TraceError::BadInstruction),
|
||||
trace_address: vec![].into_iter().collect(),
|
||||
|
@ -123,9 +123,8 @@ mod tests {
|
||||
use rlp::*;
|
||||
use crate::{
|
||||
FlatBlockTraces, FlatTransactionTraces, FlatTrace,
|
||||
trace::{Action, Res, CallResult, Call, Suicide, Reward, RewardType}
|
||||
trace::{Action, Res, CallResult, Call, CallType, Suicide, Reward, RewardType}
|
||||
};
|
||||
use evm::CallType;
|
||||
|
||||
#[test]
|
||||
fn encode_flat_transaction_traces() {
|
||||
@ -162,7 +161,7 @@ mod tests {
|
||||
value: "3627e8f712373c0000".parse().unwrap(),
|
||||
gas: 0x03e8.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call).into(),
|
||||
}),
|
||||
result: Res::Call(CallResult {
|
||||
gas_used: 0.into(),
|
||||
@ -179,7 +178,7 @@ mod tests {
|
||||
value: 0.into(),
|
||||
gas: 0x010c78.into(),
|
||||
input: vec![0x41, 0xc0, 0xe1, 0xb5],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call).into(),
|
||||
}),
|
||||
result: Res::Call(CallResult {
|
||||
gas_used: 0x0127.into(),
|
||||
|
@ -16,12 +16,19 @@
|
||||
|
||||
//! 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 parity_bytes::Bytes;
|
||||
use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable};
|
||||
use rlp_derive::{RlpEncodable, RlpDecodable};
|
||||
use vm::ActionParams;
|
||||
use evm::CallType;
|
||||
use evm::ActionType;
|
||||
use super::error::Error;
|
||||
|
||||
/// `Call` result.
|
||||
@ -33,6 +40,33 @@ pub struct CallResult {
|
||||
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.
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
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.
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
pub struct Call {
|
||||
@ -65,19 +142,96 @@ pub struct Call {
|
||||
/// The input data provided to the call.
|
||||
pub input: Bytes,
|
||||
/// 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 {
|
||||
fn from(p: ActionParams) -> Self {
|
||||
match p.call_type {
|
||||
CallType::DelegateCall | CallType::CallCode => Call {
|
||||
match p.action_type {
|
||||
ActionType::DelegateCall | ActionType::CallCode => Call {
|
||||
from: p.address,
|
||||
to: p.code_address,
|
||||
value: p.value.value(),
|
||||
gas: p.gas,
|
||||
input: p.data.unwrap_or_else(Vec::new),
|
||||
call_type: p.call_type,
|
||||
call_type: CallType::try_from(p.action_type).ok().into(),
|
||||
},
|
||||
_ => Call {
|
||||
from: p.sender,
|
||||
@ -85,7 +239,7 @@ impl From<ActionParams> for Call {
|
||||
value: p.value.value(),
|
||||
gas: p.gas,
|
||||
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,
|
||||
/// The init code.
|
||||
pub init: Bytes,
|
||||
/// Creation method (CREATE vs CREATE2).
|
||||
#[rlp(default)]
|
||||
pub creation_method: Option<CreationMethod>,
|
||||
}
|
||||
|
||||
impl From<ActionParams> for Create {
|
||||
@ -122,6 +279,7 @@ impl From<ActionParams> for Create {
|
||||
value: p.value.value(),
|
||||
gas: p.gas,
|
||||
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.
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ unexpected = { path = "../../util/unexpected" }
|
||||
vm = { path = "../vm"}
|
||||
|
||||
[dev-dependencies]
|
||||
rustc-hex = "1.0"
|
||||
rustc-hex = "2.0"
|
||||
|
||||
[features]
|
||||
test-helpers = []
|
||||
|
@ -26,7 +26,7 @@
|
||||
use block::Block as FullBlock;
|
||||
use ethereum_types::{H256, Bloom, U256, Address};
|
||||
use hash::keccak;
|
||||
use header::{Header as FullHeader};
|
||||
use header::Header as FullHeader;
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
use rlp::{self, Rlp, RlpStream};
|
||||
use transaction::UnverifiedTransaction;
|
||||
@ -60,6 +60,15 @@ impl Header {
|
||||
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.
|
||||
impl Header {
|
||||
/// Returns the header hash.
|
||||
|
@ -21,7 +21,7 @@ use derive_more::{Display, From};
|
||||
use ethereum_types::{U256, U512};
|
||||
use ethtrie::TrieError;
|
||||
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 transaction::Error as TransactionError;
|
||||
|
@ -377,11 +377,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_header_seal_fields() {
|
||||
// that's rlp of block header created with ethash engine.
|
||||
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let mix_hash_decoded = "a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let header_rlp: Vec<u8> = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let mix_hash: Vec<u8> = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let mix_hash_decoded: Vec<u8> = "a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let nonce: Vec<u8> = "88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let nonce_decoded: Vec<u8> = "ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
|
||||
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
|
||||
let seal_fields = header.seal.clone();
|
||||
@ -398,7 +398,7 @@ mod tests {
|
||||
#[test]
|
||||
fn decode_and_encode_header() {
|
||||
// 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 encoded_header = rlp::encode(&header);
|
||||
@ -410,7 +410,7 @@ mod tests {
|
||||
fn reject_header_with_large_timestamp() {
|
||||
// that's rlp of block header created with ethash engine.
|
||||
// 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
|
||||
let header: Result<Header, _> = rlp::decode(&header_rlp);
|
||||
|
@ -42,8 +42,8 @@ extern crate derive_more;
|
||||
extern crate keccak_hash as hash;
|
||||
extern crate parity_bytes as bytes;
|
||||
extern crate patricia_trie_ethereum as ethtrie;
|
||||
extern crate rlp;
|
||||
extern crate parity_snappy;
|
||||
extern crate rlp;
|
||||
extern crate unexpected;
|
||||
|
||||
#[macro_use]
|
||||
@ -51,12 +51,12 @@ extern crate rlp_derive;
|
||||
extern crate parity_util_mem;
|
||||
extern crate parity_util_mem as malloc_size_of;
|
||||
|
||||
#[macro_use]
|
||||
pub mod views;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate rustc_hex;
|
||||
|
||||
#[macro_use]
|
||||
pub mod views;
|
||||
|
||||
pub mod account_diff;
|
||||
pub mod ancestry_action;
|
||||
pub mod basic_account;
|
||||
|
@ -170,13 +170,15 @@ pub struct LocalizedReceipt {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::{Receipt, TransactionOutcome, Address, H256};
|
||||
use log_entry::LogEntry;
|
||||
use std::str::FromStr;
|
||||
use rustc_hex::FromHex;
|
||||
|
||||
#[test]
|
||||
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(
|
||||
TransactionOutcome::Unknown,
|
||||
0x40cae.into(),
|
||||
@ -191,7 +193,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
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(
|
||||
TransactionOutcome::StateRoot(H256::from_str("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee").unwrap()),
|
||||
0x40cae.into(),
|
||||
@ -201,15 +203,15 @@ mod tests {
|
||||
data: vec![0u8; 32]
|
||||
}]
|
||||
);
|
||||
let encoded = ::rlp::encode(&r);
|
||||
let encoded = rlp::encode(&r);
|
||||
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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
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(
|
||||
TransactionOutcome::StatusCode(0),
|
||||
0x40cae.into(),
|
||||
@ -219,9 +221,9 @@ mod tests {
|
||||
data: vec![0u8; 32]
|
||||
}]
|
||||
);
|
||||
let encoded = ::rlp::encode(&r);
|
||||
let encoded = rlp::encode(&r);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -548,14 +548,16 @@ impl From<SignedTransaction> for PendingTransaction {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
use ethereum_types::{U256, Address};
|
||||
use hash::keccak;
|
||||
use std::str::FromStr;
|
||||
use rustc_hex::FromHex;
|
||||
|
||||
#[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");
|
||||
assert_eq!(t.data, b"");
|
||||
assert_eq!(t.gas, U256::from(0x5208u64));
|
||||
@ -675,11 +677,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_agree_with_vitalik() {
|
||||
use rustc_hex::FromHex;
|
||||
|
||||
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 signed = SignedTransaction::new(signed).unwrap();
|
||||
let bytes = rlp::decode(&tx_data.from_hex::<Vec<u8>>().unwrap()).expect("decoding tx data failed");
|
||||
let signed = SignedTransaction::new(bytes).unwrap();
|
||||
assert_eq!(signed.sender(), Address::from_str(&address[2..]).unwrap());
|
||||
println!("chainid: {:?}", signed.chain_id());
|
||||
};
|
||||
|
@ -183,7 +183,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_block_view() {
|
||||
// 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);
|
||||
assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap());
|
||||
|
@ -167,7 +167,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_block_view() {
|
||||
// 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 view = view!(BodyView, &body);
|
||||
assert_eq!(view.transactions_count(), 1);
|
||||
|
@ -127,9 +127,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_header_view() {
|
||||
// that's rlp of block header created with ethash engine.
|
||||
let rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let rlp: Vec<u8> = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let mix_hash: Vec<u8> = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let nonce: Vec<u8> = "88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
|
||||
let view = view!(HeaderView, &rlp);
|
||||
assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap());
|
||||
|
@ -90,14 +90,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_transaction_view() {
|
||||
let rlp = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap();
|
||||
let rlp: Vec<u8> = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap();
|
||||
|
||||
let view = view!(TransactionView, &rlp);
|
||||
assert_eq!(view.nonce(), 0.into());
|
||||
assert_eq!(view.gas_price(), 1.into());
|
||||
assert_eq!(view.gas(), 0x61a8.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.s(), "efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".into());
|
||||
assert_eq!(view.v(), 0x1b);
|
||||
|
@ -62,7 +62,14 @@ pub trait Kind: 'static + Sized + Send + Sync {
|
||||
type Verified: Sized + Send + BlockLike + MallocSizeOf;
|
||||
|
||||
/// 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.
|
||||
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 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) {
|
||||
Ok(()) => Ok(input),
|
||||
Err(Error::Block(BlockError::TemporarilyInvalid(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) => {
|
||||
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 {
|
||||
self.header.parent_hash().clone()
|
||||
*self.header.parent_hash()
|
||||
}
|
||||
|
||||
fn difficulty(&self) -> U256 {
|
||||
self.header.difficulty().clone()
|
||||
*self.header.difficulty()
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,11 +156,11 @@ pub mod blocks {
|
||||
}
|
||||
|
||||
fn parent_hash(&self) -> H256 {
|
||||
self.header.parent_hash().clone()
|
||||
*self.header.parent_hash()
|
||||
}
|
||||
|
||||
fn difficulty(&self) -> U256 {
|
||||
self.header.difficulty().clone()
|
||||
*self.header.difficulty()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,8 +181,8 @@ pub mod headers {
|
||||
impl BlockLike for Header {
|
||||
fn hash(&self) -> H256 { self.hash() }
|
||||
fn raw_hash(&self) -> H256 { self.hash() }
|
||||
fn parent_hash(&self) -> H256 { self.parent_hash().clone() }
|
||||
fn difficulty(&self) -> U256 { self.difficulty().clone() }
|
||||
fn parent_hash(&self) -> H256 { *self.parent_hash() }
|
||||
fn difficulty(&self) -> U256 { *self.difficulty() }
|
||||
}
|
||||
|
||||
/// A mode for verifying headers.
|
||||
@ -182,19 +193,23 @@ pub mod headers {
|
||||
type Unverified = 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)
|
||||
.and_then(|_| verify_header_time(&input));
|
||||
|
||||
match res {
|
||||
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> {
|
||||
match check_seal {
|
||||
true => engine.verify_block_unordered(&unverified,).map(|_| unverified),
|
||||
true => engine.verify_block_unordered(&unverified).map(|_| unverified),
|
||||
false => Ok(unverified),
|
||||
}
|
||||
}
|
||||
|
@ -467,30 +467,33 @@ impl<K: Kind, C> VerificationQueue<K, C> {
|
||||
}
|
||||
|
||||
/// 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 raw_hash = input.raw_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();
|
||||
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()) {
|
||||
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) {
|
||||
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.processing.write().insert(hash, item.difficulty());
|
||||
{
|
||||
let mut td = self.total_difficulty.write();
|
||||
*td = *td + item.difficulty();
|
||||
@ -499,7 +502,7 @@ impl<K: Kind, C> VerificationQueue<K, C> {
|
||||
self.more_to_verify.notify_all();
|
||||
Ok(hash)
|
||||
},
|
||||
Err((input, err)) => {
|
||||
Err((err, input)) => {
|
||||
match err {
|
||||
// Don't mark future blocks as bad.
|
||||
Error::Block(BlockError::TemporarilyInvalid(_)) => {},
|
||||
@ -517,7 +520,7 @@ impl<K: Kind, C> VerificationQueue<K, C> {
|
||||
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 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.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.
|
||||
pub fn total_difficulty(&self) -> U256 {
|
||||
self.total_difficulty.read().clone()
|
||||
*self.total_difficulty.read()
|
||||
}
|
||||
|
||||
/// Get the current number of working verifiers.
|
||||
@ -806,9 +809,9 @@ mod tests {
|
||||
|
||||
let duplicate_import = queue.import(new_unverified(get_good_dummy_block()));
|
||||
match duplicate_import {
|
||||
Err((_, e)) => {
|
||||
Err(e) => {
|
||||
match e {
|
||||
EthcoreError::Import(ImportError::AlreadyQueued) => {},
|
||||
(EthcoreError::Import(ImportError::AlreadyQueued), _) => {},
|
||||
_ => { panic!("must return AlreadyQueued error"); }
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use bytes::Bytes;
|
||||
use hash::{keccak, KECCAK_EMPTY};
|
||||
use ethjson;
|
||||
|
||||
use call_type::CallType;
|
||||
use action_type::ActionType;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -88,8 +88,8 @@ pub struct ActionParams {
|
||||
pub code_version: U256,
|
||||
/// Input data.
|
||||
pub data: Option<Bytes>,
|
||||
/// Type of call
|
||||
pub call_type: CallType,
|
||||
/// Type of action (e.g. CALL, DELEGATECALL, CREATE, etc.)
|
||||
pub action_type: ActionType,
|
||||
/// Param types encoding
|
||||
pub params_type: ParamsType,
|
||||
}
|
||||
@ -109,7 +109,7 @@ impl Default for ActionParams {
|
||||
code: None,
|
||||
code_version: U256::zero(),
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
action_type: ActionType::Create,
|
||||
params_type: ParamsType::Separate,
|
||||
}
|
||||
}
|
||||
@ -130,7 +130,7 @@ impl From<ethjson::vm::Transaction> for ActionParams {
|
||||
gas: t.gas.into(),
|
||||
gas_price: t.gas_price.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,
|
||||
}
|
||||
}
|
||||
|
@ -14,47 +14,51 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// 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};
|
||||
|
||||
/// The type of the call-like instruction.
|
||||
/// The type of the instruction.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum CallType {
|
||||
/// Not a CALL.
|
||||
None,
|
||||
pub enum ActionType {
|
||||
/// CREATE.
|
||||
Create,
|
||||
/// CALL.
|
||||
Call,
|
||||
/// CALLCODE.
|
||||
CallCode,
|
||||
/// DELEGATECALL.
|
||||
DelegateCall,
|
||||
/// STATICCALL
|
||||
/// STATICCALL.
|
||||
StaticCall,
|
||||
/// CREATE2.
|
||||
Create2
|
||||
}
|
||||
|
||||
impl Encodable for CallType {
|
||||
impl Encodable for ActionType {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
let v = match *self {
|
||||
CallType::None => 0u32,
|
||||
CallType::Call => 1,
|
||||
CallType::CallCode => 2,
|
||||
CallType::DelegateCall => 3,
|
||||
CallType::StaticCall => 4,
|
||||
ActionType::Create => 0u32,
|
||||
ActionType::Call => 1,
|
||||
ActionType::CallCode => 2,
|
||||
ActionType::DelegateCall => 3,
|
||||
ActionType::StaticCall => 4,
|
||||
ActionType::Create2 => 5,
|
||||
};
|
||||
Encodable::rlp_append(&v, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for CallType {
|
||||
impl Decodable for ActionType {
|
||||
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
|
||||
rlp.as_val().and_then(|v| Ok(match v {
|
||||
0u32 => CallType::None,
|
||||
1 => CallType::Call,
|
||||
2 => CallType::CallCode,
|
||||
3 => CallType::DelegateCall,
|
||||
4 => CallType::StaticCall,
|
||||
_ => return Err(DecoderError::Custom("Invalid value of CallType item")),
|
||||
0u32 => ActionType::Create,
|
||||
1 => ActionType::Call,
|
||||
2 => ActionType::CallCode,
|
||||
3 => ActionType::DelegateCall,
|
||||
4 => ActionType::StaticCall,
|
||||
5 => ActionType::Create2,
|
||||
_ => return Err(DecoderError::Custom("Invalid value of ActionType item")),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -62,11 +66,11 @@ impl Decodable for CallType {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rlp::*;
|
||||
use super::CallType;
|
||||
use super::ActionType;
|
||||
|
||||
#[test]
|
||||
fn encode_call_type() {
|
||||
let ct = CallType::Call;
|
||||
let ct = ActionType::Call;
|
||||
|
||||
let mut s = RlpStream::new_list(2);
|
||||
s.append(&ct);
|
||||
@ -78,9 +82,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_encode_and_decode_call_type() {
|
||||
let original = CallType::Call;
|
||||
let original = ActionType::Call;
|
||||
let encoded = encode(&original);
|
||||
let decoded = decode(&encoded).expect("failure decoding CallType");
|
||||
let decoded = decode(&encoded).expect("failure decoding ActionType");
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
use std::sync::Arc;
|
||||
use ethereum_types::{U256, H256, Address};
|
||||
use bytes::Bytes;
|
||||
use call_type::CallType;
|
||||
use action_type::ActionType;
|
||||
use env_info::EnvInfo;
|
||||
use schedule::Schedule;
|
||||
use return_data::ReturnData;
|
||||
@ -115,7 +115,7 @@ pub trait Ext {
|
||||
value: Option<U256>,
|
||||
data: &[u8],
|
||||
code_address: &Address,
|
||||
call_type: CallType,
|
||||
call_type: ActionType,
|
||||
trap: bool
|
||||
) -> ::std::result::Result<MessageCallResult, TrapKind>;
|
||||
|
||||
|
@ -24,7 +24,7 @@ extern crate keccak_hash as hash;
|
||||
extern crate patricia_trie_ethereum as ethtrie;
|
||||
|
||||
mod action_params;
|
||||
mod call_type;
|
||||
mod action_type;
|
||||
mod env_info;
|
||||
mod schedule;
|
||||
mod ext;
|
||||
@ -34,7 +34,7 @@ mod error;
|
||||
pub mod tests;
|
||||
|
||||
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 schedule::{Schedule, VersionedSchedule, CleanDustMode, WasmCosts};
|
||||
pub use ext::{Ext, MessageCallResult, ContractCreateResult, CreateContractAddress};
|
||||
|
@ -20,7 +20,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use ethereum_types::{U256, H256, Address};
|
||||
use bytes::Bytes;
|
||||
use {
|
||||
CallType, Schedule, EnvInfo,
|
||||
ActionType, Schedule, EnvInfo,
|
||||
ReturnData, Ext, ContractCreateResult, MessageCallResult,
|
||||
CreateContractAddress, Result, GasLeft,
|
||||
};
|
||||
@ -185,7 +185,7 @@ impl Ext for FakeExt {
|
||||
value: Option<U256>,
|
||||
data: &[u8],
|
||||
code_address: &Address,
|
||||
_call_type: CallType,
|
||||
_call_type: ActionType,
|
||||
_trap: bool,
|
||||
) -> ::std::result::Result<MessageCallResult, TrapKind> {
|
||||
self.calls.insert(FakeCall {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use std::cmp;
|
||||
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 super::panic_payload;
|
||||
|
||||
@ -384,7 +384,7 @@ impl<'a> Runtime<'a> {
|
||||
fn do_call(
|
||||
&mut self,
|
||||
use_val: bool,
|
||||
call_type: CallType,
|
||||
call_type: ActionType,
|
||||
args: RuntimeArgs,
|
||||
)
|
||||
-> Result<RuntimeValue>
|
||||
@ -445,8 +445,8 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
let call_result = self.ext.call(
|
||||
&gas.into(),
|
||||
match call_type { CallType::DelegateCall => &self.context.sender, _ => &self.context.address },
|
||||
match call_type { CallType::Call | CallType::StaticCall => &address, _ => &self.context.address },
|
||||
match call_type { ActionType::DelegateCall => &self.context.sender, _ => &self.context.address },
|
||||
match call_type { ActionType::Call | ActionType::StaticCall => &address, _ => &self.context.address },
|
||||
val,
|
||||
&payload,
|
||||
&address,
|
||||
@ -487,17 +487,17 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
/// Message call
|
||||
fn ccall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> {
|
||||
self.do_call(true, CallType::Call, args)
|
||||
self.do_call(true, ActionType::Call, args)
|
||||
}
|
||||
|
||||
/// Delegate call
|
||||
fn dcall(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> {
|
||||
self.do_call(false, CallType::DelegateCall, args)
|
||||
self.do_call(false, ActionType::DelegateCall, args)
|
||||
}
|
||||
|
||||
/// Static call
|
||||
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<()>
|
||||
|
@ -45,7 +45,7 @@ use ethereum_types::{U256, Address};
|
||||
use ethcore::{json_tests, test_helpers::TrieSpec};
|
||||
use spec;
|
||||
use serde::Deserialize;
|
||||
use vm::{ActionParams, CallType};
|
||||
use vm::{ActionParams, ActionType};
|
||||
|
||||
mod info;
|
||||
mod display;
|
||||
@ -314,7 +314,7 @@ fn run_call<T: Informant>(args: Args, informant: T) {
|
||||
}
|
||||
|
||||
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_address = to;
|
||||
params.address = to;
|
||||
|
@ -9,7 +9,6 @@ edition = "2018"
|
||||
[dependencies]
|
||||
client-traits = { path = "../ethcore/client-traits" }
|
||||
common-types = { path = "../ethcore/types" }
|
||||
ethcore = { path = "../ethcore" }
|
||||
bytes = { package = "parity-bytes", version = "0.1"}
|
||||
ethereum-types = "0.8.0"
|
||||
jsonrpc-core = "14.0.3"
|
||||
|
@ -8,7 +8,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
common-types = { path = "../../ethcore/types" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
rlp = "0.4.0"
|
||||
serde = "1.0"
|
||||
@ -18,4 +18,4 @@ serde_json = "1.0"
|
||||
[dev-dependencies]
|
||||
ethkey = { path = "../../accounts/ethkey" }
|
||||
parity-crypto = { version = "0.4.2", features = ["publickey"] }
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
|
@ -23,7 +23,7 @@ use ethcore::test_helpers::TestBlockChainClient;
|
||||
use ethereum_types::{Address, H256};
|
||||
|
||||
use types::transaction::CallError;
|
||||
use vm::CallType;
|
||||
use trace::trace::CallType;
|
||||
|
||||
use jsonrpc_core::IoHandler;
|
||||
use v1::tests::helpers::{TestMinerService};
|
||||
@ -44,7 +44,7 @@ fn io() -> Tester {
|
||||
value: 0x1.into(),
|
||||
gas: 0x100.into(),
|
||||
input: vec![1, 2, 3],
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call).into(),
|
||||
}),
|
||||
result: Res::None,
|
||||
subtraces: 0,
|
||||
|
@ -24,7 +24,6 @@ use serde::ser::SerializeStruct;
|
||||
use serde::{Serialize, Serializer};
|
||||
use types::account_diff;
|
||||
use types::state_diff;
|
||||
use vm;
|
||||
|
||||
use v1::types::Bytes;
|
||||
|
||||
@ -214,6 +213,7 @@ impl From<state_diff::StateDiff> for StateDiff {
|
||||
|
||||
/// Create response
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Create {
|
||||
/// Sender
|
||||
from: H160,
|
||||
@ -223,6 +223,9 @@ pub struct Create {
|
||||
gas: U256,
|
||||
/// Initialization code
|
||||
init: Bytes,
|
||||
// Create Type
|
||||
#[serde(skip_serializing_if="Option::is_none")]
|
||||
creation_method: Option<CreationMethod>,
|
||||
}
|
||||
|
||||
impl From<trace::Create> for Create {
|
||||
@ -232,6 +235,7 @@ impl From<trace::Create> for Create {
|
||||
value: c.value,
|
||||
gas: c.gas,
|
||||
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)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum CallType {
|
||||
/// None
|
||||
None,
|
||||
/// Call
|
||||
Call,
|
||||
/// Call code
|
||||
@ -252,14 +254,32 @@ pub enum CallType {
|
||||
StaticCall,
|
||||
}
|
||||
|
||||
impl From<vm::CallType> for CallType {
|
||||
fn from(c: vm::CallType) -> Self {
|
||||
impl From<trace::CallType> for CallType {
|
||||
fn from(c: trace::CallType) -> Self {
|
||||
match c {
|
||||
vm::CallType::None => CallType::None,
|
||||
vm::CallType::Call => CallType::Call,
|
||||
vm::CallType::CallCode => CallType::CallCode,
|
||||
vm::CallType::DelegateCall => CallType::DelegateCall,
|
||||
vm::CallType::StaticCall => CallType::StaticCall,
|
||||
trace::CallType::Call => CallType::Call,
|
||||
trace::CallType::CallCode => CallType::CallCode,
|
||||
trace::CallType::DelegateCall => CallType::DelegateCall,
|
||||
trace::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: Bytes,
|
||||
/// The type of the call.
|
||||
call_type: CallType,
|
||||
call_type: Option<CallType>,
|
||||
}
|
||||
|
||||
impl From<trace::Call> for Call {
|
||||
fn from(c: trace::Call) -> Self {
|
||||
let optional: Option<trace::CallType> = c.call_type.0;
|
||||
Call {
|
||||
from: c.from,
|
||||
to: c.to,
|
||||
value: c.value,
|
||||
gas: c.gas,
|
||||
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(),
|
||||
gas: 7.into(),
|
||||
input: Bytes::new(vec![0x12, 0x34]),
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call),
|
||||
}),
|
||||
result: Res::Call(CallResult {
|
||||
gas_used: 8.into(),
|
||||
@ -707,7 +728,7 @@ mod tests {
|
||||
value: 6.into(),
|
||||
gas: 7.into(),
|
||||
input: Bytes::new(vec![0x12, 0x34]),
|
||||
call_type: CallType::Call,
|
||||
call_type: Some(CallType::Call),
|
||||
}),
|
||||
result: Res::FailedCall(TraceError::OutOfGas),
|
||||
trace_address: vec![10],
|
||||
@ -729,6 +750,7 @@ mod tests {
|
||||
value: 6.into(),
|
||||
gas: 7.into(),
|
||||
init: Bytes::new(vec![0x12, 0x34]),
|
||||
creation_method: Some(CreationMethod::Create).into(),
|
||||
}),
|
||||
result: Res::Create(CreateResult {
|
||||
gas_used: 8.into(),
|
||||
@ -743,7 +765,7 @@ mod tests {
|
||||
block_hash: H256::from_low_u64_be(14),
|
||||
};
|
||||
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]
|
||||
@ -754,6 +776,7 @@ mod tests {
|
||||
value: 6.into(),
|
||||
gas: 7.into(),
|
||||
init: Bytes::new(vec![0x12, 0x34]),
|
||||
creation_method: Some(CreationMethod::Create).into(),
|
||||
}),
|
||||
result: Res::FailedCreate(TraceError::OutOfGas),
|
||||
trace_address: vec![10],
|
||||
@ -764,7 +787,7 @@ mod tests {
|
||||
block_hash: H256::from_low_u64_be(14),
|
||||
};
|
||||
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]
|
||||
|
@ -5,8 +5,8 @@ echo "________Running test-linux.sh________"
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
export CC="sccache gcc"
|
||||
export CXX="sccache g++"
|
||||
export CC="sccache "$CC
|
||||
export CXX="sccache "$CXX
|
||||
FEATURES="json-tests"
|
||||
|
||||
OPTIONS="--release"
|
||||
|
@ -15,8 +15,8 @@ ethkey = { path = "../accounts/ethkey", optional = true }
|
||||
futures = "0.1"
|
||||
hyper = { version = "0.12", default-features = false }
|
||||
keccak-hash = "0.4.0"
|
||||
kvdb = "0.2"
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb = "0.3.1"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
lazy_static = "1.0"
|
||||
log = "0.4"
|
||||
parity-bytes = "0.1"
|
||||
@ -38,4 +38,4 @@ jsonrpc-server-utils = "14.0.3"
|
||||
[dev-dependencies]
|
||||
env_logger = "0.5"
|
||||
tempdir = "0.3"
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
|
@ -11,11 +11,11 @@ license = "GPL-3.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
rustc-hex = "2.0.1"
|
||||
arrayref = "0.3.5"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
rustc-hex = "2.0.1"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
|
@ -12,7 +12,7 @@ ethereum-types = "0.8.0"
|
||||
hash-db = "0.15.0"
|
||||
malloc_size_of = { version = "0.3.0", package = "parity-util-mem" }
|
||||
keccak-hasher = { path = "../keccak-hasher" }
|
||||
kvdb = "0.2"
|
||||
kvdb = "0.3.1"
|
||||
log = "0.4"
|
||||
memory-db = "0.18.0"
|
||||
parking_lot = "0.9"
|
||||
@ -22,4 +22,4 @@ rlp = "0.4.0"
|
||||
[dev-dependencies]
|
||||
env_logger = "0.5"
|
||||
keccak-hash = "0.4.0"
|
||||
kvdb-memorydb = "0.2.0"
|
||||
kvdb-memorydb = "0.3.1"
|
||||
|
@ -20,6 +20,7 @@ use std::{
|
||||
collections::{HashMap, hash_map::Entry},
|
||||
io,
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
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 state(&self, key: &H256) -> Option<Bytes> {
|
||||
let journal_overlay = self.journal_overlay.read();
|
||||
let key = to_short_key(key);
|
||||
journal_overlay.backing_overlay.get(&key, EMPTY_PREFIX)
|
||||
.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()))
|
||||
// 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()))
|
||||
};
|
||||
|
||||
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> {
|
||||
|
@ -6,8 +6,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
macros = { path = "../macros" }
|
||||
kvdb = "0.2"
|
||||
kvdb-rocksdb = "0.3.0"
|
||||
kvdb = "0.3.1"
|
||||
kvdb-rocksdb = "0.4.1"
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3"
|
||||
|
@ -40,11 +40,11 @@ use crate::handshake::Handshake;
|
||||
|
||||
const ENCRYPTED_HEADER_LEN: usize = 32;
|
||||
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.
|
||||
/// 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 {
|
||||
}
|
||||
@ -97,7 +97,7 @@ impl<Socket: GenericSocket> GenericConnection<Socket> {
|
||||
else if self.rec_buf.len() > self.rec_size {
|
||||
warn!(target:"network", "Read past buffer {} bytes", self.rec_buf.len() - self.rec_size);
|
||||
return Ok(Some(::std::mem::replace(&mut self.rec_buf, Bytes::new())))
|
||||
}
|
||||
}
|
||||
},
|
||||
Ok(_) => return Ok(None),
|
||||
Err(e) => {
|
||||
@ -105,7 +105,7 @@ impl<Socket: GenericSocket> GenericConnection<Socket> {
|
||||
return Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a packet to send queue.
|
||||
@ -222,7 +222,7 @@ impl Connection {
|
||||
pub fn register_socket<Host: Handler>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> io::Result<()> {
|
||||
if self.registered.compare_and_swap(false, true, AtomicOrdering::SeqCst) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
trace!(target: "network", "connection register; token={:?}", reg);
|
||||
if let Err(e) = event_loop.register(&self.socket, reg, self.interest, PollOpt::edge() /* | PollOpt::oneshot() */) { // TODO: oneshot is broken on windows
|
||||
trace!(target: "network", "Failed to register {:?}, {:?}", reg, e);
|
||||
@ -235,7 +235,7 @@ impl Connection {
|
||||
trace!(target: "network", "connection reregister; token={:?}", reg);
|
||||
if !self.registered.load(AtomicOrdering::SeqCst) {
|
||||
self.register_socket(reg, event_loop)
|
||||
} else {
|
||||
} else {
|
||||
event_loop.reregister(&self.socket, reg, self.interest, PollOpt::edge() /* | PollOpt::oneshot() */ ).unwrap_or_else(|e| { // TODO: oneshot is broken on windows
|
||||
trace!(target: "network", "Failed to reregister {:?}, {:?}", reg, e);
|
||||
});
|
||||
|
@ -1,16 +1,17 @@
|
||||
[package]
|
||||
name = "rlp_derive"
|
||||
version = "0.1.0"
|
||||
authors = ["debris <marek.kotewicz@gmail.com>"]
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "rlp_derive"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = "0.15"
|
||||
quote = "0.6"
|
||||
proc-macro2 = "0.4"
|
||||
syn = "1.0.14"
|
||||
quote = "1.0.2"
|
||||
proc-macro2 = "1.0.8"
|
||||
|
||||
[dev-dependencies]
|
||||
rlp = "0.4.0"
|
||||
|
@ -14,8 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use syn;
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
struct ParseQuotes {
|
||||
single: TokenStream,
|
||||
@ -45,10 +45,19 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream {
|
||||
_ => 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 dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site());
|
||||
let impl_block = quote! {
|
||||
impl rlp::Decodable for #name {
|
||||
fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
|
||||
@ -62,8 +71,7 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream {
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
const _: () = {
|
||||
extern crate rlp;
|
||||
#impl_block
|
||||
};
|
||||
@ -80,7 +88,13 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let fields: Vec<_> = body.fields.iter().collect();
|
||||
if fields.len() == 1 {
|
||||
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 {
|
||||
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 dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site());
|
||||
let impl_block = quote! {
|
||||
impl rlp::Decodable for #name {
|
||||
fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
|
||||
@ -102,19 +115,19 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
const _: () = {
|
||||
extern crate rlp;
|
||||
#impl_block
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn decodable_field_map(tuple: (usize, &syn::Field)) -> TokenStream {
|
||||
decodable_field(tuple.0, tuple.1, decodable_parse_quotes())
|
||||
}
|
||||
|
||||
fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> TokenStream {
|
||||
fn decodable_field(
|
||||
index: usize,
|
||||
field: &syn::Field,
|
||||
quotes: ParseQuotes,
|
||||
default_attribute_encountered: &mut bool,
|
||||
) -> TokenStream {
|
||||
let id = match field.ident {
|
||||
Some(ref ident) => quote! { #ident },
|
||||
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 single = quotes.single;
|
||||
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 {
|
||||
syn::Type::Path(ref path) => {
|
||||
let ident = &path.path.segments.first().expect("there must be at least 1 segment").value().ident;
|
||||
if &ident.to_string() == "Vec" {
|
||||
let ident = &path
|
||||
.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 {
|
||||
quote! { #id: #list(#index)?, }
|
||||
if default {
|
||||
quote! { #id: #list(#index).unwrap_or_default(), }
|
||||
} else {
|
||||
quote! { #id: #list(#index)?, }
|
||||
}
|
||||
} else {
|
||||
quote! { #id: #list()?, }
|
||||
}
|
||||
} else {
|
||||
if quotes.takes_index {
|
||||
quote! { #id: #single(#index)?, }
|
||||
if default {
|
||||
quote! { #id: #single(#index).unwrap_or_default(), }
|
||||
} else {
|
||||
quote! { #id: #single(#index)?, }
|
||||
}
|
||||
} else {
|
||||
quote! { #id: #single()?, }
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => panic!("rlp_derive not supported"),
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use syn;
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream {
|
||||
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."),
|
||||
};
|
||||
|
||||
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 stmts_len = 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! {
|
||||
impl rlp::Encodable for #name {
|
||||
fn rlp_append(&self, stream: &mut rlp::RlpStream) {
|
||||
@ -39,8 +43,7 @@ pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream {
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
const _: () = {
|
||||
extern crate rlp;
|
||||
#impl_block
|
||||
};
|
||||
@ -65,7 +68,6 @@ pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
let name = &ast.ident;
|
||||
|
||||
let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_ENCODABLE_FOR_{}", name), Span::call_site());
|
||||
let impl_block = quote! {
|
||||
impl rlp::Encodable for #name {
|
||||
fn rlp_append(&self, stream: &mut rlp::RlpStream) {
|
||||
@ -75,18 +77,13 @@ pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
const _: () = {
|
||||
extern crate rlp;
|
||||
#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 {
|
||||
let ident = match field.ident {
|
||||
Some(ref ident) => quote! { #ident },
|
||||
@ -100,24 +97,38 @@ fn encodable_field(index: usize, field: &syn::Field) -> TokenStream {
|
||||
|
||||
match field.ty {
|
||||
syn::Type::Path(ref path) => {
|
||||
let top_segment = path.path.segments.first().expect("there must be at least 1 segment");
|
||||
let ident = &top_segment.value().ident;
|
||||
let top_segment = path
|
||||
.path
|
||||
.segments
|
||||
.first()
|
||||
.expect("there must be at least 1 segment");
|
||||
let ident = &top_segment.ident;
|
||||
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) => {
|
||||
let ty = angle.args.first().expect("Vec has only one angle bracketed type; qed");
|
||||
match **ty.value() {
|
||||
syn::GenericArgument::Type(syn::Type::Path(ref path)) => &path.path.segments.first().expect("there must be at least 1 segment").value().ident,
|
||||
let ty = angle
|
||||
.args
|
||||
.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"),
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => unreachable!("Vec has only one angle bracketed type; qed"),
|
||||
};
|
||||
quote! { stream.append_list::<#inner_ident, _>(&#id); }
|
||||
} else {
|
||||
quote! { stream.append(&#id); }
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => panic!("rlp_derive not supported"),
|
||||
}
|
||||
}
|
||||
|
@ -15,19 +15,15 @@
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate proc_macro2;
|
||||
extern crate syn;
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
|
||||
mod en;
|
||||
mod de;
|
||||
mod en;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use en::{impl_encodable, impl_encodable_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 {
|
||||
let ast = syn::parse(input).unwrap();
|
||||
let gen = impl_encodable(&ast);
|
||||
@ -41,7 +37,7 @@ pub fn encodable_wrapper(input: TokenStream) -> TokenStream {
|
||||
gen.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(RlpDecodable)]
|
||||
#[proc_macro_derive(RlpDecodable, attributes(rlp))]
|
||||
pub fn decodable(input: TokenStream) -> TokenStream {
|
||||
let ast = syn::parse(input).unwrap();
|
||||
let gen = impl_decodable(&ast);
|
||||
|
@ -14,11 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
extern crate rlp;
|
||||
#[macro_use]
|
||||
extern crate rlp_derive;
|
||||
|
||||
use rlp::{encode, decode};
|
||||
use rlp::{decode, encode};
|
||||
use rlp_derive::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
|
||||
|
||||
#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
struct Foo {
|
||||
@ -32,9 +29,7 @@ struct FooWrapper {
|
||||
|
||||
#[test]
|
||||
fn test_encode_foo() {
|
||||
let foo = Foo {
|
||||
a: "cat".into(),
|
||||
};
|
||||
let foo = Foo { a: "cat".into() };
|
||||
|
||||
let expected = vec![0xc4, 0x83, b'c', b'a', b't'];
|
||||
let out = encode(&foo);
|
||||
@ -46,9 +41,7 @@ fn test_encode_foo() {
|
||||
|
||||
#[test]
|
||||
fn test_encode_foo_wrapper() {
|
||||
let foo = FooWrapper {
|
||||
a: "cat".into(),
|
||||
};
|
||||
let foo = FooWrapper { a: "cat".into() };
|
||||
|
||||
let expected = vec![0x83, b'c', b'a', b't'];
|
||||
let out = encode(&foo);
|
||||
@ -57,3 +50,30 @@ fn test_encode_foo_wrapper() {
|
||||
let decoded = decode(&expected).expect("decode failure");
|
||||
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));
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
[package]
|
||||
name = "parity-version"
|
||||
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
|
||||
version = "2.7.1"
|
||||
version = "2.7.2"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user