Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
ea14290f52
304
Cargo.lock
generated
304
Cargo.lock
generated
@ -253,6 +253,16 @@ dependencies = [
|
|||||||
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "common-types"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ethcore-util 1.8.0",
|
||||||
|
"ethjson 0.1.0",
|
||||||
|
"rlp 0.2.0",
|
||||||
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conv"
|
name = "conv"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@ -419,7 +429,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethash"
|
name = "ethash"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -429,32 +439,33 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore"
|
name = "ethcore"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
||||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
|
"common-types 0.1.0",
|
||||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.7.0",
|
"ethash 1.8.0",
|
||||||
"ethcore-bloom-journal 0.1.0",
|
"ethcore-bloom-journal 0.1.0",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.8.0",
|
||||||
"ethcore-logger 1.7.0",
|
"ethcore-logger 1.8.0",
|
||||||
"ethcore-stratum 1.7.0",
|
"ethcore-stratum 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethjson 0.1.0",
|
"ethjson 0.1.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"ethstore 0.1.0",
|
"ethstore 0.1.0",
|
||||||
"evmjit 1.7.0",
|
"evm 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hardware-wallet 1.7.0",
|
"hardware-wallet 1.8.0",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
|
||||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -464,7 +475,6 @@ dependencies = [
|
|||||||
"native-contracts 0.1.0",
|
"native-contracts 0.1.0",
|
||||||
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.0",
|
"rlp 0.2.0",
|
||||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -474,7 +484,6 @@ dependencies = [
|
|||||||
"stats 0.1.0",
|
"stats 0.1.0",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -497,14 +506,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-devtools"
|
name = "ethcore-devtools"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-io"
|
name = "ethcore-io"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -515,17 +524,17 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-ipc"
|
name = "ethcore-ipc"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-ipc-codegen"
|
name = "ethcore-ipc-codegen"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
@ -540,9 +549,9 @@ dependencies = [
|
|||||||
name = "ethcore-ipc-hypervisor"
|
name = "ethcore-ipc-hypervisor"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.8.0",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (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)",
|
||||||
@ -551,9 +560,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-ipc-nano"
|
name = "ethcore-ipc-nano"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (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)",
|
||||||
@ -563,11 +572,11 @@ dependencies = [
|
|||||||
name = "ethcore-ipc-tests"
|
name = "ethcore-ipc-tests"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (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)",
|
||||||
@ -575,16 +584,17 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-light"
|
name = "ethcore-light"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-network 1.7.0",
|
"ethcore-network 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
|
"evm 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -599,7 +609,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-logger"
|
name = "ethcore-logger"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
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)",
|
||||||
"arrayvec 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -614,15 +624,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-network"
|
name = "ethcore-network"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
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)",
|
||||||
"bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.8.0",
|
||||||
"ethcore-logger 1.7.0",
|
"ethcore-logger 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethcrypto 0.1.0",
|
"ethcrypto 0.1.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -647,13 +657,13 @@ version = "1.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.8.0",
|
||||||
"ethcore-logger 1.7.0",
|
"ethcore-logger 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethcrypto 0.1.0",
|
"ethcrypto 0.1.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -675,15 +685,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-stratum"
|
name = "ethcore-stratum"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.8.0",
|
||||||
"ethcore-logger 1.7.0",
|
"ethcore-logger 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
"jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
@ -696,7 +706,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-util"
|
name = "ethcore-util"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
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)",
|
||||||
"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)",
|
||||||
@ -705,8 +715,8 @@ dependencies = [
|
|||||||
"eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)",
|
"eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)",
|
||||||
"ethcore-bigint 0.1.3",
|
"ethcore-bigint 0.1.3",
|
||||||
"ethcore-bloom-journal 0.1.0",
|
"ethcore-bloom-journal 0.1.0",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-logger 1.7.0",
|
"ethcore-logger 1.8.0",
|
||||||
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -746,7 +756,7 @@ name = "ethjson"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
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)",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -815,19 +825,19 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethsync"
|
name = "ethsync"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
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)",
|
||||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.8.0",
|
||||||
"ethcore-light 1.7.0",
|
"ethcore-light 1.8.0",
|
||||||
"ethcore-network 1.7.0",
|
"ethcore-network 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -839,13 +849,32 @@ dependencies = [
|
|||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "evm"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"common-types 0.1.0",
|
||||||
|
"ethcore-util 1.8.0",
|
||||||
|
"ethjson 0.1.0",
|
||||||
|
"evmjit 1.8.0",
|
||||||
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rlp 0.2.0",
|
||||||
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "evmbin"
|
name = "evmbin"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
|
"evm 0.1.0",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -853,7 +882,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "evmjit"
|
name = "evmjit"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -958,7 +987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hardware-wallet"
|
name = "hardware-wallet"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-bigint 0.1.3",
|
"ethcore-bigint 0.1.3",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
@ -1085,11 +1114,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipc-common-types"
|
name = "ipc-common-types"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1483,7 +1512,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"native-contract-generator 0.1.0",
|
"native-contract-generator 0.1.0",
|
||||||
]
|
]
|
||||||
@ -1682,20 +1711,20 @@ dependencies = [
|
|||||||
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-hypervisor 1.2.0",
|
"ethcore-ipc-hypervisor 1.2.0",
|
||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.8.0",
|
||||||
"ethcore-ipc-tests 0.1.0",
|
"ethcore-ipc-tests 0.1.0",
|
||||||
"ethcore-light 1.7.0",
|
"ethcore-light 1.8.0",
|
||||||
"ethcore-logger 1.7.0",
|
"ethcore-logger 1.8.0",
|
||||||
"ethcore-secretstore 1.0.0",
|
"ethcore-secretstore 1.0.0",
|
||||||
"ethcore-stratum 1.7.0",
|
"ethcore-stratum 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"ethsync 1.7.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)",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1704,14 +1733,14 @@ dependencies = [
|
|||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-dapps 1.7.0",
|
"parity-dapps 1.8.0",
|
||||||
"parity-hash-fetch 1.7.0",
|
"parity-hash-fetch 1.8.0",
|
||||||
"parity-ipfs-api 1.7.0",
|
"parity-ipfs-api 1.8.0",
|
||||||
"parity-local-store 0.1.0",
|
"parity-local-store 0.1.0",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
"parity-rpc 1.7.0",
|
"parity-rpc 1.8.0",
|
||||||
"parity-rpc-client 1.4.0",
|
"parity-rpc-client 1.4.0",
|
||||||
"parity-updater 1.7.0",
|
"parity-updater 1.8.0",
|
||||||
"path 0.1.0",
|
"path 0.1.0",
|
||||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1732,13 +1761,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-dapps"
|
name = "parity-dapps"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1750,9 +1779,9 @@ dependencies = [
|
|||||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ntp 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ntp 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-hash-fetch 1.7.0",
|
"parity-hash-fetch 1.8.0",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
"parity-ui 1.7.0",
|
"parity-ui 1.8.0",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1780,10 +1809,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-hash-fetch"
|
name = "parity-hash-fetch"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1797,11 +1826,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ipfs-api"
|
name = "parity-ipfs-api"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
@ -1812,9 +1841,9 @@ dependencies = [
|
|||||||
name = "parity-local-store"
|
name = "parity-local-store"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.0",
|
"rlp 0.2.0",
|
||||||
@ -1833,23 +1862,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-rpc"
|
name = "parity-rpc"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"ethash 1.7.0",
|
"ethash 1.8.0",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-devtools 1.7.0",
|
"ethcore-devtools 1.8.0",
|
||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-light 1.7.0",
|
"ethcore-light 1.8.0",
|
||||||
"ethcore-logger 1.7.0",
|
"ethcore-logger 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethcrypto 0.1.0",
|
"ethcrypto 0.1.0",
|
||||||
"ethjson 0.1.0",
|
"ethjson 0.1.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"ethstore 0.1.0",
|
"ethstore 0.1.0",
|
||||||
"ethsync 1.7.0",
|
"ethsync 1.8.0",
|
||||||
|
"evm 0.1.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1864,7 +1894,7 @@ dependencies = [
|
|||||||
"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)",
|
||||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
"parity-updater 1.7.0",
|
"parity-updater 1.8.0",
|
||||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.0",
|
"rlp 0.2.0",
|
||||||
@ -1884,13 +1914,13 @@ dependencies = [
|
|||||||
name = "parity-rpc-client"
|
name = "parity-rpc-client"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-ws-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
"jsonrpc-ws-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-rpc 1.7.0",
|
"parity-rpc 1.8.0",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1917,16 +1947,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui"
|
name = "parity-ui"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-ui-dev 1.7.0",
|
"parity-ui-dev 1.8.0",
|
||||||
"parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git)",
|
"parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git)",
|
||||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-dev"
|
name = "parity-ui-dev"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -1934,25 +1964,25 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-precompiled"
|
name = "parity-ui-precompiled"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "git+https://github.com/paritytech/js-precompiled.git#fa572f52beb3a7b6f6473a5a5cf07518d899c4d9"
|
source = "git+https://github.com/paritytech/js-precompiled.git#92627cfd287eb5176c016089b9e2350107f8869a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-updater"
|
name = "parity-updater"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.8.0",
|
||||||
"ethcore-ipc 1.7.0",
|
"ethcore-ipc 1.8.0",
|
||||||
"ethcore-ipc-codegen 1.7.0",
|
"ethcore-ipc-codegen 1.8.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"ethsync 1.7.0",
|
"ethsync 1.8.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ipc-common-types 1.7.0",
|
"ipc-common-types 1.8.0",
|
||||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-hash-fetch 1.7.0",
|
"parity-hash-fetch 1.8.0",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
"path 0.1.0",
|
"path 0.1.0",
|
||||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2294,9 +2324,9 @@ name = "rpc-cli"
|
|||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.8.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-rpc 1.7.0",
|
"parity-rpc 1.8.0",
|
||||||
"parity-rpc-client 1.4.0",
|
"parity-rpc-client 1.4.0",
|
||||||
"rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -81,14 +81,6 @@ Once you have rustup, install parity or download and build from source
|
|||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
## Quick build and install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo install --git https://github.com/paritytech/parity.git parity
|
|
||||||
```
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
## Install from the snap store
|
## Install from the snap store
|
||||||
|
|
||||||
In any of the [supported Linux distros](https://snapcraft.io/docs/core/install):
|
In any of the [supported Linux distros](https://snapcraft.io/docs/core/install):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
description = "Parity Dapps crate"
|
description = "Parity Dapps crate"
|
||||||
name = "parity-dapps"
|
name = "parity-dapps"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ description = "Ethcore Parity UI"
|
|||||||
homepage = "http://parity.io"
|
homepage = "http://parity.io"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
name = "parity-ui"
|
name = "parity-ui"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
@ -3,7 +3,7 @@ description = "Ethcore development/test/build tools"
|
|||||||
homepage = "http://parity.io"
|
homepage = "http://parity.io"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
name = "ethcore-devtools"
|
name = "ethcore-devtools"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ethash"
|
name = "ethash"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -3,7 +3,7 @@ description = "Ethcore library"
|
|||||||
homepage = "http://parity.io"
|
homepage = "http://parity.io"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
name = "ethcore"
|
name = "ethcore"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
@ -16,6 +16,7 @@ bloomchain = "0.1"
|
|||||||
bn = { git = "https://github.com/paritytech/bn" }
|
bn = { git = "https://github.com/paritytech/bn" }
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
clippy = { version = "0.0.103", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
common-types = { path = "types" }
|
||||||
crossbeam = "0.2.9"
|
crossbeam = "0.2.9"
|
||||||
env_logger = "0.4"
|
env_logger = "0.4"
|
||||||
ethabi = "2.0"
|
ethabi = "2.0"
|
||||||
@ -31,7 +32,7 @@ ethcore-util = { path = "../util" }
|
|||||||
ethjson = { path = "../json" }
|
ethjson = { path = "../json" }
|
||||||
ethkey = { path = "../ethkey" }
|
ethkey = { path = "../ethkey" }
|
||||||
ethstore = { path = "../ethstore" }
|
ethstore = { path = "../ethstore" }
|
||||||
evmjit = { path = "../evmjit", optional = true }
|
evm = { path = "evm" }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hardware-wallet = { path = "../hw" }
|
hardware-wallet = { path = "../hw" }
|
||||||
hyper = { git = "https://github.com/paritytech/hyper", default-features = false }
|
hyper = { git = "https://github.com/paritytech/hyper", default-features = false }
|
||||||
@ -52,14 +53,12 @@ semver = "0.6"
|
|||||||
stats = { path = "../util/stats" }
|
stats = { path = "../util/stats" }
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
transient-hashmap = "0.4"
|
transient-hashmap = "0.4"
|
||||||
parity-wasm = "0.12"
|
|
||||||
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
native-contracts = { path = "native_contracts", features = ["test_contracts"] }
|
native-contracts = { path = "native_contracts", features = ["test_contracts"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
jit = ["evmjit"]
|
jit = ["evm/jit"]
|
||||||
evm-debug = ["slow-blocks"]
|
evm-debug = ["slow-blocks"]
|
||||||
evm-debug-tests = ["evm-debug"]
|
evm-debug-tests = ["evm-debug"]
|
||||||
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
|
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
extern crate ethcore_ipc_codegen;
|
extern crate ethcore_ipc_codegen;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap();
|
|
||||||
ethcore_ipc_codegen::derive_ipc_cond("src/client/traits.rs", cfg!(feature="ipc")).unwrap();
|
ethcore_ipc_codegen::derive_ipc_cond("src/client/traits.rs", cfg!(feature="ipc")).unwrap();
|
||||||
ethcore_ipc_codegen::derive_ipc_cond("src/snapshot/snapshot_service_trait.rs", cfg!(feature="ipc")).unwrap();
|
ethcore_ipc_codegen::derive_ipc_cond("src/snapshot/snapshot_service_trait.rs", cfg!(feature="ipc")).unwrap();
|
||||||
ethcore_ipc_codegen::derive_ipc_cond("src/client/chain_notify.rs", cfg!(feature="ipc")).unwrap();
|
ethcore_ipc_codegen::derive_ipc_cond("src/client/chain_notify.rs", cfg!(feature="ipc")).unwrap();
|
||||||
|
23
ethcore/evm/Cargo.toml
Normal file
23
ethcore/evm/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[package]
|
||||||
|
name = "evm"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bit-set = "0.4"
|
||||||
|
byteorder = "1.0"
|
||||||
|
common-types = { path = "../types" }
|
||||||
|
ethcore-util = { path = "../../util" }
|
||||||
|
evmjit = { path = "../../evmjit", optional = true }
|
||||||
|
ethjson = { path = "../../json" }
|
||||||
|
lazy_static = "0.2"
|
||||||
|
log = "0.3"
|
||||||
|
rlp = { path = "../../util/rlp" }
|
||||||
|
parity-wasm = "0.12"
|
||||||
|
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rustc-hex = "1.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
jit = ["evmjit"]
|
@ -19,7 +19,8 @@ use util::{Address, Bytes, U256};
|
|||||||
use util::hash::{H256};
|
use util::hash::{H256};
|
||||||
use util::sha3::{Hashable, SHA3_EMPTY};
|
use util::sha3::{Hashable, SHA3_EMPTY};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use types::executed::CallType;
|
|
||||||
|
use {CallType};
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
@ -25,7 +25,7 @@ extern crate test;
|
|||||||
use self::test::{Bencher, black_box};
|
use self::test::{Bencher, black_box};
|
||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
use evm::{self, Factory, VMType};
|
use evm::{self, Factory, VMType};
|
||||||
use evm::tests::FakeExt;
|
use evm::tests::FakeExt;
|
||||||
|
|
70
ethcore/evm/src/call_type.rs
Normal file
70
ethcore/evm/src/call_type.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//! EVM call types.
|
||||||
|
|
||||||
|
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
|
||||||
|
|
||||||
|
/// The type of the call-like instruction.
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum CallType {
|
||||||
|
/// Not a CALL.
|
||||||
|
None,
|
||||||
|
/// CALL.
|
||||||
|
Call,
|
||||||
|
/// CALLCODE.
|
||||||
|
CallCode,
|
||||||
|
/// DELEGATECALL.
|
||||||
|
DelegateCall,
|
||||||
|
/// STATICCALL
|
||||||
|
StaticCall,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for CallType {
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
Encodable::rlp_append(&v, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for CallType {
|
||||||
|
fn decode(rlp: &UntrustedRlp) -> 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")),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use rlp::*;
|
||||||
|
use super::CallType;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn encode_call_type() {
|
||||||
|
let ct = CallType::Call;
|
||||||
|
|
||||||
|
let mut s = RlpStream::new_list(2);
|
||||||
|
s.append(&ct);
|
||||||
|
assert!(!s.is_finished(), "List shouldn't finished yet");
|
||||||
|
s.append(&ct);
|
||||||
|
assert!(s.is_finished(), "List should be finished now");
|
||||||
|
s.out();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_encode_and_decode_call_type() {
|
||||||
|
let original = CallType::Call;
|
||||||
|
let encoded = encode(&original);
|
||||||
|
let decoded = decode(&encoded);
|
||||||
|
assert_eq!(original, decoded);
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use util::{U256, Address, H256, Hashable};
|
use util::{U256, Address, H256, Hashable};
|
||||||
use header::BlockNumber;
|
use types::BlockNumber;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
|
|
||||||
/// Simple vector of hashes, should be at most 256 items large, can be smaller if being used
|
/// Simple vector of hashes, should be at most 256 items large, can be smaller if being used
|
||||||
@ -82,7 +82,7 @@ mod tests {
|
|||||||
use ethjson;
|
use ethjson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_serializes_form_json() {
|
fn it_serializes_from_json() {
|
||||||
let env_info = EnvInfo::from(ethjson::vm::Env {
|
let env_info = EnvInfo::from(ethjson::vm::Env {
|
||||||
author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()),
|
author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()),
|
||||||
number: ethjson::uint::Uint(U256::from(1_112_339)),
|
number: ethjson::uint::Uint(U256::from(1_112_339)),
|
@ -19,8 +19,8 @@
|
|||||||
use std::{ops, cmp, fmt};
|
use std::{ops, cmp, fmt};
|
||||||
use util::{U128, U256, U512, trie};
|
use util::{U128, U256, U512, trie};
|
||||||
use action_params::ActionParams;
|
use action_params::ActionParams;
|
||||||
use evm::Ext;
|
use {Ext};
|
||||||
use builtin;
|
|
||||||
use super::wasm;
|
use super::wasm;
|
||||||
|
|
||||||
/// Evm errors.
|
/// Evm errors.
|
||||||
@ -77,12 +77,6 @@ impl From<Box<trie::TrieError>> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<builtin::Error> for Error {
|
|
||||||
fn from(err: builtin::Error) -> Self {
|
|
||||||
Error::BuiltIn(err.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<wasm::RuntimeError> for Error {
|
impl From<wasm::RuntimeError> for Error {
|
||||||
fn from(err: wasm::RuntimeError) -> Self {
|
fn from(err: wasm::RuntimeError) -> Self {
|
||||||
Error::Wasm(format!("Runtime error: {:?}", err))
|
Error::Wasm(format!("Runtime error: {:?}", err))
|
||||||
@ -109,7 +103,6 @@ impl fmt::Display for Error {
|
|||||||
/// A specialized version of Result over EVM errors.
|
/// A specialized version of Result over EVM errors.
|
||||||
pub type Result<T> = ::std::result::Result<T, Error>;
|
pub type Result<T> = ::std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
|
||||||
/// Return data buffer. Holds memory from a previous call and a slice into that memory.
|
/// Return data buffer. Holds memory from a previous call and a slice into that memory.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ReturnData {
|
pub struct ReturnData {
|
@ -17,9 +17,10 @@
|
|||||||
//! Interface for Evm externalities.
|
//! Interface for Evm externalities.
|
||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use evm::{self, Schedule, ReturnData};
|
use call_type::CallType;
|
||||||
use env_info::*;
|
use env_info::EnvInfo;
|
||||||
use types::executed::CallType;
|
use schedule::Schedule;
|
||||||
|
use evm::{self, ReturnData};
|
||||||
|
|
||||||
/// Result of externalities create function.
|
/// Result of externalities create function.
|
||||||
pub enum ContractCreateResult {
|
pub enum ContractCreateResult {
|
@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use super::u256_to_address;
|
use super::u256_to_address;
|
||||||
use evm::{self, CostType};
|
|
||||||
use evm::instructions::{self, Instruction, InstructionInfo};
|
use {evm, ext};
|
||||||
use evm::interpreter::stack::Stack;
|
use instructions::{self, Instruction, InstructionInfo};
|
||||||
use evm::schedule::Schedule;
|
use interpreter::stack::Stack;
|
||||||
|
use schedule::Schedule;
|
||||||
|
|
||||||
macro_rules! overflowing {
|
macro_rules! overflowing {
|
||||||
($x: expr) => {{
|
($x: expr) => {{
|
||||||
@ -30,26 +31,26 @@ macro_rules! overflowing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
||||||
enum Request<Cost: CostType> {
|
enum Request<Cost: ::evm::CostType> {
|
||||||
Gas(Cost),
|
Gas(Cost),
|
||||||
GasMem(Cost, Cost),
|
GasMem(Cost, Cost),
|
||||||
GasMemProvide(Cost, Cost, Option<U256>),
|
GasMemProvide(Cost, Cost, Option<U256>),
|
||||||
GasMemCopy(Cost, Cost, Cost)
|
GasMemCopy(Cost, Cost, Cost)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InstructionRequirements<Cost: CostType> {
|
pub struct InstructionRequirements<Cost> {
|
||||||
pub gas_cost: Cost,
|
pub gas_cost: Cost,
|
||||||
pub provide_gas: Option<Cost>,
|
pub provide_gas: Option<Cost>,
|
||||||
pub memory_total_gas: Cost,
|
pub memory_total_gas: Cost,
|
||||||
pub memory_required_size: usize,
|
pub memory_required_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Gasometer<Gas: CostType> {
|
pub struct Gasometer<Gas> {
|
||||||
pub current_gas: Gas,
|
pub current_gas: Gas,
|
||||||
pub current_mem_gas: Gas,
|
pub current_mem_gas: Gas,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Gas: CostType> Gasometer<Gas> {
|
impl<Gas: evm::CostType> Gasometer<Gas> {
|
||||||
|
|
||||||
pub fn new(current_gas: Gas) -> Self {
|
pub fn new(current_gas: Gas) -> Self {
|
||||||
Gasometer {
|
Gasometer {
|
||||||
@ -106,7 +107,7 @@ impl<Gas: CostType> Gasometer<Gas> {
|
|||||||
/// it will be the amount of gas that the current context provides to the child context.
|
/// it will be the amount of gas that the current context provides to the child context.
|
||||||
pub fn requirements(
|
pub fn requirements(
|
||||||
&mut self,
|
&mut self,
|
||||||
ext: &evm::Ext,
|
ext: &ext::Ext,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
info: &InstructionInfo,
|
info: &InstructionInfo,
|
||||||
stack: &Stack<U256>,
|
stack: &Stack<U256>,
|
||||||
@ -290,7 +291,7 @@ impl<Gas: CostType> Gasometer<Gas> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mem_gas_cost(&self, schedule: &evm::Schedule, current_mem_size: usize, mem_size: &Gas) -> evm::Result<(Gas, Gas, usize)> {
|
fn mem_gas_cost(&self, schedule: &Schedule, current_mem_size: usize, mem_size: &Gas) -> evm::Result<(Gas, Gas, usize)> {
|
||||||
let gas_for_mem = |mem_size: Gas| {
|
let gas_for_mem = |mem_size: Gas| {
|
||||||
let s = mem_size >> 5;
|
let s = mem_size >> 5;
|
||||||
// s * memory_gas + s * s / quad_coeff_div
|
// s * memory_gas + s * s / quad_coeff_div
|
||||||
@ -318,12 +319,12 @@ impl<Gas: CostType> Gasometer<Gas> {
|
|||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mem_needed_const<Gas: CostType>(mem: &U256, add: usize) -> evm::Result<Gas> {
|
fn mem_needed_const<Gas: evm::CostType>(mem: &U256, add: usize) -> evm::Result<Gas> {
|
||||||
Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add))))
|
Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add))))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mem_needed<Gas: CostType>(offset: &U256, size: &U256) -> evm::Result<Gas> {
|
fn mem_needed<Gas: evm::CostType>(offset: &U256, size: &U256) -> evm::Result<Gas> {
|
||||||
if size.is_zero() {
|
if size.is_zero() {
|
||||||
return Ok(Gas::from(0));
|
return Ok(Gas::from(0));
|
||||||
}
|
}
|
||||||
@ -332,7 +333,7 @@ fn mem_needed<Gas: CostType>(offset: &U256, size: &U256) -> evm::Result<Gas> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_gas_usize<Gas: CostType>(value: Gas, num: usize) -> (Gas, bool) {
|
fn add_gas_usize<Gas: evm::CostType>(value: Gas, num: usize) -> (Gas, bool) {
|
||||||
value.overflow_add(Gas::from(num))
|
value.overflow_add(Gas::from(num))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +341,7 @@ fn add_gas_usize<Gas: CostType>(value: Gas, num: usize) -> (Gas, bool) {
|
|||||||
fn test_mem_gas_cost() {
|
fn test_mem_gas_cost() {
|
||||||
// given
|
// given
|
||||||
let gasometer = Gasometer::<U256>::new(U256::zero());
|
let gasometer = Gasometer::<U256>::new(U256::zero());
|
||||||
let schedule = evm::Schedule::default();
|
let schedule = Schedule::default();
|
||||||
let current_mem_size = 5;
|
let current_mem_size = 5;
|
||||||
let mem_size = !U256::zero();
|
let mem_size = !U256::zero();
|
||||||
|
|
||||||
@ -357,7 +358,7 @@ fn test_mem_gas_cost() {
|
|||||||
fn test_calculate_mem_cost() {
|
fn test_calculate_mem_cost() {
|
||||||
// given
|
// given
|
||||||
let gasometer = Gasometer::<usize>::new(0);
|
let gasometer = Gasometer::<usize>::new(0);
|
||||||
let schedule = evm::Schedule::default();
|
let schedule = Schedule::default();
|
||||||
let current_mem_size = 0;
|
let current_mem_size = 0;
|
||||||
let mem_size = 5;
|
let mem_size = 5;
|
||||||
|
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use util::U256;
|
use util::U256;
|
||||||
use evm::ReturnData;
|
use {ReturnData};
|
||||||
|
|
||||||
const MAX_RETURN_WASTE_BYTES: usize = 16384;
|
const MAX_RETURN_WASTE_BYTES: usize = 16384;
|
||||||
|
|
@ -30,9 +30,10 @@ pub use self::shared_cache::SharedCache;
|
|||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use action_params::{ActionParams, ActionValue};
|
||||||
use types::executed::CallType;
|
use call_type::CallType;
|
||||||
use evm::instructions::{self, Instruction, InstructionInfo};
|
use instructions::{self, Instruction, InstructionInfo};
|
||||||
use evm::{self, MessageCallResult, ContractCreateResult, GasLeft, CostType, CreateContractAddress, ReturnData};
|
use evm::{self, GasLeft, CostType, ReturnData};
|
||||||
|
use ext::{self, MessageCallResult, ContractCreateResult, CreateContractAddress};
|
||||||
use bit_set::BitSet;
|
use bit_set::BitSet;
|
||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
@ -107,7 +108,7 @@ pub struct Interpreter<Cost: CostType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
|
impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
|
||||||
fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result<GasLeft> {
|
fn exec(&mut self, params: ActionParams, ext: &mut ext::Ext) -> evm::Result<GasLeft> {
|
||||||
self.mem.clear();
|
self.mem.clear();
|
||||||
|
|
||||||
let mut informant = informant::EvmInformant::new(ext.depth());
|
let mut informant = informant::EvmInformant::new(ext.depth());
|
||||||
@ -204,7 +205,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_instruction(&self, ext: &evm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack<U256>) -> evm::Result<()> {
|
fn verify_instruction(&self, ext: &ext::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack<U256>) -> evm::Result<()> {
|
||||||
let schedule = ext.schedule();
|
let schedule = ext.schedule();
|
||||||
|
|
||||||
if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) ||
|
if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) ||
|
||||||
@ -270,7 +271,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
gas: Cost,
|
gas: Cost,
|
||||||
params: &ActionParams,
|
params: &ActionParams,
|
||||||
ext: &mut evm::Ext,
|
ext: &mut ext::Ext,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
code: &mut CodeReader,
|
code: &mut CodeReader,
|
||||||
stack: &mut Stack<U256>,
|
stack: &mut Stack<U256>,
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use evm::instructions;
|
use instructions;
|
||||||
|
|
||||||
/// Stack trait with VM-friendly API
|
/// Stack trait with VM-friendly API
|
||||||
pub trait Stack<T> {
|
pub trait Stack<T> {
|
@ -18,7 +18,7 @@
|
|||||||
use util::*;
|
use util::*;
|
||||||
use evmjit;
|
use evmjit;
|
||||||
use evm::{self, GasLeft};
|
use evm::{self, GasLeft};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
|
|
||||||
/// Should be used to convert jit types to ethcore
|
/// Should be used to convert jit types to ethcore
|
||||||
trait FromJit<T>: Sized {
|
trait FromJit<T>: Sized {
|
@ -16,16 +16,41 @@
|
|||||||
|
|
||||||
//! Ethereum virtual machine.
|
//! Ethereum virtual machine.
|
||||||
|
|
||||||
|
extern crate byteorder;
|
||||||
|
extern crate bit_set;
|
||||||
|
extern crate common_types as types;
|
||||||
|
extern crate ethcore_util as util;
|
||||||
|
extern crate ethjson;
|
||||||
|
extern crate rlp;
|
||||||
|
extern crate parity_wasm;
|
||||||
|
extern crate wasm_utils;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
|
#[cfg(feature = "jit")]
|
||||||
|
extern crate evmjit;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
extern crate rustc_hex;
|
||||||
|
|
||||||
|
pub mod action_params;
|
||||||
|
pub mod call_type;
|
||||||
|
pub mod env_info;
|
||||||
pub mod ext;
|
pub mod ext;
|
||||||
pub mod evm;
|
pub mod evm;
|
||||||
pub mod interpreter;
|
pub mod interpreter;
|
||||||
#[macro_use]
|
|
||||||
pub mod factory;
|
|
||||||
pub mod schedule;
|
pub mod schedule;
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
pub mod factory;
|
||||||
mod vmtype;
|
mod vmtype;
|
||||||
mod instructions;
|
mod instructions;
|
||||||
|
|
||||||
#[cfg(feature = "jit" )]
|
#[cfg(feature = "jit" )]
|
||||||
mod jit;
|
mod jit;
|
||||||
|
|
||||||
@ -34,10 +59,12 @@ mod tests;
|
|||||||
#[cfg(all(feature="benches", test))]
|
#[cfg(all(feature="benches", test))]
|
||||||
mod benches;
|
mod benches;
|
||||||
|
|
||||||
|
pub use self::action_params::ActionParams;
|
||||||
|
pub use self::call_type::CallType;
|
||||||
|
pub use self::env_info::EnvInfo;
|
||||||
pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData};
|
pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData};
|
||||||
pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress};
|
pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress};
|
||||||
pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes};
|
pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes};
|
||||||
pub use self::vmtype::VMType;
|
pub use self::vmtype::VMType;
|
||||||
pub use self::factory::Factory;
|
pub use self::factory::Factory;
|
||||||
pub use self::schedule::{Schedule, CleanDustMode};
|
pub use self::schedule::{Schedule, CleanDustMode};
|
||||||
pub use types::executed::CallType;
|
|
@ -15,7 +15,6 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Cost schedule and other parameterisations for the EVM.
|
//! Cost schedule and other parameterisations for the EVM.
|
||||||
use spec::CommonParams;
|
|
||||||
|
|
||||||
/// Definition of the cost schedule and other parameterisations for the EVM.
|
/// Definition of the cost schedule and other parameterisations for the EVM.
|
||||||
pub struct Schedule {
|
pub struct Schedule {
|
||||||
@ -185,26 +184,6 @@ impl Schedule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedule for the post-EIP-150-era of the Ethereum main net.
|
|
||||||
pub fn from_params(block_number: u64, params: &CommonParams) -> Schedule {
|
|
||||||
let mut schedule = Schedule::new_post_eip150(usize::max_value(), true, true, true);
|
|
||||||
schedule.apply_params(block_number, params);
|
|
||||||
schedule
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Apply common spec config parameters to the schedule.
|
|
||||||
pub fn apply_params(&mut self, block_number: u64, params: &CommonParams) {
|
|
||||||
self.have_create2 = block_number >= params.eip86_transition;
|
|
||||||
self.have_revert = block_number >= params.eip140_transition;
|
|
||||||
self.have_static_call = block_number >= params.eip214_transition;
|
|
||||||
if block_number >= params.eip210_transition {
|
|
||||||
self.blockhash_gas = 350;
|
|
||||||
}
|
|
||||||
if block_number >= params.dust_protection_transition {
|
|
||||||
self.kill_dust = if params.remove_dust_contracts { CleanDustMode::WithCodeAndStorage } else { CleanDustMode::BasicOnly };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Schedule for the Metropolis of the Ethereum main net.
|
/// Schedule for the Metropolis of the Ethereum main net.
|
||||||
pub fn new_metropolis() -> Schedule {
|
pub fn new_metropolis() -> Schedule {
|
||||||
let mut schedule = Self::new_post_eip150(24576, true, true, true);
|
let mut schedule = Self::new_post_eip150(24576, true, true, true);
|
@ -19,13 +19,12 @@ use rustc_hex::FromHex;
|
|||||||
use util::*;
|
use util::*;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use action_params::{ActionParams, ActionValue};
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use types::executed::CallType;
|
use call_type::CallType;
|
||||||
use evm::{self, Ext, Schedule, Factory, GasLeft, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData};
|
use schedule::Schedule;
|
||||||
use tests::helpers::*;
|
use evm::{self, GasLeft, ReturnData};
|
||||||
use types::transaction::SYSTEM_ADDRESS;
|
use ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress};
|
||||||
use executive::Executive;
|
use factory::Factory;
|
||||||
use state::Substate;
|
use vmtype::VMType;
|
||||||
use trace::{NoopVMTracer, NoopTracer};
|
|
||||||
|
|
||||||
pub struct FakeLogEntry {
|
pub struct FakeLogEntry {
|
||||||
topics: Vec<H256>,
|
topics: Vec<H256>,
|
||||||
@ -438,67 +437,6 @@ fn test_blockhash(factory: super::Factory) {
|
|||||||
assert_eq!(ext.store.get(&H256::new()).unwrap(), &blockhash);
|
assert_eq!(ext.store.get(&H256::new()).unwrap(), &blockhash);
|
||||||
}
|
}
|
||||||
|
|
||||||
evm_test!{test_blockhash_eip210: test_blockhash_eip210_jit, test_blockhash_eip210_int}
|
|
||||||
fn test_blockhash_eip210(factory: super::Factory) {
|
|
||||||
let get_prev_hash_code = Arc::new("600143034060205260206020f3".from_hex().unwrap()); // this returns previous block hash
|
|
||||||
let get_prev_hash_code_hash = get_prev_hash_code.sha3();
|
|
||||||
// This is same as DEFAULT_BLOCKHASH_CONTRACT except for metropolis transition block check removed.
|
|
||||||
let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b";
|
|
||||||
let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap());
|
|
||||||
let blockhash_contract_code_hash = blockhash_contract_code.sha3();
|
|
||||||
let engine = TestEngine::new_metropolis();
|
|
||||||
let mut env_info = EnvInfo::default();
|
|
||||||
|
|
||||||
// populate state with 256 last hashes
|
|
||||||
let mut state = get_temp_state_with_factory(factory);
|
|
||||||
let contract_address: Address = 0xf0.into();
|
|
||||||
state.init_code(&contract_address, (*blockhash_contract_code).clone()).unwrap();
|
|
||||||
for i in 1 .. 257 {
|
|
||||||
env_info.number = i.into();
|
|
||||||
let params = ActionParams {
|
|
||||||
code_address: contract_address.clone(),
|
|
||||||
address: contract_address,
|
|
||||||
sender: SYSTEM_ADDRESS.clone(),
|
|
||||||
origin: SYSTEM_ADDRESS.clone(),
|
|
||||||
gas: 100000.into(),
|
|
||||||
gas_price: 0.into(),
|
|
||||||
value: ActionValue::Transfer(0.into()),
|
|
||||||
code: Some(blockhash_contract_code.clone()),
|
|
||||||
code_hash: Some(blockhash_contract_code_hash),
|
|
||||||
data: Some(H256::from(i - 1).to_vec()),
|
|
||||||
call_type: CallType::Call,
|
|
||||||
};
|
|
||||||
let mut ex = Executive::new(&mut state, &env_info, &engine);
|
|
||||||
let mut substate = Substate::new();
|
|
||||||
let mut output = [];
|
|
||||||
if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) {
|
|
||||||
panic!("Encountered error on updating last hashes: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
env_info.number = 256;
|
|
||||||
let params = ActionParams {
|
|
||||||
code_address: Address::new(),
|
|
||||||
address: Address::new(),
|
|
||||||
sender: Address::new(),
|
|
||||||
origin: Address::new(),
|
|
||||||
gas: 100000.into(),
|
|
||||||
gas_price: 0.into(),
|
|
||||||
value: ActionValue::Transfer(0.into()),
|
|
||||||
code: Some(get_prev_hash_code),
|
|
||||||
code_hash: Some(get_prev_hash_code_hash),
|
|
||||||
data: None,
|
|
||||||
call_type: CallType::Call,
|
|
||||||
};
|
|
||||||
let mut ex = Executive::new(&mut state, &env_info, &engine);
|
|
||||||
let mut substate = Substate::new();
|
|
||||||
let mut output = H256::new();
|
|
||||||
if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) {
|
|
||||||
panic!("Encountered error on getting last hash: {}", e);
|
|
||||||
}
|
|
||||||
assert_eq!(output, 255.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
evm_test!{test_calldataload: test_calldataload_jit, test_calldataload_int}
|
evm_test!{test_calldataload: test_calldataload_jit, test_calldataload_int}
|
||||||
fn test_calldataload(factory: super::Factory) {
|
fn test_calldataload(factory: super::Factory) {
|
||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
@ -58,7 +58,7 @@ impl WasmInterpreter {
|
|||||||
|
|
||||||
impl evm::Evm for WasmInterpreter {
|
impl evm::Evm for WasmInterpreter {
|
||||||
|
|
||||||
fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result<GasLeft> {
|
fn exec(&mut self, params: ActionParams, ext: &mut ::ext::Ext) -> evm::Result<GasLeft> {
|
||||||
use parity_wasm::elements::Deserialize;
|
use parity_wasm::elements::Deserialize;
|
||||||
|
|
||||||
let code = params.code.expect("exec is only called on contract with code; qed");
|
let code = params.code.expect("exec is only called on contract with code; qed");
|
||||||
@ -76,7 +76,7 @@ impl evm::Evm for WasmInterpreter {
|
|||||||
if params.gas > ::std::u64::MAX.into() {
|
if params.gas > ::std::u64::MAX.into() {
|
||||||
return Err(evm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned()));
|
return Err(evm::Error::Wasm("Wasm interpreter cannot run contracts with gas >= 2^64".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut runtime = Runtime::with_params(
|
let mut runtime = Runtime::with_params(
|
||||||
ext,
|
ext,
|
||||||
env_memory,
|
env_memory,
|
||||||
@ -106,7 +106,7 @@ impl evm::Evm for WasmInterpreter {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let execution_params = interpreter::ExecutionParams::with_external(
|
let execution_params = interpreter::ExecutionParams::with_external(
|
||||||
"env".into(),
|
"env".into(),
|
||||||
Arc::new(
|
Arc::new(
|
||||||
interpreter::env_native_module(env_instance, native_bindings(&mut runtime))
|
interpreter::env_native_module(env_instance, native_bindings(&mut runtime))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@ -115,7 +115,7 @@ impl evm::Evm for WasmInterpreter {
|
|||||||
})?
|
})?
|
||||||
)
|
)
|
||||||
).add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32));
|
).add_argument(interpreter::RuntimeValue::I32(d_ptr.as_raw() as i32));
|
||||||
|
|
||||||
let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals))
|
let module_instance = self.program.add_module("contract", contract_module, Some(&execution_params.externals))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
trace!(target: "wasm", "Error adding contract module: {:?}", err);
|
trace!(target: "wasm", "Error adding contract module: {:?}", err);
|
||||||
@ -138,11 +138,11 @@ impl evm::Evm for WasmInterpreter {
|
|||||||
// todo: use memory views to avoid copy
|
// todo: use memory views to avoid copy
|
||||||
self.result.extend(result.pop(&*runtime.memory())?);
|
self.result.extend(result.pop(&*runtime.memory())?);
|
||||||
let len = self.result.len();
|
let len = self.result.len();
|
||||||
Ok(GasLeft::NeedsReturn {
|
Ok(GasLeft::NeedsReturn {
|
||||||
gas_left: runtime.gas_left()?.into(),
|
gas_left: runtime.gas_left()?.into(),
|
||||||
data: ReturnData::new(
|
data: ReturnData::new(
|
||||||
::std::mem::replace(&mut self.result, Vec::with_capacity(DEFAULT_RESULT_BUFFER)),
|
::std::mem::replace(&mut self.result, Vec::with_capacity(DEFAULT_RESULT_BUFFER)),
|
||||||
0,
|
0,
|
||||||
len,
|
len,
|
||||||
),
|
),
|
||||||
apply_state: true,
|
apply_state: true,
|
||||||
@ -156,4 +156,4 @@ fn native_bindings<'a>(runtime: &'a mut Runtime) -> interpreter::UserFunctions<'
|
|||||||
executor: runtime,
|
executor: runtime,
|
||||||
functions: ::std::borrow::Cow::from(env::SIGNATURES),
|
functions: ::std::borrow::Cow::from(env::SIGNATURES),
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use byteorder::{LittleEndian, ByteOrder};
|
use byteorder::{LittleEndian, ByteOrder};
|
||||||
|
|
||||||
use evm;
|
use ext;
|
||||||
|
|
||||||
use parity_wasm::interpreter;
|
use parity_wasm::interpreter;
|
||||||
use util::{Address, H256, U256};
|
use util::{Address, H256, U256};
|
||||||
@ -62,16 +62,16 @@ pub struct Runtime<'a> {
|
|||||||
gas_counter: u64,
|
gas_counter: u64,
|
||||||
gas_limit: u64,
|
gas_limit: u64,
|
||||||
dynamic_top: u32,
|
dynamic_top: u32,
|
||||||
ext: &'a mut evm::Ext,
|
ext: &'a mut ext::Ext,
|
||||||
memory: Arc<interpreter::MemoryInstance>,
|
memory: Arc<interpreter::MemoryInstance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Runtime<'a> {
|
impl<'a> Runtime<'a> {
|
||||||
/// New runtime for wasm contract with specified params
|
/// New runtime for wasm contract with specified params
|
||||||
pub fn with_params<'b>(
|
pub fn with_params<'b>(
|
||||||
ext: &'b mut evm::Ext,
|
ext: &'b mut ext::Ext,
|
||||||
memory: Arc<interpreter::MemoryInstance>,
|
memory: Arc<interpreter::MemoryInstance>,
|
||||||
stack_space: u32,
|
stack_space: u32,
|
||||||
gas_limit: u64,
|
gas_limit: u64,
|
||||||
) -> Runtime<'b> {
|
) -> Runtime<'b> {
|
||||||
Runtime {
|
Runtime {
|
||||||
@ -84,7 +84,7 @@ impl<'a> Runtime<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write to the storage from wasm memory
|
/// Write to the storage from wasm memory
|
||||||
pub fn storage_write(&mut self, context: interpreter::CallerContext)
|
pub fn storage_write(&mut self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
let mut context = context;
|
let mut context = context;
|
||||||
@ -99,12 +99,12 @@ impl<'a> Runtime<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read from the storage to wasm memory
|
/// Read from the storage to wasm memory
|
||||||
pub fn storage_read(&mut self, context: interpreter::CallerContext)
|
pub fn storage_read(&mut self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
let mut context = context;
|
let mut context = context;
|
||||||
let val_ptr = context.value_stack.pop_as::<i32>()?;
|
let val_ptr = context.value_stack.pop_as::<i32>()?;
|
||||||
let key = self.pop_h256(&mut context)?;
|
let key = self.pop_h256(&mut context)?;
|
||||||
|
|
||||||
let val = self.ext.storage_at(&key)
|
let val = self.ext.storage_at(&key)
|
||||||
.map_err(|_| interpreter::Error::Trap("Storage read error".to_owned()))?;
|
.map_err(|_| interpreter::Error::Trap("Storage read error".to_owned()))?;
|
||||||
@ -115,11 +115,11 @@ impl<'a> Runtime<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pass suicide to state runtime
|
/// Pass suicide to state runtime
|
||||||
pub fn suicide(&mut self, context: interpreter::CallerContext)
|
pub fn suicide(&mut self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
let mut context = context;
|
let mut context = context;
|
||||||
let refund_address = self.pop_address(&mut context)?;
|
let refund_address = self.pop_address(&mut context)?;
|
||||||
|
|
||||||
self.ext.suicide(&refund_address)
|
self.ext.suicide(&refund_address)
|
||||||
.map_err(|_| interpreter::Error::Trap("Suicide error".to_owned()))?;
|
.map_err(|_| interpreter::Error::Trap("Suicide error".to_owned()))?;
|
||||||
@ -128,7 +128,7 @@ impl<'a> Runtime<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Invoke create in the state runtime
|
/// Invoke create in the state runtime
|
||||||
pub fn create(&mut self, context: interpreter::CallerContext)
|
pub fn create(&mut self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -139,11 +139,11 @@ impl<'a> Runtime<'a> {
|
|||||||
trace!(target: "wasm", "runtime: create contract");
|
trace!(target: "wasm", "runtime: create contract");
|
||||||
let mut context = context;
|
let mut context = context;
|
||||||
let result_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
let result_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
trace!(target: "wasm", " result_ptr: {:?}", result_ptr);
|
trace!(target: "wasm", " result_ptr: {:?}", result_ptr);
|
||||||
let code_len = context.value_stack.pop_as::<i32>()? as u32;
|
let code_len = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
trace!(target: "wasm", " code_len: {:?}", code_len);
|
trace!(target: "wasm", " code_len: {:?}", code_len);
|
||||||
let code_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
let code_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
trace!(target: "wasm", " code_ptr: {:?}", code_ptr);
|
trace!(target: "wasm", " code_ptr: {:?}", code_ptr);
|
||||||
let endowment = self.pop_u256(&mut context)?;
|
let endowment = self.pop_u256(&mut context)?;
|
||||||
trace!(target: "wasm", " val: {:?}", endowment);
|
trace!(target: "wasm", " val: {:?}", endowment);
|
||||||
|
|
||||||
@ -152,15 +152,15 @@ impl<'a> Runtime<'a> {
|
|||||||
let gas_left = self.gas_left()
|
let gas_left = self.gas_left()
|
||||||
.map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))?
|
.map_err(|_| interpreter::Error::Trap("Gas state error".to_owned()))?
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
match self.ext.create(&gas_left, &endowment, &code, evm::CreateContractAddress::FromSenderAndCodeHash) {
|
match self.ext.create(&gas_left, &endowment, &code, ext::CreateContractAddress::FromSenderAndCodeHash) {
|
||||||
evm::ContractCreateResult::Created(address, gas_left) => {
|
ext::ContractCreateResult::Created(address, gas_left) => {
|
||||||
self.memory.set(result_ptr, &*address)?;
|
self.memory.set(result_ptr, &*address)?;
|
||||||
self.gas_counter = self.gas_limit - gas_left.low_u64();
|
self.gas_counter = self.gas_limit - gas_left.low_u64();
|
||||||
trace!(target: "wasm", "runtime: create contract success (@{:?})", address);
|
trace!(target: "wasm", "runtime: create contract success (@{:?})", address);
|
||||||
Ok(Some(0i32.into()))
|
Ok(Some(0i32.into()))
|
||||||
},
|
},
|
||||||
evm::ContractCreateResult::Failed => {
|
ext::ContractCreateResult::Failed => {
|
||||||
trace!(target: "wasm", "runtime: create contract fail");
|
trace!(target: "wasm", "runtime: create contract fail");
|
||||||
Ok(Some((-1i32).into()))
|
Ok(Some((-1i32).into()))
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ impl<'a> Runtime<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate memory using the wasm stack params
|
/// Allocate memory using the wasm stack params
|
||||||
pub fn malloc(&mut self, context: interpreter::CallerContext)
|
pub fn malloc(&mut self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
let amount = context.value_stack.pop_as::<i32>()? as u32;
|
let amount = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
@ -185,14 +185,14 @@ impl<'a> Runtime<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Report gas cost with the params passed in wasm stack
|
/// Report gas cost with the params passed in wasm stack
|
||||||
fn gas(&mut self, context: interpreter::CallerContext)
|
fn gas(&mut self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
let amount = context.value_stack.pop_as::<i32>()? as u64;
|
let amount = context.value_stack.pop_as::<i32>()? as u64;
|
||||||
if self.charge_gas(amount) {
|
if self.charge_gas(amount) {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit)))
|
Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,13 +204,13 @@ impl<'a> Runtime<'a> {
|
|||||||
} else {
|
} else {
|
||||||
self.gas_counter = prev + amount;
|
self.gas_counter = prev + amount;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn h256_at(&self, ptr: WasmPtr) -> Result<H256, interpreter::Error> {
|
fn h256_at(&self, ptr: WasmPtr) -> Result<H256, interpreter::Error> {
|
||||||
Ok(H256::from_slice(&ptr.slice(32, &*self.memory)
|
Ok(H256::from_slice(&ptr.slice(32, &*self.memory)
|
||||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?
|
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_h256(&self, context: &mut interpreter::CallerContext) -> Result<H256, interpreter::Error> {
|
fn pop_h256(&self, context: &mut interpreter::CallerContext) -> Result<H256, interpreter::Error> {
|
||||||
@ -228,7 +228,7 @@ impl<'a> Runtime<'a> {
|
|||||||
fn address_at(&self, ptr: WasmPtr) -> Result<Address, interpreter::Error> {
|
fn address_at(&self, ptr: WasmPtr) -> Result<Address, interpreter::Error> {
|
||||||
Ok(Address::from_slice(&ptr.slice(20, &*self.memory)
|
Ok(Address::from_slice(&ptr.slice(20, &*self.memory)
|
||||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?
|
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_address(&self, context: &mut interpreter::CallerContext) -> Result<Address, interpreter::Error> {
|
fn pop_address(&self, context: &mut interpreter::CallerContext) -> Result<Address, interpreter::Error> {
|
||||||
@ -237,13 +237,13 @@ impl<'a> Runtime<'a> {
|
|||||||
self.address_at(ptr)
|
self.address_at(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn user_trap(&mut self, _context: interpreter::CallerContext)
|
fn user_trap(&mut self, _context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
Err(interpreter::Error::Trap("unknown trap".to_owned()))
|
Err(interpreter::Error::Trap("unknown trap".to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn user_noop(&mut self,
|
fn user_noop(&mut self,
|
||||||
_context: interpreter::CallerContext
|
_context: interpreter::CallerContext
|
||||||
) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
|
) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@ -270,16 +270,16 @@ impl<'a> Runtime<'a> {
|
|||||||
self.memory.set(args_ptr+40, &call_args.origin)?;
|
self.memory.set(args_ptr+40, &call_args.origin)?;
|
||||||
self.memory.set(args_ptr+60, &call_args.value)?;
|
self.memory.set(args_ptr+60, &call_args.value)?;
|
||||||
self.memory.set(args_ptr+92, &call_args.data)?;
|
self.memory.set(args_ptr+92, &call_args.data)?;
|
||||||
|
|
||||||
Ok(d_ptr.into())
|
Ok(d_ptr.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_log(&mut self, context: interpreter::CallerContext)
|
fn debug_log(&mut self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
let msg_len = context.value_stack.pop_as::<i32>()? as u32;
|
let msg_len = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
let msg_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
let msg_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
|
|
||||||
let msg = String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
|
let msg = String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
|
||||||
.map_err(|_| interpreter::Error::Trap("Debug log utf-8 decoding error".to_owned()))?;
|
.map_err(|_| interpreter::Error::Trap("Debug log utf-8 decoding error".to_owned()))?;
|
||||||
|
|
||||||
@ -299,8 +299,8 @@ impl<'a> Runtime<'a> {
|
|||||||
&*self.memory
|
&*self.memory
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mem_copy(&self, context: interpreter::CallerContext)
|
fn mem_copy(&self, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
let len = context.value_stack.pop_as::<i32>()? as u32;
|
let len = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||||
@ -314,7 +314,7 @@ impl<'a> Runtime<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> {
|
impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> {
|
||||||
fn execute(&mut self, name: &str, context: interpreter::CallerContext)
|
fn execute(&mut self, name: &str, context: interpreter::CallerContext)
|
||||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||||
{
|
{
|
||||||
match name {
|
match name {
|
||||||
@ -353,4 +353,4 @@ impl<'a> interpreter::UserFunctionExecutor for Runtime<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,22 +1,31 @@
|
|||||||
use std::path::PathBuf;
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
use std::fs::File;
|
// This file is part of Parity.
|
||||||
use std::io::Read;
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethcore_logger::init_log;
|
|
||||||
use super::super::tests::{FakeExt, FakeCall, FakeCallType};
|
use super::super::tests::{FakeExt, FakeCall, FakeCallType};
|
||||||
use super::WasmInterpreter;
|
use super::WasmInterpreter;
|
||||||
use evm::{self, Evm, GasLeft};
|
use evm::{self, Evm, GasLeft};
|
||||||
use action_params::{ActionParams, ActionValue};
|
use action_params::{ActionParams, ActionValue};
|
||||||
use util::{U256, H256, Address};
|
use util::{U256, H256, Address};
|
||||||
|
|
||||||
fn load_sample(name: &str) -> Vec<u8> {
|
macro_rules! load_sample {
|
||||||
let mut path = PathBuf::from("./res/wasm-tests/compiled");
|
($name: expr) => {
|
||||||
path.push(name);
|
include_bytes!(concat!("../../../res/wasm-tests/compiled/", $name)).to_vec()
|
||||||
let mut file = File::open(path).expect(&format!("File {} for test to exist", name));
|
}
|
||||||
let mut data = vec![];
|
|
||||||
file.read_to_end(&mut data).expect(&format!("Test {} to load ok", name));
|
|
||||||
data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> {
|
fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> {
|
||||||
@ -34,9 +43,7 @@ fn wasm_interpreter() -> WasmInterpreter {
|
|||||||
/// Empty contract does almost nothing except producing 1 (one) local node debug log message
|
/// Empty contract does almost nothing except producing 1 (one) local node debug log message
|
||||||
#[test]
|
#[test]
|
||||||
fn empty() {
|
fn empty() {
|
||||||
init_log();
|
let code = load_sample!("empty.wasm");
|
||||||
|
|
||||||
let code = load_sample("empty.wasm");
|
|
||||||
let address: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
|
let address: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
@ -58,9 +65,7 @@ fn empty() {
|
|||||||
// logger.wasm writes all these provided fixed header fields to some arbitrary storage keys.
|
// logger.wasm writes all these provided fixed header fields to some arbitrary storage keys.
|
||||||
#[test]
|
#[test]
|
||||||
fn logger() {
|
fn logger() {
|
||||||
init_log();
|
let code = load_sample!("logger.wasm");
|
||||||
|
|
||||||
let code = load_sample("logger.wasm");
|
|
||||||
let address: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
|
let address: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
|
||||||
let sender: Address = "0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d".parse().unwrap();
|
let sender: Address = "0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d".parse().unwrap();
|
||||||
let origin: Address = "0102030405060708090a0b0c0d0e0f1011121314".parse().unwrap();
|
let origin: Address = "0102030405060708090a0b0c0d0e0f1011121314".parse().unwrap();
|
||||||
@ -113,9 +118,7 @@ fn logger() {
|
|||||||
// if it has any result.
|
// if it has any result.
|
||||||
#[test]
|
#[test]
|
||||||
fn identity() {
|
fn identity() {
|
||||||
init_log();
|
let code = load_sample!("identity.wasm");
|
||||||
|
|
||||||
let code = load_sample("identity.wasm");
|
|
||||||
let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
|
let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
@ -143,14 +146,12 @@ fn identity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dispersion test sends byte array and expect the contract to 'disperse' the original elements with
|
// Dispersion test sends byte array and expect the contract to 'disperse' the original elements with
|
||||||
// their modulo 19 dopant.
|
// their modulo 19 dopant.
|
||||||
// The result is always twice as long as the input.
|
// The result is always twice as long as the input.
|
||||||
// This also tests byte-perfect memory allocation and in/out ptr lifecycle.
|
// This also tests byte-perfect memory allocation and in/out ptr lifecycle.
|
||||||
#[test]
|
#[test]
|
||||||
fn dispersion() {
|
fn dispersion() {
|
||||||
init_log();
|
let code = load_sample!("dispersion.wasm");
|
||||||
|
|
||||||
let code = load_sample("dispersion.wasm");
|
|
||||||
|
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
@ -179,9 +180,7 @@ fn dispersion() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn suicide_not() {
|
fn suicide_not() {
|
||||||
init_log();
|
let code = load_sample!("suicidal.wasm");
|
||||||
|
|
||||||
let code = load_sample("suicidal.wasm");
|
|
||||||
|
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
@ -205,14 +204,12 @@ fn suicide_not() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
result,
|
result,
|
||||||
vec![0u8]
|
vec![0u8]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn suicide() {
|
fn suicide() {
|
||||||
init_log();
|
let code = load_sample!("suicidal.wasm");
|
||||||
|
|
||||||
let code = load_sample("suicidal.wasm");
|
|
||||||
|
|
||||||
let refund: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
|
let refund: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
@ -242,11 +239,9 @@ fn suicide() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create() {
|
fn create() {
|
||||||
init_log();
|
|
||||||
|
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(Arc::new(load_sample("creator.wasm")));
|
params.code = Some(Arc::new(load_sample!("creator.wasm")));
|
||||||
params.data = Some(vec![0u8, 2, 4, 8, 16, 32, 64, 128]);
|
params.data = Some(vec![0u8, 2, 4, 8, 16, 32, 64, 128]);
|
||||||
params.value = ActionValue::transfer(1_000_000_000);
|
params.value = ActionValue::transfer(1_000_000_000);
|
||||||
|
|
||||||
@ -276,4 +271,4 @@ fn create() {
|
|||||||
}
|
}
|
||||||
));
|
));
|
||||||
assert_eq!(gas_left, U256::from(99_768));
|
assert_eq!(gas_left, U256::from(99_768));
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ description = "Parity Light Client Implementation"
|
|||||||
homepage = "http://parity.io"
|
homepage = "http://parity.io"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
name = "ethcore-light"
|
name = "ethcore-light"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ ethcore-network = { path = "../../util/network" }
|
|||||||
ethcore-io = { path = "../../util/io" }
|
ethcore-io = { path = "../../util/io" }
|
||||||
ethcore-ipc = { path = "../../ipc/rpc", optional = true }
|
ethcore-ipc = { path = "../../ipc/rpc", optional = true }
|
||||||
ethcore-devtools = { path = "../../devtools" }
|
ethcore-devtools = { path = "../../devtools" }
|
||||||
|
evm = { path = "../evm" }
|
||||||
rlp = { path = "../../util/rlp" }
|
rlp = { path = "../../util/rlp" }
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
smallvec = "0.4"
|
smallvec = "0.4"
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
|
|
||||||
use std::sync::{Weak, Arc};
|
use std::sync::{Weak, Arc};
|
||||||
|
|
||||||
use ethcore::block_import_error::BlockImportError;
|
|
||||||
use ethcore::block_status::BlockStatus;
|
use ethcore::block_status::BlockStatus;
|
||||||
use ethcore::client::{ClientReport, EnvInfo};
|
use ethcore::client::{ClientReport, EnvInfo};
|
||||||
use ethcore::engines::Engine;
|
use ethcore::engines::Engine;
|
||||||
|
use ethcore::error::BlockImportError;
|
||||||
use ethcore::ids::BlockId;
|
use ethcore::ids::BlockId;
|
||||||
use ethcore::header::Header;
|
use ethcore::header::Header;
|
||||||
use ethcore::verification::queue::{self, HeaderQueue};
|
use ethcore::verification::queue::{self, HeaderQueue};
|
||||||
|
@ -71,6 +71,7 @@ extern crate ethcore_io as io;
|
|||||||
extern crate ethcore_network as network;
|
extern crate ethcore_network as network;
|
||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
|
extern crate evm;
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate itertools;
|
extern crate itertools;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
@ -21,10 +21,10 @@ use std::sync::Arc;
|
|||||||
use ethcore::basic_account::BasicAccount;
|
use ethcore::basic_account::BasicAccount;
|
||||||
use ethcore::encoded;
|
use ethcore::encoded;
|
||||||
use ethcore::engines::Engine;
|
use ethcore::engines::Engine;
|
||||||
use ethcore::env_info::EnvInfo;
|
|
||||||
use ethcore::receipt::Receipt;
|
use ethcore::receipt::Receipt;
|
||||||
use ethcore::state::{self, ProvedExecution};
|
use ethcore::state::{self, ProvedExecution};
|
||||||
use ethcore::transaction::SignedTransaction;
|
use ethcore::transaction::SignedTransaction;
|
||||||
|
use evm::env_info::EnvInfo;
|
||||||
|
|
||||||
use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field};
|
use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field};
|
||||||
|
|
||||||
|
@ -26,9 +26,8 @@
|
|||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use ethcore::error::TransactionError;
|
use ethcore::error::{TransactionError, TransactionImportResult};
|
||||||
use ethcore::transaction::{Condition, PendingTransaction, SignedTransaction};
|
use ethcore::transaction::{Condition, PendingTransaction, SignedTransaction};
|
||||||
use ethcore::transaction_import::TransactionImportResult;
|
|
||||||
use util::{Address, U256, H256, H256FastMap};
|
use util::{Address, U256, H256, H256FastMap};
|
||||||
|
|
||||||
// Knowledge of an account's current nonce.
|
// Knowledge of an account's current nonce.
|
||||||
|
@ -64,7 +64,9 @@ pub enum SignError {
|
|||||||
/// Low-level hardware device error.
|
/// Low-level hardware device error.
|
||||||
Hardware(HardwareError),
|
Hardware(HardwareError),
|
||||||
/// Low-level error from store
|
/// Low-level error from store
|
||||||
SStore(SSError)
|
SStore(SSError),
|
||||||
|
/// Inappropriate chain
|
||||||
|
InappropriateChain,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for SignError {
|
impl fmt::Display for SignError {
|
||||||
@ -74,6 +76,7 @@ impl fmt::Display for SignError {
|
|||||||
SignError::NotFound => write!(f, "Account does not exist"),
|
SignError::NotFound => write!(f, "Account does not exist"),
|
||||||
SignError::Hardware(ref e) => write!(f, "{}", e),
|
SignError::Hardware(ref e) => write!(f, "{}", e),
|
||||||
SignError::SStore(ref e) => write!(f, "{}", e),
|
SignError::SStore(ref e) => write!(f, "{}", e),
|
||||||
|
SignError::InappropriateChain => write!(f, "Inappropriate chain"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,11 @@
|
|||||||
|
|
||||||
//! Ethcore basic typenames.
|
//! Ethcore basic typenames.
|
||||||
|
|
||||||
use util::hash::H2048;
|
|
||||||
|
|
||||||
/// Type for a 2048-bit log-bloom, as used by our blocks.
|
/// Type for a 2048-bit log-bloom, as used by our blocks.
|
||||||
pub type LogBloom = H2048;
|
pub type LogBloom = ::log_entry::LogBloom;
|
||||||
|
|
||||||
/// Constant 2048-bit datum for 0. Often used as a default.
|
/// Constant 2048-bit datum for 0. Often used as a default.
|
||||||
pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]);
|
pub static ZERO_LOGBLOOM: LogBloom = ::util::hash::H2048([0x00; 256]);
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
||||||
/// Semantic boolean for when a seal/signature is included.
|
/// Semantic boolean for when a seal/signature is included.
|
||||||
|
@ -25,7 +25,7 @@ use util::{Bytes, Address, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RL
|
|||||||
use util::error::{Mismatch, OutOfBounds};
|
use util::error::{Mismatch, OutOfBounds};
|
||||||
|
|
||||||
use basic_types::{LogBloom, Seal};
|
use basic_types::{LogBloom, Seal};
|
||||||
use env_info::{EnvInfo, LastHashes};
|
use evm::env_info::{EnvInfo, LastHashes};
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use error::{Error, BlockError, TransactionError};
|
use error::{Error, BlockError, TransactionError};
|
||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
@ -200,7 +200,7 @@ pub trait IsBlock {
|
|||||||
|
|
||||||
/// Trait for a object that has a state database.
|
/// Trait for a object that has a state database.
|
||||||
pub trait Drain {
|
pub trait Drain {
|
||||||
/// Drop this object and return the underlieing database.
|
/// Drop this object and return the underlying database.
|
||||||
fn drain(self) -> StateDB;
|
fn drain(self) -> StateDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +370,22 @@ impl<'x> OpenBlock<'x> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Push transactions onto the block.
|
||||||
|
pub fn push_transactions(&mut self, transactions: &[SignedTransaction]) -> Result<(), Error> {
|
||||||
|
push_transactions(self, transactions)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Populate self from a header.
|
||||||
|
pub fn populate_from(&mut self, header: &Header) {
|
||||||
|
self.set_difficulty(*header.difficulty());
|
||||||
|
self.set_gas_limit(*header.gas_limit());
|
||||||
|
self.set_timestamp(header.timestamp());
|
||||||
|
self.set_author(header.author().clone());
|
||||||
|
self.set_extra_data(header.extra_data().clone()).unwrap_or_else(|e| warn!("Couldn't set extradata: {}. Ignoring.", e));
|
||||||
|
self.set_uncles_hash(header.uncles_hash().clone());
|
||||||
|
self.set_transactions_root(header.transactions_root().clone());
|
||||||
|
}
|
||||||
|
|
||||||
/// Turn this into a `ClosedBlock`.
|
/// Turn this into a `ClosedBlock`.
|
||||||
pub fn close(self) -> ClosedBlock {
|
pub fn close(self) -> ClosedBlock {
|
||||||
let mut s = self;
|
let mut s = self;
|
||||||
@ -579,18 +595,13 @@ pub fn enact(
|
|||||||
is_epoch_begin,
|
is_epoch_begin,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
b.set_difficulty(*header.difficulty());
|
b.populate_from(header);
|
||||||
b.set_gas_limit(*header.gas_limit());
|
b.push_transactions(transactions)?;
|
||||||
b.set_timestamp(header.timestamp());
|
|
||||||
b.set_author(header.author().clone());
|
|
||||||
b.set_extra_data(header.extra_data().clone()).unwrap_or_else(|e| warn!("Couldn't set extradata: {}. Ignoring.", e));
|
|
||||||
b.set_uncles_hash(header.uncles_hash().clone());
|
|
||||||
b.set_transactions_root(header.transactions_root().clone());
|
|
||||||
|
|
||||||
push_transactions(&mut b, transactions)?;
|
|
||||||
for u in uncles {
|
for u in uncles {
|
||||||
b.push_uncle(u.clone())?;
|
b.push_uncle(u.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(b.close_and_lock())
|
Ok(b.close_and_lock())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +667,7 @@ mod tests {
|
|||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use env_info::LastHashes;
|
use evm::env_info::LastHashes;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use header::Header;
|
use header::Header;
|
||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
@ -681,7 +692,36 @@ mod tests {
|
|||||||
let header = block.header();
|
let header = block.header();
|
||||||
let transactions: Result<Vec<_>, Error> = block.transactions().into_iter().map(SignedTransaction::new).collect();
|
let transactions: Result<Vec<_>, Error> = block.transactions().into_iter().map(SignedTransaction::new).collect();
|
||||||
let transactions = transactions?;
|
let transactions = transactions?;
|
||||||
enact(&header, &transactions, &block.uncles(), engine, tracing, db, parent, last_hashes, factories, false)
|
|
||||||
|
{
|
||||||
|
if ::log::max_log_level() >= ::log::LogLevel::Trace {
|
||||||
|
let s = State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(parent.number() + 1), factories.clone())?;
|
||||||
|
trace!(target: "enact", "num={}, root={}, author={}, author_balance={}\n",
|
||||||
|
header.number(), s.root(), header.author(), s.balance(&header.author())?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut b = OpenBlock::new(
|
||||||
|
engine,
|
||||||
|
factories,
|
||||||
|
tracing,
|
||||||
|
db,
|
||||||
|
parent,
|
||||||
|
last_hashes,
|
||||||
|
Address::new(),
|
||||||
|
(3141562.into(), 31415620.into()),
|
||||||
|
vec![],
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
b.populate_from(&header);
|
||||||
|
b.push_transactions(&transactions)?;
|
||||||
|
|
||||||
|
for u in &block.uncles() {
|
||||||
|
b.push_uncle(u.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(b.close_and_lock())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
||||||
|
@ -36,6 +36,12 @@ impl From<&'static str> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<::evm::Error> for Error {
|
||||||
|
fn into(self) -> ::evm::Error {
|
||||||
|
::evm::Error::BuiltIn(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Native implementation of a built-in contract.
|
/// Native implementation of a built-in contract.
|
||||||
pub trait Impl: Send + Sync {
|
pub trait Impl: Send + Sync {
|
||||||
/// execute this built-in on the given input, writing to the given output.
|
/// execute this built-in on the given input, writing to the given output.
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
use std::collections::{HashSet, HashMap, BTreeMap, VecDeque};
|
use std::collections::{HashSet, HashMap, BTreeMap, VecDeque};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::fmt;
|
|
||||||
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
||||||
use std::time::{Instant};
|
use std::time::{Instant};
|
||||||
use time::precise_time_ns;
|
use time::precise_time_ns;
|
||||||
@ -43,8 +42,8 @@ use client::{
|
|||||||
};
|
};
|
||||||
use encoded;
|
use encoded;
|
||||||
use engines::{Engine, EpochTransition};
|
use engines::{Engine, EpochTransition};
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use env_info::LastHashes;
|
use evm::env_info::LastHashes;
|
||||||
use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError};
|
use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError};
|
||||||
use evm::{Factory as EvmFactory, Schedule};
|
use evm::{Factory as EvmFactory, Schedule};
|
||||||
use executive::{Executive, Executed, TransactOptions, contract_address};
|
use executive::{Executive, Executed, TransactOptions, contract_address};
|
||||||
@ -84,12 +83,6 @@ const MAX_TX_QUEUE_SIZE: usize = 4096;
|
|||||||
const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2;
|
const MAX_QUEUE_SIZE_TO_SLEEP_ON: usize = 2;
|
||||||
const MIN_HISTORY_SIZE: u64 = 8;
|
const MIN_HISTORY_SIZE: u64 = 8;
|
||||||
|
|
||||||
impl fmt::Display for BlockChainInfo {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "#{}.{}", self.best_block_number, self.best_block_hash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Report on the status of a client.
|
/// Report on the status of a client.
|
||||||
#[derive(Default, Clone, Debug, Eq, PartialEq)]
|
#[derive(Default, Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct ClientReport {
|
pub struct ClientReport {
|
||||||
@ -537,7 +530,7 @@ impl Client {
|
|||||||
} else {
|
} else {
|
||||||
imported_blocks.push(header.hash());
|
imported_blocks.push(header.hash());
|
||||||
|
|
||||||
let route = self.commit_block(closed_block, &header.hash(), &block.bytes);
|
let route = self.commit_block(closed_block, &header, &block.bytes);
|
||||||
import_results.push(route);
|
import_results.push(route);
|
||||||
|
|
||||||
self.report.write().accrue_block(&block);
|
self.report.write().accrue_block(&block);
|
||||||
@ -642,10 +635,14 @@ impl Client {
|
|||||||
Ok(hash)
|
Ok(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit_block<B>(&self, block: B, hash: &H256, block_data: &[u8]) -> ImportRoute where B: IsBlock + Drain {
|
// NOTE: the header of the block passed here is not necessarily sealed, as
|
||||||
let number = block.header().number();
|
// it is for reconstructing the state transition.
|
||||||
let parent = block.header().parent_hash().clone();
|
//
|
||||||
let header = block.header().clone(); // TODO: optimize and avoid copy.
|
// The header passed is from the original block data and is sealed.
|
||||||
|
fn commit_block<B>(&self, block: B, header: &Header, block_data: &[u8]) -> ImportRoute where B: IsBlock + Drain {
|
||||||
|
let hash = &header.hash();
|
||||||
|
let number = header.number();
|
||||||
|
let parent = header.parent_hash();
|
||||||
let chain = self.chain.read();
|
let chain = self.chain.read();
|
||||||
|
|
||||||
// Commit results
|
// Commit results
|
||||||
@ -655,6 +652,8 @@ impl Client {
|
|||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(header.hash(), BlockView::new(block_data).header_view().sha3());
|
||||||
|
|
||||||
//let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
|
//let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
|
||||||
|
|
||||||
let mut batch = DBTransaction::new();
|
let mut batch = DBTransaction::new();
|
||||||
@ -664,6 +663,17 @@ impl Client {
|
|||||||
// TODO: Prove it with a test.
|
// TODO: Prove it with a test.
|
||||||
let mut state = block.drain();
|
let mut state = block.drain();
|
||||||
|
|
||||||
|
// check epoch end signal, potentially generating a proof on the current
|
||||||
|
// state.
|
||||||
|
self.check_epoch_end_signal(
|
||||||
|
&header,
|
||||||
|
block_data,
|
||||||
|
&receipts,
|
||||||
|
&state,
|
||||||
|
&chain,
|
||||||
|
&mut batch,
|
||||||
|
);
|
||||||
|
|
||||||
state.journal_under(&mut batch, number, hash).expect("DB commit failed");
|
state.journal_under(&mut batch, number, hash).expect("DB commit failed");
|
||||||
let route = chain.insert_block(&mut batch, block_data, receipts.clone());
|
let route = chain.insert_block(&mut batch, block_data, receipts.clone());
|
||||||
|
|
||||||
@ -681,10 +691,6 @@ impl Client {
|
|||||||
self.db.read().write_buffered(batch);
|
self.db.read().write_buffered(batch);
|
||||||
chain.commit();
|
chain.commit();
|
||||||
|
|
||||||
// check for epoch end. do this after writing first batch so we can prove
|
|
||||||
// transactions on the block's state.
|
|
||||||
// TODO: work these changes into the existing DBTransaction.
|
|
||||||
self.check_epoch_end_signal(&header, block_data, &receipts, &chain);
|
|
||||||
self.check_epoch_end(&header, &chain);
|
self.check_epoch_end(&header, &chain);
|
||||||
|
|
||||||
self.update_last_hashes(&parent, hash);
|
self.update_last_hashes(&parent, hash);
|
||||||
@ -698,38 +704,82 @@ impl Client {
|
|||||||
|
|
||||||
// check for epoch end signal and write pending transition if it occurs.
|
// check for epoch end signal and write pending transition if it occurs.
|
||||||
// state for the given block must be available.
|
// state for the given block must be available.
|
||||||
fn check_epoch_end_signal(&self, header: &Header, block: &[u8], receipts: &[Receipt], chain: &BlockChain) {
|
fn check_epoch_end_signal(
|
||||||
|
&self,
|
||||||
|
header: &Header,
|
||||||
|
block_bytes: &[u8],
|
||||||
|
receipts: &[Receipt],
|
||||||
|
state_db: &StateDB,
|
||||||
|
chain: &BlockChain,
|
||||||
|
batch: &mut DBTransaction,
|
||||||
|
) {
|
||||||
use engines::EpochChange;
|
use engines::EpochChange;
|
||||||
|
|
||||||
let hash = header.hash();
|
let hash = header.hash();
|
||||||
match self.engine.signals_epoch_end(header, Some(block), Some(&receipts)) {
|
match self.engine.signals_epoch_end(header, Some(block_bytes), Some(&receipts)) {
|
||||||
EpochChange::Yes(proof) => {
|
EpochChange::Yes(proof) => {
|
||||||
use engines::epoch::PendingTransition;
|
use engines::epoch::PendingTransition;
|
||||||
use engines::Proof;
|
use engines::Proof;
|
||||||
|
|
||||||
let proof = match proof {
|
let proof = match proof {
|
||||||
Proof::Known(proof) => proof,
|
Proof::Known(proof) => proof,
|
||||||
Proof::WithState(with_state) =>
|
Proof::WithState(with_state) => {
|
||||||
match self.with_proving_caller(BlockId::Hash(hash), move |c| with_state(c)) {
|
let env_info = EnvInfo {
|
||||||
|
number: header.number(),
|
||||||
|
author: header.author().clone(),
|
||||||
|
timestamp: header.timestamp(),
|
||||||
|
difficulty: header.difficulty().clone(),
|
||||||
|
last_hashes: self.build_last_hashes(header.parent_hash().clone()),
|
||||||
|
gas_used: U256::default(),
|
||||||
|
gas_limit: u64::max_value().into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let call = move |addr, data| {
|
||||||
|
let mut state_db = state_db.boxed_clone();
|
||||||
|
let backend = ::state::backend::Proving::new(state_db.as_hashdb_mut());
|
||||||
|
|
||||||
|
let transaction =
|
||||||
|
self.contract_call_tx(BlockId::Hash(*header.parent_hash()), addr, data);
|
||||||
|
|
||||||
|
let mut state = State::from_existing(
|
||||||
|
backend,
|
||||||
|
header.state_root().clone(),
|
||||||
|
self.engine.account_start_nonce(header.number()),
|
||||||
|
self.factories.clone(),
|
||||||
|
).expect("state known to be available for just-imported block; qed");
|
||||||
|
|
||||||
|
let options = TransactOptions { tracing: false, vm_tracing: false, check_nonce: false };
|
||||||
|
let res = Executive::new(&mut state, &env_info, &*self.engine)
|
||||||
|
.transact(&transaction, options);
|
||||||
|
|
||||||
|
let res = match res {
|
||||||
|
Err(ExecutionError::Internal(e)) =>
|
||||||
|
Err(format!("Internal error: {}", e)),
|
||||||
|
Err(e) => {
|
||||||
|
trace!(target: "client", "Proved call failed: {}", e);
|
||||||
|
Ok((Vec::new(), state.drop().1.extract_proof()))
|
||||||
|
}
|
||||||
|
Ok(res) => Ok((res.output, state.drop().1.extract_proof())),
|
||||||
|
};
|
||||||
|
|
||||||
|
res.map(|(output, proof)| (output, proof.into_iter().map(|x| x.into_vec()).collect()))
|
||||||
|
};
|
||||||
|
|
||||||
|
match (with_state)(&call) {
|
||||||
Ok(proof) => proof,
|
Ok(proof) => proof,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!(target: "client", "Failed to generate transition proof for block {}: {}", hash, e);
|
warn!(target: "client", "Failed to generate transition proof for block {}: {}", hash, e);
|
||||||
warn!(target: "client", "Snapshots produced by this client may be incomplete");
|
warn!(target: "client", "Snapshots produced by this client may be incomplete");
|
||||||
|
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!(target: "client", "Block {} signals epoch end.", hash);
|
debug!(target: "client", "Block {} signals epoch end.", hash);
|
||||||
|
|
||||||
// write pending transition to DB.
|
|
||||||
let mut batch = DBTransaction::new();
|
|
||||||
|
|
||||||
let pending = PendingTransition { proof: proof };
|
let pending = PendingTransition { proof: proof };
|
||||||
chain.insert_pending_transition(&mut batch, hash, pending);
|
chain.insert_pending_transition(batch, hash, pending);
|
||||||
|
|
||||||
self.db.read().write_buffered(batch);
|
|
||||||
},
|
},
|
||||||
EpochChange::No => {},
|
EpochChange::No => {},
|
||||||
EpochChange::Unsure(_) => {
|
EpochChange::Unsure(_) => {
|
||||||
@ -756,7 +806,11 @@ impl Client {
|
|||||||
block_number: header.number(),
|
block_number: header.number(),
|
||||||
proof: proof,
|
proof: proof,
|
||||||
});
|
});
|
||||||
self.db.read().write_buffered(batch);
|
|
||||||
|
// always write the batch directly since epoch transition proofs are
|
||||||
|
// fetched from a DB iterator and DB iterators are only available on
|
||||||
|
// flushed data.
|
||||||
|
self.db.read().write(batch).expect("DB flush failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1773,7 +1827,9 @@ impl MiningBlockChainClient for Client {
|
|||||||
|
|
||||||
let number = block.header().number();
|
let number = block.header().number();
|
||||||
let block_data = block.rlp_bytes();
|
let block_data = block.rlp_bytes();
|
||||||
let route = self.commit_block(block, &h, &block_data);
|
let header = block.header().clone();
|
||||||
|
|
||||||
|
let route = self.commit_block(block, &header, &block_data);
|
||||||
trace!(target: "client", "Imported sealed block #{} ({})", number, h);
|
trace!(target: "client", "Imported sealed block #{} ({})", number, h);
|
||||||
self.state_db.lock().sync_cache(&route.enacted, &route.retracted, false);
|
self.state_db.lock().sync_cache(&route.enacted, &route.retracted, false);
|
||||||
route
|
route
|
||||||
|
@ -17,14 +17,16 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||||
|
|
||||||
|
use mode::Mode as IpcMode;
|
||||||
|
use verification::{VerifierType, QueueConfig};
|
||||||
|
use util::{journaldb, CompactionProfile};
|
||||||
|
|
||||||
pub use std::time::Duration;
|
pub use std::time::Duration;
|
||||||
pub use blockchain::Config as BlockChainConfig;
|
pub use blockchain::Config as BlockChainConfig;
|
||||||
pub use trace::Config as TraceConfig;
|
pub use trace::Config as TraceConfig;
|
||||||
pub use evm::VMType;
|
pub use evm::VMType;
|
||||||
|
|
||||||
use verification::{VerifierType, QueueConfig};
|
|
||||||
use util::{journaldb, CompactionProfile};
|
|
||||||
|
|
||||||
/// Client state db compaction profile
|
/// Client state db compaction profile
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum DatabaseCompactionProfile {
|
pub enum DatabaseCompactionProfile {
|
||||||
@ -98,6 +100,29 @@ impl Display for Mode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<IpcMode> for Mode {
|
||||||
|
fn into(self) -> IpcMode {
|
||||||
|
match self {
|
||||||
|
Mode::Off => IpcMode::Off,
|
||||||
|
Mode::Dark(timeout) => IpcMode::Dark(timeout.as_secs()),
|
||||||
|
Mode::Passive(timeout, alarm) => IpcMode::Passive(timeout.as_secs(), alarm.as_secs()),
|
||||||
|
Mode::Active => IpcMode::Active,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IpcMode> for Mode {
|
||||||
|
fn from(mode: IpcMode) -> Self {
|
||||||
|
match mode {
|
||||||
|
IpcMode::Off => Mode::Off,
|
||||||
|
IpcMode::Dark(timeout) => Mode::Dark(Duration::from_secs(timeout)),
|
||||||
|
IpcMode::Passive(timeout, alarm) => Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm)),
|
||||||
|
IpcMode::Active => Mode::Active,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Client configuration. Includes configs for all sub-systems.
|
/// Client configuration. Includes configs for all sub-systems.
|
||||||
#[derive(Debug, PartialEq, Default)]
|
#[derive(Debug, PartialEq, Default)]
|
||||||
pub struct ClientConfig {
|
pub struct ClientConfig {
|
||||||
|
@ -23,7 +23,7 @@ use util::kvdb::{self, KeyValueDB};
|
|||||||
use {state, state_db, client, executive, trace, db, spec};
|
use {state, state_db, client, executive, trace, db, spec};
|
||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
use evm::{self, VMType};
|
use evm::{self, VMType};
|
||||||
use action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
|
|
||||||
/// EVM test Error.
|
/// EVM test Error.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -40,11 +40,9 @@ pub use types::pruning_info::PruningInfo;
|
|||||||
pub use types::call_analytics::CallAnalytics;
|
pub use types::call_analytics::CallAnalytics;
|
||||||
|
|
||||||
pub use executive::{Executed, Executive, TransactOptions};
|
pub use executive::{Executed, Executive, TransactOptions};
|
||||||
pub use env_info::{LastHashes, EnvInfo};
|
pub use evm::env_info::{LastHashes, EnvInfo};
|
||||||
|
|
||||||
pub use block_import_error::BlockImportError;
|
pub use error::{BlockImportError, TransactionImportError, TransactionImportResult};
|
||||||
pub use transaction_import::TransactionImportResult;
|
|
||||||
pub use transaction_import::TransactionImportError;
|
|
||||||
pub use verification::VerifierType;
|
pub use verification::VerifierType;
|
||||||
|
|
||||||
/// IPC interfaces
|
/// IPC interfaces
|
||||||
|
@ -15,24 +15,27 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use util::{U256, Address, H256, H2048, Bytes, Itertools};
|
|
||||||
use util::hashdb::DBValue;
|
|
||||||
use blockchain::TreeRoute;
|
|
||||||
use verification::queue::QueueInfo as BlockQueueInfo;
|
|
||||||
use block::{OpenBlock, SealedBlock, ClosedBlock};
|
use block::{OpenBlock, SealedBlock, ClosedBlock};
|
||||||
use header::{BlockNumber};
|
use blockchain::TreeRoute;
|
||||||
use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction};
|
use encoded;
|
||||||
use transaction_import::TransactionImportResult;
|
use evm::env_info::LastHashes;
|
||||||
use log_entry::LocalizedLogEntry;
|
|
||||||
use filter::Filter;
|
|
||||||
use error::{ImportResult, CallError, Error as EthcoreError};
|
use error::{ImportResult, CallError, Error as EthcoreError};
|
||||||
use receipt::LocalizedReceipt;
|
use error::{TransactionImportResult, BlockImportError};
|
||||||
use trace::LocalizedTrace;
|
|
||||||
use evm::{Factory as EvmFactory, Schedule};
|
use evm::{Factory as EvmFactory, Schedule};
|
||||||
use executive::Executed;
|
use executive::Executed;
|
||||||
use env_info::LastHashes;
|
use filter::Filter;
|
||||||
use block_import_error::BlockImportError;
|
use header::{BlockNumber};
|
||||||
use ipc::IpcConfig;
|
use ipc::IpcConfig;
|
||||||
|
use log_entry::LocalizedLogEntry;
|
||||||
|
use receipt::LocalizedReceipt;
|
||||||
|
use trace::LocalizedTrace;
|
||||||
|
use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction};
|
||||||
|
use verification::queue::QueueInfo as BlockQueueInfo;
|
||||||
|
|
||||||
|
use util::{U256, Address, H256, H2048, Bytes, Itertools};
|
||||||
|
use util::hashdb::DBValue;
|
||||||
|
|
||||||
use types::ids::*;
|
use types::ids::*;
|
||||||
use types::basic_account::BasicAccount;
|
use types::basic_account::BasicAccount;
|
||||||
use types::trace_filter::Filter as TraceFilter;
|
use types::trace_filter::Filter as TraceFilter;
|
||||||
@ -41,7 +44,6 @@ use types::blockchain_info::BlockChainInfo;
|
|||||||
use types::block_status::BlockStatus;
|
use types::block_status::BlockStatus;
|
||||||
use types::mode::Mode;
|
use types::mode::Mode;
|
||||||
use types::pruning_info::PruningInfo;
|
use types::pruning_info::PruningInfo;
|
||||||
use encoded;
|
|
||||||
|
|
||||||
#[ipc(client_ident="RemoteClient")]
|
#[ipc(client_ident="RemoteClient")]
|
||||||
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
||||||
|
@ -66,6 +66,7 @@ impl RollingFinality {
|
|||||||
|
|
||||||
let entry = self.sign_count.entry(signer);
|
let entry = self.sign_count.entry(signer);
|
||||||
if let (true, &Entry::Vacant(_)) = (would_be_finalized, &entry) {
|
if let (true, &Entry::Vacant(_)) = (would_be_finalized, &entry) {
|
||||||
|
trace!(target: "finality", "Encountered already finalized block {}", hash);
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ impl RollingFinality {
|
|||||||
self.headers.push_front((hash, signer));
|
self.headers.push_front((hash, signer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!(target: "finality", "Rolling finality state: {:?}", self.headers);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +130,9 @@ impl RollingFinality {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!(target: "finality", "Blocks finalized by {:?}: {:?}", head, newly_finalized);
|
||||||
|
|
||||||
|
self.last_pushed = Some(head);
|
||||||
Ok(newly_finalized)
|
Ok(newly_finalized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,9 +220,9 @@ pub struct AuthorityRound {
|
|||||||
builtins: BTreeMap<Address, Builtin>,
|
builtins: BTreeMap<Address, Builtin>,
|
||||||
transition_service: IoService<()>,
|
transition_service: IoService<()>,
|
||||||
step: Arc<Step>,
|
step: Arc<Step>,
|
||||||
proposed: AtomicBool,
|
can_propose: AtomicBool,
|
||||||
client: RwLock<Option<Weak<EngineClient>>>,
|
client: RwLock<Option<Weak<EngineClient>>>,
|
||||||
signer: EngineSigner,
|
signer: RwLock<EngineSigner>,
|
||||||
validators: Box<ValidatorSet>,
|
validators: Box<ValidatorSet>,
|
||||||
validate_score_transition: u64,
|
validate_score_transition: u64,
|
||||||
eip155_transition: u64,
|
eip155_transition: u64,
|
||||||
@ -311,7 +311,7 @@ fn verify_external<F: Fn(Report)>(header: &Header, validators: &ValidatorSet, st
|
|||||||
|
|
||||||
// Give one step slack if step is lagging, double vote is still not possible.
|
// Give one step slack if step is lagging, double vote is still not possible.
|
||||||
if step.is_future(header_step) {
|
if step.is_future(header_step) {
|
||||||
trace!(target: "engine", "verify_block_unordered: block from the future");
|
trace!(target: "engine", "verify_block_external: block from the future");
|
||||||
report(Report::Benign(*header.author(), header.number()));
|
report(Report::Benign(*header.author(), header.number()));
|
||||||
Err(BlockError::InvalidSeal)?
|
Err(BlockError::InvalidSeal)?
|
||||||
} else {
|
} else {
|
||||||
@ -321,7 +321,7 @@ fn verify_external<F: Fn(Report)>(header: &Header, validators: &ValidatorSet, st
|
|||||||
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
|
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
|
||||||
|
|
||||||
if is_invalid_proposer {
|
if is_invalid_proposer {
|
||||||
trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", header_step);
|
trace!(target: "engine", "verify_block_external: bad proposer for step: {}", header_step);
|
||||||
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
|
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -372,7 +372,7 @@ impl AuthorityRound {
|
|||||||
calibrate: our_params.start_step.is_none(),
|
calibrate: our_params.start_step.is_none(),
|
||||||
duration: our_params.step_duration,
|
duration: our_params.step_duration,
|
||||||
}),
|
}),
|
||||||
proposed: AtomicBool::new(false),
|
can_propose: AtomicBool::new(true),
|
||||||
client: RwLock::new(None),
|
client: RwLock::new(None),
|
||||||
signer: Default::default(),
|
signer: Default::default(),
|
||||||
validators: our_params.validators,
|
validators: our_params.validators,
|
||||||
@ -439,7 +439,7 @@ impl Engine for AuthorityRound {
|
|||||||
|
|
||||||
fn step(&self) {
|
fn step(&self) {
|
||||||
self.step.increment();
|
self.step.increment();
|
||||||
self.proposed.store(false, AtomicOrdering::SeqCst);
|
self.can_propose.store(true, AtomicOrdering::SeqCst);
|
||||||
if let Some(ref weak) = *self.client.read() {
|
if let Some(ref weak) = *self.client.read() {
|
||||||
if let Some(c) = weak.upgrade() {
|
if let Some(c) = weak.upgrade() {
|
||||||
c.update_sealing();
|
c.update_sealing();
|
||||||
@ -471,7 +471,7 @@ impl Engine for AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn seals_internally(&self) -> Option<bool> {
|
fn seals_internally(&self) -> Option<bool> {
|
||||||
Some(self.signer.address() != Address::default())
|
Some(self.signer.read().is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to seal the block internally.
|
/// Attempt to seal the block internally.
|
||||||
@ -481,7 +481,7 @@ impl Engine for AuthorityRound {
|
|||||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||||
// first check to avoid generating signature most of the time
|
// first check to avoid generating signature most of the time
|
||||||
// (but there's still a race to the `compare_and_swap`)
|
// (but there's still a race to the `compare_and_swap`)
|
||||||
if self.proposed.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
if !self.can_propose.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
||||||
|
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
let step = self.step.load();
|
let step = self.step.load();
|
||||||
@ -512,11 +512,11 @@ impl Engine for AuthorityRound {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if is_step_proposer(validators, header.parent_hash(), step, header.author()) {
|
if is_step_proposer(validators, header.parent_hash(), step, header.author()) {
|
||||||
if let Ok(signature) = self.signer.sign(header.bare_hash()) {
|
if let Ok(signature) = self.sign(header.bare_hash()) {
|
||||||
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
|
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
|
||||||
|
|
||||||
// only issue the seal if we were the first to reach the compare_and_swap.
|
// only issue the seal if we were the first to reach the compare_and_swap.
|
||||||
if !self.proposed.compare_and_swap(false, true, AtomicOrdering::SeqCst) {
|
if self.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) {
|
||||||
return Seal::Regular(vec![encode(&step).into_vec(), encode(&(&H520::from(signature) as &[u8])).into_vec()]);
|
return Seal::Regular(vec![encode(&step).into_vec(), encode(&(&H520::from(signature) as &[u8])).into_vec()]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -532,7 +532,7 @@ impl Engine for AuthorityRound {
|
|||||||
fn on_new_block(
|
fn on_new_block(
|
||||||
&self,
|
&self,
|
||||||
block: &mut ExecutedBlock,
|
block: &mut ExecutedBlock,
|
||||||
last_hashes: Arc<::env_info::LastHashes>,
|
last_hashes: Arc<::evm::env_info::LastHashes>,
|
||||||
epoch_begin: bool,
|
epoch_begin: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let parent_hash = block.fields().header.parent_hash().clone();
|
let parent_hash = block.fields().header.parent_hash().clone();
|
||||||
@ -614,16 +614,18 @@ impl Engine for AuthorityRound {
|
|||||||
Err(EngineError::DoubleVote(header.author().clone()))?;
|
Err(EngineError::DoubleVote(header.author().clone()))?;
|
||||||
}
|
}
|
||||||
// Report skipped primaries.
|
// Report skipped primaries.
|
||||||
if step > parent_step + 1 {
|
if let (true, Some(me)) = (step > parent_step + 1, self.signer.read().address()) {
|
||||||
// TODO: use epochmanager to get correct validator set for reporting?
|
debug!(target: "engine", "Author {} built block with step gap. current step: {}, parent step: {}",
|
||||||
// or just rely on the fact that in general these will be the same
|
|
||||||
// and some reports might go missing?
|
|
||||||
trace!(target: "engine", "Author {} built block with step gap. current step: {}, parent step: {}",
|
|
||||||
header.author(), step, parent_step);
|
header.author(), step, parent_step);
|
||||||
|
let mut reported = HashSet::new();
|
||||||
for s in parent_step + 1..step {
|
for s in parent_step + 1..step {
|
||||||
let skipped_primary = step_proposer(&*self.validators, &parent.hash(), s);
|
let skipped_primary = step_proposer(&*self.validators, &parent.hash(), s);
|
||||||
self.validators.report_benign(&skipped_primary, header.number(), header.number());
|
// Do not report this signer.
|
||||||
|
if skipped_primary != me {
|
||||||
|
self.validators.report_benign(&skipped_primary, header.number(), header.number());
|
||||||
|
}
|
||||||
|
// Stop reporting once validators start repeating.
|
||||||
|
if !reported.insert(skipped_primary) { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,6 +725,9 @@ impl Engine for AuthorityRound {
|
|||||||
if epoch_manager.finality_checker.subchain_head() != Some(*chain_head.parent_hash()) {
|
if epoch_manager.finality_checker.subchain_head() != Some(*chain_head.parent_hash()) {
|
||||||
// build new finality checker from ancestry of chain head,
|
// build new finality checker from ancestry of chain head,
|
||||||
// not including chain head itself yet.
|
// not including chain head itself yet.
|
||||||
|
trace!(target: "finality", "Building finality up to parent of {} ({})",
|
||||||
|
chain_head.hash(), chain_head.parent_hash());
|
||||||
|
|
||||||
let mut hash = chain_head.parent_hash().clone();
|
let mut hash = chain_head.parent_hash().clone();
|
||||||
let epoch_transition_hash = epoch_manager.epoch_transition_hash;
|
let epoch_transition_hash = epoch_manager.epoch_transition_hash;
|
||||||
|
|
||||||
@ -734,6 +739,8 @@ impl Engine for AuthorityRound {
|
|||||||
if header.number() == 0 { return None }
|
if header.number() == 0 { return None }
|
||||||
|
|
||||||
let res = (hash, header.author().clone());
|
let res = (hash, header.author().clone());
|
||||||
|
trace!(target: "finality", "Ancestry iteration: yielding {:?}", res);
|
||||||
|
|
||||||
hash = header.parent_hash().clone();
|
hash = header.parent_hash().clone();
|
||||||
Some(res)
|
Some(res)
|
||||||
})
|
})
|
||||||
@ -766,6 +773,16 @@ impl Engine for AuthorityRound {
|
|||||||
let finality_proof = ::rlp::encode_list(&finality_proof);
|
let finality_proof = ::rlp::encode_list(&finality_proof);
|
||||||
epoch_manager.note_new_epoch();
|
epoch_manager.note_new_epoch();
|
||||||
|
|
||||||
|
info!(target: "engine", "Applying validator set change signalled at block {}", signal_number);
|
||||||
|
|
||||||
|
// We turn off can_propose here because upon validator set change there can
|
||||||
|
// be two valid proposers for a single step: one from the old set and
|
||||||
|
// one from the new.
|
||||||
|
//
|
||||||
|
// This way, upon encountering an epoch change, the proposer from the
|
||||||
|
// new set will be forced to wait until the next step to avoid sealing a
|
||||||
|
// block that breaks the invariant that the parent's step < the block's step.
|
||||||
|
self.can_propose.store(false, AtomicOrdering::SeqCst);
|
||||||
return Some(combine_proofs(signal_number, &pending.proof, &*finality_proof));
|
return Some(combine_proofs(signal_number, &pending.proof, &*finality_proof));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,11 +833,11 @@ impl Engine for AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
||||||
self.signer.set(ap, address, password);
|
self.signer.write().set(ap, address, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, hash: H256) -> Result<Signature, Error> {
|
fn sign(&self, hash: H256) -> Result<Signature, Error> {
|
||||||
self.signer.sign(hash).map_err(Into::into)
|
self.signer.read().sign(hash).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
|
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
|
||||||
@ -1018,6 +1035,12 @@ mod tests {
|
|||||||
header.set_gas_limit(U256::from_str("222222").unwrap());
|
header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||||
header.set_seal(vec![encode(&3usize).into_vec()]);
|
header.set_seal(vec![encode(&3usize).into_vec()]);
|
||||||
|
|
||||||
|
// Do not report when signer not present.
|
||||||
|
assert!(aura.verify_block_family(&header, &parent_header, None).is_ok());
|
||||||
|
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 0);
|
||||||
|
|
||||||
|
aura.set_signer(Arc::new(AccountProvider::transient_provider()), Default::default(), Default::default());
|
||||||
|
|
||||||
assert!(aura.verify_block_family(&header, &parent_header, None).is_ok());
|
assert!(aura.verify_block_family(&header, &parent_header, None).is_ok());
|
||||||
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ pub struct BasicAuthority {
|
|||||||
params: CommonParams,
|
params: CommonParams,
|
||||||
gas_limit_bound_divisor: U256,
|
gas_limit_bound_divisor: U256,
|
||||||
builtins: BTreeMap<Address, Builtin>,
|
builtins: BTreeMap<Address, Builtin>,
|
||||||
signer: EngineSigner,
|
signer: RwLock<EngineSigner>,
|
||||||
validators: Box<ValidatorSet>,
|
validators: Box<ValidatorSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ impl Engine for BasicAuthority {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn seals_internally(&self) -> Option<bool> {
|
fn seals_internally(&self) -> Option<bool> {
|
||||||
Some(self.signer.address() != Address::default())
|
Some(self.signer.read().is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to seal the block internally.
|
/// Attempt to seal the block internally.
|
||||||
@ -138,7 +138,7 @@ impl Engine for BasicAuthority {
|
|||||||
let author = header.author();
|
let author = header.author();
|
||||||
if self.validators.contains(header.parent_hash(), author) {
|
if self.validators.contains(header.parent_hash(), author) {
|
||||||
// account should be pernamently unlocked, otherwise sealing will fail
|
// account should be pernamently unlocked, otherwise sealing will fail
|
||||||
if let Ok(signature) = self.signer.sign(header.bare_hash()) {
|
if let Ok(signature) = self.sign(header.bare_hash()) {
|
||||||
return Seal::Regular(vec![::rlp::encode(&(&H520::from(signature) as &[u8])).into_vec()]);
|
return Seal::Regular(vec![::rlp::encode(&(&H520::from(signature) as &[u8])).into_vec()]);
|
||||||
} else {
|
} else {
|
||||||
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
|
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
|
||||||
@ -240,11 +240,11 @@ impl Engine for BasicAuthority {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
||||||
self.signer.set(ap, address, password);
|
self.signer.write().set(ap, address, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, hash: H256) -> Result<Signature, Error> {
|
fn sign(&self, hash: H256) -> Result<Signature, Error> {
|
||||||
self.signer.sign(hash).map_err(Into::into)
|
self.signer.read().sign(hash).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
|
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
|
||||||
|
@ -43,7 +43,7 @@ use account_provider::AccountProvider;
|
|||||||
use block::ExecutedBlock;
|
use block::ExecutedBlock;
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use env_info::{EnvInfo, LastHashes};
|
use evm::env_info::{EnvInfo, LastHashes};
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
use header::{Header, BlockNumber};
|
use header::{Header, BlockNumber};
|
||||||
@ -193,7 +193,7 @@ pub trait Engine : Sync + Send {
|
|||||||
|
|
||||||
/// Get the EVM schedule for the given `block_number`.
|
/// Get the EVM schedule for the given `block_number`.
|
||||||
fn schedule(&self, block_number: BlockNumber) -> Schedule {
|
fn schedule(&self, block_number: BlockNumber) -> Schedule {
|
||||||
Schedule::from_params(block_number, self.params())
|
self.params().schedule(block_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builtin-contracts we would like to see in the chain.
|
/// Builtin-contracts we would like to see in the chain.
|
||||||
@ -394,12 +394,12 @@ pub trait Engine : Sync + Send {
|
|||||||
/// Common engine utilities
|
/// Common engine utilities
|
||||||
pub mod common {
|
pub mod common {
|
||||||
use block::ExecutedBlock;
|
use block::ExecutedBlock;
|
||||||
use env_info::{EnvInfo, LastHashes};
|
use evm::env_info::{EnvInfo, LastHashes};
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use transaction::SYSTEM_ADDRESS;
|
use transaction::SYSTEM_ADDRESS;
|
||||||
use executive::Executive;
|
use executive::Executive;
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use evm::action_params::{ActionParams, ActionValue};
|
||||||
use trace::{NoopTracer, NoopVMTracer};
|
use trace::{NoopTracer, NoopVMTracer};
|
||||||
use state::Substate;
|
use state::Substate;
|
||||||
|
|
||||||
|
@ -16,21 +16,21 @@
|
|||||||
|
|
||||||
//! A signer used by Engines which need to sign messages.
|
//! A signer used by Engines which need to sign messages.
|
||||||
|
|
||||||
use util::{Arc, Mutex, RwLock, H256, Address};
|
use util::{Arc, H256, Address};
|
||||||
use ethkey::Signature;
|
use ethkey::Signature;
|
||||||
use account_provider::{self, AccountProvider};
|
use account_provider::{self, AccountProvider};
|
||||||
|
|
||||||
/// Everything that an Engine needs to sign messages.
|
/// Everything that an Engine needs to sign messages.
|
||||||
pub struct EngineSigner {
|
pub struct EngineSigner {
|
||||||
account_provider: Mutex<Arc<AccountProvider>>,
|
account_provider: Arc<AccountProvider>,
|
||||||
address: RwLock<Address>,
|
address: Option<Address>,
|
||||||
password: RwLock<Option<String>>,
|
password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EngineSigner {
|
impl Default for EngineSigner {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
EngineSigner {
|
EngineSigner {
|
||||||
account_provider: Mutex::new(Arc::new(AccountProvider::transient_provider())),
|
account_provider: Arc::new(AccountProvider::transient_provider()),
|
||||||
address: Default::default(),
|
address: Default::default(),
|
||||||
password: Default::default(),
|
password: Default::default(),
|
||||||
}
|
}
|
||||||
@ -39,25 +39,30 @@ impl Default for EngineSigner {
|
|||||||
|
|
||||||
impl EngineSigner {
|
impl EngineSigner {
|
||||||
/// Set up the signer to sign with given address and password.
|
/// Set up the signer to sign with given address and password.
|
||||||
pub fn set(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
pub fn set(&mut self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
||||||
*self.account_provider.lock() = ap;
|
self.account_provider = ap;
|
||||||
*self.address.write() = address;
|
self.address = Some(address);
|
||||||
*self.password.write() = Some(password);
|
self.password = Some(password);
|
||||||
debug!(target: "poa", "Setting Engine signer to {}", address);
|
debug!(target: "poa", "Setting Engine signer to {}", address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sign a consensus message hash.
|
/// Sign a consensus message hash.
|
||||||
pub fn sign(&self, hash: H256) -> Result<Signature, account_provider::SignError> {
|
pub fn sign(&self, hash: H256) -> Result<Signature, account_provider::SignError> {
|
||||||
self.account_provider.lock().sign(*self.address.read(), self.password.read().clone(), hash)
|
self.account_provider.sign(self.address.unwrap_or_else(Default::default), self.password.clone(), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signing address.
|
/// Signing address.
|
||||||
pub fn address(&self) -> Address {
|
pub fn address(&self) -> Option<Address> {
|
||||||
self.address.read().clone()
|
self.address.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the given address is the signing address.
|
/// Check if the given address is the signing address.
|
||||||
pub fn is_address(&self, address: &Address) -> bool {
|
pub fn is_address(&self, address: &Address) -> bool {
|
||||||
*self.address.read() == *address
|
self.address.map_or(false, |a| a == *address)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the signing address was set.
|
||||||
|
pub fn is_some(&self) -> bool {
|
||||||
|
self.address.is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ pub struct Tendermint {
|
|||||||
/// Vote accumulator.
|
/// Vote accumulator.
|
||||||
votes: VoteCollector<ConsensusMessage>,
|
votes: VoteCollector<ConsensusMessage>,
|
||||||
/// Used to sign messages and proposals.
|
/// Used to sign messages and proposals.
|
||||||
signer: EngineSigner,
|
signer: RwLock<EngineSigner>,
|
||||||
/// Message for the last PoLC.
|
/// Message for the last PoLC.
|
||||||
lock_change: RwLock<Option<ConsensusMessage>>,
|
lock_change: RwLock<Option<ConsensusMessage>>,
|
||||||
/// Last lock view.
|
/// Last lock view.
|
||||||
@ -159,19 +159,22 @@ impl Tendermint {
|
|||||||
let r = self.view.load(AtomicOrdering::SeqCst);
|
let r = self.view.load(AtomicOrdering::SeqCst);
|
||||||
let s = *self.step.read();
|
let s = *self.step.read();
|
||||||
let vote_info = message_info_rlp(&VoteStep::new(h, r, s), block_hash);
|
let vote_info = message_info_rlp(&VoteStep::new(h, r, s), block_hash);
|
||||||
match self.signer.sign(vote_info.sha3()).map(Into::into) {
|
match (self.signer.read().address(), self.sign(vote_info.sha3()).map(Into::into)) {
|
||||||
Ok(signature) => {
|
(Some(validator), Ok(signature)) => {
|
||||||
let message_rlp = message_full_rlp(&signature, &vote_info);
|
let message_rlp = message_full_rlp(&signature, &vote_info);
|
||||||
let message = ConsensusMessage::new(signature, h, r, s, block_hash);
|
let message = ConsensusMessage::new(signature, h, r, s, block_hash);
|
||||||
let validator = self.signer.address();
|
|
||||||
self.votes.vote(message.clone(), &validator);
|
self.votes.vote(message.clone(), &validator);
|
||||||
debug!(target: "engine", "Generated {:?} as {}.", message, validator);
|
debug!(target: "engine", "Generated {:?} as {}.", message, validator);
|
||||||
self.handle_valid_message(&message);
|
self.handle_valid_message(&message);
|
||||||
|
|
||||||
Some(message_rlp)
|
Some(message_rlp)
|
||||||
},
|
},
|
||||||
Err(e) => {
|
(None, _) => {
|
||||||
trace!(target: "engine", "Could not sign the message {}", e);
|
trace!(target: "engine", "No message, since there is no engine signer.");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
(Some(v), Err(e)) => {
|
||||||
|
trace!(target: "engine", "{} could not sign the message {}", v, e);
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -272,7 +275,7 @@ impl Tendermint {
|
|||||||
/// Check if current signer is the current proposer.
|
/// Check if current signer is the current proposer.
|
||||||
fn is_signer_proposer(&self, bh: &H256) -> bool {
|
fn is_signer_proposer(&self, bh: &H256) -> bool {
|
||||||
let proposer = self.view_proposer(bh, self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst));
|
let proposer = self.view_proposer(bh, self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst));
|
||||||
self.signer.is_address(&proposer)
|
self.signer.read().is_address(&proposer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_height(&self, message: &ConsensusMessage) -> bool {
|
fn is_height(&self, message: &ConsensusMessage) -> bool {
|
||||||
@ -420,7 +423,7 @@ impl Engine for Tendermint {
|
|||||||
|
|
||||||
/// Should this node participate.
|
/// Should this node participate.
|
||||||
fn seals_internally(&self) -> Option<bool> {
|
fn seals_internally(&self) -> Option<bool> {
|
||||||
Some(self.signer.address() != Address::default())
|
Some(self.signer.read().is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to seal generate a proposal seal.
|
/// Attempt to seal generate a proposal seal.
|
||||||
@ -436,7 +439,7 @@ impl Engine for Tendermint {
|
|||||||
let view = self.view.load(AtomicOrdering::SeqCst);
|
let view = self.view.load(AtomicOrdering::SeqCst);
|
||||||
let bh = Some(header.bare_hash());
|
let bh = Some(header.bare_hash());
|
||||||
let vote_info = message_info_rlp(&VoteStep::new(height, view, Step::Propose), bh.clone());
|
let vote_info = message_info_rlp(&VoteStep::new(height, view, Step::Propose), bh.clone());
|
||||||
if let Ok(signature) = self.signer.sign(vote_info.sha3()).map(Into::into) {
|
if let Ok(signature) = self.sign(vote_info.sha3()).map(Into::into) {
|
||||||
// Insert Propose vote.
|
// Insert Propose vote.
|
||||||
debug!(target: "engine", "Submitting proposal {} at height {} view {}.", header.bare_hash(), height, view);
|
debug!(target: "engine", "Submitting proposal {} at height {} view {}.", header.bare_hash(), height, view);
|
||||||
self.votes.vote(ConsensusMessage::new(signature, height, view, Step::Propose, bh), author);
|
self.votes.vote(ConsensusMessage::new(signature, height, view, Step::Propose, bh), author);
|
||||||
@ -565,13 +568,13 @@ impl Engine for Tendermint {
|
|||||||
|
|
||||||
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: String) {
|
||||||
{
|
{
|
||||||
self.signer.set(ap, address, password);
|
self.signer.write().set(ap, address, password);
|
||||||
}
|
}
|
||||||
self.to_step(Step::Propose);
|
self.to_step(Step::Propose);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, hash: H256) -> Result<Signature, Error> {
|
fn sign(&self, hash: H256) -> Result<Signature, Error> {
|
||||||
self.signer.sign(hash).map_err(Into::into)
|
self.signer.read().sign(hash).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
@ -901,7 +904,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn seal_submission() {
|
fn seal_submission() {
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use types::transaction::{Transaction, Action};
|
use transaction::{Transaction, Action};
|
||||||
use client::BlockChainClient;
|
use client::BlockChainClient;
|
||||||
|
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
|
@ -110,6 +110,9 @@ fn prove_initial(provider: &Provider, header: &Header, caller: &Call) -> Result<
|
|||||||
trace!(target: "engine", "obtained proof for initial set: {} validators, {} bytes",
|
trace!(target: "engine", "obtained proof for initial set: {} validators, {} bytes",
|
||||||
validators.len(), proof.len());
|
validators.len(), proof.len());
|
||||||
|
|
||||||
|
info!(target: "engine", "Signal for switch to contract-based validator set.");
|
||||||
|
info!(target: "engine", "Initial contract validators: {:?}", validators);
|
||||||
|
|
||||||
proof
|
proof
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -231,9 +234,7 @@ impl ValidatorSet for ValidatorSafeContract {
|
|||||||
.map(|out| (out, Vec::new()))) // generate no proofs in general
|
.map(|out| (out, Vec::new()))) // generate no proofs in general
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_epoch_begin(&self, first: bool, _header: &Header, caller: &mut SystemCall) -> Result<(), ::error::Error> {
|
fn on_epoch_begin(&self, _first: bool, _header: &Header, caller: &mut SystemCall) -> Result<(), ::error::Error> {
|
||||||
if first { return Ok(()) } // only signalled changes need to be noted.
|
|
||||||
|
|
||||||
self.provider.finalize_change(caller)
|
self.provider.finalize_change(caller)
|
||||||
.wait()
|
.wait()
|
||||||
.map_err(::engines::EngineError::FailedSystemCall)
|
.map_err(::engines::EngineError::FailedSystemCall)
|
||||||
@ -271,8 +272,9 @@ impl ValidatorSet for ValidatorSafeContract {
|
|||||||
None => ::engines::EpochChange::Unsure(::engines::Unsure::NeedsReceipts),
|
None => ::engines::EpochChange::Unsure(::engines::Unsure::NeedsReceipts),
|
||||||
Some(receipts) => match self.extract_from_event(bloom, header, receipts) {
|
Some(receipts) => match self.extract_from_event(bloom, header, receipts) {
|
||||||
None => ::engines::EpochChange::No,
|
None => ::engines::EpochChange::No,
|
||||||
Some(_) => {
|
Some(list) => {
|
||||||
debug!(target: "engine", "signalling transition within contract");
|
info!(target: "engine", "Signal for transition within contract. New list: {:?}",
|
||||||
|
&*list);
|
||||||
|
|
||||||
let proof = encode_proof(&header, receipts);
|
let proof = encode_proof(&header, receipts);
|
||||||
::engines::EpochChange::Yes(::engines::Proof::Known(proof))
|
::engines::EpochChange::Yes(::engines::Proof::Known(proof))
|
||||||
@ -297,7 +299,7 @@ impl ValidatorSet for ValidatorSafeContract {
|
|||||||
let (old_header, state_items) = decode_first_proof(&rlp)?;
|
let (old_header, state_items) = decode_first_proof(&rlp)?;
|
||||||
let old_hash = old_header.hash();
|
let old_hash = old_header.hash();
|
||||||
|
|
||||||
let env_info = ::env_info::EnvInfo {
|
let env_info = ::evm::env_info::EnvInfo {
|
||||||
number: old_header.number(),
|
number: old_header.number(),
|
||||||
author: *old_header.author(),
|
author: *old_header.author(),
|
||||||
difficulty: *old_header.difficulty(),
|
difficulty: *old_header.difficulty(),
|
||||||
|
@ -22,13 +22,12 @@ use header::BlockNumber;
|
|||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
use client::Error as ClientError;
|
use client::Error as ClientError;
|
||||||
use ipc::binary::{BinaryConvertError, BinaryConvertable};
|
use ipc::binary::{BinaryConvertError, BinaryConvertable};
|
||||||
use types::block_import_error::BlockImportError;
|
|
||||||
use snapshot::Error as SnapshotError;
|
use snapshot::Error as SnapshotError;
|
||||||
use engines::EngineError;
|
use engines::EngineError;
|
||||||
use ethkey::Error as EthkeyError;
|
use ethkey::Error as EthkeyError;
|
||||||
use account_provider::SignError as AccountsError;
|
use account_provider::SignError as AccountsError;
|
||||||
|
|
||||||
pub use types::executed::{ExecutionError, CallError};
|
pub use executed::{ExecutionError, CallError};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
/// Errors concerning transaction processing.
|
/// Errors concerning transaction processing.
|
||||||
@ -239,6 +238,53 @@ impl fmt::Display for ImportError {
|
|||||||
f.write_fmt(format_args!("Block import error ({})", msg))
|
f.write_fmt(format_args!("Block import error ({})", msg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Error dedicated to import block function
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum BlockImportError {
|
||||||
|
/// Import error
|
||||||
|
Import(ImportError),
|
||||||
|
/// Block error
|
||||||
|
Block(BlockError),
|
||||||
|
/// Other error
|
||||||
|
Other(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Error> for BlockImportError {
|
||||||
|
fn from(e: Error) -> Self {
|
||||||
|
match e {
|
||||||
|
Error::Block(block_error) => BlockImportError::Block(block_error),
|
||||||
|
Error::Import(import_error) => BlockImportError::Import(import_error),
|
||||||
|
_ => BlockImportError::Other(format!("other block import error: {:?}", e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the result of importing transaction.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub enum TransactionImportResult {
|
||||||
|
/// Transaction was imported to current queue.
|
||||||
|
Current,
|
||||||
|
/// Transaction was imported to future queue.
|
||||||
|
Future
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Api-level error for transaction import
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum TransactionImportError {
|
||||||
|
/// Transaction error
|
||||||
|
Transaction(TransactionError),
|
||||||
|
/// Other error
|
||||||
|
Other(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Error> for TransactionImportError {
|
||||||
|
fn from(e: Error) -> Self {
|
||||||
|
match e {
|
||||||
|
Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error),
|
||||||
|
_ => TransactionImportError::Other(format!("other block import error: {:?}", e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// General error type which should be capable of representing all errors in ethcore.
|
/// General error type which should be capable of representing all errors in ethcore.
|
||||||
|
@ -19,7 +19,7 @@ use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager};
|
|||||||
use util::*;
|
use util::*;
|
||||||
use block::*;
|
use block::*;
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use error::{BlockError, Error, TransactionError};
|
use error::{BlockError, Error, TransactionError};
|
||||||
use header::{Header, BlockNumber};
|
use header::{Header, BlockNumber};
|
||||||
use state::CleanupMode;
|
use state::CleanupMode;
|
||||||
@ -29,7 +29,7 @@ use engines::{self, Engine};
|
|||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use rlp::{self, UntrustedRlp};
|
use rlp::{self, UntrustedRlp};
|
||||||
use env_info::LastHashes;
|
use evm::env_info::LastHashes;
|
||||||
|
|
||||||
/// Parity tries to round block.gas_limit to multiple of this constant
|
/// Parity tries to round block.gas_limit to multiple of this constant
|
||||||
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
|
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
|
||||||
@ -209,7 +209,8 @@ impl Engine for Arc<Ethash> {
|
|||||||
block_number >= self.ethash_params.eip160_transition,
|
block_number >= self.ethash_params.eip160_transition,
|
||||||
block_number >= self.ethash_params.eip161abc_transition,
|
block_number >= self.ethash_params.eip161abc_transition,
|
||||||
block_number >= self.ethash_params.eip161d_transition);
|
block_number >= self.ethash_params.eip161d_transition);
|
||||||
schedule.apply_params(block_number, self.params());
|
|
||||||
|
self.params().update_schedule(block_number, &mut schedule);
|
||||||
schedule
|
schedule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1027,7 +1028,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rejects_transactions_below_min_gas_price() {
|
fn rejects_transactions_below_min_gas_price() {
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use types::transaction::{Transaction, Action};
|
use transaction::{Transaction, Action};
|
||||||
|
|
||||||
let spec = new_homestead_test();
|
let spec = new_homestead_test();
|
||||||
let mut ethparams = get_default_ethash_params();
|
let mut ethparams = get_default_ethash_params();
|
||||||
|
@ -17,58 +17,15 @@
|
|||||||
//! Transaction execution format module.
|
//! Transaction execution format module.
|
||||||
|
|
||||||
use util::{Bytes, U256, Address, U512, trie};
|
use util::{Bytes, U256, Address, U512, trie};
|
||||||
use rlp::*;
|
|
||||||
use evm;
|
use evm;
|
||||||
use trace::{VMTrace, FlatTrace};
|
use trace::{VMTrace, FlatTrace};
|
||||||
use types::log_entry::LogEntry;
|
use log_entry::LogEntry;
|
||||||
use types::state_diff::StateDiff;
|
use state_diff::StateDiff;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// The type of the call-like instruction.
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum CallType {
|
|
||||||
/// Not a CALL.
|
|
||||||
None,
|
|
||||||
/// CALL.
|
|
||||||
Call,
|
|
||||||
/// CALLCODE.
|
|
||||||
CallCode,
|
|
||||||
/// DELEGATECALL.
|
|
||||||
DelegateCall,
|
|
||||||
/// STATICCALL
|
|
||||||
StaticCall,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for CallType {
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
Encodable::rlp_append(&v, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for CallType {
|
|
||||||
fn decode(rlp: &UntrustedRlp) -> 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")),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transaction execution receipt.
|
/// Transaction execution receipt.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct Executed {
|
pub struct Executed {
|
||||||
/// True if the outer call/create resulted in an exceptional exit.
|
/// True if the outer call/create resulted in an exceptional exit.
|
||||||
pub exception: Option<evm::Error>,
|
pub exception: Option<evm::Error>,
|
||||||
@ -112,7 +69,6 @@ pub struct Executed {
|
|||||||
|
|
||||||
/// Result of executing the transaction.
|
/// Result of executing the transaction.
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum ExecutionError {
|
pub enum ExecutionError {
|
||||||
/// Returned when there gas paid for transaction execution is
|
/// Returned when there gas paid for transaction execution is
|
||||||
/// lower than base gas required.
|
/// lower than base gas required.
|
||||||
@ -192,7 +148,6 @@ impl fmt::Display for ExecutionError {
|
|||||||
|
|
||||||
/// Result of executing the transaction.
|
/// Result of executing the transaction.
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum CallError {
|
pub enum CallError {
|
||||||
/// Couldn't find the transaction in the chain.
|
/// Couldn't find the transaction in the chain.
|
||||||
TransactionNotFound,
|
TransactionNotFound,
|
||||||
@ -230,29 +185,3 @@ impl fmt::Display for CallError {
|
|||||||
|
|
||||||
/// Transaction execution result.
|
/// Transaction execution result.
|
||||||
pub type ExecutionResult = Result<Executed, ExecutionError>;
|
pub type ExecutionResult = Result<Executed, ExecutionError>;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use rlp::*;
|
|
||||||
use super::CallType;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn encode_call_type() {
|
|
||||||
let ct = CallType::Call;
|
|
||||||
|
|
||||||
let mut s = RlpStream::new_list(2);
|
|
||||||
s.append(&ct);
|
|
||||||
assert!(!s.is_finished(), "List shouldn't finished yet");
|
|
||||||
s.append(&ct);
|
|
||||||
assert!(s.is_finished(), "List should be finished now");
|
|
||||||
s.out();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_encode_and_decode_call_type() {
|
|
||||||
let original = CallType::Call;
|
|
||||||
let encoded = encode(&original);
|
|
||||||
let decoded = decode(&encoded);
|
|
||||||
assert_eq!(original, decoded);
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,18 +16,18 @@
|
|||||||
|
|
||||||
//! Transaction Execution environment.
|
//! Transaction Execution environment.
|
||||||
use util::*;
|
use util::*;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use evm::action_params::{ActionParams, ActionValue};
|
||||||
use state::{Backend as StateBackend, State, Substate, CleanupMode};
|
use state::{Backend as StateBackend, State, Substate, CleanupMode};
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use error::ExecutionError;
|
use error::ExecutionError;
|
||||||
use evm::{self, wasm, Factory, Ext, Finalize, CreateContractAddress, FinalizationResult, ReturnData, CleanDustMode};
|
use evm::{self, wasm, Factory, Ext, Finalize, CreateContractAddress, FinalizationResult, ReturnData, CleanDustMode};
|
||||||
use externalities::*;
|
use externalities::*;
|
||||||
use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer};
|
use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer};
|
||||||
use transaction::{Action, SignedTransaction};
|
use transaction::{Action, SignedTransaction};
|
||||||
use crossbeam;
|
use crossbeam;
|
||||||
pub use types::executed::{Executed, ExecutionResult};
|
pub use executed::{Executed, ExecutionResult};
|
||||||
|
|
||||||
/// Roughly estimate what stack size each level of evm depth will use
|
/// Roughly estimate what stack size each level of evm depth will use
|
||||||
/// TODO [todr] We probably need some more sophisticated calculations here (limit on my machine 132)
|
/// TODO [todr] We probably need some more sophisticated calculations here (limit on my machine 132)
|
||||||
@ -602,8 +602,8 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use util::{H256, U256, U512, Address, FromStr};
|
use util::{H256, U256, U512, Address, FromStr};
|
||||||
use util::bytes::BytesRef;
|
use util::bytes::BytesRef;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use evm::action_params::{ActionParams, ActionValue};
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use evm::{Factory, VMType, CreateContractAddress};
|
use evm::{Factory, VMType, CreateContractAddress};
|
||||||
use error::ExecutionError;
|
use error::ExecutionError;
|
||||||
use state::{Substate, CleanupMode};
|
use state::{Substate, CleanupMode};
|
||||||
@ -613,7 +613,7 @@ mod tests {
|
|||||||
use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer};
|
use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer};
|
||||||
use transaction::{Action, Transaction};
|
use transaction::{Action, Transaction};
|
||||||
|
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_contract_address() {
|
fn test_contract_address() {
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
//! Transaction Execution environment.
|
//! Transaction Execution environment.
|
||||||
use util::*;
|
use util::*;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use evm::action_params::{ActionParams, ActionValue};
|
||||||
use state::{Backend as StateBackend, State, Substate, CleanupMode};
|
use state::{Backend as StateBackend, State, Substate, CleanupMode};
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use executive::*;
|
use executive::*;
|
||||||
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData};
|
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
use types::transaction::UNSIGNED_SENDER;
|
use transaction::UNSIGNED_SENDER;
|
||||||
use trace::{Tracer, VMTracer};
|
use trace::{Tracer, VMTracer};
|
||||||
|
|
||||||
/// Policy for handling output data on `RETURN` opcode.
|
/// Policy for handling output data on `RETURN` opcode.
|
||||||
@ -396,13 +396,13 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
|
|||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use evm::Ext;
|
use evm::Ext;
|
||||||
use state::{State, Substate};
|
use state::{State, Substate};
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use trace::{NoopTracer, NoopVMTracer};
|
use trace::{NoopTracer, NoopVMTracer};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
|
|
||||||
fn get_test_origin() -> OriginInfo {
|
fn get_test_origin() -> OriginInfo {
|
||||||
OriginInfo {
|
OriginInfo {
|
||||||
|
@ -25,8 +25,7 @@ use std::cell::RefCell;
|
|||||||
|
|
||||||
pub use basic_types::Seal;
|
pub use basic_types::Seal;
|
||||||
|
|
||||||
/// Type for Block number
|
pub use types::BlockNumber;
|
||||||
pub type BlockNumber = u64;
|
|
||||||
|
|
||||||
/// A block header.
|
/// A block header.
|
||||||
///
|
///
|
||||||
|
@ -15,15 +15,15 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use super::test_common::*;
|
use super::test_common::*;
|
||||||
use action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
use state::{Backend as StateBackend, State, Substate};
|
use state::{Backend as StateBackend, State, Substate};
|
||||||
use executive::*;
|
use executive::*;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use evm;
|
use evm;
|
||||||
use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData};
|
use evm::{Schedule, Ext, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData};
|
||||||
use externalities::*;
|
use externalities::*;
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use trace::{Tracer, NoopTracer};
|
use trace::{Tracer, NoopTracer};
|
||||||
|
@ -21,8 +21,8 @@ use ethereum;
|
|||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use ethjson::state::test::ForkSpec;
|
use ethjson::state::test::ForkSpec;
|
||||||
use types::transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref FRONTIER: Spec = ethereum::new_frontier_test();
|
pub static ref FRONTIER: Spec = ethereum::new_frontier_test();
|
||||||
|
@ -76,6 +76,7 @@ extern crate bloomchain;
|
|||||||
extern crate bn;
|
extern crate bn;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate crossbeam;
|
extern crate crossbeam;
|
||||||
|
extern crate common_types as types;
|
||||||
extern crate crypto;
|
extern crate crypto;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate ethabi;
|
extern crate ethabi;
|
||||||
@ -105,8 +106,6 @@ extern crate semver;
|
|||||||
extern crate stats;
|
extern crate stats;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate transient_hashmap;
|
extern crate transient_hashmap;
|
||||||
extern crate parity_wasm;
|
|
||||||
extern crate wasm_utils;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
@ -116,6 +115,8 @@ extern crate ethcore_util as util;
|
|||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate ethcore_ipc as ipc;
|
extern crate ethcore_ipc as ipc;
|
||||||
|
#[cfg_attr(test, macro_use)]
|
||||||
|
extern crate evm;
|
||||||
|
|
||||||
#[cfg(feature = "jit" )]
|
#[cfg(feature = "jit" )]
|
||||||
extern crate evmjit;
|
extern crate evmjit;
|
||||||
@ -123,26 +124,26 @@ extern crate evmjit;
|
|||||||
pub extern crate ethstore;
|
pub extern crate ethstore;
|
||||||
|
|
||||||
pub mod account_provider;
|
pub mod account_provider;
|
||||||
pub mod engines;
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
|
pub mod db;
|
||||||
|
pub mod encoded;
|
||||||
|
pub mod engines;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod ethereum;
|
pub mod ethereum;
|
||||||
|
pub mod executed;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
pub mod service;
|
|
||||||
pub mod trace;
|
|
||||||
pub mod spec;
|
|
||||||
pub mod views;
|
|
||||||
pub mod pod_state;
|
|
||||||
pub mod migrations;
|
pub mod migrations;
|
||||||
pub mod miner;
|
pub mod miner;
|
||||||
|
pub mod pod_state;
|
||||||
|
pub mod service;
|
||||||
pub mod snapshot;
|
pub mod snapshot;
|
||||||
pub mod action_params;
|
pub mod spec;
|
||||||
pub mod db;
|
|
||||||
pub mod verification;
|
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod env_info;
|
pub mod trace;
|
||||||
#[macro_use] pub mod evm;
|
pub mod transaction;
|
||||||
|
pub mod verification;
|
||||||
|
pub mod views;
|
||||||
|
|
||||||
mod cache_manager;
|
mod cache_manager;
|
||||||
mod blooms;
|
mod blooms;
|
||||||
@ -154,7 +155,6 @@ mod builtin;
|
|||||||
mod executive;
|
mod executive;
|
||||||
mod externalities;
|
mod externalities;
|
||||||
mod blockchain;
|
mod blockchain;
|
||||||
mod types;
|
|
||||||
mod factory;
|
mod factory;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -98,6 +98,8 @@ pub struct MinerOptions {
|
|||||||
pub tx_gas_limit: U256,
|
pub tx_gas_limit: U256,
|
||||||
/// Maximum size of the transaction queue.
|
/// Maximum size of the transaction queue.
|
||||||
pub tx_queue_size: usize,
|
pub tx_queue_size: usize,
|
||||||
|
/// Maximum memory usage of transactions in the queue (current / future).
|
||||||
|
pub tx_queue_memory_limit: Option<usize>,
|
||||||
/// Strategy to use for prioritizing transactions in the queue.
|
/// Strategy to use for prioritizing transactions in the queue.
|
||||||
pub tx_queue_strategy: PrioritizationStrategy,
|
pub tx_queue_strategy: PrioritizationStrategy,
|
||||||
/// Whether we should fallback to providing all the queue's transactions or just pending.
|
/// Whether we should fallback to providing all the queue's transactions or just pending.
|
||||||
@ -123,8 +125,9 @@ impl Default for MinerOptions {
|
|||||||
reseal_on_own_tx: true,
|
reseal_on_own_tx: true,
|
||||||
reseal_on_uncle: false,
|
reseal_on_uncle: false,
|
||||||
tx_gas_limit: !U256::zero(),
|
tx_gas_limit: !U256::zero(),
|
||||||
tx_queue_size: 1024,
|
tx_queue_size: 8192,
|
||||||
tx_queue_gas_limit: GasLimit::Auto,
|
tx_queue_memory_limit: Some(2 * 1024 * 1024),
|
||||||
|
tx_queue_gas_limit: GasLimit::None,
|
||||||
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
|
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
|
||||||
pending_set: PendingSet::AlwaysQueue,
|
pending_set: PendingSet::AlwaysQueue,
|
||||||
reseal_min_period: Duration::from_secs(2),
|
reseal_min_period: Duration::from_secs(2),
|
||||||
@ -252,8 +255,15 @@ impl Miner {
|
|||||||
GasLimit::Fixed(ref limit) => *limit,
|
GasLimit::Fixed(ref limit) => *limit,
|
||||||
_ => !U256::zero(),
|
_ => !U256::zero(),
|
||||||
};
|
};
|
||||||
|
let mem_limit = options.tx_queue_memory_limit.unwrap_or_else(usize::max_value);
|
||||||
|
|
||||||
let txq = TransactionQueue::with_limits(options.tx_queue_strategy, options.tx_queue_size, gas_limit, options.tx_gas_limit);
|
let txq = TransactionQueue::with_limits(
|
||||||
|
options.tx_queue_strategy,
|
||||||
|
options.tx_queue_size,
|
||||||
|
mem_limit,
|
||||||
|
gas_limit,
|
||||||
|
options.tx_gas_limit
|
||||||
|
);
|
||||||
let txq = match options.tx_queue_banning {
|
let txq = match options.tx_queue_banning {
|
||||||
Banning::Disabled => BanningTransactionQueue::new(txq, Threshold::NeverBan, Duration::from_secs(180)),
|
Banning::Disabled => BanningTransactionQueue::new(txq, Threshold::NeverBan, Duration::from_secs(180)),
|
||||||
Banning::Enabled { ban_duration, min_offends, .. } => BanningTransactionQueue::new(
|
Banning::Enabled { ban_duration, min_offends, .. } => BanningTransactionQueue::new(
|
||||||
@ -804,9 +814,15 @@ impl MinerService for Miner {
|
|||||||
// | Make sure to release the locks before calling that method. |
|
// | Make sure to release the locks before calling that method. |
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
self.engine.set_signer(ap.clone(), address, password);
|
self.engine.set_signer(ap.clone(), address, password);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
warn!(target: "miner", "No account provider");
|
||||||
|
Err(AccountError::NotFound)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
warn!(target: "miner", "Cannot set engine signer on a PoW chain.");
|
||||||
|
Err(AccountError::InappropriateChain)
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_extra_data(&self, extra_data: Bytes) {
|
fn set_extra_data(&self, extra_data: Bytes) {
|
||||||
@ -1085,6 +1101,10 @@ impl MinerService for Miner {
|
|||||||
self.transaction_queue.read().last_nonce(address)
|
self.transaction_queue.read().last_nonce(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_produce_work_package(&self) -> bool {
|
||||||
|
self.engine.seals_internally().is_none()
|
||||||
|
}
|
||||||
|
|
||||||
/// Update sealing if required.
|
/// Update sealing if required.
|
||||||
/// Prepare the block and work if the Engine does not seal internally.
|
/// Prepare the block and work if the Engine does not seal internally.
|
||||||
fn update_sealing(&self, chain: &MiningBlockChainClient) {
|
fn update_sealing(&self, chain: &MiningBlockChainClient) {
|
||||||
@ -1113,7 +1133,7 @@ impl MinerService for Miner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_sealing(&self) -> bool {
|
fn is_currently_sealing(&self) -> bool {
|
||||||
self.sealing_work.lock().queue.is_in_use()
|
self.sealing_work.lock().queue.is_in_use()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1270,9 +1290,9 @@ mod tests {
|
|||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
|
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use types::transaction::{SignedTransaction, Transaction, PendingTransaction, Action};
|
use transaction::{SignedTransaction, Transaction, PendingTransaction, Action};
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use tests::helpers::{generate_dummy_client};
|
use tests::helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_prepare_block_to_seal() {
|
fn should_prepare_block_to_seal() {
|
||||||
@ -1318,6 +1338,7 @@ mod tests {
|
|||||||
reseal_max_period: Duration::from_secs(120),
|
reseal_max_period: Duration::from_secs(120),
|
||||||
tx_gas_limit: !U256::zero(),
|
tx_gas_limit: !U256::zero(),
|
||||||
tx_queue_size: 1024,
|
tx_queue_size: 1024,
|
||||||
|
tx_queue_memory_limit: None,
|
||||||
tx_queue_gas_limit: GasLimit::None,
|
tx_queue_gas_limit: GasLimit::None,
|
||||||
tx_queue_strategy: PrioritizationStrategy::GasFactorAndGasPrice,
|
tx_queue_strategy: PrioritizationStrategy::GasFactorAndGasPrice,
|
||||||
pending_set: PendingSet::AlwaysSealing,
|
pending_set: PendingSet::AlwaysSealing,
|
||||||
@ -1440,4 +1461,22 @@ mod tests {
|
|||||||
assert!(miner.pending_block().is_none());
|
assert!(miner.pending_block().is_none());
|
||||||
assert_eq!(client.chain_info().best_block_number, 4 as BlockNumber);
|
assert_eq!(client.chain_info().best_block_number, 4 as BlockNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_fail_setting_engine_signer_on_pow() {
|
||||||
|
let spec = Spec::new_pow_test_spec;
|
||||||
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
|
let addr = tap.insert_account("1".sha3().into(), "").unwrap();
|
||||||
|
let client = generate_dummy_client_with_spec_and_accounts(spec, Some(tap.clone()));
|
||||||
|
assert!(match client.miner().set_engine_signer(addr, "".into()) { Err(AccountError::InappropriateChain) => true, _ => false })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_fail_setting_engine_signer_without_account_provider() {
|
||||||
|
let spec = Spec::new_instant;
|
||||||
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
|
let addr = tap.insert_account("1".sha3().into(), "").unwrap();
|
||||||
|
let client = generate_dummy_client_with_spec_and_accounts(spec, None);
|
||||||
|
assert!(match client.miner().set_engine_signer(addr, "".into()) { Err(AccountError::NotFound) => true, _ => false });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,6 +136,9 @@ pub trait MinerService : Send + Sync {
|
|||||||
/// Called when blocks are imported to chain, updates transactions queue.
|
/// Called when blocks are imported to chain, updates transactions queue.
|
||||||
fn chain_new_blocks(&self, chain: &MiningBlockChainClient, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256]);
|
fn chain_new_blocks(&self, chain: &MiningBlockChainClient, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256]);
|
||||||
|
|
||||||
|
/// PoW chain - can produce work package
|
||||||
|
fn can_produce_work_package(&self) -> bool;
|
||||||
|
|
||||||
/// New chain head event. Restart mining operation.
|
/// New chain head event. Restart mining operation.
|
||||||
fn update_sealing(&self, chain: &MiningBlockChainClient);
|
fn update_sealing(&self, chain: &MiningBlockChainClient);
|
||||||
|
|
||||||
@ -176,7 +179,7 @@ pub trait MinerService : Send + Sync {
|
|||||||
fn last_nonce(&self, address: &Address) -> Option<U256>;
|
fn last_nonce(&self, address: &Address) -> Option<U256>;
|
||||||
|
|
||||||
/// Is it currently sealing?
|
/// Is it currently sealing?
|
||||||
fn is_sealing(&self) -> bool;
|
fn is_currently_sealing(&self) -> bool;
|
||||||
|
|
||||||
/// Suggested gas price.
|
/// Suggested gas price.
|
||||||
fn sensible_gas_price(&self) -> U256;
|
fn sensible_gas_price(&self) -> U256;
|
||||||
|
@ -105,7 +105,7 @@ use std::cmp::Ordering;
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap};
|
use std::collections::{HashSet, HashMap, BTreeSet, BTreeMap};
|
||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
use util::{Address, H256, U256};
|
use util::{Address, H256, U256, HeapSizeOf};
|
||||||
use util::table::Table;
|
use util::table::Table;
|
||||||
use transaction::*;
|
use transaction::*;
|
||||||
use error::{Error, TransactionError};
|
use error::{Error, TransactionError};
|
||||||
@ -171,6 +171,8 @@ struct TransactionOrder {
|
|||||||
/// Gas (limit) of the transaction. Usage depends on strategy.
|
/// Gas (limit) of the transaction. Usage depends on strategy.
|
||||||
/// Low gas limit = High priority (processed earlier)
|
/// Low gas limit = High priority (processed earlier)
|
||||||
gas: U256,
|
gas: U256,
|
||||||
|
/// Heap usage of this transaction.
|
||||||
|
mem_usage: usize,
|
||||||
/// Transaction ordering strategy
|
/// Transaction ordering strategy
|
||||||
strategy: PrioritizationStrategy,
|
strategy: PrioritizationStrategy,
|
||||||
/// Hash to identify associated transaction
|
/// Hash to identify associated transaction
|
||||||
@ -191,8 +193,9 @@ impl TransactionOrder {
|
|||||||
TransactionOrder {
|
TransactionOrder {
|
||||||
nonce_height: tx.nonce() - base_nonce,
|
nonce_height: tx.nonce() - base_nonce,
|
||||||
gas_price: tx.transaction.gas_price,
|
gas_price: tx.transaction.gas_price,
|
||||||
gas: tx.transaction.gas,
|
|
||||||
gas_factor: factor,
|
gas_factor: factor,
|
||||||
|
gas: tx.transaction.gas,
|
||||||
|
mem_usage: tx.transaction.heap_size_of_children(),
|
||||||
strategy: strategy,
|
strategy: strategy,
|
||||||
hash: tx.hash(),
|
hash: tx.hash(),
|
||||||
insertion_id: tx.insertion_id,
|
insertion_id: tx.insertion_id,
|
||||||
@ -370,7 +373,8 @@ struct TransactionSet {
|
|||||||
by_address: Table<Address, U256, TransactionOrder>,
|
by_address: Table<Address, U256, TransactionOrder>,
|
||||||
by_gas_price: GasPriceQueue,
|
by_gas_price: GasPriceQueue,
|
||||||
limit: usize,
|
limit: usize,
|
||||||
gas_limit: U256,
|
total_gas_limit: U256,
|
||||||
|
memory_limit: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionSet {
|
impl TransactionSet {
|
||||||
@ -402,18 +406,24 @@ impl TransactionSet {
|
|||||||
/// Returns addresses and lowest nonces of transactions removed because of limit.
|
/// Returns addresses and lowest nonces of transactions removed because of limit.
|
||||||
fn enforce_limit(&mut self, by_hash: &mut HashMap<H256, VerifiedTransaction>, local: &mut LocalTransactionsList) -> Option<HashMap<Address, U256>> {
|
fn enforce_limit(&mut self, by_hash: &mut HashMap<H256, VerifiedTransaction>, local: &mut LocalTransactionsList) -> Option<HashMap<Address, U256>> {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
|
let mut mem_usage = 0;
|
||||||
let mut gas: U256 = 0.into();
|
let mut gas: U256 = 0.into();
|
||||||
let to_drop : Vec<(Address, U256)> = {
|
let to_drop : Vec<(Address, U256)> = {
|
||||||
self.by_priority
|
self.by_priority
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|order| {
|
.filter(|order| {
|
||||||
count = count + 1;
|
// update transaction count and mem usage
|
||||||
|
count += 1;
|
||||||
|
mem_usage += order.mem_usage;
|
||||||
|
|
||||||
|
// calculate current gas usage
|
||||||
let r = gas.overflowing_add(order.gas);
|
let r = gas.overflowing_add(order.gas);
|
||||||
if r.1 { return false }
|
if r.1 { return false }
|
||||||
gas = r.0;
|
gas = r.0;
|
||||||
|
|
||||||
|
let is_own_or_retracted = order.origin.is_local() || order.origin == TransactionOrigin::RetractedBlock;
|
||||||
// Own and retracted transactions are allowed to go above all limits.
|
// Own and retracted transactions are allowed to go above all limits.
|
||||||
order.origin != TransactionOrigin::Local && order.origin != TransactionOrigin::RetractedBlock &&
|
!is_own_or_retracted && (mem_usage > self.memory_limit || count > self.limit || gas > self.total_gas_limit)
|
||||||
(gas > self.gas_limit || count > self.limit)
|
|
||||||
})
|
})
|
||||||
.map(|order| by_hash.get(&order.hash)
|
.map(|order| by_hash.get(&order.hash)
|
||||||
.expect("All transactions in `self.by_priority` and `self.by_address` are kept in sync with `by_hash`."))
|
.expect("All transactions in `self.by_priority` and `self.by_address` are kept in sync with `by_hash`."))
|
||||||
@ -502,6 +512,10 @@ const GAS_LIMIT_HYSTERESIS: usize = 200; // (100/GAS_LIMIT_HYSTERESIS) %
|
|||||||
/// `new_gas_price > old_gas_price + old_gas_price >> SHIFT`
|
/// `new_gas_price > old_gas_price + old_gas_price >> SHIFT`
|
||||||
const GAS_PRICE_BUMP_SHIFT: usize = 3; // 2 = 25%, 3 = 12.5%, 4 = 6.25%
|
const GAS_PRICE_BUMP_SHIFT: usize = 3; // 2 = 25%, 3 = 12.5%, 4 = 6.25%
|
||||||
|
|
||||||
|
/// Future queue limits are lower from current queue limits:
|
||||||
|
/// `future_limit = current_limit >> SHIFT`
|
||||||
|
const FUTURE_QUEUE_LIMITS_SHIFT: usize = 3; // 2 = 25%, 3 = 12.5%, 4 = 6.25%
|
||||||
|
|
||||||
/// Describes the strategy used to prioritize transactions in the queue.
|
/// Describes the strategy used to prioritize transactions in the queue.
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
@ -557,7 +571,7 @@ pub struct TransactionQueue {
|
|||||||
/// The maximum amount of gas any individual transaction may use.
|
/// The maximum amount of gas any individual transaction may use.
|
||||||
tx_gas_limit: U256,
|
tx_gas_limit: U256,
|
||||||
/// Current gas limit (block gas limit * factor). Transactions above the limit will not be accepted (default to !0)
|
/// Current gas limit (block gas limit * factor). Transactions above the limit will not be accepted (default to !0)
|
||||||
gas_limit: U256,
|
total_gas_limit: U256,
|
||||||
/// Maximal time transaction may occupy the queue.
|
/// Maximal time transaction may occupy the queue.
|
||||||
/// When we reach `max_time_in_queue / 2^3` we re-validate
|
/// When we reach `max_time_in_queue / 2^3` we re-validate
|
||||||
/// account balance.
|
/// account balance.
|
||||||
@ -585,35 +599,43 @@ impl Default for TransactionQueue {
|
|||||||
impl TransactionQueue {
|
impl TransactionQueue {
|
||||||
/// Creates new instance of this Queue
|
/// Creates new instance of this Queue
|
||||||
pub fn new(strategy: PrioritizationStrategy) -> Self {
|
pub fn new(strategy: PrioritizationStrategy) -> Self {
|
||||||
Self::with_limits(strategy, 1024, !U256::zero(), !U256::zero())
|
Self::with_limits(strategy, 8192, usize::max_value(), !U256::zero(), !U256::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new instance of this Queue with specified limits
|
/// Create new instance of this Queue with specified limits
|
||||||
pub fn with_limits(strategy: PrioritizationStrategy, limit: usize, gas_limit: U256, tx_gas_limit: U256) -> Self {
|
pub fn with_limits(
|
||||||
|
strategy: PrioritizationStrategy,
|
||||||
|
limit: usize,
|
||||||
|
memory_limit: usize,
|
||||||
|
total_gas_limit: U256,
|
||||||
|
tx_gas_limit: U256,
|
||||||
|
) -> Self {
|
||||||
let current = TransactionSet {
|
let current = TransactionSet {
|
||||||
by_priority: BTreeSet::new(),
|
by_priority: BTreeSet::new(),
|
||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
by_gas_price: Default::default(),
|
by_gas_price: Default::default(),
|
||||||
limit: limit,
|
limit,
|
||||||
gas_limit: gas_limit,
|
total_gas_limit,
|
||||||
|
memory_limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
let future = TransactionSet {
|
let future = TransactionSet {
|
||||||
by_priority: BTreeSet::new(),
|
by_priority: BTreeSet::new(),
|
||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
by_gas_price: Default::default(),
|
by_gas_price: Default::default(),
|
||||||
limit: limit,
|
total_gas_limit: total_gas_limit >> FUTURE_QUEUE_LIMITS_SHIFT,
|
||||||
gas_limit: gas_limit,
|
limit: limit >> FUTURE_QUEUE_LIMITS_SHIFT,
|
||||||
|
memory_limit: memory_limit >> FUTURE_QUEUE_LIMITS_SHIFT,
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionQueue {
|
TransactionQueue {
|
||||||
strategy: strategy,
|
strategy,
|
||||||
minimal_gas_price: U256::zero(),
|
minimal_gas_price: U256::zero(),
|
||||||
tx_gas_limit: tx_gas_limit,
|
total_gas_limit: !U256::zero(),
|
||||||
gas_limit: !U256::zero(),
|
tx_gas_limit,
|
||||||
max_time_in_queue: DEFAULT_QUEUING_PERIOD,
|
max_time_in_queue: DEFAULT_QUEUING_PERIOD,
|
||||||
current: current,
|
current,
|
||||||
future: future,
|
future,
|
||||||
by_hash: HashMap::new(),
|
by_hash: HashMap::new(),
|
||||||
last_nonces: HashMap::new(),
|
last_nonces: HashMap::new(),
|
||||||
local_transactions: LocalTransactionsList::default(),
|
local_transactions: LocalTransactionsList::default(),
|
||||||
@ -624,7 +646,7 @@ impl TransactionQueue {
|
|||||||
/// Set the new limit for `current` and `future` queue.
|
/// Set the new limit for `current` and `future` queue.
|
||||||
pub fn set_limit(&mut self, limit: usize) {
|
pub fn set_limit(&mut self, limit: usize) {
|
||||||
self.current.set_limit(limit);
|
self.current.set_limit(limit);
|
||||||
self.future.set_limit(limit);
|
self.future.set_limit(limit >> FUTURE_QUEUE_LIMITS_SHIFT);
|
||||||
// And ensure the limits
|
// And ensure the limits
|
||||||
self.current.enforce_limit(&mut self.by_hash, &mut self.local_transactions);
|
self.current.enforce_limit(&mut self.by_hash, &mut self.local_transactions);
|
||||||
self.future.enforce_limit(&mut self.by_hash, &mut self.local_transactions);
|
self.future.enforce_limit(&mut self.by_hash, &mut self.local_transactions);
|
||||||
@ -657,16 +679,17 @@ impl TransactionQueue {
|
|||||||
pub fn set_gas_limit(&mut self, gas_limit: U256) {
|
pub fn set_gas_limit(&mut self, gas_limit: U256) {
|
||||||
let extra = gas_limit / U256::from(GAS_LIMIT_HYSTERESIS);
|
let extra = gas_limit / U256::from(GAS_LIMIT_HYSTERESIS);
|
||||||
|
|
||||||
self.gas_limit = match gas_limit.overflowing_add(extra) {
|
let total_gas_limit = match gas_limit.overflowing_add(extra) {
|
||||||
(_, true) => !U256::zero(),
|
(_, true) => !U256::zero(),
|
||||||
(val, false) => val,
|
(val, false) => val,
|
||||||
};
|
};
|
||||||
|
self.total_gas_limit = total_gas_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets new total gas limit.
|
/// Sets new total gas limit.
|
||||||
pub fn set_total_gas_limit(&mut self, gas_limit: U256) {
|
pub fn set_total_gas_limit(&mut self, total_gas_limit: U256) {
|
||||||
self.future.gas_limit = gas_limit;
|
self.current.total_gas_limit = total_gas_limit;
|
||||||
self.current.gas_limit = gas_limit;
|
self.future.total_gas_limit = total_gas_limit >> FUTURE_QUEUE_LIMITS_SHIFT;
|
||||||
self.future.enforce_limit(&mut self.by_hash, &mut self.local_transactions);
|
self.future.enforce_limit(&mut self.by_hash, &mut self.local_transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,16 +819,17 @@ impl TransactionQueue {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if tx.gas > self.gas_limit || tx.gas > self.tx_gas_limit {
|
let gas_limit = cmp::min(self.tx_gas_limit, self.total_gas_limit);
|
||||||
|
if tx.gas > gas_limit {
|
||||||
trace!(target: "txqueue",
|
trace!(target: "txqueue",
|
||||||
"Dropping transaction above gas limit: {:?} ({} > min({}, {}))",
|
"Dropping transaction above gas limit: {:?} ({} > min({}, {}))",
|
||||||
tx.hash(),
|
tx.hash(),
|
||||||
tx.gas,
|
tx.gas,
|
||||||
self.gas_limit,
|
self.total_gas_limit,
|
||||||
self.tx_gas_limit
|
self.tx_gas_limit
|
||||||
);
|
);
|
||||||
return Err(Error::Transaction(TransactionError::GasLimitExceeded {
|
return Err(Error::Transaction(TransactionError::GasLimitExceeded {
|
||||||
limit: self.gas_limit,
|
limit: gas_limit,
|
||||||
got: tx.gas,
|
got: tx.gas,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -1591,7 +1615,13 @@ pub mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_return_correct_nonces_when_dropped_because_of_limit() {
|
fn should_return_correct_nonces_when_dropped_because_of_limit() {
|
||||||
// given
|
// given
|
||||||
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 2, !U256::zero(), !U256::zero());
|
let mut txq = TransactionQueue::with_limits(
|
||||||
|
PrioritizationStrategy::GasPriceOnly,
|
||||||
|
2,
|
||||||
|
usize::max_value(),
|
||||||
|
!U256::zero(),
|
||||||
|
!U256::zero(),
|
||||||
|
);
|
||||||
let (tx1, tx2) = new_tx_pair(123.into(), 1.into(), 1.into(), 0.into());
|
let (tx1, tx2) = new_tx_pair(123.into(), 1.into(), 1.into(), 0.into());
|
||||||
let sender = tx1.sender();
|
let sender = tx1.sender();
|
||||||
let nonce = tx1.nonce;
|
let nonce = tx1.nonce;
|
||||||
@ -1631,7 +1661,8 @@ pub mod test {
|
|||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
by_gas_price: Default::default(),
|
by_gas_price: Default::default(),
|
||||||
limit: 1,
|
limit: 1,
|
||||||
gas_limit: !U256::zero(),
|
total_gas_limit: !U256::zero(),
|
||||||
|
memory_limit: usize::max_value(),
|
||||||
};
|
};
|
||||||
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
let tx1 = VerifiedTransaction::new(tx1, TransactionOrigin::External, None, 0, 0);
|
let tx1 = VerifiedTransaction::new(tx1, TransactionOrigin::External, None, 0, 0);
|
||||||
@ -1672,7 +1703,8 @@ pub mod test {
|
|||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
by_gas_price: Default::default(),
|
by_gas_price: Default::default(),
|
||||||
limit: 1,
|
limit: 1,
|
||||||
gas_limit: !U256::zero(),
|
total_gas_limit: !U256::zero(),
|
||||||
|
memory_limit: 0,
|
||||||
};
|
};
|
||||||
// Create two transactions with same nonce
|
// Create two transactions with same nonce
|
||||||
// (same hash)
|
// (same hash)
|
||||||
@ -1721,7 +1753,8 @@ pub mod test {
|
|||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
by_gas_price: Default::default(),
|
by_gas_price: Default::default(),
|
||||||
limit: 2,
|
limit: 2,
|
||||||
gas_limit: !U256::zero(),
|
total_gas_limit: !U256::zero(),
|
||||||
|
memory_limit: 0,
|
||||||
};
|
};
|
||||||
let tx = new_tx_default();
|
let tx = new_tx_default();
|
||||||
let tx1 = VerifiedTransaction::new(tx.clone(), TransactionOrigin::External, None, 0, 0);
|
let tx1 = VerifiedTransaction::new(tx.clone(), TransactionOrigin::External, None, 0, 0);
|
||||||
@ -1739,7 +1772,8 @@ pub mod test {
|
|||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
by_gas_price: Default::default(),
|
by_gas_price: Default::default(),
|
||||||
limit: 1,
|
limit: 1,
|
||||||
gas_limit: !U256::zero(),
|
total_gas_limit: !U256::zero(),
|
||||||
|
memory_limit: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(set.gas_price_entry_limit(), 0.into());
|
assert_eq!(set.gas_price_entry_limit(), 0.into());
|
||||||
@ -1884,17 +1918,17 @@ pub mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn gas_limit_should_never_overflow() {
|
fn tx_gas_limit_should_never_overflow() {
|
||||||
// given
|
// given
|
||||||
let mut txq = TransactionQueue::default();
|
let mut txq = TransactionQueue::default();
|
||||||
txq.set_gas_limit(U256::zero());
|
txq.set_gas_limit(U256::zero());
|
||||||
assert_eq!(txq.gas_limit, U256::zero());
|
assert_eq!(txq.total_gas_limit, U256::zero());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.set_gas_limit(!U256::zero());
|
txq.set_gas_limit(!U256::zero());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(txq.gas_limit, !U256::zero());
|
assert_eq!(txq.total_gas_limit, !U256::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -2352,7 +2386,13 @@ pub mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_drop_old_transactions_when_hitting_the_limit() {
|
fn should_drop_old_transactions_when_hitting_the_limit() {
|
||||||
// given
|
// given
|
||||||
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 1, !U256::zero(), !U256::zero());
|
let mut txq = TransactionQueue::with_limits(
|
||||||
|
PrioritizationStrategy::GasPriceOnly,
|
||||||
|
1,
|
||||||
|
usize::max_value(),
|
||||||
|
!U256::zero(),
|
||||||
|
!U256::zero()
|
||||||
|
);
|
||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
let sender = tx.sender();
|
let sender = tx.sender();
|
||||||
let nonce = tx.nonce;
|
let nonce = tx.nonce;
|
||||||
@ -2373,7 +2413,13 @@ pub mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_limit_future_transactions() {
|
fn should_limit_future_transactions() {
|
||||||
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 1, !U256::zero(), !U256::zero());
|
let mut txq = TransactionQueue::with_limits(
|
||||||
|
PrioritizationStrategy::GasPriceOnly,
|
||||||
|
1 << FUTURE_QUEUE_LIMITS_SHIFT,
|
||||||
|
usize::max_value(),
|
||||||
|
!U256::zero(),
|
||||||
|
!U256::zero(),
|
||||||
|
);
|
||||||
txq.current.set_limit(10);
|
txq.current.set_limit(10);
|
||||||
let (tx1, tx2) = new_tx_pair_default(4.into(), 1.into());
|
let (tx1, tx2) = new_tx_pair_default(4.into(), 1.into());
|
||||||
let (tx3, tx4) = new_tx_pair_default(4.into(), 2.into());
|
let (tx3, tx4) = new_tx_pair_default(4.into(), 2.into());
|
||||||
@ -2392,7 +2438,13 @@ pub mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_limit_by_gas() {
|
fn should_limit_by_gas() {
|
||||||
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
|
let mut txq = TransactionQueue::with_limits(
|
||||||
|
PrioritizationStrategy::GasPriceOnly,
|
||||||
|
100,
|
||||||
|
usize::max_value(),
|
||||||
|
default_gas_val() * U256::from(2),
|
||||||
|
!U256::zero()
|
||||||
|
);
|
||||||
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
||||||
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
||||||
txq.add(tx1.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, 0, None, &default_tx_provider()).unwrap();
|
||||||
@ -2405,7 +2457,13 @@ pub mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_keep_own_transactions_above_gas_limit() {
|
fn should_keep_own_transactions_above_gas_limit() {
|
||||||
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
|
let mut txq = TransactionQueue::with_limits(
|
||||||
|
PrioritizationStrategy::GasPriceOnly,
|
||||||
|
100,
|
||||||
|
usize::max_value(),
|
||||||
|
default_gas_val() * U256::from(2),
|
||||||
|
!U256::zero()
|
||||||
|
);
|
||||||
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
||||||
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
||||||
let (tx5, _) = new_tx_pair_default(U256::from(1), U256::from(2));
|
let (tx5, _) = new_tx_pair_default(U256::from(1), U256::from(2));
|
||||||
@ -2679,7 +2737,13 @@ pub mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_keep_right_order_in_future() {
|
fn should_keep_right_order_in_future() {
|
||||||
// given
|
// given
|
||||||
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 1, !U256::zero(), !U256::zero());
|
let mut txq = TransactionQueue::with_limits(
|
||||||
|
PrioritizationStrategy::GasPriceOnly,
|
||||||
|
1 << FUTURE_QUEUE_LIMITS_SHIFT,
|
||||||
|
usize::max_value(),
|
||||||
|
!U256::zero(),
|
||||||
|
!U256::zero()
|
||||||
|
);
|
||||||
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
let prev_nonce = default_account_details().nonce - U256::one();
|
let prev_nonce = default_account_details().nonce - U256::one();
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ mod tests {
|
|||||||
use views::BlockView;
|
use views::BlockView;
|
||||||
use block::Block;
|
use block::Block;
|
||||||
use super::AbridgedBlock;
|
use super::AbridgedBlock;
|
||||||
use types::transaction::{Action, Transaction};
|
use transaction::{Action, Transaction};
|
||||||
|
|
||||||
use util::{Address, H256, U256, Bytes};
|
use util::{Address, H256, U256, Bytes};
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ use rustc_hex::FromHex;
|
|||||||
use super::genesis::Genesis;
|
use super::genesis::Genesis;
|
||||||
use super::seal::Generic as GenericSeal;
|
use super::seal::Generic as GenericSeal;
|
||||||
|
|
||||||
use action_params::{ActionValue, ActionParams};
|
use evm::action_params::{ActionValue, ActionParams};
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT};
|
use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT};
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use ethereum;
|
use ethereum;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
@ -36,7 +36,7 @@ use state_db::StateDB;
|
|||||||
use state::{Backend, State, Substate};
|
use state::{Backend, State, Substate};
|
||||||
use state::backend::Basic as BasicBackend;
|
use state::backend::Basic as BasicBackend;
|
||||||
use trace::{NoopTracer, NoopVMTracer};
|
use trace::{NoopTracer, NoopVMTracer};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
use util::*;
|
use util::*;
|
||||||
|
|
||||||
/// Parameters common to all engines.
|
/// Parameters common to all engines.
|
||||||
@ -87,6 +87,31 @@ pub struct CommonParams {
|
|||||||
pub wasm: bool,
|
pub wasm: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CommonParams {
|
||||||
|
/// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net.
|
||||||
|
pub fn schedule(&self, block_number: u64) -> ::evm::Schedule {
|
||||||
|
let mut schedule = ::evm::Schedule::new_post_eip150(usize::max_value(), true, true, true);
|
||||||
|
self.update_schedule(block_number, &mut schedule);
|
||||||
|
schedule
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply common spec config parameters to the schedule.
|
||||||
|
pub fn update_schedule(&self, block_number: u64, schedule: &mut ::evm::Schedule) {
|
||||||
|
schedule.have_create2 = block_number >= self.eip86_transition;
|
||||||
|
schedule.have_revert = block_number >= self.eip140_transition;
|
||||||
|
schedule.have_static_call = block_number >= self.eip214_transition;
|
||||||
|
if block_number >= self.eip210_transition {
|
||||||
|
schedule.blockhash_gas = 350;
|
||||||
|
}
|
||||||
|
if block_number >= self.dust_protection_transition {
|
||||||
|
schedule.kill_dust = match self.remove_dust_contracts {
|
||||||
|
true => ::evm::CleanDustMode::WithCodeAndStorage,
|
||||||
|
false => ::evm::CleanDustMode::BasicOnly,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ethjson::spec::Params> for CommonParams {
|
impl From<ethjson::spec::Params> for CommonParams {
|
||||||
fn from(p: ethjson::spec::Params) -> Self {
|
fn from(p: ethjson::spec::Params) -> Self {
|
||||||
CommonParams {
|
CommonParams {
|
||||||
@ -451,6 +476,9 @@ impl Spec {
|
|||||||
/// Create a new Spec with BasicAuthority which uses multiple validator sets changing with height.
|
/// Create a new Spec with BasicAuthority which uses multiple validator sets changing with height.
|
||||||
/// Account with secrets "0".sha3() is the validator for block 1 and with "1".sha3() onwards.
|
/// Account with secrets "0".sha3() is the validator for block 1 and with "1".sha3() onwards.
|
||||||
pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") }
|
pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") }
|
||||||
|
|
||||||
|
/// Create a new spec for a PoW chain
|
||||||
|
pub fn new_pow_test_spec() -> Self { load_bundled!("ethereum/olympic") }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -24,7 +24,7 @@ use std::collections::hash_map::Entry;
|
|||||||
|
|
||||||
use receipt::Receipt;
|
use receipt::Receipt;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use executive::{Executive, TransactOptions};
|
use executive::{Executive, TransactOptions};
|
||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
@ -32,7 +32,7 @@ use trace::FlatTrace;
|
|||||||
use pod_account::*;
|
use pod_account::*;
|
||||||
use pod_state::{self, PodState};
|
use pod_state::{self, PodState};
|
||||||
use types::basic_account::BasicAccount;
|
use types::basic_account::BasicAccount;
|
||||||
use types::executed::{Executed, ExecutionError};
|
use executed::{Executed, ExecutionError};
|
||||||
use types::state_diff::StateDiff;
|
use types::state_diff::StateDiff;
|
||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
@ -982,12 +982,12 @@ mod tests {
|
|||||||
use ethkey::Secret;
|
use ethkey::Secret;
|
||||||
use util::{U256, H256, Address, Hashable};
|
use util::{U256, H256, Address, Hashable};
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use spec::*;
|
use spec::*;
|
||||||
use transaction::*;
|
use transaction::*;
|
||||||
use ethcore_logger::init_log;
|
use ethcore_logger::init_log;
|
||||||
use trace::{FlatTrace, TraceError, trace};
|
use trace::{FlatTrace, TraceError, trace};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
|
|
||||||
fn secret() -> Secret {
|
fn secret() -> Secret {
|
||||||
"".sha3().into()
|
"".sha3().into()
|
||||||
|
76
ethcore/src/tests/evm.rs
Normal file
76
ethcore/src/tests/evm.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
//! Tests of EVM integration with transaction execution.
|
||||||
|
|
||||||
|
use evm::action_params::{ActionParams, ActionValue};
|
||||||
|
use evm::env_info::EnvInfo;
|
||||||
|
use evm::{Factory, VMType};
|
||||||
|
use evm::call_type::CallType;
|
||||||
|
use executive::Executive;
|
||||||
|
use state::Substate;
|
||||||
|
use tests::helpers::*;
|
||||||
|
use trace::{NoopVMTracer, NoopTracer};
|
||||||
|
use transaction::SYSTEM_ADDRESS;
|
||||||
|
|
||||||
|
use rustc_hex::FromHex;
|
||||||
|
|
||||||
|
use util::*;
|
||||||
|
|
||||||
|
evm_test!{test_blockhash_eip210: test_blockhash_eip210_jit, test_blockhash_eip210_int}
|
||||||
|
fn test_blockhash_eip210(factory: Factory) {
|
||||||
|
let get_prev_hash_code = Arc::new("600143034060205260206020f3".from_hex().unwrap()); // this returns previous block hash
|
||||||
|
let get_prev_hash_code_hash = get_prev_hash_code.sha3();
|
||||||
|
// This is same as DEFAULT_BLOCKHASH_CONTRACT except for metropolis transition block check removed.
|
||||||
|
let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b";
|
||||||
|
let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap());
|
||||||
|
let blockhash_contract_code_hash = blockhash_contract_code.sha3();
|
||||||
|
let engine = TestEngine::new_metropolis();
|
||||||
|
let mut env_info = EnvInfo::default();
|
||||||
|
|
||||||
|
// populate state with 256 last hashes
|
||||||
|
let mut state = get_temp_state_with_factory(factory);
|
||||||
|
let contract_address: Address = 0xf0.into();
|
||||||
|
state.init_code(&contract_address, (*blockhash_contract_code).clone()).unwrap();
|
||||||
|
for i in 1 .. 257 {
|
||||||
|
env_info.number = i.into();
|
||||||
|
let params = ActionParams {
|
||||||
|
code_address: contract_address.clone(),
|
||||||
|
address: contract_address,
|
||||||
|
sender: SYSTEM_ADDRESS.clone(),
|
||||||
|
origin: SYSTEM_ADDRESS.clone(),
|
||||||
|
gas: 100000.into(),
|
||||||
|
gas_price: 0.into(),
|
||||||
|
value: ActionValue::Transfer(0.into()),
|
||||||
|
code: Some(blockhash_contract_code.clone()),
|
||||||
|
code_hash: Some(blockhash_contract_code_hash),
|
||||||
|
data: Some(H256::from(i - 1).to_vec()),
|
||||||
|
call_type: CallType::Call,
|
||||||
|
};
|
||||||
|
let mut ex = Executive::new(&mut state, &env_info, &engine);
|
||||||
|
let mut substate = Substate::new();
|
||||||
|
let mut output = [];
|
||||||
|
if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) {
|
||||||
|
panic!("Encountered error on updating last hashes: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
env_info.number = 256;
|
||||||
|
let params = ActionParams {
|
||||||
|
code_address: Address::new(),
|
||||||
|
address: Address::new(),
|
||||||
|
sender: Address::new(),
|
||||||
|
origin: Address::new(),
|
||||||
|
gas: 100000.into(),
|
||||||
|
gas_price: 0.into(),
|
||||||
|
value: ActionValue::Transfer(0.into()),
|
||||||
|
code: Some(get_prev_hash_code),
|
||||||
|
code_hash: Some(get_prev_hash_code_hash),
|
||||||
|
data: None,
|
||||||
|
call_type: CallType::Call,
|
||||||
|
};
|
||||||
|
let mut ex = Executive::new(&mut state, &env_info, &engine);
|
||||||
|
let mut substate = Substate::new();
|
||||||
|
let mut output = H256::new();
|
||||||
|
if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) {
|
||||||
|
panic!("Encountered error on getting last hash: {}", e);
|
||||||
|
}
|
||||||
|
assert_eq!(output, 255.into());
|
||||||
|
}
|
@ -16,5 +16,8 @@
|
|||||||
|
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
mod client;
|
mod client;
|
||||||
|
mod evm;
|
||||||
|
|
||||||
#[cfg(feature="ipc")]
|
#[cfg(feature="ipc")]
|
||||||
mod rpc;
|
mod rpc;
|
||||||
|
|
||||||
|
@ -410,7 +410,7 @@ mod tests {
|
|||||||
use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError};
|
use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError};
|
||||||
use trace::trace::{Call, Action, Res};
|
use trace::trace::{Call, Action, Res};
|
||||||
use trace::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces};
|
use trace::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
|
|
||||||
struct NoopExtras;
|
struct NoopExtras;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! Simple executive tracer.
|
//! Simple executive tracer.
|
||||||
|
|
||||||
use util::{Bytes, Address, U256};
|
use util::{Bytes, Address, U256};
|
||||||
use action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide};
|
use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide};
|
||||||
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
|
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
|
||||||
|
|
||||||
|
@ -22,21 +22,24 @@ mod db;
|
|||||||
mod executive_tracer;
|
mod executive_tracer;
|
||||||
mod import;
|
mod import;
|
||||||
mod noop_tracer;
|
mod noop_tracer;
|
||||||
|
mod types;
|
||||||
|
|
||||||
pub use types::trace_types::{filter, flat, localized, trace};
|
|
||||||
pub use types::trace_types::error::Error as TraceError;
|
|
||||||
pub use self::config::Config;
|
pub use self::config::Config;
|
||||||
pub use self::db::TraceDB;
|
pub use self::db::TraceDB;
|
||||||
pub use types::trace_types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
|
|
||||||
pub use types::trace_types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
|
||||||
pub use self::noop_tracer::{NoopTracer, NoopVMTracer};
|
pub use self::noop_tracer::{NoopTracer, NoopVMTracer};
|
||||||
pub use self::executive_tracer::{ExecutiveTracer, ExecutiveVMTracer};
|
pub use self::executive_tracer::{ExecutiveTracer, ExecutiveVMTracer};
|
||||||
pub use types::trace_types::filter::{Filter, AddressesFilter};
|
|
||||||
pub use self::import::ImportRequest;
|
pub use self::import::ImportRequest;
|
||||||
pub use self::localized::LocalizedTrace;
|
pub use self::localized::LocalizedTrace;
|
||||||
|
|
||||||
|
pub use self::types::{filter, flat, localized, trace};
|
||||||
|
pub use self::types::error::Error as TraceError;
|
||||||
|
pub use self::types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
|
||||||
|
pub use self::types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
||||||
|
pub use self::types::filter::{Filter, AddressesFilter};
|
||||||
|
|
||||||
use util::{Bytes, Address, U256, H256, DBTransaction};
|
use util::{Bytes, Address, U256, H256, DBTransaction};
|
||||||
use self::trace::{Call, Create};
|
use self::trace::{Call, Create};
|
||||||
use action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
|
|
||||||
/// This trait is used by executive to build traces.
|
/// This trait is used by executive to build traces.
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! Nonoperative tracer.
|
//! Nonoperative tracer.
|
||||||
|
|
||||||
use util::{Bytes, Address, U256};
|
use util::{Bytes, Address, U256};
|
||||||
use action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
|
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
|
||||||
use trace::trace::{Call, Create, VMTrace};
|
use trace::trace::{Call, Create, VMTrace};
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ use evm::Error as EvmError;
|
|||||||
|
|
||||||
/// Trace evm errors.
|
/// Trace evm errors.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// `OutOfGas` is returned when transaction execution runs out of gas.
|
/// `OutOfGas` is returned when transaction execution runs out of gas.
|
||||||
OutOfGas,
|
OutOfGas,
|
||||||
@ -34,7 +33,7 @@ pub enum Error {
|
|||||||
/// `StackUnderflow` when there is not enough stack elements to execute instruction
|
/// `StackUnderflow` when there is not enough stack elements to execute instruction
|
||||||
StackUnderflow,
|
StackUnderflow,
|
||||||
/// When execution would exceed defined Stack Limit
|
/// When execution would exceed defined Stack Limit
|
||||||
OutOfStack,
|
OutOfStack,
|
||||||
/// When builtin contract failed on input data
|
/// When builtin contract failed on input data
|
||||||
BuiltIn,
|
BuiltIn,
|
||||||
/// Returned on evm internal error. Should never be ignored during development.
|
/// Returned on evm internal error. Should never be ignored during development.
|
@ -23,13 +23,12 @@ use util::sha3::Hashable;
|
|||||||
use util::bloom::Bloomable;
|
use util::bloom::Bloomable;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
use trace::flat::FlatTrace;
|
use trace::flat::FlatTrace;
|
||||||
use types::trace_types::trace::{Action, Res};
|
use super::trace::{Action, Res};
|
||||||
|
|
||||||
/// Addresses filter.
|
/// Addresses filter.
|
||||||
///
|
///
|
||||||
/// Used to create bloom possibilities and match filters.
|
/// Used to create bloom possibilities and match filters.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct AddressesFilter {
|
pub struct AddressesFilter {
|
||||||
list: Vec<Address>
|
list: Vec<Address>
|
||||||
}
|
}
|
||||||
@ -76,7 +75,6 @@ impl AddressesFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
/// Traces filter.
|
/// Traces filter.
|
||||||
pub struct Filter {
|
pub struct Filter {
|
||||||
/// Block range.
|
/// Block range.
|
||||||
@ -143,7 +141,7 @@ mod tests {
|
|||||||
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide};
|
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide};
|
||||||
use trace::flat::FlatTrace;
|
use trace::flat::FlatTrace;
|
||||||
use trace::{Filter, AddressesFilter, TraceError};
|
use trace::{Filter, AddressesFilter, TraceError};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_trace_filter_bloom_possibilities() {
|
fn empty_trace_filter_bloom_possibilities() {
|
@ -26,7 +26,6 @@ use super::trace::{Action, Res};
|
|||||||
///
|
///
|
||||||
/// Parent and children indexes refer to positions in this vector.
|
/// Parent and children indexes refer to positions in this vector.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct FlatTrace {
|
pub struct FlatTrace {
|
||||||
/// Type of action performed by a transaction.
|
/// Type of action performed by a transaction.
|
||||||
pub action: Action,
|
pub action: Action,
|
||||||
@ -164,7 +163,7 @@ mod tests {
|
|||||||
use rlp::*;
|
use rlp::*;
|
||||||
use super::{FlatBlockTraces, FlatTransactionTraces, FlatTrace};
|
use super::{FlatBlockTraces, FlatTransactionTraces, FlatTrace};
|
||||||
use trace::trace::{Action, Res, CallResult, Call, Suicide};
|
use trace::trace::{Action, Res, CallResult, Call, Suicide};
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encode_flat_transaction_traces() {
|
fn encode_flat_transaction_traces() {
|
@ -22,7 +22,6 @@ use header::BlockNumber;
|
|||||||
|
|
||||||
/// Localized trace.
|
/// Localized trace.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct LocalizedTrace {
|
pub struct LocalizedTrace {
|
||||||
/// Type of action performed by a transaction.
|
/// Type of action performed by a transaction.
|
||||||
pub action: Action,
|
pub action: Action,
|
@ -21,9 +21,9 @@ use util::sha3::Hashable;
|
|||||||
use util::bloom::Bloomable;
|
use util::bloom::Bloomable;
|
||||||
use rlp::*;
|
use rlp::*;
|
||||||
|
|
||||||
use action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
use types::executed::CallType;
|
use evm::CallType;
|
||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
|
|
||||||
/// `Call` result.
|
/// `Call` result.
|
@ -32,9 +32,8 @@ pub const UNSIGNED_SENDER: Address = ::util::H160([0xff; 20]);
|
|||||||
/// System sender address for internal state updates.
|
/// System sender address for internal state updates.
|
||||||
pub const SYSTEM_ADDRESS: Address = ::util::H160([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xfe]);
|
pub const SYSTEM_ADDRESS: Address = ::util::H160([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xfe]);
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
/// Transaction action type.
|
/// Transaction action type.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
/// Create creates new contract.
|
/// Create creates new contract.
|
||||||
Create,
|
Create,
|
||||||
@ -59,7 +58,6 @@ impl Decodable for Action {
|
|||||||
|
|
||||||
/// Transaction activation condition.
|
/// Transaction activation condition.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum Condition {
|
pub enum Condition {
|
||||||
/// Valid at this block number or later.
|
/// Valid at this block number or later.
|
||||||
Number(BlockNumber),
|
Number(BlockNumber),
|
||||||
@ -70,7 +68,6 @@ pub enum Condition {
|
|||||||
/// A set of information describing an externally-originating message call
|
/// A set of information describing an externally-originating message call
|
||||||
/// or contract creation operation.
|
/// or contract creation operation.
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
/// Nonce.
|
/// Nonce.
|
||||||
pub nonce: U256,
|
pub nonce: U256,
|
||||||
@ -241,9 +238,8 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signed transaction information.
|
/// Signed transaction information without verified signature.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct UnverifiedTransaction {
|
pub struct UnverifiedTransaction {
|
||||||
/// Plain Transaction.
|
/// Plain Transaction.
|
||||||
unsigned: Transaction,
|
unsigned: Transaction,
|
||||||
@ -470,7 +466,6 @@ impl SignedTransaction {
|
|||||||
|
|
||||||
/// Signed Transaction that is a part of canon blockchain.
|
/// Signed Transaction that is a part of canon blockchain.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct LocalizedTransaction {
|
pub struct LocalizedTransaction {
|
||||||
/// Signed part.
|
/// Signed part.
|
||||||
pub signed: UnverifiedTransaction,
|
pub signed: UnverifiedTransaction,
|
||||||
@ -511,7 +506,6 @@ impl Deref for LocalizedTransaction {
|
|||||||
|
|
||||||
/// Queued transaction with additional information.
|
/// Queued transaction with additional information.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct PendingTransaction {
|
pub struct PendingTransaction {
|
||||||
/// Signed transaction data.
|
/// Signed transaction data.
|
||||||
pub transaction: SignedTransaction,
|
pub transaction: SignedTransaction,
|
||||||
@ -544,91 +538,97 @@ impl From<SignedTransaction> for PendingTransaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn sender_test() {
|
mod tests {
|
||||||
let t: UnverifiedTransaction = decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
|
use super::*;
|
||||||
assert_eq!(t.data, b"");
|
use util::{Hashable, U256};
|
||||||
assert_eq!(t.gas, U256::from(0x5208u64));
|
|
||||||
assert_eq!(t.gas_price, U256::from(0x01u64));
|
#[test]
|
||||||
assert_eq!(t.nonce, U256::from(0x00u64));
|
fn sender_test() {
|
||||||
if let Action::Call(ref to) = t.action {
|
let t: UnverifiedTransaction = decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
|
||||||
assert_eq!(*to, "095e7baea6a6c7c4c2dfeb977efac326af552d87".into());
|
assert_eq!(t.data, b"");
|
||||||
} else { panic!(); }
|
assert_eq!(t.gas, U256::from(0x5208u64));
|
||||||
assert_eq!(t.value, U256::from(0x0au64));
|
assert_eq!(t.gas_price, U256::from(0x01u64));
|
||||||
assert_eq!(public_to_address(&t.recover_public().unwrap()), "0f65fe9276bc9a24ae7083ae28e2660ef72df99e".into());
|
assert_eq!(t.nonce, U256::from(0x00u64));
|
||||||
assert_eq!(t.network_id(), None);
|
if let Action::Call(ref to) = t.action {
|
||||||
}
|
assert_eq!(*to, "095e7baea6a6c7c4c2dfeb977efac326af552d87".into());
|
||||||
|
} else { panic!(); }
|
||||||
#[test]
|
assert_eq!(t.value, U256::from(0x0au64));
|
||||||
fn signing() {
|
assert_eq!(public_to_address(&t.recover_public().unwrap()), "0f65fe9276bc9a24ae7083ae28e2660ef72df99e".into());
|
||||||
use ethkey::{Random, Generator};
|
assert_eq!(t.network_id(), None);
|
||||||
|
}
|
||||||
let key = Random.generate().unwrap();
|
|
||||||
let t = Transaction {
|
#[test]
|
||||||
action: Action::Create,
|
fn signing() {
|
||||||
nonce: U256::from(42),
|
use ethkey::{Random, Generator};
|
||||||
gas_price: U256::from(3000),
|
|
||||||
gas: U256::from(50_000),
|
let key = Random.generate().unwrap();
|
||||||
value: U256::from(1),
|
let t = Transaction {
|
||||||
data: b"Hello!".to_vec()
|
action: Action::Create,
|
||||||
}.sign(&key.secret(), None);
|
nonce: U256::from(42),
|
||||||
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
gas_price: U256::from(3000),
|
||||||
assert_eq!(t.network_id(), None);
|
gas: U256::from(50_000),
|
||||||
}
|
value: U256::from(1),
|
||||||
|
data: b"Hello!".to_vec()
|
||||||
#[test]
|
}.sign(&key.secret(), None);
|
||||||
fn fake_signing() {
|
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
||||||
let t = Transaction {
|
assert_eq!(t.network_id(), None);
|
||||||
action: Action::Create,
|
}
|
||||||
nonce: U256::from(42),
|
|
||||||
gas_price: U256::from(3000),
|
#[test]
|
||||||
gas: U256::from(50_000),
|
fn fake_signing() {
|
||||||
value: U256::from(1),
|
let t = Transaction {
|
||||||
data: b"Hello!".to_vec()
|
action: Action::Create,
|
||||||
}.fake_sign(Address::from(0x69));
|
nonce: U256::from(42),
|
||||||
assert_eq!(Address::from(0x69), t.sender());
|
gas_price: U256::from(3000),
|
||||||
assert_eq!(t.network_id(), None);
|
gas: U256::from(50_000),
|
||||||
|
value: U256::from(1),
|
||||||
let t = t.clone();
|
data: b"Hello!".to_vec()
|
||||||
assert_eq!(Address::from(0x69), t.sender());
|
}.fake_sign(Address::from(0x69));
|
||||||
assert_eq!(t.network_id(), None);
|
assert_eq!(Address::from(0x69), t.sender());
|
||||||
}
|
assert_eq!(t.network_id(), None);
|
||||||
|
|
||||||
#[test]
|
let t = t.clone();
|
||||||
fn should_recover_from_network_specific_signing() {
|
assert_eq!(Address::from(0x69), t.sender());
|
||||||
use ethkey::{Random, Generator};
|
assert_eq!(t.network_id(), None);
|
||||||
let key = Random.generate().unwrap();
|
}
|
||||||
let t = Transaction {
|
|
||||||
action: Action::Create,
|
#[test]
|
||||||
nonce: U256::from(42),
|
fn should_recover_from_network_specific_signing() {
|
||||||
gas_price: U256::from(3000),
|
use ethkey::{Random, Generator};
|
||||||
gas: U256::from(50_000),
|
let key = Random.generate().unwrap();
|
||||||
value: U256::from(1),
|
let t = Transaction {
|
||||||
data: b"Hello!".to_vec()
|
action: Action::Create,
|
||||||
}.sign(&key.secret(), Some(69));
|
nonce: U256::from(42),
|
||||||
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
gas_price: U256::from(3000),
|
||||||
assert_eq!(t.network_id(), Some(69));
|
gas: U256::from(50_000),
|
||||||
}
|
value: U256::from(1),
|
||||||
|
data: b"Hello!".to_vec()
|
||||||
#[test]
|
}.sign(&key.secret(), Some(69));
|
||||||
fn should_agree_with_vitalik() {
|
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
||||||
use rustc_hex::FromHex;
|
assert_eq!(t.network_id(), Some(69));
|
||||||
|
}
|
||||||
let test_vector = |tx_data: &str, address: &'static str| {
|
|
||||||
let signed = decode(&FromHex::from_hex(tx_data).unwrap());
|
#[test]
|
||||||
let signed = SignedTransaction::new(signed).unwrap();
|
fn should_agree_with_vitalik() {
|
||||||
assert_eq!(signed.sender(), address.into());
|
use rustc_hex::FromHex;
|
||||||
flushln!("networkid: {:?}", signed.network_id());
|
|
||||||
};
|
let test_vector = |tx_data: &str, address: &'static str| {
|
||||||
|
let signed = decode(&FromHex::from_hex(tx_data).unwrap());
|
||||||
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce");
|
let signed = SignedTransaction::new(signed).unwrap();
|
||||||
test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112");
|
assert_eq!(signed.sender(), address.into());
|
||||||
test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be");
|
flushln!("networkid: {:?}", signed.network_id());
|
||||||
test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0");
|
};
|
||||||
test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554");
|
|
||||||
test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4");
|
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce");
|
||||||
test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35");
|
test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112");
|
||||||
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332");
|
test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be");
|
||||||
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029");
|
test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0");
|
||||||
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f");
|
test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554");
|
||||||
|
test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4");
|
||||||
|
test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35");
|
||||||
|
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332");
|
||||||
|
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029");
|
||||||
|
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f");
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,42 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Block import error related types
|
|
||||||
|
|
||||||
use error::{ImportError, BlockError, Error};
|
|
||||||
use std::convert::From;
|
|
||||||
|
|
||||||
/// Error dedicated to import block function
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum BlockImportError {
|
|
||||||
/// Import error
|
|
||||||
Import(ImportError),
|
|
||||||
/// Block error
|
|
||||||
Block(BlockError),
|
|
||||||
/// Other error
|
|
||||||
Other(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Error> for BlockImportError {
|
|
||||||
fn from(e: Error) -> Self {
|
|
||||||
match e {
|
|
||||||
Error::Block(block_error) => BlockImportError::Block(block_error),
|
|
||||||
Error::Import(import_error) => BlockImportError::Import(import_error),
|
|
||||||
_ => BlockImportError::Other(format!("other block import error: {:?}", e)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Block status description module
|
|
||||||
use verification::queue::Status as QueueStatus;
|
|
||||||
|
|
||||||
/// General block status
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum BlockStatus {
|
|
||||||
/// Part of the blockchain.
|
|
||||||
InChain,
|
|
||||||
/// Queued for import.
|
|
||||||
Queued,
|
|
||||||
/// Known as bad.
|
|
||||||
Bad,
|
|
||||||
/// Unknown.
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<QueueStatus> for BlockStatus {
|
|
||||||
fn from(status: QueueStatus) -> Self {
|
|
||||||
match status {
|
|
||||||
QueueStatus::Queued => BlockStatus::Queued,
|
|
||||||
QueueStatus::Bad => BlockStatus::Bad,
|
|
||||||
QueueStatus::Unknown => BlockStatus::Unknown,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Transaction import result related types
|
|
||||||
|
|
||||||
use ipc::binary::{BinaryConvertError, BinaryConvertable};
|
|
||||||
use error::{TransactionError, Error};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
||||||
/// Represents the result of importing transaction.
|
|
||||||
pub enum TransactionImportResult {
|
|
||||||
/// Transaction was imported to current queue.
|
|
||||||
Current,
|
|
||||||
/// Transaction was imported to future queue.
|
|
||||||
Future
|
|
||||||
}
|
|
||||||
|
|
||||||
binary_fixed_size!(TransactionImportResult);
|
|
||||||
|
|
||||||
/// Api-level error for transaction import
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum TransactionImportError {
|
|
||||||
/// Transaction error
|
|
||||||
Transaction(TransactionError),
|
|
||||||
/// Other error
|
|
||||||
Other(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Error> for TransactionImportError {
|
|
||||||
fn from(e: Error) -> Self {
|
|
||||||
match e {
|
|
||||||
Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error),
|
|
||||||
_ => TransactionImportError::Other(format!("other block import error: {:?}", e)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -115,6 +115,17 @@ pub enum Status {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<::block_status::BlockStatus> for Status {
|
||||||
|
fn into(self) -> ::block_status::BlockStatus {
|
||||||
|
use ::block_status::BlockStatus;
|
||||||
|
match self {
|
||||||
|
Status::Queued => BlockStatus::Queued,
|
||||||
|
Status::Bad => BlockStatus::Bad,
|
||||||
|
Status::Unknown => BlockStatus::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the internal queue sizes.
|
// the internal queue sizes.
|
||||||
struct Sizes {
|
struct Sizes {
|
||||||
unverified: AtomicUsize,
|
unverified: AtomicUsize,
|
||||||
|
@ -585,7 +585,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn dust_protection() {
|
fn dust_protection() {
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use types::transaction::{Transaction, Action};
|
use transaction::{Transaction, Action};
|
||||||
use engines::NullEngine;
|
use engines::NullEngine;
|
||||||
|
|
||||||
let mut params = CommonParams::default();
|
let mut params = CommonParams::default();
|
||||||
|
13
ethcore/types/Cargo.toml
Normal file
13
ethcore/types/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "common-types"
|
||||||
|
description = "Common types used throughout the codebase"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rlp = { path = "../../util/rlp" }
|
||||||
|
ethcore-util = { path = "../../util" }
|
||||||
|
ethjson = { path = "../../json" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rustc-hex= "1.0"
|
@ -20,12 +20,10 @@ use std::cmp::*;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use util::{U256, H256, Bytes};
|
use util::{U256, H256, Bytes};
|
||||||
use ipc::binary::BinaryConvertable;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
/// Diff type for specifying a change (or not).
|
/// Diff type for specifying a change (or not).
|
||||||
pub enum Diff<T> where T: Eq + BinaryConvertable {
|
pub enum Diff<T> where T: Eq {
|
||||||
/// Both sides are the same.
|
/// Both sides are the same.
|
||||||
Same,
|
Same,
|
||||||
/// Left (pre, source) side doesn't include value, right side (post, destination) does.
|
/// Left (pre, source) side doesn't include value, right side (post, destination) does.
|
||||||
@ -36,7 +34,7 @@ pub enum Diff<T> where T: Eq + BinaryConvertable {
|
|||||||
Died(T),
|
Died(T),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Diff<T> where T: Eq + BinaryConvertable {
|
impl<T> Diff<T> where T: Eq {
|
||||||
/// Construct new object with given `pre` and `post`.
|
/// Construct new object with given `pre` and `post`.
|
||||||
pub fn new(pre: T, post: T) -> Self { if pre == post { Diff::Same } else { Diff::Changed(pre, post) } }
|
pub fn new(pre: T, post: T) -> Self { if pre == post { Diff::Same } else { Diff::Changed(pre, post) } }
|
||||||
|
|
@ -14,12 +14,15 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Types used in the public api
|
/// General block status
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
#![cfg_attr(feature = "ipc", allow(dead_code, unused_assignments, unused_variables))] // codegen issues
|
pub enum BlockStatus {
|
||||||
|
/// Part of the blockchain.
|
||||||
#[cfg(feature = "ipc")]
|
InChain,
|
||||||
include!(concat!(env!("OUT_DIR"), "/mod.rs.in"));
|
/// Queued for import.
|
||||||
|
Queued,
|
||||||
#[cfg(not(feature = "ipc"))]
|
/// Known as bad.
|
||||||
include!("mod.rs.in");
|
Bad,
|
||||||
|
/// Unknown.
|
||||||
|
Unknown,
|
||||||
|
}
|
@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
//! Blockhain info type definition
|
//! Blockhain info type definition
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use util::{U256, H256};
|
use util::{U256, H256};
|
||||||
use header::BlockNumber;
|
use security_level::SecurityLevel;
|
||||||
use types::security_level::SecurityLevel;
|
use {BlockNumber};
|
||||||
|
|
||||||
/// Information about the blockchain gathered together.
|
/// Information about the blockchain gathered together.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct BlockChainInfo {
|
pub struct BlockChainInfo {
|
||||||
/// Blockchain difficulty.
|
/// Blockchain difficulty.
|
||||||
pub total_difficulty: U256,
|
pub total_difficulty: U256,
|
||||||
@ -57,3 +58,9 @@ impl BlockChainInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for BlockChainInfo {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "#{}.{}", self.best_block_number, self.best_block_hash)
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
/// Options concerning what analytics we run on the call.
|
/// Options concerning what analytics we run on the call.
|
||||||
#[derive(Eq, PartialEq, Default, Clone, Copy, Debug)]
|
#[derive(Eq, PartialEq, Default, Clone, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct CallAnalytics {
|
pub struct CallAnalytics {
|
||||||
/// Make a transaction trace.
|
/// Make a transaction trace.
|
||||||
pub transaction_tracing: bool,
|
pub transaction_tracing: bool,
|
@ -18,12 +18,11 @@
|
|||||||
|
|
||||||
use util::{Address, H256, Hashable, H2048};
|
use util::{Address, H256, Hashable, H2048};
|
||||||
use util::bloom::Bloomable;
|
use util::bloom::Bloomable;
|
||||||
use client::BlockId;
|
use ids::BlockId;
|
||||||
use log_entry::LogEntry;
|
use log_entry::LogEntry;
|
||||||
|
|
||||||
/// Blockchain Filter.
|
/// Blockchain Filter.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct Filter {
|
pub struct Filter {
|
||||||
/// Blockchain will be searched from this block.
|
/// Blockchain will be searched from this block.
|
||||||
pub from_block: BlockId,
|
pub from_block: BlockId,
|
||||||
@ -114,7 +113,7 @@ impl Filter {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use filter::Filter;
|
use filter::Filter;
|
||||||
use client::BlockId;
|
use ids::BlockId;
|
||||||
use log_entry::LogEntry;
|
use log_entry::LogEntry;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
@ -17,11 +17,10 @@
|
|||||||
//! Unique identifiers.
|
//! Unique identifiers.
|
||||||
|
|
||||||
use util::hash::H256;
|
use util::hash::H256;
|
||||||
use header::BlockNumber;
|
use {BlockNumber};
|
||||||
|
|
||||||
/// Uniquely identifies block.
|
/// Uniquely identifies block.
|
||||||
#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)]
|
#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum BlockId {
|
pub enum BlockId {
|
||||||
/// Block's sha3.
|
/// Block's sha3.
|
||||||
/// Querying by hash is always faster.
|
/// Querying by hash is always faster.
|
||||||
@ -38,7 +37,6 @@ pub enum BlockId {
|
|||||||
|
|
||||||
/// Uniquely identifies transaction.
|
/// Uniquely identifies transaction.
|
||||||
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub enum TransactionId {
|
pub enum TransactionId {
|
||||||
/// Transaction's sha3.
|
/// Transaction's sha3.
|
||||||
Hash(H256),
|
Hash(H256),
|
||||||
@ -48,7 +46,6 @@ pub enum TransactionId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Uniquely identifies Trace.
|
/// Uniquely identifies Trace.
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct TraceId {
|
pub struct TraceId {
|
||||||
/// Transaction
|
/// Transaction
|
||||||
pub transaction: TransactionId,
|
pub transaction: TransactionId,
|
||||||
@ -58,7 +55,6 @@ pub struct TraceId {
|
|||||||
|
|
||||||
/// Uniquely identifies Uncle.
|
/// Uniquely identifies Uncle.
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct UncleId {
|
pub struct UncleId {
|
||||||
/// Block id.
|
/// Block id.
|
||||||
pub block: BlockId,
|
pub block: BlockId,
|
@ -14,27 +14,33 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
pub mod transaction;
|
//! Types used in the public API
|
||||||
pub mod ids;
|
|
||||||
pub mod receipt;
|
extern crate ethcore_util as util;
|
||||||
pub mod tree_route;
|
extern crate ethjson;
|
||||||
pub mod blockchain_info;
|
extern crate rlp;
|
||||||
pub mod log_entry;
|
|
||||||
pub mod trace_types;
|
#[cfg(test)]
|
||||||
pub mod executed;
|
extern crate rustc_hex;
|
||||||
pub mod block_status;
|
|
||||||
pub mod account_diff;
|
pub mod account_diff;
|
||||||
pub mod state_diff;
|
pub mod basic_account;
|
||||||
pub mod verification_queue_info;
|
pub mod block_status;
|
||||||
pub mod filter;
|
pub mod blockchain_info;
|
||||||
pub mod trace_filter;
|
|
||||||
pub mod call_analytics;
|
pub mod call_analytics;
|
||||||
pub mod transaction_import;
|
pub mod filter;
|
||||||
pub mod block_import_error;
|
pub mod ids;
|
||||||
pub mod restoration_status;
|
pub mod log_entry;
|
||||||
pub mod snapshot_manifest;
|
|
||||||
pub mod mode;
|
pub mod mode;
|
||||||
pub mod pruning_info;
|
pub mod pruning_info;
|
||||||
|
pub mod receipt;
|
||||||
|
pub mod restoration_status;
|
||||||
pub mod security_level;
|
pub mod security_level;
|
||||||
pub mod encoded;
|
pub mod snapshot_manifest;
|
||||||
pub mod basic_account;
|
pub mod state_diff;
|
||||||
|
pub mod trace_filter;
|
||||||
|
pub mod tree_route;
|
||||||
|
pub mod verification_queue_info;
|
||||||
|
|
||||||
|
/// Type for block number.
|
||||||
|
pub type BlockNumber = u64;
|
@ -21,13 +21,13 @@ use util::{H256, Address, Bytes, HeapSizeOf, Hashable};
|
|||||||
use util::bloom::Bloomable;
|
use util::bloom::Bloomable;
|
||||||
use rlp::*;
|
use rlp::*;
|
||||||
|
|
||||||
use basic_types::LogBloom;
|
use {BlockNumber};
|
||||||
use header::BlockNumber;
|
|
||||||
use ethjson;
|
use ethjson;
|
||||||
|
|
||||||
|
pub type LogBloom = ::util::H2048;
|
||||||
|
|
||||||
/// A record of execution for a `LOG` operation.
|
/// A record of execution for a `LOG` operation.
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct LogEntry {
|
pub struct LogEntry {
|
||||||
/// The address of the contract executing at the point of the `LOG` operation.
|
/// The address of the contract executing at the point of the `LOG` operation.
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
@ -82,7 +82,6 @@ impl From<ethjson::state::Log> for LogEntry {
|
|||||||
|
|
||||||
/// Log localized in a blockchain.
|
/// Log localized in a blockchain.
|
||||||
#[derive(Default, Debug, PartialEq, Clone)]
|
#[derive(Default, Debug, PartialEq, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
|
||||||
pub struct LocalizedLogEntry {
|
pub struct LocalizedLogEntry {
|
||||||
/// Plain log entry.
|
/// Plain log entry.
|
||||||
pub entry: LogEntry,
|
pub entry: LogEntry,
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user