Merge branch 'master' into aura-contract-warp

This commit is contained in:
Robert Habermeier 2017-04-19 20:43:24 +02:00
commit 6652df03df
226 changed files with 4115 additions and 3002 deletions

View File

@ -541,7 +541,7 @@ test-windows:
- git submodule update --init --recursive - git submodule update --init --recursive
script: script:
- set RUST_BACKTRACE=1 - set RUST_BACKTRACE=1
- echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release - echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p parity-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release
tags: tags:
- rust-windows - rust-windows
allow_failure: true allow_failure: true

141
Cargo.lock generated
View File

@ -18,7 +18,6 @@ dependencies = [
"ethcore-ipc-tests 0.1.0", "ethcore-ipc-tests 0.1.0",
"ethcore-light 1.7.0", "ethcore-light 1.7.0",
"ethcore-logger 1.7.0", "ethcore-logger 1.7.0",
"ethcore-rpc 1.7.0",
"ethcore-secretstore 1.0.0", "ethcore-secretstore 1.0.0",
"ethcore-signer 1.7.0", "ethcore-signer 1.7.0",
"ethcore-stratum 1.7.0", "ethcore-stratum 1.7.0",
@ -38,6 +37,7 @@ dependencies = [
"parity-ipfs-api 1.7.0", "parity-ipfs-api 1.7.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-client 1.4.0", "parity-rpc-client 1.4.0",
"parity-updater 1.7.0", "parity-updater 1.7.0",
"path 0.1.0", "path 0.1.0",
@ -592,49 +592,6 @@ dependencies = [
"tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ethcore-rpc"
version = "1.7.0"
dependencies = [
"cid 0.2.1 (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",
"ethcore 1.7.0",
"ethcore-devtools 1.7.0",
"ethcore-io 1.7.0",
"ethcore-ipc 1.7.0",
"ethcore-light 1.7.0",
"ethcore-logger 1.7.0",
"ethcore-util 1.7.0",
"ethcrypto 0.1.0",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
"ethsync 1.7.0",
"fetch 0.1.0",
"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-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-ipc-server 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-minihttp-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)",
"multihash 0.5.1 (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-updater 1.7.0",
"rlp 0.1.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0",
"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)",
]
[[package]] [[package]]
name = "ethcore-secretstore" name = "ethcore-secretstore"
version = "1.0.0" version = "1.0.0"
@ -674,12 +631,12 @@ 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.7.0",
"ethcore-io 1.7.0", "ethcore-io 1.7.0",
"ethcore-rpc 1.7.0",
"ethcore-util 1.7.0", "ethcore-util 1.7.0",
"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-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 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)",
"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-rpc 1.7.0",
"parity-ui 1.7.0", "parity-ui 1.7.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_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)",
@ -1080,7 +1037,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "jsonrpc-core" name = "jsonrpc-core"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"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)",
@ -1092,7 +1049,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-http-server" name = "jsonrpc-http-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
"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)",
@ -1105,7 +1062,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-ipc-server" name = "jsonrpc-ipc-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"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-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1117,7 +1074,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-macros" name = "jsonrpc-macros"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"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-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1127,7 +1084,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-minihttp-server" name = "jsonrpc-minihttp-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"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-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1141,7 +1098,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-pubsub" name = "jsonrpc-pubsub"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"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)",
"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)",
@ -1151,7 +1108,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-server-utils" name = "jsonrpc-server-utils"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"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)",
"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)",
@ -1162,7 +1119,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-tcp-server" name = "jsonrpc-tcp-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [ dependencies = [
"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-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1172,6 +1129,17 @@ dependencies = [
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "jsonrpc-ws-server"
version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#ad0682785a693eba3069e48b57ec89abb62c3b60"
dependencies = [
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-server-utils 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)",
"ws 0.6.0 (git+https://github.com/tomusdrw/ws-rs)",
]
[[package]] [[package]]
name = "kernel32-sys" name = "kernel32-sys"
version = "0.2.2" version = "0.2.2"
@ -1708,16 +1676,60 @@ dependencies = [
"tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "parity-rpc"
version = "1.7.0"
dependencies = [
"cid 0.2.1 (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",
"ethcore 1.7.0",
"ethcore-devtools 1.7.0",
"ethcore-io 1.7.0",
"ethcore-ipc 1.7.0",
"ethcore-light 1.7.0",
"ethcore-logger 1.7.0",
"ethcore-util 1.7.0",
"ethcrypto 0.1.0",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
"ethsync 1.7.0",
"fetch 0.1.0",
"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-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-ipc-server 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-minihttp-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)",
"multihash 0.5.1 (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-updater 1.7.0",
"rlp 0.1.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0",
"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)",
]
[[package]] [[package]]
name = "parity-rpc-client" name = "parity-rpc-client"
version = "1.4.0" version = "1.4.0"
dependencies = [ dependencies = [
"ethcore-rpc 1.7.0",
"ethcore-signer 1.7.0", "ethcore-signer 1.7.0",
"ethcore-util 1.7.0", "ethcore-util 1.7.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)",
"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-rpc 1.7.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 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1761,7 +1773,7 @@ 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#b4c41885c6e02c64fb773546b2f135f56ea7022f" source = "git+https://github.com/paritytech/js-precompiled.git#bceb0caa1eae7d78ad3386338a76b7ca92bf033a"
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)",
] ]
@ -2081,9 +2093,9 @@ name = "rpc-cli"
version = "1.4.0" version = "1.4.0"
dependencies = [ dependencies = [
"ethcore-bigint 0.1.2", "ethcore-bigint 0.1.2",
"ethcore-rpc 1.7.0",
"ethcore-util 1.7.0", "ethcore-util 1.7.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-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)",
] ]
@ -2710,6 +2722,21 @@ dependencies = [
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ws"
version = "0.6.0"
source = "git+https://github.com/tomusdrw/ws-rs#3259e7ca906c848beae109eb32e492871f8f397d"
dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "ws2_32-sys" name = "ws2_32-sys"
version = "0.2.1" version = "0.2.1"
@ -2824,6 +2851,7 @@ dependencies = [
"checksum jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>" "checksum jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
"checksum jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>" "checksum jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
"checksum jsonrpc-tcp-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>" "checksum jsonrpc-tcp-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
"checksum jsonrpc-ws-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f" "checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
@ -2981,6 +3009,7 @@ dependencies = [
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum ws 0.5.3 (git+https://github.com/paritytech/ws-rs.git?branch=parity-1.7)" = "<none>" "checksum ws 0.5.3 (git+https://github.com/paritytech/ws-rs.git?branch=parity-1.7)" = "<none>"
"checksum ws 0.6.0 (git+https://github.com/tomusdrw/ws-rs)" = "<none>"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77b831a5ba77110f438f0ac5583aafeb087f70432998ba6b7dcb1d32185db453" "checksum xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77b831a5ba77110f438f0ac5583aafeb087f70432998ba6b7dcb1d32185db453"
"checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef" "checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef"

View File

@ -33,7 +33,6 @@ ethcore = { path = "ethcore" }
ethcore-util = { path = "util" } ethcore-util = { path = "util" }
ethcore-io = { path = "util/io" } ethcore-io = { path = "util/io" }
ethcore-devtools = { path = "devtools" } ethcore-devtools = { path = "devtools" }
ethcore-rpc = { path = "rpc" }
ethcore-signer = { path = "signer" } ethcore-signer = { path = "signer" }
ethcore-ipc = { path = "ipc/rpc" } ethcore-ipc = { path = "ipc/rpc" }
ethcore-ipc-nano = { path = "ipc/nano" } ethcore-ipc-nano = { path = "ipc/nano" }
@ -45,12 +44,13 @@ ethkey = { path = "ethkey" }
evmbin = { path = "evmbin" } evmbin = { path = "evmbin" }
rlp = { path = "util/rlp" } rlp = { path = "util/rlp" }
rpc-cli = { path = "rpc_cli" } rpc-cli = { path = "rpc_cli" }
parity-rpc-client = { path = "rpc_client" }
parity-hash-fetch = { path = "hash-fetch" } parity-hash-fetch = { path = "hash-fetch" }
parity-ipfs-api = { path = "ipfs" } parity-ipfs-api = { path = "ipfs" }
parity-updater = { path = "updater" }
parity-reactor = { path = "util/reactor" }
parity-local-store = { path = "local-store" } parity-local-store = { path = "local-store" }
parity-reactor = { path = "util/reactor" }
parity-rpc = { path = "rpc" }
parity-rpc-client = { path = "rpc_client" }
parity-updater = { path = "updater" }
path = { path = "util/path" } path = { path = "util/path" }
parity-dapps = { path = "dapps", optional = true } parity-dapps = { path = "dapps", optional = true }
@ -85,7 +85,7 @@ ui-precompiled = [
dapps = ["parity-dapps"] dapps = ["parity-dapps"]
ipc = ["ethcore/ipc", "ethsync/ipc"] ipc = ["ethcore/ipc", "ethsync/ipc"]
jit = ["ethcore/jit"] jit = ["ethcore/jit"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "parity-dapps/dev", "ethcore-signer/dev"] dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "parity-rpc/dev", "parity-dapps/dev", "ethcore-signer/dev"]
json-tests = ["ethcore/json-tests"] json-tests = ["ethcore/json-tests"]
test-heavy = ["ethcore/test-heavy"] test-heavy = ["ethcore/test-heavy"]
ethkey-cli = ["ethcore/ethkey-cli"] ethkey-cli = ["ethcore/ethkey-cli"]

View File

@ -33,7 +33,7 @@ Be sure to check out [our wiki][wiki-url] for more information.
Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and
cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs. cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs.
Parity comes with a built-in wallet. To access [Parity Wallet](http://127.0.0.1:8080/) simply go to http://127.0.0.1:8080/. It Parity comes with a built-in wallet. To access [Parity Wallet](http://web3.site/) simply go to http://web3.site/ (if you don't have access to the internet, but still want to use the service, you can also use http://127.0.0.1:8180/). It
includes various functionality allowing you to: includes various functionality allowing you to:
- create and manage your Ethereum accounts; - create and manage your Ethereum accounts;
- manage your Ether and any Ethereum tokens; - manage your Ether and any Ethereum tokens;

View File

@ -17,7 +17,7 @@
use std::sync::Arc; use std::sync::Arc;
use hyper; use hyper;
use ethcore_rpc::{Metadata, Origin}; use parity_rpc::{Metadata, Origin};
use jsonrpc_core::{Middleware, MetaIoHandler}; use jsonrpc_core::{Middleware, MetaIoHandler};
use jsonrpc_http_server::{self as http, AccessControlAllowOrigin, HttpMetaExtractor}; use jsonrpc_http_server::{self as http, AccessControlAllowOrigin, HttpMetaExtractor};
use jsonrpc_http_server::tokio_core::reactor::Remote; use jsonrpc_http_server::tokio_core::reactor::Remote;

View File

@ -361,6 +361,22 @@ impl HeaderChain {
} }
} }
/// Get a block's hash by ID. In the case of query by number, only canonical results
/// will be returned.
pub fn block_hash(&self, id: BlockId) -> Option<H256> {
match id {
BlockId::Earliest => Some(self.genesis_hash()),
BlockId::Hash(hash) => Some(hash),
BlockId::Number(num) => {
if self.best_block.read().number < num { return None }
self.candidates.read().get(&num).map(|entry| entry.canonical_hash)
}
BlockId::Latest | BlockId::Pending => {
Some(self.best_block.read().hash)
}
}
}
/// Get a block header. In the case of query by number, only canonical blocks /// Get a block header. In the case of query by number, only canonical blocks
/// will be returned. /// will be returned.
pub fn block_header(&self, id: BlockId) -> Option<encoded::Header> { pub fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
@ -414,6 +430,28 @@ impl HeaderChain {
} }
} }
/// Get a block's chain score.
/// Returns nothing for non-canonical blocks.
pub fn score(&self, id: BlockId) -> Option<U256> {
let genesis_hash = self.genesis_hash();
match id {
BlockId::Earliest | BlockId::Number(0) => Some(self.genesis_header.difficulty()),
BlockId::Hash(hash) if hash == genesis_hash => Some(self.genesis_header.difficulty()),
BlockId::Hash(hash) => match self.block_header(BlockId::Hash(hash)) {
Some(header) => self.candidates.read().get(&header.number())
.and_then(|era| era.candidates.iter().find(|e| e.hash == hash))
.map(|c| c.total_difficulty),
None => None,
},
BlockId::Number(num) => {
let candidates = self.candidates.read();
if self.best_block.read().number < num { return None }
candidates.get(&num).map(|era| era.candidates[0].total_difficulty)
}
BlockId::Latest | BlockId::Pending => Some(self.best_block.read().total_difficulty)
}
}
/// Get the best block's header. /// Get the best block's header.
pub fn best_header(&self) -> encoded::Header { pub fn best_header(&self) -> encoded::Header {
self.block_header(BlockId::Latest).expect("Header for best block always stored; qed") self.block_header(BlockId::Latest).expect("Header for best block always stored; qed")

View File

@ -31,7 +31,7 @@ use ethcore::service::ClientIoMessage;
use ethcore::encoded; use ethcore::encoded;
use io::IoChannel; use io::IoChannel;
use util::{H256, Mutex, RwLock}; use util::{H256, U256, Mutex, RwLock};
use util::kvdb::{KeyValueDB, CompactionProfile}; use util::kvdb::{KeyValueDB, CompactionProfile};
use self::header_chain::{AncestryIter, HeaderChain}; use self::header_chain::{AncestryIter, HeaderChain};
@ -67,18 +67,31 @@ pub trait LightChainClient: Send + Sync {
/// parent queued prior. /// parent queued prior.
fn queue_header(&self, header: Header) -> Result<H256, BlockImportError>; fn queue_header(&self, header: Header) -> Result<H256, BlockImportError>;
/// Attempt to get a block hash by block id.
fn block_hash(&self, id: BlockId) -> Option<H256>;
/// Attempt to get block header by block id. /// Attempt to get block header by block id.
fn block_header(&self, id: BlockId) -> Option<encoded::Header>; fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
/// Get the best block header. /// Get the best block header.
fn best_block_header(&self) -> encoded::Header; fn best_block_header(&self) -> encoded::Header;
/// Get a block's chain score by ID.
fn score(&self, id: BlockId) -> Option<U256>;
/// Get an iterator over a block and its ancestry. /// Get an iterator over a block and its ancestry.
fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a>; fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a>;
/// Get the signing network ID. /// Get the signing network ID.
fn signing_network_id(&self) -> Option<u64>; fn signing_network_id(&self) -> Option<u64>;
/// Get environment info for execution at a given block.
/// Fails if that block's header is not stored.
fn env_info(&self, id: BlockId) -> Option<EnvInfo>;
/// Get a handle to the consensus engine.
fn engine(&self) -> &Arc<Engine>;
/// Query whether a block is known. /// Query whether a block is known.
fn is_known(&self, hash: &H256) -> bool; fn is_known(&self, hash: &H256) -> bool;
@ -93,6 +106,9 @@ pub trait LightChainClient: Send + Sync {
/// Get the `i`th CHT root. /// Get the `i`th CHT root.
fn cht_root(&self, i: usize) -> Option<H256>; fn cht_root(&self, i: usize) -> Option<H256>;
/// Get the EIP-86 transition block number.
fn eip86_transition(&self) -> u64;
} }
/// Something which can be treated as a `LightChainClient`. /// Something which can be treated as a `LightChainClient`.
@ -183,6 +199,11 @@ impl Client {
self.queue.queue_info() self.queue.queue_info()
} }
/// Attempt to get a block hash by block id.
pub fn block_hash(&self, id: BlockId) -> Option<H256> {
self.chain.block_hash(id)
}
/// Get a block header by Id. /// Get a block header by Id.
pub fn block_header(&self, id: BlockId) -> Option<encoded::Header> { pub fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
self.chain.block_header(id) self.chain.block_header(id)
@ -193,6 +214,11 @@ impl Client {
self.chain.best_header() self.chain.best_header()
} }
/// Get a block's chain score.
pub fn score(&self, id: BlockId) -> Option<U256> {
self.chain.score(id)
}
/// Get an iterator over a block and its ancestry. /// Get an iterator over a block and its ancestry.
pub fn ancestry_iter(&self, start: BlockId) -> AncestryIter { pub fn ancestry_iter(&self, start: BlockId) -> AncestryIter {
self.chain.ancestry_iter(start) self.chain.ancestry_iter(start)
@ -310,6 +336,10 @@ impl LightChainClient for Client {
self.import_header(header) self.import_header(header)
} }
fn block_hash(&self, id: BlockId) -> Option<H256> {
Client::block_hash(self, id)
}
fn block_header(&self, id: BlockId) -> Option<encoded::Header> { fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
Client::block_header(self, id) Client::block_header(self, id)
} }
@ -318,6 +348,10 @@ impl LightChainClient for Client {
Client::best_block_header(self) Client::best_block_header(self)
} }
fn score(&self, id: BlockId) -> Option<U256> {
Client::score(self, id)
}
fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a> { fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a> {
Box::new(Client::ancestry_iter(self, start)) Box::new(Client::ancestry_iter(self, start))
} }
@ -326,6 +360,14 @@ impl LightChainClient for Client {
Client::signing_network_id(self) Client::signing_network_id(self)
} }
fn env_info(&self, id: BlockId) -> Option<EnvInfo> {
Client::env_info(self, id)
}
fn engine(&self) -> &Arc<Engine> {
Client::engine(self)
}
fn is_known(&self, hash: &H256) -> bool { fn is_known(&self, hash: &H256) -> bool {
self.status(hash) == BlockStatus::InChain self.status(hash) == BlockStatus::InChain
} }
@ -345,4 +387,8 @@ impl LightChainClient for Client {
fn cht_root(&self, i: usize) -> Option<H256> { fn cht_root(&self, i: usize) -> Option<H256> {
Client::cht_root(self, i) Client::cht_root(self, i)
} }
fn eip86_transition(&self) -> u64 {
self.engine().params().eip86_transition
}
} }

View File

