[beta] Backports (#6891)

* v1.8.2

* Refactor static context check in CREATE. (#6886)

* Refactor static context check in CREATE.

* Fix wasm.

* Fix serialization of non-localized transactions (#6868)

* Fix serialization of non-localized transactions.

* Return proper SignedTransactions representation.

* Allow force sealing and reseal=0 for non-dev chains. (#6878)
This commit is contained in:
Arkadiy Paronyan 2017-10-25 13:13:11 +02:00 committed by GitHub
parent 0e4a06d078
commit 1b6588cb27
22 changed files with 155 additions and 120 deletions

52
Cargo.lock generated
View File

@ -5,7 +5,7 @@ dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0", "vm 0.1.0",
@ -374,7 +374,7 @@ dependencies = [
"bloomable 0.1.0", "bloomable 0.1.0",
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethjson 0.1.0", "ethjson 0.1.0",
"hash 0.1.0", "hash 0.1.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -588,7 +588,7 @@ dependencies = [
"ethcore-ipc-nano 1.8.0", "ethcore-ipc-nano 1.8.0",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-stratum 1.8.0", "ethcore-stratum 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethjson 0.1.0", "ethjson 0.1.0",
"ethkey 0.2.0", "ethkey 0.2.0",
"ethstore 0.1.0", "ethstore 0.1.0",
@ -682,7 +682,7 @@ version = "1.8.0"
dependencies = [ dependencies = [
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-devtools 1.8.0", "ethcore-devtools 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -732,7 +732,7 @@ dependencies = [
"ethcore-ipc 1.8.0", "ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0", "ethcore-ipc-codegen 1.8.0",
"ethcore-ipc-nano 1.8.0", "ethcore-ipc-nano 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -751,7 +751,7 @@ dependencies = [
"ethcore-ipc 1.8.0", "ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0", "ethcore-ipc-codegen 1.8.0",
"ethcore-network 1.8.0", "ethcore-network 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"evm 0.1.0", "evm 0.1.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"hash 0.1.0", "hash 0.1.0",
@ -801,7 +801,7 @@ dependencies = [
"ethcore-devtools 1.8.0", "ethcore-devtools 1.8.0",
"ethcore-io 1.8.0", "ethcore-io 1.8.0",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethcrypto 0.1.0", "ethcrypto 0.1.0",
"ethkey 0.2.0", "ethkey 0.2.0",
"hash 0.1.0", "hash 0.1.0",
@ -836,7 +836,7 @@ dependencies = [
"ethcore-ipc-codegen 1.8.0", "ethcore-ipc-codegen 1.8.0",
"ethcore-ipc-nano 1.8.0", "ethcore-ipc-nano 1.8.0",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethcrypto 0.1.0", "ethcrypto 0.1.0",
"ethkey 0.2.0", "ethkey 0.2.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -871,7 +871,7 @@ dependencies = [
"ethcore-ipc-codegen 1.8.0", "ethcore-ipc-codegen 1.8.0",
"ethcore-ipc-nano 1.8.0", "ethcore-ipc-nano 1.8.0",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"hash 0.1.0", "hash 0.1.0",
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
@ -884,7 +884,7 @@ dependencies = [
[[package]] [[package]]
name = "ethcore-util" name = "ethcore-util"
version = "1.8.1" version = "1.8.2"
dependencies = [ dependencies = [
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1018,7 +1018,7 @@ dependencies = [
"ethcore-ipc-nano 1.8.0", "ethcore-ipc-nano 1.8.0",
"ethcore-light 1.8.0", "ethcore-light 1.8.0",
"ethcore-network 1.8.0", "ethcore-network 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethkey 0.2.0", "ethkey 0.2.0",
"hash 0.1.0", "hash 0.1.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1044,7 +1044,7 @@ dependencies = [
"common-types 0.1.0", "common-types 0.1.0",
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethjson 0.1.0", "ethjson 0.1.0",
"evmjit 1.8.0", "evmjit 1.8.0",
"hash 0.1.0", "hash 0.1.0",
@ -1066,7 +1066,7 @@ dependencies = [
"ethcore 1.8.0", "ethcore 1.8.0",
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethjson 0.1.0", "ethjson 0.1.0",
"evm 0.1.0", "evm 0.1.0",
"panic_hook 0.1.0", "panic_hook 0.1.0",
@ -1364,7 +1364,7 @@ dependencies = [
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-ipc 1.8.0", "ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0", "ethcore-ipc-codegen 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1857,7 +1857,7 @@ dependencies = [
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-io 1.8.0", "ethcore-io 1.8.0",
"ethcore-network 1.8.0", "ethcore-network 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb 0.1.0", "kvdb 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2056,7 +2056,7 @@ dependencies = [
[[package]] [[package]]
name = "parity" name = "parity"
version = "1.8.1" version = "1.8.2"
dependencies = [ dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2080,7 +2080,7 @@ dependencies = [
"ethcore-network 1.8.0", "ethcore-network 1.8.0",
"ethcore-secretstore 1.0.0", "ethcore-secretstore 1.0.0",
"ethcore-stratum 1.8.0", "ethcore-stratum 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethkey 0.2.0", "ethkey 0.2.0",
"ethsync 1.8.0", "ethsync 1.8.0",
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2136,7 +2136,7 @@ dependencies = [
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-devtools 1.8.0", "ethcore-devtools 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"fetch 0.1.0", "fetch 0.1.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2198,7 +2198,7 @@ dependencies = [
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"fetch 0.1.0", "fetch 0.1.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"hash 0.1.0", "hash 0.1.0",
@ -2220,7 +2220,7 @@ dependencies = [
"ethcore 1.8.0", "ethcore 1.8.0",
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", "jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
"multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2234,7 +2234,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"ethcore 1.8.0", "ethcore 1.8.0",
"ethcore-io 1.8.0", "ethcore-io 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethkey 0.2.0", "ethkey 0.2.0",
"kvdb 0.1.0", "kvdb 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2249,7 +2249,7 @@ name = "parity-machine"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
] ]
[[package]] [[package]]
@ -2277,7 +2277,7 @@ dependencies = [
"ethcore-light 1.8.0", "ethcore-light 1.8.0",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-network 1.8.0", "ethcore-network 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethcrypto 0.1.0", "ethcrypto 0.1.0",
"ethjson 0.1.0", "ethjson 0.1.0",
"ethkey 0.2.0", "ethkey 0.2.0",
@ -2387,7 +2387,7 @@ dependencies = [
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-ipc 1.8.0", "ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0", "ethcore-ipc-codegen 1.8.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethsync 1.8.0", "ethsync 1.8.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-common-types 1.8.0", "ipc-common-types 1.8.0",
@ -2849,7 +2849,7 @@ name = "rpc-cli"
version = "1.4.0" version = "1.4.0"
dependencies = [ dependencies = [
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-rpc 1.8.0", "parity-rpc 1.8.0",
"parity-rpc-client 1.4.0", "parity-rpc-client 1.4.0",
@ -3565,7 +3565,7 @@ dependencies = [
"common-types 0.1.0", "common-types 0.1.0",
"ethcore-bigint 0.1.3", "ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-util 1.8.1", "ethcore-util 1.8.2",
"ethjson 0.1.0", "ethjson 0.1.0",
"evmjit 1.8.0", "evmjit 1.8.0",
"hash 0.1.0", "hash 0.1.0",

View File

@ -1,7 +1,7 @@
[package] [package]
description = "Parity Ethereum client" description = "Parity Ethereum client"
name = "parity" name = "parity"
version = "1.8.1" version = "1.8.2"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"

View File

@ -322,20 +322,24 @@ impl<Cost: CostType> Interpreter<Cost> {
let init_off = stack.pop_back(); let init_off = stack.pop_back();
let init_size = stack.pop_back(); let init_size = stack.pop_back();
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed"); let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed");
let contract_code = self.mem.read_slice(init_off, init_size); if ext.is_static() {
let can_create = ext.balance(&params.address)? >= endowment && ext.depth() < ext.schedule().max_depth; return Err(vm::Error::MutableCallInStaticContext);
}
// clear return data buffer before creating new call frame. // clear return data buffer before creating new call frame.
self.return_data = ReturnData::empty(); self.return_data = ReturnData::empty();
let can_create = ext.balance(&params.address)? >= endowment && ext.depth() < ext.schedule().max_depth;
if !can_create { if !can_create {
stack.push(U256::zero()); stack.push(U256::zero());
return Ok(InstructionResult::UnusedGas(create_gas)); return Ok(InstructionResult::UnusedGas(create_gas));
} }
let contract_code = self.mem.read_slice(init_off, init_size);
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme); let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme);
return match create_result { return match create_result {
ContractCreateResult::Created(address, gas_left) => { ContractCreateResult::Created(address, gas_left) => {
@ -351,9 +355,6 @@ impl<Cost: CostType> Interpreter<Cost> {
stack.push(U256::zero()); stack.push(U256::zero());
Ok(InstructionResult::Ok) Ok(InstructionResult::Ok)
}, },
ContractCreateResult::FailedInStaticCall => {
Err(vm::Error::MutableCallInStaticContext)
},
}; };
}, },
instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL | instructions::STATICCALL => { instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL | instructions::STATICCALL => {

View File

@ -724,7 +724,6 @@ fn test_jumps(factory: super::Factory) {
assert_eq!(gas_left, U256::from(54_117)); assert_eq!(gas_left, U256::from(54_117));
} }
evm_test!{test_calls: test_calls_jit, test_calls_int} evm_test!{test_calls: test_calls_jit, test_calls_int}
fn test_calls(factory: super::Factory) { fn test_calls(factory: super::Factory) {
let code = "600054602d57600160005560006000600060006050610998610100f160006000600060006050610998610100f25b".from_hex().unwrap(); let code = "600054602d57600160005560006000600060006050610998610100f160006000600060006050610998610100f25b".from_hex().unwrap();
@ -769,6 +768,27 @@ fn test_calls(factory: super::Factory) {
assert_eq!(ext.calls.len(), 2); assert_eq!(ext.calls.len(), 2);
} }
evm_test!{test_create_in_staticcall: test_create_in_staticcall_jit, test_create_in_staticcall_int}
fn test_create_in_staticcall(factory: super::Factory) {
let code = "600060006064f000".from_hex().unwrap();
let address = Address::from(0x155);
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
params.address = address.clone();
let mut ext = FakeExt::new_byzantium();
ext.is_static = true;
let err = {
let mut vm = factory.create(params.gas);
test_finalize(vm.exec(params, &mut ext)).unwrap_err()
};
assert_eq!(err, vm::Error::MutableCallInStaticContext);
assert_eq!(ext.calls.len(), 0);
}
fn assert_set_contains<T : Debug + Eq + PartialEq + Hash>(set: &HashSet<T>, val: &T) { fn assert_set_contains<T : Debug + Eq + PartialEq + Hash>(set: &HashSet<T>, val: &T) {
let contains = set.contains(val); let contains = set.contains(val);
if !contains { if !contains {

View File

@ -240,7 +240,6 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
Ok(FinalizationResult{ gas_left, apply_state: false, return_data }) => { Ok(FinalizationResult{ gas_left, apply_state: false, return_data }) => {
ContractCreateResult::Reverted(gas_left, return_data) ContractCreateResult::Reverted(gas_left, return_data)
}, },
Err(vm::Error::MutableCallInStaticContext) => ContractCreateResult::FailedInStaticCall,
_ => ContractCreateResult::Failed, _ => ContractCreateResult::Failed,
} }
} }

View File

@ -469,6 +469,11 @@ impl SignedTransaction {
pub fn is_unsigned(&self) -> bool { pub fn is_unsigned(&self) -> bool {
self.transaction.is_unsigned() self.transaction.is_unsigned()
} }
/// Deconstructs this transaction back into `UnverifiedTransaction`
pub fn deconstruct(self) -> (UnverifiedTransaction, Address, Option<Public>) {
(self.transaction, self.sender, self.public)
}
} }
/// Signed Transaction that is a part of canon blockchain. /// Signed Transaction that is a part of canon blockchain.

View File

@ -35,9 +35,6 @@ pub enum ContractCreateResult {
/// Returned when contract creation failed. /// Returned when contract creation failed.
/// VM doesn't have to know the reason. /// VM doesn't have to know the reason.
Failed, Failed,
/// Returned when contract creation failed.
/// VM doesn't have to know the reason.
FailedInStaticCall,
/// Reverted with REVERT. /// Reverted with REVERT.
Reverted(U256, ReturnData), Reverted(U256, ReturnData),
} }

View File

@ -65,6 +65,7 @@ pub struct FakeExt {
pub schedule: Schedule, pub schedule: Schedule,
pub balances: HashMap<Address, U256>, pub balances: HashMap<Address, U256>,
pub tracing: bool, pub tracing: bool,
pub is_static: bool,
} }
// similar to the normal `finalize` function, but ignoring NeedsReturn. // similar to the normal `finalize` function, but ignoring NeedsReturn.
@ -192,7 +193,7 @@ impl Ext for FakeExt {
} }
fn is_static(&self) -> bool { fn is_static(&self) -> bool {
false self.is_static
} }
fn inc_sstore_clears(&mut self) { fn inc_sstore_clears(&mut self) {

View File

@ -221,8 +221,8 @@ impl<'a, 'b> Runtime<'a, 'b> {
} }
/// Charge gas according to closure /// Charge gas according to closure
pub fn charge<F>(&mut self, f: F) -> Result<(), InterpreterError> pub fn charge<F>(&mut self, f: F) -> Result<(), InterpreterError>
where F: FnOnce(&vm::Schedule) -> u64 where F: FnOnce(&vm::Schedule) -> u64
{ {
let amount = f(self.ext.schedule()); let amount = f(self.ext.schedule());
if !self.charge_gas(amount as u64) { if !self.charge_gas(amount as u64) {
@ -277,10 +277,6 @@ impl<'a, 'b> Runtime<'a, 'b> {
self.gas_counter = self.gas_limit - gas_left.low_u64(); self.gas_counter = self.gas_limit - gas_left.low_u64();
Ok(Some((-1i32).into())) Ok(Some((-1i32).into()))
}, },
vm::ContractCreateResult::FailedInStaticCall => {
trace!(target: "wasm", "runtime: create contract called in static context");
Err(interpreter::Error::Trap("CREATE in static context".to_owned()))
},
} }
} }
@ -615,11 +611,11 @@ impl<'a, 'b> Runtime<'a, 'b> {
} }
fn return_u256_ptr(&mut self, ptr: u32, val: U256) -> Result<(), InterpreterError> { fn return_u256_ptr(&mut self, ptr: u32, val: U256) -> Result<(), InterpreterError> {
let value: H256 = val.into(); let value: H256 = val.into();
self.charge(|schedule| schedule.wasm.static_u256 as u64)?; self.charge(|schedule| schedule.wasm.static_u256 as u64)?;
self.memory.set(ptr, &*value)?; self.memory.set(ptr, &*value)?;
Ok(()) Ok(())
} }
fn coinbase(&mut self, context: InterpreterCallerContext) fn coinbase(&mut self, context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError> -> Result<Option<interpreter::RuntimeValue>, InterpreterError>
@ -640,7 +636,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
context.value_stack.pop_as::<i32>()? as u32, context.value_stack.pop_as::<i32>()? as u32,
sender, sender,
)?; )?;
Ok(None) Ok(None)
} }
fn address(&mut self, context: InterpreterCallerContext) fn address(&mut self, context: InterpreterCallerContext)
@ -651,7 +647,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
context.value_stack.pop_as::<i32>()? as u32, context.value_stack.pop_as::<i32>()? as u32,
addr, addr,
)?; )?;
Ok(None) Ok(None)
} }
fn origin(&mut self, context: InterpreterCallerContext) fn origin(&mut self, context: InterpreterCallerContext)
@ -662,7 +658,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
context.value_stack.pop_as::<i32>()? as u32, context.value_stack.pop_as::<i32>()? as u32,
origin, origin,
)?; )?;
Ok(None) Ok(None)
} }
fn value(&mut self, context: InterpreterCallerContext) fn value(&mut self, context: InterpreterCallerContext)
@ -709,7 +705,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
context.value_stack.pop_as::<i32>()? as u32, context.value_stack.pop_as::<i32>()? as u32,
gas_limit, gas_limit,
)?; )?;
Ok(None) Ok(None)
} }
fn return_i64(&mut self, val: i64) -> Result<Option<interpreter::RuntimeValue>, InterpreterError> { fn return_i64(&mut self, val: i64) -> Result<Option<interpreter::RuntimeValue>, InterpreterError> {

View File

@ -462,7 +462,7 @@
<key>OVERWRITE_PERMISSIONS</key> <key>OVERWRITE_PERMISSIONS</key>
<false/> <false/>
<key>VERSION</key> <key>VERSION</key>
<string>1.8.1</string> <string>1.8.2</string>
</dict> </dict>
<key>UUID</key> <key>UUID</key>
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string> <string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>

View File

@ -10,7 +10,7 @@
!define DESCRIPTION "Fast, light, robust Ethereum implementation" !define DESCRIPTION "Fast, light, robust Ethereum implementation"
!define VERSIONMAJOR 1 !define VERSIONMAJOR 1
!define VERSIONMINOR 8 !define VERSIONMINOR 8
!define VERSIONBUILD 1 !define VERSIONBUILD 2
!define ARGS "" !define ARGS ""
!define FIRST_START_ARGS "ui --mode=passive" !define FIRST_START_ARGS "ui --mode=passive"

View File

@ -40,7 +40,7 @@ use parity_rpc::NetworkSettings;
use cache::CacheConfig; use cache::CacheConfig;
use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_and_local, use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_and_local,
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy}; geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy};
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras}; use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, SpecType};
use ethcore_logger::Config as LogConfig; use ethcore_logger::Config as LogConfig;
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path}; use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
use dapps::Configuration as DappsConfiguration; use dapps::Configuration as DappsConfiguration;
@ -109,7 +109,7 @@ impl Configuration {
let pruning = self.args.arg_pruning.parse()?; let pruning = self.args.arg_pruning.parse()?;
let pruning_history = self.args.arg_pruning_history; let pruning_history = self.args.arg_pruning_history;
let vm_type = self.vm_type()?; let vm_type = self.vm_type()?;
let spec = self.chain().parse()?; let spec = self.chain()?;
let mode = match self.args.arg_mode.as_ref() { let mode = match self.args.arg_mode.as_ref() {
"last" => None, "last" => None,
mode => Some(to_mode(&mode, self.args.arg_mode_timeout, self.args.arg_mode_alarm)?), mode => Some(to_mode(&mode, self.args.arg_mode_timeout, self.args.arg_mode_alarm)?),
@ -336,7 +336,7 @@ impl Configuration {
pruning_memory: self.args.arg_pruning_memory, pruning_memory: self.args.arg_pruning_memory,
daemon: daemon, daemon: daemon,
logger_config: logger_config.clone(), logger_config: logger_config.clone(),
miner_options: self.miner_options(self.args.arg_reseal_min_period)?, miner_options: self.miner_options()?,
ntp_servers: self.ntp_servers(), ntp_servers: self.ntp_servers(),
ws_conf: ws_conf, ws_conf: ws_conf,
http_conf: http_conf, http_conf: http_conf,
@ -441,15 +441,16 @@ impl Configuration {
} }
} }
fn chain(&self) -> String { fn chain(&self) -> Result<SpecType, String> {
if let Some(ref s) = self.spec_name_override { let name = if let Some(ref s) = self.spec_name_override {
s.clone() s.clone()
} } else if self.args.flag_testnet {
else if self.args.flag_testnet {
"testnet".to_owned() "testnet".to_owned()
} else { } else {
self.args.arg_chain.clone() self.args.arg_chain.clone()
} };
Ok(name.parse()?)
} }
fn max_peers(&self) -> u32 { fn max_peers(&self) -> u32 {
@ -504,8 +505,9 @@ impl Configuration {
} else { Ok(None) } } else { Ok(None) }
} }
fn miner_options(&self, reseal_min_period: u64) -> Result<MinerOptions, String> { fn miner_options(&self) -> Result<MinerOptions, String> {
if self.args.flag_force_sealing && reseal_min_period == 0 { let is_dev_chain = self.chain()? == SpecType::Dev;
if is_dev_chain && self.args.flag_force_sealing && self.args.arg_reseal_min_period == 0 {
return Err("Force sealing can't be used with reseal_min_period = 0".into()); return Err("Force sealing can't be used with reseal_min_period = 0".into());
} }
@ -528,7 +530,7 @@ impl Configuration {
tx_queue_gas_limit: to_gas_limit(&self.args.arg_tx_queue_gas)?, tx_queue_gas_limit: to_gas_limit(&self.args.arg_tx_queue_gas)?,
tx_queue_strategy: to_queue_strategy(&self.args.arg_tx_queue_strategy)?, tx_queue_strategy: to_queue_strategy(&self.args.arg_tx_queue_strategy)?,
pending_set: to_pending_set(&self.args.arg_relay_set)?, pending_set: to_pending_set(&self.args.arg_relay_set)?,
reseal_min_period: Duration::from_millis(reseal_min_period), reseal_min_period: Duration::from_millis(self.args.arg_reseal_min_period),
reseal_max_period: Duration::from_millis(self.args.arg_reseal_max_period), reseal_max_period: Duration::from_millis(self.args.arg_reseal_max_period),
work_queue_size: self.args.arg_work_queue_size, work_queue_size: self.args.arg_work_queue_size,
enable_resubmission: !self.args.flag_remove_solved, enable_resubmission: !self.args.flag_remove_solved,
@ -883,7 +885,7 @@ impl Configuration {
let net_addresses = self.net_addresses()?; let net_addresses = self.net_addresses()?;
Ok(NetworkSettings { Ok(NetworkSettings {
name: self.args.arg_identity.clone(), name: self.args.arg_identity.clone(),
chain: self.chain(), chain: format!("{}", self.chain()?),
network_port: net_addresses.0.port(), network_port: net_addresses.0.port(),
rpc_enabled: http_conf.enabled, rpc_enabled: http_conf.enabled,
rpc_interface: http_conf.interface, rpc_interface: http_conf.interface,
@ -914,8 +916,6 @@ impl Configuration {
} }
fn directories(&self) -> Directories { fn directories(&self) -> Directories {
use path;
let local_path = default_local_path(); let local_path = default_local_path();
let base_path = self.args.arg_base_path.as_ref().or_else(|| self.args.arg_datadir.as_ref()).map_or_else(|| default_data_path(), |s| s.clone()); let base_path = self.args.arg_base_path.as_ref().or_else(|| self.args.arg_datadir.as_ref()).map_or_else(|| default_data_path(), |s| s.clone());
let data_path = replace_home("", &base_path); let data_path = replace_home("", &base_path);
@ -935,21 +935,6 @@ impl Configuration {
let secretstore_path = replace_home(&data_path, &self.args.arg_secretstore_path); let secretstore_path = replace_home(&data_path, &self.args.arg_secretstore_path);
let ui_path = replace_home(&data_path, &self.args.arg_ui_path); let ui_path = replace_home(&data_path, &self.args.arg_ui_path);
if self.args.flag_geth && !cfg!(windows) {
let geth_root = if self.chain() == "testnet".to_owned() { path::ethereum::test() } else { path::ethereum::default() };
::std::fs::create_dir_all(geth_root.as_path()).unwrap_or_else(
|e| warn!("Failed to create '{}' for geth mode: {}", &geth_root.to_str().unwrap(), e));
}
if cfg!(feature = "ipc") && !cfg!(feature = "windows") {
let mut path_buf = PathBuf::from(data_path.clone());
path_buf.push("ipc");
let ipc_path = path_buf.to_str().unwrap();
::std::fs::create_dir_all(ipc_path).unwrap_or_else(
|e| warn!("Failed to directory '{}' for ipc sockets: {}", ipc_path, e)
);
}
Directories { Directories {
keys: keys_path, keys: keys_path,
base: data_path, base: data_path,
@ -1401,21 +1386,20 @@ mod tests {
let conf3 = parse(&["parity", "--tx-queue-strategy", "gas"]); let conf3 = parse(&["parity", "--tx-queue-strategy", "gas"]);
// then // then
let min_period = conf0.args.arg_reseal_min_period; assert_eq!(conf0.miner_options().unwrap(), mining_options);
assert_eq!(conf0.miner_options(min_period).unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasFactorAndGasPrice; mining_options.tx_queue_strategy = PrioritizationStrategy::GasFactorAndGasPrice;
assert_eq!(conf1.miner_options(min_period).unwrap(), mining_options); assert_eq!(conf1.miner_options().unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasPriceOnly; mining_options.tx_queue_strategy = PrioritizationStrategy::GasPriceOnly;
assert_eq!(conf2.miner_options(min_period).unwrap(), mining_options); assert_eq!(conf2.miner_options().unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasAndGasPrice; mining_options.tx_queue_strategy = PrioritizationStrategy::GasAndGasPrice;
assert_eq!(conf3.miner_options(min_period).unwrap(), mining_options); assert_eq!(conf3.miner_options().unwrap(), mining_options);
} }
#[test] #[test]
fn should_fail_on_force_reseal_and_reseal_min_period() { fn should_fail_on_force_reseal_and_reseal_min_period() {
let conf = parse(&["parity", "--chain", "dev", "--force-sealing"]); let conf = parse(&["parity", "--chain", "dev", "--force-sealing", "--reseal-min-period", "0"]);
assert!(conf.miner_options(0).is_err()); assert!(conf.miner_options().is_err());
} }
#[test] #[test]
@ -1443,7 +1427,7 @@ mod tests {
// then // then
assert_eq!(conf.network_settings(), Ok(NetworkSettings { assert_eq!(conf.network_settings(), Ok(NetworkSettings {
name: "testname".to_owned(), name: "testname".to_owned(),
chain: "testnet".to_owned(), chain: "kovan".to_owned(),
network_port: 30303, network_port: 30303,
rpc_enabled: true, rpc_enabled: true,
rpc_interface: "127.0.0.1".to_owned(), rpc_interface: "127.0.0.1".to_owned(),

View File

@ -301,6 +301,12 @@ pub fn new_ipc<D: rpc_apis::Dependencies>(
let handler = setup_apis(conf.apis, dependencies); let handler = setup_apis(conf.apis, dependencies);
let remote = dependencies.remote.clone(); let remote = dependencies.remote.clone();
let path = PathBuf::from(&conf.socket_addr);
if let Some(dir) = path.parent() {
::std::fs::create_dir_all(&dir)
.map_err(|err| format!("Unable to create IPC directory at {}: {}", dir.display(), err))?;
}
match rpc::start_ipc(&conf.socket_addr, handler, remote, rpc::RpcExtractor) { match rpc::start_ipc(&conf.socket_addr, handler, remote, rpc::RpcExtractor) {
Ok(server) => Ok(Some(server)), Ok(server) => Ok(Some(server)),
Err(io_error) => Err(format!("IPC error: {}", io_error)), Err(io_error) => Err(format!("IPC error: {}", io_error)),

View File

@ -71,6 +71,9 @@ pub trait Dispatcher: Send + Sync + Clone {
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith) fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
-> BoxFuture<WithToken<SignedTransaction>, Error>; -> BoxFuture<WithToken<SignedTransaction>, Error>;
/// Converts a `SignedTransaction` into `RichRawTransaction`
fn enrich(&self, SignedTransaction) -> RpcRichRawTransaction;
/// "Dispatch" a local transaction. /// "Dispatch" a local transaction.
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error>; fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error>;
} }
@ -163,6 +166,11 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
})) }))
} }
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
let block_number = self.client.best_block_header().number();
RpcRichRawTransaction::from_signed(signed_transaction, block_number, self.client.eip86_transition())
}
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error> { fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error> {
let hash = signed_transaction.transaction.hash(); let hash = signed_transaction.transaction.hash();
@ -261,11 +269,11 @@ impl LightDispatcher {
transaction_queue: Arc<RwLock<LightTransactionQueue>>, transaction_queue: Arc<RwLock<LightTransactionQueue>>,
) -> Self { ) -> Self {
LightDispatcher { LightDispatcher {
sync: sync, sync,
client: client, client,
on_demand: on_demand, on_demand,
cache: cache, cache,
transaction_queue: transaction_queue, transaction_queue,
} }
} }
@ -399,6 +407,11 @@ impl Dispatcher for LightDispatcher {
.and_then(move |nonce| with_nonce(filled, nonce))) .and_then(move |nonce| with_nonce(filled, nonce)))
} }
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
let block_number = self.client.best_block_header().number();
RpcRichRawTransaction::from_signed(signed_transaction, block_number, self.client.eip86_transition())
}
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error> { fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error> {
let hash = signed_transaction.transaction.hash(); let hash = signed_transaction.transaction.hash();
@ -510,8 +523,8 @@ pub fn execute<D: Dispatcher + 'static>(
}, },
ConfirmationPayload::SignTransaction(request) => { ConfirmationPayload::SignTransaction(request) => {
Box::new(dispatcher.sign(accounts, request, pass) Box::new(dispatcher.sign(accounts, request, pass)
.map(|result| result .map(move |result| result
.map(RpcRichRawTransaction::from) .map(move |tx| dispatcher.enrich(tx))
.map(ConfirmationResponse::SignTransaction) .map(ConfirmationResponse::SignTransaction)
)) ))
}, },

View File

@ -23,7 +23,7 @@ use ethcore::encoded;
use ethcore::executed::{Executed, ExecutionError}; use ethcore::executed::{Executed, ExecutionError};
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use ethcore::filter::Filter as EthcoreFilter; use ethcore::filter::Filter as EthcoreFilter;
use ethcore::transaction::{Action, Transaction as EthTransaction, SignedTransaction}; use ethcore::transaction::{Action, Transaction as EthTransaction, SignedTransaction, LocalizedTransaction};
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use jsonrpc_core::{BoxFuture, Error}; use jsonrpc_core::{BoxFuture, Error};
@ -65,13 +65,24 @@ pub struct LightFetch {
/// Extract a transaction at given index. /// Extract a transaction at given index.
pub fn extract_transaction_at_index(block: encoded::Block, index: usize, eip86_transition: u64) -> Option<Transaction> { pub fn extract_transaction_at_index(block: encoded::Block, index: usize, eip86_transition: u64) -> Option<Transaction> {
block.transactions().into_iter().nth(index) block.transactions().into_iter().nth(index)
// Verify if transaction signature is correct.
.and_then(|tx| SignedTransaction::new(tx).ok()) .and_then(|tx| SignedTransaction::new(tx).ok())
.map(|tx| Transaction::from_signed(tx, block.number(), eip86_transition)) .map(|signed_tx| {
.map(|mut tx| { let (signed, sender, _) = signed_tx.deconstruct();
tx.block_hash = Some(block.hash().into()); let block_hash = block.hash();
tx.transaction_index = Some(index.into()); let block_number = block.number();
tx let transaction_index = index;
let cached_sender = Some(sender);
LocalizedTransaction {
signed,
block_number,
block_hash,
transaction_index,
cached_sender,
}
}) })
.map(|tx| Transaction::from_localized(tx, eip86_transition))
} }

View File

@ -73,8 +73,8 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
SignerClient { SignerClient {
signer: signer.clone(), signer: signer.clone(),
accounts: store.clone(), accounts: store.clone(),
dispatcher: dispatcher, dispatcher,
subscribers: subscribers, subscribers,
} }
} }
@ -205,7 +205,8 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
}, },
ConfirmationPayload::SignTransaction(request) => { ConfirmationPayload::SignTransaction(request) => {
Self::verify_transaction(bytes, request, |pending_transaction| { Self::verify_transaction(bytes, request, |pending_transaction| {
Ok(ConfirmationResponse::SignTransaction(pending_transaction.transaction.into())) let rich = self.dispatcher.enrich(pending_transaction.transaction);
Ok(ConfirmationResponse::SignTransaction(rich))
}) })
}, },
ConfirmationPayload::EthSignMessage(address, data) => { ConfirmationPayload::EthSignMessage(address, data) => {

View File

@ -547,7 +547,7 @@ fn rpc_eth_pending_transaction_by_hash() {
tester.miner.pending_transactions.lock().insert(H256::zero(), tx); tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
} }
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":"0x0","chainId":null,"condition":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"chainId":null,"condition":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"#;
let request = r#"{ let request = r#"{
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "eth_getTransactionByHash", "method": "eth_getTransactionByHash",
@ -863,7 +863,7 @@ fn rpc_eth_sign_transaction() {
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() + let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
r#""raw":"0x"# + &rlp.to_hex() + r#"","# + r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
r#""tx":{"# + r#""tx":{"# +
r#""blockHash":null,"blockNumber":"0x0","# + r#""blockHash":null,"blockNumber":null,"# +
&format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) + &format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) +
r#""condition":null,"creates":null,"# + r#""condition":null,"creates":null,"# +
&format!("\"from\":\"0x{:?}\",", &address) + &format!("\"from\":\"0x{:?}\",", &address) +

View File

@ -234,7 +234,7 @@ fn rpc_parity_remove_transaction() {
let hash = signed.hash(); let hash = signed.hash();
let request = r#"{"jsonrpc": "2.0", "method": "parity_removeTransaction", "params":[""#.to_owned() + &format!("0x{:?}", hash) + r#""], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_removeTransaction", "params":[""#.to_owned() + &format!("0x{:?}", hash) + r#""], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":"0x0","chainId":null,"condition":null,"creates":null,"from":"0x0000000000000000000000000000000000000002","gas":"0x76c0","gasPrice":"0x9184e72a000","hash":"0xa2e0da8a8064e0b9f93e95a53c2db6d01280efb8ac72a708d25487e67dd0f8fc","input":"0x","nonce":"0x1","publicKey":null,"r":"0x1","raw":"0xe9018609184e72a0008276c0940000000000000000000000000000000000000005849184e72a80800101","s":"0x1","standardV":"0x4","to":"0x0000000000000000000000000000000000000005","transactionIndex":null,"v":"0x0","value":"0x9184e72a"},"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"chainId":null,"condition":null,"creates":null,"from":"0x0000000000000000000000000000000000000002","gas":"0x76c0","gasPrice":"0x9184e72a000","hash":"0xa2e0da8a8064e0b9f93e95a53c2db6d01280efb8ac72a708d25487e67dd0f8fc","input":"0x","nonce":"0x1","publicKey":null,"r":"0x1","raw":"0xe9018609184e72a0008276c0940000000000000000000000000000000000000005849184e72a80800101","s":"0x1","standardV":"0x4","to":"0x0000000000000000000000000000000000000005","transactionIndex":null,"v":"0x0","value":"0x9184e72a"},"id":1}"#;
miner.pending_transactions.lock().insert(hash, signed); miner.pending_transactions.lock().insert(hash, signed);
assert_eq!(io.handle_request_sync(&request), Some(response.to_owned())); assert_eq!(io.handle_request_sync(&request), Some(response.to_owned()));

View File

@ -456,7 +456,7 @@ fn should_confirm_sign_transaction_with_rlp() {
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() + let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
r#""raw":"0x"# + &rlp.to_hex() + r#"","# + r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
r#""tx":{"# + r#""tx":{"# +
r#""blockHash":null,"blockNumber":"0x0","# + r#""blockHash":null,"blockNumber":null,"# +
&format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) + &format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) +
r#""condition":null,"creates":null,"# + r#""condition":null,"creates":null,"# +
&format!("\"from\":\"0x{:?}\",", &address) + &format!("\"from\":\"0x{:?}\",", &address) +

View File

@ -25,7 +25,7 @@ use v1::impls::SigningQueueClient;
use v1::metadata::Metadata; use v1::metadata::Metadata;
use v1::traits::{EthSigning, ParitySigning, Parity}; use v1::traits::{EthSigning, ParitySigning, Parity};
use v1::helpers::{SignerService, SigningQueue, FullDispatcher}; use v1::helpers::{SignerService, SigningQueue, FullDispatcher};
use v1::types::ConfirmationResponse; use v1::types::{ConfirmationResponse, RichRawTransaction};
use v1::tests::helpers::TestMinerService; use v1::tests::helpers::TestMinerService;
use v1::tests::mocked::parity; use v1::tests::mocked::parity;
@ -299,7 +299,7 @@ fn should_add_sign_transaction_to_the_queue() {
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() + let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
r#""raw":"0x"# + &rlp.to_hex() + r#"","# + r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
r#""tx":{"# + r#""tx":{"# +
r#""blockHash":null,"blockNumber":"0x0","# + r#""blockHash":null,"blockNumber":null,"# +
&format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) + &format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) +
r#""condition":null,"creates":null,"# + r#""condition":null,"creates":null,"# +
&format!("\"from\":\"0x{:?}\",", &address) + &format!("\"from\":\"0x{:?}\",", &address) +
@ -326,7 +326,9 @@ fn should_add_sign_transaction_to_the_queue() {
::std::thread::spawn(move || loop { ::std::thread::spawn(move || loop {
if signer.requests().len() == 1 { if signer.requests().len() == 1 {
// respond // respond
signer.request_confirmed(1.into(), Ok(ConfirmationResponse::SignTransaction(t.into()))); signer.request_confirmed(1.into(), Ok(ConfirmationResponse::SignTransaction(
RichRawTransaction::from_signed(t.into(), 0x0, u64::max_value())
)));
break break
} }
::std::thread::sleep(Duration::from_millis(100)) ::std::thread::sleep(Duration::from_millis(100))

View File

@ -158,11 +158,10 @@ pub struct RichRawTransaction {
pub transaction: Transaction pub transaction: Transaction
} }
impl RichRawTransaction {
impl From<SignedTransaction> for RichRawTransaction { /// Creates new `RichRawTransaction` from `SignedTransaction`.
fn from(t: SignedTransaction) -> Self { pub fn from_signed(tx: SignedTransaction, block_number: u64, eip86_transition: u64) -> Self {
// TODO: change transition to 0 when EIP-86 is commonly used. let tx = Transaction::from_signed(tx, block_number, eip86_transition);
let tx: Transaction = Transaction::from_signed(t, 0, u64::max_value());
RichRawTransaction { RichRawTransaction {
raw: tx.raw.clone(), raw: tx.raw.clone(),
transaction: tx, transaction: tx,
@ -213,7 +212,7 @@ impl Transaction {
hash: t.hash().into(), hash: t.hash().into(),
nonce: t.nonce.into(), nonce: t.nonce.into(),
block_hash: None, block_hash: None,
block_number: Some(block_number.into()), block_number: None,
transaction_index: None, transaction_index: None,
from: t.sender().into(), from: t.sender().into(),
to: match t.action { to: match t.action {

View File

@ -3,7 +3,7 @@ description = "Ethcore utility library"
homepage = "http://parity.io" homepage = "http://parity.io"
license = "GPL-3.0" license = "GPL-3.0"
name = "ethcore-util" name = "ethcore-util"
version = "1.8.1" version = "1.8.2"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"