Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f96d152548 | ||
|
|
c8f57315a8 | ||
|
|
e1925015c8 | ||
|
|
a5ed4cfc4b | ||
|
|
cfa197061e | ||
|
|
9075ff883f | ||
|
|
39317136c7 | ||
|
|
f4a496ac8c | ||
|
|
12940e4ed7 | ||
|
|
2c2587e44c | ||
|
|
d219ebc9ae | ||
|
|
412d1cb578 | ||
|
|
6638b01b46 | ||
|
|
d5fcf3b8ed | ||
|
|
6bb3edeb8a | ||
|
|
16c091590f | ||
|
|
eb7c648250 | ||
|
|
be23afd1cd |
110
Cargo.lock
generated
110
Cargo.lock
generated
@@ -1,7 +1,3 @@
|
||||
[root]
|
||||
name = "using_queue"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "advapi32-sys"
|
||||
version = "0.2.0"
|
||||
@@ -190,7 +186,7 @@ source = "git+https://github.com/paritytech/bn#c9831a8d10d55045692394cbc10efe032
|
||||
dependencies = [
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -258,7 +254,7 @@ dependencies = [
|
||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -277,7 +273,7 @@ dependencies = [
|
||||
name = "common-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethjson 0.1.0",
|
||||
"rlp 0.2.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -429,12 +425,12 @@ dependencies = [
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethabi"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -466,7 +462,7 @@ dependencies = [
|
||||
"common-types 0.1.0",
|
||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethash 1.7.0",
|
||||
"ethcore-bloom-journal 0.1.0",
|
||||
"ethcore-devtools 1.7.0",
|
||||
@@ -476,7 +472,7 @@ dependencies = [
|
||||
"ethcore-ipc-nano 1.7.0",
|
||||
"ethcore-logger 1.7.0",
|
||||
"ethcore-stratum 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"ethstore 0.1.0",
|
||||
@@ -497,7 +493,7 @@ dependencies = [
|
||||
"rlp 0.2.0",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.6.0 (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)",
|
||||
@@ -545,7 +541,7 @@ name = "ethcore-ipc"
|
||||
version = "1.7.0"
|
||||
dependencies = [
|
||||
"ethcore-devtools 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -594,7 +590,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.7.0",
|
||||
"ethcore-ipc-codegen 1.7.0",
|
||||
"ethcore-ipc-nano 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -611,7 +607,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.7.0",
|
||||
"ethcore-ipc-codegen 1.7.0",
|
||||
"ethcore-network 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"evm 0.1.0",
|
||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -650,7 +646,7 @@ dependencies = [
|
||||
"ethcore-devtools 1.7.0",
|
||||
"ethcore-io 1.7.0",
|
||||
"ethcore-logger 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -663,7 +659,7 @@ dependencies = [
|
||||
"rlp 0.2.0",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -674,14 +670,14 @@ name = "ethcore-secretstore"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.7.0",
|
||||
"ethcore-devtools 1.7.0",
|
||||
"ethcore-ipc 1.7.0",
|
||||
"ethcore-ipc-codegen 1.7.0",
|
||||
"ethcore-ipc-nano 1.7.0",
|
||||
"ethcore-logger 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -711,7 +707,7 @@ dependencies = [
|
||||
"ethcore-ipc-codegen 1.7.0",
|
||||
"ethcore-ipc-nano 1.7.0",
|
||||
"ethcore-logger 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"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-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||
@@ -724,7 +720,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-util"
|
||||
version = "1.7.6"
|
||||
version = "1.7.12"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -774,7 +770,7 @@ name = "ethjson"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -855,7 +851,7 @@ dependencies = [
|
||||
"ethcore-ipc-nano 1.7.0",
|
||||
"ethcore-light 1.7.0",
|
||||
"ethcore-network 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethkey 0.2.0",
|
||||
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -874,7 +870,7 @@ dependencies = [
|
||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"common-types 0.1.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethjson 0.1.0",
|
||||
"evmjit 1.7.0",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -891,7 +887,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethjson 0.1.0",
|
||||
"evm 0.1.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1057,7 +1053,7 @@ dependencies = [
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rotor 0.6.3 (git+https://github.com/tailhook/rotor)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spmc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1075,7 +1071,7 @@ dependencies = [
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1136,7 +1132,7 @@ version = "1.7.0"
|
||||
dependencies = [
|
||||
"ethcore-ipc 1.7.0",
|
||||
"ethcore-ipc-codegen 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1520,7 +1516,7 @@ dependencies = [
|
||||
name = "native-contract-generator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heck 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1529,8 +1525,8 @@ name = "native-contracts"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.7.12",
|
||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-contract-generator 0.1.0",
|
||||
]
|
||||
@@ -1621,7 +1617,7 @@ dependencies = [
|
||||
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1630,7 +1626,7 @@ version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1658,7 +1654,7 @@ dependencies = [
|
||||
"num-bigint 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1735,7 +1731,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity"
|
||||
version = "1.7.6"
|
||||
version = "1.7.12"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1755,7 +1751,7 @@ dependencies = [
|
||||
"ethcore-logger 1.7.0",
|
||||
"ethcore-secretstore 1.0.0",
|
||||
"ethcore-stratum 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethkey 0.2.0",
|
||||
"ethsync 1.7.0",
|
||||
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1801,7 +1797,7 @@ dependencies = [
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-devtools 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"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)",
|
||||
@@ -1844,8 +1840,8 @@ dependencies = [
|
||||
name = "parity-hash-fetch"
|
||||
version = "1.7.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.7.12",
|
||||
"fetch 0.1.0",
|
||||
"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)",
|
||||
@@ -1863,7 +1859,7 @@ version = "1.7.0"
|
||||
dependencies = [
|
||||
"cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1876,7 +1872,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore 1.7.0",
|
||||
"ethcore-io 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethkey 0.2.0",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
@@ -1906,7 +1902,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.7.0",
|
||||
"ethcore-light 1.7.0",
|
||||
"ethcore-logger 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
@@ -1948,7 +1944,7 @@ dependencies = [
|
||||
name = "parity-rpc-client"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"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-ws-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||
@@ -1998,7 +1994,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git?branch=stable#1f3321388c17206628aeb22db00f0988b1510f50"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git?branch=stable#bbc5b6c3e3a43ab21b94d37922cdbed766c7b5c8"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2007,11 +2003,11 @@ dependencies = [
|
||||
name = "parity-updater"
|
||||
version = "1.7.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.7.0",
|
||||
"ethcore-ipc 1.7.0",
|
||||
"ethcore-ipc-codegen 1.7.0",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"ethsync 1.7.0",
|
||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-common-types 1.7.0",
|
||||
@@ -2367,7 +2363,7 @@ name = "rpc-cli"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.7.6",
|
||||
"ethcore-util 1.7.12",
|
||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc 1.7.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
@@ -2382,7 +2378,7 @@ dependencies = [
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -2398,7 +2394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.19"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -2668,7 +2664,7 @@ version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_pos 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2679,7 +2675,7 @@ name = "syntex_pos"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2689,7 +2685,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_errors 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_pos 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2901,7 +2897,7 @@ name = "toml"
|
||||
version = "0.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2997,6 +2993,10 @@ dependencies = [
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "using_queue"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "1.0.0"
|
||||
@@ -3163,7 +3163,7 @@ dependencies = [
|
||||
"checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
|
||||
"checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143"
|
||||
"checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
|
||||
"checksum ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3d62319ee0f35abf20afe8859dd2668195912614346447bb2dee9fb8da7c62"
|
||||
"checksum ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6af84a622f9169efc6ead7f70043ca2058ef261c50e5e1e2ac60ccd381e386"
|
||||
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
|
||||
"checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
@@ -3291,7 +3291,7 @@ dependencies = [
|
||||
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||
"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95"
|
||||
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
|
||||
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
|
||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
||||
"checksum rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e114e275f7c9b5d50bb52b28f9aac1921209f02aa6077c8b255e21eefaf8ffa"
|
||||
"checksum schannel 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4e45ac5e9e4698c1c138d2972bedcd90b81fe1efeba805449d2bdd54512de5f9"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity"
|
||||
version = "1.7.6"
|
||||
version = "1.7.12"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
@@ -193,7 +193,7 @@ const UPDATE_TIMEOUT_ERR_SECS: u64 = 60;
|
||||
const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10;
|
||||
|
||||
/// Maximal valid time drift.
|
||||
pub const MAX_DRIFT: i64 = 500;
|
||||
pub const MAX_DRIFT: i64 = 10_000;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// A time checker.
|
||||
|
||||
@@ -30,9 +30,6 @@ pub enum ContractCreateResult {
|
||||
/// Returned when contract creation failed.
|
||||
/// VM doesn't have to know the reason.
|
||||
Failed,
|
||||
/// Returned when contract creation failed.
|
||||
/// VM doesn't have to know the reason.
|
||||
FailedInStaticCall,
|
||||
/// Reverted with REVERT.
|
||||
Reverted(U256, ReturnData),
|
||||
}
|
||||
|
||||
@@ -313,20 +313,24 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
let init_off = stack.pop_back();
|
||||
let init_size = stack.pop_back();
|
||||
|
||||
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
|
||||
let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed");
|
||||
|
||||
let contract_code = self.mem.read_slice(init_off, init_size);
|
||||
let can_create = ext.balance(¶ms.address)? >= endowment && ext.depth() < ext.schedule().max_depth;
|
||||
if ext.is_static() {
|
||||
return Err(evm::Error::MutableCallInStaticContext);
|
||||
}
|
||||
|
||||
// clear return data buffer before creating new call frame.
|
||||
self.return_data = ReturnData::empty();
|
||||
|
||||
let can_create = ext.balance(¶ms.address)? >= endowment && ext.depth() < ext.schedule().max_depth;
|
||||
if !can_create {
|
||||
stack.push(U256::zero());
|
||||
return Ok(InstructionResult::UnusedGas(create_gas));
|
||||
}
|
||||
|
||||
let contract_code = self.mem.read_slice(init_off, init_size);
|
||||
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
|
||||
|
||||
let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme);
|
||||
return match create_result {
|
||||
ContractCreateResult::Created(address, gas_left) => {
|
||||
@@ -342,9 +346,6 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
stack.push(U256::zero());
|
||||
Ok(InstructionResult::Ok)
|
||||
},
|
||||
ContractCreateResult::FailedInStaticCall => {
|
||||
Err(evm::Error::MutableCallInStaticContext)
|
||||
},
|
||||
};
|
||||
},
|
||||
instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL | instructions::STATICCALL => {
|
||||
@@ -906,8 +907,8 @@ mod tests {
|
||||
use rustc_hex::FromHex;
|
||||
use vmtype::VMType;
|
||||
use factory::Factory;
|
||||
use vm::{self, ActionParams, ActionValue};
|
||||
use vm::tests::{FakeExt, test_finalize};
|
||||
use action_params::{ActionParams, ActionValue};
|
||||
use ::tests::{FakeExt, test_finalize};
|
||||
|
||||
#[test]
|
||||
fn should_not_fail_on_tracing_mem() {
|
||||
@@ -950,6 +951,6 @@ mod tests {
|
||||
test_finalize(vm.exec(params, &mut ext)).err().unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(err, ::vm::Error::OutOfBounds);
|
||||
assert_eq!(err, ::Error::OutOfBounds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,18 +55,20 @@ pub struct FakeExt {
|
||||
pub store: HashMap<H256, H256>,
|
||||
pub suicides: HashSet<Address>,
|
||||
pub calls: HashSet<FakeCall>,
|
||||
sstore_clears: usize,
|
||||
depth: usize,
|
||||
blockhashes: HashMap<U256, H256>,
|
||||
codes: HashMap<Address, Arc<Bytes>>,
|
||||
logs: Vec<FakeLogEntry>,
|
||||
info: EnvInfo,
|
||||
schedule: Schedule,
|
||||
balances: HashMap<Address, U256>,
|
||||
pub sstore_clears: usize,
|
||||
pub depth: usize,
|
||||
pub blockhashes: HashMap<U256, H256>,
|
||||
pub codes: HashMap<Address, Arc<Bytes>>,
|
||||
pub logs: Vec<FakeLogEntry>,
|
||||
pub info: EnvInfo,
|
||||
pub schedule: Schedule,
|
||||
pub balances: HashMap<Address, U256>,
|
||||
pub is_static: bool,
|
||||
pub tracing: bool,
|
||||
}
|
||||
|
||||
// similar to the normal `finalize` function, but ignoring NeedsReturn.
|
||||
fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> {
|
||||
pub fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> {
|
||||
match res {
|
||||
Ok(GasLeft::Known(gas)) => Ok(gas),
|
||||
Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented.
|
||||
@@ -78,6 +80,12 @@ impl FakeExt {
|
||||
pub fn new() -> Self {
|
||||
FakeExt::default()
|
||||
}
|
||||
|
||||
pub fn new_byzantium() -> Self {
|
||||
let mut ext = FakeExt::new();
|
||||
ext.schedule = Schedule::new_byzantium();
|
||||
ext
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Schedule {
|
||||
@@ -168,7 +176,7 @@ impl Ext for FakeExt {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ret(self, _gas: &U256, _data: &ReturnData) -> evm::Result<U256> {
|
||||
fn ret(self, _gas: &U256, _data: &ReturnData, _apply_state: bool) -> evm::Result<U256> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -192,6 +200,10 @@ impl Ext for FakeExt {
|
||||
fn inc_sstore_clears(&mut self) {
|
||||
self.sstore_clears += 1;
|
||||
}
|
||||
|
||||
fn is_static(&self) -> bool {
|
||||
self.is_static
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -917,7 +929,6 @@ fn test_jumps(factory: super::Factory) {
|
||||
assert_eq!(gas_left, U256::from(54_117));
|
||||
}
|
||||
|
||||
|
||||
evm_test!{test_calls: test_calls_jit, test_calls_int}
|
||||
fn test_calls(factory: super::Factory) {
|
||||
let code = "600054602d57600160005560006000600060006050610998610100f160006000600060006050610998610100f25b".from_hex().unwrap();
|
||||
@@ -962,6 +973,27 @@ fn test_calls(factory: super::Factory) {
|
||||
assert_eq!(ext.calls.len(), 2);
|
||||
}
|
||||
|
||||
evm_test!{test_create_in_staticcall: test_create_in_staticcall_jit, test_create_in_staticcall_int}
|
||||
fn test_create_in_staticcall(factory: super::Factory) {
|
||||
let code = "600060006064f000".from_hex().unwrap();
|
||||
|
||||
let address = Address::from(0x155);
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.address = address.clone();
|
||||
let mut ext = FakeExt::new_byzantium();
|
||||
ext.is_static = true;
|
||||
|
||||
let err = {
|
||||
let mut vm = factory.create(params.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap_err()
|
||||
};
|
||||
|
||||
assert_eq!(err, ::Error::MutableCallInStaticContext);
|
||||
assert_eq!(ext.calls.len(), 0);
|
||||
}
|
||||
|
||||
fn assert_set_contains<T : Debug + Eq + PartialEq + Hash>(set: &HashSet<T>, val: &T) {
|
||||
let contains = set.contains(val);
|
||||
if !contains {
|
||||
|
||||
@@ -169,10 +169,6 @@ impl<'a> Runtime<'a> {
|
||||
self.gas_counter = self.gas_limit - gas_left.low_u64();
|
||||
Ok(Some((-1i32).into()))
|
||||
},
|
||||
ext::ContractCreateResult::FailedInStaticCall => {
|
||||
trace!(target: "wasm", "runtime: create contract called in static context");
|
||||
Err(interpreter::Error::Trap("CREATE in static context".to_owned()))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -173,24 +173,38 @@
|
||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://efe4f2493f4aff2d641b1db8366b96ddacfe13e7a6e9c8f8f8cf49f9cdba0fdf3258d8c8f8d0c5db529f8123c8f1d95f36d54d590ca1bb366a5818b9a4ba521c@163.172.187.252:30303",
|
||||
"enode://6a868ced2dec399c53f730261173638a93a40214cf299ccf4d42a76e3fa54701db410669e8006347a4b3a74fa090bb35af0320e4bc8d04cf5b7f582b1db285f5@163.172.131.191:30303",
|
||||
"enode://66a483383882a518fcc59db6c017f9cd13c71261f13c8d7e67ed43adbbc82a932d88d2291f59be577e9425181fc08828dc916fdd053af935a9491edf9d6006ba@212.47.247.103:30303",
|
||||
"enode://cd6611461840543d5b9c56fbf088736154c699c43973b3a1a32390cf27106f87e58a818a606ccb05f3866de95a4fe860786fea71bf891ea95f234480d3022aa3@163.172.157.114:30303",
|
||||
"enode://78b094cb27ceeecbe311bc278f4fde8b9a265db42d268c88484c94d7a2d19b82a1bd22dfd6c2bd4d90f9b05e6d42255e6eb85de15f73848ff82ed0be9cdf5202@52.233.198.218:30303",
|
||||
"enode://00526537cb7e1aa6cf49714f0635fd0f608904d8d0693b949eea2dcdfdb0abbe4c794003a5fe57aa662d0a9215e8dfa4d2deb6ef0101c5e185e2617721813d43@40.65.122.44:30303",
|
||||
"enode://4a456b4b6e6ee1f51389763e51b80fe04782c762445d96c32a96ebd34bd9178c1894924d5101123eacfd4f0fc4da25b5e1ee7f18832ac0bf4c6d6ac81442d698@40.71.6.49:3030",
|
||||
"enode://68f85e7403976aa92318eff804cbe9bc988e0f5230d9d07ae4def030cbae16603262638e272d19875b7e5c54e296ba88ab6ec6e98face9e2537346c4dce78882@52.243.47.211:30303",
|
||||
"enode://dc72806c3aa8fda207c8c018aba8d6cf143728b3628b6ded8d5e8cdeb8aa05cbd53f710ecd014c9a8f0d1e98f2874bff8afb15a229202f510a9c0258d1f6d109@159.203.210.80:30303",
|
||||
"enode://5a62f19d35c0da8b576c9414568c728d4744e6e9d436c0f9db27456400011414f515871f13a6b8e0468534b5116cfe765d7630f680f1707a38467940a9f62511@45.55.33.62:30303",
|
||||
"enode://605e04a43b1156966b3a3b66b980c87b7f18522f7f712035f84576016be909a2798a438b2b17b1a8c58db314d88539a77419ca4be36148c086900fba487c9d39@188.166.255.12:30303",
|
||||
"enode://1d1f7bcb159d308eb2f3d5e32dc5f8786d714ec696bb2f7e3d982f9bcd04c938c139432f13aadcaf5128304a8005e8606aebf5eebd9ec192a1471c13b5e31d49@138.201.223.35:30303",
|
||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
||||
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303",
|
||||
"enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303",
|
||||
"enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303",
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||
"enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303",
|
||||
"enode://0cc5f5ffb5d9098c8b8c62325f3797f56509bff942704687b6530992ac706e2cb946b90a34f1f19548cd3c7baccbcaea354531e5983c7d1bc0dee16ce4b6440b@40.118.3.223:30305",
|
||||
"enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30308",
|
||||
"enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30309",
|
||||
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303",
|
||||
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
|
||||
"enode://2c9059f05c352b29d559192fe6bca272d965c9f2290632a2cfda7f83da7d2634f3ec45ae3a72c54dd4204926fb8082dcf9686e0d7504257541c86fc8569bcf4b@163.172.171.38:30303",
|
||||
"enode://efe4f2493f4aff2d641b1db8366b96ddacfe13e7a6e9c8f8f8cf49f9cdba0fdf3258d8c8f8d0c5db529f8123c8f1d95f36d54d590ca1bb366a5818b9a4ba521c@163.172.187.252:30303",
|
||||
"enode://bcc7240543fe2cf86f5e9093d05753dd83343f8fda7bf0e833f65985c73afccf8f981301e13ef49c4804491eab043647374df1c4adf85766af88a624ecc3330e@136.243.154.244:30303",
|
||||
"enode://ed4227681ca8c70beb2277b9e870353a9693f12e7c548c35df6bca6a956934d6f659999c2decb31f75ce217822eefca149ace914f1cbe461ed5a2ebaf9501455@88.212.206.70:30303",
|
||||
"enode://cadc6e573b6bc2a9128f2f635ac0db3353e360b56deef239e9be7e7fce039502e0ec670b595f6288c0d2116812516ad6b6ff8d5728ff45eba176989e40dead1e@37.128.191.230:30303",
|
||||
"enode://595a9a06f8b9bc9835c8723b6a82105aea5d55c66b029b6d44f229d6d135ac3ecdd3e9309360a961ea39d7bee7bac5d03564077a4e08823acc723370aace65ec@46.20.235.22:30303",
|
||||
"enode://029178d6d6f9f8026fc0bc17d5d1401aac76ec9d86633bba2320b5eed7b312980c0a210b74b20c4f9a8b0b2bf884b111fa9ea5c5f916bb9bbc0e0c8640a0f56c@216.158.85.185:30303",
|
||||
"enode://fdd1b9bb613cfbc200bba17ce199a9490edc752a833f88d4134bf52bb0d858aa5524cb3ec9366c7a4ef4637754b8b15b5dc913e4ed9fdb6022f7512d7b63f181@212.47.247.103:30303",
|
||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
||||
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303",
|
||||
|
||||
"enode://89d5dc2a81e574c19d0465f497c1af96732d1b61a41de89c2a37f35707689ac416529fae1038809852b235c2d30fd325abdc57c122feeefbeaaf802cc7e9580d@45.55.33.62:30303",
|
||||
"enode://605e04a43b1156966b3a3b66b980c87b7f18522f7f712035f84576016be909a2798a438b2b17b1a8c58db314d88539a77419ca4be36148c086900fba487c9d39@188.166.255.12:30303",
|
||||
"enode://016b20125f447a3b203a3cae953b2ede8ffe51290c071e7599294be84317635730c397b8ff74404d6be412d539ee5bb5c3c700618723d3b53958c92bd33eaa82@159.203.210.80:30303",
|
||||
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
|
||||
"enode://8d91c8137890d29110b9463882f17ae4e279cd2c90cf56573187ed1c8546fca5f590a9f05e9f108eb1bd91767ed01ede4daad9e001b61727885eaa246ddb39c2@163.172.171.38:30303"
|
||||
"enode://fdd1b9bb613cfbc200bba17ce199a9490edc752a833f88d4134bf52bb0d858aa5524cb3ec9366c7a4ef4637754b8b15b5dc913e4ed9fdb6022f7512d7b63f181@212.47.247.103:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
||||
@@ -26,15 +26,21 @@
|
||||
},
|
||||
"validateScoreTransition": 1000000,
|
||||
"eip155Transition": 1000000,
|
||||
"validateStepTransition": 1500000
|
||||
}
|
||||
"validateStepTransition": 1500000,
|
||||
"maximumUncleCountTransition": 5067000,
|
||||
"maximumUncleCount": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x2A",
|
||||
"validateReceiptsTransition" : 1000000
|
||||
"validateReceiptsTransition" : 1000000,
|
||||
"eip140Transition": 5067000,
|
||||
"eip211Transition": 5067000,
|
||||
"eip214Transition": 5067000,
|
||||
"eip658Transition": 5067000
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@@ -49,15 +55,19 @@
|
||||
"accounts": {
|
||||
"0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 5067000, "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 5067000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 5067000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 5067000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
|
||||
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
|
||||
},
|
||||
"nodes": [
|
||||
"enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303",
|
||||
"enode://dcf984764db421fa0cd8dc7fc02ae378545723abb94d179f55325514cc30185eaea3dcefde6e358b7cdbe970c50b7c49e841618713a9a72d6f3f59ad9949ec6b@52.165.239.18:30303",
|
||||
"enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303",
|
||||
"enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303",
|
||||
"enode://8fa162563a8e5a05eef3e1cd5abc5828c71344f7277bb788a395cce4a0e30baf2b34b92fe0b2dbbba2313ee40236bae2aab3c9811941b9f5a7e8e90aaa27ecba@52.165.239.18:30303",
|
||||
"enode://7e2e7f00784f516939f94e22bdc6cf96153603ca2b5df1c7cc0f90a38e7a2f218ffb1c05b156835e8b49086d11fdd1b3e2965be16baa55204167aa9bf536a4d9@52.243.47.56:30303",
|
||||
"enode://d51b3e98bf35addf2f1d0ea1ffc90483e24d7c60b0fb3be1701e818f3d6778c06e53fdec737a534fe222956296f9d6e909baa025916a94601897e5c7136a7d95@40.71.221.215:30303",
|
||||
"enode://419d42e300e8fd379ff6d045d93d7e66a091441e7b3c9f1d3d10088d8634ad37721e6bf86148f78c3f1b9f1360dc566ca8ee830b2d2079bc9f7171ea6152bb64@52.166.117.77:30303"
|
||||
"enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ impl AccountProvider {
|
||||
|
||||
/// Checks whether an account with a given address is present.
|
||||
pub fn has_account(&self, address: Address) -> Result<bool, Error> {
|
||||
Ok(self.accounts()?.iter().any(|&a| a == address))
|
||||
Ok(self.sstore.account_ref(&address).is_ok() && !self.blacklisted_accounts.contains(&address))
|
||||
}
|
||||
|
||||
/// Returns addresses of all accounts.
|
||||
|
||||
@@ -324,8 +324,13 @@ impl<'x> OpenBlock<'x> {
|
||||
/// NOTE Will check chain constraints and the uncle number but will NOT check
|
||||
/// that the header itself is actually valid.
|
||||
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
|
||||
if self.block.uncles.len() + 1 > self.engine.maximum_uncle_count() {
|
||||
return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.uncles.len() + 1}));
|
||||
let max_uncles = self.engine.maximum_uncle_count(self.block.header().number());
|
||||
if self.block.uncles.len() + 1 > max_uncles {
|
||||
return Err(BlockError::TooManyUncles(OutOfBounds{
|
||||
min: None,
|
||||
max: Some(max_uncles),
|
||||
found: self.block.uncles.len() + 1,
|
||||
}));
|
||||
}
|
||||
// TODO: check number
|
||||
// TODO: check not a direct ancestor (use last_hashes for that)
|
||||
|
||||
@@ -1192,12 +1192,12 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
|
||||
const UPPER_CEILING: u64 = 1_000_000_000_000u64;
|
||||
let (mut upper, env_info) = {
|
||||
let (mut upper, max_upper, env_info) = {
|
||||
let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?;
|
||||
let initial_upper = env_info.gas_limit;
|
||||
env_info.gas_limit = UPPER_CEILING.into();
|
||||
(initial_upper, env_info)
|
||||
let init = env_info.gas_limit;
|
||||
let max = init * U256::from(10);
|
||||
env_info.gas_limit = max;
|
||||
(init, max, env_info)
|
||||
};
|
||||
|
||||
// that's just a copy of the state.
|
||||
@@ -1218,9 +1218,7 @@ impl BlockChainClient for Client {
|
||||
};
|
||||
|
||||
if !cond(upper)? {
|
||||
// impossible at block gas limit - try `UPPER_CEILING` instead.
|
||||
// TODO: consider raising limit by powers of two.
|
||||
upper = UPPER_CEILING.into();
|
||||
upper = max_upper;
|
||||
if !cond(upper)? {
|
||||
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
||||
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
|
||||
@@ -1788,7 +1786,7 @@ impl MiningBlockChainClient for Client {
|
||||
.find_uncle_headers(&h, engine.maximum_uncle_age())
|
||||
.unwrap_or_else(Vec::new)
|
||||
.into_iter()
|
||||
.take(engine.maximum_uncle_count())
|
||||
.take(engine.maximum_uncle_count(open_block.header().number()))
|
||||
.foreach(|h| {
|
||||
open_block.push_uncle(h).expect("pushing maximum_uncle_count;
|
||||
open_block was just created;
|
||||
@@ -1803,7 +1801,7 @@ impl MiningBlockChainClient for Client {
|
||||
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
|
||||
let engine = &*self.engine;
|
||||
let mut block = block.reopen(engine);
|
||||
let max_uncles = engine.maximum_uncle_count();
|
||||
let max_uncles = engine.maximum_uncle_count(block.header().number());
|
||||
if block.uncles().len() < max_uncles {
|
||||
let chain = self.chain.read();
|
||||
let h = chain.best_block_hash();
|
||||
|
||||
@@ -49,12 +49,16 @@ mod finality;
|
||||
pub struct AuthorityRoundParams {
|
||||
/// Gas limit divisor.
|
||||
pub gas_limit_bound_divisor: U256,
|
||||
/// Time to wait before next block or authority switching.
|
||||
pub step_duration: Duration,
|
||||
/// Block reward.
|
||||
pub block_reward: U256,
|
||||
/// Namereg contract address.
|
||||
pub registrar: Address,
|
||||
/// Time to wait before next block or authority switching,
|
||||
/// in seconds.
|
||||
///
|
||||
/// Deliberately typed as u16 as too high of a value leads
|
||||
/// to slow block issuance.
|
||||
pub step_duration: u16,
|
||||
/// Starting step,
|
||||
pub start_step: Option<u64>,
|
||||
/// Valid validators.
|
||||
@@ -67,13 +71,24 @@ pub struct AuthorityRoundParams {
|
||||
pub validate_step_transition: u64,
|
||||
/// Immediate transitions.
|
||||
pub immediate_transitions: bool,
|
||||
/// Number of accepted uncles transition block.
|
||||
pub maximum_uncle_count_transition: u64,
|
||||
/// Number of accepted uncles.
|
||||
pub maximum_uncle_count: usize,
|
||||
}
|
||||
|
||||
const U16_MAX: usize = ::std::u16::MAX as usize;
|
||||
|
||||
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
fn from(p: ethjson::spec::AuthorityRoundParams) -> Self {
|
||||
let mut step_duration_usize: usize = p.step_duration.into();
|
||||
if step_duration_usize > U16_MAX {
|
||||
step_duration_usize = U16_MAX;
|
||||
warn!(target: "engine", "step_duration is too high ({}), setting it to {}", step_duration_usize, U16_MAX);
|
||||
}
|
||||
AuthorityRoundParams {
|
||||
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
|
||||
step_duration: Duration::from_secs(p.step_duration.into()),
|
||||
step_duration: step_duration_usize as u16,
|
||||
validators: new_validator_set(p.validators),
|
||||
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
|
||||
registrar: p.registrar.map_or_else(Address::new, Into::into),
|
||||
@@ -82,6 +97,8 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
eip155_transition: p.eip155_transition.map_or(0, Into::into),
|
||||
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
||||
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
||||
maximum_uncle_count_transition: p.maximum_uncle_count_transition.map_or(0, Into::into),
|
||||
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,40 +108,83 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
struct Step {
|
||||
calibrate: bool, // whether calibration is enabled.
|
||||
inner: AtomicUsize,
|
||||
duration: Duration,
|
||||
duration: u16,
|
||||
}
|
||||
|
||||
impl Step {
|
||||
fn load(&self) -> usize { self.inner.load(AtomicOrdering::SeqCst) }
|
||||
fn duration_remaining(&self) -> Duration {
|
||||
let now = unix_now();
|
||||
let step_end = self.duration * (self.load() as u32 + 1);
|
||||
if step_end > now {
|
||||
step_end - now
|
||||
} else {
|
||||
Duration::from_secs(0)
|
||||
let expected_seconds = (self.load() as u64)
|
||||
.checked_add(1)
|
||||
.and_then(|ctr| ctr.checked_mul(self.duration as u64))
|
||||
.map(Duration::from_secs);
|
||||
|
||||
match expected_seconds {
|
||||
Some(step_end) if step_end > now => step_end - now,
|
||||
Some(_) => Duration::from_secs(0),
|
||||
None => {
|
||||
let ctr = self.load();
|
||||
error!(target: "engine", "Step counter is too high: {}, aborting", ctr);
|
||||
panic!("step counter is too high: {}", ctr)
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn increment(&self) {
|
||||
self.inner.fetch_add(1, AtomicOrdering::SeqCst);
|
||||
use std::usize;
|
||||
// fetch_add won't panic on overflow but will rather wrap
|
||||
// around, leading to zero as the step counter, which might
|
||||
// lead to unexpected situations, so it's better to shut down.
|
||||
if self.inner.fetch_add(1, AtomicOrdering::SeqCst) == usize::MAX {
|
||||
error!(target: "engine", "Step counter is too high: {}, aborting", usize::MAX);
|
||||
panic!("step counter is too high: {}", usize::MAX);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn calibrate(&self) {
|
||||
if self.calibrate {
|
||||
let new_step = unix_now().as_secs() / self.duration.as_secs();
|
||||
let new_step = unix_now().as_secs() / (self.duration as u64);
|
||||
self.inner.store(new_step as usize, AtomicOrdering::SeqCst);
|
||||
}
|
||||
}
|
||||
fn is_future(&self, given: usize) -> bool {
|
||||
if given > self.load() + 1 {
|
||||
// Make absolutely sure that the given step is correct.
|
||||
self.calibrate();
|
||||
given > self.load() + 1
|
||||
|
||||
fn check_future(&self, given: usize) -> Result<(), Option<OutOfBounds<u64>>> {
|
||||
const REJECTED_STEP_DRIFT: usize = 4;
|
||||
|
||||
// Verify if the step is correct.
|
||||
if given <= self.load() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Make absolutely sure that the given step is incorrect.
|
||||
self.calibrate();
|
||||
let current = self.load();
|
||||
|
||||
// reject blocks too far in the future
|
||||
if given > current + REJECTED_STEP_DRIFT {
|
||||
Err(None)
|
||||
// wait a bit for blocks in near future
|
||||
} else if given > current {
|
||||
let d = self.duration as u64;
|
||||
Err(Some(OutOfBounds {
|
||||
min: None,
|
||||
max: Some(d * current as u64),
|
||||
found: d * given as u64,
|
||||
}))
|
||||
} else {
|
||||
false
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||
fn calculate_score(parent_step: U256, current_step: U256) -> U256 {
|
||||
U256::from(U128::max_value()) + parent_step - current_step
|
||||
}
|
||||
|
||||
struct EpochManager {
|
||||
epoch_transition_hash: H256,
|
||||
epoch_transition_number: BlockNumber,
|
||||
@@ -229,6 +289,8 @@ pub struct AuthorityRound {
|
||||
validate_step_transition: u64,
|
||||
epoch_manager: Mutex<EpochManager>,
|
||||
immediate_transitions: bool,
|
||||
maximum_uncle_count_transition: u64,
|
||||
maximum_uncle_count: usize,
|
||||
}
|
||||
|
||||
// header-chain validator.
|
||||
@@ -309,22 +371,28 @@ fn verify_external<F: Fn(Report)>(header: &Header, validators: &ValidatorSet, st
|
||||
{
|
||||
let header_step = header_step(header)?;
|
||||
|
||||
// Give one step slack if step is lagging, double vote is still not possible.
|
||||
if step.is_future(header_step) {
|
||||
trace!(target: "engine", "verify_block_external: block from the future");
|
||||
report(Report::Benign(*header.author(), header.number()));
|
||||
Err(BlockError::InvalidSeal)?
|
||||
} else {
|
||||
let proposer_signature = header_signature(header)?;
|
||||
let correct_proposer = validators.get(header.parent_hash(), header_step);
|
||||
let is_invalid_proposer = *header.author() != correct_proposer ||
|
||||
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
|
||||
match step.check_future(header_step) {
|
||||
Err(None) => {
|
||||
trace!(target: "engine", "verify_block_external: block from the future");
|
||||
report(Report::Benign(*header.author(), header.number()));
|
||||
return Err(BlockError::InvalidSeal.into())
|
||||
},
|
||||
Err(Some(oob)) => {
|
||||
trace!(target: "engine", "verify_block_external: block too early");
|
||||
return Err(BlockError::TemporarilyInvalid(oob).into())
|
||||
},
|
||||
Ok(_) => {
|
||||
let proposer_signature = header_signature(header)?;
|
||||
let correct_proposer = validators.get(header.parent_hash(), header_step);
|
||||
let is_invalid_proposer = *header.author() != correct_proposer ||
|
||||
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
|
||||
|
||||
if is_invalid_proposer {
|
||||
trace!(target: "engine", "verify_block_external: bad proposer for step: {}", header_step);
|
||||
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
|
||||
} else {
|
||||
Ok(())
|
||||
if is_invalid_proposer {
|
||||
trace!(target: "engine", "verify_block_external: bad proposer for step: {}", header_step);
|
||||
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -357,8 +425,12 @@ impl AsMillis for Duration {
|
||||
impl AuthorityRound {
|
||||
/// Create a new instance of AuthorityRound engine.
|
||||
pub fn new(params: CommonParams, our_params: AuthorityRoundParams, builtins: BTreeMap<Address, Builtin>) -> Result<Arc<Self>, Error> {
|
||||
if our_params.step_duration == 0 {
|
||||
error!(target: "engine", "Authority Round step duration can't be zero, aborting");
|
||||
panic!("authority_round: step duration can't be zero")
|
||||
}
|
||||
let should_timeout = our_params.start_step.is_none();
|
||||
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / our_params.step_duration.as_secs())) as usize;
|
||||
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / (our_params.step_duration as u64))) as usize;
|
||||
let engine = Arc::new(
|
||||
AuthorityRound {
|
||||
params: params,
|
||||
@@ -381,6 +453,8 @@ impl AuthorityRound {
|
||||
validate_step_transition: our_params.validate_step_transition,
|
||||
epoch_manager: Mutex::new(EpochManager::blank()),
|
||||
immediate_transitions: our_params.immediate_transitions,
|
||||
maximum_uncle_count_transition: our_params.maximum_uncle_count_transition,
|
||||
maximum_uncle_count: our_params.maximum_uncle_count,
|
||||
});
|
||||
|
||||
// Do not initialize timeouts for tests.
|
||||
@@ -414,9 +488,15 @@ impl IoHandler<()> for TransitionHandler {
|
||||
fn timeout(&self, io: &IoContext<()>, timer: TimerToken) {
|
||||
if timer == ENGINE_TIMEOUT_TOKEN {
|
||||
if let Some(engine) = self.engine.upgrade() {
|
||||
engine.step();
|
||||
let remaining = engine.step.duration_remaining();
|
||||
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining.as_millis())
|
||||
// NOTE we might be lagging by couple of steps in case the timeout
|
||||
// has not been called fast enough.
|
||||
// Make sure to advance up to the actual step.
|
||||
while engine.step.duration_remaining().as_millis() == 0 {
|
||||
engine.step();
|
||||
}
|
||||
|
||||
let next_run_at = engine.step.duration_remaining().as_millis() >> 2;
|
||||
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, next_run_at)
|
||||
.unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e))
|
||||
}
|
||||
}
|
||||
@@ -455,10 +535,19 @@ impl Engine for AuthorityRound {
|
||||
]
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, block: BlockNumber) -> usize {
|
||||
if block >= self.maximum_uncle_count_transition {
|
||||
self.maximum_uncle_count
|
||||
} else {
|
||||
// fallback to default value
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) {
|
||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||
let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load().into();
|
||||
header.set_difficulty(new_difficulty);
|
||||
let parent_step = header_step(parent).expect("Header has been verified; qed");
|
||||
let score = calculate_score(parent_step.into(), self.step.load().into());
|
||||
header.set_difficulty(score);
|
||||
header.set_gas_limit({
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.gas_limit_bound_divisor;
|
||||
@@ -471,21 +560,38 @@ impl Engine for AuthorityRound {
|
||||
}
|
||||
|
||||
fn seals_internally(&self) -> Option<bool> {
|
||||
// TODO: accept a `&Call` here so we can query the validator set.
|
||||
Some(self.signer.read().is_some())
|
||||
}
|
||||
|
||||
/// Attempt to seal the block internally.
|
||||
///
|
||||
/// This operation is synchronous and may (quite reasonably) not be available, in which `false` will
|
||||
/// be returned.
|
||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
||||
/// `Seal::None` will be returned.
|
||||
fn generate_seal(&self, block: &ExecutedBlock, parent: &Header) -> Seal {
|
||||
// first check to avoid generating signature most of the time
|
||||
// (but there's still a race to the `compare_and_swap`)
|
||||
if !self.can_propose.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
||||
|
||||
let header = block.header();
|
||||
let parent_step: U256 = header_step(parent)
|
||||
.expect("Header has been verified; qed").into();
|
||||
|
||||
let step = self.step.load();
|
||||
|
||||
let expected_diff = calculate_score(parent_step, step.into());
|
||||
|
||||
if header.difficulty() != &expected_diff {
|
||||
debug!(target: "engine", "Aborting seal generation. The step has changed in the meantime. {:?} != {:?}",
|
||||
header.difficulty(), expected_diff);
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
if parent_step > step.into() {
|
||||
warn!(target: "engine", "Aborting seal generation for invalid step: {} > {}", parent_step, step);
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
// fetch correct validator set for current epoch, taking into account
|
||||
// finality of previous transitions.
|
||||
let active_set;
|
||||
@@ -512,6 +618,13 @@ impl Engine for AuthorityRound {
|
||||
};
|
||||
|
||||
if is_step_proposer(validators, header.parent_hash(), step, header.author()) {
|
||||
// this is guarded against by `can_propose` unless the block was signed
|
||||
// on the same step (implies same key) and on a different node.
|
||||
if parent_step == step.into() {
|
||||
warn!("Attempted to seal block on the same step as parent. Is this authority sealing with more than one node?");
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
if let Ok(signature) = self.sign(header.bare_hash()) {
|
||||
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
|
||||
|
||||
@@ -526,6 +639,7 @@ impl Engine for AuthorityRound {
|
||||
trace!(target: "engine", "generate_seal: {} not a proposer for step {}.",
|
||||
header.author(), step);
|
||||
}
|
||||
|
||||
Seal::None
|
||||
}
|
||||
|
||||
@@ -924,17 +1038,51 @@ mod tests {
|
||||
let b2 = b2.close_and_lock();
|
||||
|
||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b1.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) {
|
||||
assert!(b1.clone().try_seal(engine, seal).is_ok());
|
||||
// Second proposal is forbidden.
|
||||
assert!(engine.generate_seal(b1.block()) == Seal::None);
|
||||
assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None);
|
||||
}
|
||||
|
||||
engine.set_signer(tap, addr2, "2".into());
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b2.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) {
|
||||
assert!(b2.clone().try_seal(engine, seal).is_ok());
|
||||
// Second proposal is forbidden.
|
||||
assert!(engine.generate_seal(b2.block()) == Seal::None);
|
||||
assert!(engine.generate_seal(b2.block(), &genesis_header) == Seal::None);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checks_difficulty_in_generate_seal() {
|
||||
let tap = Arc::new(AccountProvider::transient_provider());
|
||||
let addr1 = tap.insert_account("1".sha3().into(), "1").unwrap();
|
||||
let addr2 = tap.insert_account("0".sha3().into(), "0").unwrap();
|
||||
|
||||
let spec = Spec::new_test_round();
|
||||
let engine = &*spec.engine;
|
||||
|
||||
let genesis_header = spec.genesis_header();
|
||||
let db1 = spec.ensure_db_good(get_temp_state_db(), &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 b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||
let b1 = b1.close_and_lock();
|
||||
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||
let b2 = b2.close_and_lock();
|
||||
|
||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||
match engine.generate_seal(b1.block(), &genesis_header) {
|
||||
Seal::None | Seal::Proposal(_) => panic!("wrong seal"),
|
||||
Seal::Regular(_) => {
|
||||
engine.step();
|
||||
|
||||
engine.set_signer(tap.clone(), addr2, "0".into());
|
||||
match engine.generate_seal(b2.block(), &genesis_header) {
|
||||
Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"),
|
||||
Seal::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1018,16 +1166,19 @@ mod tests {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
gas_limit_bound_divisor: U256::from_str("400").unwrap(),
|
||||
step_duration: Default::default(),
|
||||
block_reward: Default::default(),
|
||||
registrar: Default::default(),
|
||||
step_duration: 1,
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
eip155_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 0,
|
||||
maximum_uncle_count: 0,
|
||||
};
|
||||
|
||||
let aura = AuthorityRound::new(Default::default(), params, Default::default()).unwrap();
|
||||
|
||||
let mut parent_header: Header = Header::default();
|
||||
@@ -1047,4 +1198,75 @@ mod tests {
|
||||
assert!(aura.verify_block_family(&header, &parent_header, None).is_ok());
|
||||
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uncles_transition() {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
gas_limit_bound_divisor: 5.into(),
|
||||
block_reward: Default::default(),
|
||||
registrar: Default::default(),
|
||||
step_duration: 1,
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
eip155_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 1,
|
||||
maximum_uncle_count: 0,
|
||||
};
|
||||
|
||||
let aura = AuthorityRound::new(Default::default(), params, Default::default()).unwrap();
|
||||
|
||||
assert_eq!(aura.maximum_uncle_count(0), 2);
|
||||
assert_eq!(aura.maximum_uncle_count(1), 0);
|
||||
assert_eq!(aura.maximum_uncle_count(100), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="counter is too high")]
|
||||
fn test_counter_increment_too_high() {
|
||||
use super::Step;
|
||||
let step = Step {
|
||||
calibrate: false,
|
||||
inner: AtomicUsize::new(::std::usize::MAX),
|
||||
duration: 1,
|
||||
};
|
||||
step.increment();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="counter is too high")]
|
||||
fn test_counter_duration_remaining_too_high() {
|
||||
use super::Step;
|
||||
let step = Step {
|
||||
calibrate: false,
|
||||
inner: AtomicUsize::new(::std::usize::MAX),
|
||||
duration: 1,
|
||||
};
|
||||
step.duration_remaining();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="authority_round: step duration can't be zero")]
|
||||
fn test_step_duration_zero() {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
step_duration: 0,
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 0,
|
||||
maximum_uncle_count: 0,
|
||||
block_reward: Default::default(),
|
||||
eip155_transition: 0,
|
||||
registrar: Default::default(),
|
||||
gas_limit_bound_divisor: 5.into(),
|
||||
};
|
||||
|
||||
AuthorityRound::new(Default::default(), params, Default::default()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ impl Engine for BasicAuthority {
|
||||
}
|
||||
|
||||
/// Attempt to seal the block internally.
|
||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||
let header = block.header();
|
||||
let author = header.author();
|
||||
if self.validators.contains(header.parent_hash(), author) {
|
||||
@@ -320,7 +320,7 @@ mod tests {
|
||||
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![], false).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) {
|
||||
assert!(b.try_seal(engine, seal).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use std::collections::BTreeMap;
|
||||
use util::{Address, HashMap};
|
||||
use builtin::Builtin;
|
||||
use engines::{Engine, Seal};
|
||||
use header::Header;
|
||||
use spec::CommonParams;
|
||||
use block::ExecutedBlock;
|
||||
|
||||
@@ -58,8 +59,8 @@ impl Engine for InstantSeal {
|
||||
|
||||
fn seals_internally(&self) -> Option<bool> { Some(true) }
|
||||
|
||||
fn generate_seal(&self, _block: &ExecutedBlock) -> Seal {
|
||||
Seal::Regular(Vec::new())
|
||||
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||
if block.fields().transactions.is_empty() { Seal::None } else { Seal::Regular(Vec::new()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ mod tests {
|
||||
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![], false).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) {
|
||||
assert!(b.try_seal(engine, seal).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,8 @@ pub trait Engine : Sync + Send {
|
||||
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
|
||||
fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size }
|
||||
/// Maximum number of uncles a block is allowed to declare.
|
||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||
|
||||
/// The number of generations back that uncles can be.
|
||||
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||
/// The nonce with which accounts begin at given block.
|
||||
@@ -242,7 +243,10 @@ pub trait Engine : Sync + Send {
|
||||
///
|
||||
/// This operation is synchronous and may (quite reasonably) not be available, in which None will
|
||||
/// be returned.
|
||||
fn generate_seal(&self, _block: &ExecutedBlock) -> Seal { Seal::None }
|
||||
///
|
||||
/// It is fine to require access to state or a full client for this function, since
|
||||
/// light clients do not generate seals.
|
||||
fn generate_seal(&self, _block: &ExecutedBlock, _parent: &Header) -> Seal { Seal::None }
|
||||
|
||||
/// Phase 1 quick block verification. Only does checks that are cheap. `block` (the header's full block)
|
||||
/// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import.
|
||||
|
||||
@@ -57,6 +57,8 @@ impl Engine for NullEngine {
|
||||
&self.builtins
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||
|
||||
fn schedule(&self, _block_number: BlockNumber) -> Schedule {
|
||||
Schedule::new_homestead()
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ impl Engine for Tendermint {
|
||||
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
|
||||
|
||||
fn maximum_uncle_count(&self) -> usize { 0 }
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||
|
||||
fn maximum_uncle_age(&self) -> usize { 0 }
|
||||
|
||||
@@ -427,7 +427,10 @@ impl Engine for Tendermint {
|
||||
}
|
||||
|
||||
/// Attempt to seal generate a proposal seal.
|
||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||
///
|
||||
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
||||
/// `Seal::None` will be returned.
|
||||
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||
let header = block.header();
|
||||
let author = header.author();
|
||||
// Only proposer can generate seal if None was generated.
|
||||
@@ -681,7 +684,7 @@ mod tests {
|
||||
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![], false).unwrap();
|
||||
let b = b.close();
|
||||
if let Seal::Proposal(seal) = spec.engine.generate_seal(b.block()) {
|
||||
if let Seal::Proposal(seal) = spec.engine.generate_seal(b.block(), &genesis_header) {
|
||||
(b, seal)
|
||||
} else {
|
||||
panic!()
|
||||
|
||||
@@ -159,22 +159,36 @@ mod tests {
|
||||
|
||||
// Make sure reporting can be done.
|
||||
client.miner().set_gas_floor_target(1_000_000.into());
|
||||
|
||||
client.miner().set_engine_signer(v1, "".into()).unwrap();
|
||||
|
||||
// Check a block that is a bit in future, reject it but don't report the validator.
|
||||
let mut header = Header::default();
|
||||
let seal = vec![encode(&5u8).into_vec(), encode(&(&H520::default() as &[u8])).into_vec()];
|
||||
header.set_seal(seal);
|
||||
header.set_author(v1);
|
||||
header.set_number(2);
|
||||
header.set_parent_hash(client.chain_info().best_block_hash);
|
||||
assert!(client.engine().verify_block_external(&header, None).is_err());
|
||||
client.engine().step();
|
||||
assert_eq!(client.chain_info().best_block_number, 0);
|
||||
|
||||
// Now create one that is more in future. That one should be rejected and validator should be reported.
|
||||
let mut header = Header::default();
|
||||
let seal = vec![encode(&8u8).into_vec(), encode(&(&H520::default() as &[u8])).into_vec()];
|
||||
header.set_seal(seal);
|
||||
header.set_author(v1);
|
||||
header.set_number(2);
|
||||
header.set_parent_hash(client.chain_info().best_block_hash);
|
||||
// `reportBenign` when the designated proposer releases block from the future (bad clock).
|
||||
assert!(client.engine().verify_block_external(&header, None).is_err());
|
||||
// Seal a block.
|
||||
client.engine().step();
|
||||
assert_eq!(client.chain_info().best_block_number, 1);
|
||||
// Check if the unresponsive validator is `disliked`.
|
||||
assert_eq!(client.call_contract(BlockId::Latest, validator_contract, "d8f2e0bf".from_hex().unwrap()).unwrap().to_hex(), "0000000000000000000000007d577a597b2742b498cb5cf0c26cdcd726d39e6e");
|
||||
assert_eq!(
|
||||
client.call_contract(BlockId::Latest, validator_contract, "d8f2e0bf".from_hex().unwrap()).unwrap().to_hex(),
|
||||
"0000000000000000000000007d577a597b2742b498cb5cf0c26cdcd726d39e6e"
|
||||
);
|
||||
// Simulate a misbehaving validator by handling a double proposal.
|
||||
let header = client.best_block_header().decode();
|
||||
assert!(client.engine().verify_block_family(&header, &header, None).is_err());
|
||||
|
||||
@@ -157,6 +157,8 @@ pub enum BlockError {
|
||||
InvalidReceiptsRoot(Mismatch<H256>),
|
||||
/// Timestamp header field is invalid.
|
||||
InvalidTimestamp(OutOfBounds<u64>),
|
||||
/// Timestamp header field is too far in future.
|
||||
TemporarilyInvalid(OutOfBounds<u64>),
|
||||
/// Log bloom header field is invalid.
|
||||
InvalidLogBloom(Mismatch<LogBloom>),
|
||||
/// Parent hash field of header is invalid; this is an invalid error indicating a logic flaw in the codebase.
|
||||
@@ -202,6 +204,7 @@ impl fmt::Display for BlockError {
|
||||
InvalidGasLimit(ref oob) => format!("Invalid gas limit: {}", oob),
|
||||
InvalidReceiptsRoot(ref mis) => format!("Invalid receipts trie root in header: {}", mis),
|
||||
InvalidTimestamp(ref oob) => format!("Invalid timestamp in header: {}", oob),
|
||||
TemporarilyInvalid(ref oob) => format!("Future timestamp in header: {}", oob),
|
||||
InvalidLogBloom(ref oob) => format!("Invalid log bloom in header: {}", oob),
|
||||
InvalidParentHash(ref mis) => format!("Invalid parent hash: {}", mis),
|
||||
InvalidNumber(ref mis) => format!("Invalid number in header: {}", mis),
|
||||
|
||||
@@ -217,7 +217,7 @@ impl Engine for Arc<Ethash> {
|
||||
} else if block_number < self.ethash_params.eip150_transition {
|
||||
Schedule::new_homestead()
|
||||
} else {
|
||||
/// There's no max_code_size transition so we tie it to eip161abc
|
||||
// There's no max_code_size transition so we tie it to eip161abc
|
||||
let max_code_size = if block_number >= self.ethash_params.eip161abc_transition { self.ethash_params.max_code_size as usize } else { usize::max_value() };
|
||||
let mut schedule = Schedule::new_post_eip150(
|
||||
max_code_size,
|
||||
@@ -238,6 +238,8 @@ impl Engine for Arc<Ethash> {
|
||||
}
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, mut gas_ceil_target: U256) {
|
||||
let difficulty = self.calculate_difficulty(header, parent);
|
||||
if header.number() >= self.ethash_params.max_gas_limit_transition && gas_ceil_target > self.ethash_params.max_gas_limit {
|
||||
|
||||
@@ -31,7 +31,7 @@ use std::path::Path;
|
||||
use super::spec::*;
|
||||
|
||||
/// Most recent fork block that we support on Mainnet.
|
||||
pub const FORK_SUPPORTED_FOUNDATION: u64 = 2675000;
|
||||
pub const FORK_SUPPORTED_FOUNDATION: u64 = 4370000;
|
||||
|
||||
/// Most recent fork block that we support on Ropsten.
|
||||
pub const FORK_SUPPORTED_ROPSTEN: u64 = 10;
|
||||
|
||||
@@ -234,7 +234,6 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
|
||||
Ok(FinalizationResult{ gas_left, apply_state: false, return_data }) => {
|
||||
ContractCreateResult::Reverted(gas_left, return_data)
|
||||
},
|
||||
Err(evm::Error::MutableCallInStaticContext) => ContractCreateResult::FailedInStaticCall,
|
||||
_ => ContractCreateResult::Failed,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,7 +499,13 @@ impl Miner {
|
||||
fn seal_and_import_block_internally(&self, chain: &MiningBlockChainClient, block: ClosedBlock) -> bool {
|
||||
if !block.transactions().is_empty() || self.forced_sealing() || Instant::now() > *self.next_mandatory_reseal.read() {
|
||||
trace!(target: "miner", "seal_block_internally: attempting internal seal.");
|
||||
match self.engine.generate_seal(block.block()) {
|
||||
|
||||
let parent_header = match chain.block_header(BlockId::Hash(*block.header().parent_hash())) {
|
||||
Some(hdr) => hdr.decode(),
|
||||
None => return false,
|
||||
};
|
||||
|
||||
match self.engine.generate_seal(block.block(), &parent_header) {
|
||||
// Save proposal for later seal submission and broadcast it.
|
||||
Seal::Proposal(seal) => {
|
||||
trace!(target: "miner", "Received a Proposal seal.");
|
||||
@@ -621,10 +627,6 @@ impl Miner {
|
||||
condition: Option<TransactionCondition>,
|
||||
transaction_queue: &mut BanningTransactionQueue,
|
||||
) -> Vec<Result<TransactionImportResult, Error>> {
|
||||
let accounts = self.accounts.as_ref()
|
||||
.and_then(|provider| provider.accounts().ok())
|
||||
.map(|accounts| accounts.into_iter().collect::<HashSet<_>>());
|
||||
|
||||
let best_block_header = client.best_block_header().decode();
|
||||
let insertion_time = client.chain_info().best_block_number;
|
||||
|
||||
@@ -643,8 +645,8 @@ impl Miner {
|
||||
Err(e)
|
||||
},
|
||||
Ok(transaction) => {
|
||||
let origin = accounts.as_ref().and_then(|accounts| {
|
||||
match accounts.contains(&transaction.sender()) {
|
||||
let origin = self.accounts.as_ref().and_then(|accounts| {
|
||||
match accounts.has_account(transaction.sender()).unwrap_or(false) {
|
||||
true => Some(TransactionOrigin::Local),
|
||||
false => None,
|
||||
}
|
||||
|
||||
@@ -500,7 +500,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
Err(err) => {
|
||||
match err {
|
||||
// Don't mark future blocks as bad.
|
||||
Error::Block(BlockError::InvalidTimestamp(ref e)) if e.max.is_some() => {},
|
||||
Error::Block(BlockError::TemporarilyInvalid(_)) => {},
|
||||
_ => {
|
||||
self.verification.bad.lock().insert(h.clone());
|
||||
}
|
||||
|
||||
@@ -110,9 +110,14 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &
|
||||
engine.verify_block_family(&header, &parent, Some(bytes))?;
|
||||
|
||||
let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?;
|
||||
let max_uncles = engine.maximum_uncle_count(header.number());
|
||||
if num_uncles != 0 {
|
||||
if num_uncles > engine.maximum_uncle_count() {
|
||||
return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles })));
|
||||
if num_uncles > max_uncles {
|
||||
return Err(From::from(BlockError::TooManyUncles(OutOfBounds {
|
||||
min: None,
|
||||
max: Some(max_uncles),
|
||||
found: num_uncles,
|
||||
})));
|
||||
}
|
||||
|
||||
let mut excluded = HashSet::new();
|
||||
@@ -225,11 +230,20 @@ pub fn verify_header_params(header: &Header, engine: &Engine, is_full: bool) ->
|
||||
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
|
||||
}
|
||||
if is_full {
|
||||
let max_time = get_time().sec as u64 + 30;
|
||||
if header.timestamp() > max_time {
|
||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
|
||||
const ACCEPTABLE_DRIFT_SECS: u64 = 15;
|
||||
let max_time = get_time().sec as u64 + ACCEPTABLE_DRIFT_SECS;
|
||||
let invalid_threshold = max_time + ACCEPTABLE_DRIFT_SECS * 9;
|
||||
let timestamp = header.timestamp();
|
||||
|
||||
if timestamp > invalid_threshold {
|
||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp })))
|
||||
}
|
||||
|
||||
if timestamp > max_time {
|
||||
return Err(From::from(BlockError::TemporarilyInvalid(OutOfBounds { max: Some(max_time), min: None, found: timestamp })))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -293,11 +307,13 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fail_timestamp(result: Result<(), Error>) {
|
||||
fn check_fail_timestamp(result: Result<(), Error>, temp: bool) {
|
||||
let name = if temp { "TemporarilyInvalid" } else { "InvalidTimestamp" };
|
||||
match result {
|
||||
Err(Error::Block(BlockError::InvalidTimestamp(_))) => (),
|
||||
Err(other) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: {:?}", other),
|
||||
Ok(_) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: Ok"),
|
||||
Err(Error::Block(BlockError::InvalidTimestamp(_))) if !temp => (),
|
||||
Err(Error::Block(BlockError::TemporarilyInvalid(_))) if temp => (),
|
||||
Err(other) => panic!("Block verification failed.\nExpected: {}\nGot: {:?}", name, other),
|
||||
Ok(_) => panic!("Block verification failed.\nExpected: {}\nGot: Ok", name),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,11 +572,17 @@ mod tests {
|
||||
|
||||
header = good.clone();
|
||||
header.set_timestamp(2450000000);
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), false);
|
||||
|
||||
header = good.clone();
|
||||
header.set_timestamp(get_time().sec as u64 + 40);
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||
header.set_timestamp(get_time().sec as u64 + 20);
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), true);
|
||||
|
||||
header = good.clone();
|
||||
header.set_timestamp(get_time().sec as u64 + 10);
|
||||
header.set_uncles_hash(good_uncles_hash.clone());
|
||||
header.set_transactions_root(good_transactions_root.clone());
|
||||
check_ok(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||
|
||||
header = good.clone();
|
||||
header.set_number(9);
|
||||
@@ -571,7 +593,7 @@ mod tests {
|
||||
let mut bad_uncles = good_uncles.clone();
|
||||
bad_uncles.push(good_uncle1.clone());
|
||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &bad_uncles), engine, &bc),
|
||||
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count()), min: None, found: bad_uncles.len() }));
|
||||
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count(header.number())), min: None, found: bad_uncles.len() }));
|
||||
|
||||
header = good.clone();
|
||||
bad_uncles = vec![ good_uncle1.clone(), good_uncle1.clone() ];
|
||||
|
||||
@@ -122,6 +122,13 @@ impl<T> DiskDirectory<T> where T: KeyFileManager {
|
||||
Ok(hasher.finish())
|
||||
}
|
||||
|
||||
fn last_modification_date(&self) -> Result<u64, Error> {
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
let duration = fs::metadata(&self.path)?.modified()?.duration_since(UNIX_EPOCH).unwrap_or(Duration::default());
|
||||
let timestamp = duration.as_secs() ^ (duration.subsec_nanos() as u64);
|
||||
Ok(timestamp)
|
||||
}
|
||||
|
||||
/// all accounts found in keys directory
|
||||
fn files_content(&self) -> Result<HashMap<PathBuf, SafeAccount>, Error> {
|
||||
// it's not done using one iterator cause
|
||||
@@ -226,7 +233,7 @@ impl<T> KeyDirectory for DiskDirectory<T> where T: KeyFileManager {
|
||||
}
|
||||
|
||||
fn unique_repr(&self) -> Result<u64, Error> {
|
||||
self.files_hash()
|
||||
self.last_modification_date()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ use std::collections::{BTreeMap, HashMap};
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use std::time::{Instant, Duration};
|
||||
|
||||
use crypto::KEY_ITERATIONS;
|
||||
use random::Random;
|
||||
@@ -28,6 +29,8 @@ use presale::PresaleWallet;
|
||||
use json::{self, Uuid, OpaqueKeyFile};
|
||||
use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret};
|
||||
|
||||
const REFRESH_TIME_SEC: u64 = 5;
|
||||
|
||||
/// Accounts store.
|
||||
pub struct EthStore {
|
||||
store: EthMultiStore,
|
||||
@@ -241,7 +244,12 @@ pub struct EthMultiStore {
|
||||
// order lock: cache, then vaults
|
||||
cache: RwLock<BTreeMap<StoreAccountRef, Vec<SafeAccount>>>,
|
||||
vaults: Mutex<HashMap<String, Box<VaultKeyDirectory>>>,
|
||||
dir_hash: Mutex<Option<u64>>,
|
||||
timestamp: Mutex<Timestamp>,
|
||||
}
|
||||
|
||||
struct Timestamp {
|
||||
dir_hash: Option<u64>,
|
||||
last_checked: Instant,
|
||||
}
|
||||
|
||||
impl EthMultiStore {
|
||||
@@ -257,20 +265,27 @@ impl EthMultiStore {
|
||||
vaults: Mutex::new(HashMap::new()),
|
||||
iterations: iterations,
|
||||
cache: Default::default(),
|
||||
dir_hash: Default::default(),
|
||||
timestamp: Mutex::new(Timestamp {
|
||||
dir_hash: None,
|
||||
last_checked: Instant::now(),
|
||||
}),
|
||||
};
|
||||
store.reload_accounts()?;
|
||||
Ok(store)
|
||||
}
|
||||
|
||||
fn reload_if_changed(&self) -> Result<(), Error> {
|
||||
let mut last_dir_hash = self.dir_hash.lock();
|
||||
let dir_hash = Some(self.dir.unique_repr()?);
|
||||
if *last_dir_hash == dir_hash {
|
||||
return Ok(())
|
||||
let mut last_timestamp = self.timestamp.lock();
|
||||
let now = Instant::now();
|
||||
if (now - last_timestamp.last_checked) > Duration::from_secs(REFRESH_TIME_SEC) {
|
||||
let dir_hash = Some(self.dir.unique_repr()?);
|
||||
last_timestamp.last_checked = now;
|
||||
if last_timestamp.dir_hash == dir_hash {
|
||||
return Ok(())
|
||||
}
|
||||
self.reload_accounts()?;
|
||||
last_timestamp.dir_hash = dir_hash;
|
||||
}
|
||||
self.reload_accounts()?;
|
||||
*last_dir_hash = dir_hash;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -451,11 +466,11 @@ impl SimpleSecretStore for EthMultiStore {
|
||||
}
|
||||
|
||||
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error> {
|
||||
use std::collections::Bound;
|
||||
self.reload_if_changed()?;
|
||||
self.cache.read().keys()
|
||||
.find(|r| &r.address == address)
|
||||
.cloned()
|
||||
.ok_or(Error::InvalidAccount)
|
||||
let cache = self.cache.read();
|
||||
let mut r = cache.range((Bound::Included(*address), Bound::Included(*address)));
|
||||
r.next().ok_or(Error::InvalidAccount).map(|(k, _)| k.clone())
|
||||
}
|
||||
|
||||
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error> {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::PathBuf;
|
||||
use std::cmp::Ordering;
|
||||
use ethkey::{Address, Message, Signature, Secret, Public};
|
||||
use Error;
|
||||
use json::{Uuid, OpaqueKeyFile};
|
||||
@@ -32,12 +33,24 @@ pub enum SecretVaultRef {
|
||||
}
|
||||
|
||||
/// Stored account reference
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Ord)]
|
||||
pub struct StoreAccountRef {
|
||||
/// Vault reference
|
||||
pub vault: SecretVaultRef,
|
||||
/// Account address
|
||||
pub address: Address,
|
||||
/// Vault reference
|
||||
pub vault: SecretVaultRef,
|
||||
}
|
||||
|
||||
impl PartialOrd for StoreAccountRef {
|
||||
fn partial_cmp(&self, other: &StoreAccountRef) -> Option<Ordering> {
|
||||
Some(self.address.cmp(&other.address).then_with(|| self.vault.cmp(&other.vault)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::borrow::Borrow<Address> for StoreAccountRef {
|
||||
fn borrow(&self) -> &Address {
|
||||
&self.address
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple Secret Store API
|
||||
|
||||
@@ -17,35 +17,35 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { walletSourceURL } from '~/contracts/code/wallet';
|
||||
// import { walletSourceURL } from '~/contracts/code/wallet';
|
||||
import { RadioButtons } from '~/ui';
|
||||
|
||||
const TYPES = [
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.label'
|
||||
defaultMessage='Multi-Sig wallet'
|
||||
/>
|
||||
),
|
||||
key: 'MULTISIG',
|
||||
description: (
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.description'
|
||||
defaultMessage='Create/Deploy a {link} Wallet'
|
||||
values={ {
|
||||
link: (
|
||||
<a href={ walletSourceURL } target='_blank'>
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.link'
|
||||
defaultMessage='standard multi-signature'
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
} }
|
||||
/>
|
||||
)
|
||||
},
|
||||
// {
|
||||
// label: (
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.label'
|
||||
// defaultMessage='Multi-Sig wallet'
|
||||
// />
|
||||
// ),
|
||||
// key: 'MULTISIG',
|
||||
// description: (
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.description'
|
||||
// defaultMessage='Create/Deploy a {link} Wallet'
|
||||
// values={ {
|
||||
// link: (
|
||||
// <a href={ walletSourceURL } target='_blank'>
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.link'
|
||||
// defaultMessage='standard multi-signature'
|
||||
// />
|
||||
// </a>
|
||||
// )
|
||||
// } }
|
||||
// />
|
||||
// )
|
||||
// },
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
|
||||
@@ -59,7 +59,7 @@ const STEPS = {
|
||||
export default class CreateWalletStore {
|
||||
@observable step = null;
|
||||
@observable txhash = null;
|
||||
@observable walletType = 'MULTISIG';
|
||||
@observable walletType = 'WATCH'; // 'MULTISIG';
|
||||
|
||||
@observable wallet = {
|
||||
account: '',
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct AuthorityRoundParams {
|
||||
/// Gas limit divisor.
|
||||
#[serde(rename="gasLimitBoundDivisor")]
|
||||
pub gas_limit_bound_divisor: Uint,
|
||||
/// Block duration.
|
||||
/// Block duration, in seconds.
|
||||
#[serde(rename="stepDuration")]
|
||||
pub step_duration: Uint,
|
||||
/// Valid authorities
|
||||
@@ -52,6 +52,12 @@ pub struct AuthorityRoundParams {
|
||||
/// Whether transitions should be immediate.
|
||||
#[serde(rename="immediateTransitions")]
|
||||
pub immediate_transitions: Option<bool>,
|
||||
/// Block at which maximum uncle count should be considered.
|
||||
#[serde(rename="maximumUncleCountTransition")]
|
||||
pub maximum_uncle_count_transition: Option<Uint>,
|
||||
/// Maximum number of accepted uncles.
|
||||
#[serde(rename="maximumUncleCount")]
|
||||
pub maximum_uncle_count: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Authority engine deserialization.
|
||||
@@ -84,6 +90,8 @@ mod tests {
|
||||
"startStep" : 24,
|
||||
"eip155Transition": "0x42",
|
||||
"validateStepTransition": 150
|
||||
"maximumUncleCountTransition": 10000000,
|
||||
"maximumUncleCount": 5
|
||||
}
|
||||
}"#;
|
||||
|
||||
@@ -96,5 +104,8 @@ mod tests {
|
||||
assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24))));
|
||||
assert_eq!(deserialized.params.eip155_transition, Some(Uint(U256::from(0x42))));
|
||||
assert_eq!(deserialized.params.immediate_transitions, None);
|
||||
|
||||
assert_eq!(deserialized.params.maximum_uncle_count_transition, Some(Uint(10_000_000.into())));
|
||||
assert_eq!(deserialized.params.maximum_uncle_count, Some(Uint(5.into())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
<string>1.7.6</string>
|
||||
<string>1.7.12</string>
|
||||
</dict>
|
||||
<key>UUID</key>
|
||||
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
|
||||
!define VERSIONMAJOR 1
|
||||
!define VERSIONMINOR 7
|
||||
!define VERSIONBUILD 6
|
||||
!define VERSIONBUILD 12
|
||||
!define ARGS "--warp"
|
||||
!define FIRST_START_ARGS "ui --warp --mode=passive"
|
||||
|
||||
|
||||
@@ -584,8 +584,12 @@ fn execute_export(cmd: ExportBlockchain) -> Result<(), String> {
|
||||
}
|
||||
let b = client.block(BlockId::Number(i)).ok_or("Error exporting incomplete chain")?.into_inner();
|
||||
match format {
|
||||
DataFormat::Binary => { out.write(&b).expect("Couldn't write to stream."); }
|
||||
DataFormat::Hex => { out.write_fmt(format_args!("{}", b.pretty())).expect("Couldn't write to stream."); }
|
||||
DataFormat::Binary => {
|
||||
out.write(&b).map_err(|e| format!("Couldn't write to stream. Cause: {}", e))?;
|
||||
}
|
||||
DataFormat::Hex => {
|
||||
out.write_fmt(format_args!("{}", b.pretty())).map_err(|e| format!("Couldn't write to stream. Cause: {}", e))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -761,7 +761,8 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn cors(cors: Option<&String>) -> Option<Vec<String>> {
|
||||
cors.map(|ref c| c.split(',').map(Into::into).collect())
|
||||
// Never return `None` here (enables CORS for all hosts).
|
||||
Some(cors.map(|ref c| c.split(',').map(Into::into).collect()).unwrap_or_default())
|
||||
}
|
||||
|
||||
fn rpc_cors(&self) -> Option<Vec<String>> {
|
||||
@@ -1490,7 +1491,7 @@ mod tests {
|
||||
let conf2 = parse(&["parity", "--ipfs-api-cors", "http://parity.io,http://something.io"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.ipfs_cors(), None);
|
||||
assert_eq!(conf0.ipfs_cors(), Some(vec![]));
|
||||
assert_eq!(conf1.ipfs_cors(), Some(vec!["*".into()]));
|
||||
assert_eq!(conf2.ipfs_cors(), Some(vec!["http://parity.io".into(),"http://something.io".into()]));
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ impl Default for Configuration {
|
||||
enabled: false,
|
||||
port: 5001,
|
||||
interface: "127.0.0.1".into(),
|
||||
cors: None,
|
||||
hosts: Some(Vec::new()),
|
||||
cors: Some(vec![]),
|
||||
hosts: Some(vec![]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ impl Default for HttpConfiguration {
|
||||
interface: "127.0.0.1".into(),
|
||||
port: 8545,
|
||||
apis: ApiSet::UnsafeContext,
|
||||
cors: None,
|
||||
hosts: Some(Vec::new()),
|
||||
cors: Some(vec![]),
|
||||
hosts: Some(vec![]),
|
||||
server_threads: None,
|
||||
processing_threads: 0,
|
||||
}
|
||||
@@ -95,7 +95,7 @@ impl From<UiConfiguration> for HttpConfiguration {
|
||||
interface: conf.interface,
|
||||
port: conf.port,
|
||||
apis: rpc_apis::ApiSet::UnsafeContext,
|
||||
cors: None,
|
||||
cors: Some(vec![]),
|
||||
hosts: conf.hosts,
|
||||
server_threads: None,
|
||||
processing_threads: 0,
|
||||
|
||||
@@ -19,4 +19,5 @@ export TARGETS="
|
||||
-p ethcore-ipc-tests \
|
||||
-p ethcore-ipc-nano \
|
||||
-p ethcore-light \
|
||||
-p evm \
|
||||
-p parity"
|
||||
|
||||
@@ -3,7 +3,7 @@ description = "Ethcore utility library"
|
||||
homepage = "http://parity.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore-util"
|
||||
version = "1.7.6"
|
||||
version = "1.7.12"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user