@ -35,7 +35,7 @@ use futures::sync::oneshot::{self, Sender, Receiver};
use network::PeerId; use network::PeerId;
use rlp::RlpStream; use rlp::RlpStream;
use util::{Bytes, RwLock, Mutex, U256, H256}; use util::{Bytes, RwLock, Mutex, U256, H256};
use util::sha3::{SHA3_NULL_RLP, SHA3_EMPTY_LIST_RLP}; use util::sha3::{SHA3_NULL_RLP, SHA3_EMPTY, SHA3_EMPTY_LIST_RLP};
use net::{self, Handler, Status, Capabilities, Announcement, EventContext, BasicContext, ReqId}; use net::{self, Handler, Status, Capabilities, Announcement, EventContext, BasicContext, ReqId};
use cache::Cache; use cache::Cache;
@ -83,7 +83,7 @@ enum Pending {
HeaderByHash(request::HeaderByHash, Sender<encoded::Header>), HeaderByHash(request::HeaderByHash, Sender<encoded::Header>),
Block(request::Body, Sender<encoded::Block>), Block(request::Body, Sender<encoded::Block>),
BlockReceipts(request::BlockReceipts, Sender<Vec<Receipt>>), BlockReceipts(request::BlockReceipts, Sender<Vec<Receipt>>),
Account(request::Account, Sender<Option<BasicAccount>>), Account(request::Account, Sender<BasicAccount>),
Code(request::Code, Sender<Bytes>), Code(request::Code, Sender<Bytes>),
TxProof(request::TransactionProof, Sender<Result<Executed, ExecutionError>>), TxProof(request::TransactionProof, Sender<Result<Executed, ExecutionError>>),
} }
@ -136,18 +136,20 @@ pub struct OnDemand {
pending_requests: RwLock<HashMap<ReqId, Pending>>, pending_requests: RwLock<HashMap<ReqId, Pending>>,
cache: Arc<Mutex<Cache>>, cache: Arc<Mutex<Cache>>,
orphaned_requests: RwLock<Vec<Pending>>, orphaned_requests: RwLock<Vec<Pending>>,
start_nonce: U256,
} }
const RECEIVER_IN_SCOPE: &'static str = "Receiver is still in scope, so it's not dropped; qed"; const RECEIVER_IN_SCOPE: &'static str = "Receiver is still in scope, so it's not dropped; qed";
impl OnDemand { impl OnDemand {
/// Create a new `OnDemand` service with the given cache. /// Create a new `OnDemand` service with the given cache.
pub fn new(cache: Arc<Mutex<Cache>>) -> Self { pub fn new(cache: Arc<Mutex<Cache>>, account_start_nonce: U256) -> Self {
OnDemand { OnDemand {
peers: RwLock::new(HashMap::new()), peers: RwLock::new(HashMap::new()),
pending_requests: RwLock::new(HashMap::new()), pending_requests: RwLock::new(HashMap::new()),
cache: cache, cache: cache,
orphaned_requests: RwLock::new(Vec::new()), orphaned_requests: RwLock::new(Vec::new()),
start_nonce: account_start_nonce,
} }
} }
@ -268,7 +270,7 @@ impl OnDemand {
/// Request an account by address and block header -- which gives a hash to query and a state root /// Request an account by address and block header -- which gives a hash to query and a state root
/// to verify against. /// to verify against.
pub fn account(&self, ctx: &BasicContext, req: request::Account) -> Receiver<Option<BasicAccount>> { pub fn account(&self, ctx: &BasicContext, req: request::Account) -> Receiver<BasicAccount> {
let (sender, receiver) = oneshot::channel(); let (sender, receiver) = oneshot::channel();
self.dispatch(ctx, Pending::Account(req, sender)); self.dispatch(ctx, Pending::Account(req, sender));
receiver receiver
@ -279,7 +281,7 @@ impl OnDemand {
let (sender, receiver) = oneshot::channel(); let (sender, receiver) = oneshot::channel();
// fast path for no code. // fast path for no code.
if req.code_hash == ::util::sha3::SHA3_EMPTY { if req.code_hash == SHA3_EMPTY {
sender.send(Vec::new()).expect(RECEIVER_IN_SCOPE) sender.send(Vec::new()).expect(RECEIVER_IN_SCOPE)
} else { } else {
self.dispatch(ctx, Pending::Code(req, sender)); self.dispatch(ctx, Pending::Code(req, sender));
@ -497,10 +499,19 @@ impl Handler for OnDemand {
Pending::Account(req, sender) => { Pending::Account(req, sender) => {
if let NetworkResponse::Account(ref response) = *response { if let NetworkResponse::Account(ref response) = *response {
match req.check_response(&response.proof) { match req.check_response(&response.proof) {
Ok(maybe_account) => { Ok(account) => {
let account = account.unwrap_or_else(|| {
BasicAccount {
balance: 0.into(),
nonce: self.start_nonce,
code_hash: SHA3_EMPTY,
storage_root: SHA3_NULL_RLP
}
});
// TODO: validate against request outputs. // TODO: validate against request outputs.
// needs engine + env info as part of request. // needs engine + env info as part of request.
let _ = sender.send(maybe_account); let _ = sender.send(account);
return return
} }
Err(e) => warn!(target: "on_demand", "Error handling response for state request: {:?}", e), Err(e) => warn!(target: "on_demand", "Error handling response for state request: {:?}", e),
@ -572,7 +583,7 @@ mod tests {
#[test] #[test]
fn detects_hangup() { fn detects_hangup() {
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::hours(6)))); let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::hours(6))));
let on_demand = OnDemand::new(cache); let on_demand = OnDemand::new(cache, 0.into());
let result = on_demand.header_by_hash(&FakeContext, request::HeaderByHash(H256::default())); let result = on_demand.header_by_hash(&FakeContext, request::HeaderByHash(H256::default()));
assert!(on_demand.orphaned_requests.read().len() == 1); assert!(on_demand.orphaned_requests.read().len() == 1);

View File

@ -30,7 +30,8 @@
"chainID": "0x3d", "chainID": "0x3d",
"forkBlock": "0x1d4c00", "forkBlock": "0x1d4c00",
"forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -14,7 +14,8 @@
"eip155Transition": "0x7fffffffffffffff", "eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff" "eip161dTransition": "0x7fffffffffffffff",
"maxCodeSize": 24576
} }
} }
}, },
@ -23,7 +24,8 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffffff" "eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -14,7 +14,8 @@
"eip155Transition": "0x7fffffffffffffff", "eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x0", "eip160Transition": "0x0",
"eip161abcTransition": "0x0", "eip161abcTransition": "0x0",
"eip161dTransition": "0x0" "eip161dTransition": "0x0",
"maxCodeSize": 24576
} }
} }
}, },
@ -23,7 +24,8 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffffff" "eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -30,7 +30,8 @@
"networkID": "0x1", "networkID": "0x1",
"chainID": "0x2", "chainID": "0x2",
"subprotocolName": "exp", "subprotocolName": "exp",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -147,7 +147,8 @@
"networkID" : "0x1", "networkID" : "0x1",
"forkBlock": "0x1d4c00", "forkBlock": "0x1d4c00",
"forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb", "forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -143,7 +143,8 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -23,7 +23,8 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -23,7 +23,8 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -30,7 +30,8 @@
"chainID": "0x3e", "chainID": "0x3e",
"forkBlock": "0x1b34d8", "forkBlock": "0x1b34d8",
"forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -23,7 +23,8 @@
"maximumExtraDataSize": "0x0400", "maximumExtraDataSize": "0x0400",
"minGasLimit": "125000", "minGasLimit": "125000",
"networkID" : "0x0", "networkID" : "0x0",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -27,7 +27,8 @@
"networkID" : "0x3", "networkID" : "0x3",
"forkBlock": 641350, "forkBlock": 641350,
"forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb", "forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb",
"eip98Transition": "0x7fffffffffffff" "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -139,11 +139,12 @@
} }
}, },
"params": { "params": {
"eip98Transition": "0x7fffffffffffffff",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1" "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -7,7 +7,8 @@
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x2" "networkID" : "0x2",
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -671,8 +671,7 @@ mod tests {
use spec::*; use spec::*;
let spec = Spec::new_test(); let spec = Spec::new_test();
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let b = b.close_and_lock(); let b = b.close_and_lock();
@ -686,16 +685,14 @@ mod tests {
let engine = &*spec.engine; let engine = &*spec.engine;
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap() let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
.close_and_lock().seal(engine, vec![]).unwrap(); .close_and_lock().seal(engine, vec![]).unwrap();
let orig_bytes = b.rlp_bytes(); let orig_bytes = b.rlp_bytes();
let orig_db = b.drain(); let orig_db = b.drain();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap(); let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
assert_eq!(e.rlp_bytes(), orig_bytes); assert_eq!(e.rlp_bytes(), orig_bytes);
@ -712,8 +709,7 @@ mod tests {
let engine = &*spec.engine; let engine = &*spec.engine;
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let mut uncle1_header = Header::new(); let mut uncle1_header = Header::new();
@ -727,8 +723,7 @@ mod tests {
let orig_bytes = b.rlp_bytes(); let orig_bytes = b.rlp_bytes();
let orig_db = b.drain(); let orig_db = b.drain();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap(); let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
let bytes = e.rlp_bytes(); let bytes = e.rlp_bytes();

View File

@ -1859,15 +1859,13 @@ mod tests {
#[test] #[test]
fn can_contain_arbitrary_block_sequence() { fn can_contain_arbitrary_block_sequence() {
let bc_result = generate_dummy_blockchain(50); let bc = generate_dummy_blockchain(50);
let bc = bc_result.reference();
assert_eq!(bc.best_block_number(), 49); assert_eq!(bc.best_block_number(), 49);
} }
#[test] #[test]
fn can_collect_garbage() { fn can_collect_garbage() {
let bc_result = generate_dummy_blockchain(3000); let bc = generate_dummy_blockchain(3000);
let bc = bc_result.reference();
assert_eq!(bc.best_block_number(), 2999); assert_eq!(bc.best_block_number(), 2999);
let best_hash = bc.best_block_hash(); let best_hash = bc.best_block_hash();
@ -1886,15 +1884,13 @@ mod tests {
#[test] #[test]
fn can_contain_arbitrary_block_sequence_with_extra() { fn can_contain_arbitrary_block_sequence_with_extra() {
let bc_result = generate_dummy_blockchain_with_extra(25); let bc = generate_dummy_blockchain_with_extra(25);
let bc = bc_result.reference();
assert_eq!(bc.best_block_number(), 24); assert_eq!(bc.best_block_number(), 24);
} }
#[test] #[test]
fn can_contain_only_genesis_block() { fn can_contain_only_genesis_block() {
let bc_result = generate_dummy_empty_blockchain(); let bc = generate_dummy_empty_blockchain();
let bc = bc_result.reference();
assert_eq!(bc.best_block_number(), 0); assert_eq!(bc.best_block_number(), 0);
} }

View File

@ -1054,7 +1054,7 @@ impl BlockChainClient for Client {
return Err(err.into()) return Err(err.into())
} }
} }
let lower = t.gas_required(&self.engine.schedule(&env_info)).into(); let lower = t.gas_required(&self.engine.schedule(env_info.number)).into();
if cond(lower)? { if cond(lower)? {
trace!(target: "estimate_gas", "estimate_gas succeeded with {}", lower); trace!(target: "estimate_gas", "estimate_gas succeeded with {}", lower);
return Ok(lower) return Ok(lower)
@ -1353,7 +1353,8 @@ impl BlockChainClient for Client {
.collect(); .collect();
match (transaction, previous_receipts) { match (transaction, previous_receipts) {
(Some(transaction), Some(previous_receipts)) => { (Some(transaction), Some(previous_receipts)) => {
Some(transaction_receipt(transaction, previous_receipts)) let schedule = self.engine().schedule(block_number);
Some(transaction_receipt(&schedule, transaction, previous_receipts))
}, },
_ => None, _ => None,
} }
@ -1587,11 +1588,15 @@ impl BlockChainClient for Client {
}) })
.and_then(|a| if a.is_zero() { None } else { Some(a) }) .and_then(|a| if a.is_zero() { None } else { Some(a) })
} }
fn eip86_transition(&self) -> u64 {
self.engine().params().eip86_transition
}
} }
impl MiningBlockChainClient for Client { impl MiningBlockChainClient for Client {
fn latest_schedule(&self) -> Schedule { fn latest_schedule(&self) -> Schedule {
self.engine.schedule(&self.latest_env_info()) self.engine.schedule(self.latest_env_info().number)
} }
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock { fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
@ -1742,7 +1747,7 @@ impl Drop for Client {
/// Returns `LocalizedReceipt` given `LocalizedTransaction` /// Returns `LocalizedReceipt` given `LocalizedTransaction`
/// and a vector of receipts from given block up to transaction index. /// and a vector of receipts from given block up to transaction index.
fn transaction_receipt(mut tx: LocalizedTransaction, mut receipts: Vec<Receipt>) -> LocalizedReceipt { fn transaction_receipt(schedule: &Schedule, mut tx: LocalizedTransaction, mut receipts: Vec<Receipt>) -> LocalizedReceipt {
assert_eq!(receipts.len(), tx.transaction_index + 1, "All previous receipts are provided."); assert_eq!(receipts.len(), tx.transaction_index + 1, "All previous receipts are provided.");
let sender = tx.sender(); let sender = tx.sender();
@ -1761,12 +1766,12 @@ fn transaction_receipt(mut tx: LocalizedTransaction, mut receipts: Vec<Receipt>)
transaction_hash: transaction_hash, transaction_hash: transaction_hash,
transaction_index: transaction_index, transaction_index: transaction_index,
block_hash: block_hash, block_hash: block_hash,
block_number:block_number, block_number: block_number,
cumulative_gas_used: receipt.gas_used, cumulative_gas_used: receipt.gas_used,
gas_used: receipt.gas_used - prior_gas_used, gas_used: receipt.gas_used - prior_gas_used,
contract_address: match tx.action { contract_address: match tx.action {
Action::Call(_) => None, Action::Call(_) => None,
Action::Create => Some(contract_address(&sender, &tx.nonce)) Action::Create => Some(contract_address(schedule.create_address, &sender, &tx.nonce, &tx.data.sha3()))
}, },
logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry { logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry {
entry: log, entry: log,
@ -1804,7 +1809,7 @@ mod tests {
// Separate thread uncommited transaction // Separate thread uncommited transaction
let go = Arc::new(AtomicBool::new(false)); let go = Arc::new(AtomicBool::new(false));
let go_thread = go.clone(); let go_thread = go.clone();
let another_client = client.reference().clone(); let another_client = client.clone();
thread::spawn(move || { thread::spawn(move || {
let mut batch = DBTransaction::new(); let mut batch = DBTransaction::new();
another_client.chain.read().insert_block(&mut batch, &new_block, Vec::new()); another_client.chain.read().insert_block(&mut batch, &new_block, Vec::new());
@ -1821,6 +1826,7 @@ mod tests {
#[test] #[test]
fn should_return_correct_log_index() { fn should_return_correct_log_index() {
use super::transaction_receipt; use super::transaction_receipt;
use evm::schedule::Schedule;
use ethkey::KeyPair; use ethkey::KeyPair;
use log_entry::{LogEntry, LocalizedLogEntry}; use log_entry::{LogEntry, LocalizedLogEntry};
use receipt::{Receipt, LocalizedReceipt}; use receipt::{Receipt, LocalizedReceipt};
@ -1830,6 +1836,7 @@ mod tests {
// given // given
let key = KeyPair::from_secret_slice(&"test".sha3()).unwrap(); let key = KeyPair::from_secret_slice(&"test".sha3()).unwrap();
let secret = key.secret(); let secret = key.secret();
let schedule = Schedule::new_homestead();
let block_number = 1; let block_number = 1;
let block_hash = 5.into(); let block_hash = 5.into();
@ -1873,7 +1880,7 @@ mod tests {
}]; }];
// when // when
let receipt = transaction_receipt(transaction, receipts); let receipt = transaction_receipt(&schedule, transaction, receipts);
// then // then
assert_eq!(receipt, LocalizedReceipt { assert_eq!(receipt, LocalizedReceipt {

View File

@ -353,7 +353,7 @@ pub fn get_temp_state_db() -> GuardedTempResult<StateDB> {
impl MiningBlockChainClient for TestBlockChainClient { impl MiningBlockChainClient for TestBlockChainClient {
fn latest_schedule(&self) -> Schedule { fn latest_schedule(&self) -> Schedule {
Schedule::new_post_eip150(24576, true, true, true) Schedule::new_post_eip150(24576, true, true, true, true)
} }
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock { fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
@ -756,6 +756,8 @@ impl BlockChainClient for TestBlockChainClient {
fn registrar_address(&self) -> Option<Address> { None } fn registrar_address(&self) -> Option<Address> { None }
fn registry_address(&self, _name: String) -> Option<Address> { None } fn registry_address(&self, _name: String) -> Option<Address> { None }
fn eip86_transition(&self) -> u64 { u64::max_value() }
} }
impl ProvingBlockChainClient for TestBlockChainClient { impl ProvingBlockChainClient for TestBlockChainClient {

View File

@ -272,6 +272,9 @@ pub trait BlockChainClient : Sync + Send {
/// Get the address of a particular blockchain service, if available. /// Get the address of a particular blockchain service, if available.
fn registry_address(&self, name: String) -> Option<Address>; fn registry_address(&self, name: String) -> Option<Address>;
/// Get the EIP-86 transition block number.
fn eip86_transition(&self) -> u64;
} }
impl IpcConfig for BlockChainClient { } impl IpcConfig for BlockChainClient { }

View File

@ -26,12 +26,11 @@ use account_provider::AccountProvider;
use block::*; use block::*;
use spec::CommonParams; use spec::CommonParams;
use engines::{Call, Engine, Seal, EngineError}; use engines::{Call, Engine, Seal, EngineError};
use header::Header; use header::{Header, BlockNumber};
use error::{Error, TransactionError, BlockError}; use error::{Error, TransactionError, BlockError};
use evm::Schedule; use evm::Schedule;
use ethjson; use ethjson;
use io::{IoContext, IoHandler, TimerToken, IoService}; use io::{IoContext, IoHandler, TimerToken, IoService};
use env_info::EnvInfo;
use builtin::Builtin; use builtin::Builtin;
use transaction::UnverifiedTransaction; use transaction::UnverifiedTransaction;
use client::{Client, EngineClient}; use client::{Client, EngineClient};
@ -290,8 +289,9 @@ impl Engine for AuthorityRound {
] ]
} }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { fn schedule(&self, block_number: BlockNumber) -> Schedule {
Schedule::new_post_eip150(usize::max_value(), true, true, true) let eip86 = block_number >= self.params.eip86_transition;
Schedule::new_post_eip150(usize::max_value(), true, true, true, eip86)
} }
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) {
@ -451,7 +451,6 @@ impl Engine for AuthorityRound {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use util::*; use util::*;
use env_info::EnvInfo;
use header::Header; use header::Header;
use error::{Error, BlockError}; use error::{Error, BlockError};
use ethkey::Secret; use ethkey::Secret;
@ -472,15 +471,7 @@ mod tests {
#[test] #[test]
fn can_return_schedule() { fn can_return_schedule() {
let engine = Spec::new_test_round().engine; let engine = Spec::new_test_round().engine;
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(10000000);
number: 10000000,
author: 0.into(),
timestamp: 0,
difficulty: 0.into(),
last_hashes: Arc::new(vec![]),
gas_used: 0.into(),
gas_limit: 0.into(),
});
assert!(schedule.stack_limit > 0); assert!(schedule.stack_limit > 0);
} }
@ -518,8 +509,8 @@ mod tests {
let spec = Spec::new_test_round(); let spec = Spec::new_test_round();
let engine = &*spec.engine; let engine = &*spec.engine;
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let db1 = spec.ensure_db_good(get_temp_state_db().take(), &Default::default()).unwrap(); let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db2 = spec.ensure_db_good(get_temp_state_db().take(), &Default::default()).unwrap(); let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap();
let b1 = b1.close_and_lock(); let b1 = b1.close_and_lock();

View File

@ -24,11 +24,10 @@ use block::*;
use builtin::Builtin; use builtin::Builtin;
use spec::CommonParams; use spec::CommonParams;
use engines::{Engine, EngineError, Seal, Call, EpochChange}; use engines::{Engine, EngineError, Seal, Call, EpochChange};
use env_info::EnvInfo;
use error::{BlockError, Error}; use error::{BlockError, Error};
use evm::Schedule; use evm::Schedule;
use ethjson; use ethjson;
use header::Header; use header::{Header, BlockNumber};
use client::Client; use client::Client;
use super::signer::EngineSigner; use super::signer::EngineSigner;
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
@ -110,7 +109,7 @@ impl Engine for BasicAuthority {
/// Additional engine-specific information for the user/developer concerning `header`. /// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { map!["signature".to_owned() => "TODO".to_owned()] } fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { map!["signature".to_owned() => "TODO".to_owned()] }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { fn schedule(&self, _block_number: BlockNumber) -> Schedule {
Schedule::new_homestead() Schedule::new_homestead()
} }
@ -223,7 +222,6 @@ impl Engine for BasicAuthority {
mod tests { mod tests {
use util::*; use util::*;
use block::*; use block::*;
use env_info::EnvInfo;
use error::{BlockError, Error}; use error::{BlockError, Error};
use tests::helpers::*; use tests::helpers::*;
use account_provider::AccountProvider; use account_provider::AccountProvider;
@ -248,16 +246,7 @@ mod tests {
#[test] #[test]
fn can_return_schedule() { fn can_return_schedule() {
let engine = new_test_authority().engine; let engine = new_test_authority().engine;
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(10000000);
number: 10000000,
author: 0.into(),
timestamp: 0,
difficulty: 0.into(),
last_hashes: Arc::new(vec![]),
gas_used: 0.into(),
gas_limit: 0.into(),
});
assert!(schedule.stack_limit > 0); assert!(schedule.stack_limit > 0);
} }
@ -294,8 +283,7 @@ mod tests {
let engine = &*spec.engine; let engine = &*spec.engine;
engine.set_signer(Arc::new(tap), addr, "".into()); engine.set_signer(Arc::new(tap), addr, "".into());
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
let b = b.close_and_lock(); let b = b.close_and_lock();

View File

@ -18,10 +18,10 @@ use std::collections::BTreeMap;
use util::{Address, HashMap}; use util::{Address, HashMap};
use builtin::Builtin; use builtin::Builtin;
use engines::{Engine, Seal}; use engines::{Engine, Seal};
use env_info::EnvInfo;
use spec::CommonParams; use spec::CommonParams;
use evm::Schedule; use evm::Schedule;
use block::ExecutedBlock; use block::ExecutedBlock;
use header::BlockNumber;
/// An engine which does not provide any consensus mechanism, just seals blocks internally. /// An engine which does not provide any consensus mechanism, just seals blocks internally.
pub struct InstantSeal { pub struct InstantSeal {
@ -58,8 +58,9 @@ impl Engine for InstantSeal {
&self.builtins &self.builtins
} }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { fn schedule(&self, block_number: BlockNumber) -> Schedule {
Schedule::new_post_eip150(usize::max_value(), true, true, true) let eip86 = block_number >= self.params.eip86_transition;
Schedule::new_post_eip150(usize::max_value(), true, true, true, eip86)
} }
fn seals_internally(&self) -> Option<bool> { Some(true) } fn seals_internally(&self) -> Option<bool> { Some(true) }
@ -82,8 +83,7 @@ mod tests {
fn instant_can_seal() { fn instant_can_seal() {
let spec = Spec::new_instant(); let spec = Spec::new_instant();
let engine = &*spec.engine; let engine = &*spec.engine;
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap();

View File

@ -41,13 +41,13 @@ use block::ExecutedBlock;
use builtin::Builtin; use builtin::Builtin;
use client::Client; use client::Client;
use env_info::EnvInfo; use env_info::EnvInfo;
use error::{Error, TransactionError}; use error::Error;
use evm::Schedule; use evm::Schedule;
use header::Header; use header::{Header, BlockNumber};
use spec::CommonParams;
use snapshot::SnapshotComponents;
use transaction::{UnverifiedTransaction, SignedTransaction};
use receipt::Receipt; use receipt::Receipt;
use snapshot::SnapshotComponents;
use spec::CommonParams;
use transaction::{UnverifiedTransaction, SignedTransaction};
use ethkey::Signature; use ethkey::Signature;
use util::*; use util::*;
@ -141,8 +141,8 @@ pub trait Engine : Sync + Send {
/// Get the general parameters of the chain. /// Get the general parameters of the chain.
fn params(&self) -> &CommonParams; fn params(&self) -> &CommonParams;
/// Get the EVM schedule for the given `env_info`. /// Get the EVM schedule for the given `block_number`.
fn schedule(&self, env_info: &EnvInfo) -> Schedule; fn schedule(&self, block_number: BlockNumber) -> Schedule;
/// Builtin-contracts we would like to see in the chain. /// Builtin-contracts we would like to see in the chain.
/// (In principle these are just hints for the engine since that has the last word on them.) /// (In principle these are just hints for the engine since that has the last word on them.)
@ -193,14 +193,7 @@ pub trait Engine : Sync + Send {
// TODO: Add flags for which bits of the transaction to check. // TODO: Add flags for which bits of the transaction to check.
// TODO: consider including State in the params. // TODO: consider including State in the params.
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> { fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> {
t.check_low_s()?; t.verify_basic(true, Some(self.params().network_id), true)?;
if let Some(n) = t.network_id() {
if n != self.params().chain_id {
return Err(TransactionError::InvalidNetworkId.into());
}
}
Ok(()) Ok(())
} }

View File

@ -20,7 +20,7 @@ use builtin::Builtin;
use engines::Engine; use engines::Engine;
use spec::CommonParams; use spec::CommonParams;
use evm::Schedule; use evm::Schedule;
use env_info::EnvInfo; use header::BlockNumber;
/// An engine which does not provide any consensus mechanism and does not seal blocks. /// An engine which does not provide any consensus mechanism and does not seal blocks.
pub struct NullEngine { pub struct NullEngine {
@ -57,7 +57,7 @@ impl Engine for NullEngine {
&self.builtins &self.builtins
} }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { fn schedule(&self, _block_number: BlockNumber) -> Schedule {
Schedule::new_homestead() Schedule::new_homestead()
} }

View File

@ -30,9 +30,8 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use util::*; use util::*;
use client::{Client, EngineClient}; use client::{Client, EngineClient};
use error::{Error, BlockError}; use error::{Error, BlockError};
use header::Header; use header::{Header, BlockNumber};
use builtin::Builtin; use builtin::Builtin;
use env_info::EnvInfo;
use rlp::UntrustedRlp; use rlp::UntrustedRlp;
use ethkey::{recover, public_to_address, Signature}; use ethkey::{recover, public_to_address, Signature};
use account_provider::AccountProvider; use account_provider::AccountProvider;
@ -405,8 +404,9 @@ impl Engine for Tendermint {
] ]
} }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { fn schedule(&self, block_number: BlockNumber) -> Schedule {
Schedule::new_post_eip150(usize::max_value(), true, true, true) let eip86 = block_number >= self.params.eip86_transition;
Schedule::new_post_eip150(usize::max_value(), true, true, true, eip86)
} }
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) {
@ -658,7 +658,6 @@ mod tests {
use block::*; use block::*;
use error::{Error, BlockError}; use error::{Error, BlockError};
use header::Header; use header::Header;
use env_info::EnvInfo;
use ethkey::Secret; use ethkey::Secret;
use client::chain_notify::ChainNotify; use client::chain_notify::ChainNotify;
use miner::MinerService; use miner::MinerService;
@ -676,8 +675,8 @@ mod tests {
} }
fn propose_default(spec: &Spec, proposer: Address) -> (ClosedBlock, Vec<Bytes>) { fn propose_default(spec: &Spec, proposer: Address) -> (ClosedBlock, Vec<Bytes>) {
let mut db_result = get_temp_state_db(); let db = get_temp_state_db();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); let db = spec.ensure_db_good(db, &Default::default()).unwrap();
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![]).unwrap();
@ -740,15 +739,7 @@ mod tests {
#[test] #[test]
fn can_return_schedule() { fn can_return_schedule() {
let engine = Spec::new_test_tendermint().engine; let engine = Spec::new_test_tendermint().engine;
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(10000000);
number: 10000000,
author: 0.into(),
timestamp: 0,
difficulty: 0.into(),
last_hashes: Arc::new(vec![]),
gas_used: 0.into(),
gas_limit: 0.into(),
});
assert!(schedule.stack_limit > 0); assert!(schedule.stack_limit > 0);
} }

View File

@ -298,6 +298,7 @@ mod tests {
let s0 = Secret::from_slice(&"1".sha3()).unwrap(); let s0 = Secret::from_slice(&"1".sha3()).unwrap();
let v0 = tap.insert_account(s0.clone(), "").unwrap(); let v0 = tap.insert_account(s0.clone(), "").unwrap();
let v1 = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "").unwrap(); let v1 = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "").unwrap();
let network_id = Spec::new_validator_safe_contract().network_id();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap)); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
client.engine().register_client(Arc::downgrade(&client)); client.engine().register_client(Arc::downgrade(&client));
let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap();
@ -311,7 +312,7 @@ mod tests {
action: Action::Call(validator_contract), action: Action::Call(validator_contract),
value: 0.into(), value: 0.into(),
data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
}.sign(&s0, None); }.sign(&s0, Some(network_id));
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
client.update_sealing(); client.update_sealing();
assert_eq!(client.chain_info().best_block_number, 1); assert_eq!(client.chain_info().best_block_number, 1);
@ -323,7 +324,7 @@ mod tests {
action: Action::Call(validator_contract), action: Action::Call(validator_contract),
value: 0.into(), value: 0.into(),
data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
}.sign(&s0, None); }.sign(&s0, Some(network_id));
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
client.update_sealing(); client.update_sealing();
// The transaction is not yet included so still unable to seal. // The transaction is not yet included so still unable to seal.
@ -342,7 +343,7 @@ mod tests {
action: Action::Call(Address::default()), action: Action::Call(Address::default()),
value: 0.into(), value: 0.into(),
data: Vec::new(), data: Vec::new(),
}.sign(&s0, None); }.sign(&s0, Some(network_id));
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
client.update_sealing(); client.update_sealing();
// Able to seal again. // Able to seal again.

View File

@ -19,8 +19,8 @@ use util::*;
use block::*; use block::*;
use builtin::Builtin; use builtin::Builtin;
use env_info::EnvInfo; use env_info::EnvInfo;
use error::{BlockError, TransactionError, Error}; use error::{BlockError, Error, TransactionError};
use header::Header; use header::{Header, BlockNumber};
use state::CleanupMode; use state::CleanupMode;
use spec::CommonParams; use spec::CommonParams;
use transaction::UnverifiedTransaction; use transaction::UnverifiedTransaction;
@ -183,19 +183,20 @@ impl Engine for Arc<Ethash> {
map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())] map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())]
} }
fn schedule(&self, env_info: &EnvInfo) -> Schedule { fn schedule(&self, block_number: BlockNumber) -> Schedule {
trace!(target: "client", "Creating schedule. fCML={}, bGCML={}", self.ethash_params.homestead_transition, self.ethash_params.eip150_transition); trace!(target: "client", "Creating schedule. fCML={}, bGCML={}", self.ethash_params.homestead_transition, self.ethash_params.eip150_transition);
if env_info.number < self.ethash_params.homestead_transition { if block_number < self.ethash_params.homestead_transition {
Schedule::new_frontier() Schedule::new_frontier()
} else if env_info.number < self.ethash_params.eip150_transition { } else if block_number < self.ethash_params.eip150_transition {
Schedule::new_homestead() Schedule::new_homestead()
} else { } else {
Schedule::new_post_eip150( Schedule::new_post_eip150(
self.ethash_params.max_code_size as usize, self.ethash_params.max_code_size as usize,
env_info.number >= self.ethash_params.eip160_transition, block_number >= self.ethash_params.eip160_transition,
env_info.number >= self.ethash_params.eip161abc_transition, block_number >= self.ethash_params.eip161abc_transition,
env_info.number >= self.ethash_params.eip161d_transition block_number >= self.ethash_params.eip161d_transition,
block_number >= self.params.eip86_transition
) )
} }
} }
@ -385,20 +386,13 @@ impl Engine for Arc<Ethash> {
} }
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> {
if header.number() >= self.ethash_params.homestead_transition {
t.check_low_s()?;
}
if let Some(n) = t.network_id() {
if header.number() < self.ethash_params.eip155_transition || n != self.params().chain_id {
return Err(TransactionError::InvalidNetworkId.into())
}
}
if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price { if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price {
return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into()); return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into());
} }
let check_low_s = header.number() >= self.ethash_params.homestead_transition;
let network_id = if header.number() >= self.ethash_params.eip155_transition { Some(self.params().chain_id) } else { None };
t.verify_basic(check_low_s, network_id, false)?;
Ok(()) Ok(())
} }
@ -536,7 +530,6 @@ mod tests {
use block::*; use block::*;
use tests::helpers::*; use tests::helpers::*;
use engines::Engine; use engines::Engine;
use env_info::EnvInfo;
use error::{BlockError, Error}; use error::{BlockError, Error};
use header::Header; use header::Header;
use super::super::{new_morden, new_homestead_test}; use super::super::{new_morden, new_homestead_test};
@ -548,8 +541,7 @@ mod tests {
let spec = new_morden(); let spec = new_morden();
let engine = &*spec.engine; let engine = &*spec.engine;
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let b = b.close(); let b = b.close();
@ -561,8 +553,7 @@ mod tests {
let spec = new_morden(); let spec = new_morden();
let engine = &*spec.engine; let engine = &*spec.engine;
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]); let last_hashes = Arc::new(vec![genesis_header.hash()]);
let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let mut uncle = Header::new(); let mut uncle = Header::new();
@ -585,28 +576,10 @@ mod tests {
#[test] #[test]
fn can_return_schedule() { fn can_return_schedule() {
let engine = new_morden().engine; let engine = new_morden().engine;
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(10000000);
number: 10000000,
author: 0.into(),
timestamp: 0,
difficulty: 0.into(),
last_hashes: Arc::new(vec![]),
gas_used: 0.into(),
gas_limit: 0.into(),
});
assert!(schedule.stack_limit > 0); assert!(schedule.stack_limit > 0);
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(100);
number: 100,
author: 0.into(),
timestamp: 0,
difficulty: 0.into(),
last_hashes: Arc::new(vec![]),
gas_used: 0.into(),
gas_limit: 0.into(),
});
assert!(!schedule.have_delegate_call); assert!(!schedule.have_delegate_call);
} }

View File

@ -94,8 +94,7 @@ mod tests {
let spec = new_morden(); let spec = new_morden();
let engine = &spec.engine; let engine = &spec.engine;
let genesis_header = spec.genesis_header(); let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap(); let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap();
assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()).unwrap(), 1u64.into()); assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()).unwrap(), 1u64.into());
assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()).unwrap(), 1u64.into()); assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()).unwrap(), 1u64.into());

View File

@ -41,6 +41,17 @@ pub enum MessageCallResult {
Failed Failed
} }
/// Specifies how an address is calculated for a new contract.
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum CreateContractAddress {
/// Address is calculated from nonce and sender. Pre EIP-86 (Metropolis)
FromSenderAndNonce,
/// Address is calculated from code hash. Default since EIP-86
FromCodeHash,
/// Address is calculated from code hash and sender. Used by CREATE_P2SH instruction.
FromSenderAndCodeHash,
}
/// Externalities interface for EVMs /// Externalities interface for EVMs
// TODO: [rob] associated error type instead of `trie::Result`. Not all EVMs are trie powered. // TODO: [rob] associated error type instead of `trie::Result`. Not all EVMs are trie powered.
pub trait Ext { pub trait Ext {
@ -68,7 +79,7 @@ pub trait Ext {
/// Creates new contract. /// Creates new contract.
/// ///
/// Returns gas_left and contract address if contract creation was succesfull. /// Returns gas_left and contract address if contract creation was succesfull.
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult; fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult;
/// Message call. /// Message call.
/// ///

View File

@ -278,6 +278,7 @@ lazy_static! {
arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::Zero); arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::Zero);
arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::Special); arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::Special);
arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::Special); arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::Special);
arr[CREATE_P2SH as usize] = InstructionInfo::new("CREATE_P2SH", 0, 3, 1, true, GasPriceTier::Special);
arr arr
}; };
} }
@ -553,6 +554,8 @@ pub const CALLCODE: Instruction = 0xf2;
pub const RETURN: Instruction = 0xf3; pub const RETURN: Instruction = 0xf3;
/// like CALLCODE but keeps caller's value and sender /// like CALLCODE but keeps caller's value and sender
pub const DELEGATECALL: Instruction = 0xf4; pub const DELEGATECALL: Instruction = 0xf4;
/// create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160
pub const CREATE_P2SH: Instruction = 0xfb;
/// halt execution and register account for later deletion /// halt execution and register account for later deletion
pub const SUICIDE: Instruction = 0xff; pub const SUICIDE: Instruction = 0xff;

View File

@ -223,7 +223,7 @@ impl<Gas: CostType> Gasometer<Gas> {
Request::GasMemProvide(gas, mem, Some(requested)) Request::GasMemProvide(gas, mem, Some(requested))
}, },
instructions::CREATE => { instructions::CREATE | instructions::CREATE_P2SH => {
let gas = Gas::from(schedule.create_gas); let gas = Gas::from(schedule.create_gas);
let mem = mem_needed(stack.peek(1), stack.peek(2))?; let mem = mem_needed(stack.peek(1), stack.peek(2))?;

View File

@ -32,7 +32,7 @@ use std::marker::PhantomData;
use action_params::{ActionParams, ActionValue}; use action_params::{ActionParams, ActionValue};
use types::executed::CallType; use types::executed::CallType;
use evm::instructions::{self, Instruction, InstructionInfo}; use evm::instructions::{self, Instruction, InstructionInfo};
use evm::{self, MessageCallResult, ContractCreateResult, GasLeft, CostType}; use evm::{self, MessageCallResult, ContractCreateResult, GasLeft, CostType, CreateContractAddress};
use bit_set::BitSet; use bit_set::BitSet;
use util::*; use util::*;
@ -182,7 +182,9 @@ 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: &evm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack<U256>) -> evm::Result<()> {
let schedule = ext.schedule(); let schedule = ext.schedule();
if !schedule.have_delegate_call && instruction == instructions::DELEGATECALL { if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) ||
(instruction == instructions::CREATE_P2SH && !schedule.have_create_p2sh) {
return Err(evm::Error::BadInstruction { return Err(evm::Error::BadInstruction {
instruction: instruction instruction: instruction
}); });
@ -266,10 +268,12 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::JUMPDEST => { instructions::JUMPDEST => {
// ignore // ignore
}, },
instructions::CREATE => { instructions::CREATE | instructions::CREATE_P2SH => {
let endowment = stack.pop_back(); let endowment = stack.pop_back();
let init_off = stack.pop_back(); let init_off = stack.pop_back();
let init_size = stack.pop_back(); let init_size = stack.pop_back();
let address_scheme = if instruction == instructions::CREATE { ext.schedule().create_address } else { CreateContractAddress::FromSenderAndCodeHash };
let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed"); let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed");
let contract_code = self.mem.read_slice(init_off, init_size); let contract_code = self.mem.read_slice(init_off, init_size);
@ -280,7 +284,7 @@ impl<Cost: CostType> Interpreter<Cost> {
return Ok(InstructionResult::UnusedGas(create_gas)); return Ok(InstructionResult::UnusedGas(create_gas));
} }
let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code); let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme);
return match create_result { return match create_result {
ContractCreateResult::Created(address, gas_left) => { ContractCreateResult::Created(address, gas_left) => {
stack.push(address_to_u256(address)); stack.push(address_to_u256(address));

View File

@ -32,7 +32,7 @@ mod tests;
mod benches; mod benches;
pub use self::evm::{Evm, Error, Finalize, GasLeft, Result, CostType}; pub use self::evm::{Evm, Error, Finalize, GasLeft, Result, CostType};
pub use self::ext::{Ext, ContractCreateResult, MessageCallResult}; pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress};
pub use self::factory::{Factory, VMType}; pub use self::factory::{Factory, VMType};
pub use self::schedule::Schedule; pub use self::schedule::Schedule;
pub use types::executed::CallType; pub use types::executed::CallType;

View File

@ -15,6 +15,7 @@
// 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 evm::CreateContractAddress;
/// 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 {
@ -22,6 +23,8 @@ pub struct Schedule {
pub exceptional_failed_code_deposit: bool, pub exceptional_failed_code_deposit: bool,
/// Does it have a delegate cal /// Does it have a delegate cal
pub have_delegate_call: bool, pub have_delegate_call: bool,
/// Does it have a CREATE_P2SH instruction
pub have_create_p2sh: bool,
/// VM stack limit /// VM stack limit
pub stack_limit: usize, pub stack_limit: usize,
/// Max number of nested calls/creates /// Max number of nested calls/creates
@ -99,6 +102,8 @@ pub struct Schedule {
pub no_empty: bool, pub no_empty: bool,
/// Kill empty accounts if touched. /// Kill empty accounts if touched.
pub kill_empty: bool, pub kill_empty: bool,
/// Contract address generation scheme
pub create_address: CreateContractAddress,
} }
impl Schedule { impl Schedule {
@ -113,10 +118,11 @@ impl Schedule {
} }
/// Schedule for the post-EIP-150-era of the Ethereum main net. /// Schedule for the post-EIP-150-era of the Ethereum main net.
pub fn new_post_eip150(max_code_size: usize, fix_exp: bool, no_empty: bool, kill_empty: bool) -> Schedule { pub fn new_post_eip150(max_code_size: usize, fix_exp: bool, no_empty: bool, kill_empty: bool, have_create_p2sh: bool) -> Schedule {
Schedule { Schedule {
exceptional_failed_code_deposit: true, exceptional_failed_code_deposit: true,
have_delegate_call: true, have_delegate_call: true,
have_create_p2sh: have_create_p2sh,
stack_limit: 1024, stack_limit: 1024,
max_depth: 1024, max_depth: 1024,
tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0],
@ -155,13 +161,20 @@ impl Schedule {
sub_gas_cap_divisor: Some(64), sub_gas_cap_divisor: Some(64),
no_empty: no_empty, no_empty: no_empty,
kill_empty: kill_empty, kill_empty: kill_empty,
create_address: if have_create_p2sh { CreateContractAddress::FromCodeHash } else { CreateContractAddress::FromSenderAndNonce },
} }
} }
/// Schedule for the Metropolis of the Ethereum main net.
pub fn new_metropolis() -> Schedule {
Self::new_post_eip150(24576, true, true, true, true)
}
fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule { fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule {
Schedule { Schedule {
exceptional_failed_code_deposit: efcd, exceptional_failed_code_deposit: efcd,
have_delegate_call: hdc, have_delegate_call: hdc,
have_create_p2sh: false,
stack_limit: 1024, stack_limit: 1024,
max_depth: 1024, max_depth: 1024,
tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0],
@ -200,6 +213,7 @@ impl Schedule {
sub_gas_cap_divisor: None, sub_gas_cap_divisor: None,
no_empty: false, no_empty: false,
kill_empty: false, kill_empty: false,
create_address: CreateContractAddress::FromSenderAndNonce,
} }
} }
} }

View File

@ -18,7 +18,7 @@ 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 types::executed::CallType;
use evm::{self, Ext, Schedule, Factory, GasLeft, VMType, ContractCreateResult, MessageCallResult}; use evm::{self, Ext, Schedule, Factory, GasLeft, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress};
use std::fmt::Debug; use std::fmt::Debug;
pub struct FakeLogEntry { pub struct FakeLogEntry {
@ -111,7 +111,7 @@ impl Ext for FakeExt {
self.blockhashes.get(number).unwrap_or(&H256::new()).clone() self.blockhashes.get(number).unwrap_or(&H256::new()).clone()
} }
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { fn create(&mut self, gas: &U256, value: &U256, code: &[u8], _address: CreateContractAddress) -> ContractCreateResult {
self.calls.insert(FakeCall { self.calls.insert(FakeCall {
call_type: FakeCallType::Create, call_type: FakeCallType::Create,
gas: *gas, gas: *gas,

View File

@ -22,7 +22,7 @@ use engines::Engine;
use types::executed::CallType; use types::executed::CallType;
use env_info::EnvInfo; use env_info::EnvInfo;
use error::ExecutionError; use error::ExecutionError;
use evm::{self, Ext, Factory, Finalize}; use evm::{self, Ext, Factory, Finalize, CreateContractAddress};
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};
@ -34,14 +34,29 @@ pub use types::executed::{Executed, ExecutionResult};
/// Maybe something like here: `https://github.com/ethereum/libethereum/blob/4db169b8504f2b87f7d5a481819cfb959fc65f6c/libethereum/ExtVM.cpp` /// Maybe something like here: `https://github.com/ethereum/libethereum/blob/4db169b8504f2b87f7d5a481819cfb959fc65f6c/libethereum/ExtVM.cpp`
const STACK_SIZE_PER_DEPTH: usize = 24*1024; const STACK_SIZE_PER_DEPTH: usize = 24*1024;
/// Returns new address created from address and given nonce. /// Returns new address created from address, nonce, and code hash
pub fn contract_address(address: &Address, nonce: &U256) -> Address { pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address, nonce: &U256, code_hash: &H256) -> Address {
use rlp::RlpStream; use rlp::RlpStream;
let mut stream = RlpStream::new_list(2); match address_scheme {
stream.append(address); CreateContractAddress::FromSenderAndNonce => {
stream.append(nonce); let mut stream = RlpStream::new_list(2);
From::from(stream.out().sha3()) stream.append(sender);
stream.append(nonce);
From::from(stream.as_raw().sha3())
},
CreateContractAddress::FromCodeHash => {
let mut buffer = [0u8; 20 + 32];
&mut buffer[20..].copy_from_slice(&code_hash[..]);
From::from((&buffer[..]).sha3())
},
CreateContractAddress::FromSenderAndCodeHash => {
let mut buffer = [0u8; 20 + 32];
&mut buffer[..20].copy_from_slice(&sender[..]);
&mut buffer[20..].copy_from_slice(&code_hash[..]);
From::from((&buffer[..]).sha3())
},
}
} }
/// Transaction execution options. /// Transaction execution options.
@ -125,7 +140,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
let sender = t.sender(); let sender = t.sender();
let nonce = self.state.nonce(&sender)?; let nonce = self.state.nonce(&sender)?;
let schedule = self.engine.schedule(self.info); let schedule = self.engine.schedule(self.info.number);
let base_gas_required = U256::from(t.gas_required(&schedule)); let base_gas_required = U256::from(t.gas_required(&schedule));
if t.gas < base_gas_required { if t.gas < base_gas_required {
@ -160,17 +175,20 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
} }
// NOTE: there can be no invalid transactions from this point. // NOTE: there can be no invalid transactions from this point.
self.state.inc_nonce(&sender)?; if !t.is_unsigned() {
self.state.inc_nonce(&sender)?;
}
self.state.sub_balance(&sender, &U256::from(gas_cost))?; self.state.sub_balance(&sender, &U256::from(gas_cost))?;
let mut substate = Substate::new(); let mut substate = Substate::new();
let (gas_left, output) = match t.action { let (gas_left, output) = match t.action {
Action::Create => { Action::Create => {
let new_address = contract_address(&sender, &nonce); let code_hash = t.data.sha3();
let new_address = contract_address(schedule.create_address, &sender, &nonce, &code_hash);
let params = ActionParams { let params = ActionParams {
code_address: new_address.clone(), code_address: new_address.clone(),
code_hash: t.data.sha3(), code_hash: code_hash,
address: new_address, address: new_address,
sender: sender.clone(), sender: sender.clone(),
origin: sender.clone(), origin: sender.clone(),
@ -253,7 +271,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
// backup used in case of running out of gas // backup used in case of running out of gas
self.state.checkpoint(); self.state.checkpoint();
let schedule = self.engine.schedule(self.info); let schedule = self.engine.schedule(self.info.number);
// at first, transfer value to destination // at first, transfer value to destination
if let ActionValue::Transfer(val) = params.value { if let ActionValue::Transfer(val) = params.value {
@ -365,8 +383,14 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
params: ActionParams, params: ActionParams,
substate: &mut Substate, substate: &mut Substate,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V vm_tracer: &mut V,
) -> evm::Result<U256> where T: Tracer, V: VMTracer { ) -> evm::Result<U256> where T: Tracer, V: VMTracer {
let schedule = self.engine.schedule(self.info.number);
if schedule.create_address != CreateContractAddress::FromSenderAndNonce && self.state.exists(&params.address)? {
return Err(evm::Error::OutOfGas);
}
// backup used in case of running out of gas // backup used in case of running out of gas
self.state.checkpoint(); self.state.checkpoint();
@ -374,7 +398,6 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
let mut unconfirmed_substate = Substate::new(); let mut unconfirmed_substate = Substate::new();
// create contract and transfer value to it if necessary // create contract and transfer value to it if necessary
let schedule = self.engine.schedule(self.info);
let nonce_offset = if schedule.no_empty {1} else {0}.into(); let nonce_offset = if schedule.no_empty {1} else {0}.into();
let prev_bal = self.state.balance(&params.address)?; let prev_bal = self.state.balance(&params.address)?;
if let ActionValue::Transfer(val) = params.value { if let ActionValue::Transfer(val) = params.value {
@ -423,7 +446,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
trace: Vec<FlatTrace>, trace: Vec<FlatTrace>,
vm_trace: Option<VMTrace> vm_trace: Option<VMTrace>
) -> ExecutionResult { ) -> ExecutionResult {
let schedule = self.engine.schedule(self.info); let schedule = self.engine.schedule(self.info.number);
// refunds from SSTORE nonzero -> zero // refunds from SSTORE nonzero -> zero
let sstore_refunds = U256::from(schedule.sstore_refund_gas) * substate.sstore_clears_count; let sstore_refunds = U256::from(schedule.sstore_refund_gas) * substate.sstore_clears_count;
@ -525,7 +548,7 @@ mod tests {
use util::bytes::BytesRef; use util::bytes::BytesRef;
use action_params::{ActionParams, ActionValue}; use action_params::{ActionParams, ActionValue};
use env_info::EnvInfo; use env_info::EnvInfo;
use evm::{Factory, VMType}; use evm::{Factory, VMType, CreateContractAddress};
use error::ExecutionError; use error::ExecutionError;
use state::{Substate, CleanupMode}; use state::{Substate, CleanupMode};
use tests::helpers::*; use tests::helpers::*;
@ -540,22 +563,21 @@ mod tests {
fn test_contract_address() { fn test_contract_address() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let expected_address = Address::from_str("3f09c73a5ed19289fb9bdc72f1742566df146f56").unwrap(); let expected_address = Address::from_str("3f09c73a5ed19289fb9bdc72f1742566df146f56").unwrap();
assert_eq!(expected_address, contract_address(&address, &U256::from(88))); assert_eq!(expected_address, contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::from(88), &H256::default()));
} }
// TODO: replace params with transactions! // TODO: replace params with transactions!
evm_test!{test_sender_balance: test_sender_balance_jit, test_sender_balance_int} evm_test!{test_sender_balance: test_sender_balance_jit, test_sender_balance_int}
fn test_sender_balance(factory: Factory) { fn test_sender_balance(factory: Factory) {
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
params.address = address.clone(); params.address = address.clone();
params.sender = sender.clone(); params.sender = sender.clone();
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new("3331600055".from_hex().unwrap())); params.code = Some(Arc::new("3331600055".from_hex().unwrap()));
params.value = ActionValue::Transfer(U256::from(0x7)); params.value = ActionValue::Transfer(U256::from(0x7));
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(0x100u64), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(0x100u64), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
@ -603,7 +625,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -613,8 +635,7 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100)); params.value = ActionValue::Transfer(U256::from(100));
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
@ -660,7 +681,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -672,8 +693,7 @@ mod tests {
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100)); params.value = ActionValue::Transfer(U256::from(100));
params.call_type = CallType::Call; params.call_type = CallType::Call;
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
@ -773,7 +793,7 @@ mod tests {
let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(); let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -783,8 +803,7 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(100.into()); params.value = ActionValue::Transfer(100.into());
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
@ -861,7 +880,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -871,8 +890,7 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100)); params.value = ActionValue::Transfer(U256::from(100));
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
@ -914,8 +932,8 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
let next_address = contract_address(&address, &U256::zero()); let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &H256::default());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
params.address = address.clone(); params.address = address.clone();
params.sender = sender.clone(); params.sender = sender.clone();
@ -923,8 +941,7 @@ mod tests {
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from(100)); params.value = ActionValue::Transfer(U256::from(100));
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(1024); let engine = TestEngine::new(1024);
@ -981,8 +998,7 @@ mod tests {
params.code = Some(Arc::new(code_a.clone())); params.code = Some(Arc::new(code_a.clone()));
params.value = ActionValue::Transfer(U256::from(100_000)); params.value = ActionValue::Transfer(U256::from(100_000));
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.init_code(&address_a, code_a.clone()).unwrap(); state.init_code(&address_a, code_a.clone()).unwrap();
state.init_code(&address_b, code_b.clone()).unwrap(); state.init_code(&address_b, code_b.clone()).unwrap();
state.add_balance(&sender, &U256::from(100_000), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100_000), CleanupMode::NoEmpty).unwrap();
@ -1024,13 +1040,12 @@ mod tests {
// 55 - sstore // 55 - sstore
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap(); let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
params.address = address.clone(); params.address = address.clone();
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(Arc::new(code.clone())); params.code = Some(Arc::new(code.clone()));
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.init_code(&address, code).unwrap(); state.init_code(&address, code).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(0); let engine = TestEngine::new(0);
@ -1060,10 +1075,9 @@ mod tests {
nonce: U256::zero() nonce: U256::zero()
}.sign(keypair.secret(), None); }.sign(keypair.secret(), None);
let sender = t.sender(); let sender = t.sender();
let contract = contract_address(&sender, &U256::zero()); let contract = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap();
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = U256::from(100_000); info.gas_limit = U256::from(100_000);
@ -1100,8 +1114,7 @@ mod tests {
}.sign(keypair.secret(), None); }.sign(keypair.secret(), None);
let sender = t.sender(); let sender = t.sender();
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap();
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = U256::from(100_000); info.gas_limit = U256::from(100_000);
@ -1133,8 +1146,7 @@ mod tests {
}.sign(keypair.secret(), None); }.sign(keypair.secret(), None);
let sender = t.sender(); let sender = t.sender();
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap();
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_used = U256::from(20_000); info.gas_used = U256::from(20_000);
@ -1168,8 +1180,7 @@ mod tests {
}.sign(keypair.secret(), None); }.sign(keypair.secret(), None);
let sender = t.sender(); let sender = t.sender();
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100_017), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(100_017), CleanupMode::NoEmpty).unwrap();
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = U256::from(100_000); info.gas_limit = U256::from(100_000);
@ -1193,7 +1204,7 @@ mod tests {
let code = "6064640fffffffff20600055".from_hex().unwrap(); let code = "6064640fffffffff20600055".from_hex().unwrap();
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -1203,8 +1214,7 @@ mod tests {
params.gas = U256::from(0x0186a0); params.gas = U256::from(0x0186a0);
params.code = Some(Arc::new(code)); params.code = Some(Arc::new(code));
params.value = ActionValue::Transfer(U256::from_str("0de0b6b3a7640000").unwrap()); params.value = ActionValue::Transfer(U256::from_str("0de0b6b3a7640000").unwrap());
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap(), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap(), CleanupMode::NoEmpty).unwrap();
let info = EnvInfo::default(); let info = EnvInfo::default();
let engine = TestEngine::new(0); let engine = TestEngine::new(0);

View File

@ -21,8 +21,9 @@ use state::{Backend as StateBackend, State, Substate};
use engines::Engine; use engines::Engine;
use env_info::EnvInfo; use env_info::EnvInfo;
use executive::*; use executive::*;
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory}; use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory, CreateContractAddress};
use types::executed::CallType; use types::executed::CallType;
use types::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.
@ -97,7 +98,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B>
depth: depth, depth: depth,
origin_info: origin_info, origin_info: origin_info,
substate: substate, substate: substate,
schedule: engine.schedule(env_info), schedule: engine.schedule(env_info.number),
output: output, output: output,
tracer: tracer, tracer: tracer,
vm_tracer: vm_tracer, vm_tracer: vm_tracer,
@ -147,10 +148,11 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
} }
} }
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address_scheme: CreateContractAddress) -> ContractCreateResult {
// create new contract address // create new contract address
let code_hash = code.sha3();
let address = match self.state.nonce(&self.origin_info.address) { let address = match self.state.nonce(&self.origin_info.address) {
Ok(nonce) => contract_address(&self.origin_info.address, &nonce), Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code_hash),
Err(e) => { Err(e) => {
debug!(target: "ext", "Database corruption encountered: {:?}", e); debug!(target: "ext", "Database corruption encountered: {:?}", e);
return ContractCreateResult::Failed return ContractCreateResult::Failed
@ -167,14 +169,16 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
gas_price: self.origin_info.gas_price, gas_price: self.origin_info.gas_price,
value: ActionValue::Transfer(*value), value: ActionValue::Transfer(*value),
code: Some(Arc::new(code.to_vec())), code: Some(Arc::new(code.to_vec())),
code_hash: code.sha3(), code_hash: code_hash,
data: None, data: None,
call_type: CallType::None, call_type: CallType::None,
}; };
if let Err(e) = self.state.inc_nonce(&self.origin_info.address) { if params.sender != UNSIGNED_SENDER {
debug!(target: "ext", "Database corruption encountered: {:?}", e); if let Err(e) = self.state.inc_nonce(&self.origin_info.address) {
return ContractCreateResult::Failed debug!(target: "ext", "Database corruption encountered: {:?}", e);
return ContractCreateResult::Failed
}
} }
let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.vm_factory, self.depth); let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.vm_factory, self.depth);
@ -346,7 +350,6 @@ mod tests {
use evm::Ext; use evm::Ext;
use state::{State, Substate}; use state::{State, Substate};
use tests::helpers::*; use tests::helpers::*;
use devtools::GuardedTempResult;
use super::*; use super::*;
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
use types::executed::CallType; use types::executed::CallType;
@ -373,7 +376,7 @@ mod tests {
} }
struct TestSetup { struct TestSetup {
state: GuardedTempResult<State<::state_db::StateDB>>, state: State<::state_db::StateDB>,
engine: Arc<Engine>, engine: Arc<Engine>,
sub_state: Substate, sub_state: Substate,
env_info: EnvInfo env_info: EnvInfo
@ -399,7 +402,7 @@ mod tests {
#[test] #[test]
fn can_be_created() { fn can_be_created() {
let mut setup = TestSetup::new(); let mut setup = TestSetup::new();
let state = setup.state.reference_mut(); let state = &mut setup.state;
let mut tracer = NoopTracer; let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer; let mut vm_tracer = NoopVMTracer;
@ -412,7 +415,7 @@ mod tests {
#[test] #[test]
fn can_return_block_hash_no_env() { fn can_return_block_hash_no_env() {
let mut setup = TestSetup::new(); let mut setup = TestSetup::new();
let state = setup.state.reference_mut(); let state = &mut setup.state;
let mut tracer = NoopTracer; let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer; let mut vm_tracer = NoopVMTracer;
@ -437,7 +440,7 @@ mod tests {
last_hashes.push(test_hash.clone()); last_hashes.push(test_hash.clone());
env_info.last_hashes = Arc::new(last_hashes); env_info.last_hashes = Arc::new(last_hashes);
} }
let state = setup.state.reference_mut(); let state = &mut setup.state;
let mut tracer = NoopTracer; let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer; let mut vm_tracer = NoopVMTracer;
@ -453,7 +456,7 @@ mod tests {
#[should_panic] #[should_panic]
fn can_call_fail_empty() { fn can_call_fail_empty() {
let mut setup = TestSetup::new(); let mut setup = TestSetup::new();
let state = setup.state.reference_mut(); let state = &mut setup.state;
let mut tracer = NoopTracer; let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer; let mut vm_tracer = NoopVMTracer;
@ -481,7 +484,7 @@ mod tests {
let log_topics = vec![H256::from("af0fa234a6af46afa23faf23bcbc1c1cb4bcb7bcbe7e7e7ee3ee2edddddddddd")]; let log_topics = vec![H256::from("af0fa234a6af46afa23faf23bcbc1c1cb4bcb7bcbe7e7e7ee3ee2edddddddddd")];
let mut setup = TestSetup::new(); let mut setup = TestSetup::new();
let state = setup.state.reference_mut(); let state = &mut setup.state;
let mut tracer = NoopTracer; let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer; let mut vm_tracer = NoopVMTracer;
@ -499,7 +502,7 @@ mod tests {
let refund_account = &Address::new(); let refund_account = &Address::new();
let mut setup = TestSetup::new(); let mut setup = TestSetup::new();
let state = setup.state.reference_mut(); let state = &mut setup.state;
let mut tracer = NoopTracer; let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer; let mut vm_tracer = NoopVMTracer;

View File

@ -48,7 +48,7 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
ChainEra::Frontier => ethereum::new_frontier_test(), ChainEra::Frontier => ethereum::new_frontier_test(),
ChainEra::Homestead => ethereum::new_homestead_test(), ChainEra::Homestead => ethereum::new_homestead_test(),
ChainEra::Eip150 => ethereum::new_eip150_test(), ChainEra::Eip150 => ethereum::new_eip150_test(),
ChainEra::Eip161 => ethereum::new_eip161_test(), ChainEra::_Eip161 => ethereum::new_eip161_test(),
ChainEra::TransitionTest => ethereum::new_transition_test(), ChainEra::TransitionTest => ethereum::new_transition_test(),
}; };
spec.set_genesis_state(state); spec.set_genesis_state(state);

View File

@ -1,43 +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/>.
use super::test_common::*;
use tests::helpers::*;
use super::state::json_chain_test;
fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::Eip150)
}
declare_test!{StateTests_EIP150_stEIPSpecificTest, "StateTests/EIP150/stEIPSpecificTest"}
declare_test!{StateTests_EIP150_stEIPsingleCodeGasPrices, "StateTests/EIP150/stEIPsingleCodeGasPrices"}
declare_test!{StateTests_EIP150_stMemExpandingEIPCalls, "StateTests/EIP150/stMemExpandingEIPCalls"}
declare_test!{StateTests_EIP150_stCallCodes, "StateTests/EIP150/Homestead/stCallCodes"}
declare_test!{StateTests_EIP150_stCallCreateCallCodeTest, "StateTests/EIP150/Homestead/stCallCreateCallCodeTest"}
declare_test!{StateTests_EIP150_stDelegatecallTest, "StateTests/EIP150/Homestead/stDelegatecallTest"}
declare_test!{StateTests_EIP150_stInitCodeTest, "StateTests/EIP150/Homestead/stInitCodeTest"}
declare_test!{StateTests_EIP150_stLogTests, "StateTests/EIP150/Homestead/stLogTests"}
declare_test!{heavy => StateTests_EIP150_stMemoryStressTest, "StateTests/EIP150/Homestead/stMemoryStressTest"}
declare_test!{heavy => StateTests_EIP150_stMemoryTest, "StateTests/EIP150/Homestead/stMemoryTest"}
declare_test!{StateTests_EIP150_stPreCompiledContracts, "StateTests/EIP150/Homestead/stPreCompiledContracts"}
declare_test!{heavy => StateTests_EIP150_stQuadraticComplexityTest, "StateTests/EIP150/Homestead/stQuadraticComplexityTest"}
declare_test!{StateTests_EIP150_stRecursiveCreate, "StateTests/EIP150/Homestead/stRecursiveCreate"}
declare_test!{StateTests_EIP150_stRefundTest, "StateTests/EIP150/Homestead/stRefundTest"}
declare_test!{StateTests_EIP150_stSpecialTest, "StateTests/EIP150/Homestead/stSpecialTest"}
declare_test!{StateTests_EIP150_stSystemOperationsTest, "StateTests/EIP150/Homestead/stSystemOperationsTest"}
declare_test!{StateTests_EIP150_stTransactionTest, "StateTests/EIP150/Homestead/stTransactionTest"}
declare_test!{StateTests_EIP150_stWalletTest, "StateTests/EIP150/Homestead/stWalletTest"}

View File

@ -1,51 +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/>.
use super::test_common::*;
use tests::helpers::*;
use super::state::json_chain_test;
fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::Eip161)
}
declare_test!{StateTests_EIP158_stEIP158SpecificTest, "StateTests/EIP158/stEIP158SpecificTest"}
declare_test!{StateTests_EIP158_stNonZeroCallsTest, "StateTests/EIP158/stNonZeroCallsTest"}
declare_test!{StateTests_EIP158_stZeroCallsTest, "StateTests/EIP158/stZeroCallsTest"}
declare_test!{StateTests_EIP158_EIP150_stMemExpandingEIPCalls, "StateTests/EIP158/EIP150/stMemExpandingEIPCalls"}
declare_test!{StateTests_EIP158_EIP150_stEIPSpecificTest, "StateTests/EIP158/EIP150/stEIPSpecificTest"}
declare_test!{StateTests_EIP158_EIP150_stEIPsingleCodeGasPrices, "StateTests/EIP158/EIP150/stEIPsingleCodeGasPrices"}
declare_test!{StateTests_EIP158_EIP150_stChangedTests, "StateTests/EIP158/EIP150/stChangedTests"}
declare_test!{StateTests_EIP158_Homestead_stBoundsTest, "StateTests/EIP158/Homestead/stBoundsTest"}
declare_test!{StateTests_EIP158_Homestead_stCallCodes, "StateTests/EIP158/Homestead/stCallCodes"}
declare_test!{StateTests_EIP158_Homestead_stCallCreateCallCodeTest, "StateTests/EIP158/Homestead/stCallCreateCallCodeTest"}
declare_test!{StateTests_EIP158_Homestead_stCallDelegateCodes, "StateTests/EIP158/Homestead/stCallDelegateCodes"}
declare_test!{StateTests_EIP158_Homestead_stCallDelegateCodesCallCode, "StateTests/EIP158/Homestead/stCallDelegateCodesCallCode"}
declare_test!{StateTests_EIP158_Homestead_stDelegatecallTest, "StateTests/EIP158/Homestead/stDelegatecallTest"}
declare_test!{StateTests_EIP158_Homestead_stHomeSteadSpecific, "StateTests/EIP158/Homestead/stHomeSteadSpecific"}
declare_test!{StateTests_EIP158_Homestead_stInitCodeTest, "StateTests/EIP158/Homestead/stInitCodeTest"}
declare_test!{StateTests_EIP158_Homestead_stLogTests, "StateTests/EIP158/Homestead/stLogTests"}
declare_test!{heavy => StateTests_EIP158_Homestead_stMemoryTest, "StateTests/EIP158/Homestead/stMemoryTest"}
declare_test!{StateTests_EIP158_Homestead_stPreCompiledContracts, "StateTests/EIP158/Homestead/stPreCompiledContracts"}
declare_test!{heavy => StateTests_EIP158_Homestead_stQuadraticComplexityTest, "StateTests/EIP158/Homestead/stQuadraticComplexityTest"}
declare_test!{StateTests_EIP158_Homestead_stRecursiveCreate, "StateTests/EIP158/Homestead/stRecursiveCreate"}
declare_test!{StateTests_EIP158_Homestead_stRefundTest, "StateTests/EIP158/Homestead/stRefundTest"}
declare_test!{StateTests_EIP158_Homestead_stSpecialTest, "StateTests/EIP158/Homestead/stSpecialTest"}
declare_test!{StateTests_EIP158_Homestead_stSystemOperationsTest, "StateTests/EIP158/Homestead/stSystemOperationsTest"}
declare_test!{StateTests_EIP158_Homestead_stTransactionTest, "StateTests/EIP158/Homestead/stTransactionTest"}
declare_test!{StateTests_EIP158_Homestead_stWalletTest, "StateTests/EIP158/Homestead/stWalletTest"}

View File

@ -21,7 +21,7 @@ use executive::*;
use engines::Engine; use engines::Engine;
use env_info::EnvInfo; use env_info::EnvInfo;
use evm; use evm;
use evm::{Schedule, Ext, Factory, Finalize, VMType, ContractCreateResult, MessageCallResult}; use evm::{Schedule, Ext, Factory, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress};
use externalities::*; use externalities::*;
use types::executed::CallType; use types::executed::CallType;
use tests::helpers::*; use tests::helpers::*;
@ -56,7 +56,8 @@ struct TestExt<'a, T: 'a, V: 'a, B: 'a>
{ {
ext: Externalities<'a, T, V, B>, ext: Externalities<'a, T, V, B>,
callcreates: Vec<CallCreate>, callcreates: Vec<CallCreate>,
contract_address: Address nonce: U256,
sender: Address,
} }
impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B> impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B>
@ -76,9 +77,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B>
vm_tracer: &'a mut V, vm_tracer: &'a mut V,
) -> trie::Result<Self> { ) -> trie::Result<Self> {
Ok(TestExt { Ok(TestExt {
contract_address: contract_address(&address, &state.nonce(&address)?), nonce: state.nonce(&address)?,
ext: Externalities::new(state, info, engine, vm_factory, depth, origin_info, substate, output, tracer, vm_tracer), ext: Externalities::new(state, info, engine, vm_factory, depth, origin_info, substate, output, tracer, vm_tracer),
callcreates: vec![] callcreates: vec![],
sender: address,
}) })
} }
} }
@ -114,14 +116,15 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
self.ext.blockhash(number) self.ext.blockhash(number)
} }
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult {
self.callcreates.push(CallCreate { self.callcreates.push(CallCreate {
data: code.to_vec(), data: code.to_vec(),
destination: None, destination: None,
gas_limit: *gas, gas_limit: *gas,
value: *value value: *value
}); });
ContractCreateResult::Created(self.contract_address.clone(), *gas) let contract_address = contract_address(address, &self.sender, &self.nonce, &code.sha3());
ContractCreateResult::Created(contract_address, *gas)
} }
fn call(&mut self, fn call(&mut self,
@ -215,8 +218,7 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec<String> {
} }
let out_of_gas = vm.out_of_gas(); let out_of_gas = vm.out_of_gas();
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.populate_from(From::from(vm.pre_state.clone())); state.populate_from(From::from(vm.pre_state.clone()));
let info = From::from(vm.env); let info = From::from(vm.env);
let engine = TestEngine::new(1); let engine = TestEngine::new(1);

View File

@ -14,7 +14,6 @@
// 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/>.
use super::test_common::*;
use super::chain::json_chain_test; use super::chain::json_chain_test;
use tests::helpers::*; use tests::helpers::*;

View File

@ -1,39 +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/>.
use super::test_common::*;
use tests::helpers::*;
use super::state::json_chain_test;
fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::Homestead)
}
declare_test!{StateTests_Homestead_stCallCodes, "StateTests/Homestead/stCallCodes"}
declare_test!{StateTests_Homestead_stCallCreateCallCodeTest, "StateTests/Homestead/stCallCreateCallCodeTest"}
declare_test!{StateTests_Homestead_stDelegatecallTest, "StateTests/Homestead/stDelegatecallTest"}
declare_test!{StateTests_Homestead_stInitCodeTest, "StateTests/Homestead/stInitCodeTest"}
declare_test!{StateTests_Homestead_stLogTests, "StateTests/Homestead/stLogTests"}
declare_test!{heavy => StateTests_Homestead_stMemoryStressTest, "StateTests/Homestead/stMemoryStressTest"}
declare_test!{heavy => StateTests_Homestead_stMemoryTest, "StateTests/Homestead/stMemoryTest"}
declare_test!{StateTests_Homestead_stPreCompiledContracts, "StateTests/Homestead/stPreCompiledContracts"}
declare_test!{heavy => StateTests_Homestead_stQuadraticComplexityTest, "StateTests/Homestead/stQuadraticComplexityTest"}
declare_test!{StateTests_Homestead_stRecursiveCreate, "StateTests/Homestead/stRecursiveCreate"}
declare_test!{StateTests_Homestead_stRefundTest, "StateTests/Homestead/stRefundTest"}
declare_test!{StateTests_Homestead_stSpecialTest, "StateTests/Homestead/stSpecialTest"}
declare_test!{StateTests_Homestead_stSystemOperationsTest, "StateTests/Homestead/stSystemOperationsTest"}
declare_test!{StateTests_Homestead_stTransactionTest, "StateTests/Homestead/stTransactionTest"}
declare_test!{StateTests_Homestead_stWalletTest, "StateTests/Homestead/stWalletTest"}

View File

@ -21,8 +21,5 @@ mod transaction;
mod executive; mod executive;
mod state; mod state;
mod chain; mod chain;
mod homestead_state;
mod homestead_chain; mod homestead_chain;
mod eip150_state;
mod eip161_state;
mod trie; mod trie;

View File

@ -16,749 +16,116 @@
use super::test_common::*; use super::test_common::*;
use tests::helpers::*; use tests::helpers::*;
use pod_state::{self, PodState}; use pod_state::PodState;
use log_entry::LogEntry;
use ethereum; use ethereum;
use spec::Spec;
use ethjson; use ethjson;
use ethjson::state::test::ForkSpec;
use types::transaction::SignedTransaction;
use env_info::EnvInfo;
pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> { lazy_static! {
pub static ref FRONTIER: Spec = ethereum::new_frontier_test();
pub static ref HOMESTEAD: Spec = ethereum::new_homestead_test();
pub static ref EIP150: Spec = ethereum::new_eip150_test();
pub static ref EIP161: Spec = ethereum::new_eip161_test();
}
pub fn json_chain_test(json_data: &[u8]) -> Vec<String> {
::ethcore_logger::init_log(); ::ethcore_logger::init_log();
let tests = ethjson::state::Test::load(json_data).unwrap(); let tests = ethjson::state::test::Test::load(json_data).unwrap();
let mut failed = Vec::new(); let mut failed = Vec::new();
let engine = match era {
ChainEra::Frontier => ethereum::new_mainnet_like().engine,
ChainEra::Homestead => ethereum::new_homestead_test().engine,
ChainEra::Eip150 => ethereum::new_eip150_test().engine,
ChainEra::Eip161 => ethereum::new_eip161_test().engine,
ChainEra::TransitionTest => ethereum::new_transition_test().engine,
};
for (name, test) in tests.into_iter() { for (name, test) in tests.into_iter() {
let mut fail = false;
{ {
let mut fail_unless = |cond: bool| if !cond && !fail { let multitransaction = test.transaction;
failed.push(name.clone()); let env: EnvInfo = test.env.into();
flushln!("FAIL");
fail = true;
true
} else {false};
flush!(" - {}...", name);
let transaction = test.transaction.into();
let post_state_root = test.post_state_root.into();
let env = test.env.into();
let pre: PodState = test.pre_state.into(); let pre: PodState = test.pre_state.into();
let post: PodState = test.post_state.into();
let logs: Vec<LogEntry> = test.logs.into_iter().map(Into::into).collect();
let calc_post = sec_trie_root(post.get().iter().map(|(k, v)| (k.to_vec(), v.rlp())).collect()); for (spec, states) in test.post_states {
let total = states.len();
let engine = match spec {
ForkSpec::Frontier => &FRONTIER.engine,
ForkSpec::Homestead => &HOMESTEAD.engine,
ForkSpec::EIP150 => &EIP150.engine,
ForkSpec::EIP158 => &EIP161.engine,
ForkSpec::Metropolis => continue,
};
if fail_unless(post_state_root == calc_post) { for (i, state) in states.into_iter().enumerate() {
println!("!!! {}: Trie root mismatch (got: {}, expect: {}):", name, calc_post, post_state_root); let info = format!(" - {} | {:?} ({}/{}) ...", name, spec, i + 1, total);
println!("!!! Post:\n{}", post);
} else {
let mut state_result = get_temp_state();
let mut state = state_result.reference_mut();
state.populate_from(pre);
state.commit()
.expect(&format!("State test {} failed due to internal error.", name));
let res = state.apply(&env, &*engine, &transaction, false);
if fail_unless(state.root() == &post_state_root) { let post_root: H256 = state.hash.into();
println!("!!! {}: State mismatch (got: {}, expect: {}):", name, state.root(), post_state_root); let transaction: SignedTransaction = multitransaction.select(&state.indexes).into();
let our_post = state.to_pod(); let mut state = get_temp_state();
println!("Got:\n{}", our_post); state.populate_from(pre.clone());
println!("Expect:\n{}", post); if transaction.verify_basic(true, None, env.number >= engine.params().eip86_transition).is_ok() {
println!("Diff ---expect -> +++got:\n{}", pod_state::diff_pod(&post, &our_post)); state.commit().expect(&format!("State test {} failed due to internal error.", name));
} let _res = state.apply(&env, &**engine, &transaction, false);
} else {
if let Ok(r) = res { let _rest = state.commit();
if fail_unless(logs == r.receipt.logs) { }
println!("!!! {}: Logs mismatch:", name); if state.root() != &post_root {
println!("Got:\n{:?}", r.receipt.logs); println!("{} !!! State mismatch (got: {}, expect: {}", info, state.root(), post_root);
println!("Expect:\n{:?}", logs); flushln!("{} fail", info);
failed.push(name.clone());
} else {
flushln!("{} ok", info);
} }
} }
} }
} }
if !fail {
flushln!("ok");
}
} }
println!("!!! {:?} tests from failed.", failed.len()); if !failed.is_empty() {
println!("!!! {:?} tests failed.", failed.len());
}
failed failed
} }
mod frontier_tests { mod state_tests {
use super::json_chain_test; use super::json_chain_test;
use tests::helpers::ChainEra;
fn do_json_test(json_data: &[u8]) -> Vec<String> { fn do_json_test(json_data: &[u8]) -> Vec<String> {
json_chain_test(json_data, ChainEra::Frontier) json_chain_test(json_data)
} }
declare_test!{StateTests_stBlockHashTest, "StateTests/stBlockHashTest"} declare_test!{GeneralStateTest_stAttackTest, "GeneralStateTests/stAttackTest/"}
declare_test!{StateTests_stCallCodes, "StateTests/stCallCodes"} declare_test!{GeneralStateTest_stBlockHashTest, "GeneralStateTests/stBlockHashTest/"}
declare_test!{StateTests_stCallCreateCallCodeTest, "StateTests/stCallCreateCallCodeTest"} declare_test!{GeneralStateTest_stBoundsTest, "GeneralStateTests/stBoundsTest/"}
declare_test!{StateTests_stExample, "StateTests/stExample"} declare_test!{GeneralStateTest_stCallCodes, "GeneralStateTests/stCallCodes/"}
declare_test!{StateTests_stInitCodeTest, "StateTests/stInitCodeTest"} declare_test!{skip => [ "createJS_ExampleContract" ], GeneralStateTest_stCallCreateCallCodeTest, "GeneralStateTests/stCallCreateCallCodeTest/"}
declare_test!{StateTests_stLogTests, "StateTests/stLogTests"} declare_test!{GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"}
declare_test!{heavy => StateTests_stMemoryStressTest, "StateTests/stMemoryStressTest"} declare_test!{GeneralStateTest_stCallDelegateCodesHomestead, "GeneralStateTests/stCallDelegateCodesHomestead/"}
declare_test!{heavy => StateTests_stMemoryTest, "StateTests/stMemoryTest"} declare_test!{GeneralStateTest_stChangedEIP150, "GeneralStateTests/stChangedEIP150/"}
declare_test!{StateTests_stPreCompiledContracts, "StateTests/stPreCompiledContracts"} declare_test!{GeneralStateTest_stCodeSizeLimit, "GeneralStateTests/stCodeSizeLimit/"}
declare_test!{heavy => StateTests_stQuadraticComplexityTest, "StateTests/stQuadraticComplexityTest"} declare_test!{GeneralStateTest_stCreateTest, "GeneralStateTests/stCreateTest/"}
declare_test!{StateTests_stRecursiveCreate, "StateTests/stRecursiveCreate"} declare_test!{GeneralStateTest_stDelegatecallTestHomestead, "GeneralStateTests/stDelegatecallTestHomestead/"}
declare_test!{StateTests_stRefundTest, "StateTests/stRefundTest"} declare_test!{GeneralStateTest_stEIP150singleCodeGasPrices, "GeneralStateTests/stEIP150singleCodeGasPrices/"}
declare_test!{StateTests_stSolidityTest, "StateTests/stSolidityTest"} declare_test!{GeneralStateTest_stEIP150Specific, "GeneralStateTests/stEIP150Specific/"}
declare_test!{StateTests_stSpecialTest, "StateTests/stSpecialTest"} declare_test!{GeneralStateTest_stExample, "GeneralStateTests/stExample/"}
declare_test!{StateTests_stSystemOperationsTest, "StateTests/stSystemOperationsTest"} declare_test!{GeneralStateTest_stHomesteadSpecific, "GeneralStateTests/stHomesteadSpecific/"}
declare_test!{StateTests_stTransactionTest, "StateTests/stTransactionTest"} declare_test!{GeneralStateTest_stInitCodeTest, "GeneralStateTests/stInitCodeTest/"}
declare_test!{StateTests_stTransitionTest, "StateTests/stTransitionTest"} declare_test!{GeneralStateTest_stLogTests, "GeneralStateTests/stLogTests/"}
declare_test!{StateTests_stWalletTest, "StateTests/stWalletTest"} declare_test!{GeneralStateTest_stMemExpandingEIP150Calls, "GeneralStateTests/stMemExpandingEIP150Calls/"}
declare_test!{heavy => GeneralStateTest_stMemoryStressTest, "GeneralStateTests/stMemoryStressTest/"}
declare_test!{StateTests_RandomTests_st201503121803PYTHON, "StateTests/RandomTests/st201503121803PYTHON"} declare_test!{GeneralStateTest_stMemoryTest, "GeneralStateTests/stMemoryTest/"}
declare_test!{StateTests_RandomTests_st201503121806PYTHON, "StateTests/RandomTests/st201503121806PYTHON"} declare_test!{GeneralStateTest_stNonZeroCallsTest, "GeneralStateTests/stNonZeroCallsTest/"}
declare_test!{StateTests_RandomTests_st201503121848GO, "StateTests/RandomTests/st201503121848GO"} declare_test!{GeneralStateTest_stPreCompiledContracts, "GeneralStateTests/stPreCompiledContracts/"}
declare_test!{StateTests_RandomTests_st201503121849GO, "StateTests/RandomTests/st201503121849GO"} declare_test!{heavy => GeneralStateTest_stQuadraticComplexityTest, "GeneralStateTests/stQuadraticComplexityTest/"}
declare_test!{StateTests_RandomTests_st201503121850GO, "StateTests/RandomTests/st201503121850GO"} declare_test!{GeneralStateTest_stRandom, "GeneralStateTests/stRandom/"}
declare_test!{StateTests_RandomTests_st201503121851GO, "StateTests/RandomTests/st201503121851GO"} declare_test!{GeneralStateTest_stRecursiveCreate, "GeneralStateTests/stRecursiveCreate/"}
declare_test!{StateTests_RandomTests_st201503121953GO, "StateTests/RandomTests/st201503121953GO"} declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"}
declare_test!{StateTests_RandomTests_st201503122023GO, "StateTests/RandomTests/st201503122023GO"} declare_test!{skip => [ "RevertDepthCreateAddressCollision" ], GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"}
declare_test!{StateTests_RandomTests_st201503122023PYTHON, "StateTests/RandomTests/st201503122023PYTHON"} declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"}
declare_test!{StateTests_RandomTests_st201503122027GO, "StateTests/RandomTests/st201503122027GO"} declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"}
declare_test!{StateTests_RandomTests_st201503122054GO, "StateTests/RandomTests/st201503122054GO"} declare_test!{GeneralStateTest_stStackTests, "GeneralStateTests/stStackTests/"}
declare_test!{StateTests_RandomTests_st201503122055GO, "StateTests/RandomTests/st201503122055GO"} declare_test!{GeneralStateTest_stSystemOperationsTest, "GeneralStateTests/stSystemOperationsTest/"}
declare_test!{StateTests_RandomTests_st201503122115CPPJIT, "StateTests/RandomTests/st201503122115CPPJIT"} declare_test!{GeneralStateTest_stTransactionTest, "GeneralStateTests/stTransactionTest/"}
declare_test!{StateTests_RandomTests_st201503122115GO, "StateTests/RandomTests/st201503122115GO"} declare_test!{GeneralStateTest_stTransitionTest, "GeneralStateTests/stTransitionTest/"}
declare_test!{StateTests_RandomTests_st201503122123GO, "StateTests/RandomTests/st201503122123GO"} declare_test!{GeneralStateTest_stWalletTest, "GeneralStateTests/stWalletTest/"}
declare_test!{StateTests_RandomTests_st201503122124GO, "StateTests/RandomTests/st201503122124GO"} declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"}
declare_test!{StateTests_RandomTests_st201503122128PYTHON, "StateTests/RandomTests/st201503122128PYTHON"} declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"}
declare_test!{StateTests_RandomTests_st201503122140GO, "StateTests/RandomTests/st201503122140GO"}
declare_test!{StateTests_RandomTests_st201503122159GO, "StateTests/RandomTests/st201503122159GO"}
declare_test!{StateTests_RandomTests_st201503122204GO, "StateTests/RandomTests/st201503122204GO"}
declare_test!{StateTests_RandomTests_st201503122212GO, "StateTests/RandomTests/st201503122212GO"}
declare_test!{StateTests_RandomTests_st201503122231GO, "StateTests/RandomTests/st201503122231GO"}
declare_test!{StateTests_RandomTests_st201503122238GO, "StateTests/RandomTests/st201503122238GO"}
declare_test!{StateTests_RandomTests_st201503122252GO, "StateTests/RandomTests/st201503122252GO"}
declare_test!{StateTests_RandomTests_st201503122316GO, "StateTests/RandomTests/st201503122316GO"}
declare_test!{StateTests_RandomTests_st201503122324GO, "StateTests/RandomTests/st201503122324GO"}
declare_test!{StateTests_RandomTests_st201503122358GO, "StateTests/RandomTests/st201503122358GO"}
declare_test!{StateTests_RandomTests_st201503130002GO, "StateTests/RandomTests/st201503130002GO"}
declare_test!{StateTests_RandomTests_st201503130005GO, "StateTests/RandomTests/st201503130005GO"}
declare_test!{StateTests_RandomTests_st201503130007GO, "StateTests/RandomTests/st201503130007GO"}
declare_test!{StateTests_RandomTests_st201503130010GO, "StateTests/RandomTests/st201503130010GO"}
declare_test!{StateTests_RandomTests_st201503130023PYTHON, "StateTests/RandomTests/st201503130023PYTHON"}
declare_test!{StateTests_RandomTests_st201503130059GO, "StateTests/RandomTests/st201503130059GO"}
declare_test!{StateTests_RandomTests_st201503130101GO, "StateTests/RandomTests/st201503130101GO"}
declare_test!{StateTests_RandomTests_st201503130109GO, "StateTests/RandomTests/st201503130109GO"}
declare_test!{StateTests_RandomTests_st201503130117GO, "StateTests/RandomTests/st201503130117GO"}
declare_test!{StateTests_RandomTests_st201503130122GO, "StateTests/RandomTests/st201503130122GO"}
declare_test!{StateTests_RandomTests_st201503130156GO, "StateTests/RandomTests/st201503130156GO"}
declare_test!{StateTests_RandomTests_st201503130156PYTHON, "StateTests/RandomTests/st201503130156PYTHON"}
declare_test!{StateTests_RandomTests_st201503130207GO, "StateTests/RandomTests/st201503130207GO"}
declare_test!{StateTests_RandomTests_st201503130219CPPJIT, "StateTests/RandomTests/st201503130219CPPJIT"}
declare_test!{StateTests_RandomTests_st201503130219GO, "StateTests/RandomTests/st201503130219GO"}
declare_test!{StateTests_RandomTests_st201503130243GO, "StateTests/RandomTests/st201503130243GO"}
declare_test!{StateTests_RandomTests_st201503130246GO, "StateTests/RandomTests/st201503130246GO"}
declare_test!{StateTests_RandomTests_st201503130321GO, "StateTests/RandomTests/st201503130321GO"}
declare_test!{StateTests_RandomTests_st201503130322GO, "StateTests/RandomTests/st201503130322GO"}
declare_test!{StateTests_RandomTests_st201503130332GO, "StateTests/RandomTests/st201503130332GO"}
declare_test!{StateTests_RandomTests_st201503130359GO, "StateTests/RandomTests/st201503130359GO"}
declare_test!{StateTests_RandomTests_st201503130405GO, "StateTests/RandomTests/st201503130405GO"}
declare_test!{StateTests_RandomTests_st201503130408GO, "StateTests/RandomTests/st201503130408GO"}
declare_test!{StateTests_RandomTests_st201503130411GO, "StateTests/RandomTests/st201503130411GO"}
declare_test!{StateTests_RandomTests_st201503130431GO, "StateTests/RandomTests/st201503130431GO"}
declare_test!{StateTests_RandomTests_st201503130437GO, "StateTests/RandomTests/st201503130437GO"}
declare_test!{StateTests_RandomTests_st201503130450GO, "StateTests/RandomTests/st201503130450GO"}
declare_test!{StateTests_RandomTests_st201503130512CPPJIT, "StateTests/RandomTests/st201503130512CPPJIT"}
declare_test!{StateTests_RandomTests_st201503130512GO, "StateTests/RandomTests/st201503130512GO"}
declare_test!{StateTests_RandomTests_st201503130615GO, "StateTests/RandomTests/st201503130615GO"}
declare_test!{StateTests_RandomTests_st201503130705GO, "StateTests/RandomTests/st201503130705GO"}
declare_test!{StateTests_RandomTests_st201503130733CPPJIT, "StateTests/RandomTests/st201503130733CPPJIT"}
declare_test!{StateTests_RandomTests_st201503130733GO, "StateTests/RandomTests/st201503130733GO"}
declare_test!{StateTests_RandomTests_st201503130747GO, "StateTests/RandomTests/st201503130747GO"}
declare_test!{StateTests_RandomTests_st201503130751GO, "StateTests/RandomTests/st201503130751GO"}
declare_test!{StateTests_RandomTests_st201503130752PYTHON, "StateTests/RandomTests/st201503130752PYTHON"}
declare_test!{StateTests_RandomTests_st201503130757PYTHON, "StateTests/RandomTests/st201503130757PYTHON"}
declare_test!{StateTests_RandomTests_st201503131658GO, "StateTests/RandomTests/st201503131658GO"}
declare_test!{StateTests_RandomTests_st201503131739GO, "StateTests/RandomTests/st201503131739GO"}
declare_test!{StateTests_RandomTests_st201503131755CPPJIT, "StateTests/RandomTests/st201503131755CPPJIT"}
declare_test!{StateTests_RandomTests_st201503131755GO, "StateTests/RandomTests/st201503131755GO"}
declare_test!{StateTests_RandomTests_st201503132001CPPJIT, "StateTests/RandomTests/st201503132001CPPJIT"}
declare_test!{StateTests_RandomTests_st201503132127PYTHON, "StateTests/RandomTests/st201503132127PYTHON"}
declare_test!{StateTests_RandomTests_st201503132201CPPJIT, "StateTests/RandomTests/st201503132201CPPJIT"}
declare_test!{StateTests_RandomTests_st201503132201GO, "StateTests/RandomTests/st201503132201GO"}
declare_test!{StateTests_RandomTests_st201503132202PYTHON, "StateTests/RandomTests/st201503132202PYTHON"}
declare_test!{StateTests_RandomTests_st201503140002PYTHON, "StateTests/RandomTests/st201503140002PYTHON"}
declare_test!{StateTests_RandomTests_st201503140240PYTHON, "StateTests/RandomTests/st201503140240PYTHON"}
declare_test!{StateTests_RandomTests_st201503140522PYTHON, "StateTests/RandomTests/st201503140522PYTHON"}
declare_test!{StateTests_RandomTests_st201503140756PYTHON, "StateTests/RandomTests/st201503140756PYTHON"}
declare_test!{StateTests_RandomTests_st201503141144PYTHON, "StateTests/RandomTests/st201503141144PYTHON"}
declare_test!{StateTests_RandomTests_st201503141510PYTHON, "StateTests/RandomTests/st201503141510PYTHON"}
declare_test!{StateTests_RandomTests_st201503150427PYTHON, "StateTests/RandomTests/st201503150427PYTHON"}
declare_test!{StateTests_RandomTests_st201503150716PYTHON, "StateTests/RandomTests/st201503150716PYTHON"}
declare_test!{StateTests_RandomTests_st201503151450PYTHON, "StateTests/RandomTests/st201503151450PYTHON"}
declare_test!{StateTests_RandomTests_st201503151516PYTHON, "StateTests/RandomTests/st201503151516PYTHON"}
declare_test!{StateTests_RandomTests_st201503151753PYTHON, "StateTests/RandomTests/st201503151753PYTHON"}
declare_test!{StateTests_RandomTests_st201503152057PYTHON, "StateTests/RandomTests/st201503152057PYTHON"}
declare_test!{StateTests_RandomTests_st201503152241PYTHON, "StateTests/RandomTests/st201503152241PYTHON"}
declare_test!{StateTests_RandomTests_st201503160014PYTHON, "StateTests/RandomTests/st201503160014PYTHON"}
declare_test!{StateTests_RandomTests_st201503160733PYTHON, "StateTests/RandomTests/st201503160733PYTHON"}
declare_test!{StateTests_RandomTests_st201503170051PYTHON, "StateTests/RandomTests/st201503170051PYTHON"}
declare_test!{StateTests_RandomTests_st201503170433PYTHON, "StateTests/RandomTests/st201503170433PYTHON"}
declare_test!{StateTests_RandomTests_st201503170523PYTHON, "StateTests/RandomTests/st201503170523PYTHON"}
declare_test!{StateTests_RandomTests_st201503171108PYTHON, "StateTests/RandomTests/st201503171108PYTHON"}
declare_test!{StateTests_RandomTests_st201503181223GO, "StateTests/RandomTests/st201503181223GO"}
declare_test!{StateTests_RandomTests_st201503181225GO, "StateTests/RandomTests/st201503181225GO"}
declare_test!{StateTests_RandomTests_st201503181226CPPJIT, "StateTests/RandomTests/st201503181226CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181227CPPJIT, "StateTests/RandomTests/st201503181227CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181227GO, "StateTests/RandomTests/st201503181227GO"}
declare_test!{StateTests_RandomTests_st201503181229GO, "StateTests/RandomTests/st201503181229GO"}
declare_test!{StateTests_RandomTests_st201503181230CPPJIT, "StateTests/RandomTests/st201503181230CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181230GO, "StateTests/RandomTests/st201503181230GO"}
declare_test!{StateTests_RandomTests_st201503181231GO, "StateTests/RandomTests/st201503181231GO"}
declare_test!{StateTests_RandomTests_st201503181232CPPJIT, "StateTests/RandomTests/st201503181232CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181232GO, "StateTests/RandomTests/st201503181232GO"}
declare_test!{StateTests_RandomTests_st201503181233GO, "StateTests/RandomTests/st201503181233GO"}
declare_test!{StateTests_RandomTests_st201503181234CPPJIT, "StateTests/RandomTests/st201503181234CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181234GO, "StateTests/RandomTests/st201503181234GO"}
declare_test!{StateTests_RandomTests_st201503181235CPPJIT, "StateTests/RandomTests/st201503181235CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181235GO, "StateTests/RandomTests/st201503181235GO"}
declare_test!{StateTests_RandomTests_st201503181236GO, "StateTests/RandomTests/st201503181236GO"}
declare_test!{StateTests_RandomTests_st201503181237GO, "StateTests/RandomTests/st201503181237GO"}
declare_test!{StateTests_RandomTests_st201503181239GO, "StateTests/RandomTests/st201503181239GO"}
declare_test!{StateTests_RandomTests_st201503181241CPPJIT, "StateTests/RandomTests/st201503181241CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181241GO, "StateTests/RandomTests/st201503181241GO"}
declare_test!{StateTests_RandomTests_st201503181243GO, "StateTests/RandomTests/st201503181243GO"}
declare_test!{StateTests_RandomTests_st201503181244GO, "StateTests/RandomTests/st201503181244GO"}
declare_test!{StateTests_RandomTests_st201503181245CPPJIT, "StateTests/RandomTests/st201503181245CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181245GO, "StateTests/RandomTests/st201503181245GO"}
declare_test!{StateTests_RandomTests_st201503181246CPPJIT, "StateTests/RandomTests/st201503181246CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181246GO, "StateTests/RandomTests/st201503181246GO"}
declare_test!{StateTests_RandomTests_st201503181247GO, "StateTests/RandomTests/st201503181247GO"}
declare_test!{StateTests_RandomTests_st201503181248GO, "StateTests/RandomTests/st201503181248GO"}
declare_test!{StateTests_RandomTests_st201503181249GO, "StateTests/RandomTests/st201503181249GO"}
declare_test!{StateTests_RandomTests_st201503181250CPPJIT, "StateTests/RandomTests/st201503181250CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181250GO, "StateTests/RandomTests/st201503181250GO"}
declare_test!{StateTests_RandomTests_st201503181251GO, "StateTests/RandomTests/st201503181251GO"}
declare_test!{StateTests_RandomTests_st201503181252CPPJIT, "StateTests/RandomTests/st201503181252CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181253GO, "StateTests/RandomTests/st201503181253GO"}
declare_test!{StateTests_RandomTests_st201503181255CPPJIT, "StateTests/RandomTests/st201503181255CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181255GO, "StateTests/RandomTests/st201503181255GO"}
declare_test!{StateTests_RandomTests_st201503181257GO, "StateTests/RandomTests/st201503181257GO"}
declare_test!{StateTests_RandomTests_st201503181258CPPJIT, "StateTests/RandomTests/st201503181258CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181258GO, "StateTests/RandomTests/st201503181258GO"}
declare_test!{StateTests_RandomTests_st201503181301CPPJIT, "StateTests/RandomTests/st201503181301CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181301GO, "StateTests/RandomTests/st201503181301GO"}
declare_test!{StateTests_RandomTests_st201503181303GO, "StateTests/RandomTests/st201503181303GO"}
declare_test!{StateTests_RandomTests_st201503181304GO, "StateTests/RandomTests/st201503181304GO"}
declare_test!{StateTests_RandomTests_st201503181305GO, "StateTests/RandomTests/st201503181305GO"}
declare_test!{StateTests_RandomTests_st201503181306GO, "StateTests/RandomTests/st201503181306GO"}
declare_test!{StateTests_RandomTests_st201503181307CPPJIT, "StateTests/RandomTests/st201503181307CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181307GO, "StateTests/RandomTests/st201503181307GO"}
declare_test!{StateTests_RandomTests_st201503181308GO, "StateTests/RandomTests/st201503181308GO"}
declare_test!{StateTests_RandomTests_st201503181309GO, "StateTests/RandomTests/st201503181309GO"}
declare_test!{StateTests_RandomTests_st201503181310GO, "StateTests/RandomTests/st201503181310GO"}
declare_test!{StateTests_RandomTests_st201503181311GO, "StateTests/RandomTests/st201503181311GO"}
declare_test!{StateTests_RandomTests_st201503181313GO, "StateTests/RandomTests/st201503181313GO"}
declare_test!{StateTests_RandomTests_st201503181314GO, "StateTests/RandomTests/st201503181314GO"}
declare_test!{StateTests_RandomTests_st201503181315CPPJIT, "StateTests/RandomTests/st201503181315CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181315GO, "StateTests/RandomTests/st201503181315GO"}
declare_test!{StateTests_RandomTests_st201503181316CPPJIT, "StateTests/RandomTests/st201503181316CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181316PYTHON, "StateTests/RandomTests/st201503181316PYTHON"}
declare_test!{StateTests_RandomTests_st201503181317GO, "StateTests/RandomTests/st201503181317GO"}
declare_test!{StateTests_RandomTests_st201503181318CPPJIT, "StateTests/RandomTests/st201503181318CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181318GO, "StateTests/RandomTests/st201503181318GO"}
declare_test!{StateTests_RandomTests_st201503181319GO, "StateTests/RandomTests/st201503181319GO"}
declare_test!{StateTests_RandomTests_st201503181319PYTHON, "StateTests/RandomTests/st201503181319PYTHON"}
declare_test!{StateTests_RandomTests_st201503181322GO, "StateTests/RandomTests/st201503181322GO"}
declare_test!{StateTests_RandomTests_st201503181323CPPJIT, "StateTests/RandomTests/st201503181323CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181323GO, "StateTests/RandomTests/st201503181323GO"}
declare_test!{StateTests_RandomTests_st201503181324GO, "StateTests/RandomTests/st201503181324GO"}
declare_test!{StateTests_RandomTests_st201503181325GO, "StateTests/RandomTests/st201503181325GO"}
declare_test!{StateTests_RandomTests_st201503181326CPPJIT, "StateTests/RandomTests/st201503181326CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181326GO, "StateTests/RandomTests/st201503181326GO"}
declare_test!{StateTests_RandomTests_st201503181327GO, "StateTests/RandomTests/st201503181327GO"}
declare_test!{StateTests_RandomTests_st201503181329CPPJIT, "StateTests/RandomTests/st201503181329CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181329GO, "StateTests/RandomTests/st201503181329GO"}
declare_test!{StateTests_RandomTests_st201503181330GO, "StateTests/RandomTests/st201503181330GO"}
declare_test!{StateTests_RandomTests_st201503181332GO, "StateTests/RandomTests/st201503181332GO"}
declare_test!{StateTests_RandomTests_st201503181333GO, "StateTests/RandomTests/st201503181333GO"}
declare_test!{StateTests_RandomTests_st201503181334GO, "StateTests/RandomTests/st201503181334GO"}
declare_test!{StateTests_RandomTests_st201503181336CPPJIT, "StateTests/RandomTests/st201503181336CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181337GO, "StateTests/RandomTests/st201503181337GO"}
declare_test!{StateTests_RandomTests_st201503181338GO, "StateTests/RandomTests/st201503181338GO"}
declare_test!{StateTests_RandomTests_st201503181339CPPJIT, "StateTests/RandomTests/st201503181339CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181339GO, "StateTests/RandomTests/st201503181339GO"}
declare_test!{StateTests_RandomTests_st201503181340GO, "StateTests/RandomTests/st201503181340GO"}
declare_test!{StateTests_RandomTests_st201503181341CPPJIT, "StateTests/RandomTests/st201503181341CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181342CPPJIT, "StateTests/RandomTests/st201503181342CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181342GO, "StateTests/RandomTests/st201503181342GO"}
declare_test!{StateTests_RandomTests_st201503181345GO, "StateTests/RandomTests/st201503181345GO"}
declare_test!{StateTests_RandomTests_st201503181346GO, "StateTests/RandomTests/st201503181346GO"}
declare_test!{StateTests_RandomTests_st201503181347CPPJIT, "StateTests/RandomTests/st201503181347CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181347GO, "StateTests/RandomTests/st201503181347GO"}
declare_test!{StateTests_RandomTests_st201503181347PYTHON, "StateTests/RandomTests/st201503181347PYTHON"}
declare_test!{StateTests_RandomTests_st201503181350CPPJIT, "StateTests/RandomTests/st201503181350CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181352GO, "StateTests/RandomTests/st201503181352GO"}
declare_test!{StateTests_RandomTests_st201503181353GO, "StateTests/RandomTests/st201503181353GO"}
declare_test!{StateTests_RandomTests_st201503181354CPPJIT, "StateTests/RandomTests/st201503181354CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181354GO, "StateTests/RandomTests/st201503181354GO"}
declare_test!{StateTests_RandomTests_st201503181355GO, "StateTests/RandomTests/st201503181355GO"}
declare_test!{StateTests_RandomTests_st201503181356CPPJIT, "StateTests/RandomTests/st201503181356CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181357CPPJIT, "StateTests/RandomTests/st201503181357CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181358CPPJIT, "StateTests/RandomTests/st201503181358CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181358GO, "StateTests/RandomTests/st201503181358GO"}
declare_test!{StateTests_RandomTests_st201503181359GO, "StateTests/RandomTests/st201503181359GO"}
declare_test!{StateTests_RandomTests_st201503181402CPPJIT, "StateTests/RandomTests/st201503181402CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181403GO, "StateTests/RandomTests/st201503181403GO"}
declare_test!{StateTests_RandomTests_st201503181406CPPJIT, "StateTests/RandomTests/st201503181406CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181406GO, "StateTests/RandomTests/st201503181406GO"}
declare_test!{StateTests_RandomTests_st201503181410GO, "StateTests/RandomTests/st201503181410GO"}
declare_test!{StateTests_RandomTests_st201503181412CPPJIT, "StateTests/RandomTests/st201503181412CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181413GO, "StateTests/RandomTests/st201503181413GO"}
declare_test!{StateTests_RandomTests_st201503181415GO, "StateTests/RandomTests/st201503181415GO"}
declare_test!{StateTests_RandomTests_st201503181416GO, "StateTests/RandomTests/st201503181416GO"}
declare_test!{StateTests_RandomTests_st201503181417CPPJIT, "StateTests/RandomTests/st201503181417CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181417GO, "StateTests/RandomTests/st201503181417GO"}
declare_test!{StateTests_RandomTests_st201503181418CPPJIT, "StateTests/RandomTests/st201503181418CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181422GO, "StateTests/RandomTests/st201503181422GO"}
declare_test!{StateTests_RandomTests_st201503181423CPPJIT, "StateTests/RandomTests/st201503181423CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181424GO, "StateTests/RandomTests/st201503181424GO"}
declare_test!{StateTests_RandomTests_st201503181426CPPJIT, "StateTests/RandomTests/st201503181426CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181426GO, "StateTests/RandomTests/st201503181426GO"}
declare_test!{StateTests_RandomTests_st201503181428GO, "StateTests/RandomTests/st201503181428GO"}
declare_test!{StateTests_RandomTests_st201503181430CPPJIT, "StateTests/RandomTests/st201503181430CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181435GO, "StateTests/RandomTests/st201503181435GO"}
declare_test!{StateTests_RandomTests_st201503181436GO, "StateTests/RandomTests/st201503181436GO"}
declare_test!{StateTests_RandomTests_st201503181437CPPJIT, "StateTests/RandomTests/st201503181437CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181437GO, "StateTests/RandomTests/st201503181437GO"}
declare_test!{StateTests_RandomTests_st201503181438CPPJIT, "StateTests/RandomTests/st201503181438CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181438GO, "StateTests/RandomTests/st201503181438GO"}
declare_test!{StateTests_RandomTests_st201503181439CPPJIT, "StateTests/RandomTests/st201503181439CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181439GO, "StateTests/RandomTests/st201503181439GO"}
declare_test!{StateTests_RandomTests_st201503181439PYTHON, "StateTests/RandomTests/st201503181439PYTHON"}
declare_test!{StateTests_RandomTests_st201503181440GO, "StateTests/RandomTests/st201503181440GO"}
declare_test!{StateTests_RandomTests_st201503181441GO, "StateTests/RandomTests/st201503181441GO"}
declare_test!{StateTests_RandomTests_st201503181442GO, "StateTests/RandomTests/st201503181442GO"}
declare_test!{StateTests_RandomTests_st201503181445CPPJIT, "StateTests/RandomTests/st201503181445CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181446GO, "StateTests/RandomTests/st201503181446GO"}
declare_test!{StateTests_RandomTests_st201503181447GO, "StateTests/RandomTests/st201503181447GO"}
declare_test!{StateTests_RandomTests_st201503181450GO, "StateTests/RandomTests/st201503181450GO"}
declare_test!{StateTests_RandomTests_st201503181451CPPJIT, "StateTests/RandomTests/st201503181451CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181453GO, "StateTests/RandomTests/st201503181453GO"}
declare_test!{StateTests_RandomTests_st201503181455GO, "StateTests/RandomTests/st201503181455GO"}
declare_test!{StateTests_RandomTests_st201503181456CPPJIT, "StateTests/RandomTests/st201503181456CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181457GO, "StateTests/RandomTests/st201503181457GO"}
declare_test!{StateTests_RandomTests_st201503181458GO, "StateTests/RandomTests/st201503181458GO"}
declare_test!{StateTests_RandomTests_st201503181459GO, "StateTests/RandomTests/st201503181459GO"}
declare_test!{StateTests_RandomTests_st201503181500GO, "StateTests/RandomTests/st201503181500GO"}
declare_test!{StateTests_RandomTests_st201503181501GO, "StateTests/RandomTests/st201503181501GO"}
declare_test!{StateTests_RandomTests_st201503181503GO, "StateTests/RandomTests/st201503181503GO"}
declare_test!{StateTests_RandomTests_st201503181504GO, "StateTests/RandomTests/st201503181504GO"}
declare_test!{StateTests_RandomTests_st201503181505GO, "StateTests/RandomTests/st201503181505GO"}
declare_test!{StateTests_RandomTests_st201503181506CPPJIT, "StateTests/RandomTests/st201503181506CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181507GO, "StateTests/RandomTests/st201503181507GO"}
declare_test!{StateTests_RandomTests_st201503181509CPPJIT, "StateTests/RandomTests/st201503181509CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181509GO, "StateTests/RandomTests/st201503181509GO"}
declare_test!{StateTests_RandomTests_st201503181510GO, "StateTests/RandomTests/st201503181510GO"}
declare_test!{StateTests_RandomTests_st201503181511GO, "StateTests/RandomTests/st201503181511GO"}
declare_test!{StateTests_RandomTests_st201503181512GO, "StateTests/RandomTests/st201503181512GO"}
declare_test!{StateTests_RandomTests_st201503181513CPPJIT, "StateTests/RandomTests/st201503181513CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181513GO, "StateTests/RandomTests/st201503181513GO"}
declare_test!{StateTests_RandomTests_st201503181514CPPJIT, "StateTests/RandomTests/st201503181514CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181514GO, "StateTests/RandomTests/st201503181514GO"}
declare_test!{StateTests_RandomTests_st201503181517CPPJIT, "StateTests/RandomTests/st201503181517CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181517GO, "StateTests/RandomTests/st201503181517GO"}
declare_test!{StateTests_RandomTests_st201503181519CPPJIT, "StateTests/RandomTests/st201503181519CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181519GO, "StateTests/RandomTests/st201503181519GO"}
declare_test!{StateTests_RandomTests_st201503181520CPPJIT, "StateTests/RandomTests/st201503181520CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181520GO, "StateTests/RandomTests/st201503181520GO"}
declare_test!{StateTests_RandomTests_st201503181521GO, "StateTests/RandomTests/st201503181521GO"}
declare_test!{StateTests_RandomTests_st201503181522GO, "StateTests/RandomTests/st201503181522GO"}
declare_test!{StateTests_RandomTests_st201503181524CPPJIT, "StateTests/RandomTests/st201503181524CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181524GO, "StateTests/RandomTests/st201503181524GO"}
declare_test!{StateTests_RandomTests_st201503181526GO, "StateTests/RandomTests/st201503181526GO"}
declare_test!{StateTests_RandomTests_st201503181527GO, "StateTests/RandomTests/st201503181527GO"}
declare_test!{StateTests_RandomTests_st201503181528CPPJIT, "StateTests/RandomTests/st201503181528CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181528GO, "StateTests/RandomTests/st201503181528GO"}
declare_test!{StateTests_RandomTests_st201503181528PYTHON, "StateTests/RandomTests/st201503181528PYTHON"}
declare_test!{StateTests_RandomTests_st201503181529GO, "StateTests/RandomTests/st201503181529GO"}
declare_test!{StateTests_RandomTests_st201503181531CPPJIT, "StateTests/RandomTests/st201503181531CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181533GO, "StateTests/RandomTests/st201503181533GO"}
declare_test!{StateTests_RandomTests_st201503181534CPPJIT, "StateTests/RandomTests/st201503181534CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181534GO, "StateTests/RandomTests/st201503181534GO"}
declare_test!{StateTests_RandomTests_st201503181536CPPJIT, "StateTests/RandomTests/st201503181536CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181536GO, "StateTests/RandomTests/st201503181536GO"}
declare_test!{StateTests_RandomTests_st201503181537GO, "StateTests/RandomTests/st201503181537GO"}
declare_test!{StateTests_RandomTests_st201503181538GO, "StateTests/RandomTests/st201503181538GO"}
declare_test!{StateTests_RandomTests_st201503181539GO, "StateTests/RandomTests/st201503181539GO"}
declare_test!{StateTests_RandomTests_st201503181540CPPJIT, "StateTests/RandomTests/st201503181540CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181540PYTHON, "StateTests/RandomTests/st201503181540PYTHON"}
declare_test!{StateTests_RandomTests_st201503181543GO, "StateTests/RandomTests/st201503181543GO"}
declare_test!{StateTests_RandomTests_st201503181544CPPJIT, "StateTests/RandomTests/st201503181544CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181544GO, "StateTests/RandomTests/st201503181544GO"}
declare_test!{StateTests_RandomTests_st201503181547GO, "StateTests/RandomTests/st201503181547GO"}
declare_test!{StateTests_RandomTests_st201503181548CPPJIT, "StateTests/RandomTests/st201503181548CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181548GO, "StateTests/RandomTests/st201503181548GO"}
declare_test!{StateTests_RandomTests_st201503181551GO, "StateTests/RandomTests/st201503181551GO"}
declare_test!{StateTests_RandomTests_st201503181552CPPJIT, "StateTests/RandomTests/st201503181552CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181553GO, "StateTests/RandomTests/st201503181553GO"}
declare_test!{StateTests_RandomTests_st201503181555CPPJIT, "StateTests/RandomTests/st201503181555CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181555GO, "StateTests/RandomTests/st201503181555GO"}
declare_test!{StateTests_RandomTests_st201503181557GO, "StateTests/RandomTests/st201503181557GO"}
declare_test!{StateTests_RandomTests_st201503181559GO, "StateTests/RandomTests/st201503181559GO"}
declare_test!{StateTests_RandomTests_st201503181601CPPJIT, "StateTests/RandomTests/st201503181601CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181601GO, "StateTests/RandomTests/st201503181601GO"}
declare_test!{StateTests_RandomTests_st201503181602GO, "StateTests/RandomTests/st201503181602GO"}
declare_test!{StateTests_RandomTests_st201503181603GO, "StateTests/RandomTests/st201503181603GO"}
declare_test!{StateTests_RandomTests_st201503181604GO, "StateTests/RandomTests/st201503181604GO"}
declare_test!{StateTests_RandomTests_st201503181605GO, "StateTests/RandomTests/st201503181605GO"}
declare_test!{StateTests_RandomTests_st201503181606GO, "StateTests/RandomTests/st201503181606GO"}
declare_test!{StateTests_RandomTests_st201503181607GO, "StateTests/RandomTests/st201503181607GO"}
declare_test!{StateTests_RandomTests_st201503181608CPPJIT, "StateTests/RandomTests/st201503181608CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181608GO, "StateTests/RandomTests/st201503181608GO"}
declare_test!{StateTests_RandomTests_st201503181609GO, "StateTests/RandomTests/st201503181609GO"}
declare_test!{StateTests_RandomTests_st201503181610CPPJIT, "StateTests/RandomTests/st201503181610CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181610GO, "StateTests/RandomTests/st201503181610GO"}
declare_test!{StateTests_RandomTests_st201503181611CPPJIT, "StateTests/RandomTests/st201503181611CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181611GO, "StateTests/RandomTests/st201503181611GO"}
declare_test!{StateTests_RandomTests_st201503181612GO, "StateTests/RandomTests/st201503181612GO"}
declare_test!{StateTests_RandomTests_st201503181614CPPJIT, "StateTests/RandomTests/st201503181614CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181614GO, "StateTests/RandomTests/st201503181614GO"}
declare_test!{StateTests_RandomTests_st201503181616CPPJIT, "StateTests/RandomTests/st201503181616CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181616GO, "StateTests/RandomTests/st201503181616GO"}
declare_test!{StateTests_RandomTests_st201503181617GO, "StateTests/RandomTests/st201503181617GO"}
declare_test!{StateTests_RandomTests_st201503181618GO, "StateTests/RandomTests/st201503181618GO"}
declare_test!{StateTests_RandomTests_st201503181619GO, "StateTests/RandomTests/st201503181619GO"}
declare_test!{StateTests_RandomTests_st201503181620CPPJIT, "StateTests/RandomTests/st201503181620CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181620GO, "StateTests/RandomTests/st201503181620GO"}
declare_test!{StateTests_RandomTests_st201503181621GO, "StateTests/RandomTests/st201503181621GO"}
declare_test!{StateTests_RandomTests_st201503181625GO, "StateTests/RandomTests/st201503181625GO"}
declare_test!{StateTests_RandomTests_st201503181626CPPJIT, "StateTests/RandomTests/st201503181626CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181626GO, "StateTests/RandomTests/st201503181626GO"}
declare_test!{StateTests_RandomTests_st201503181627GO, "StateTests/RandomTests/st201503181627GO"}
declare_test!{StateTests_RandomTests_st201503181628GO, "StateTests/RandomTests/st201503181628GO"}
declare_test!{StateTests_RandomTests_st201503181629GO, "StateTests/RandomTests/st201503181629GO"}
declare_test!{StateTests_RandomTests_st201503181630CPPJIT, "StateTests/RandomTests/st201503181630CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181630GO, "StateTests/RandomTests/st201503181630GO"}
declare_test!{StateTests_RandomTests_st201503181630PYTHON, "StateTests/RandomTests/st201503181630PYTHON"}
declare_test!{StateTests_RandomTests_st201503181632GO, "StateTests/RandomTests/st201503181632GO"}
declare_test!{StateTests_RandomTests_st201503181634CPPJIT, "StateTests/RandomTests/st201503181634CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181635GO, "StateTests/RandomTests/st201503181635GO"}
declare_test!{StateTests_RandomTests_st201503181636GO, "StateTests/RandomTests/st201503181636GO"}
declare_test!{StateTests_RandomTests_st201503181638GO, "StateTests/RandomTests/st201503181638GO"}
declare_test!{StateTests_RandomTests_st201503181639CPPJIT, "StateTests/RandomTests/st201503181639CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181641GO, "StateTests/RandomTests/st201503181641GO"}
declare_test!{StateTests_RandomTests_st201503181645GO, "StateTests/RandomTests/st201503181645GO"}
declare_test!{StateTests_RandomTests_st201503181646GO, "StateTests/RandomTests/st201503181646GO"}
declare_test!{StateTests_RandomTests_st201503181647CPPJIT, "StateTests/RandomTests/st201503181647CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181649CPPJIT, "StateTests/RandomTests/st201503181649CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181650GO, "StateTests/RandomTests/st201503181650GO"}
declare_test!{StateTests_RandomTests_st201503181652CPPJIT, "StateTests/RandomTests/st201503181652CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181653GO, "StateTests/RandomTests/st201503181653GO"}
declare_test!{StateTests_RandomTests_st201503181654GO, "StateTests/RandomTests/st201503181654GO"}
declare_test!{StateTests_RandomTests_st201503181655CPPJIT, "StateTests/RandomTests/st201503181655CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181655GO, "StateTests/RandomTests/st201503181655GO"}
declare_test!{StateTests_RandomTests_st201503181656CPPJIT, "StateTests/RandomTests/st201503181656CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181656GO, "StateTests/RandomTests/st201503181656GO"}
declare_test!{StateTests_RandomTests_st201503181657GO, "StateTests/RandomTests/st201503181657GO"}
declare_test!{StateTests_RandomTests_st201503181658GO, "StateTests/RandomTests/st201503181658GO"}
declare_test!{StateTests_RandomTests_st201503181700GO, "StateTests/RandomTests/st201503181700GO"}
declare_test!{StateTests_RandomTests_st201503181702GO, "StateTests/RandomTests/st201503181702GO"}
declare_test!{StateTests_RandomTests_st201503181703CPPJIT, "StateTests/RandomTests/st201503181703CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181703GO, "StateTests/RandomTests/st201503181703GO"}
declare_test!{StateTests_RandomTests_st201503181704GO, "StateTests/RandomTests/st201503181704GO"}
declare_test!{StateTests_RandomTests_st201503181706GO, "StateTests/RandomTests/st201503181706GO"}
declare_test!{StateTests_RandomTests_st201503181709GO, "StateTests/RandomTests/st201503181709GO"}
declare_test!{StateTests_RandomTests_st201503181711CPPJIT, "StateTests/RandomTests/st201503181711CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181711GO, "StateTests/RandomTests/st201503181711GO"}
declare_test!{StateTests_RandomTests_st201503181713CPPJIT, "StateTests/RandomTests/st201503181713CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181713GO, "StateTests/RandomTests/st201503181713GO"}
declare_test!{StateTests_RandomTests_st201503181714GO, "StateTests/RandomTests/st201503181714GO"}
declare_test!{StateTests_RandomTests_st201503181715CPPJIT, "StateTests/RandomTests/st201503181715CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181715GO, "StateTests/RandomTests/st201503181715GO"}
declare_test!{StateTests_RandomTests_st201503181716GO, "StateTests/RandomTests/st201503181716GO"}
declare_test!{StateTests_RandomTests_st201503181717GO, "StateTests/RandomTests/st201503181717GO"}
declare_test!{StateTests_RandomTests_st201503181720CPPJIT, "StateTests/RandomTests/st201503181720CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181722GO, "StateTests/RandomTests/st201503181722GO"}
declare_test!{StateTests_RandomTests_st201503181723CPPJIT, "StateTests/RandomTests/st201503181723CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181723GO, "StateTests/RandomTests/st201503181723GO"}
declare_test!{StateTests_RandomTests_st201503181724CPPJIT, "StateTests/RandomTests/st201503181724CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181724GO, "StateTests/RandomTests/st201503181724GO"}
declare_test!{StateTests_RandomTests_st201503181725GO, "StateTests/RandomTests/st201503181725GO"}
declare_test!{StateTests_RandomTests_st201503181728GO, "StateTests/RandomTests/st201503181728GO"}
declare_test!{StateTests_RandomTests_st201503181729GO, "StateTests/RandomTests/st201503181729GO"}
declare_test!{StateTests_RandomTests_st201503181730GO, "StateTests/RandomTests/st201503181730GO"}
declare_test!{StateTests_RandomTests_st201503181731CPPJIT, "StateTests/RandomTests/st201503181731CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181732GO, "StateTests/RandomTests/st201503181732GO"}
declare_test!{StateTests_RandomTests_st201503181734CPPJIT, "StateTests/RandomTests/st201503181734CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181734GO, "StateTests/RandomTests/st201503181734GO"}
declare_test!{StateTests_RandomTests_st201503181735GO, "StateTests/RandomTests/st201503181735GO"}
declare_test!{StateTests_RandomTests_st201503181737CPPJIT, "StateTests/RandomTests/st201503181737CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181737GO, "StateTests/RandomTests/st201503181737GO"}
declare_test!{StateTests_RandomTests_st201503181738CPPJIT, "StateTests/RandomTests/st201503181738CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181738GO, "StateTests/RandomTests/st201503181738GO"}
declare_test!{StateTests_RandomTests_st201503181739GO, "StateTests/RandomTests/st201503181739GO"}
declare_test!{StateTests_RandomTests_st201503181740CPPJIT, "StateTests/RandomTests/st201503181740CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181740GO, "StateTests/RandomTests/st201503181740GO"}
declare_test!{StateTests_RandomTests_st201503181742CPPJIT, "StateTests/RandomTests/st201503181742CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181743GO, "StateTests/RandomTests/st201503181743GO"}
declare_test!{StateTests_RandomTests_st201503181744GO, "StateTests/RandomTests/st201503181744GO"}
declare_test!{StateTests_RandomTests_st201503181745CPPJIT, "StateTests/RandomTests/st201503181745CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181746GO, "StateTests/RandomTests/st201503181746GO"}
declare_test!{StateTests_RandomTests_st201503181747GO, "StateTests/RandomTests/st201503181747GO"}
declare_test!{StateTests_RandomTests_st201503181748GO, "StateTests/RandomTests/st201503181748GO"}
declare_test!{StateTests_RandomTests_st201503181749GO, "StateTests/RandomTests/st201503181749GO"}
declare_test!{StateTests_RandomTests_st201503181750CPPJIT, "StateTests/RandomTests/st201503181750CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181750GO, "StateTests/RandomTests/st201503181750GO"}
declare_test!{StateTests_RandomTests_st201503181752GO, "StateTests/RandomTests/st201503181752GO"}
declare_test!{StateTests_RandomTests_st201503181753CPPJIT, "StateTests/RandomTests/st201503181753CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181754CPPJIT, "StateTests/RandomTests/st201503181754CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181754GO, "StateTests/RandomTests/st201503181754GO"}
declare_test!{StateTests_RandomTests_st201503181755CPPJIT, "StateTests/RandomTests/st201503181755CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181755GO, "StateTests/RandomTests/st201503181755GO"}
declare_test!{StateTests_RandomTests_st201503181756GO, "StateTests/RandomTests/st201503181756GO"}
declare_test!{StateTests_RandomTests_st201503181757CPPJIT, "StateTests/RandomTests/st201503181757CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181757GO, "StateTests/RandomTests/st201503181757GO"}
declare_test!{StateTests_RandomTests_st201503181759GO, "StateTests/RandomTests/st201503181759GO"}
declare_test!{StateTests_RandomTests_st201503181800GO, "StateTests/RandomTests/st201503181800GO"}
declare_test!{StateTests_RandomTests_st201503181801GO, "StateTests/RandomTests/st201503181801GO"}
declare_test!{StateTests_RandomTests_st201503181802GO, "StateTests/RandomTests/st201503181802GO"}
declare_test!{StateTests_RandomTests_st201503181803CPPJIT, "StateTests/RandomTests/st201503181803CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181803GO, "StateTests/RandomTests/st201503181803GO"}
declare_test!{StateTests_RandomTests_st201503181804GO, "StateTests/RandomTests/st201503181804GO"}
declare_test!{StateTests_RandomTests_st201503181806GO, "StateTests/RandomTests/st201503181806GO"}
declare_test!{StateTests_RandomTests_st201503181808GO, "StateTests/RandomTests/st201503181808GO"}
declare_test!{StateTests_RandomTests_st201503181809CPPJIT, "StateTests/RandomTests/st201503181809CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181812CPPJIT, "StateTests/RandomTests/st201503181812CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181812GO, "StateTests/RandomTests/st201503181812GO"}
declare_test!{StateTests_RandomTests_st201503181814CPPJIT, "StateTests/RandomTests/st201503181814CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181815GO, "StateTests/RandomTests/st201503181815GO"}
declare_test!{StateTests_RandomTests_st201503181816CPPJIT, "StateTests/RandomTests/st201503181816CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181817CPPJIT, "StateTests/RandomTests/st201503181817CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181819GO, "StateTests/RandomTests/st201503181819GO"}
declare_test!{StateTests_RandomTests_st201503181821GO, "StateTests/RandomTests/st201503181821GO"}
declare_test!{StateTests_RandomTests_st201503181822GO, "StateTests/RandomTests/st201503181822GO"}
declare_test!{StateTests_RandomTests_st201503181823GO, "StateTests/RandomTests/st201503181823GO"}
declare_test!{StateTests_RandomTests_st201503181824GO, "StateTests/RandomTests/st201503181824GO"}
declare_test!{StateTests_RandomTests_st201503181825GO, "StateTests/RandomTests/st201503181825GO"}
declare_test!{StateTests_RandomTests_st201503181829GO, "StateTests/RandomTests/st201503181829GO"}
declare_test!{StateTests_RandomTests_st201503181830CPPJIT, "StateTests/RandomTests/st201503181830CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181833GO, "StateTests/RandomTests/st201503181833GO"}
declare_test!{StateTests_RandomTests_st201503181834CPPJIT, "StateTests/RandomTests/st201503181834CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181834GO, "StateTests/RandomTests/st201503181834GO"}
declare_test!{StateTests_RandomTests_st201503181837GO, "StateTests/RandomTests/st201503181837GO"}
declare_test!{StateTests_RandomTests_st201503181840GO, "StateTests/RandomTests/st201503181840GO"}
declare_test!{StateTests_RandomTests_st201503181842GO, "StateTests/RandomTests/st201503181842GO"}
declare_test!{StateTests_RandomTests_st201503181843GO, "StateTests/RandomTests/st201503181843GO"}
declare_test!{StateTests_RandomTests_st201503181844GO, "StateTests/RandomTests/st201503181844GO"}
declare_test!{StateTests_RandomTests_st201503181845GO, "StateTests/RandomTests/st201503181845GO"}
declare_test!{StateTests_RandomTests_st201503181846GO, "StateTests/RandomTests/st201503181846GO"}
declare_test!{StateTests_RandomTests_st201503181847GO, "StateTests/RandomTests/st201503181847GO"}
declare_test!{StateTests_RandomTests_st201503181848GO, "StateTests/RandomTests/st201503181848GO"}
declare_test!{StateTests_RandomTests_st201503181849GO, "StateTests/RandomTests/st201503181849GO"}
declare_test!{StateTests_RandomTests_st201503181850GO, "StateTests/RandomTests/st201503181850GO"}
declare_test!{StateTests_RandomTests_st201503181851CPPJIT, "StateTests/RandomTests/st201503181851CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181851GO, "StateTests/RandomTests/st201503181851GO"}
declare_test!{StateTests_RandomTests_st201503181852CPPJIT, "StateTests/RandomTests/st201503181852CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181854GO, "StateTests/RandomTests/st201503181854GO"}
declare_test!{StateTests_RandomTests_st201503181855CPPJIT, "StateTests/RandomTests/st201503181855CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181857PYTHON, "StateTests/RandomTests/st201503181857PYTHON"}
declare_test!{StateTests_RandomTests_st201503181859GO, "StateTests/RandomTests/st201503181859GO"}
declare_test!{StateTests_RandomTests_st201503181900GO, "StateTests/RandomTests/st201503181900GO"}
declare_test!{StateTests_RandomTests_st201503181903GO, "StateTests/RandomTests/st201503181903GO"}
declare_test!{StateTests_RandomTests_st201503181904GO, "StateTests/RandomTests/st201503181904GO"}
declare_test!{StateTests_RandomTests_st201503181906GO, "StateTests/RandomTests/st201503181906GO"}
declare_test!{StateTests_RandomTests_st201503181907GO, "StateTests/RandomTests/st201503181907GO"}
declare_test!{StateTests_RandomTests_st201503181910GO, "StateTests/RandomTests/st201503181910GO"}
declare_test!{StateTests_RandomTests_st201503181915GO, "StateTests/RandomTests/st201503181915GO"}
declare_test!{StateTests_RandomTests_st201503181919CPPJIT, "StateTests/RandomTests/st201503181919CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181919PYTHON, "StateTests/RandomTests/st201503181919PYTHON"}
declare_test!{StateTests_RandomTests_st201503181920GO, "StateTests/RandomTests/st201503181920GO"}
declare_test!{StateTests_RandomTests_st201503181922GO, "StateTests/RandomTests/st201503181922GO"}
declare_test!{StateTests_RandomTests_st201503181926GO, "StateTests/RandomTests/st201503181926GO"}
declare_test!{StateTests_RandomTests_st201503181929GO, "StateTests/RandomTests/st201503181929GO"}
declare_test!{StateTests_RandomTests_st201503181931CPPJIT, "StateTests/RandomTests/st201503181931CPPJIT"}
declare_test!{StateTests_RandomTests_st201503181931GO, "StateTests/RandomTests/st201503181931GO"}
declare_test!{StateTests_RandomTests_st201503181931PYTHON, "StateTests/RandomTests/st201503181931PYTHON"}
declare_test!{StateTests_RandomTests_st201503191646GO, "StateTests/RandomTests/st201503191646GO"}
declare_test!{StateTests_RandomTests_st201503200837JS, "StateTests/RandomTests/st201503200837JS"}
declare_test!{StateTests_RandomTests_st201503200838JS, "StateTests/RandomTests/st201503200838JS"}
declare_test!{StateTests_RandomTests_st201503200841JS, "StateTests/RandomTests/st201503200841JS"}
declare_test!{StateTests_RandomTests_st201503200848JS, "StateTests/RandomTests/st201503200848JS"}
declare_test!{StateTests_RandomTests_st201503240609JS, "StateTests/RandomTests/st201503240609JS"}
declare_test!{StateTests_RandomTests_st201503302200JS, "StateTests/RandomTests/st201503302200JS"}
declare_test!{StateTests_RandomTests_st201503302202JS, "StateTests/RandomTests/st201503302202JS"}
declare_test!{StateTests_RandomTests_st201503302206JS, "StateTests/RandomTests/st201503302206JS"}
declare_test!{StateTests_RandomTests_st201503302208JS, "StateTests/RandomTests/st201503302208JS"}
declare_test!{StateTests_RandomTests_st201503302210JS, "StateTests/RandomTests/st201503302210JS"}
declare_test!{StateTests_RandomTests_st201503302211JS, "StateTests/RandomTests/st201503302211JS"}
declare_test!{StateTests_RandomTests_st201504011535GO, "StateTests/RandomTests/st201504011535GO"}
declare_test!{StateTests_RandomTests_st201504011536GO, "StateTests/RandomTests/st201504011536GO"}
declare_test!{StateTests_RandomTests_st201504011547GO, "StateTests/RandomTests/st201504011547GO"}
declare_test!{StateTests_RandomTests_st201504011916JS, "StateTests/RandomTests/st201504011916JS"}
declare_test!{StateTests_RandomTests_st201504012130JS, "StateTests/RandomTests/st201504012130JS"}
declare_test!{StateTests_RandomTests_st201504012259JS, "StateTests/RandomTests/st201504012259JS"}
declare_test!{StateTests_RandomTests_st201504012359JS, "StateTests/RandomTests/st201504012359JS"}
declare_test!{StateTests_RandomTests_st201504020305JS, "StateTests/RandomTests/st201504020305JS"}
declare_test!{StateTests_RandomTests_st201504020400JS, "StateTests/RandomTests/st201504020400JS"}
declare_test!{StateTests_RandomTests_st201504020428JS, "StateTests/RandomTests/st201504020428JS"}
declare_test!{StateTests_RandomTests_st201504020431JS, "StateTests/RandomTests/st201504020431JS"}
declare_test!{StateTests_RandomTests_st201504020444JS, "StateTests/RandomTests/st201504020444JS"}
declare_test!{StateTests_RandomTests_st201504020538JS, "StateTests/RandomTests/st201504020538JS"}
declare_test!{StateTests_RandomTests_st201504020639JS, "StateTests/RandomTests/st201504020639JS"}
declare_test!{StateTests_RandomTests_st201504020836JS, "StateTests/RandomTests/st201504020836JS"}
declare_test!{StateTests_RandomTests_st201504020910JS, "StateTests/RandomTests/st201504020910JS"}
declare_test!{StateTests_RandomTests_st201504021057JS, "StateTests/RandomTests/st201504021057JS"}
declare_test!{StateTests_RandomTests_st201504021104JS, "StateTests/RandomTests/st201504021104JS"}
declare_test!{StateTests_RandomTests_st201504021237CPPJIT, "StateTests/RandomTests/st201504021237CPPJIT"}
declare_test!{StateTests_RandomTests_st201504021237GO, "StateTests/RandomTests/st201504021237GO"}
declare_test!{StateTests_RandomTests_st201504021237JS, "StateTests/RandomTests/st201504021237JS"}
declare_test!{StateTests_RandomTests_st201504021237PYTHON, "StateTests/RandomTests/st201504021237PYTHON"}
declare_test!{StateTests_RandomTests_st201504021949JS, "StateTests/RandomTests/st201504021949JS"}
declare_test!{StateTests_RandomTests_st201504022003CPPJIT, "StateTests/RandomTests/st201504022003CPPJIT"}
declare_test!{StateTests_RandomTests_st201504022124JS, "StateTests/RandomTests/st201504022124JS"}
declare_test!{StateTests_RandomTests_st201504030138JS, "StateTests/RandomTests/st201504030138JS"}
declare_test!{StateTests_RandomTests_st201504030646JS, "StateTests/RandomTests/st201504030646JS"}
declare_test!{StateTests_RandomTests_st201504030709JS, "StateTests/RandomTests/st201504030709JS"}
declare_test!{StateTests_RandomTests_st201504031133JS, "StateTests/RandomTests/st201504031133JS"}
declare_test!{StateTests_RandomTests_st201504031446JS, "StateTests/RandomTests/st201504031446JS"}
declare_test!{StateTests_RandomTests_st201504031841JS, "StateTests/RandomTests/st201504031841JS"}
declare_test!{StateTests_RandomTests_st201504041605JS, "StateTests/RandomTests/st201504041605JS"}
declare_test!{StateTests_RandomTests_st201504042052JS, "StateTests/RandomTests/st201504042052JS"}
declare_test!{StateTests_RandomTests_st201504042226CPPJIT, "StateTests/RandomTests/st201504042226CPPJIT"}
declare_test!{StateTests_RandomTests_st201504042355CPPJIT, "StateTests/RandomTests/st201504042355CPPJIT"}
declare_test!{StateTests_RandomTests_st201504050059JS, "StateTests/RandomTests/st201504050059JS"}
declare_test!{StateTests_RandomTests_st201504050733JS, "StateTests/RandomTests/st201504050733JS"}
declare_test!{StateTests_RandomTests_st201504051540JS, "StateTests/RandomTests/st201504051540JS"}
declare_test!{StateTests_RandomTests_st201504051944CPPJIT, "StateTests/RandomTests/st201504051944CPPJIT"}
declare_test!{StateTests_RandomTests_st201504052008CPPJIT, "StateTests/RandomTests/st201504052008CPPJIT"}
declare_test!{StateTests_RandomTests_st201504052014GO, "StateTests/RandomTests/st201504052014GO"}
declare_test!{StateTests_RandomTests_st201504052031CPPJIT, "StateTests/RandomTests/st201504052031CPPJIT"}
declare_test!{StateTests_RandomTests_st201504060057CPPJIT, "StateTests/RandomTests/st201504060057CPPJIT"}
declare_test!{StateTests_RandomTests_st201504060418CPPJIT, "StateTests/RandomTests/st201504060418CPPJIT"}
declare_test!{StateTests_RandomTests_st201504061106CPPJIT, "StateTests/RandomTests/st201504061106CPPJIT"}
declare_test!{StateTests_RandomTests_st201504061134CPPJIT, "StateTests/RandomTests/st201504061134CPPJIT"}
declare_test!{StateTests_RandomTests_st201504062033CPPJIT, "StateTests/RandomTests/st201504062033CPPJIT"}
declare_test!{StateTests_RandomTests_st201504062046CPPJIT, "StateTests/RandomTests/st201504062046CPPJIT"}
declare_test!{StateTests_RandomTests_st201504062314CPPJIT, "StateTests/RandomTests/st201504062314CPPJIT"}
declare_test!{StateTests_RandomTests_st201504070746JS, "StateTests/RandomTests/st201504070746JS"}
declare_test!{StateTests_RandomTests_st201504070816CPPJIT, "StateTests/RandomTests/st201504070816CPPJIT"}
declare_test!{StateTests_RandomTests_st201504070836CPPJIT, "StateTests/RandomTests/st201504070836CPPJIT"}
declare_test!{StateTests_RandomTests_st201504070839CPPJIT, "StateTests/RandomTests/st201504070839CPPJIT"}
declare_test!{StateTests_RandomTests_st201504071041CPPJIT, "StateTests/RandomTests/st201504071041CPPJIT"}
declare_test!{StateTests_RandomTests_st201504071056CPPJIT, "StateTests/RandomTests/st201504071056CPPJIT"}
declare_test!{StateTests_RandomTests_st201504071621CPPJIT, "StateTests/RandomTests/st201504071621CPPJIT"}
declare_test!{StateTests_RandomTests_st201504071653CPPJIT, "StateTests/RandomTests/st201504071653CPPJIT"}
declare_test!{StateTests_RandomTests_st201504071750CPPJIT, "StateTests/RandomTests/st201504071750CPPJIT"}
declare_test!{StateTests_RandomTests_st201504071905CPPJIT, "StateTests/RandomTests/st201504071905CPPJIT"}
declare_test!{StateTests_RandomTests_st201504080454CPPJIT, "StateTests/RandomTests/st201504080454CPPJIT"}
declare_test!{StateTests_RandomTests_st201504080457CPPJIT, "StateTests/RandomTests/st201504080457CPPJIT"}
declare_test!{StateTests_RandomTests_st201504080650CPPJIT, "StateTests/RandomTests/st201504080650CPPJIT"}
declare_test!{StateTests_RandomTests_st201504080840CPPJIT, "StateTests/RandomTests/st201504080840CPPJIT"}
declare_test!{StateTests_RandomTests_st201504080948CPPJIT, "StateTests/RandomTests/st201504080948CPPJIT"}
declare_test!{StateTests_RandomTests_st201504081100CPPJIT, "StateTests/RandomTests/st201504081100CPPJIT"}
declare_test!{StateTests_RandomTests_st201504081134CPPJIT, "StateTests/RandomTests/st201504081134CPPJIT"}
declare_test!{StateTests_RandomTests_st201504081138CPPJIT, "StateTests/RandomTests/st201504081138CPPJIT"}
declare_test!{StateTests_RandomTests_st201504081611CPPJIT, "StateTests/RandomTests/st201504081611CPPJIT"}
declare_test!{StateTests_RandomTests_st201504081841JAVA, "StateTests/RandomTests/st201504081841JAVA"}
declare_test!{StateTests_RandomTests_st201504081842JAVA, "StateTests/RandomTests/st201504081842JAVA"}
declare_test!{StateTests_RandomTests_st201504081843JAVA, "StateTests/RandomTests/st201504081843JAVA"}
declare_test!{StateTests_RandomTests_st201504081928CPPJIT, "StateTests/RandomTests/st201504081928CPPJIT"}
declare_test!{StateTests_RandomTests_st201504081953JAVA, "StateTests/RandomTests/st201504081953JAVA"}
declare_test!{StateTests_RandomTests_st201504081954JAVA, "StateTests/RandomTests/st201504081954JAVA"}
declare_test!{StateTests_RandomTests_st201504081955JAVA, "StateTests/RandomTests/st201504081955JAVA"}
declare_test!{StateTests_RandomTests_st201504081956JAVA, "StateTests/RandomTests/st201504081956JAVA"}
declare_test!{StateTests_RandomTests_st201504081957JAVA, "StateTests/RandomTests/st201504081957JAVA"}
declare_test!{StateTests_RandomTests_st201504082000JAVA, "StateTests/RandomTests/st201504082000JAVA"}
declare_test!{StateTests_RandomTests_st201504082001JAVA, "StateTests/RandomTests/st201504082001JAVA"}
declare_test!{StateTests_RandomTests_st201504082002JAVA, "StateTests/RandomTests/st201504082002JAVA"}
declare_test!{StateTests_RandomTests_st201504090553CPPJIT, "StateTests/RandomTests/st201504090553CPPJIT"}
declare_test!{StateTests_RandomTests_st201504090657CPPJIT, "StateTests/RandomTests/st201504090657CPPJIT"}
declare_test!{StateTests_RandomTests_st201504091403CPPJIT, "StateTests/RandomTests/st201504091403CPPJIT"}
declare_test!{StateTests_RandomTests_st201504091641CPPJIT, "StateTests/RandomTests/st201504091641CPPJIT"}
declare_test!{StateTests_RandomTests_st201504092303CPPJIT, "StateTests/RandomTests/st201504092303CPPJIT"}
declare_test!{StateTests_RandomTests_st201504100125CPPJIT, "StateTests/RandomTests/st201504100125CPPJIT"}
declare_test!{StateTests_RandomTests_st201504100215CPPJIT, "StateTests/RandomTests/st201504100215CPPJIT"}
declare_test!{StateTests_RandomTests_st201504100226PYTHON, "StateTests/RandomTests/st201504100226PYTHON"}
declare_test!{StateTests_RandomTests_st201504100308CPPJIT, "StateTests/RandomTests/st201504100308CPPJIT"}
declare_test!{StateTests_RandomTests_st201504100337CPPJIT, "StateTests/RandomTests/st201504100337CPPJIT"}
declare_test!{StateTests_RandomTests_st201504100341CPPJIT, "StateTests/RandomTests/st201504100341CPPJIT"}
declare_test!{StateTests_RandomTests_st201504101009CPPJIT, "StateTests/RandomTests/st201504101009CPPJIT"}
declare_test!{StateTests_RandomTests_st201504101150CPPJIT, "StateTests/RandomTests/st201504101150CPPJIT"}
declare_test!{StateTests_RandomTests_st201504101223CPPJIT, "StateTests/RandomTests/st201504101223CPPJIT"}
declare_test!{StateTests_RandomTests_st201504101338CPPJIT, "StateTests/RandomTests/st201504101338CPPJIT"}
declare_test!{StateTests_RandomTests_st201504101754PYTHON, "StateTests/RandomTests/st201504101754PYTHON"}
declare_test!{StateTests_RandomTests_st201504111554CPPJIT, "StateTests/RandomTests/st201504111554CPPJIT"}
declare_test!{StateTests_RandomTests_st201504130653JS, "StateTests/RandomTests/st201504130653JS"}
declare_test!{StateTests_RandomTests_st201504131821CPPJIT, "StateTests/RandomTests/st201504131821CPPJIT"}
declare_test!{StateTests_RandomTests_st201504140229CPPJIT, "StateTests/RandomTests/st201504140229CPPJIT"}
declare_test!{StateTests_RandomTests_st201504140236CPPJIT, "StateTests/RandomTests/st201504140236CPPJIT"}
declare_test!{StateTests_RandomTests_st201504140359CPPJIT, "StateTests/RandomTests/st201504140359CPPJIT"}
declare_test!{StateTests_RandomTests_st201504140750CPPJIT, "StateTests/RandomTests/st201504140750CPPJIT"}
declare_test!{StateTests_RandomTests_st201504140818CPPJIT, "StateTests/RandomTests/st201504140818CPPJIT"}
declare_test!{StateTests_RandomTests_st201504140900CPPJIT, "StateTests/RandomTests/st201504140900CPPJIT"}
declare_test!{StateTests_RandomTests_st201504150854CPPJIT, "StateTests/RandomTests/st201504150854CPPJIT"}
declare_test!{StateTests_RandomTests_st201504151057CPPJIT, "StateTests/RandomTests/st201504151057CPPJIT"}
declare_test!{StateTests_RandomTests_st201504202124CPPJIT, "StateTests/RandomTests/st201504202124CPPJIT"}
declare_test!{StateTests_RandomTests_st201504210245CPPJIT, "StateTests/RandomTests/st201504210245CPPJIT"}
declare_test!{StateTests_RandomTests_st201504210957CPPJIT, "StateTests/RandomTests/st201504210957CPPJIT"}
declare_test!{StateTests_RandomTests_st201504211739CPPJIT, "StateTests/RandomTests/st201504211739CPPJIT"}
declare_test!{StateTests_RandomTests_st201504212038CPPJIT, "StateTests/RandomTests/st201504212038CPPJIT"}
declare_test!{StateTests_RandomTests_st201504230729CPPJIT, "StateTests/RandomTests/st201504230729CPPJIT"}
declare_test!{StateTests_RandomTests_st201504231639CPPJIT, "StateTests/RandomTests/st201504231639CPPJIT"}
declare_test!{StateTests_RandomTests_st201504231710CPPJIT, "StateTests/RandomTests/st201504231710CPPJIT"}
declare_test!{StateTests_RandomTests_st201504231742CPPJIT, "StateTests/RandomTests/st201504231742CPPJIT"}
declare_test!{StateTests_RandomTests_st201504232350CPPJIT, "StateTests/RandomTests/st201504232350CPPJIT"}
declare_test!{StateTests_RandomTests_st201504240140CPPJIT, "StateTests/RandomTests/st201504240140CPPJIT"}
declare_test!{StateTests_RandomTests_st201504240220CPPJIT, "StateTests/RandomTests/st201504240220CPPJIT"}
declare_test!{StateTests_RandomTests_st201504240351CPPJIT, "StateTests/RandomTests/st201504240351CPPJIT"}
declare_test!{StateTests_RandomTests_st201504240817CPPJIT, "StateTests/RandomTests/st201504240817CPPJIT"}
declare_test!{StateTests_RandomTests_st201504241118CPPJIT, "StateTests/RandomTests/st201504241118CPPJIT"}
declare_test!{StateTests_RandomTests_st201505021810CPPJIT, "StateTests/RandomTests/st201505021810CPPJIT"}
declare_test!{StateTests_RandomTests_st201505050557JS, "StateTests/RandomTests/st201505050557JS"}
declare_test!{StateTests_RandomTests_st201505050929GO, "StateTests/RandomTests/st201505050929GO"}
declare_test!{StateTests_RandomTests_st201505050942PYTHON, "StateTests/RandomTests/st201505050942PYTHON"}
declare_test!{StateTests_RandomTests_st201505051004PYTHON, "StateTests/RandomTests/st201505051004PYTHON"}
declare_test!{StateTests_RandomTests_st201505051016PYTHON, "StateTests/RandomTests/st201505051016PYTHON"}
declare_test!{StateTests_RandomTests_st201505051114GO, "StateTests/RandomTests/st201505051114GO"}
declare_test!{StateTests_RandomTests_st201505051238GO, "StateTests/RandomTests/st201505051238GO"}
declare_test!{StateTests_RandomTests_st201505051249GO, "StateTests/RandomTests/st201505051249GO"}
declare_test!{StateTests_RandomTests_st201505051558PYTHON, "StateTests/RandomTests/st201505051558PYTHON"}
declare_test!{StateTests_RandomTests_st201505051611PYTHON, "StateTests/RandomTests/st201505051611PYTHON"}
declare_test!{StateTests_RandomTests_st201505051648JS, "StateTests/RandomTests/st201505051648JS"}
declare_test!{StateTests_RandomTests_st201505051710GO, "StateTests/RandomTests/st201505051710GO"}
declare_test!{StateTests_RandomTests_st201505052013GO, "StateTests/RandomTests/st201505052013GO"}
declare_test!{StateTests_RandomTests_st201505052102JS, "StateTests/RandomTests/st201505052102JS"}
declare_test!{StateTests_RandomTests_st201505052235GO, "StateTests/RandomTests/st201505052235GO"}
declare_test!{StateTests_RandomTests_st201505052238JS, "StateTests/RandomTests/st201505052238JS"}
declare_test!{StateTests_RandomTests_st201505052242PYTHON, "StateTests/RandomTests/st201505052242PYTHON"}
declare_test!{StateTests_RandomTests_st201505052343PYTHON, "StateTests/RandomTests/st201505052343PYTHON"}
declare_test!{StateTests_RandomTests_st201505060120GO, "StateTests/RandomTests/st201505060120GO"}
declare_test!{StateTests_RandomTests_st201505060121GO, "StateTests/RandomTests/st201505060121GO"}
declare_test!{StateTests_RandomTests_st201505060136PYTHON, "StateTests/RandomTests/st201505060136PYTHON"}
declare_test!{StateTests_RandomTests_st201505060646JS, "StateTests/RandomTests/st201505060646JS"}
declare_test!{StateTests_RandomTests_st201505252314CPPJIT, "StateTests/RandomTests/st201505252314CPPJIT"}
declare_test!{StateTests_RandomTests_st201505272131CPPJIT, "StateTests/RandomTests/st201505272131CPPJIT"}
declare_test!{StateTests_RandomTests_st201506040034GO, "StateTests/RandomTests/st201506040034GO"}
declare_test!{StateTests_RandomTests_st201506040157GO, "StateTests/RandomTests/st201506040157GO"}
declare_test!{StateTests_RandomTests_st201506052130GO, "StateTests/RandomTests/st201506052130GO"}
declare_test!{StateTests_RandomTests_st201506060929GO, "StateTests/RandomTests/st201506060929GO"}
declare_test!{StateTests_RandomTests_st201506061255GO, "StateTests/RandomTests/st201506061255GO"}
declare_test!{StateTests_RandomTests_st201506062331GO, "StateTests/RandomTests/st201506062331GO"}
declare_test!{StateTests_RandomTests_st201506070548GO, "StateTests/RandomTests/st201506070548GO"}
declare_test!{StateTests_RandomTests_st201506071050GO, "StateTests/RandomTests/st201506071050GO"}
declare_test!{StateTests_RandomTests_st201506071624GO, "StateTests/RandomTests/st201506071624GO"}
declare_test!{StateTests_RandomTests_st201506071819GO, "StateTests/RandomTests/st201506071819GO"}
declare_test!{StateTests_RandomTests_st201506072007GO, "StateTests/RandomTests/st201506072007GO"}
declare_test!{StateTests_RandomTests_st201506080556GO, "StateTests/RandomTests/st201506080556GO"}
declare_test!{StateTests_RandomTests_st201506080721GO, "StateTests/RandomTests/st201506080721GO"}
declare_test!{StateTests_RandomTests_st201506091836GO, "StateTests/RandomTests/st201506091836GO"}
declare_test!{StateTests_RandomTests_st201506092032GO, "StateTests/RandomTests/st201506092032GO"}
declare_test!{StateTests_RandomTests_st201506101359JS, "StateTests/RandomTests/st201506101359JS"}
declare_test!{StateTests_RandomTests_st201507030359GO, "StateTests/RandomTests/st201507030359GO"}
} }

View File

@ -15,21 +15,63 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
pub use util::*; pub use util::*;
use std::fs::{File, read_dir};
use std::path::Path;
use std::ffi::OsString;
pub fn run_test_path(p: &Path, skip: &[&'static str], runner: fn (json_data: &[u8]) -> Vec<String>) {
let path = Path::new(p);
let s: HashSet<OsString> = skip.iter().map(|s| {
let mut os: OsString = s.into();
os.push(".json");
os
}).collect();
if path.is_dir() {
for p in read_dir(path).unwrap().filter_map(|e| {
let e = e.unwrap();
if s.contains(&e.file_name()) {
None
} else {
Some(e.path())
}}) {
run_test_path(&p, skip, runner)
}
} else {
let mut path = p.to_path_buf();
path.set_extension("json");
run_test_file(&path, runner)
}
}
pub fn run_test_file(path: &Path, runner: fn (json_data: &[u8]) -> Vec<String>) {
let mut data = Vec::new();
let mut file = File::open(&path).expect("Error opening test file");
file.read_to_end(&mut data).expect("Error reading test file");
let results = runner(&data);
assert!(results.is_empty());
}
macro_rules! test { macro_rules! test {
($name: expr) => { ($name: expr, $skip: expr) => {
assert!(do_json_test(include_bytes!(concat!("../../res/ethereum/tests/", $name, ".json"))).is_empty()); ::json_tests::test_common::run_test_path(::std::path::Path::new(concat!("res/ethereum/tests/", $name)), &$skip, do_json_test);
} }
} }
#[macro_export] #[macro_export]
macro_rules! declare_test { macro_rules! declare_test {
(skip => $arr: expr, $id: ident, $name: expr) => {
#[test]
#[allow(non_snake_case)]
fn $id() {
test!($name, $arr);
}
};
(ignore => $id: ident, $name: expr) => { (ignore => $id: ident, $name: expr) => {
#[ignore] #[ignore]
#[test] #[test]
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn $id() { fn $id() {
test!($name); test!($name, []);
} }
}; };
(heavy => $id: ident, $name: expr) => { (heavy => $id: ident, $name: expr) => {
@ -37,14 +79,14 @@ macro_rules! declare_test {
#[test] #[test]
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn $id() { fn $id() {
test!($name); test!($name, []);
} }
}; };
($id: ident, $name: expr) => { ($id: ident, $name: expr) => {
#[test] #[test]
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn $id() { fn $id() {
test!($name); test!($name, []);
} }
} }
} }

View File

@ -18,35 +18,37 @@ use super::test_common::*;
use evm; use evm;
use ethjson; use ethjson;
use rlp::UntrustedRlp; use rlp::UntrustedRlp;
use transaction::{Action, UnverifiedTransaction}; use transaction::{Action, UnverifiedTransaction, SignedTransaction};
use ethstore::ethkey::public_to_address;
fn do_json_test(json_data: &[u8]) -> Vec<String> { fn do_json_test(json_data: &[u8]) -> Vec<String> {
let tests = ethjson::transaction::Test::load(json_data).unwrap(); let tests = ethjson::transaction::Test::load(json_data).unwrap();
let mut failed = Vec::new(); let mut failed = Vec::new();
let old_schedule = evm::Schedule::new_frontier(); let frontier_schedule = evm::Schedule::new_frontier();
let new_schedule = evm::Schedule::new_homestead(); let homestead_schedule = evm::Schedule::new_homestead();
let metropolis_schedule = evm::Schedule::new_metropolis();
for (name, test) in tests.into_iter() { for (name, test) in tests.into_iter() {
let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); }; let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); };
let number: Option<u64> = test.block_number.map(Into::into); let number: Option<u64> = test.block_number.map(Into::into);
let schedule = match number { let schedule = match number {
None => &old_schedule, None => &frontier_schedule,
Some(x) if x < 1_150_000 => &old_schedule, Some(x) if x < 1_150_000 => &frontier_schedule,
Some(_) => &new_schedule Some(x) if x < 3_000_000 => &homestead_schedule,
Some(_) => &metropolis_schedule
}; };
let allow_network_id_of_one = number.map_or(false, |n| n >= 2_675_000); let allow_network_id_of_one = number.map_or(false, |n| n >= 2_675_000);
let allow_unsigned = number.map_or(false, |n| n >= 3_000_000);
let rlp: Vec<u8> = test.rlp.into(); let rlp: Vec<u8> = test.rlp.into();
let res = UntrustedRlp::new(&rlp) let res = UntrustedRlp::new(&rlp)
.as_val() .as_val()
.map_err(From::from) .map_err(From::from)
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one)); .and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one, allow_unsigned));
fail_unless(test.transaction.is_none() == res.is_err(), "Validity different"); fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) { if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
let t = res.unwrap(); let t = res.unwrap();
fail_unless(public_to_address(&t.recover_public().unwrap()) == sender.into(), "sender mismatch"); fail_unless(SignedTransaction::new(t.clone()).unwrap().sender() == sender.into(), "sender mismatch");
let is_acceptable_network_id = match t.network_id() { let is_acceptable_network_id = match t.network_id() {
None => true, None => true,
Some(1) if allow_network_id_of_one => true, Some(1) if allow_network_id_of_one => true,
@ -84,3 +86,7 @@ declare_test!{TransactionTests_Homestead_ttTransactionTestEip155VitaliksTests, "
declare_test!{TransactionTests_EIP155_ttTransactionTest, "TransactionTests/EIP155/ttTransactionTest"} declare_test!{TransactionTests_EIP155_ttTransactionTest, "TransactionTests/EIP155/ttTransactionTest"}
declare_test!{TransactionTests_EIP155_ttTransactionTestEip155VitaliksTests, "TransactionTests/EIP155/ttTransactionTestEip155VitaliksTests"} declare_test!{TransactionTests_EIP155_ttTransactionTestEip155VitaliksTests, "TransactionTests/EIP155/ttTransactionTestEip155VitaliksTests"}
declare_test!{TransactionTests_EIP155_ttTransactionTestVRule, "TransactionTests/EIP155/ttTransactionTestVRule"} declare_test!{TransactionTests_EIP155_ttTransactionTestVRule, "TransactionTests/EIP155/ttTransactionTestVRule"}
declare_test!{TransactionTests_Metropolis_ttMetropolisTest, "TransactionTests/Metropolis/ttMetropolisTest"}
declare_test!{TransactionTests_Metropolis_ttTransactionTest, "TransactionTests/Metropolis/ttTransactionTest"}
declare_test!{TransactionTests_Metropolis_ttTransactionTestZeroSig, "TransactionTests/Metropolis/ttTransactionTestZeroSig"}

View File

@ -170,3 +170,4 @@ mod json_tests;
pub use types::*; pub use types::*;
pub use executive::contract_address; pub use executive::contract_address;
pub use evm::CreateContractAddress;

View File

@ -1048,7 +1048,7 @@ impl MinerService for Miner {
Action::Call(_) => None, Action::Call(_) => None,
Action::Create => { Action::Create => {
let sender = tx.sender(); let sender = tx.sender();
Some(contract_address(&sender, &tx.nonce)) Some(contract_address(self.engine.schedule(pending.header().number()).create_address, &sender, &tx.nonce, &tx.data.sha3()))
} }
}, },
logs: receipt.logs.clone(), logs: receipt.logs.clone(),
@ -1327,6 +1327,10 @@ mod tests {
} }
fn transaction() -> SignedTransaction { fn transaction() -> SignedTransaction {
transaction_with_network_id(2)
}
fn transaction_with_network_id(id: u64) -> SignedTransaction {
let keypair = Random.generate().unwrap(); let keypair = Random.generate().unwrap();
Transaction { Transaction {
action: Action::Create, action: Action::Create,
@ -1335,7 +1339,7 @@ mod tests {
gas: U256::from(100_000), gas: U256::from(100_000),
gas_price: U256::zero(), gas_price: U256::zero(),
nonce: U256::zero(), nonce: U256::zero(),
}.sign(keypair.secret(), None) }.sign(keypair.secret(), Some(id))
} }
#[test] #[test]
@ -1411,21 +1415,21 @@ mod tests {
#[test] #[test]
fn internal_seals_without_work() { fn internal_seals_without_work() {
let miner = Miner::with_spec(&Spec::new_instant()); let spec = Spec::new_instant();
let miner = Miner::with_spec(&spec);
let c = generate_dummy_client(2); let client = generate_dummy_client(2);
let client = c.reference().as_ref();
assert_eq!(miner.import_external_transactions(client, vec![transaction().into()]).pop().unwrap().unwrap(), TransactionImportResult::Current); assert_eq!(miner.import_external_transactions(&*client, vec![transaction_with_network_id(spec.network_id()).into()]).pop().unwrap().unwrap(), TransactionImportResult::Current);
miner.update_sealing(client); miner.update_sealing(&*client);
client.flush_queue(); client.flush_queue();
assert!(miner.pending_block().is_none()); assert!(miner.pending_block().is_none());
assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber); assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber);
assert_eq!(miner.import_own_transaction(client, PendingTransaction::new(transaction().into(), None)).unwrap(), TransactionImportResult::Current); assert_eq!(miner.import_own_transaction(&*client, PendingTransaction::new(transaction_with_network_id(spec.network_id()).into(), None)).unwrap(), TransactionImportResult::Current);
miner.update_sealing(client); miner.update_sealing(&*client);
client.flush_queue(); client.flush_queue();
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);

View File

@ -57,6 +57,8 @@ pub struct CommonParams {
pub eip98_transition: BlockNumber, pub eip98_transition: BlockNumber,
/// Validate block receipts root. /// Validate block receipts root.
pub validate_receipts_transition: u64, pub validate_receipts_transition: u64,
/// Number of first block where EIP-86 (Metropolis) rules begin.
pub eip86_transition: BlockNumber,
} }
impl From<ethjson::spec::Params> for CommonParams { impl From<ethjson::spec::Params> for CommonParams {
@ -71,6 +73,7 @@ impl From<ethjson::spec::Params> for CommonParams {
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None }, fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
eip98_transition: p.eip98_transition.map_or(0, Into::into), eip98_transition: p.eip98_transition.map_or(0, Into::into),
validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into),
eip86_transition: p.eip86_transition.map_or(BlockNumber::max_value(), Into::into),
} }
} }
} }
@ -306,6 +309,7 @@ impl Spec {
call_type: CallType::None, call_type: CallType::None,
}; };
let mut substate = Substate::new(); let mut substate = Substate::new();
state.kill_account(address);
{ {
let mut exec = Executive::new(&mut state, &env_info, self.engine.as_ref(), &factories.vm); let mut exec = Executive::new(&mut state, &env_info, self.engine.as_ref(), &factories.vm);
if let Err(e) = exec.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) { if let Err(e) = exec.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) {
@ -391,9 +395,9 @@ mod tests {
#[test] #[test]
fn genesis_constructor() { fn genesis_constructor() {
::ethcore_logger::init_log();
let spec = Spec::new_test_constructor(); let spec = Spec::new_test_constructor();
let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let state = State::from_existing(db.boxed_clone(), spec.state_root(), spec.engine.account_start_nonce(), Default::default()).unwrap(); let state = State::from_existing(db.boxed_clone(), spec.state_root(), spec.engine.account_start_nonce(), Default::default()).unwrap();
let expected = H256::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap(); let expected = H256::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap();
assert_eq!(state.storage_at(&Address::from_str("0000000000000000000000000000000000000005").unwrap(), &H256::zero()).unwrap(), expected); assert_eq!(state.storage_at(&Address::from_str("0000000000000000000000000000000000000005").unwrap(), &H256::zero()).unwrap(), expected);

View File

@ -939,7 +939,6 @@ 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 devtools::*;
use env_info::EnvInfo; use env_info::EnvInfo;
use spec::*; use spec::*;
use transaction::*; use transaction::*;
@ -955,8 +954,7 @@ mod tests {
fn should_apply_create_transaction() { fn should_apply_create_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -998,9 +996,8 @@ mod tests {
let a = Address::zero(); let a = Address::zero();
let temp = RandomTempPath::new();
let mut state = { let mut state = {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state();
assert_eq!(state.exists(&a).unwrap(), false); assert_eq!(state.exists(&a).unwrap(), false);
state.inc_nonce(&a).unwrap(); state.inc_nonce(&a).unwrap();
state.commit().unwrap(); state.commit().unwrap();
@ -1015,8 +1012,7 @@ mod tests {
fn should_trace_failed_create_transaction() { fn should_trace_failed_create_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1052,8 +1048,7 @@ mod tests {
fn should_trace_call_transaction() { fn should_trace_call_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1095,8 +1090,7 @@ mod tests {
fn should_trace_basic_call_transaction() { fn should_trace_basic_call_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1137,8 +1131,7 @@ mod tests {
fn should_trace_call_transaction_to_builtin() { fn should_trace_call_transaction_to_builtin() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1179,8 +1172,7 @@ mod tests {
fn should_not_trace_subcall_transaction_to_builtin() { fn should_not_trace_subcall_transaction_to_builtin() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1222,8 +1214,7 @@ mod tests {
fn should_not_trace_callcode() { fn should_not_trace_callcode() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1281,15 +1272,14 @@ mod tests {
fn should_not_trace_delegatecall() { fn should_not_trace_delegatecall() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
info.number = 0x789b0; info.number = 0x789b0;
let engine = &*Spec::new_test().engine; let engine = &*Spec::new_test().engine;
println!("schedule.have_delegate_call: {:?}", engine.schedule(&info).have_delegate_call); println!("schedule.have_delegate_call: {:?}", engine.schedule(info.number).have_delegate_call);
let t = Transaction { let t = Transaction {
nonce: 0.into(), nonce: 0.into(),
@ -1343,8 +1333,7 @@ mod tests {
fn should_trace_failed_call_transaction() { fn should_trace_failed_call_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1383,8 +1372,7 @@ mod tests {
fn should_trace_call_with_subcall_transaction() { fn should_trace_call_with_subcall_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1443,8 +1431,7 @@ mod tests {
fn should_trace_call_with_basic_subcall_transaction() { fn should_trace_call_with_basic_subcall_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1498,8 +1485,7 @@ mod tests {
fn should_not_trace_call_with_invalid_basic_subcall_transaction() { fn should_not_trace_call_with_invalid_basic_subcall_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1541,8 +1527,7 @@ mod tests {
fn should_trace_failed_subcall_transaction() { fn should_trace_failed_subcall_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1597,8 +1582,7 @@ mod tests {
fn should_trace_call_with_subcall_with_subcall_transaction() { fn should_trace_call_with_subcall_with_subcall_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1672,8 +1656,7 @@ mod tests {
fn should_trace_failed_subcall_with_subcall_transaction() { fn should_trace_failed_subcall_with_subcall_transaction() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1745,8 +1728,7 @@ mod tests {
fn should_trace_suicide() { fn should_trace_suicide() {
init_log(); init_log();
let temp = RandomTempPath::new(); let mut state = get_temp_state();
let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into(); info.gas_limit = 1_000_000.into();
@ -1797,9 +1779,8 @@ mod tests {
#[test] #[test]
fn code_from_database() { fn code_from_database() {
let a = Address::zero(); let a = Address::zero();
let temp = RandomTempPath::new();
let (root, db) = { let (root, db) = {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state();
state.require_or_from(&a, false, ||Account::new_contract(42.into(), 0.into()), |_|{}).unwrap(); state.require_or_from(&a, false, ||Account::new_contract(42.into(), 0.into()), |_|{}).unwrap();
state.init_code(&a, vec![1, 2, 3]).unwrap(); state.init_code(&a, vec![1, 2, 3]).unwrap();
assert_eq!(state.code(&a).unwrap(), Some(Arc::new([1u8, 2, 3].to_vec()))); assert_eq!(state.code(&a).unwrap(), Some(Arc::new([1u8, 2, 3].to_vec())));
@ -1815,9 +1796,8 @@ mod tests {
#[test] #[test]
fn storage_at_from_database() { fn storage_at_from_database() {
let a = Address::zero(); let a = Address::zero();
let temp = RandomTempPath::new();
let (root, db) = { let (root, db) = {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state();
state.set_storage(&a, H256::from(&U256::from(1u64)), H256::from(&U256::from(69u64))).unwrap(); state.set_storage(&a, H256::from(&U256::from(1u64)), H256::from(&U256::from(69u64))).unwrap();
state.commit().unwrap(); state.commit().unwrap();
state.drop() state.drop()
@ -1830,9 +1810,8 @@ mod tests {
#[test] #[test]
fn get_from_database() { fn get_from_database() {
let a = Address::zero(); let a = Address::zero();
let temp = RandomTempPath::new();
let (root, db) = { let (root, db) = {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state();
state.inc_nonce(&a).unwrap(); state.inc_nonce(&a).unwrap();
state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap(); state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap();
state.commit().unwrap(); state.commit().unwrap();
@ -1848,8 +1827,7 @@ mod tests {
#[test] #[test]
fn remove() { fn remove() {
let a = Address::zero(); let a = Address::zero();
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
assert_eq!(state.exists(&a).unwrap(), false); assert_eq!(state.exists(&a).unwrap(), false);
assert_eq!(state.exists_and_not_null(&a).unwrap(), false); assert_eq!(state.exists_and_not_null(&a).unwrap(), false);
state.inc_nonce(&a).unwrap(); state.inc_nonce(&a).unwrap();
@ -1865,8 +1843,7 @@ mod tests {
#[test] #[test]
fn empty_account_is_not_created() { fn empty_account_is_not_created() {
let a = Address::zero(); let a = Address::zero();
let path = RandomTempPath::new(); let db = get_temp_state_db();
let db = get_temp_state_db_in(path.as_path());
let (root, db) = { let (root, db) = {
let mut state = State::new(db, U256::from(0), Default::default()); let mut state = State::new(db, U256::from(0), Default::default());
state.add_balance(&a, &U256::default(), CleanupMode::NoEmpty).unwrap(); // create an empty account state.add_balance(&a, &U256::default(), CleanupMode::NoEmpty).unwrap(); // create an empty account
@ -1881,8 +1858,7 @@ mod tests {
#[test] #[test]
fn empty_account_exists_when_creation_forced() { fn empty_account_exists_when_creation_forced() {
let a = Address::zero(); let a = Address::zero();
let path = RandomTempPath::new(); let db = get_temp_state_db();
let db = get_temp_state_db_in(path.as_path());
let (root, db) = { let (root, db) = {
let mut state = State::new(db, U256::from(0), Default::default()); let mut state = State::new(db, U256::from(0), Default::default());
state.add_balance(&a, &U256::default(), CleanupMode::ForceCreate).unwrap(); // create an empty account state.add_balance(&a, &U256::default(), CleanupMode::ForceCreate).unwrap(); // create an empty account
@ -1897,9 +1873,8 @@ mod tests {
#[test] #[test]
fn remove_from_database() { fn remove_from_database() {
let a = Address::zero(); let a = Address::zero();
let temp = RandomTempPath::new();
let (root, db) = { let (root, db) = {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state();
state.inc_nonce(&a).unwrap(); state.inc_nonce(&a).unwrap();
state.commit().unwrap(); state.commit().unwrap();
assert_eq!(state.exists(&a).unwrap(), true); assert_eq!(state.exists(&a).unwrap(), true);
@ -1925,8 +1900,7 @@ mod tests {
#[test] #[test]
fn alter_balance() { fn alter_balance() {
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero(); let a = Address::zero();
let b = 1u64.into(); let b = 1u64.into();
state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap(); state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap();
@ -1947,8 +1921,7 @@ mod tests {
#[test] #[test]
fn alter_nonce() { fn alter_nonce() {
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero(); let a = Address::zero();
state.inc_nonce(&a).unwrap(); state.inc_nonce(&a).unwrap();
assert_eq!(state.nonce(&a).unwrap(), U256::from(1u64)); assert_eq!(state.nonce(&a).unwrap(), U256::from(1u64));
@ -1964,8 +1937,7 @@ mod tests {
#[test] #[test]
fn balance_nonce() { fn balance_nonce() {
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero(); let a = Address::zero();
assert_eq!(state.balance(&a).unwrap(), U256::from(0u64)); assert_eq!(state.balance(&a).unwrap(), U256::from(0u64));
assert_eq!(state.nonce(&a).unwrap(), U256::from(0u64)); assert_eq!(state.nonce(&a).unwrap(), U256::from(0u64));
@ -1976,8 +1948,7 @@ mod tests {
#[test] #[test]
fn ensure_cached() { fn ensure_cached() {
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero(); let a = Address::zero();
state.require(&a, false).unwrap(); state.require(&a, false).unwrap();
state.commit().unwrap(); state.commit().unwrap();
@ -1986,8 +1957,7 @@ mod tests {
#[test] #[test]
fn checkpoint_basic() { fn checkpoint_basic() {
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero(); let a = Address::zero();
state.checkpoint(); state.checkpoint();
state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap(); state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap();
@ -2003,8 +1973,7 @@ mod tests {
#[test] #[test]
fn checkpoint_nested() { fn checkpoint_nested() {
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero(); let a = Address::zero();
state.checkpoint(); state.checkpoint();
state.checkpoint(); state.checkpoint();
@ -2018,16 +1987,14 @@ mod tests {
#[test] #[test]
fn create_empty() { fn create_empty() {
let mut state_result = get_temp_state(); let mut state = get_temp_state();
let mut state = state_result.reference_mut();
state.commit().unwrap(); state.commit().unwrap();
assert_eq!(state.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); assert_eq!(state.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
} }
#[test] #[test]
fn should_not_panic_on_state_diff_with_storage() { fn should_not_panic_on_state_diff_with_storage() {
let state = get_temp_state(); let mut state = get_temp_state();
let mut state = state.reference().clone();
let a: Address = 0xa.into(); let a: Address = 0xa.into();
state.init_code(&a, b"abcdefg".to_vec()).unwrap();; state.init_code(&a, b"abcdefg".to_vec()).unwrap();;

View File

@ -463,8 +463,7 @@ mod tests {
fn state_db_smoke() { fn state_db_smoke() {
init_log(); init_log();
let mut state_db_result = get_temp_state_db(); let state_db = get_temp_state_db();
let state_db = state_db_result.take();
let root_parent = H256::random(); let root_parent = H256::random();
let address = Address::random(); let address = Address::random();
let h0 = H256::random(); let h0 = H256::random();

View File

@ -72,8 +72,7 @@ fn should_return_registrar() {
#[test] #[test]
fn returns_state_root_basic() { fn returns_state_root_basic() {
let client_result = generate_dummy_client(6); let client = generate_dummy_client(6);
let client = client_result.reference();
let test_spec = get_test_spec(); let test_spec = get_test_spec();
let genesis_header = test_spec.genesis_header(); let genesis_header = test_spec.genesis_header();
@ -125,8 +124,7 @@ fn query_none_block() {
#[test] #[test]
fn query_bad_block() { fn query_bad_block() {
let client_result = get_test_client_with_blocks(vec![get_bad_state_dummy_block()]); let client = get_test_client_with_blocks(vec![get_bad_state_dummy_block()]);
let client = client_result.reference();
let bad_block: Option<_> = client.block_header(BlockId::Number(1)); let bad_block: Option<_> = client.block_header(BlockId::Number(1));
assert!(bad_block.is_none()); assert!(bad_block.is_none());
@ -135,8 +133,7 @@ fn query_bad_block() {
#[test] #[test]
fn returns_chain_info() { fn returns_chain_info() {
let dummy_block = get_good_dummy_block(); let dummy_block = get_good_dummy_block();
let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); let client = get_test_client_with_blocks(vec![dummy_block.clone()]);
let client = client_result.reference();
let block = BlockView::new(&dummy_block); let block = BlockView::new(&dummy_block);
let info = client.chain_info(); let info = client.chain_info();
assert_eq!(info.best_block_hash, block.header().hash()); assert_eq!(info.best_block_hash, block.header().hash());
@ -145,8 +142,7 @@ fn returns_chain_info() {
#[test] #[test]
fn returns_logs() { fn returns_logs() {
let dummy_block = get_good_dummy_block(); let dummy_block = get_good_dummy_block();
let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); let client = get_test_client_with_blocks(vec![dummy_block.clone()]);
let client = client_result.reference();
let logs = client.logs(Filter { let logs = client.logs(Filter {
from_block: BlockId::Earliest, from_block: BlockId::Earliest,
to_block: BlockId::Latest, to_block: BlockId::Latest,
@ -160,14 +156,13 @@ fn returns_logs() {
#[test] #[test]
fn returns_logs_with_limit() { fn returns_logs_with_limit() {
let dummy_block = get_good_dummy_block(); let dummy_block = get_good_dummy_block();
let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); let client = get_test_client_with_blocks(vec![dummy_block.clone()]);
let client = client_result.reference();
let logs = client.logs(Filter { let logs = client.logs(Filter {
from_block: BlockId::Earliest, from_block: BlockId::Earliest,
to_block: BlockId::Latest, to_block: BlockId::Latest,
address: None, address: None,
topics: vec![], topics: vec![],
limit: Some(2), limit: None,
}); });
assert_eq!(logs.len(), 0); assert_eq!(logs.len(), 0);
} }
@ -175,8 +170,7 @@ fn returns_logs_with_limit() {
#[test] #[test]
fn returns_block_body() { fn returns_block_body() {
let dummy_block = get_good_dummy_block(); let dummy_block = get_good_dummy_block();
let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); let client = get_test_client_with_blocks(vec![dummy_block.clone()]);
let client = client_result.reference();
let block = BlockView::new(&dummy_block); let block = BlockView::new(&dummy_block);
let body = client.block_body(BlockId::Hash(block.header().hash())).unwrap(); let body = client.block_body(BlockId::Hash(block.header().hash())).unwrap();
let body = body.rlp(); let body = body.rlp();
@ -187,8 +181,7 @@ fn returns_block_body() {
#[test] #[test]
fn imports_block_sequence() { fn imports_block_sequence() {
let client_result = generate_dummy_client(6); let client = generate_dummy_client(6);
let client = client_result.reference();
let block = client.block_header(BlockId::Number(5)).unwrap(); let block = client.block_header(BlockId::Number(5)).unwrap();
assert!(!block.into_inner().is_empty()); assert!(!block.into_inner().is_empty());
@ -196,8 +189,7 @@ fn imports_block_sequence() {
#[test] #[test]
fn can_collect_garbage() { fn can_collect_garbage() {
let client_result = generate_dummy_client(100); let client = generate_dummy_client(100);
let client = client_result.reference();
client.tick(); client.tick();
assert!(client.blockchain_cache_info().blocks < 100 * 1024); assert!(client.blockchain_cache_info().blocks < 100 * 1024);
} }
@ -205,19 +197,16 @@ fn can_collect_garbage() {
#[test] #[test]
fn can_generate_gas_price_median() { fn can_generate_gas_price_median() {
let client_result = generate_dummy_client_with_data(3, 1, slice_into![1, 2, 3]); let client = generate_dummy_client_with_data(3, 1, slice_into![1, 2, 3]);
let client = client_result.reference();
assert_eq!(Some(&U256::from(2)), client.gas_price_corpus(3).median()); assert_eq!(Some(&U256::from(2)), client.gas_price_corpus(3).median());
let client_result = generate_dummy_client_with_data(4, 1, slice_into![1, 4, 3, 2]); let client = generate_dummy_client_with_data(4, 1, slice_into![1, 4, 3, 2]);
let client = client_result.reference();
assert_eq!(Some(&U256::from(3)), client.gas_price_corpus(3).median()); assert_eq!(Some(&U256::from(3)), client.gas_price_corpus(3).median());
} }
#[test] #[test]
fn can_generate_gas_price_histogram() { fn can_generate_gas_price_histogram() {
let client_result = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]); let client = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]);
let client = client_result.reference();
let hist = client.gas_price_corpus(20).histogram(5).unwrap(); let hist = client.gas_price_corpus(20).histogram(5).unwrap();
let correct_hist = ::stats::Histogram { bucket_bounds: vec_into![643, 2294, 3945, 5596, 7247, 8898], counts: vec![4,2,4,6,4] }; let correct_hist = ::stats::Histogram { bucket_bounds: vec_into![643, 2294, 3945, 5596, 7247, 8898], counts: vec![4,2,4,6,4] };
@ -226,32 +215,29 @@ fn can_generate_gas_price_histogram() {
#[test] #[test]
fn empty_gas_price_histogram() { fn empty_gas_price_histogram() {
let client_result = generate_dummy_client_with_data(20, 0, slice_into![]); let client = generate_dummy_client_with_data(20, 0, slice_into![]);
let client = client_result.reference();
assert!(client.gas_price_corpus(20).histogram(5).is_none()); assert!(client.gas_price_corpus(20).histogram(5).is_none());
} }
#[test] #[test]
fn corpus_is_sorted() { fn corpus_is_sorted() {
let client_result = generate_dummy_client_with_data(2, 1, slice_into![U256::from_str("11426908979").unwrap(), U256::from_str("50426908979").unwrap()]); let client = generate_dummy_client_with_data(2, 1, slice_into![U256::from_str("11426908979").unwrap(), U256::from_str("50426908979").unwrap()]);
let client = client_result.reference();
let corpus = client.gas_price_corpus(20); let corpus = client.gas_price_corpus(20);
assert!(corpus[0] < corpus[1]); assert!(corpus[0] < corpus[1]);
} }
#[test] #[test]
fn can_handle_long_fork() { fn can_handle_long_fork() {
let client_result = generate_dummy_client(1200); let client = generate_dummy_client(1200);
let client = client_result.reference();
for _ in 0..20 { for _ in 0..20 {
client.import_verified_blocks(); client.import_verified_blocks();
} }
assert_eq!(1200, client.chain_info().best_block_number); assert_eq!(1200, client.chain_info().best_block_number);
push_blocks_to_client(client, 45, 1201, 800); push_blocks_to_client(&client, 45, 1201, 800);
push_blocks_to_client(client, 49, 1201, 800); push_blocks_to_client(&client, 49, 1201, 800);
push_blocks_to_client(client, 53, 1201, 600); push_blocks_to_client(&client, 53, 1201, 600);
for _ in 0..400 { for _ in 0..400 {
client.import_verified_blocks(); client.import_verified_blocks();
@ -262,8 +248,7 @@ fn can_handle_long_fork() {
#[test] #[test]
fn can_mine() { fn can_mine() {
let dummy_blocks = get_good_dummy_block_seq(2); let dummy_blocks = get_good_dummy_block_seq(2);
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]); let client = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
let client = client_result.reference();
let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).close(); let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).close();
@ -329,14 +314,13 @@ fn does_not_propagate_delayed_transactions() {
value: 0.into(), value: 0.into(),
data: Vec::new(), data: Vec::new(),
}.sign(secret, None), None); }.sign(secret, None), None);
let client_result = generate_dummy_client(1); let client = generate_dummy_client(1);
let client = client_result.reference();
client.miner().import_own_transaction(&**client, tx0).unwrap(); client.miner().import_own_transaction(&*client, tx0).unwrap();
client.miner().import_own_transaction(&**client, tx1).unwrap(); client.miner().import_own_transaction(&*client, tx1).unwrap();
assert_eq!(0, client.ready_transactions().len()); assert_eq!(0, client.ready_transactions().len());
assert_eq!(2, client.miner().pending_transactions().len()); assert_eq!(2, client.miner().pending_transactions().len());
push_blocks_to_client(client, 53, 2, 2); push_blocks_to_client(&client, 53, 2, 2);
client.flush_queue(); client.flush_queue();
assert_eq!(2, client.ready_transactions().len()); assert_eq!(2, client.ready_transactions().len());
assert_eq!(2, client.miner().pending_transactions().len()); assert_eq!(2, client.miner().pending_transactions().len());
@ -346,8 +330,7 @@ fn does_not_propagate_delayed_transactions() {
fn transaction_proof() { fn transaction_proof() {
use ::client::ProvingBlockChainClient; use ::client::ProvingBlockChainClient;
let client_result = generate_dummy_client(0); let client = generate_dummy_client(0);
let client = client_result.reference();
let address = Address::random(); let address = Address::random();
let test_spec = Spec::new_test(); let test_spec = Spec::new_test();
for _ in 0..20 { for _ in 0..20 {

View File

@ -27,10 +27,8 @@ use builtin::Builtin;
use state::*; use state::*;
use evm::Schedule; use evm::Schedule;
use engines::Engine; use engines::Engine;
use env_info::EnvInfo;
use ethereum; use ethereum;
use ethereum::ethash::EthashParams; use ethereum::ethash::EthashParams;
use devtools::*;
use miner::Miner; use miner::Miner;
use header::Header; use header::Header;
use transaction::{Action, Transaction, SignedTransaction}; use transaction::{Action, Transaction, SignedTransaction};
@ -42,7 +40,7 @@ pub enum ChainEra {
Frontier, Frontier,
Homestead, Homestead,
Eip150, Eip150,
Eip161, _Eip161,
TransitionTest, TransitionTest,
} }
@ -73,7 +71,7 @@ impl Engine for TestEngine {
self.engine.builtins() self.engine.builtins()
} }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { fn schedule(&self, _block_number: u64) -> Schedule {
let mut schedule = Schedule::new_frontier(); let mut schedule = Schedule::new_frontier();
schedule.max_depth = self.max_depth; schedule.max_depth = self.max_depth;
schedule schedule
@ -133,28 +131,26 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransa
rlp.out() rlp.out()
} }
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> { pub fn generate_dummy_client(block_number: u32) -> Arc<Client> {
generate_dummy_client_with_spec_and_data(Spec::new_test, block_number, 0, &[]) generate_dummy_client_with_spec_and_data(Spec::new_test, block_number, 0, &[])
} }
pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult<Arc<Client>> { pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc<Client> {
generate_dummy_client_with_spec_and_data(Spec::new_null, block_number, txs_per_block, tx_gas_prices) generate_dummy_client_with_spec_and_data(Spec::new_null, block_number, txs_per_block, tx_gas_prices)
} }
pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult<Arc<Client>> where F: Fn()->Spec { pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc<Client> where F: Fn()->Spec {
generate_dummy_client_with_spec_accounts_and_data(get_test_spec, None, block_number, txs_per_block, tx_gas_prices) generate_dummy_client_with_spec_accounts_and_data(get_test_spec, None, block_number, txs_per_block, tx_gas_prices)
} }
pub fn generate_dummy_client_with_spec_and_accounts<F>(get_test_spec: F, accounts: Option<Arc<AccountProvider>>) -> GuardedTempResult<Arc<Client>> where F: Fn()->Spec { pub fn generate_dummy_client_with_spec_and_accounts<F>(get_test_spec: F, accounts: Option<Arc<AccountProvider>>) -> Arc<Client> where F: Fn()->Spec {
generate_dummy_client_with_spec_accounts_and_data(get_test_spec, accounts, 0, 0, &[]) generate_dummy_client_with_spec_accounts_and_data(get_test_spec, accounts, 0, 0, &[])
} }
pub fn generate_dummy_client_with_spec_accounts_and_data<F>(get_test_spec: F, accounts: Option<Arc<AccountProvider>>, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult<Arc<Client>> where F: Fn()->Spec { pub fn generate_dummy_client_with_spec_accounts_and_data<F>(get_test_spec: F, accounts: Option<Arc<AccountProvider>>, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc<Client> where F: Fn()->Spec {
let dir = RandomTempPath::new();
let test_spec = get_test_spec(); let test_spec = get_test_spec();
let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); let client_db = new_db();
let client_db = Arc::new(Database::open(&db_config, dir.as_path().to_str().unwrap()).unwrap());
let client = Client::new( let client = Client::new(
ClientConfig::default(), ClientConfig::default(),
@ -165,8 +161,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data<F>(get_test_spec: F, ac
).unwrap(); ).unwrap();
let test_engine = &*test_spec.engine; let test_engine = &*test_spec.engine;
let mut db_result = get_temp_state_db(); let mut db = test_spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let mut db = test_spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let genesis_header = test_spec.genesis_header(); let genesis_header = test_spec.genesis_header();
let mut rolling_timestamp = 40; let mut rolling_timestamp = 40;
@ -205,7 +200,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data<F>(get_test_spec: F, ac
action: Action::Create, action: Action::Create,
data: vec![], data: vec![],
value: U256::zero(), value: U256::zero(),
}.sign(kp.secret(), None), None).unwrap(); }.sign(kp.secret(), Some(test_spec.network_id())), None).unwrap();
n += 1; n += 1;
} }
@ -220,11 +215,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data<F>(get_test_spec: F, ac
} }
client.flush_queue(); client.flush_queue();
client.import_verified_blocks(); client.import_verified_blocks();
client
GuardedTempResult::<Arc<Client>> {
_temp: dir,
result: Some(client)
}
} }
pub fn push_blocks_to_client(client: &Arc<Client>, timestamp_salt: u64, starting_number: usize, block_number: usize) { pub fn push_blocks_to_client(client: &Arc<Client>, timestamp_salt: u64, starting_number: usize, block_number: usize) {
@ -256,11 +247,9 @@ pub fn push_blocks_to_client(client: &Arc<Client>, timestamp_salt: u64, starting
} }
} }
pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> { pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> Arc<Client> {
let dir = RandomTempPath::new();
let test_spec = get_test_spec(); let test_spec = get_test_spec();
let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); let client_db = new_db();
let client_db = Arc::new(Database::open(&db_config, dir.as_path().to_str().unwrap()).unwrap());
let client = Client::new( let client = Client::new(
ClientConfig::default(), ClientConfig::default(),
@ -277,23 +266,15 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<
} }
client.flush_queue(); client.flush_queue();
client.import_verified_blocks(); client.import_verified_blocks();
client
GuardedTempResult::<Arc<Client>> {
_temp: dir,
result: Some(client)
}
} }
fn new_db(path: &str) -> Arc<Database> { fn new_db() -> Arc<KeyValueDB> {
Arc::new( Arc::new(::util::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)))
Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), path)
.expect("Opening database for tests should always work.")
)
} }
pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockChain> { pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain {
let temp = RandomTempPath::new(); let db = new_db();
let db = new_db(temp.as_str());
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());
let mut batch = db.transaction(); let mut batch = db.transaction();
@ -302,16 +283,11 @@ pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockCh
bc.commit(); bc.commit();
} }
db.write(batch).unwrap(); db.write(batch).unwrap();
bc
GuardedTempResult::<BlockChain> {
_temp: temp,
result: Some(bc)
}
} }
pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempResult<BlockChain> { pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain {
let temp = RandomTempPath::new(); let db = new_db();
let db = new_db(temp.as_str());
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());
@ -321,58 +297,29 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempRes
bc.commit(); bc.commit();
} }
db.write(batch).unwrap(); db.write(batch).unwrap();
bc
GuardedTempResult::<BlockChain> {
_temp: temp,
result: Some(bc)
}
} }
pub fn generate_dummy_empty_blockchain() -> GuardedTempResult<BlockChain> { pub fn generate_dummy_empty_blockchain() -> BlockChain {
let temp = RandomTempPath::new(); let db = new_db();
let db = new_db(temp.as_str());
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());
bc
GuardedTempResult::<BlockChain> {
_temp: temp,
result: Some(bc)
}
} }
pub fn get_temp_state_db() -> GuardedTempResult<StateDB> { pub fn get_temp_state() -> State<::state_db::StateDB> {
let temp = RandomTempPath::new(); let journal_db = get_temp_state_db();
let journal_db = get_temp_state_db_in(temp.as_path());
GuardedTempResult {
_temp: temp,
result: Some(journal_db)
}
}
pub fn get_temp_state() -> GuardedTempResult<State<::state_db::StateDB>> {
let temp = RandomTempPath::new();
let journal_db = get_temp_state_db_in(temp.as_path());
GuardedTempResult {
_temp: temp,
result: Some(State::new(journal_db, U256::from(0), Default::default())),
}
}
pub fn get_temp_state_db_in(path: &Path) -> StateDB {
let db = new_db(path.to_str().expect("Only valid utf8 paths for tests."));
let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, ::db::COL_STATE);
StateDB::new(journal_db, 5 * 1024 * 1024)
}
pub fn get_temp_state_in(path: &Path) -> State<::state_db::StateDB> {
let journal_db = get_temp_state_db_in(path);
State::new(journal_db, U256::from(0), Default::default()) State::new(journal_db, U256::from(0), Default::default())
} }
pub fn get_temp_state_db() -> StateDB {
let db = new_db();
let journal_db = journaldb::new(db, journaldb::Algorithm::EarlyMerge, ::db::COL_STATE);
StateDB::new(journal_db, 5 * 1024 * 1024)
}
pub fn get_good_dummy_block_seq(count: usize) -> Vec<Bytes> { pub fn get_good_dummy_block_seq(count: usize) -> Vec<Bytes> {
let test_spec = get_test_spec(); let test_spec = get_test_spec();
get_good_dummy_block_fork_seq(1, count, &test_spec.genesis_header().hash()) get_good_dummy_block_fork_seq(1, count, &test_spec.genesis_header().hash())
} }
pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_hash: &H256) -> Vec<Bytes> { pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_hash: &H256) -> Vec<Bytes> {
@ -394,7 +341,6 @@ pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_h
rolling_timestamp = rolling_timestamp + 10; rolling_timestamp = rolling_timestamp + 10;
r.push(create_test_block(&block_header)); r.push(create_test_block(&block_header));
} }
r r
} }

View File

@ -199,6 +199,12 @@ impl Block {
/// Decode to a full block. /// Decode to a full block.
pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0) } pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0) }
/// Decode the header.
pub fn decode_header(&self) -> FullHeader { self.rlp().val_at(0) }
/// Clone the encoded header.
pub fn header(&self) -> Header { Header(self.rlp().at(0).as_raw().to_vec()) }
/// Get the rlp of this block. /// Get the rlp of this block.
#[inline] #[inline]
pub fn rlp(&self) -> Rlp { pub fn rlp(&self) -> Rlp {

View File

@ -19,13 +19,16 @@
use std::ops::Deref; use std::ops::Deref;
use rlp::*; use rlp::*;
use util::sha3::Hashable; use util::sha3::Hashable;
use util::{H256, Address, U256, Bytes, HeapSizeOf}; use util::{H256, Address, U256, Bytes, HeapSizeOf, Uint};
use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError}; use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError};
use error::*; use error::*;
use evm::Schedule; use evm::Schedule;
use header::BlockNumber; use header::BlockNumber;
use ethjson; use ethjson;
/// Fake address for unsigned transactions as defined by EIP-86.
pub const UNSIGNED_SENDER: Address = ::util::H160([0xff; 20]);
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "ipc", binary)] #[cfg_attr(feature = "ipc", binary)]
/// Transaction action type. /// Transaction action type.
@ -110,8 +113,8 @@ impl HeapSizeOf for Transaction {
impl From<ethjson::state::Transaction> for SignedTransaction { impl From<ethjson::state::Transaction> for SignedTransaction {
fn from(t: ethjson::state::Transaction) -> Self { fn from(t: ethjson::state::Transaction) -> Self {
let to: Option<ethjson::hash::Address> = t.to.into(); let to: Option<ethjson::hash::Address> = t.to.into();
let secret = Secret::from_slice(&t.secret.0).expect("Valid secret expected."); let secret = t.secret.map(|s| Secret::from_slice(&s.0).expect("Valid secret expected."));
Transaction { let tx = Transaction {
nonce: t.nonce.into(), nonce: t.nonce.into(),
gas_price: t.gas_price.into(), gas_price: t.gas_price.into(),
gas: t.gas_limit.into(), gas: t.gas_limit.into(),
@ -121,7 +124,11 @@ impl From<ethjson::state::Transaction> for SignedTransaction {
}, },
value: t.value.into(), value: t.value.into(),
data: t.data.into(), data: t.data.into(),
}.sign(&secret, None) };
match secret {
Some(s) => tx.sign(&s, None),
None => tx.null_sign(),
}
} }
} }
@ -180,8 +187,8 @@ impl Transaction {
pub fn invalid_sign(self) -> UnverifiedTransaction { pub fn invalid_sign(self) -> UnverifiedTransaction {
UnverifiedTransaction { UnverifiedTransaction {
unsigned: self, unsigned: self,
r: U256::default(), r: U256::one(),
s: U256::default(), s: U256::one(),
v: 0, v: 0,
hash: 0.into(), hash: 0.into(),
}.compute_hash() }.compute_hash()
@ -192,13 +199,28 @@ impl Transaction {
SignedTransaction { SignedTransaction {
transaction: UnverifiedTransaction { transaction: UnverifiedTransaction {
unsigned: self, unsigned: self,
r: U256::default(), r: U256::one(),
s: U256::default(), s: U256::one(),
v: 0, v: 0,
hash: 0.into(), hash: 0.into(),
}.compute_hash(), }.compute_hash(),
sender: from, sender: from,
public: Public::default(), public: None,
}
}
/// Add EIP-86 compatible empty signature.
pub fn null_sign(self) -> SignedTransaction {
SignedTransaction {
transaction: UnverifiedTransaction {
unsigned: self,
r: U256::zero(),
s: U256::zero(),
v: 0,
hash: 0.into(),
}.compute_hash(),
sender: UNSIGNED_SENDER,
public: None,
} }
} }
@ -276,6 +298,11 @@ impl UnverifiedTransaction {
self self
} }
/// Checks is signature is empty.
pub fn is_unsigned(&self) -> bool {
self.r.is_zero() && self.s.is_zero()
}
/// Append object with a signature into RLP stream /// Append object with a signature into RLP stream
fn rlp_append_sealed_transaction(&self, s: &mut RlpStream) { fn rlp_append_sealed_transaction(&self, s: &mut RlpStream) {
s.begin_list(9); s.begin_list(9);
@ -307,6 +334,7 @@ impl UnverifiedTransaction {
/// The network ID, or `None` if this is a global transaction. /// The network ID, or `None` if this is a global transaction.
pub fn network_id(&self) -> Option<u64> { pub fn network_id(&self) -> Option<u64> {
match self.v { match self.v {
v if self.is_unsigned() => Some(v),
v if v > 36 => Some((v - 35) / 2), v if v > 36 => Some((v - 35) / 2),
_ => None, _ => None,
} }
@ -340,21 +368,33 @@ impl UnverifiedTransaction {
// TODO: consider use in block validation. // TODO: consider use in block validation.
#[cfg(test)] #[cfg(test)]
#[cfg(feature = "json-tests")] #[cfg(feature = "json-tests")]
pub fn validate(self, schedule: &Schedule, require_low: bool, allow_network_id_of_one: bool) -> Result<UnverifiedTransaction, Error> { pub fn validate(self, schedule: &Schedule, require_low: bool, allow_network_id_of_one: bool, allow_empty_signature: bool) -> Result<UnverifiedTransaction, Error> {
if require_low && !self.signature().is_low_s() { let chain_id = if allow_network_id_of_one { Some(1) } else { None };
self.verify_basic(require_low, chain_id, allow_empty_signature)?;
if !allow_empty_signature || !self.is_unsigned() {
self.recover_public()?;
}
if self.gas < U256::from(self.gas_required(&schedule)) {
return Err(TransactionError::InvalidGasLimit(::util::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
}
Ok(self)
}
/// Verify basic signature params. Does not attempt sender recovery.
pub fn verify_basic(&self, check_low_s: bool, chain_id: Option<u64>, allow_empty_signature: bool) -> Result<(), Error> {
if check_low_s && !(allow_empty_signature && self.is_unsigned()) {
self.check_low_s()?;
}
// EIP-86: Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account 0.
if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) {
return Err(EthkeyError::InvalidSignature.into()) return Err(EthkeyError::InvalidSignature.into())
} }
match self.network_id() { match (self.network_id(), chain_id) {
None => {}, (None, _) => {},
Some(1) if allow_network_id_of_one => {}, (Some(n), Some(m)) if n == m => {},
_ => return Err(TransactionError::InvalidNetworkId.into()), _ => return Err(TransactionError::InvalidNetworkId.into()),
} };
self.recover_public()?; Ok(())
if self.gas < U256::from(self.gas_required(&schedule)) {
Err(TransactionError::InvalidGasLimit(::util::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
} else {
Ok(self)
}
} }
} }
@ -363,7 +403,7 @@ impl UnverifiedTransaction {
pub struct SignedTransaction { pub struct SignedTransaction {
transaction: UnverifiedTransaction, transaction: UnverifiedTransaction,
sender: Address, sender: Address,
public: Public, public: Option<Public>,
} }
impl HeapSizeOf for SignedTransaction { impl HeapSizeOf for SignedTransaction {
@ -392,13 +432,21 @@ impl From<SignedTransaction> for UnverifiedTransaction {
impl SignedTransaction { impl SignedTransaction {
/// Try to verify transaction and recover sender. /// Try to verify transaction and recover sender.
pub fn new(transaction: UnverifiedTransaction) -> Result<Self, Error> { pub fn new(transaction: UnverifiedTransaction) -> Result<Self, Error> {
let public = transaction.recover_public()?; if transaction.is_unsigned() {
let sender = public_to_address(&public); Ok(SignedTransaction {
Ok(SignedTransaction { transaction: transaction,
transaction: transaction, sender: UNSIGNED_SENDER,
sender: sender, public: None,
public: public, })
}) } else {
let public = transaction.recover_public()?;
let sender = public_to_address(&public);
Ok(SignedTransaction {
transaction: transaction,
sender: sender,
public: Some(public),
})
}
} }
/// Returns transaction sender. /// Returns transaction sender.
@ -407,9 +455,14 @@ impl SignedTransaction {
} }
/// Returns a public key of the sender. /// Returns a public key of the sender.
pub fn public_key(&self) -> Public { pub fn public_key(&self) -> Option<Public> {
self.public self.public
} }
/// Checks is signature is empty.
pub fn is_unsigned(&self) -> bool {
self.transaction.is_unsigned()
}
} }
/// Signed Transaction that is a part of canon blockchain. /// Signed Transaction that is a part of canon blockchain.
@ -435,6 +488,9 @@ impl LocalizedTransaction {
if let Some(sender) = self.cached_sender { if let Some(sender) = self.cached_sender {
return sender; return sender;
} }
if self.is_unsigned() {
return UNSIGNED_SENDER.clone();
}
let sender = public_to_address(&self.recover_public() let sender = public_to_address(&self.recover_public()
.expect("LocalizedTransaction is always constructed from transaction from blockchain; Blockchain only stores verified transactions; qed")); .expect("LocalizedTransaction is always constructed from transaction from blockchain; Blockchain only stores verified transactions; qed"));
self.cached_sender = Some(sender); self.cached_sender = Some(sender);

View File

@ -73,10 +73,12 @@ impl From<Crypto> for String {
} }
impl Crypto { impl Crypto {
/// Encrypt account secret
pub fn with_secret(secret: &Secret, password: &str, iterations: u32) -> Self { pub fn with_secret(secret: &Secret, password: &str, iterations: u32) -> Self {
Crypto::with_plain(&*secret, password, iterations) Crypto::with_plain(&*secret, password, iterations)
} }
/// Encrypt custom plain data
pub fn with_plain(plain: &[u8], password: &str, iterations: u32) -> Self { pub fn with_plain(plain: &[u8], password: &str, iterations: u32) -> Self {
let salt: [u8; 32] = Random::random(); let salt: [u8; 32] = Random::random();
let iv: [u8; 16] = Random::random(); let iv: [u8; 16] = Random::random();
@ -113,6 +115,7 @@ impl Crypto {
} }
} }
/// Try to decrypt and convert result to account secret
pub fn secret(&self, password: &str) -> Result<Secret, Error> { pub fn secret(&self, password: &str) -> Result<Secret, Error> {
if self.ciphertext.len() > 32 { if self.ciphertext.len() > 32 {
return Err(Error::InvalidSecret); return Err(Error::InvalidSecret);
@ -122,6 +125,7 @@ impl Crypto {
Ok(Secret::from_slice(&secret)?) Ok(Secret::from_slice(&secret)?)
} }
/// Try to decrypt and return result as is
pub fn decrypt(&self, password: &str) -> Result<Vec<u8>, Error> { pub fn decrypt(&self, password: &str) -> Result<Vec<u8>, Error> {
let expected_len = self.ciphertext.len(); let expected_len = self.ciphertext.len();
self.do_decrypt(password, expected_len) self.do_decrypt(password, expected_len)

View File

@ -20,7 +20,7 @@ use std::sync::Arc;
use std::collections::HashMap; use std::collections::HashMap;
use util::{U256, H256, Address, Bytes, trie}; use util::{U256, H256, Address, Bytes, trie};
use ethcore::client::EnvInfo; use ethcore::client::EnvInfo;
use ethcore::evm::{self, Ext, ContractCreateResult, MessageCallResult, Schedule, CallType}; use ethcore::evm::{self, Ext, ContractCreateResult, MessageCallResult, Schedule, CallType, CreateContractAddress};
pub struct FakeExt { pub struct FakeExt {
schedule: Schedule, schedule: Schedule,
@ -31,7 +31,7 @@ pub struct FakeExt {
impl Default for FakeExt { impl Default for FakeExt {
fn default() -> Self { fn default() -> Self {
FakeExt { FakeExt {
schedule: Schedule::new_post_eip150(usize::max_value(), true, true, true), schedule: Schedule::new_post_eip150(usize::max_value(), true, true, true, true),
store: HashMap::new(), store: HashMap::new(),
depth: 1, depth: 1,
} }
@ -68,7 +68,7 @@ impl Ext for FakeExt {
unimplemented!(); unimplemented!();
} }
fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8]) -> ContractCreateResult { fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8], _address: CreateContractAddress) -> ContractCreateResult {
unimplemented!(); unimplemented!();
} }

View File

@ -92,6 +92,7 @@ pub struct Client<F: Fetch + 'static = FetchClient> {
contract: URLHintContract, contract: URLHintContract,
fetch: F, fetch: F,
remote: Remote, remote: Remote,
random_path: Arc<Fn() -> PathBuf + Sync + Send>,
} }
impl Client { impl Client {
@ -109,6 +110,7 @@ impl<F: Fetch + 'static> Client<F> {
contract: URLHintContract::new(contract), contract: URLHintContract::new(contract),
fetch: fetch, fetch: fetch,
remote: remote, remote: remote,
random_path: Arc::new(random_temp_path),
} }
} }
} }
@ -131,6 +133,7 @@ impl<F: Fetch + 'static> HashFetch for Client<F> {
match url { match url {
Err(err) => on_done(Err(err)), Err(err) => on_done(Err(err)),
Ok(url) => { Ok(url) => {
let random_path = self.random_path.clone();
let future = self.fetch.fetch(&url).then(move |result| { let future = self.fetch.fetch(&url).then(move |result| {
fn validate_hash(path: PathBuf, hash: H256, result: Result<Response, FetchError>) -> Result<PathBuf, Error> { fn validate_hash(path: PathBuf, hash: H256, result: Result<Response, FetchError>) -> Result<PathBuf, Error> {
let response = result?; let response = result?;
@ -155,12 +158,12 @@ impl<F: Fetch + 'static> HashFetch for Client<F> {
} }
debug!(target: "fetch", "Content fetched, validating hash ({:?})", hash); debug!(target: "fetch", "Content fetched, validating hash ({:?})", hash);
let path = random_temp_path(); let path = random_path();
let res = validate_hash(path.clone(), hash, result); let res = validate_hash(path.clone(), hash, result);
if let Err(ref err) = res { if let Err(ref err) = res {
trace!(target: "fetch", "Error: {:?}", err); trace!(target: "fetch", "Error: {:?}", err);
// Remove temporary file in case of error // Remove temporary file in case of error
let _ = fs::remove_dir_all(&path); let _ = fs::remove_file(&path);
} }
on_done(res); on_done(res);
@ -192,7 +195,7 @@ mod tests {
use fetch::{self, Fetch}; use fetch::{self, Fetch};
use parity_reactor::Remote; use parity_reactor::Remote;
use urlhint::tests::{FakeRegistrar, URLHINT}; use urlhint::tests::{FakeRegistrar, URLHINT};
use super::{Error, Client, HashFetch}; use super::{Error, Client, HashFetch, random_temp_path};
#[derive(Clone)] #[derive(Clone)]
@ -262,12 +265,16 @@ mod tests {
let result = rx.recv().unwrap(); let result = rx.recv().unwrap();
assert_eq!(result.unwrap_err(), Error::InvalidStatus); assert_eq!(result.unwrap_err(), Error::InvalidStatus);
} }
#[test] #[test]
fn should_return_hash_mismatch() { fn should_return_hash_mismatch() {
// given // given
let registrar = Arc::new(registrar()); let registrar = Arc::new(registrar());
let fetch = FakeFetch { return_success: true }; let fetch = FakeFetch { return_success: true };
let client = Client::with_fetch(registrar.clone(), fetch, Remote::new_sync()); let mut client = Client::with_fetch(registrar.clone(), fetch, Remote::new_sync());
let path = random_temp_path();
let path2 = path.clone();
client.random_path = Arc::new(move || path2.clone());
// when // when
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
@ -279,6 +286,7 @@ mod tests {
let result = rx.recv().unwrap(); let result = rx.recv().unwrap();
let hash = "0x06b0a4f426f6713234b2d4b2468640bc4e0bb72657a920ad24c5087153c593c8".into(); let hash = "0x06b0a4f426f6713234b2d4b2468640bc4e0bb72657a920ad24c5087153c593c8".into();
assert_eq!(result.unwrap_err(), Error::HashMismatch { expected: 2.into(), got: hash }); assert_eq!(result.unwrap_err(), Error::HashMismatch { expected: 2.into(), got: hash });
assert!(!path.exists(), "Temporary file should be removed.");
} }
#[test] #[test]

View File

@ -1,6 +1,6 @@
{ {
"name": "parity.js", "name": "parity.js",
"version": "1.7.49", "version": "1.7.57",
"main": "release/index.js", "main": "release/index.js",
"jsnext:main": "src/index.js", "jsnext:main": "src/index.js",
"author": "Parity Team <admin@parity.io>", "author": "Parity Team <admin@parity.io>",

View File

@ -55,11 +55,12 @@ export default class Api extends EventEmitter {
.nodeKind() .nodeKind()
.then((nodeKind) => { .then((nodeKind) => {
if (nodeKind.availability === 'public') { if (nodeKind.availability === 'public') {
return new LocalAccountsMiddleware(transport); return LocalAccountsMiddleware;
} }
return null; return null;
}); })
.catch(() => null);
transport.addMiddleware(middleware); transport.addMiddleware(middleware);
} }

View File

@ -18,8 +18,8 @@ import { randomPhrase } from '@parity/wordlist';
import { phraseToAddress, phraseToWallet } from './'; import { phraseToAddress, phraseToWallet } from './';
describe('api/local/ethkey', () => { describe('api/local/ethkey', () => {
describe.skip('phraseToAddress', function () { describe('phraseToAddress', function () {
this.timeout(10000); this.timeout(30000);
it('generates a valid address', () => { it('generates a valid address', () => {
const phrase = randomPhrase(12); const phrase = randomPhrase(12);
@ -37,8 +37,8 @@ describe('api/local/ethkey', () => {
}); });
}); });
describe.skip('phraseToWallet', function () { describe('phraseToWallet', function () {
this.timeout(10000); this.timeout(30000);
it('generates a valid wallet object', () => { it('generates a valid wallet object', () => {
const phrase = randomPhrase(12); const phrase = randomPhrase(12);

View File

@ -14,7 +14,7 @@
// 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/>.
import secp256k1 from 'secp256k1/js'; import secp256k1 from 'secp256k1';
import { keccak_256 as keccak256 } from 'js-sha3'; import { keccak_256 as keccak256 } from 'js-sha3';
import { bytesToHex } from '~/api/util/format'; import { bytesToHex } from '~/api/util/format';
@ -28,11 +28,9 @@ if (!isWorker) {
} }
// keythereum should never be used outside of the browser // keythereum should never be used outside of the browser
let keythereum = null; let keythereum = require('keythereum');
if (isWorker) { if (isWorker) {
require('keythereum/dist/keythereum');
keythereum = self.keythereum; keythereum = self.keythereum;
} }
@ -109,9 +107,13 @@ const actions = {
}; };
self.onmessage = function ({ data }) { self.onmessage = function ({ data }) {
const result = route(data); try {
const result = route(data);
postMessage(result); postMessage([null, result]);
} catch (err) {
postMessage([err, null]);
}
}; };
// Emulate a web worker in Node.js // Emulate a web worker in Node.js
@ -119,9 +121,13 @@ class KeyWorker {
postMessage (data) { postMessage (data) {
// Force async // Force async
setTimeout(() => { setTimeout(() => {
const result = route(data); try {
const result = route(data);
this.onmessage({ data: result }); this.onmessage({ data: [null, result] });
} catch (err) {
this.onmessage({ data: [err, null] });
}
}, 0); }, 0);
} }

View File

@ -33,8 +33,15 @@ class WorkerContainer {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this._worker.postMessage({ action, payload }); this._worker.postMessage({ action, payload });
this._worker.onmessage = ({ data }) => { this._worker.onmessage = ({ data }) => {
const [err, result] = data;
this.busy = false; this.busy = false;
resolve(data);
if (err) {
reject(err);
} else {
resolve(result);
}
}; };
}); });
} }

View File

@ -14,4 +14,4 @@
// 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/>.
export LocalAccountsMiddleware from './middleware'; export LocalAccountsMiddleware from './localAccountsMiddleware';

View File

@ -23,15 +23,6 @@ import { phraseToWallet, phraseToAddress, verifySecret } from './ethkey';
import { randomPhrase } from '@parity/wordlist'; import { randomPhrase } from '@parity/wordlist';
export default class LocalAccountsMiddleware extends Middleware { export default class LocalAccountsMiddleware extends Middleware {
// Maps transaction requests to transaction hashes.
// This allows the locally-signed transactions to emulate the signer.
transactionHashes = {};
transactions = {};
// Current transaction id. This doesn't need to be stored, as it's
// only relevant for the current the session.
transactionId = 1;
constructor (transport) { constructor (transport) {
super(transport); super(transport);
@ -170,13 +161,27 @@ export default class LocalAccountsMiddleware extends Middleware {
data data
} = Object.assign(transactions.get(id), modify); } = Object.assign(transactions.get(id), modify);
transactions.lock(id);
const account = accounts.get(from); const account = accounts.get(from);
return Promise.all([ return Promise.all([
this.rpcRequest('parity_nextNonce', [from]), this.rpcRequest('parity_nextNonce', [from]),
account.decryptPrivateKey(password) account.decryptPrivateKey(password)
]) ])
.catch((err) => {
transactions.unlock(id);
// transaction got unlocked, can propagate rejection further
throw err;
})
.then(([nonce, privateKey]) => { .then(([nonce, privateKey]) => {
if (!privateKey) {
transactions.unlock(id);
throw new Error('Invalid password');
}
const tx = new EthereumTx({ const tx = new EthereumTx({
nonce, nonce,
to, to,

View File

@ -0,0 +1,154 @@
// 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/>.
import LocalAccountsMiddleware from './localAccountsMiddleware';
import JsonRpcBase from '../transport/jsonRpcBase';
const RPC_RESPONSE = Symbol('RPC response');
const ADDRESS = '0x00a329c0648769a73afac7f9381e08fb43dbea72';
const SECRET = '0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7';
const PASSWORD = 'password';
const FOO_PHRASE = 'foobar';
const FOO_PASSWORD = 'foopass';
const FOO_ADDRESS = '0x007ef7ac1058e5955e366ab9d6b6c4ebcc937e7e';
class MockedTransport extends JsonRpcBase {
_execute (method, params) {
return RPC_RESPONSE;
}
}
describe('api/local/LocalAccountsMiddleware', function () {
this.timeout(30000);
let transport;
beforeEach(() => {
transport = new MockedTransport();
transport.addMiddleware(LocalAccountsMiddleware);
// Same as `parity_newAccountFromPhrase` with empty phrase
return transport
.execute('parity_newAccountFromSecret', SECRET, PASSWORD)
.catch((_err) => {
// Ignore the error - all instances of LocalAccountsMiddleware
// share account storage
});
});
it('registers all necessary methods', () => {
return Promise
.all([
'eth_accounts',
'eth_coinbase',
'parity_accountsInfo',
'parity_allAccountsInfo',
'parity_changePassword',
'parity_checkRequest',
'parity_defaultAccount',
'parity_generateSecretPhrase',
'parity_getNewDappsAddresses',
'parity_hardwareAccountsInfo',
'parity_newAccountFromPhrase',
'parity_newAccountFromSecret',
'parity_setAccountMeta',
'parity_setAccountName',
'parity_postTransaction',
'parity_phraseToAddress',
'parity_useLocalAccounts',
'parity_listGethAccounts',
'parity_listRecentDapps',
'parity_killAccount',
'parity_testPassword',
'signer_confirmRequest',
'signer_rejectRequest',
'signer_requestsToConfirm'
].map((method) => {
return transport
.execute(method)
.then((result) => {
expect(result).not.to.be.equal(RPC_RESPONSE);
})
// Some errors are expected here since we are calling methods
// without parameters.
.catch((_) => {});
}));
});
it('allows non-registered methods through', () => {
return transport
.execute('eth_getBalance', '0x407d73d8a49eeb85d32cf465507dd71d507100c1')
.then((result) => {
expect(result).to.be.equal(RPC_RESPONSE);
});
});
it('can handle `eth_accounts`', () => {
return transport
.execute('eth_accounts')
.then((accounts) => {
expect(accounts.length).to.be.equal(1);
expect(accounts[0]).to.be.equal(ADDRESS);
});
});
it('can handle `parity_defaultAccount`', () => {
return transport
.execute('parity_defaultAccount')
.then((address) => {
expect(address).to.be.equal(ADDRESS);
});
});
it('can handle `parity_phraseToAddress`', () => {
return transport
.execute('parity_phraseToAddress', '')
.then((address) => {
expect(address).to.be.equal(ADDRESS);
return transport.execute('parity_phraseToAddress', FOO_PHRASE);
})
.then((address) => {
expect(address).to.be.equal(FOO_ADDRESS);
});
});
it('can create and kill an account', () => {
return transport
.execute('parity_newAccountFromPhrase', FOO_PHRASE, FOO_PASSWORD)
.then((address) => {
expect(address).to.be.equal(FOO_ADDRESS);
return transport.execute('eth_accounts');
})
.then((accounts) => {
expect(accounts.length).to.be.equal(2);
expect(accounts.includes(FOO_ADDRESS)).to.be.true;
return transport.execute('parity_killAccount', FOO_ADDRESS, FOO_PASSWORD);
})
.then((result) => {
expect(result).to.be.true;
return transport.execute('eth_accounts');
})
.then((accounts) => {
expect(accounts.length).to.be.equal(1);
expect(accounts.includes(FOO_ADDRESS)).to.be.false;
});
});
});

View File

@ -18,6 +18,7 @@ import { toHex } from '../util/format';
import { TransportError } from '../transport'; import { TransportError } from '../transport';
const AWAITING = Symbol('awaiting'); const AWAITING = Symbol('awaiting');
const LOCKED = Symbol('locked');
const CONFIRMED = Symbol('confirmed'); const CONFIRMED = Symbol('confirmed');
const REJECTED = Symbol('rejected'); const REJECTED = Symbol('rejected');
@ -57,6 +58,26 @@ class Transactions {
return state.transaction; return state.transaction;
} }
lock (id) {
const state = this._states[id];
if (!state || state.status !== AWAITING) {
throw new Error('Trying to lock an invalid transaction');
}
state.status = LOCKED;
}
unlock (id) {
const state = this._states[id];
if (!state || state.status !== LOCKED) {
throw new Error('Trying to unlock an invalid transaction');
}
state.status = AWAITING;
}
hash (id) { hash (id) {
const state = this._states[id]; const state = this._states[id];
@ -76,9 +97,12 @@ class Transactions {
confirm (id, hash) { confirm (id, hash) {
const state = this._states[id]; const state = this._states[id];
const status = state ? state.status : null;
if (!state || state.status !== AWAITING) { switch (status) {
throw new Error('Trying to confirm an invalid transaction'); case AWAITING: break;
case LOCKED: break;
default: throw new Error('Trying to confirm an invalid transaction');
} }
state.hash = hash; state.hash = hash;

View File

@ -65,4 +65,21 @@ describe('api/local/transactions', () => {
expect(requests.length).to.be.equal(0); expect(requests.length).to.be.equal(0);
expect(() => transactions.hash(id)).to.throw(TransportError); expect(() => transactions.hash(id)).to.throw(TransportError);
}); });
it('can lock and confirm transactions', () => {
const id = transactions.add(DUMMY_TX);
const hash = '0x1111111111111111111111111111111111111111';
transactions.lock(id);
const requests = transactions.requestsToConfirm();
expect(requests.length).to.be.equal(0);
expect(transactions.get(id)).to.be.null;
expect(transactions.hash(id)).to.be.null;
transactions.confirm(id, hash);
expect(transactions.hash(id)).to.be.equal(hash);
});
}); });

View File

@ -522,6 +522,11 @@ export default class Parity {
.then(outNumber); .then(outNumber);
} }
signMessage (address, password, messageHash) {
return this._transport
.execute('parity_signMessage', inAddress(address), password, inHex(messageHash));
}
testPassword (account, password) { testPassword (account, password) {
return this._transport return this._transport
.execute('parity_testPassword', inAddress(account), password); .execute('parity_testPassword', inAddress(account), password);

View File

@ -38,20 +38,20 @@ export default class JsonRpcBase extends EventEmitter {
return json; return json;
} }
addMiddleware (middleware) { addMiddleware (Middleware) {
this._middlewareList = Promise this._middlewareList = Promise
.all([ .all([
middleware, Middleware,
this._middlewareList this._middlewareList
]) ])
.then(([middleware, middlewareList]) => { .then(([Middleware, middlewareList]) => {
// Do nothing if `handlerPromise` resolves to a null-y value. // Do nothing if `handlerPromise` resolves to a null-y value.
if (middleware == null) { if (Middleware == null) {
return middlewareList; return middlewareList;
} }
// don't mutate the original array // don't mutate the original array
return middlewareList.concat([middleware]); return middlewareList.concat([new Middleware(this)]);
}); });
} }
@ -80,8 +80,8 @@ export default class JsonRpcBase extends EventEmitter {
const res = middleware.handle(method, params); const res = middleware.handle(method, params);
if (res != null) { if (res != null) {
// If `res` isn't a promise, we need to wrap it return Promise
return Promise.resolve(res) .resolve(res)
.then((res) => { .then((res) => {
const result = this._wrapSuccessResult(res); const result = this._wrapSuccessResult(res);
const json = this.encode(method, params); const json = this.encode(method, params);

View File

@ -28,9 +28,7 @@ export default class Middleware {
const handler = this._handlers[method]; const handler = this._handlers[method];
if (handler != null) { if (handler != null) {
const response = handler(params); return handler(params);
return response;
} }
return null; return null;

View File

@ -25,17 +25,21 @@ class MockTransport extends JsonRpcBase {
} }
} }
class MockMiddleware extends Middleware {
constructor (transport) {
super(transport);
this.register('mock_rpc', ([num]) => num);
this.register('mock_null', () => null);
}
}
describe('api/transport/Middleware', () => { describe('api/transport/Middleware', () => {
let middleware;
let transport; let transport;
beforeEach(() => { beforeEach(() => {
transport = new MockTransport(); transport = new MockTransport();
middleware = new Middleware(transport); transport.addMiddleware(MockMiddleware);
middleware.register('mock_rpc', ([num]) => num);
middleware.register('mock_null', () => null);
transport.addMiddleware(middleware);
}); });
it('Routes requests to middleware', () => { it('Routes requests to middleware', () => {

View File

@ -27,7 +27,7 @@ export default class TokenReg {
} }
getInstance () { getInstance () {
return this.getContract().instance; return this.getContract().then((contract) => contract.instance);
} }
tokenCount () { tokenCount () {

View File

@ -16,13 +16,17 @@
export default { export default {
button: { button: {
delete: `verwijder account`, delete: `verwijder`,
edit: `bewerk`, edit: `bewerk`,
faucet: `Kovan ETH`,
password: `wachtwoord`, password: `wachtwoord`,
shapeshift: `shapeshift`, shapeshift: `shapeshift`,
transfer: `verzend`, transfer: `verzend`,
verify: `verifieer` verify: `verifieer`
}, },
hardware: {
confirmDelete: `Weet je zeker dat je de volgende hardware adressen van je account lijst wilt verwijderen?`
},
header: { header: {
outgoingTransactions: `{count} uitgaande transacties`, outgoingTransactions: `{count} uitgaande transacties`,
uuid: `uuid: {uuid}` uuid: `uuid: {uuid}`

View File

@ -16,8 +16,8 @@
export default { export default {
button: { button: {
newAccount: `nieuw account`, newAccount: `account`,
newWallet: `nieuw wallet`, newWallet: `wallet`,
vaults: `kluizen` vaults: `kluizen`
}, },
summary: { summary: {
@ -27,5 +27,8 @@ export default {
tooltip: { tooltip: {
actions: `voor de huidige weergave zijn koppelingen beschikbaar op de werkbalk voor snelle toegang: het uitvoeren van acties of het creëren van een nieuw item`, actions: `voor de huidige weergave zijn koppelingen beschikbaar op de werkbalk voor snelle toegang: het uitvoeren van acties of het creëren van een nieuw item`,
overview: `hier vind je een overzichtelijke weergave van je accounts, waarin je meta informatie kunt bewerken en transacties kunt uitvoeren en bekijken` overview: `hier vind je een overzichtelijke weergave van je accounts, waarin je meta informatie kunt bewerken en transacties kunt uitvoeren en bekijken`
},
tooltips: {
owner: `{name} (eigenaar)`
} }
}; };

View File

@ -19,6 +19,7 @@ export default {
add: `Adres Opslaan`, add: `Adres Opslaan`,
close: `Annuleer` close: `Annuleer`
}, },
header: `Om een nieuwe invoer aan je adresboek toe te voegen, heb je het netwerk adres van het account nodig en kun je optioneel een beschrijving toevoegen. Zodra de nieuwe invoer is toegevoegd, zal het in je adresboek verschijnen.`,
input: { input: {
address: { address: {
hint: `het netwerk adres van het item`, hint: `het netwerk adres van het item`,
@ -33,5 +34,5 @@ export default {
label: `Adres Naam` label: `Adres Naam`
} }
}, },
label: `voeg opgeslagen adres toe` label: `voeg een opgeslagen adres toe`
}; };

28
js/src/i18n/nl/address.js Normal file
View File

@ -0,0 +1,28 @@
// 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/>.
export default {
buttons: {
edit: `bewerken`,
forget: `vergeten`,
save: `opslaan`
},
delete: {
confirmInfo: `Weet je zeker dat je het volgende adres uit je adresboek wilt verwijderen?`,
title: `bevestig verwijderen`
},
title: `Adres Informatie`
};

View File

@ -14,6 +14,12 @@
// 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/>.
export default function () { export default {
// empty file included while building parity.js (don't include local keygen) buttons: {
} add: `adres`
},
errors: {
invalidFile: `Het opgegeven bestand is ongeldig...`
},
title: `Opgeslagen Adressen`
};

View File

@ -15,6 +15,9 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default { export default {
frame: {
error: `FOUT: Deze applicatie kan niet en zou niet geladen moeten worden in een embedded iFrame`
},
status: { status: {
consensus: { consensus: {
capable: `Capable`, capable: `Capable`,

View File

@ -15,5 +15,27 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default { export default {
minedBlock: `Opgenomen in blok #{blockNumber}` buttons: {
close: `Sluit`,
details: `details`,
edit: `bewerken`,
execute: `uitvoeren`,
forget: `vergeten`
},
details: {
title: `contract details`
},
events: {
eventPending: `pending`,
noEvents: `Er zijn vanuit dit contract nog geen events verzonden.`,
title: `events`
},
minedBlock: `Opgenomen in blok #{blockNumber}`,
queries: {
buttons: {
query: `Query`
},
title: `queries`
},
title: `Contract Informatie`
}; };

View File

@ -0,0 +1,28 @@
// 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/>.
export default {
buttons: {
deploy: `publiceer`,
develop: `ontwikkel`,
watch: `bekijk`
},
sortOrder: {
date: `datum`,
minedBlock: `opgenomen blok`
},
title: `Contracten`
};

View File

@ -20,10 +20,6 @@ export default {
hint: `Het netwerk adres van het account`, hint: `Het netwerk adres van het account`,
label: `adres` label: `adres`
}, },
name: {
hint: `Een beschrijvende naam van het account`,
label: `account naam`
},
phrase: { phrase: {
hint: `De account herstel zin`, hint: `De account herstel zin`,
label: `Eigenaar's herstel zin (houd deze woorden veilig en prive want hiermee kun je volledige, ongelimiteerde toegang tot het account verkrijgen).` label: `Eigenaar's herstel zin (houd deze woorden veilig en prive want hiermee kun je volledige, ongelimiteerde toegang tot het account verkrijgen).`
@ -35,31 +31,38 @@ export default {
button: { button: {
back: `Terug`, back: `Terug`,
cancel: `Annuleer`, cancel: `Annuleer`,
close: `Sluit`,
create: `Aanmaken`, create: `Aanmaken`,
done: `Klaar`,
import: `Importeer`, import: `Importeer`,
next: `Volgende`, next: `Volgende`,
print: `Herstel zin afdrukken` print: `Herstel zin afdrukken`
}, },
creationType: { creationType: {
fromGeth: { fromGeth: {
label: `Importeer accounts uit Geth keystore` description: `Importeer accounts uit Geth keystore met het originele wachtwoord`,
label: `Geth keystore`
}, },
fromJSON: { fromJSON: {
label: `Importeer account uit een opgeslagen JSON file` description: `Importeer account uit een JSON sleutelbestand met het originele wachtwoord`,
label: `JSON bestand`
}, },
fromNew: { fromNew: {
label: `Handmatig account aanmaken` description: `Selecteer je identiteits-icoon en kies je wachtwoord`,
label: `Nieuw Account`
}, },
fromPhrase: { fromPhrase: {
label: `Herstel account met een herstel zin` description: `Herstel je account met een eerder bewaarde herstel zin en een nieuw wachtwoord`,
label: `Herstel zin`
}, },
fromPresale: { fromPresale: {
label: `Importeer account van een Ethereum voor-verkoop (pre-sale) wallet` description: `Importeer een Ethereum voor-verkoop (pre-sale) wallet bestand met het originele wachtwoord`,
label: `voor-verkoop wallet`
}, },
fromRaw: { fromRaw: {
label: `Importeer een prive sleutel (raw private key)` description: `Importeer een eerder gemaakte prive sleutel (raw private key) met een nieuw wachtwoord`,
} label: `Prive sleutel`
},
info: `Selecteer de manier waarop je je account wilt aanmaken of importeren. Maak een nieuw account aan met een naam en wachtwoord, of importeer/herstel een bestaand account vanuit verschillende bronnen zoals een herstel zin of een sleutelbestand. Met behulp van deze wizard word je door het proces begeleid om een account aan te maken.`
}, },
newAccount: { newAccount: {
hint: { hint: {
@ -80,6 +83,7 @@ export default {
} }
}, },
newGeth: { newGeth: {
available: `Er zijn momenteel {count} importeerbare sleutels (keys) beschikbaar vanuit Geth keystore, welke nog niet in je Parity installatie beschikbaar zijn. Selecteer de accounts die je wilt importeren en ga verder naar de volgende stap om het importeren te voltooien.`,
noKeys: `Er zijn momenteel geen importeerbare sleutels (keys) beschikbaar in de Geth keystore; of ze zijn al in je Parity installatie beschikbaar` noKeys: `Er zijn momenteel geen importeerbare sleutels (keys) beschikbaar in de Geth keystore; of ze zijn al in je Parity installatie beschikbaar`
}, },
newImport: { newImport: {

View File

@ -53,7 +53,7 @@ export default {
label: `wallet naam` label: `wallet naam`
}, },
ownerMulti: { ownerMulti: {
hint: `het eigenaars account van dit contract`, hint: `het account wat eigenaar is van dit contract`,
label: `van account (contract eigenaar)` label: `van account (contract eigenaar)`
}, },
ownersMulti: { ownersMulti: {
@ -80,6 +80,7 @@ export default {
}, },
states: { states: {
completed: `Het contract is succesvol aangemaakt`, completed: `Het contract is succesvol aangemaakt`,
confirmationNeeded: `Voor het aanmaken van dit contract is bevestiging door andere eigenaren van het Wallet vereist`,
preparing: `Transactie aan het voorbereiden voor verzending op het netwerk`, preparing: `Transactie aan het voorbereiden voor verzending op het netwerk`,
validatingCode: `De contract code van het aangemaakte contract wordt gevalideerd`, validatingCode: `De contract code van het aangemaakte contract wordt gevalideerd`,
waitingConfirm: `Wachten tot de transactie bevestigd is in de Parity Secure Signer`, waitingConfirm: `Wachten tot de transactie bevestigd is in de Parity Secure Signer`,
@ -93,7 +94,7 @@ export default {
}, },
type: { type: {
multisig: { multisig: {
description: `Creëer/Maak een {link} Wallet aan`, description: `Maak een {link} Wallet aan`,
label: `Multi-Sig wallet`, label: `Multi-Sig wallet`,
link: `standaard multi-signature` link: `standaard multi-signature`
}, },

View File

@ -36,11 +36,10 @@ export default {
}, },
external: { external: {
accept: `Ik begrijp dat deze toepassingen niet bij Parity zijn aangesloten`, accept: `Ik begrijp dat deze toepassingen niet bij Parity zijn aangesloten`,
warning: `Deze applicaties gepuliceerd door derde partijen zijn niet bij Parity aangesloten, noch worden ze gepubliceerd door Parity. Alle applicaties blijven in beheer van hun eigen auteur. Zorg ervoor dat je snapt wat het doel van een applicatie is voordat je ermee aan de slag gaat.` warning: `Deze applicaties zijn gepuliceerd door derde partijen welke niet verwant zijn aan Parity en zijn dus ook niet door Parity uitgebracht. Alle applicaties blijven in beheer van hun eigen auteur. Zorg ervoor dat je snapt wat het doel van een applicatie is voordat je ermee aan de slag gaat.`
}, },
label: `Gedecentraliseerde Applicaties`, label: `Gedecentraliseerde Applicaties`,
permissions: { permissions: {
description: `{activeIcon} account is beschikbaar voor applicaties, {defaultIcon} account is het standaard account`,
label: `zichtbare dapp accounts` label: `zichtbare dapp accounts`
} }
}; };

View File

@ -37,6 +37,13 @@ export default {
hint: `het account wat eigenaar is van dit contract`, hint: `het account wat eigenaar is van dit contract`,
label: `van account (contract eigenaar)` label: `van account (contract eigenaar)`
}, },
advanced: {
label: `geavanceerde verzend opties`
},
amount: {
hint: `de naar het contract te verzenden hoeveelheid`,
label: `te verzenden hoeveelheid (in {tag})`
},
code: { code: {
hint: `de gecompileerde code van het aan te maken contract`, hint: `de gecompileerde code van het aan te maken contract`,
label: `code` label: `code`
@ -65,6 +72,7 @@ export default {
}, },
state: { state: {
completed: `Het contract is succesvol aangemaakt`, completed: `Het contract is succesvol aangemaakt`,
confirmationNeeded: `Deze actie vereist de bevestiging van de andere eigenaren van het contract`,
preparing: `Transactie aan het voorbereiden om te verzenden op het netwerk`, preparing: `Transactie aan het voorbereiden om te verzenden op het netwerk`,
validatingCode: `De contract code van het aangemaakte contract valideren`, validatingCode: `De contract code van het aangemaakte contract valideren`,
waitReceipt: `Wachten tot het aanmaken van het contract bevestigd is`, waitReceipt: `Wachten tot het aanmaken van het contract bevestigd is`,
@ -74,6 +82,7 @@ export default {
completed: `voltooid`, completed: `voltooid`,
deployment: `aangemaakt`, deployment: `aangemaakt`,
details: `contract details`, details: `contract details`,
extras: `extra informatie`,
failed: `aanmaken mislukt`, failed: `aanmaken mislukt`,
parameters: `contract parameters`, parameters: `contract parameters`,
rejected: `afgewezen` rejected: `afgewezen`

28
js/src/i18n/nl/faucet.js Normal file
View File

@ -0,0 +1,28 @@
// 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/>.
export default {
buttons: {
close: `sluit`,
done: `klaar`,
request: `verzoek`
},
summary: {
done: `Jouw Kovan ETH is aangevraagd bij het faucet, wat reageerde met het volgende bericht -`,
info: `Om een hoeveelheid Kovan ETH aan te vragen voor dit adres, moet je ervoor zorgen dat het adres op het mainnet sms-geverifieerd is. Zodra je dit uitvoert, zal het faucet Kovan ETH naar je huidige account verzenden.`
},
title: `Kovan ETH Faucet`
};

View File

@ -17,16 +17,33 @@
export default { export default {
button: { button: {
close: `Sluiten`, close: `Sluiten`,
create: `creëer`, create: `Creëer`,
next: `volgende`, next: `Volgende`,
print: `Woorden Afdrukken`, print: `Woorden Afdrukken`,
skip: `Overslaan` skip: `Overslaan`
}, },
completed: {
congrats: `Gefeliciteerd! Je node configuratie is succesvol afgerond en het programma is klaar voor gebruikt.`,
next: `Om je snel aan de slag te laten gaan krijg je in de volgende stap een korte algemene inleiding in het gebruik van het programma en lopen we door de beschikbare funcies.`
},
title: { title: {
completed: `voltooid`, completed: `voltooid`,
newAccount: `nieuw account`, newAccount: `nieuw account`,
recovery: `herstelzin`, recovery: `herstelzin`,
terms: `voorwaarden`, terms: `voorwaarden`,
welcome: `welkom` welcome: `welkom`
},
tnc: {
accept: `Ik accepteer de voorwaarden en condities`
},
welcome: {
description: `Als onderdeel van een nieuwe installatie, begeleiden we je in de enkele hierna volgende stappen met het configureren van je Parity node en jouw bijbehorende accounts. Ons doel hiervan is om het je zo gemakkelijk mogelijk te maken and zodat je binnen de kortste tijd klaar bent voor gebruik, dus heb even geduld en blijf bij ons. Zodra je de wizard voltooid hebt, heb je -`,
greeting: `Welkom bij Parity, de snelste en makkelijkste manier om je eigen node te draaien.`,
next: `Klik volgende om door te gaan.`,
step: {
account: `Je eerste Parity account aangemaakt;`,
privacy: `Onze privacybeleid en bedrijfsvoorwaarden begrepen;`,
recovery: `De mogelijkheid om je account te herstellen.`
}
} }
}; };

View File

@ -18,10 +18,13 @@ import account from './account';
import accounts from './accounts'; import accounts from './accounts';
import addAddress from './addAddress'; import addAddress from './addAddress';
import addContract from './addContract'; import addContract from './addContract';
import address from './address';
import addresses from './addresses';
import addressSelect from './addressSelect'; import addressSelect from './addressSelect';
import application from './application'; import application from './application';
import connection from './connection'; import connection from './connection';
import contract from './contract'; import contract from './contract';
import contracts from './contracts';
import createAccount from './createAccount'; import createAccount from './createAccount';
import createWallet from './createWallet'; import createWallet from './createWallet';
import dapp from './dapp'; import dapp from './dapp';
@ -32,31 +35,41 @@ import editMeta from './editMeta';
import errors from './errors'; import errors from './errors';
import executeContract from './executeContract'; import executeContract from './executeContract';
import extension from './extension'; import extension from './extension';
import faucet from './faucet';
import firstRun from './firstRun'; import firstRun from './firstRun';
import home from './home'; import home from './home';
import loadContract from './loadContract'; import loadContract from './loadContract';
import parityBar from './parityBar'; import parityBar from './parityBar';
import passwordChange from './passwordChange'; import passwordChange from './passwordChange';
import saveContract from './saveContract';
import settings from './settings'; import settings from './settings';
import shapeshift from './shapeshift'; import shapeshift from './shapeshift';
import signer from './signer';
import status from './status';
import tabBar from './tabBar'; import tabBar from './tabBar';
import transfer from './transfer'; import transfer from './transfer';
import txEditor from './txEditor'; import txEditor from './txEditor';
import ui from './ui'; import ui from './ui';
import upgradeParity from './upgradeParity'; import upgradeParity from './upgradeParity';
import vaults from './vaults'; import vaults from './vaults';
import verification from './verification';
import wallet from './wallet';
import walletSettings from './walletSettings'; import walletSettings from './walletSettings';
import web from './web'; import web from './web';
import writeContract from './writeContract';
export default { export default {
account, account,
accounts, accounts,
addAddress, addAddress,
addContract, addContract,
address,
addresses,
addressSelect, addressSelect,
application, application,
connection, connection,
contract, contract,
contracts,
createAccount, createAccount,
createWallet, createWallet,
dapp, dapp,
@ -67,19 +80,26 @@ export default {
errors, errors,
executeContract, executeContract,
extension, extension,
faucet,
firstRun, firstRun,
home, home,
loadContract, loadContract,
parityBar, parityBar,
passwordChange, passwordChange,
saveContract,
settings, settings,
shapeshift, shapeshift,
signer,
status,
tabBar, tabBar,
transfer, transfer,
txEditor, txEditor,
ui, ui,
upgradeParity, upgradeParity,
vaults, vaults,
verification,
wallet,
walletSettings, walletSettings,
web web,
writeContract
}; };

View File

@ -30,6 +30,7 @@ export default {
label: `nieuw wachtwoord` label: `nieuw wachtwoord`
}, },
passwordHint: { passwordHint: {
display: `Hint {hint}`,
hint: `hint voor het nieuwe wachtwoord`, hint: `hint voor het nieuwe wachtwoord`,
label: `(optioneel) nieuwe wachtwoord hint` label: `(optioneel) nieuwe wachtwoord hint`
}, },

View File

@ -0,0 +1,27 @@
// 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/>.
export default {
buttons: {
cancel: `Annuleer`,
save: `Opslaan`
},
name: {
hint: `kies een naam voor dit contract`,
label: `contract naam`
},
title: `contract opslaan`
};

View File

@ -22,6 +22,18 @@ export default {
label: `achtergrond` label: `achtergrond`
}, },
parity: { parity: {
chains: {
chain_classic: `Parity synchroniseert met het Ethereum Classic netwerk`,
chain_dev: `Parity gebruikt een lokale ontwikkelaars chain`,
chain_expanse: `Parity synchroniseert met het Expanse netwerk`,
chain_foundation: `Parity synchroniseert met het Ethereum netwerk wat door de Ethereum Foundation is uitgebracht`,
chain_kovan: `Parity synchroniseert met het Kovan test netwerk`,
chain_olympic: `Parity synchroniseert met het Olympic test netwerk`,
chain_ropsten: `Parity synchroniseert met het Ropsten test netwerk`,
cmorden_kovan: `Parity synchroniseert met het Morden (Classic) test netwerk`,
hint: `de chain waarmee de Parity node synchroniseert`,
label: `te synchroniseren chain/netwerk`
},
languages: { languages: {
hint: `de taal waarin deze interface wordt weergegeven`, hint: `de taal waarin deze interface wordt weergegeven`,
label: `Weergave taal` label: `Weergave taal`
@ -35,7 +47,7 @@ export default {
mode_offline: `Parity synchroniseert niet`, mode_offline: `Parity synchroniseert niet`,
mode_passive: `Parity synchroniseert in het begin. Daarna slaapt Parity en wordt regelmatig wakker voor synchronisatie` mode_passive: `Parity synchroniseert in het begin. Daarna slaapt Parity en wordt regelmatig wakker voor synchronisatie`
}, },
overview_0: `Pas de Parity node instellingen aan en kies de synchronisatie modus in dit menu.`, overview_0: `Pas de Parity node instellingen aan en kies de manier van synchroniseren in dit menu.`,
label: `parity` label: `parity`
}, },
proxy: { proxy: {
@ -53,7 +65,7 @@ export default {
label: `Accounts` label: `Accounts`
}, },
addresses: { addresses: {
description: `Een overzicht van alle contacten en adresboek items die door deze Parity installatie worden beheerd. Monitor en volg accounts waarbij je transactie details met slechts een muisklik kunt weergeven.`, description: `Een overzicht van alle door deze Parity installatie beheerde contacten en adresboek items. Monitor en volg accounts waarbij je transactie details met slechts een muisklik kunt weergeven.`,
label: `Adresboek` label: `Adresboek`
}, },
apps: { apps: {
@ -64,10 +76,10 @@ export default {
description: `Monitor, volg en maak gebruik van specifieke contracten die op het netwerk zijn gezet. Dit is een meer technisch gerichte omgeving, voornamelijk bedoeld voor geavanceerde gebruikers die de werking van bepaalde contracten goed begrijpen.`, description: `Monitor, volg en maak gebruik van specifieke contracten die op het netwerk zijn gezet. Dit is een meer technisch gerichte omgeving, voornamelijk bedoeld voor geavanceerde gebruikers die de werking van bepaalde contracten goed begrijpen.`,
label: `Contracten` label: `Contracten`
}, },
overview_0: `Beheer de beschikbare weergaven van deze interface en selecteer enkel de delen van de applicatie die voor jou van belang zijn.`, overview_0: `Beheer de beschikbare weergaven van deze interface, en selecteer enkel de delen van de applicatie die voor jou van belang zijn.`,
overview_1: `Ben je een eind gebruiker? De standaard instellingen zijn geschikt voor zowel beginners als gevorderde gebruikers.`, overview_1: `Ben je een eind gebruiker? De standaard instellingen zijn geschikt voor zowel beginners als gevorderde gebruikers.`,
overview_2: `Ben je een ontwikkelaar? Voeg enkele functies toe om je contracten te beheren en gebruik te maken van gedecentraliseerde applicaties.`, overview_2: `Ben je een ontwikkelaar? Voeg enkele functies toe om je contracten te beheren en gebruik te maken van gedecentraliseerde applicaties.`,
overview_3: `Ben je een miner of run je een grootschalige node? Voeg enkele functies toe om je alle informatie te geven die je nodig hebt om je node te monitoren.`, overview_3: `Ben je een miner of draai je een grootschalige node? Voeg enkele functies toe om je alle informatie te geven die je nodig hebt om je node te monitoren.`,
settings: { settings: {
description: `Deze weergave. Hiermee kun je Parity aan passen in termen van opties, bediening en look en feel.`, description: `Deze weergave. Hiermee kun je Parity aan passen in termen van opties, bediening en look en feel.`,
label: `Instellingen` label: `Instellingen`

103
js/src/i18n/nl/signer.js Normal file
View File

@ -0,0 +1,103 @@
// 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/>.
export default {
embedded: {
noPending: `Er zijn momenteel geen lopende verzoeken die op je goedkeuring wachten`
},
mainDetails: {
editTx: `Bewerk condities/gas/gasprijs`,
tooltips: {
total1: `De waarde van de transactie inclusief de miningskosten is {total} {type}.`,
total2: `(Dit is inclusief een miners vergoeding van {fee} {token})`,
value1: `De waarde van de transactie.`
}
},
requestOrigin: {
dapp: `door een dapp op {url}`,
ipc: `via IPC sessie`,
rpc: `via RPC {rpc}`,
signerCurrent: `via huidige tab`,
signerUI: `via UI sessie`,
unknownInterface: `via onbekende interface`,
unknownRpc: `niet geïdentificeerd`,
unknownUrl: `onbekende URL`
},
requestsPage: {
noPending: `Er zijn geen verzoeken die je goedkeuring vereisen.`,
pendingTitle: `Openstaande Verzoeken`,
queueTitle: `Lokale Transacties`
},
sending: {
hardware: {
confirm: `Bevestig de transactie op je aangesloten hardware wallet`,
connect: `Sluit je hardware wallet aan voordat je de transactie bevestigd`
}
},
signRequest: {
request: `Een verzoek om data te ondertekenen met jouw account:`,
state: {
confirmed: `Bevestigd`,
rejected: `Afgewezen`
},
unknownBinary: `(Onbekende binary data)`,
warning: `WAARSCHUWING: Deze gevolgen hiervan kunnen ernstig zijn. Bevestig het verzoek alleen als je het zeker weet.`
},
title: `Trusted Signer`,
txPending: {
buttons: {
viewToggle: `bekijk transactie`
}
},
txPendingConfirm: {
buttons: {
confirmBusy: `Bevestigen...`,
confirmRequest: `Bevestig Verzoek`
},
errors: {
invalidWallet: `Opgegeven wallet bestand is ongeldig.`
},
password: {
decrypt: {
hint: `open (decrypt) de sleutel met je wachtwoord`,
label: `Sleutel Wachtwoord`
},
unlock: {
hint: `ontgrendel het account`,
label: `Account Wachtwoord`
}
},
passwordHint: `(hint) {passwordHint}`,
selectKey: {
hint: `De sleutelbestand (keyfile) die je voor dit account wilt gebruiken`,
label: `Selecteer Lokale Sleutel (key)`
},
tooltips: {
password: `Geef een wachtwoord voor dit account`
}
},
txPendingForm: {
changedMind: `Ik heb me bedacht`,
reject: `wijs verzoek af`
},
txPendingReject: {
buttons: {
reject: `Wijs Verzoek Af`
},
info: `Weet je zeker dat je dit verzoek wilt afwijzen?`,
undone: `Dit kan niet ongedaan gemaakt worden`
}
};

Some files were not shown because too many files have changed in this diff Show More