Compare commits
19 Commits
v1.9.3
...
v1.9.5-ci5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a667de45fe | ||
|
|
ff71e787db | ||
|
|
0940fe91e5 | ||
|
|
f205490fb0 | ||
|
|
dc8d6d819e | ||
|
|
feef2f8791 | ||
|
|
3c15a501ca | ||
|
|
b7682dabf4 | ||
|
|
2acfdfc977 | ||
|
|
a6d732ed14 | ||
|
|
a9a58d230e | ||
|
|
edbff0d34d | ||
|
|
94defd7f82 | ||
|
|
362fb1dfed | ||
|
|
caaac78971 | ||
|
|
1762e82676 | ||
|
|
6f21a32b2b | ||
|
|
86f6cea29d | ||
|
|
3d6670972f |
@@ -9,12 +9,10 @@ variables:
|
||||
CARGOFLAGS: ""
|
||||
CI_SERVER_NAME: "GitLab CI"
|
||||
LIBSSL: "libssl1.0.0 (>=1.0.0)"
|
||||
CARGO_HOME: $CI_PROJECT_DIR/cargo
|
||||
cache:
|
||||
key: "$CI_BUILD_STAGE-$CI_BUILD_REF_NAME"
|
||||
paths:
|
||||
- target/
|
||||
- cargo/
|
||||
untracked: true
|
||||
linux-stable:
|
||||
stage: build
|
||||
@@ -133,7 +131,7 @@ linux-aarch64:
|
||||
name: "aarch64-unknown-linux-gnu_parity"
|
||||
linux-snap:
|
||||
stage: build
|
||||
image: snapcore/snapcraft:stable
|
||||
image: parity/snapcraft:gitlab-ci
|
||||
only:
|
||||
- stable
|
||||
- beta
|
||||
|
||||
247
Cargo.lock
generated
247
Cargo.lock
generated
@@ -106,7 +106,7 @@ name = "base64"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -115,7 +115,7 @@ name = "bigint"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -127,7 +127,7 @@ name = "bincode"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -183,22 +183,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bloomchain"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.2.1",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bn"
|
||||
version = "0.4.4"
|
||||
source = "git+https://github.com/paritytech/bn#c9831a8d10d55045692394cbc10efe0321ddb16f"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.16 (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 = "byteorder"
|
||||
version = "1.1.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -206,7 +210,7 @@ name = "bytes"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -270,9 +274,10 @@ name = "common-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bloomable 0.1.0",
|
||||
"ethbloom 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethjson 0.1.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
@@ -454,7 +459,7 @@ dependencies = [
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -470,15 +475,25 @@ dependencies = [
|
||||
"primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethbloom"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bloomable 0.1.0",
|
||||
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bloomchain 0.2.0",
|
||||
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"common-types 0.1.0",
|
||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethash 1.9.0",
|
||||
@@ -489,7 +504,7 @@ dependencies = [
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-stratum 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.3.0",
|
||||
"ethstore 0.2.0",
|
||||
@@ -604,7 +619,7 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -678,19 +693,19 @@ dependencies = [
|
||||
"snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-secretstore"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.3.0",
|
||||
"ethsync 1.9.0",
|
||||
@@ -709,7 +724,7 @@ dependencies = [
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -736,7 +751,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-util"
|
||||
version = "1.9.0"
|
||||
version = "1.9.5"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
@@ -756,8 +771,8 @@ dependencies = [
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethkey 0.3.0",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -775,7 +790,7 @@ dependencies = [
|
||||
name = "ethkey"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
@@ -785,7 +800,7 @@ dependencies = [
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"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)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -814,6 +829,7 @@ dependencies = [
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -823,9 +839,10 @@ dependencies = [
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -854,7 +871,7 @@ dependencies = [
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethkey 0.3.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -878,7 +895,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"evmjit 1.9.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
@@ -898,7 +915,7 @@ dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethjson 0.1.0",
|
||||
"evm 0.1.0",
|
||||
"panic_hook 0.1.0",
|
||||
@@ -913,7 +930,7 @@ dependencies = [
|
||||
name = "evmjit"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -972,6 +989,20 @@ dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.16"
|
||||
@@ -1333,7 +1364,7 @@ dependencies = [
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws 0.7.1 (git+https://github.com/tomusdrw/ws-rs)",
|
||||
"ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1343,7 +1374,7 @@ dependencies = [
|
||||
"cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1421,7 +1452,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1529,6 +1560,11 @@ dependencies = [
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memorydb"
|
||||
version = "0.1.1"
|
||||
@@ -1664,7 +1700,7 @@ version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1679,7 +1715,7 @@ dependencies = [
|
||||
name = "native-contracts"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1719,7 +1755,7 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1755,7 +1791,7 @@ name = "ntp"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1913,7 +1949,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity"
|
||||
version = "1.9.3"
|
||||
version = "1.9.5"
|
||||
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)",
|
||||
@@ -1933,7 +1969,7 @@ dependencies = [
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-secretstore 1.0.0",
|
||||
"ethcore-stratum 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethkey 0.3.0",
|
||||
"ethsync 1.9.0",
|
||||
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1961,7 +1997,7 @@ dependencies = [
|
||||
"parity-rpc 1.9.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
"parity-updater 1.9.0",
|
||||
"parity-version 1.9.3",
|
||||
"parity-version 1.9.5",
|
||||
"parity-whisper 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
@@ -1993,7 +2029,7 @@ dependencies = [
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2009,7 +2045,7 @@ dependencies = [
|
||||
"parity-hash-fetch 1.9.0",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-ui 1.9.0",
|
||||
"parity-version 1.9.3",
|
||||
"parity-version 1.9.5",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2055,7 +2091,7 @@ dependencies = [
|
||||
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
@@ -2105,7 +2141,7 @@ name = "parity-machine"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2131,7 +2167,7 @@ dependencies = [
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.3.0",
|
||||
@@ -2157,7 +2193,7 @@ dependencies = [
|
||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-updater 1.9.0",
|
||||
"parity-version 1.9.3",
|
||||
"parity-version 1.9.5",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2170,7 +2206,7 @@ dependencies = [
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stats 0.1.0",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
@@ -2216,8 +2252,8 @@ version = "1.9.0"
|
||||
dependencies = [
|
||||
"parity-ui-dev 1.9.0",
|
||||
"parity-ui-old-dev 1.9.0",
|
||||
"parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git)",
|
||||
"parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git)",
|
||||
"parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git)",
|
||||
"parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -2238,7 +2274,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-old-precompiled"
|
||||
version = "1.9.0"
|
||||
source = "git+https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git#54398b761c19fbdfb47e3f2fc21eddec92f8ca40"
|
||||
source = "git+https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git#4a84c8a0f15c048e37950d1c08d1b364e8c3d401"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2246,7 +2282,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.9.0"
|
||||
source = "git+https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git#266a67a3a0112efcdcfdd8b1ef0721a28575bbc7"
|
||||
source = "git+https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git#f1e0969378f00c8528062a9aebb7408f3dbd47de"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2259,13 +2295,13 @@ dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethsync 1.9.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.9.0",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-version 1.9.3",
|
||||
"parity-version 1.9.5",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2274,7 +2310,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-version"
|
||||
version = "1.9.3"
|
||||
version = "1.9.5"
|
||||
dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"rlp 0.2.1",
|
||||
@@ -2286,10 +2322,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-wasm"
|
||||
version = "0.23.0"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2299,7 +2335,7 @@ name = "parity-whisper"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcrypto 0.1.0",
|
||||
@@ -2320,7 +2356,7 @@ dependencies = [
|
||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2586,6 +2622,16 @@ dependencies = [
|
||||
"magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "0.7.1"
|
||||
@@ -2674,7 +2720,7 @@ dependencies = [
|
||||
name = "rlp"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2739,7 +2785,7 @@ name = "rpc-cli"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc 1.9.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
@@ -3026,11 +3072,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "0.1.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
@@ -3171,8 +3214,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "1.3.1"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-core"
|
||||
@@ -3461,11 +3507,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "vm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"common-types 0.1.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"ethjson 0.1.0",
|
||||
"keccak-hash 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3482,39 +3528,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "wasm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcore-util 1.9.5",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
|
||||
"wasmi 0.0.0 (git+https://github.com/pepyakin/wasmi)",
|
||||
"wasmi 0.0.0 (git+https://github.com/paritytech/wasmi)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/wasm-utils#6fdc1c4ed47a6acb0a4774da505a416dd637bc6d"
|
||||
source = "git+https://github.com/paritytech/wasm-utils#9527b969a4928f6293369380defc7982493a678c"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmi"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/pepyakin/wasmi#551c99273042deaad869c17798060e2212deacab"
|
||||
source = "git+https://github.com/paritytech/wasmi#7c88c6ad651ec6a6aa00b08e61c70853161a0a99"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3522,17 +3569,36 @@ name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ws"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/tomusdrw/ws-rs#f8306a798b7541d64624299a83a2c934f173beed"
|
||||
version = "0.7.5"
|
||||
source = "git+https://github.com/tomusdrw/ws-rs#368ce39e2aa8700d568ca29dbacaecdf1bf749d1"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3608,9 +3674,8 @@ dependencies = [
|
||||
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d"
|
||||
"checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "<none>"
|
||||
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
|
||||
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
|
||||
"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6"
|
||||
"checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
@@ -3638,6 +3703,7 @@ dependencies = [
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
|
||||
"checksum ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819a3adef0413a2519cbd9a19a35dd1c20c7a0110705beaba8aa4aa87eda95f"
|
||||
"checksum ethbloom 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3d1d93b56bf23b8d38c71e4a5360607fc8e91d402ec20a7e90f4e896cfd21d2b"
|
||||
"checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5"
|
||||
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
|
||||
"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423"
|
||||
@@ -3645,6 +3711,8 @@ dependencies = [
|
||||
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "05a23db7bd162d4e8265968602930c476f688f0c180b44bdaf55e0cb2c687558"
|
||||
"checksum futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "77d49e7de8b91b20d6fda43eea906637eff18b96702eb6b2872df8bfab1ad2b5"
|
||||
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
||||
@@ -3697,6 +3765,7 @@ dependencies = [
|
||||
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
|
||||
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
||||
"checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"
|
||||
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
|
||||
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
|
||||
"checksum mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e3d709ffbb330e1566dc2f2a3c9b58a5ad4a381f740b810cd305dc3f089bc160"
|
||||
"checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae"
|
||||
@@ -3730,9 +3799,9 @@ dependencies = [
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "261c025c67ba416e9fe63aa9b3236520ce3c74cfbe43590c9cdcec4ccc8180e4"
|
||||
"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
|
||||
"checksum parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git)" = "<none>"
|
||||
"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git)" = "<none>"
|
||||
"checksum parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ba4b1d4236b76694f6ab8d8d00cdbe1e37c6dd1b5c803d26721f27e097d4d9"
|
||||
"checksum parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git)" = "<none>"
|
||||
"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git)" = "<none>"
|
||||
"checksum parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3c21b85fed4e8490e716b7fcb247185ec201f28845be6e749ab864401463c7"
|
||||
"checksum parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0dec124478845b142f68b446cbee953d14d4b41f1bc0425024417720dce693"
|
||||
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
|
||||
"checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412"
|
||||
@@ -3759,6 +3828,7 @@ dependencies = [
|
||||
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
|
||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
|
||||
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
|
||||
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
|
||||
@@ -3808,7 +3878,7 @@ dependencies = [
|
||||
"checksum spmc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd1f11d1fb5fd41834e55ce0b85a186efbf2f2afd9fdb09e2c8d72f9bff1ad1a"
|
||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b811576c12506ff3f6da145585dc833edc32ee34c9fc021127d90e8134cc05c"
|
||||
"checksum subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7f6353c2ee5407358d063a14cccc1630804527090a6fb5a9489ce4924280fb"
|
||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||
"checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e"
|
||||
@@ -3824,7 +3894,7 @@ dependencies = [
|
||||
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
||||
"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
|
||||
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
|
||||
"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292"
|
||||
"checksum tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58911ed5eb275a8fd2f1f0418ed360a42f59329864b64e1e95377a9024498c01"
|
||||
"checksum tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e85d419699ec4b71bfe35bbc25bb8771e52eff0471a7f75c853ad06e200b4f86"
|
||||
"checksum tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ab83e7adb5677e42e405fa4ceff75659d93c4d7d7dd22f52fcec59ee9f02af"
|
||||
"checksum tokio-named-pipes 0.1.0 (git+https://github.com/nikvolf/tokio-named-pipes)" = "<none>"
|
||||
@@ -3857,10 +3927,13 @@ dependencies = [
|
||||
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)" = "<none>"
|
||||
"checksum wasmi 0.0.0 (git+https://github.com/pepyakin/wasmi)" = "<none>"
|
||||
"checksum wasmi 0.0.0 (git+https://github.com/paritytech/wasmi)" = "<none>"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum ws 0.7.1 (git+https://github.com/tomusdrw/ws-rs)" = "<none>"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "<none>"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
|
||||
"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity"
|
||||
version = "1.9.3"
|
||||
version = "1.9.5"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
@@ -13,8 +13,8 @@ rustc_version = "0.1"
|
||||
parity-ui-dev = { path = "../../js", optional = true }
|
||||
parity-ui-old-dev = { path = "../../js-old", optional = true }
|
||||
# This is managed by the js/scripts/release.sh script on CI - keep it in a single line
|
||||
parity-ui-old-precompiled = { git = "https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git", optional = true }
|
||||
parity-ui-precompiled = { git = "https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git", optional = true }
|
||||
parity-ui-old-precompiled = { git = "https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git", optional = true }
|
||||
parity-ui-precompiled = { git = "https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git", optional = true }
|
||||
|
||||
[features]
|
||||
no-precompiled-js = ["parity-ui-dev", "parity-ui-old-dev"]
|
||||
|
||||
@@ -8,7 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
ansi_term = "0.9"
|
||||
bloomchain = "0.1"
|
||||
bloomchain = { path = "../util/bloomchain" }
|
||||
bn = { git = "https://github.com/paritytech/bn" }
|
||||
byteorder = "1.0"
|
||||
common-types = { path = "types" }
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x1",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0x0",
|
||||
"eip98Transition": "0xffffffffffffffff",
|
||||
"eip140Transition": "0x0",
|
||||
"eip211Transition": "0x0",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x1",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0x0",
|
||||
"eip98Transition": "0xffffffffffffffff",
|
||||
"eip140Transition": "0x0",
|
||||
"eip210Transition": "0x0",
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
"eip98Transition": "0x7fffffffffffffff",
|
||||
"eip86Transition": "0x7fffffffffffffff",
|
||||
"eip155Transition": "0x7fffffffffffffff",
|
||||
"maxCodeSize": 24576
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0x7fffffffffffffff"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
"eip98Transition": "0x7fffffffffffffff",
|
||||
"eip86Transition": "0x7fffffffffffffff",
|
||||
"eip155Transition": "0x7fffffffffffffff",
|
||||
"maxCodeSize": 24576
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0x0"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
|
||||
@@ -152,6 +152,7 @@
|
||||
"eip98Transition": "0x7fffffffffffff",
|
||||
"eip86Transition": "0x7fffffffffffff",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": 2675000,
|
||||
"eip140Transition": 4370000,
|
||||
"eip211Transition": 4370000,
|
||||
"eip214Transition": 4370000,
|
||||
|
||||
@@ -34,13 +34,16 @@
|
||||
"networkID" : "0x2A",
|
||||
"forkBlock": 4297256,
|
||||
"forkCanonHash": "0x0a66d93c2f727dca618fabaf70c39b37018c73d78b939d8b11efbbd09034778f",
|
||||
"validateReceiptsTransition" : 1000000,
|
||||
"eip155Transition": 1000000,
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": 6600000,
|
||||
"validateChainIdTransition": 1000000,
|
||||
"validateReceiptsTransition" : 1000000,
|
||||
"eip140Transition": 5067000,
|
||||
"eip211Transition": 5067000,
|
||||
"eip214Transition": 5067000,
|
||||
"eip658Transition": 5067000
|
||||
"eip658Transition": 5067000,
|
||||
"wasmActivationTransition": 6600000
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
"eip211Transition":"0x7fffffffffffff",
|
||||
"eip214Transition":"0x7fffffffffffff",
|
||||
"eip658Transition":"0x7fffffffffffff",
|
||||
"maxCodeSize":"0x6000"
|
||||
"maxCodeSize":"0x6000",
|
||||
"maxCodeSizeTransition": "0x7fffffffffffff"
|
||||
},
|
||||
"genesis":{
|
||||
"seal":{
|
||||
|
||||
161
ethcore/res/ethereum/mcip6_byz.json
Normal file
161
ethcore/res/ethereum/mcip6_byz.json
Normal file
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"name":"Musicoin Byzantium Test",
|
||||
"dataDir":"mcip6test",
|
||||
"engine":{
|
||||
"Ethash":{
|
||||
"params":{
|
||||
"minimumDifficulty":"0x020000",
|
||||
"difficultyBoundDivisor":"0x0800",
|
||||
"durationLimit":"0x0d",
|
||||
"homesteadTransition":"0x17",
|
||||
"eip100bTransition":"0x2a",
|
||||
"eip150Transition":"0x2a",
|
||||
"eip160Transition":"0x7fffffffffffff",
|
||||
"eip161abcTransition":"0x7fffffffffffff",
|
||||
"eip161dTransition":"0x7fffffffffffff",
|
||||
"eip649Transition":"0x2a",
|
||||
"blockReward":"0x1105a0185b50a80000",
|
||||
"mcip3Transition":"0x17",
|
||||
"mcip3MinerReward":"0xd8d726b7177a80000",
|
||||
"mcip3UbiReward":"0x2b5e3af16b1880000",
|
||||
"mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310",
|
||||
"mcip3DevReward":"0xc249fdd327780000",
|
||||
"mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536"
|
||||
}
|
||||
}
|
||||
},
|
||||
"params":{
|
||||
"gasLimitBoundDivisor":"0x0400",
|
||||
"registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D",
|
||||
"accountStartNonce":"0x00",
|
||||
"maximumExtraDataSize":"0x20",
|
||||
"minGasLimit":"0x1388",
|
||||
"networkID":"0x76740c",
|
||||
"forkBlock":"0x2b",
|
||||
"forkCanonHash":"0x23c3171e864a5d513a3ef85e4cf86dac4cc36b89e5b8e63bf0ebcca68b9e43c9",
|
||||
"eip86Transition":"0x7fffffffffffff",
|
||||
"eip98Transition":"0x7fffffffffffff",
|
||||
"eip140Transition":"0x2a",
|
||||
"eip155Transition":"0x2a",
|
||||
"eip211Transition":"0x2a",
|
||||
"eip214Transition":"0x2a",
|
||||
"eip658Transition":"0x2a",
|
||||
"maxCodeSize":"0x6000",
|
||||
"maxCodeSizeTransition": "0x7fffffffffffff"
|
||||
},
|
||||
"genesis":{
|
||||
"seal":{
|
||||
"ethereum":{
|
||||
"nonce":"0x000000000000002a",
|
||||
"mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578"
|
||||
}
|
||||
},
|
||||
"difficulty":"0x3d0900",
|
||||
"author":"0x0000000000000000000000000000000000000000",
|
||||
"timestamp":"0x00",
|
||||
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData":"",
|
||||
"gasLimit":"0x7a1200"
|
||||
},
|
||||
"nodes":[
|
||||
"enode://5ddc110733f6d34101973cdef3f9b43484159acf6f816d3b1ee92bc3c98ea453e857bb1207edf0ec0242008ab3a0f9f05eeaee99d47bd414c08a5bdf4847de13@176.9.3.148:30303",
|
||||
"enode://38f074f4db8e64dfbaf87984bf290eef67772a901a7113d1b62f36216be152b8450c393d6fc562a5e38f04f99bc8f439a99010a230b1d92dc1df43bf0bd00615@176.9.3.148:30403"
|
||||
],
|
||||
"accounts":{
|
||||
"0000000000000000000000000000000000000001":{
|
||||
"balance":"1",
|
||||
"builtin":{
|
||||
"name":"ecrecover",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":3000,
|
||||
"word":0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000002":{
|
||||
"balance":"1",
|
||||
"builtin":{
|
||||
"name":"sha256",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":60,
|
||||
"word":12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000003":{
|
||||
"balance":"1",
|
||||
"builtin":{
|
||||
"name":"ripemd160",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":600,
|
||||
"word":120
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000004":{
|
||||
"balance":"1",
|
||||
"builtin":{
|
||||
"name":"identity",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":15,
|
||||
"word":3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000005":{
|
||||
"builtin":{
|
||||
"name":"modexp",
|
||||
"activate_at":"0x2a",
|
||||
"pricing":{
|
||||
"modexp":{
|
||||
"divisor":20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000006":{
|
||||
"builtin":{
|
||||
"name":"alt_bn128_add",
|
||||
"activate_at":"0x2a",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":500,
|
||||
"word":0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000007":{
|
||||
"builtin":{
|
||||
"name":"alt_bn128_mul",
|
||||
"activate_at":"0x2a",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":40000,
|
||||
"word":0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000008":{
|
||||
"builtin":{
|
||||
"name":"alt_bn128_pairing",
|
||||
"activate_at":"0x2a",
|
||||
"pricing":{
|
||||
"alt_bn128_pairing":{
|
||||
"base":100000,
|
||||
"pair":80000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,12 @@
|
||||
"difficultyBoundDivisor":"0x0800",
|
||||
"durationLimit":"0x0d",
|
||||
"homesteadTransition":"0x118c30",
|
||||
"eip100bTransition":"0x7fffffffffffff",
|
||||
"eip150Transition":"0x7fffffffffffff",
|
||||
"eip100bTransition":"0x21e88e",
|
||||
"eip150Transition":"0x21e88e",
|
||||
"eip160Transition":"0x7fffffffffffff",
|
||||
"eip161abcTransition":"0x7fffffffffffff",
|
||||
"eip161dTransition":"0x7fffffffffffff",
|
||||
"eip649Transition":"0x7fffffffffffff",
|
||||
"eip649Transition":"0x21e88e",
|
||||
"blockReward":"0x1105a0185b50a80000",
|
||||
"mcip3Transition":"0x124f81",
|
||||
"mcip3MinerReward":"0xd8d726b7177a80000",
|
||||
@@ -31,16 +31,17 @@
|
||||
"maximumExtraDataSize":"0x20",
|
||||
"minGasLimit":"0x1388",
|
||||
"networkID":"0x76740f",
|
||||
"forkBlock":"0x5b6",
|
||||
"forkCanonHash":"0xa5e88ad9e34d113e264e307bc27e8471452c8fc13780324bb3abb96fd0558343",
|
||||
"forkBlock":"0x1d8015",
|
||||
"forkCanonHash":"0x380602acf82b629a0be6b5adb2b4a801e960a07dc8261bf196d21befdbb8f2f9",
|
||||
"eip86Transition":"0x7fffffffffffff",
|
||||
"eip98Transition":"0x7fffffffffffff",
|
||||
"eip140Transition":"0x7fffffffffffff",
|
||||
"eip155Transition":"0x7fffffffffffff",
|
||||
"eip211Transition":"0x7fffffffffffff",
|
||||
"eip214Transition":"0x7fffffffffffff",
|
||||
"eip658Transition":"0x7fffffffffffff",
|
||||
"maxCodeSize":"0x6000"
|
||||
"eip140Transition":"0x21e88e",
|
||||
"eip155Transition":"0x21e88e",
|
||||
"eip211Transition":"0x21e88e",
|
||||
"eip214Transition":"0x21e88e",
|
||||
"eip658Transition":"0x21e88e",
|
||||
"maxCodeSize":"0x6000",
|
||||
"maxCodeSizeTransition": "0x7fffffffffffff"
|
||||
},
|
||||
"genesis":{
|
||||
"seal":{
|
||||
@@ -57,12 +58,9 @@
|
||||
"gasLimit":"0x7a1200"
|
||||
},
|
||||
"nodes":[
|
||||
"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://09fcd36d553044c8b499b9b9e13a228ffd99572c513f77073d41f009717c464cd4399c0e665d6aff1590324254ee4e698b2b2533b1998dd04d896b9d6aff7895@35.185.67.35:30303",
|
||||
"enode://89e51a34770a0badf8ea18c4c4d2c361cde707abd60031d99b1ab3010363e1898230a516ddb37d974af8d8db1b322779d7fe0caae0617bed4924d1b4968cf92b@35.231.48.142:30303",
|
||||
"enode://b58c0c71f08864c0cf7fa9dea2c4cbefae5ae7a36cc30d286603b24982d25f3ccc056b589119324c51768fc2054b8c529ecf682e06e1e9980170b93ff194ed7a@132.148.132.9:30303",
|
||||
"enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303",
|
||||
"enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303",
|
||||
"enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555"
|
||||
@@ -119,7 +117,7 @@
|
||||
"0000000000000000000000000000000000000005":{
|
||||
"builtin":{
|
||||
"name":"modexp",
|
||||
"activate_at":"0x7fffffffffffff",
|
||||
"activate_at":"0x21e88e",
|
||||
"pricing":{
|
||||
"modexp":{
|
||||
"divisor":20
|
||||
@@ -130,7 +128,7 @@
|
||||
"0000000000000000000000000000000000000006":{
|
||||
"builtin":{
|
||||
"name":"alt_bn128_add",
|
||||
"activate_at":"0x7fffffffffffff",
|
||||
"activate_at":"0x21e88e",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":500,
|
||||
@@ -142,7 +140,7 @@
|
||||
"0000000000000000000000000000000000000007":{
|
||||
"builtin":{
|
||||
"name":"alt_bn128_mul",
|
||||
"activate_at":"0x7fffffffffffff",
|
||||
"activate_at":"0x21e88e",
|
||||
"pricing":{
|
||||
"linear":{
|
||||
"base":40000,
|
||||
@@ -154,7 +152,7 @@
|
||||
"0000000000000000000000000000000000000008":{
|
||||
"builtin":{
|
||||
"name":"alt_bn128_pairing",
|
||||
"activate_at":"0x7fffffffffffff",
|
||||
"activate_at":"0x21e88e",
|
||||
"pricing":{
|
||||
"alt_bn128_pairing":{
|
||||
"base":100000,
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"forkBlock": 641350,
|
||||
"forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": 10,
|
||||
"eip155Transition": 10,
|
||||
"eip98Transition": "0x7fffffffffffff",
|
||||
"eip86Transition": "0x7fffffffffffff",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x1",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0",
|
||||
"eip98Transition": "5",
|
||||
"eip140Transition": "5",
|
||||
"eip211Transition": "5",
|
||||
|
||||
@@ -32,7 +32,7 @@ pub struct BlockInfo {
|
||||
}
|
||||
|
||||
/// Describes location of newly inserted block.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum BlockLocation {
|
||||
/// It's part of the canon chain.
|
||||
CanonChain,
|
||||
@@ -44,7 +44,7 @@ pub enum BlockLocation {
|
||||
BranchBecomingCanonChain(BranchBecomingCanonChainData),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct BranchBecomingCanonChainData {
|
||||
/// Hash of the newest common ancestor with old canon chain.
|
||||
pub ancestor: H256,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@
|
||||
|
||||
use std::ops;
|
||||
use std::io::Write;
|
||||
use bloomchain;
|
||||
use blooms::{GroupPosition, BloomGroup};
|
||||
use db::Key;
|
||||
use engines::epoch::{Transition as EpochTransition};
|
||||
@@ -98,32 +97,17 @@ impl ops::Deref for LogGroupKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct LogGroupPosition(GroupPosition);
|
||||
|
||||
impl From<bloomchain::group::GroupPosition> for LogGroupPosition {
|
||||
fn from(position: bloomchain::group::GroupPosition) -> Self {
|
||||
LogGroupPosition(From::from(position))
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for LogGroupPosition {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.0.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl Key<BloomGroup> for LogGroupPosition {
|
||||
impl Key<BloomGroup> for GroupPosition {
|
||||
type Target = LogGroupKey;
|
||||
|
||||
fn key(&self) -> Self::Target {
|
||||
let mut result = [0u8; 6];
|
||||
result[0] = ExtrasIndex::BlocksBlooms as u8;
|
||||
result[1] = self.0.level;
|
||||
result[2] = (self.0.index >> 24) as u8;
|
||||
result[3] = (self.0.index >> 16) as u8;
|
||||
result[4] = (self.0.index >> 8) as u8;
|
||||
result[5] = self.0.index as u8;
|
||||
result[1] = self.level;
|
||||
result[2] = (self.index >> 24) as u8;
|
||||
result[3] = (self.index >> 16) as u8;
|
||||
result[4] = (self.index >> 8) as u8;
|
||||
result[5] = self.index as u8;
|
||||
LogGroupKey(result)
|
||||
}
|
||||
}
|
||||
|
||||
219
ethcore/src/blockchain/generator.rs
Normal file
219
ethcore/src/blockchain/generator.rs
Normal file
@@ -0,0 +1,219 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Blockchain generator for tests.
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use bigint::prelude::{U256, H256};
|
||||
use bloomchain::Bloom;
|
||||
|
||||
use bytes::Bytes;
|
||||
use header::Header;
|
||||
use rlp::encode;
|
||||
use transaction::SignedTransaction;
|
||||
use views::BlockView;
|
||||
|
||||
/// Helper structure, used for encoding blocks.
|
||||
#[derive(Default, Clone, RlpEncodable)]
|
||||
pub struct Block {
|
||||
pub header: Header,
|
||||
pub transactions: Vec<SignedTransaction>,
|
||||
pub uncles: Vec<Header>
|
||||
}
|
||||
|
||||
impl Block {
|
||||
#[inline]
|
||||
pub fn header(&self) -> Header {
|
||||
self.header.clone()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hash(&self) -> H256 {
|
||||
BlockView::new(&self.encoded()).header_view().hash()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn number(&self) -> u64 {
|
||||
self.header.number()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn encoded(&self) -> Bytes {
|
||||
encode(self).into_vec()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BlockOptions {
|
||||
pub difficulty: U256,
|
||||
pub bloom: Bloom,
|
||||
pub transactions: Vec<SignedTransaction>,
|
||||
}
|
||||
|
||||
impl Default for BlockOptions {
|
||||
fn default() -> Self {
|
||||
BlockOptions {
|
||||
difficulty: 10.into(),
|
||||
bloom: Bloom::default(),
|
||||
transactions: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BlockBuilder {
|
||||
blocks: VecDeque<Block>,
|
||||
}
|
||||
|
||||
impl BlockBuilder {
|
||||
pub fn genesis() -> Self {
|
||||
let mut blocks = VecDeque::with_capacity(1);
|
||||
blocks.push_back(Block::default());
|
||||
|
||||
BlockBuilder {
|
||||
blocks,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_block(&self) -> Self {
|
||||
self.add_block_with(|| BlockOptions::default())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_blocks(&self, count: usize) -> Self {
|
||||
self.add_blocks_with(count, || BlockOptions::default())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_block_with<T>(&self, get_metadata: T) -> Self where T: Fn() -> BlockOptions {
|
||||
self.add_blocks_with(1, get_metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_block_with_difficulty<T>(&self, difficulty: T) -> Self where T: Into<U256> {
|
||||
let difficulty = difficulty.into();
|
||||
self.add_blocks_with(1, move || BlockOptions {
|
||||
difficulty,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_block_with_transactions<T>(&self, transactions: T) -> Self
|
||||
where T: IntoIterator<Item = SignedTransaction> {
|
||||
let transactions = transactions.into_iter().collect::<Vec<_>>();
|
||||
self.add_blocks_with(1, || BlockOptions {
|
||||
transactions: transactions.clone(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_block_with_bloom(&self, bloom: Bloom) -> Self {
|
||||
self.add_blocks_with(1, move || BlockOptions {
|
||||
bloom,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_blocks_with<T>(&self, count: usize, get_metadata: T) -> Self where T: Fn() -> BlockOptions {
|
||||
assert!(count > 0, "There must be at least 1 block");
|
||||
let mut parent_hash = self.last().hash();
|
||||
let mut parent_number = self.last().number();
|
||||
let mut blocks = VecDeque::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
let mut block = Block::default();
|
||||
let metadata = get_metadata();
|
||||
let block_number = parent_number + 1;
|
||||
block.header.set_parent_hash(parent_hash);
|
||||
block.header.set_number(block_number);
|
||||
block.header.set_log_bloom(metadata.bloom);
|
||||
block.header.set_difficulty(metadata.difficulty);
|
||||
block.transactions = metadata.transactions;
|
||||
|
||||
parent_hash = block.hash();
|
||||
parent_number = block_number;
|
||||
|
||||
blocks.push_back(block);
|
||||
}
|
||||
|
||||
BlockBuilder {
|
||||
blocks,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn last(&self) -> &Block {
|
||||
self.blocks.back().expect("There is always at least 1 block")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BlockGenerator {
|
||||
builders: VecDeque<BlockBuilder>,
|
||||
}
|
||||
|
||||
impl BlockGenerator {
|
||||
pub fn new<T>(builders: T) -> Self where T: IntoIterator<Item = BlockBuilder> {
|
||||
BlockGenerator {
|
||||
builders: builders.into_iter().collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for BlockGenerator {
|
||||
type Item = Block;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
match self.builders.front_mut() {
|
||||
Some(ref mut builder) => {
|
||||
if let Some(block) = builder.blocks.pop_front() {
|
||||
return Some(block);
|
||||
}
|
||||
},
|
||||
None => return None,
|
||||
}
|
||||
self.builders.pop_front();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{BlockBuilder, BlockOptions, BlockGenerator};
|
||||
|
||||
#[test]
|
||||
fn test_block_builder() {
|
||||
let genesis = BlockBuilder::genesis();
|
||||
let block_1 = genesis.add_block();
|
||||
let block_1001 = block_1.add_blocks(1000);
|
||||
let block_1002 = block_1001.add_block_with(|| BlockOptions::default());
|
||||
let generator = BlockGenerator::new(vec![genesis, block_1, block_1001, block_1002]);
|
||||
assert_eq!(generator.count(), 1003);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_builder_fork() {
|
||||
let genesis = BlockBuilder::genesis();
|
||||
let block_10a = genesis.add_blocks(10);
|
||||
let block_11b = genesis.add_blocks(11);
|
||||
assert_eq!(block_10a.last().number(), 10);
|
||||
assert_eq!(block_11b.last().number(), 11);
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use rlp::*;
|
||||
use bigint::hash::{H256, H2048};
|
||||
use bytes::Bytes;
|
||||
use header::Header;
|
||||
use transaction::SignedTransaction;
|
||||
|
||||
use super::fork::Forkable;
|
||||
use super::bloom::WithBloom;
|
||||
use super::complete::CompleteBlock;
|
||||
use super::transaction::WithTransaction;
|
||||
|
||||
/// Helper structure, used for encoding blocks.
|
||||
#[derive(Default)]
|
||||
pub struct Block {
|
||||
pub header: Header,
|
||||
pub transactions: Vec<SignedTransaction>,
|
||||
pub uncles: Vec<Header>
|
||||
}
|
||||
|
||||
impl Encodable for Block {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.begin_list(3);
|
||||
s.append(&self.header);
|
||||
s.append_list(&self.transactions);
|
||||
s.append_list(&self.uncles);
|
||||
}
|
||||
}
|
||||
|
||||
impl Forkable for Block {
|
||||
fn fork(mut self, fork_number: usize) -> Self where Self: Sized {
|
||||
let difficulty = self.header.difficulty().clone() - fork_number.into();
|
||||
self.header.set_difficulty(difficulty);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl WithBloom for Block {
|
||||
fn with_bloom(mut self, bloom: H2048) -> Self where Self: Sized {
|
||||
self.header.set_log_bloom(bloom);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl WithTransaction for Block {
|
||||
fn with_transaction(mut self, transaction: SignedTransaction) -> Self where Self: Sized {
|
||||
self.transactions.push(transaction);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl CompleteBlock for Block {
|
||||
fn complete(mut self, parent_hash: H256) -> Bytes {
|
||||
self.header.set_parent_hash(parent_hash);
|
||||
encode(&self).into_vec()
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use bigint::hash::H2048;
|
||||
|
||||
pub trait WithBloom {
|
||||
fn with_bloom(self, bloom: H2048) -> Self where Self: Sized;
|
||||
}
|
||||
|
||||
pub struct Bloom<'a, I> where I: 'a {
|
||||
pub iter: &'a mut I,
|
||||
pub bloom: H2048,
|
||||
}
|
||||
|
||||
impl<'a, I> Iterator for Bloom<'a, I> where I: Iterator, <I as Iterator>::Item: WithBloom {
|
||||
type Item = <I as Iterator>::Item;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map(|item| item.with_bloom(self.bloom.clone()))
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use bigint::hash::H256;
|
||||
use bytes::Bytes;
|
||||
use views::BlockView;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct BlockFinalizer {
|
||||
parent_hash: H256
|
||||
}
|
||||
|
||||
impl BlockFinalizer {
|
||||
pub fn fork(&self) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CompleteBlock {
|
||||
fn complete(self, parent_hash: H256) -> Bytes;
|
||||
}
|
||||
|
||||
pub struct Complete<'a, I> where I: 'a {
|
||||
pub iter: &'a mut I,
|
||||
pub finalizer: &'a mut BlockFinalizer,
|
||||
}
|
||||
|
||||
impl<'a, I> Iterator for Complete<'a, I> where I: Iterator, <I as Iterator>::Item: CompleteBlock {
|
||||
type Item = Bytes;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map(|item| {
|
||||
let rlp = item.complete(self.finalizer.parent_hash.clone());
|
||||
self.finalizer.parent_hash = BlockView::new(&rlp).header_view().hash();
|
||||
rlp
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pub trait Forkable {
|
||||
fn fork(self, fork_number: usize) -> Self where Self: Sized;
|
||||
}
|
||||
|
||||
pub struct Fork<I> {
|
||||
pub iter: I,
|
||||
pub fork_number: usize,
|
||||
}
|
||||
|
||||
impl<I> Clone for Fork<I> where I: Iterator + Clone {
|
||||
fn clone(&self) -> Self {
|
||||
Fork {
|
||||
iter: self.iter.clone(),
|
||||
fork_number: self.fork_number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> Iterator for Fork<I> where I: Iterator, <I as Iterator>::Item: Forkable {
|
||||
type Item = <I as Iterator>::Item;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map(|item| item.fork(self.fork_number))
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H2048;
|
||||
use bytes::Bytes;
|
||||
use header::BlockNumber;
|
||||
use transaction::SignedTransaction;
|
||||
use super::fork::Fork;
|
||||
use super::bloom::Bloom;
|
||||
use super::complete::{BlockFinalizer, CompleteBlock, Complete};
|
||||
use super::block::Block;
|
||||
use super::transaction::Transaction;
|
||||
|
||||
/// Chain iterator interface.
|
||||
pub trait ChainIterator: Iterator + Sized {
|
||||
/// Should be called to create a fork of current iterator.
|
||||
/// Blocks generated by fork will have lower difficulty than current chain.
|
||||
fn fork(&self, fork_number: usize) -> Fork<Self> where Self: Clone;
|
||||
/// Should be called to make every consecutive block have given bloom.
|
||||
fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self>;
|
||||
/// Should be called to make every consecutive block have given transaction.
|
||||
fn with_transaction(&mut self, transaction: SignedTransaction) -> Transaction<Self>;
|
||||
/// Should be called to complete block. Without complete, block may have incorrect hash.
|
||||
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self>;
|
||||
/// Completes and generates block.
|
||||
fn generate<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Option<Bytes> where Self::Item: CompleteBlock;
|
||||
}
|
||||
|
||||
impl<I> ChainIterator for I where I: Iterator + Sized {
|
||||
fn fork(&self, fork_number: usize) -> Fork<Self> where I: Clone {
|
||||
Fork {
|
||||
iter: self.clone(),
|
||||
fork_number: fork_number
|
||||
}
|
||||
}
|
||||
|
||||
fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self> {
|
||||
Bloom {
|
||||
iter: self,
|
||||
bloom: bloom
|
||||
}
|
||||
}
|
||||
|
||||
fn with_transaction(&mut self, transaction: SignedTransaction) -> Transaction<Self> {
|
||||
Transaction {
|
||||
iter: self,
|
||||
transaction: transaction,
|
||||
}
|
||||
}
|
||||
|
||||
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self> {
|
||||
Complete {
|
||||
iter: self,
|
||||
finalizer: finalizer
|
||||
}
|
||||
}
|
||||
|
||||
fn generate<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Option<Bytes> where <I as Iterator>::Item: CompleteBlock {
|
||||
self.complete(finalizer).next()
|
||||
}
|
||||
}
|
||||
|
||||
/// Blockchain generator.
|
||||
#[derive(Clone)]
|
||||
pub struct ChainGenerator {
|
||||
/// Next block number.
|
||||
number: BlockNumber,
|
||||
/// Next block difficulty.
|
||||
difficulty: U256,
|
||||
}
|
||||
|
||||
impl ChainGenerator {
|
||||
fn prepare_block(&self) -> Block {
|
||||
let mut block = Block::default();
|
||||
block.header.set_number(self.number);
|
||||
block.header.set_difficulty(self.difficulty);
|
||||
block
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ChainGenerator {
|
||||
fn default() -> Self {
|
||||
ChainGenerator {
|
||||
number: 0,
|
||||
difficulty: 1000.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ChainGenerator {
|
||||
type Item = Block;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let block = self.prepare_block();
|
||||
self.number += 1;
|
||||
Some(block)
|
||||
}
|
||||
}
|
||||
|
||||
mod tests {
|
||||
use bigint::hash::{H256, H2048};
|
||||
use views::BlockView;
|
||||
use blockchain::generator::{ChainIterator, ChainGenerator, BlockFinalizer};
|
||||
|
||||
#[test]
|
||||
fn canon_chain_generator() {
|
||||
let mut canon_chain = ChainGenerator::default();
|
||||
let mut finalizer = BlockFinalizer::default();
|
||||
|
||||
let genesis_rlp = canon_chain.generate(&mut finalizer).unwrap();
|
||||
let genesis = BlockView::new(&genesis_rlp);
|
||||
|
||||
assert_eq!(genesis.header_view().parent_hash(), H256::default());
|
||||
assert_eq!(genesis.header_view().number(), 0);
|
||||
|
||||
let b1_rlp = canon_chain.generate(&mut finalizer).unwrap();
|
||||
let b1 = BlockView::new(&b1_rlp);
|
||||
|
||||
assert_eq!(b1.header_view().parent_hash(), genesis.header_view().hash());
|
||||
assert_eq!(b1.header_view().number(), 1);
|
||||
|
||||
let mut fork_chain = canon_chain.fork(1);
|
||||
|
||||
let b2_rlp_fork = fork_chain.generate(&mut finalizer.fork()).unwrap();
|
||||
let b2_fork = BlockView::new(&b2_rlp_fork);
|
||||
|
||||
assert_eq!(b2_fork.header_view().parent_hash(), b1.header_view().hash());
|
||||
assert_eq!(b2_fork.header_view().number(), 2);
|
||||
|
||||
let b2_rlp = canon_chain.generate(&mut finalizer).unwrap();
|
||||
let b2 = BlockView::new(&b2_rlp);
|
||||
|
||||
assert_eq!(b2.header_view().parent_hash(), b1.header_view().hash());
|
||||
assert_eq!(b2.header_view().number(), 2);
|
||||
assert!(b2.header_view().difficulty() > b2_fork.header_view().difficulty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_bloom_generator() {
|
||||
let bloom = H2048([0x1; 256]);
|
||||
let mut gen = ChainGenerator::default();
|
||||
let mut finalizer = BlockFinalizer::default();
|
||||
|
||||
let block0_rlp = gen.with_bloom(bloom).generate(&mut finalizer).unwrap();
|
||||
let block1_rlp = gen.generate(&mut finalizer).unwrap();
|
||||
let block0 = BlockView::new(&block0_rlp);
|
||||
let block1 = BlockView::new(&block1_rlp);
|
||||
|
||||
assert_eq!(block0.header_view().number(), 0);
|
||||
assert_eq!(block0.header_view().parent_hash(), H256::default());
|
||||
|
||||
assert_eq!(block1.header_view().number(), 1);
|
||||
assert_eq!(block1.header_view().parent_hash(), block0.header_view().hash());
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_1000_blocks() {
|
||||
let generator = ChainGenerator::default();
|
||||
let mut finalizer = BlockFinalizer::default();
|
||||
let blocks: Vec<_> = generator.take(1000).complete(&mut finalizer).collect();
|
||||
assert_eq!(blocks.len(), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Blockchain generator for tests.
|
||||
|
||||
mod bloom;
|
||||
mod block;
|
||||
mod complete;
|
||||
mod fork;
|
||||
pub mod generator;
|
||||
mod transaction;
|
||||
|
||||
pub use self::complete::BlockFinalizer;
|
||||
pub use self::generator::{ChainIterator, ChainGenerator};
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use transaction::SignedTransaction;
|
||||
|
||||
pub trait WithTransaction {
|
||||
fn with_transaction(self, transaction: SignedTransaction) -> Self where Self: Sized;
|
||||
}
|
||||
|
||||
pub struct Transaction<'a, I> where I: 'a {
|
||||
pub iter: &'a mut I,
|
||||
pub transaction: SignedTransaction,
|
||||
}
|
||||
|
||||
impl <'a, I> Iterator for Transaction<'a, I> where I: Iterator, <I as Iterator>::Item: WithTransaction {
|
||||
type Item = <I as Iterator>::Item;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map(|item| item.with_transaction(self.transaction.clone()))
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@ use std::collections::HashMap;
|
||||
use bigint::hash::H256;
|
||||
use header::BlockNumber;
|
||||
use blockchain::block_info::BlockInfo;
|
||||
use blooms::BloomGroup;
|
||||
use super::extras::{BlockDetails, BlockReceipts, TransactionAddress, LogGroupPosition};
|
||||
use blockchain::extras::{BlockDetails, BlockReceipts, TransactionAddress};
|
||||
use blooms::{BloomGroup, GroupPosition};
|
||||
|
||||
/// Block extras update info.
|
||||
pub struct ExtrasUpdate<'a> {
|
||||
@@ -20,7 +20,7 @@ pub struct ExtrasUpdate<'a> {
|
||||
/// Modified block receipts.
|
||||
pub block_receipts: HashMap<H256, BlockReceipts>,
|
||||
/// Modified blocks blooms.
|
||||
pub blocks_blooms: HashMap<LogGroupPosition, BloomGroup>,
|
||||
pub blocks_blooms: HashMap<GroupPosition, BloomGroup>,
|
||||
/// Modified transaction addresses (None signifies removed transactions).
|
||||
pub transactions_addresses: HashMap<H256, Option<TransactionAddress>>,
|
||||
}
|
||||
|
||||
@@ -28,13 +28,6 @@ impl From<LogBloom> for Bloom {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bc::Bloom> for Bloom {
|
||||
fn from(bloom: bc::Bloom) -> Self {
|
||||
let bytes: [u8; 256] = bloom.into();
|
||||
Bloom(LogBloom::from(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<bc::Bloom> for Bloom {
|
||||
fn into(self) -> bc::Bloom {
|
||||
let log = self.0;
|
||||
|
||||
@@ -15,58 +15,39 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use bloomchain::group as bc;
|
||||
use rlp::*;
|
||||
use bloomchain::{Bloom, BloomCompat};
|
||||
use heapsize::HeapSizeOf;
|
||||
use super::Bloom;
|
||||
|
||||
/// Represents group of X consecutive blooms.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||
pub struct BloomGroup {
|
||||
blooms: Vec<Bloom>,
|
||||
}
|
||||
|
||||
impl BloomGroup {
|
||||
pub fn accrue_bloom_group(&mut self, group: &BloomGroup) {
|
||||
for (bloom, other) in self.blooms.iter_mut().zip(group.blooms.iter()) {
|
||||
bloom.accrue_bloom(other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bc::BloomGroup> for BloomGroup {
|
||||
fn from(group: bc::BloomGroup) -> Self {
|
||||
let blooms = group.blooms
|
||||
.into_iter()
|
||||
.map(From::from)
|
||||
.collect();
|
||||
|
||||
BloomGroup {
|
||||
blooms: blooms
|
||||
blooms: group.blooms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<bc::BloomGroup> for BloomGroup {
|
||||
fn into(self) -> bc::BloomGroup {
|
||||
let blooms = self.blooms
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
|
||||
bc::BloomGroup {
|
||||
blooms: blooms
|
||||
blooms: self.blooms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for BloomGroup {
|
||||
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
||||
let blooms = rlp.as_list()?;
|
||||
let group = BloomGroup {
|
||||
blooms: blooms
|
||||
};
|
||||
Ok(group)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for BloomGroup {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.append_list(&self.blooms);
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for BloomGroup {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.blooms.heap_size_of_children()
|
||||
|
||||
@@ -29,7 +29,7 @@ use error::{BlockError, Error};
|
||||
use header::{Header, BlockNumber};
|
||||
use engines::{self, Engine};
|
||||
use ethjson;
|
||||
use rlp::{self, UntrustedRlp};
|
||||
use rlp::UntrustedRlp;
|
||||
use machine::EthereumMachine;
|
||||
use semantic_version::SemanticVersion;
|
||||
|
||||
@@ -41,6 +41,38 @@ const MAX_SNAPSHOT_BLOCKS: u64 = 30000;
|
||||
|
||||
const DEFAULT_EIP649_DELAY: u64 = 3_000_000;
|
||||
|
||||
/// Ethash specific seal
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Seal {
|
||||
/// Ethash seal mix_hash
|
||||
pub mix_hash: H256,
|
||||
/// Ethash seal nonce
|
||||
pub nonce: H64,
|
||||
}
|
||||
|
||||
impl Seal {
|
||||
/// Tries to parse rlp as ethash seal.
|
||||
pub fn parse_seal<T: AsRef<[u8]>>(seal: &[T]) -> Result<Self, Error> {
|
||||
if seal.len() != 2 {
|
||||
return Err(BlockError::InvalidSealArity(
|
||||
Mismatch {
|
||||
expected: 2,
|
||||
found: seal.len()
|
||||
}
|
||||
).into());
|
||||
}
|
||||
|
||||
let mix_hash = UntrustedRlp::new(seal[0].as_ref()).as_val::<H256>()?;
|
||||
let nonce = UntrustedRlp::new(seal[1].as_ref()).as_val::<H64>()?;
|
||||
let seal = Seal {
|
||||
mix_hash,
|
||||
nonce,
|
||||
};
|
||||
|
||||
Ok(seal)
|
||||
}
|
||||
}
|
||||
|
||||
/// Ethash params.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct EthashParams {
|
||||
@@ -177,13 +209,12 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
|
||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||
fn extra_info(&self, header: &Header) -> BTreeMap<String, String> {
|
||||
if header.seal().len() == self.seal_fields() {
|
||||
map![
|
||||
"nonce".to_owned() => format!("0x{}", header.nonce().hex()),
|
||||
"mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())
|
||||
]
|
||||
} else {
|
||||
BTreeMap::default()
|
||||
match Seal::parse_seal(header.seal()) {
|
||||
Ok(seal) => map![
|
||||
"nonce".to_owned() => format!("0x{}", seal.nonce.hex()),
|
||||
"mixHash".to_owned() => format!("0x{}", seal.mix_hash.hex())
|
||||
],
|
||||
_ => BTreeMap::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,13 +300,7 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
|
||||
fn verify_block_basic(&self, header: &Header) -> Result<(), Error> {
|
||||
// check the seal fields.
|
||||
if header.seal().len() != self.seal_fields() {
|
||||
return Err(From::from(BlockError::InvalidSealArity(
|
||||
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
|
||||
)));
|
||||
}
|
||||
UntrustedRlp::new(&header.seal()[0]).as_val::<H256>()?;
|
||||
UntrustedRlp::new(&header.seal()[1]).as_val::<H64>()?;
|
||||
let seal = Seal::parse_seal(header.seal())?;
|
||||
|
||||
// TODO: consider removing these lines.
|
||||
let min_difficulty = self.ethash_params.minimum_difficulty;
|
||||
@@ -285,9 +310,10 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
|
||||
let difficulty = Ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
|
||||
&header.bare_hash().0,
|
||||
header.nonce().low_u64(),
|
||||
&header.mix_hash().0
|
||||
seal.nonce.low_u64(),
|
||||
&seal.mix_hash.0
|
||||
)));
|
||||
|
||||
if &difficulty < header.difficulty() {
|
||||
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
|
||||
}
|
||||
@@ -300,17 +326,20 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
}
|
||||
|
||||
fn verify_block_unordered(&self, header: &Header) -> Result<(), Error> {
|
||||
if header.seal().len() != self.seal_fields() {
|
||||
return Err(From::from(BlockError::InvalidSealArity(
|
||||
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
|
||||
)));
|
||||
}
|
||||
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, header.nonce().low_u64());
|
||||
let seal = Seal::parse_seal(header.seal())?;
|
||||
|
||||
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, seal.nonce.low_u64());
|
||||
let mix = H256(result.mix_hash);
|
||||
let difficulty = Ethash::boundary_to_difficulty(&H256(result.value));
|
||||
trace!(target: "miner", "num: {}, seed: {}, h: {}, non: {}, mix: {}, res: {}" , header.number() as u64, H256(slow_hash_block_number(header.number() as u64)), header.bare_hash(), header.nonce().low_u64(), H256(result.mix_hash), H256(result.value));
|
||||
if mix != header.mix_hash() {
|
||||
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: header.mix_hash() })));
|
||||
trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}",
|
||||
num = header.number() as u64,
|
||||
seed = H256(slow_hash_block_number(header.number() as u64)),
|
||||
h = header.bare_hash(),
|
||||
non = seal.nonce.low_u64(),
|
||||
mix = H256(result.mix_hash),
|
||||
res = H256(result.value));
|
||||
if mix != seal.mix_hash {
|
||||
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash })));
|
||||
}
|
||||
if &difficulty < header.difficulty() {
|
||||
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
|
||||
@@ -441,18 +470,6 @@ impl Ethash {
|
||||
}
|
||||
}
|
||||
|
||||
impl Header {
|
||||
/// Get the nonce field of the header.
|
||||
pub fn nonce(&self) -> H64 {
|
||||
rlp::decode(&self.seal()[1])
|
||||
}
|
||||
|
||||
/// Get the mix hash field of the header.
|
||||
pub fn mix_hash(&self) -> H256 {
|
||||
rlp::decode(&self.seal()[0])
|
||||
}
|
||||
}
|
||||
|
||||
fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u64) -> (u64, U256) {
|
||||
let eras = if block_number != 0 && block_number % era_rounds == 0 {
|
||||
block_number / era_rounds - 1
|
||||
@@ -637,7 +654,7 @@ mod tests {
|
||||
#[test]
|
||||
fn can_do_seal_unordered_verification_fail() {
|
||||
let engine = test_spec().engine;
|
||||
let header: Header = Header::default();
|
||||
let header = Header::default();
|
||||
|
||||
let verify_result = engine.verify_block_unordered(&header);
|
||||
|
||||
@@ -648,6 +665,17 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_do_seal_unordered_verification_fail2() {
|
||||
let engine = test_spec().engine;
|
||||
let mut header = Header::default();
|
||||
header.set_seal(vec![vec![], vec![]]);
|
||||
|
||||
let verify_result = engine.verify_block_unordered(&header);
|
||||
// rlp error, shouldn't panic
|
||||
assert!(verify_result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_do_seal256_verification_fail() {
|
||||
let engine = test_spec().engine;
|
||||
|
||||
@@ -155,8 +155,8 @@ pub mod verification;
|
||||
pub mod views;
|
||||
|
||||
mod cache_manager;
|
||||
mod blooms;
|
||||
mod basic_types;
|
||||
mod blooms;
|
||||
mod pod_account;
|
||||
mod state_db;
|
||||
mod account_db;
|
||||
|
||||
@@ -264,15 +264,9 @@ impl EthereumMachine {
|
||||
} else if block_number < ext.eip150_transition {
|
||||
Schedule::new_homestead()
|
||||
} else {
|
||||
// There's no max_code_size transition so we tie it to eip161abc
|
||||
let max_code_size = if block_number >= ext.eip161abc_transition {
|
||||
self.params.max_code_size as usize
|
||||
} else {
|
||||
usize::max_value()
|
||||
};
|
||||
|
||||
let max_code_size = self.params.max_code_size(block_number);
|
||||
let mut schedule = Schedule::new_post_eip150(
|
||||
max_code_size,
|
||||
max_code_size as _,
|
||||
block_number >= ext.eip160_transition,
|
||||
block_number >= ext.eip161abc_transition,
|
||||
block_number >= ext.eip161d_transition
|
||||
|
||||
@@ -57,6 +57,8 @@ pub enum Error {
|
||||
VersionNotSupported(u64),
|
||||
/// Max chunk size is to small to fit basic account data.
|
||||
ChunkTooSmall,
|
||||
/// Oversized chunk
|
||||
ChunkTooLarge,
|
||||
/// Snapshots not supported by the consensus engine.
|
||||
SnapshotsUnsupported,
|
||||
/// Bad epoch transition.
|
||||
@@ -85,6 +87,7 @@ impl fmt::Display for Error {
|
||||
Error::Trie(ref err) => err.fmt(f),
|
||||
Error::VersionNotSupported(ref ver) => write!(f, "Snapshot version {} is not supprted.", ver),
|
||||
Error::ChunkTooSmall => write!(f, "Chunk size is too small."),
|
||||
Error::ChunkTooLarge => write!(f, "Chunk size is too large."),
|
||||
Error::SnapshotsUnsupported => write!(f, "Snapshots unsupported by consensus engine."),
|
||||
Error::BadEpochProof(i) => write!(f, "Bad epoch proof for transition to epoch {}", i),
|
||||
Error::WrongChunkFormat(ref msg) => write!(f, "Wrong chunk format: {}", msg),
|
||||
|
||||
@@ -77,6 +77,11 @@ mod traits;
|
||||
// Try to have chunks be around 4MB (before compression)
|
||||
const PREFERRED_CHUNK_SIZE: usize = 4 * 1024 * 1024;
|
||||
|
||||
// Maximal chunk size (decompressed)
|
||||
// Snappy::decompressed_len estimation may sometimes yield results greater
|
||||
// than PREFERRED_CHUNK_SIZE so allow some threshold here.
|
||||
const MAX_CHUNK_SIZE: usize = PREFERRED_CHUNK_SIZE / 4 * 5;
|
||||
|
||||
// Minimum supported state chunk version.
|
||||
const MIN_SUPPORTED_STATE_CHUNK_VERSION: u64 = 1;
|
||||
// current state chunk version.
|
||||
|
||||
@@ -23,7 +23,7 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
|
||||
use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService};
|
||||
use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE};
|
||||
use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter};
|
||||
|
||||
use blockchain::BlockChain;
|
||||
@@ -130,6 +130,11 @@ impl Restoration {
|
||||
// feeds a state chunk, aborts early if `flag` becomes false.
|
||||
fn feed_state(&mut self, hash: H256, chunk: &[u8], flag: &AtomicBool) -> Result<(), Error> {
|
||||
if self.state_chunks_left.contains(&hash) {
|
||||
let expected_len = snappy::decompressed_len(chunk)?;
|
||||
if expected_len > MAX_CHUNK_SIZE {
|
||||
trace!(target: "snapshot", "Discarding large chunk: {} vs {}", expected_len, MAX_CHUNK_SIZE);
|
||||
return Err(::snapshot::Error::ChunkTooLarge.into());
|
||||
}
|
||||
let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?;
|
||||
|
||||
self.state.feed(&self.snappy_buffer[..len], flag)?;
|
||||
@@ -147,6 +152,11 @@ impl Restoration {
|
||||
// feeds a block chunk
|
||||
fn feed_blocks(&mut self, hash: H256, chunk: &[u8], engine: &EthEngine, flag: &AtomicBool) -> Result<(), Error> {
|
||||
if self.block_chunks_left.contains(&hash) {
|
||||
let expected_len = snappy::decompressed_len(chunk)?;
|
||||
if expected_len > MAX_CHUNK_SIZE {
|
||||
trace!(target: "snapshot", "Discarding large chunk: {} vs {}", expected_len, MAX_CHUNK_SIZE);
|
||||
return Err(::snapshot::Error::ChunkTooLarge.into());
|
||||
}
|
||||
let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?;
|
||||
|
||||
self.secondary.feed(&self.snappy_buffer[..len], engine, flag)?;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use devtools::RandomTempPath;
|
||||
use error::Error;
|
||||
|
||||
use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer};
|
||||
use blockchain::generator::{BlockGenerator, BlockBuilder};
|
||||
use blockchain::BlockChain;
|
||||
use snapshot::{chunk_secondary, Error as SnapshotError, Progress, SnapshotComponents};
|
||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
||||
@@ -35,9 +35,10 @@ use std::sync::atomic::AtomicBool;
|
||||
const SNAPSHOT_MODE: ::snapshot::PowSnapshot = ::snapshot::PowSnapshot { blocks: 30000, max_restore_blocks: 30000 };
|
||||
|
||||
fn chunk_and_restore(amount: u64) {
|
||||
let mut canon_chain = ChainGenerator::default();
|
||||
let mut finalizer = BlockFinalizer::default();
|
||||
let genesis = canon_chain.generate(&mut finalizer).unwrap();
|
||||
let genesis = BlockBuilder::genesis();
|
||||
let rest = genesis.add_blocks(amount as usize);
|
||||
let generator = BlockGenerator::new(vec![rest]);
|
||||
let genesis = genesis.last();
|
||||
|
||||
let engine = ::spec::Spec::new_test().engine;
|
||||
let new_path = RandomTempPath::create_dir();
|
||||
@@ -45,13 +46,12 @@ fn chunk_and_restore(amount: u64) {
|
||||
snapshot_path.push("SNAP");
|
||||
|
||||
let old_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());
|
||||
let bc = BlockChain::new(Default::default(), &genesis.encoded(), old_db.clone());
|
||||
|
||||
// build the blockchain.
|
||||
let mut batch = DBTransaction::new();
|
||||
for _ in 0..amount {
|
||||
let block = canon_chain.generate(&mut finalizer).unwrap();
|
||||
bc.insert_block(&mut batch, &block, vec![]);
|
||||
for block in generator {
|
||||
bc.insert_block(&mut batch, &block.encoded(), vec![]);
|
||||
bc.commit();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ fn chunk_and_restore(amount: u64) {
|
||||
|
||||
// restore it.
|
||||
let new_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone());
|
||||
let new_chain = BlockChain::new(Default::default(), &genesis.encoded(), new_db.clone());
|
||||
let mut rebuilder = SNAPSHOT_MODE.rebuilder(new_chain, new_db.clone(), &manifest).unwrap();
|
||||
|
||||
let reader = PackedReader::new(&snapshot_path).unwrap().unwrap();
|
||||
@@ -97,15 +97,19 @@ fn chunk_and_restore(amount: u64) {
|
||||
drop(rebuilder);
|
||||
|
||||
// and test it.
|
||||
let new_chain = BlockChain::new(Default::default(), &genesis, new_db);
|
||||
let new_chain = BlockChain::new(Default::default(), &genesis.encoded(), new_db);
|
||||
assert_eq!(new_chain.best_block_hash(), best_hash);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chunk_and_restore_500() { chunk_and_restore(500) }
|
||||
fn chunk_and_restore_500() {
|
||||
chunk_and_restore(500)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chunk_and_restore_40k() { chunk_and_restore(40000) }
|
||||
fn chunk_and_restore_4k() {
|
||||
chunk_and_restore(4000)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checks_flag() {
|
||||
@@ -120,17 +124,12 @@ fn checks_flag() {
|
||||
|
||||
stream.append_empty_data().append_empty_data();
|
||||
|
||||
let genesis = {
|
||||
let mut canon_chain = ChainGenerator::default();
|
||||
let mut finalizer = BlockFinalizer::default();
|
||||
canon_chain.generate(&mut finalizer).unwrap()
|
||||
};
|
||||
|
||||
let genesis = BlockBuilder::genesis();
|
||||
let chunk = stream.out();
|
||||
|
||||
let db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let engine = ::spec::Spec::new_test().engine;
|
||||
let chain = BlockChain::new(Default::default(), &genesis, db.clone());
|
||||
let chain = BlockChain::new(Default::default(), &genesis.last().encoded(), db.clone());
|
||||
|
||||
let manifest = ::snapshot::ManifestData {
|
||||
version: 2,
|
||||
|
||||
@@ -120,6 +120,8 @@ pub struct CommonParams {
|
||||
pub node_permission_contract: Option<Address>,
|
||||
/// Maximum contract code size that can be deployed.
|
||||
pub max_code_size: u64,
|
||||
/// Number of first block where max code size limit is active.
|
||||
pub max_code_size_transition: BlockNumber,
|
||||
/// Transaction permission managing contract address.
|
||||
pub transaction_permission_contract: Option<Address>,
|
||||
}
|
||||
@@ -127,11 +129,20 @@ pub struct CommonParams {
|
||||
impl CommonParams {
|
||||
/// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net.
|
||||
pub fn schedule(&self, block_number: u64) -> ::vm::Schedule {
|
||||
let mut schedule = ::vm::Schedule::new_post_eip150(self.max_code_size as _, true, true, true);
|
||||
let mut schedule = ::vm::Schedule::new_post_eip150(self.max_code_size(block_number) as _, true, true, true);
|
||||
self.update_schedule(block_number, &mut schedule);
|
||||
schedule
|
||||
}
|
||||
|
||||
/// Returns max code size at given block.
|
||||
pub fn max_code_size(&self, block_number: u64) -> u64 {
|
||||
if block_number >= self.max_code_size_transition {
|
||||
self.max_code_size
|
||||
} else {
|
||||
u64::max_value()
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply common spec config parameters to the schedule.
|
||||
pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) {
|
||||
schedule.have_create2 = block_number >= self.eip86_transition;
|
||||
@@ -228,6 +239,7 @@ impl From<ethjson::spec::Params> for CommonParams {
|
||||
registrar: p.registrar.map_or_else(Address::new, Into::into),
|
||||
node_permission_contract: p.node_permission_contract.map(Into::into),
|
||||
max_code_size: p.max_code_size.map_or(u64::max_value(), Into::into),
|
||||
max_code_size_transition: p.max_code_size_transition.map_or(0, Into::into),
|
||||
transaction_permission_contract: p.transaction_permission_contract.map(Into::into),
|
||||
wasm_activation_transition: p.wasm_activation_transition.map_or(
|
||||
BlockNumber::max_value(),
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
use bloomchain::Bloom;
|
||||
use bloomchain::group::{BloomGroup, GroupPosition};
|
||||
use basic_types::LogBloom;
|
||||
|
||||
/// Helper structure representing bloom of the trace.
|
||||
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||
pub struct BlockTracesBloom(LogBloom);
|
||||
|
||||
impl From<LogBloom> for BlockTracesBloom {
|
||||
fn from(bloom: LogBloom) -> BlockTracesBloom {
|
||||
BlockTracesBloom(bloom)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Bloom> for BlockTracesBloom {
|
||||
fn from(bloom: Bloom) -> BlockTracesBloom {
|
||||
let bytes: [u8; 256] = bloom.into();
|
||||
BlockTracesBloom(LogBloom::from(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Bloom> for BlockTracesBloom {
|
||||
fn into(self) -> Bloom {
|
||||
let log = self.0;
|
||||
Bloom::from(log.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents group of X consecutive blooms.
|
||||
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
|
||||
pub struct BlockTracesBloomGroup {
|
||||
blooms: Vec<BlockTracesBloom>,
|
||||
}
|
||||
|
||||
impl From<BloomGroup> for BlockTracesBloomGroup {
|
||||
fn from(group: BloomGroup) -> Self {
|
||||
let blooms = group.blooms
|
||||
.into_iter()
|
||||
.map(From::from)
|
||||
.collect();
|
||||
|
||||
BlockTracesBloomGroup {
|
||||
blooms: blooms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<BloomGroup> for BlockTracesBloomGroup {
|
||||
fn into(self) -> BloomGroup {
|
||||
let blooms = self.blooms
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
|
||||
BloomGroup {
|
||||
blooms: blooms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents `BloomGroup` position in database.
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||
pub struct TraceGroupPosition {
|
||||
/// Bloom level.
|
||||
pub level: u8,
|
||||
/// Group index.
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
impl From<GroupPosition> for TraceGroupPosition {
|
||||
fn from(p: GroupPosition) -> Self {
|
||||
TraceGroupPosition {
|
||||
level: p.level as u8,
|
||||
index: p.index as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,7 +279,6 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
|
||||
} else {
|
||||
self.traces(block_hash).expect("Traces database is incomplete.").bloom()
|
||||
})
|
||||
.map(blooms::Bloom::from)
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
//! Tracing
|
||||
|
||||
mod bloom;
|
||||
mod config;
|
||||
mod db;
|
||||
mod executive_tracer;
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
//! Trace filters type definitions
|
||||
|
||||
use std::ops::Range;
|
||||
use bloomchain::{Filter as BloomFilter, Bloom, Number};
|
||||
use hash::keccak;
|
||||
use util::Address;
|
||||
use bloomable::Bloomable;
|
||||
use basic_types::LogBloom;
|
||||
use bloomable::Bloomable;
|
||||
use bloomchain::{Filter as BloomFilter, Number, Bloom};
|
||||
use hash::keccak;
|
||||
use trace::flat::FlatTrace;
|
||||
use util::Address;
|
||||
|
||||
use super::trace::{Action, Res};
|
||||
|
||||
/// Addresses filter.
|
||||
@@ -90,9 +91,6 @@ pub struct Filter {
|
||||
impl BloomFilter for Filter {
|
||||
fn bloom_possibilities(&self) -> Vec<Bloom> {
|
||||
self.bloom_possibilities()
|
||||
.into_iter()
|
||||
.map(|b| Bloom::from(b.0))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<Number> {
|
||||
|
||||
@@ -28,7 +28,7 @@ use client::BlockChainClient;
|
||||
use engines::EthEngine;
|
||||
use error::{BlockError, Error};
|
||||
use header::{BlockNumber, Header};
|
||||
use transaction::SignedTransaction;
|
||||
use transaction::{SignedTransaction, UnverifiedTransaction};
|
||||
use views::BlockView;
|
||||
|
||||
use bigint::hash::H256;
|
||||
@@ -69,11 +69,9 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &EthEngine) ->
|
||||
verify_header_params(&u, engine, false)?;
|
||||
engine.verify_block_basic(&u)?;
|
||||
}
|
||||
// Verify transactions.
|
||||
// TODO: either use transaction views or cache the decoded transactions.
|
||||
let v = BlockView::new(bytes);
|
||||
for t in v.transactions() {
|
||||
engine.verify_transaction_basic(&t, &header)?;
|
||||
|
||||
for t in UntrustedRlp::new(bytes).at(1)?.iter().map(|rlp| rlp.as_val::<UnverifiedTransaction>()) {
|
||||
engine.verify_transaction_basic(&t?, &header)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -355,6 +353,7 @@ mod tests {
|
||||
use types::log_entry::{LogEntry, LocalizedLogEntry};
|
||||
use time::get_time;
|
||||
use encoded;
|
||||
use rlp;
|
||||
|
||||
fn check_ok(result: Result<(), Error>) {
|
||||
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
||||
@@ -508,6 +507,27 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_block_basic_with_invalid_transactions() {
|
||||
let spec = Spec::new_test();
|
||||
let engine = &*spec.engine;
|
||||
|
||||
let block = {
|
||||
let mut rlp = rlp::RlpStream::new_list(3);
|
||||
let mut header = Header::default();
|
||||
// that's an invalid transaction list rlp
|
||||
let invalid_transactions = vec![vec![0u8]];
|
||||
header.set_transactions_root(ordered_trie_root(invalid_transactions.clone()));
|
||||
header.set_gas_limit(engine.params().min_gas_limit);
|
||||
rlp.append(&header);
|
||||
rlp.append_list::<Vec<u8>, _>(&invalid_transactions);
|
||||
rlp.append_raw(&rlp::EMPTY_LIST_RLP, 1);
|
||||
rlp.out()
|
||||
};
|
||||
|
||||
assert!(basic_test(&block, engine).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_block() {
|
||||
use rlp::RlpStream;
|
||||
|
||||
@@ -12,6 +12,7 @@ ethcore-util = { path = "../../util" }
|
||||
ethcore-bigint = { path = "../../util/bigint" }
|
||||
ethjson = { path = "../../json" }
|
||||
bloomable = { path = "../../util/bloomable" }
|
||||
ethbloom = "0.2.5"
|
||||
keccak-hash = { path = "../../util/hash" }
|
||||
heapsize = "0.4"
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Blockchain filter
|
||||
|
||||
use util::Address;
|
||||
use bigint::hash::{H256, H2048};
|
||||
use bigint::hash::{H256, H2048 as Bloom};
|
||||
use bloomable::Bloomable;
|
||||
use ids::BlockId;
|
||||
use log_entry::LogEntry;
|
||||
@@ -75,15 +75,15 @@ impl Clone for Filter {
|
||||
|
||||
impl Filter {
|
||||
/// Returns combinations of each address and topic.
|
||||
pub fn bloom_possibilities(&self) -> Vec<H2048> {
|
||||
pub fn bloom_possibilities(&self) -> Vec<Bloom> {
|
||||
let blooms = match self.address {
|
||||
Some(ref addresses) if !addresses.is_empty() =>
|
||||
addresses.iter().map(|ref address| {
|
||||
let mut bloom = H2048::default();
|
||||
let mut bloom = Bloom::default();
|
||||
bloom.shift_bloomed(&keccak(address));
|
||||
bloom
|
||||
}).collect(),
|
||||
_ => vec![H2048::default()]
|
||||
_ => vec![Bloom::default()]
|
||||
};
|
||||
|
||||
self.topics.iter().fold(blooms, |bs, topic| match *topic {
|
||||
@@ -93,7 +93,7 @@ impl Filter {
|
||||
let mut b = bloom.clone();
|
||||
b.shift_bloomed(&keccak(topic));
|
||||
b
|
||||
}).collect::<Vec<H2048>>()
|
||||
}).collect::<Vec<Bloom>>()
|
||||
}).collect()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ extern crate rlp;
|
||||
#[macro_use]
|
||||
extern crate rlp_derive;
|
||||
extern crate bloomable;
|
||||
extern crate ethbloom;
|
||||
extern crate keccak_hash as hash;
|
||||
extern crate heapsize;
|
||||
|
||||
|
||||
@@ -119,8 +119,8 @@ pub struct Schedule {
|
||||
|
||||
/// Wasm cost table
|
||||
pub struct WasmCosts {
|
||||
/// Arena allocator cost, per byte
|
||||
pub alloc: u32,
|
||||
/// Default opcode cost
|
||||
pub regular: u32,
|
||||
/// Div operations multiplier.
|
||||
pub div: u32,
|
||||
/// Div operations multiplier.
|
||||
@@ -135,17 +135,20 @@ pub struct WasmCosts {
|
||||
pub initial_mem: u32,
|
||||
/// Grow memory cost, per page (64kb)
|
||||
pub grow_mem: u32,
|
||||
/// Memory copy cost, per byte
|
||||
pub memcpy: u32,
|
||||
/// Max stack height (native WebAssembly stack limiter)
|
||||
pub max_stack_height: u32,
|
||||
/// Cost of wasm opcode is calculated as TABLE_ENTRY_COST * `opcodes_mul` / `opcodes_div`
|
||||
pub opcodes_mul: u32,
|
||||
/// Cost of wasm opcode is calculated as TABLE_ENTRY_COST * `opcodes_mul` / `opcodes_div`
|
||||
pub opcodes_div: u32,
|
||||
|
||||
}
|
||||
|
||||
impl Default for WasmCosts {
|
||||
fn default() -> Self {
|
||||
WasmCosts {
|
||||
alloc: 2,
|
||||
regular: 1,
|
||||
div: 16,
|
||||
mul: 4,
|
||||
mem: 2,
|
||||
@@ -153,6 +156,8 @@ impl Default for WasmCosts {
|
||||
static_address: 40,
|
||||
initial_mem: 4096,
|
||||
grow_mem: 8192,
|
||||
memcpy: 1,
|
||||
max_stack_height: 64*1024,
|
||||
opcodes_mul: 3,
|
||||
opcodes_div: 8,
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ byteorder = "1.0"
|
||||
ethcore-util = { path = "../../util" }
|
||||
ethcore-bigint = { path = "../../util/bigint" }
|
||||
log = "0.3"
|
||||
parity-wasm = "0.23"
|
||||
parity-wasm = "0.27"
|
||||
libc = "0.2"
|
||||
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
|
||||
vm = { path = "../vm" }
|
||||
ethcore-logger = { path = "../../logger" }
|
||||
wasmi = { git = "https://github.com/pepyakin/wasmi" }
|
||||
wasmi = { git = "https://github.com/paritytech/wasmi" }
|
||||
@@ -19,7 +19,7 @@
|
||||
use std::cell::RefCell;
|
||||
use wasmi::{
|
||||
self, Signature, Error, FuncRef, FuncInstance, MemoryDescriptor,
|
||||
MemoryRef, MemoryInstance,
|
||||
MemoryRef, MemoryInstance, memory_units,
|
||||
};
|
||||
|
||||
/// Internal ids all functions runtime supports. This is just a glue for wasmi interpreter
|
||||
@@ -219,7 +219,10 @@ impl ImportResolver {
|
||||
let mut mem_ref = self.memory.borrow_mut();
|
||||
if mem_ref.is_none() {
|
||||
*mem_ref = Some(
|
||||
MemoryInstance::alloc(0, Some(0)).expect("Memory allocation (0, 0) should not fail; qed")
|
||||
MemoryInstance::alloc(
|
||||
memory_units::Pages(0),
|
||||
Some(memory_units::Pages(0)),
|
||||
).expect("Memory allocation (0, 0) should not fail; qed")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -229,7 +232,7 @@ impl ImportResolver {
|
||||
|
||||
/// Returns memory size module initially requested
|
||||
pub fn memory_size(&self) -> Result<u32, Error> {
|
||||
Ok(self.memory_ref().size())
|
||||
Ok(self.memory_ref().current_size().0 as u32)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +284,10 @@ impl wasmi::ModuleImportResolver for ImportResolver {
|
||||
{
|
||||
Err(Error::Instantiation("Module requested too much memory".to_owned()))
|
||||
} else {
|
||||
let mem = MemoryInstance::alloc(descriptor.initial(), descriptor.maximum())?;
|
||||
let mem = MemoryInstance::alloc(
|
||||
memory_units::Pages(descriptor.initial() as usize),
|
||||
descriptor.maximum().map(|x| memory_units::Pages(x as usize)),
|
||||
)?;
|
||||
*self.memory.borrow_mut() = Some(mem.clone());
|
||||
Ok(mem)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ mod panic_payload;
|
||||
mod parser;
|
||||
|
||||
use vm::{GasLeft, ReturnData, ActionParams};
|
||||
use wasmi::Error as InterpreterError;
|
||||
use wasmi::{Error as InterpreterError, Trap};
|
||||
|
||||
use runtime::{Runtime, RuntimeContext};
|
||||
|
||||
@@ -43,17 +43,29 @@ use bigint::uint::U256;
|
||||
|
||||
/// Wrapped interpreter error
|
||||
#[derive(Debug)]
|
||||
pub struct Error(InterpreterError);
|
||||
pub enum Error {
|
||||
Interpreter(InterpreterError),
|
||||
Trap(Trap),
|
||||
}
|
||||
|
||||
impl From<InterpreterError> for Error {
|
||||
fn from(e: InterpreterError) -> Self {
|
||||
Error(e)
|
||||
Error::Interpreter(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Trap> for Error {
|
||||
fn from(e: Trap) -> Self {
|
||||
Error::Trap(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for vm::Error {
|
||||
fn from(e: Error) -> Self {
|
||||
vm::Error::Wasm(format!("Wasm runtime error: {:?}", e.0))
|
||||
match e {
|
||||
Error::Interpreter(e) => vm::Error::Wasm(format!("Wasm runtime error: {:?}", e)),
|
||||
Error::Trap(e) => vm::Error::Wasm(format!("Wasm contract trap: {:?}", e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,19 +78,25 @@ impl From<runtime::Error> for vm::Error {
|
||||
}
|
||||
}
|
||||
|
||||
enum ExecutionOutcome {
|
||||
Suicide,
|
||||
Return,
|
||||
NotSpecial,
|
||||
}
|
||||
|
||||
impl vm::Vm for WasmInterpreter {
|
||||
|
||||
fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
|
||||
let (module, data) = parser::payload(¶ms, ext.schedule().wasm())?;
|
||||
|
||||
let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error)?;
|
||||
let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error::Interpreter)?;
|
||||
|
||||
let instantiation_resolover = env::ImportResolver::with_limit(16);
|
||||
let instantiation_resolver = env::ImportResolver::with_limit(16);
|
||||
|
||||
let module_instance = wasmi::ModuleInstance::new(
|
||||
&loaded_module,
|
||||
&wasmi::ImportsBuilder::new().with_resolver("env", &instantiation_resolover)
|
||||
).map_err(Error)?;
|
||||
&wasmi::ImportsBuilder::new().with_resolver("env", &instantiation_resolver)
|
||||
).map_err(Error::Interpreter)?;
|
||||
|
||||
let adjusted_gas = params.gas * U256::from(ext.schedule().wasm().opcodes_div) /
|
||||
U256::from(ext.schedule().wasm().opcodes_mul);
|
||||
@@ -88,13 +106,13 @@ impl vm::Vm for WasmInterpreter {
|
||||
return Err(vm::Error::Wasm("Wasm interpreter cannot run contracts with gas (wasm adjusted) >= 2^64".to_owned()));
|
||||
}
|
||||
|
||||
let initial_memory = instantiation_resolover.memory_size().map_err(Error)?;
|
||||
let initial_memory = instantiation_resolver.memory_size().map_err(Error::Interpreter)?;
|
||||
trace!(target: "wasm", "Contract requested {:?} pages of initial memory", initial_memory);
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut runtime = Runtime::with_params(
|
||||
ext,
|
||||
instantiation_resolover.memory_ref(),
|
||||
instantiation_resolver.memory_ref(),
|
||||
// cannot overflow, checked above
|
||||
adjusted_gas.low_u64(),
|
||||
data.to_vec(),
|
||||
@@ -115,33 +133,29 @@ impl vm::Vm for WasmInterpreter {
|
||||
assert!(runtime.schedule().wasm().initial_mem < 1 << 16);
|
||||
runtime.charge(|s| initial_memory as u64 * s.wasm().initial_mem as u64)?;
|
||||
|
||||
let module_instance = module_instance.run_start(&mut runtime).map_err(Error)?;
|
||||
let module_instance = module_instance.run_start(&mut runtime).map_err(Error::Trap)?;
|
||||
|
||||
match module_instance.invoke_export("call", &[], &mut runtime) {
|
||||
Ok(_) => { },
|
||||
Err(InterpreterError::Host(boxed)) => {
|
||||
match boxed.downcast_ref::<runtime::Error>() {
|
||||
None => {
|
||||
return Err(vm::Error::Wasm("Invalid user error used in interpreter".to_owned()));
|
||||
}
|
||||
Some(runtime_err) => {
|
||||
match *runtime_err {
|
||||
runtime::Error::Suicide => {
|
||||
// Suicide uses trap to break execution
|
||||
}
|
||||
ref any_err => {
|
||||
trace!(target: "wasm", "Error executing contract: {:?}", boxed);
|
||||
return Err(vm::Error::from(Error::from(InterpreterError::Host(Box::new(any_err.clone())))));
|
||||
}
|
||||
}
|
||||
}
|
||||
let invoke_result = module_instance.invoke_export("call", &[], &mut runtime);
|
||||
|
||||
let mut execution_outcome = ExecutionOutcome::NotSpecial;
|
||||
if let Err(InterpreterError::Trap(ref trap)) = invoke_result {
|
||||
if let wasmi::TrapKind::Host(ref boxed) = *trap.kind() {
|
||||
let ref runtime_err = boxed.downcast_ref::<runtime::Error>()
|
||||
.expect("Host errors other than runtime::Error never produced; qed");
|
||||
|
||||
match **runtime_err {
|
||||
runtime::Error::Suicide => { execution_outcome = ExecutionOutcome::Suicide; },
|
||||
runtime::Error::Return => { execution_outcome = ExecutionOutcome::Return; },
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
trace!(target: "wasm", "Error executing contract: {:?}", err);
|
||||
return Err(vm::Error::from(Error::from(err)))
|
||||
}
|
||||
}
|
||||
|
||||
if let (ExecutionOutcome::NotSpecial, Err(e)) = (execution_outcome, invoke_result) {
|
||||
trace!(target: "wasm", "Error executing contract: {:?}", e);
|
||||
return Err(vm::Error::from(Error::from(e)));
|
||||
}
|
||||
|
||||
(
|
||||
runtime.gas_left().expect("Cannot fail since it was not updated since last charge"),
|
||||
runtime.into_result(),
|
||||
|
||||
@@ -22,14 +22,18 @@ use parity_wasm::elements::{self, Deserialize};
|
||||
use parity_wasm::peek_size;
|
||||
|
||||
fn gas_rules(wasm_costs: &vm::WasmCosts) -> rules::Set {
|
||||
rules::Set::new({
|
||||
let mut vals = ::std::collections::HashMap::with_capacity(4);
|
||||
vals.insert(rules::InstructionType::Load, wasm_costs.mem as u32);
|
||||
vals.insert(rules::InstructionType::Store, wasm_costs.mem as u32);
|
||||
vals.insert(rules::InstructionType::Div, wasm_costs.div as u32);
|
||||
vals.insert(rules::InstructionType::Mul, wasm_costs.mul as u32);
|
||||
vals
|
||||
}).with_grow_cost(wasm_costs.grow_mem)
|
||||
rules::Set::new(
|
||||
wasm_costs.regular,
|
||||
{
|
||||
let mut vals = ::std::collections::HashMap::with_capacity(8);
|
||||
vals.insert(rules::InstructionType::Load, rules::Metering::Fixed(wasm_costs.mem as u32));
|
||||
vals.insert(rules::InstructionType::Store, rules::Metering::Fixed(wasm_costs.mem as u32));
|
||||
vals.insert(rules::InstructionType::Div, rules::Metering::Fixed(wasm_costs.div as u32));
|
||||
vals.insert(rules::InstructionType::Mul, rules::Metering::Fixed(wasm_costs.mul as u32));
|
||||
vals
|
||||
})
|
||||
.with_grow_cost(wasm_costs.grow_mem)
|
||||
.with_forbidden_floats()
|
||||
}
|
||||
|
||||
/// Splits payload to code and data according to params.params_type, also
|
||||
@@ -71,7 +75,12 @@ pub fn payload<'a>(params: &'a vm::ActionParams, wasm_costs: &vm::WasmCosts)
|
||||
let contract_module = wasm_utils::inject_gas_counter(
|
||||
deserialized_module,
|
||||
&gas_rules(wasm_costs),
|
||||
);
|
||||
).map_err(|_| vm::Error::Wasm(format!("Wasm contract error: bytecode invalid")))?;
|
||||
|
||||
let contract_module = wasm_utils::stack_height::inject_limiter(
|
||||
contract_module,
|
||||
wasm_costs.max_stack_height,
|
||||
).map_err(|_| vm::Error::Wasm(format!("Wasm contract error: stack limiter failure")))?;
|
||||
|
||||
let data = match params.params_type {
|
||||
vm::ParamsType::Embedded => {
|
||||
|
||||
@@ -20,7 +20,7 @@ use util::Address;
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use vm::{self, CallType};
|
||||
use wasmi::{self, MemoryRef, RuntimeArgs, RuntimeValue, Error as InterpreterError};
|
||||
use wasmi::{self, MemoryRef, RuntimeArgs, RuntimeValue, Error as InterpreterError, Trap, TrapKind};
|
||||
use super::panic_payload;
|
||||
|
||||
pub struct RuntimeContext {
|
||||
@@ -52,6 +52,8 @@ pub enum Error {
|
||||
MemoryAccessViolation,
|
||||
/// Native code resulted in suicide
|
||||
Suicide,
|
||||
/// Native code requested execution to finish
|
||||
Return,
|
||||
/// Suicide was requested but coudn't complete
|
||||
SuicideAbort,
|
||||
/// Invalid gas state inside interpreter
|
||||
@@ -72,15 +74,40 @@ pub enum Error {
|
||||
Other,
|
||||
/// Syscall signature mismatch
|
||||
InvalidSyscall,
|
||||
/// Unreachable instruction encountered
|
||||
Unreachable,
|
||||
/// Invalid virtual call
|
||||
InvalidVirtualCall,
|
||||
/// Division by zero
|
||||
DivisionByZero,
|
||||
/// Invalid conversion to integer
|
||||
InvalidConversionToInt,
|
||||
/// Stack overflow
|
||||
StackOverflow,
|
||||
/// Panic with message
|
||||
Panic(String),
|
||||
}
|
||||
|
||||
impl wasmi::HostError for Error { }
|
||||
|
||||
impl From<Trap> for Error {
|
||||
fn from(trap: Trap) -> Self {
|
||||
match *trap.kind() {
|
||||
TrapKind::Unreachable => Error::Unreachable,
|
||||
TrapKind::MemoryAccessOutOfBounds => Error::MemoryAccessViolation,
|
||||
TrapKind::TableAccessOutOfBounds | TrapKind::ElemUninitialized => Error::InvalidVirtualCall,
|
||||
TrapKind::DivisionByZero => Error::DivisionByZero,
|
||||
TrapKind::InvalidConversionToInt => Error::InvalidConversionToInt,
|
||||
TrapKind::UnexpectedSignature => Error::InvalidVirtualCall,
|
||||
TrapKind::StackOverflow => Error::StackOverflow,
|
||||
TrapKind::Host(_) => Error::Other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InterpreterError> for Error {
|
||||
fn from(interpreter_err: InterpreterError) -> Self {
|
||||
match interpreter_err {
|
||||
fn from(err: InterpreterError) -> Self {
|
||||
match err {
|
||||
InterpreterError::Value(_) => Error::InvalidSyscall,
|
||||
InterpreterError::Memory(_) => Error::MemoryAccessViolation,
|
||||
_ => Error::Other,
|
||||
@@ -98,6 +125,7 @@ impl ::std::fmt::Display for Error {
|
||||
Error::InvalidGasState => write!(f, "Invalid gas state"),
|
||||
Error::BalanceQueryError => write!(f, "Balance query resulted in an error"),
|
||||
Error::Suicide => write!(f, "Suicide result"),
|
||||
Error::Return => write!(f, "Return result"),
|
||||
Error::Unknown => write!(f, "Unknown runtime function invoked"),
|
||||
Error::AllocationFailed => write!(f, "Memory allocation failed (OOM)"),
|
||||
Error::BadUtf8 => write!(f, "String encoding is bad utf-8 sequence"),
|
||||
@@ -105,6 +133,11 @@ impl ::std::fmt::Display for Error {
|
||||
Error::Log => write!(f, "Error occured while logging an event"),
|
||||
Error::InvalidSyscall => write!(f, "Invalid syscall signature encountered at runtime"),
|
||||
Error::Other => write!(f, "Other unspecified error"),
|
||||
Error::Unreachable => write!(f, "Unreachable instruction encountered"),
|
||||
Error::InvalidVirtualCall => write!(f, "Invalid virtual call"),
|
||||
Error::DivisionByZero => write!(f, "Division by zero"),
|
||||
Error::StackOverflow => write!(f, "Stack overflow"),
|
||||
Error::InvalidConversionToInt => write!(f, "Invalid conversion to integer"),
|
||||
Error::Panic(ref msg) => write!(f, "Panic: {}", msg),
|
||||
}
|
||||
}
|
||||
@@ -161,12 +194,14 @@ impl<'a> Runtime<'a> {
|
||||
/// Intuition about the return value sense is to aswer the question 'are we allowed to continue?'
|
||||
fn charge_gas(&mut self, amount: u64) -> bool {
|
||||
let prev = self.gas_counter;
|
||||
if prev + amount > self.gas_limit {
|
||||
// exceeds gas
|
||||
false
|
||||
} else {
|
||||
self.gas_counter = prev + amount;
|
||||
true
|
||||
match prev.checked_add(amount) {
|
||||
// gas charge overflow protection
|
||||
None => false,
|
||||
Some(val) if val > self.gas_limit => false,
|
||||
Some(_) => {
|
||||
self.gas_counter = prev + amount;
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,8 +255,8 @@ impl<'a> Runtime<'a> {
|
||||
/// Read from the storage to wasm memory.
|
||||
pub fn storage_read(&mut self, args: RuntimeArgs) -> Result<()>
|
||||
{
|
||||
let key = self.h256_at(args.nth(0)?)?;
|
||||
let val_ptr: u32 = args.nth(1)?;
|
||||
let key = self.h256_at(args.nth_checked(0)?)?;
|
||||
let val_ptr: u32 = args.nth_checked(1)?;
|
||||
|
||||
let val = self.ext.storage_at(&key).map_err(|_| Error::StorageReadError)?;
|
||||
|
||||
@@ -235,8 +270,8 @@ impl<'a> Runtime<'a> {
|
||||
/// Write to storage from wasm memory.
|
||||
pub fn storage_write(&mut self, args: RuntimeArgs) -> Result<()>
|
||||
{
|
||||
let key = self.h256_at(args.nth(0)?)?;
|
||||
let val_ptr: u32 = args.nth(1)?;
|
||||
let key = self.h256_at(args.nth_checked(0)?)?;
|
||||
let val_ptr: u32 = args.nth_checked(1)?;
|
||||
|
||||
let val = self.h256_at(val_ptr)?;
|
||||
let former_val = self.ext.storage_at(&key).map_err(|_| Error::StorageUpdateError)?;
|
||||
@@ -264,14 +299,14 @@ impl<'a> Runtime<'a> {
|
||||
/// Return. Syscall takes 2 arguments - pointer in sandboxed memory where result is and
|
||||
/// the length of the result.
|
||||
pub fn ret(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let ptr: u32 = args.nth(0)?;
|
||||
let len: u32 = args.nth(1)?;
|
||||
let ptr: u32 = args.nth_checked(0)?;
|
||||
let len: u32 = args.nth_checked(1)?;
|
||||
|
||||
trace!(target: "wasm", "Contract ret: {} bytes @ {}", len, ptr);
|
||||
|
||||
self.result = self.memory.get(ptr, len as usize)?;
|
||||
|
||||
Ok(())
|
||||
Err(Error::Return)
|
||||
}
|
||||
|
||||
/// Destroy the runtime, returning currently recorded result of the execution.
|
||||
@@ -287,7 +322,7 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
/// Report gas cost with the params passed in wasm stack
|
||||
fn gas(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let amount: u32 = args.nth(0)?;
|
||||
let amount: u32 = args.nth_checked(0)?;
|
||||
if self.charge_gas(amount as u64) {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -302,7 +337,10 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
/// Write input bytes to the memory location using the passed pointer
|
||||
fn fetch_input(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let ptr: u32 = args.nth(0)?;
|
||||
let args_len = self.args.len() as u64;
|
||||
self.charge(|s| args_len * s.wasm().memcpy as u64)?;
|
||||
|
||||
let ptr: u32 = args.nth_checked(0)?;
|
||||
self.memory.set(ptr, &self.args[..])?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -310,8 +348,8 @@ impl<'a> Runtime<'a> {
|
||||
/// User panic. Contract can invoke this when he encounters unrecoverable error.
|
||||
fn panic(&mut self, args: RuntimeArgs) -> Result<()>
|
||||
{
|
||||
let payload_ptr: u32 = args.nth(0)?;
|
||||
let payload_len: u32 = args.nth(1)?;
|
||||
let payload_ptr: u32 = args.nth_checked(0)?;
|
||||
let payload_len: u32 = args.nth_checked(1)?;
|
||||
|
||||
let raw_payload = self.memory.get(payload_ptr, payload_len as usize)?;
|
||||
let payload = panic_payload::decode(&raw_payload);
|
||||
@@ -345,26 +383,26 @@ impl<'a> Runtime<'a> {
|
||||
{
|
||||
trace!(target: "wasm", "runtime: CALL({:?})", call_type);
|
||||
|
||||
let gas: u64 = args.nth(0)?;
|
||||
let gas: u64 = args.nth_checked(0)?;
|
||||
trace!(target: "wasm", " gas: {:?}", gas);
|
||||
|
||||
let address = self.address_at(args.nth(1)?)?;
|
||||
let address = self.address_at(args.nth_checked(1)?)?;
|
||||
trace!(target: "wasm", " address: {:?}", address);
|
||||
|
||||
let vofs = if use_val { 1 } else { 0 };
|
||||
let val = if use_val { Some(self.u256_at(args.nth(2)?)?) } else { None };
|
||||
let val = if use_val { Some(self.u256_at(args.nth_checked(2)?)?) } else { None };
|
||||
trace!(target: "wasm", " val: {:?}", val);
|
||||
|
||||
let input_ptr: u32 = args.nth(2 + vofs)?;
|
||||
let input_ptr: u32 = args.nth_checked(2 + vofs)?;
|
||||
trace!(target: "wasm", " input_ptr: {:?}", input_ptr);
|
||||
|
||||
let input_len: u32 = args.nth(3 + vofs)?;
|
||||
let input_len: u32 = args.nth_checked(3 + vofs)?;
|
||||
trace!(target: "wasm", " input_len: {:?}", input_len);
|
||||
|
||||
let result_ptr: u32 = args.nth(4 + vofs)?;
|
||||
let result_ptr: u32 = args.nth_checked(4 + vofs)?;
|
||||
trace!(target: "wasm", " result_ptr: {:?}", result_ptr);
|
||||
|
||||
let result_alloc_len: u32 = args.nth(5 + vofs)?;
|
||||
let result_alloc_len: u32 = args.nth_checked(5 + vofs)?;
|
||||
trace!(target: "wasm", " result_len: {:?}", result_alloc_len);
|
||||
|
||||
if let Some(ref val) = val {
|
||||
@@ -464,7 +502,7 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
pub fn value(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let val = self.context.value;
|
||||
self.return_u256_ptr(args.nth(0)?, val)
|
||||
self.return_u256_ptr(args.nth_checked(0)?, val)
|
||||
}
|
||||
|
||||
pub fn create(&mut self, args: RuntimeArgs) -> Result<RuntimeValue>
|
||||
@@ -474,13 +512,13 @@ impl<'a> Runtime<'a> {
|
||||
// fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
|
||||
//
|
||||
trace!(target: "wasm", "runtime: CREATE");
|
||||
let endowment = self.u256_at(args.nth(0)?)?;
|
||||
let endowment = self.u256_at(args.nth_checked(0)?)?;
|
||||
trace!(target: "wasm", " val: {:?}", endowment);
|
||||
let code_ptr: u32 = args.nth(1)?;
|
||||
let code_ptr: u32 = args.nth_checked(1)?;
|
||||
trace!(target: "wasm", " code_ptr: {:?}", code_ptr);
|
||||
let code_len: u32 = args.nth(2)?;
|
||||
let code_len: u32 = args.nth_checked(2)?;
|
||||
trace!(target: "wasm", " code_len: {:?}", code_len);
|
||||
let result_ptr: u32 = args.nth(3)?;
|
||||
let result_ptr: u32 = args.nth_checked(3)?;
|
||||
trace!(target: "wasm", "result_ptr: {:?}", result_ptr);
|
||||
|
||||
let code = self.memory.get(code_ptr, code_len as usize)?;
|
||||
@@ -522,13 +560,13 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
fn debug(&mut self, args: RuntimeArgs) -> Result<()>
|
||||
{
|
||||
let msg_ptr: u32 = args.nth(0)?;
|
||||
let msg_len: u32 = args.nth(1)?;
|
||||
trace!(target: "wasm", "Contract debug message: {}", {
|
||||
let msg_ptr: u32 = args.nth_checked(0)?;
|
||||
let msg_len: u32 = args.nth_checked(1)?;
|
||||
|
||||
let msg = String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
|
||||
.map_err(|_| Error::BadUtf8)?;
|
||||
|
||||
trace!(target: "wasm", "Contract debug message: {}", msg);
|
||||
String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
|
||||
.map_err(|_| Error::BadUtf8)?
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -536,7 +574,7 @@ impl<'a> Runtime<'a> {
|
||||
/// Pass suicide to state runtime
|
||||
pub fn suicide(&mut self, args: RuntimeArgs) -> Result<()>
|
||||
{
|
||||
let refund_address = self.address_at(args.nth(0)?)?;
|
||||
let refund_address = self.address_at(args.nth_checked(0)?)?;
|
||||
|
||||
if self.ext.exists(&refund_address).map_err(|_| Error::SuicideAbort)? {
|
||||
trace!(target: "wasm", "Suicide: refund to existing address {}", refund_address);
|
||||
@@ -554,8 +592,8 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
pub fn blockhash(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
self.adjusted_charge(|schedule| schedule.blockhash_gas as u64)?;
|
||||
let hash = self.ext.blockhash(&U256::from(args.nth::<u64>(0)?));
|
||||
self.memory.set(args.nth(1)?, &*hash)?;
|
||||
let hash = self.ext.blockhash(&U256::from(args.nth_checked::<u64>(0)?));
|
||||
self.memory.set(args.nth_checked(1)?, &*hash)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -566,32 +604,32 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
pub fn coinbase(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let coinbase = self.ext.env_info().author;
|
||||
self.return_address_ptr(args.nth(0)?, coinbase)
|
||||
self.return_address_ptr(args.nth_checked(0)?, coinbase)
|
||||
}
|
||||
|
||||
pub fn difficulty(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let difficulty = self.ext.env_info().difficulty;
|
||||
self.return_u256_ptr(args.nth(0)?, difficulty)
|
||||
self.return_u256_ptr(args.nth_checked(0)?, difficulty)
|
||||
}
|
||||
|
||||
pub fn gaslimit(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let gas_limit = self.ext.env_info().gas_limit;
|
||||
self.return_u256_ptr(args.nth(0)?, gas_limit)
|
||||
self.return_u256_ptr(args.nth_checked(0)?, gas_limit)
|
||||
}
|
||||
|
||||
pub fn address(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let address = self.context.address;
|
||||
self.return_address_ptr(args.nth(0)?, address)
|
||||
self.return_address_ptr(args.nth_checked(0)?, address)
|
||||
}
|
||||
|
||||
pub fn sender(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let sender = self.context.sender;
|
||||
self.return_address_ptr(args.nth(0)?, sender)
|
||||
self.return_address_ptr(args.nth_checked(0)?, sender)
|
||||
}
|
||||
|
||||
pub fn origin(&mut self, args: RuntimeArgs) -> Result<()> {
|
||||
let origin = self.context.origin;
|
||||
self.return_address_ptr(args.nth(0)?, origin)
|
||||
self.return_address_ptr(args.nth_checked(0)?, origin)
|
||||
}
|
||||
|
||||
pub fn timestamp(&mut self) -> Result<RuntimeValue> {
|
||||
@@ -601,12 +639,10 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
pub fn elog(&mut self, args: RuntimeArgs) -> Result<()>
|
||||
{
|
||||
// signature is:
|
||||
// pub fn elog(topic_ptr: *const u8, topic_count: u32, data_ptr: *const u8, data_len: u32);
|
||||
let topic_ptr: u32 = args.nth(0)?;
|
||||
let topic_count: u32 = args.nth(1)?;
|
||||
let data_ptr: u32 = args.nth(2)?;
|
||||
let data_len: u32 = args.nth(3)?;
|
||||
let topic_ptr: u32 = args.nth_checked(0)?;
|
||||
let topic_count: u32 = args.nth_checked(1)?;
|
||||
let data_ptr: u32 = args.nth_checked(2)?;
|
||||
let data_len: u32 = args.nth_checked(3)?;
|
||||
|
||||
if topic_count > 4 {
|
||||
return Err(Error::Log.into());
|
||||
@@ -639,7 +675,7 @@ impl<'a> Runtime<'a> {
|
||||
|
||||
mod ext_impl {
|
||||
|
||||
use wasmi::{Externals, RuntimeArgs, RuntimeValue, Error};
|
||||
use wasmi::{Externals, RuntimeArgs, RuntimeValue, Trap};
|
||||
use env::ids::*;
|
||||
|
||||
macro_rules! void {
|
||||
@@ -659,7 +695,7 @@ mod ext_impl {
|
||||
&mut self,
|
||||
index: usize,
|
||||
args: RuntimeArgs,
|
||||
) -> Result<Option<RuntimeValue>, Error> {
|
||||
) -> Result<Option<RuntimeValue>, Trap> {
|
||||
match index {
|
||||
STORAGE_WRITE_FUNC => void!(self.storage_write(args)),
|
||||
STORAGE_READ_FUNC => void!(self.storage_read(args)),
|
||||
|
||||
@@ -209,7 +209,7 @@ fn dispersion() {
|
||||
result,
|
||||
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(93_972));
|
||||
assert_eq!(gas_left, U256::from(94_013));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -237,7 +237,7 @@ fn suicide_not() {
|
||||
result,
|
||||
vec![0u8]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(94_970));
|
||||
assert_eq!(gas_left, U256::from(94_984));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -269,7 +269,7 @@ fn suicide() {
|
||||
};
|
||||
|
||||
assert!(ext.suicides.contains(&refund));
|
||||
assert_eq!(gas_left, U256::from(94_933));
|
||||
assert_eq!(gas_left, U256::from(94_925));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -299,7 +299,7 @@ fn create() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Create,
|
||||
gas: U256::from(60_917),
|
||||
gas: U256::from(60_914),
|
||||
sender_address: None,
|
||||
receive_address: None,
|
||||
value: Some(1_000_000_000.into()),
|
||||
@@ -307,7 +307,7 @@ fn create() {
|
||||
code_address: None,
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(60_903));
|
||||
assert_eq!(gas_left, U256::from(60_900));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -467,7 +467,7 @@ fn realloc() {
|
||||
}
|
||||
};
|
||||
assert_eq!(result, vec![0u8; 2]);
|
||||
assert_eq!(gas_left, U256::from(94_352));
|
||||
assert_eq!(gas_left, U256::from(94_372));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -543,7 +543,7 @@ fn keccak() {
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(84_223));
|
||||
assert_eq!(gas_left, U256::from(84_240));
|
||||
}
|
||||
|
||||
// math_* tests check the ability of wasm contract to perform big integer operations
|
||||
@@ -572,7 +572,7 @@ fn math_add() {
|
||||
U256::from_dec_str("1888888888888888888888888888887").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(93_818));
|
||||
assert_eq!(gas_left, U256::from(93_814));
|
||||
}
|
||||
|
||||
// multiplication
|
||||
@@ -594,7 +594,7 @@ fn math_mul() {
|
||||
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(93_304));
|
||||
assert_eq!(gas_left, U256::from(93_300));
|
||||
}
|
||||
|
||||
// subtraction
|
||||
@@ -616,7 +616,7 @@ fn math_sub() {
|
||||
U256::from_dec_str("111111111111111111111111111111").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(93_831));
|
||||
assert_eq!(gas_left, U256::from(93_826));
|
||||
}
|
||||
|
||||
// subtraction with overflow
|
||||
@@ -658,7 +658,7 @@ fn math_div() {
|
||||
U256::from_dec_str("1125000").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(90_607));
|
||||
assert_eq!(gas_left, U256::from(90_603));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -686,7 +686,7 @@ fn storage_metering() {
|
||||
};
|
||||
|
||||
// 0 -> not 0
|
||||
assert_eq!(gas_left, U256::from(74_410));
|
||||
assert_eq!(gas_left, U256::from(74_338));
|
||||
|
||||
// #2
|
||||
|
||||
@@ -705,7 +705,7 @@ fn storage_metering() {
|
||||
};
|
||||
|
||||
// not 0 -> not 0
|
||||
assert_eq!(gas_left, U256::from(89_410));
|
||||
assert_eq!(gas_left, U256::from(89_338));
|
||||
}
|
||||
|
||||
// This test checks the ability of wasm contract to invoke
|
||||
@@ -793,7 +793,7 @@ fn externs() {
|
||||
"Gas limit requested and returned does not match"
|
||||
);
|
||||
|
||||
assert_eq!(gas_left, U256::from(92_089));
|
||||
assert_eq!(gas_left, U256::from(92_110));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -819,7 +819,7 @@ fn embedded_keccak() {
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(84_223));
|
||||
assert_eq!(gas_left, U256::from(84_240));
|
||||
}
|
||||
|
||||
/// This test checks the correctness of log extern
|
||||
@@ -854,5 +854,5 @@ fn events() {
|
||||
assert_eq!(&log_entry.data, b"gnihtemos");
|
||||
|
||||
assert_eq!(&result, b"gnihtemos");
|
||||
assert_eq!(gas_left, U256::from(81_235));
|
||||
assert_eq!(gas_left, U256::from(81_292));
|
||||
}
|
||||
|
||||
@@ -9,4 +9,4 @@ tiny-keccak = "1.3"
|
||||
eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
|
||||
ethkey = { path = "../ethkey" }
|
||||
ethcore-bigint = { path = "../util/bigint" }
|
||||
subtle = "0.1"
|
||||
subtle = "0.5"
|
||||
|
||||
@@ -308,7 +308,7 @@ pub mod ecies {
|
||||
hmac.raw_result(&mut mac);
|
||||
|
||||
// constant time compare to avoid timing attack.
|
||||
if ::subtle::arrays_equal(&mac[..], msg_mac) != 1 {
|
||||
if ::subtle::slices_equal(&mac[..], msg_mac) != 1 {
|
||||
return Err(Error::InvalidMessage);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ ethcore-bigint = { path = "../util/bigint" }
|
||||
dir = { path = "../util/dir" }
|
||||
smallvec = "0.4"
|
||||
parity-wordlist = "1.0"
|
||||
subtle = "0.5"
|
||||
tempdir = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
matches = "0.1"
|
||||
|
||||
[lib]
|
||||
|
||||
@@ -266,7 +266,7 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
|
||||
let password = load_password(&args.arg_password)?;
|
||||
let account_ref = open_args_vault_account(&store, address, &args)?;
|
||||
let signature = store.sign(&account_ref, &password, &message)?;
|
||||
Ok(format!("0x{:?}", signature))
|
||||
Ok(format!("0x{}", signature))
|
||||
} else if args.cmd_public {
|
||||
let address = args.arg_address.parse().map_err(|_| ethstore::Error::InvalidAccount)?;
|
||||
let password = load_password(&args.arg_password)?;
|
||||
|
||||
@@ -21,6 +21,7 @@ use crypto::Keccak256;
|
||||
use random::Random;
|
||||
use smallvec::SmallVec;
|
||||
use account::{Cipher, Kdf, Aes128Ctr, Pbkdf2, Prf};
|
||||
use subtle;
|
||||
|
||||
/// Encrypted data
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
@@ -136,7 +137,7 @@ impl Crypto {
|
||||
|
||||
let mac = crypto::derive_mac(&derived_right_bits, &self.ciphertext).keccak256();
|
||||
|
||||
if mac != self.mac {
|
||||
if subtle::slices_equal(&mac, &self.mac) == 0 {
|
||||
return Err(Error::InvalidPassword);
|
||||
}
|
||||
|
||||
@@ -158,7 +159,7 @@ impl Crypto {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ethkey::{Generator, Random};
|
||||
use super::Crypto;
|
||||
use super::{Crypto, Error};
|
||||
|
||||
#[test]
|
||||
fn crypto_with_secret_create() {
|
||||
@@ -169,11 +170,10 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn crypto_with_secret_invalid_password() {
|
||||
let keypair = Random.generate().unwrap();
|
||||
let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240);
|
||||
let _ = crypto.secret("this is sparta!").unwrap();
|
||||
assert_matches!(crypto.secret("this is sparta!"), Err(Error::InvalidPassword))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -28,6 +28,7 @@ extern crate rustc_hex;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate smallvec;
|
||||
extern crate subtle;
|
||||
extern crate time;
|
||||
extern crate tiny_keccak;
|
||||
extern crate tempdir;
|
||||
@@ -42,7 +43,11 @@ extern crate log;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
pub mod accounts_dir;
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate matches;
|
||||
|
||||
pub mod accounts_dir;
|
||||
pub mod ethkey;
|
||||
|
||||
mod account;
|
||||
|
||||
@@ -22,16 +22,21 @@ use super::{WalletInfo, KeyPath};
|
||||
use bigint::hash::H256;
|
||||
use ethkey::{Address, Signature};
|
||||
use hidapi;
|
||||
use libusb;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
|
||||
use std::cmp::min;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::Duration;
|
||||
use std::thread;
|
||||
|
||||
/// Ledger vendor ID
|
||||
pub const LEDGER_VID: u16 = 0x2c97;
|
||||
/// Legder product IDs: [Nano S and Blue]
|
||||
pub const LEDGER_PIDS: [u16; 2] = [0x0000, 0x0001];
|
||||
|
||||
const LEDGER_VID: u16 = 0x2c97;
|
||||
const LEDGER_PIDS: [u16; 2] = [0x0000, 0x0001]; // Nano S and Blue
|
||||
const ETH_DERIVATION_PATH_BE: [u8; 17] = [4, 0x80, 0, 0, 44, 0x80, 0, 0, 60, 0x80, 0, 0, 0, 0, 0, 0, 0]; // 44'/60'/0'/0
|
||||
const ETC_DERIVATION_PATH_BE: [u8; 21] = [5, 0x80, 0, 0, 44, 0x80, 0, 0, 60, 0x80, 0x02, 0x73, 0xd0, 0x80, 0, 0, 0, 0, 0, 0, 0]; // 44'/60'/160720'/0'/0
|
||||
|
||||
@@ -54,10 +59,14 @@ pub enum Error {
|
||||
Protocol(&'static str),
|
||||
/// Hidapi error.
|
||||
Usb(hidapi::HidError),
|
||||
/// Libusb error
|
||||
LibUsb(libusb::Error),
|
||||
/// Device with request key is not available.
|
||||
KeyNotFound,
|
||||
/// Signing has been cancelled by user.
|
||||
UserCancel,
|
||||
/// Invalid Device
|
||||
InvalidDevice,
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@@ -65,8 +74,10 @@ impl fmt::Display for Error {
|
||||
match *self {
|
||||
Error::Protocol(ref s) => write!(f, "Ledger protocol error: {}", s),
|
||||
Error::Usb(ref e) => write!(f, "USB communication error: {}", e),
|
||||
Error::LibUsb(ref e) => write!(f, "LibUSB communication error: {}", e),
|
||||
Error::KeyNotFound => write!(f, "Key not found"),
|
||||
Error::UserCancel => write!(f, "Operation has been cancelled"),
|
||||
Error::InvalidDevice => write!(f, "Unsupported product was entered"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +88,12 @@ impl From<hidapi::HidError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<libusb::Error> for Error {
|
||||
fn from(err: libusb::Error) -> Error {
|
||||
Error::LibUsb(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// Ledger device manager.
|
||||
pub struct Manager {
|
||||
usb: Arc<Mutex<hidapi::HidApi>>,
|
||||
@@ -234,16 +251,7 @@ impl Manager {
|
||||
fn open_path<R, F>(&self, f: F) -> Result<R, Error>
|
||||
where F: Fn() -> Result<R, &'static str>
|
||||
{
|
||||
let mut err = Error::KeyNotFound;
|
||||
// Try to open device a few times.
|
||||
for _ in 0..10 {
|
||||
match f() {
|
||||
Ok(handle) => return Ok(handle),
|
||||
Err(e) => err = From::from(e),
|
||||
}
|
||||
::std::thread::sleep(Duration::from_millis(200));
|
||||
}
|
||||
Err(err)
|
||||
f().map_err(Into::into)
|
||||
}
|
||||
|
||||
fn send_apdu(handle: &hidapi::HidDevice, command: u8, p1: u8, p2: u8, data: &[u8]) -> Result<Vec<u8>, Error> {
|
||||
@@ -333,6 +341,54 @@ impl Manager {
|
||||
message.truncate(new_len);
|
||||
Ok(message)
|
||||
}
|
||||
|
||||
fn is_valid_ledger(device: &libusb::Device) -> Result<(), Error> {
|
||||
let desc = device.device_descriptor()?;
|
||||
let vendor_id = desc.vendor_id();
|
||||
let product_id = desc.product_id();
|
||||
|
||||
if vendor_id == LEDGER_VID && LEDGER_PIDS.contains(&product_id) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::InvalidDevice)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Ledger event handler
|
||||
/// A seperate thread is handling incoming events
|
||||
pub struct EventHandler {
|
||||
ledger: Weak<Manager>,
|
||||
}
|
||||
|
||||
impl EventHandler {
|
||||
/// Ledger event handler constructor
|
||||
pub fn new(ledger: Weak<Manager>) -> Self {
|
||||
Self { ledger: ledger }
|
||||
}
|
||||
}
|
||||
|
||||
impl libusb::Hotplug for EventHandler {
|
||||
fn device_arrived(&mut self, device: libusb::Device) {
|
||||
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
|
||||
debug!(target: "hw", "Ledger arrived");
|
||||
// Wait for the device to boot up
|
||||
thread::sleep(Duration::from_millis(1000));
|
||||
if let Err(e) = ledger.update_devices() {
|
||||
debug!(target: "hw", "Ledger connect error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn device_left(&mut self, device: libusb::Device) {
|
||||
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
|
||||
debug!(target: "hw", "Ledger left");
|
||||
if let Err(e) = ledger.update_devices() {
|
||||
debug!(target: "hw", "Ledger disconnect error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
114
hw/src/lib.rs
114
hw/src/lib.rs
@@ -33,13 +33,15 @@ use ethkey::{Address, Signature};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use std::fmt;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use bigint::prelude::uint::U256;
|
||||
|
||||
const USB_DEVICE_CLASS_DEVICE: u8 = 0;
|
||||
|
||||
/// Hardware wallet error.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
@@ -128,84 +130,78 @@ impl From<libusb::Error> for Error {
|
||||
|
||||
/// Hardware wallet management interface.
|
||||
pub struct HardwareWalletManager {
|
||||
update_thread: Option<thread::JoinHandle<()>>,
|
||||
exiting: Arc<AtomicBool>,
|
||||
ledger: Arc<ledger::Manager>,
|
||||
trezor: Arc<trezor::Manager>,
|
||||
}
|
||||
|
||||
struct EventHandler {
|
||||
ledger: Weak<ledger::Manager>,
|
||||
trezor: Weak<trezor::Manager>,
|
||||
}
|
||||
|
||||
impl libusb::Hotplug for EventHandler {
|
||||
fn device_arrived(&mut self, _device: libusb::Device) {
|
||||
debug!("USB Device arrived");
|
||||
if let (Some(l), Some(t)) = (self.ledger.upgrade(), self.trezor.upgrade()) {
|
||||
for _ in 0..10 {
|
||||
let l_devices = l.update_devices().unwrap_or_else(|e| {
|
||||
debug!("Error enumerating Ledger devices: {}", e);
|
||||
0
|
||||
});
|
||||
let t_devices = t.update_devices().unwrap_or_else(|e| {
|
||||
debug!("Error enumerating Trezor devices: {}", e);
|
||||
0
|
||||
});
|
||||
if l_devices + t_devices > 0 {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn device_left(&mut self, _device: libusb::Device) {
|
||||
debug!("USB Device lost");
|
||||
if let (Some(l), Some(t)) = (self.ledger.upgrade(), self.trezor.upgrade()) {
|
||||
l.update_devices().unwrap_or_else(|e| {debug!("Error enumerating Ledger devices: {}", e); 0});
|
||||
t.update_devices().unwrap_or_else(|e| {debug!("Error enumerating Trezor devices: {}", e); 0});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HardwareWalletManager {
|
||||
/// Hardware wallet constructor
|
||||
pub fn new() -> Result<HardwareWalletManager, Error> {
|
||||
let usb_context = Arc::new(libusb::Context::new()?);
|
||||
let usb_context_trezor = Arc::new(libusb::Context::new()?);
|
||||
let usb_context_ledger = Arc::new(libusb::Context::new()?);
|
||||
let hidapi = Arc::new(Mutex::new(hidapi::HidApi::new().map_err(|e| Error::Hid(e.to_string().clone()))?));
|
||||
let ledger = Arc::new(ledger::Manager::new(hidapi.clone()));
|
||||
let trezor = Arc::new(trezor::Manager::new(hidapi.clone()));
|
||||
usb_context.register_callback(
|
||||
None, None, None,
|
||||
Box::new(EventHandler {
|
||||
ledger: Arc::downgrade(&ledger),
|
||||
trezor: Arc::downgrade(&trezor),
|
||||
}),
|
||||
)?;
|
||||
|
||||
// Subscribe to TREZOR V1
|
||||
// Note, this support only TREZOR V1 becasue TREZOR V2 has another vendorID for some reason
|
||||
// Also, we now only support one product as the second argument specifies
|
||||
usb_context_trezor.register_callback(
|
||||
Some(trezor::TREZOR_VID), Some(trezor::TREZOR_PIDS[0]), Some(USB_DEVICE_CLASS_DEVICE),
|
||||
Box::new(trezor::EventHandler::new(Arc::downgrade(&trezor))))?;
|
||||
|
||||
// Subscribe to all Ledger Devices
|
||||
// This means that we need to check that the given productID is supported
|
||||
// None => LIBUSB_HOTPLUG_MATCH_ANY, in other words that all are subscribed to
|
||||
// More info can be found: http://libusb.sourceforge.net/api-1.0/group__hotplug.html#gae6c5f1add6cc754005549c7259dc35ea
|
||||
usb_context_ledger.register_callback(
|
||||
Some(ledger::LEDGER_VID), None, Some(USB_DEVICE_CLASS_DEVICE),
|
||||
Box::new(ledger::EventHandler::new(Arc::downgrade(&ledger))))?;
|
||||
|
||||
let exiting = Arc::new(AtomicBool::new(false));
|
||||
let thread_exiting = exiting.clone();
|
||||
let thread_exiting_ledger = exiting.clone();
|
||||
let thread_exiting_trezor = exiting.clone();
|
||||
let l = ledger.clone();
|
||||
let t = trezor.clone();
|
||||
let thread = thread::Builder::new()
|
||||
.name("hw_wallet".to_string())
|
||||
|
||||
// Ledger event thread
|
||||
thread::Builder::new()
|
||||
.name("hw_wallet_ledger".to_string())
|
||||
.spawn(move || {
|
||||
if let Err(e) = l.update_devices() {
|
||||
debug!("Error updating ledger devices: {}", e);
|
||||
}
|
||||
if let Err(e) = t.update_devices() {
|
||||
debug!("Error updating trezor devices: {}", e);
|
||||
debug!(target: "hw", "Ledger couldn't connect at startup, error: {}", e);
|
||||
//debug!("Ledger could not connect at startup, error: {}", e);
|
||||
}
|
||||
loop {
|
||||
usb_context.handle_events(Some(Duration::from_millis(500)))
|
||||
.unwrap_or_else(|e| debug!("Error processing USB events: {}", e));
|
||||
if thread_exiting.load(atomic::Ordering::Acquire) {
|
||||
usb_context_ledger.handle_events(Some(Duration::from_millis(500)))
|
||||
.unwrap_or_else(|e| debug!(target: "hw", "Ledger event handler error: {}", e));
|
||||
if thread_exiting_ledger.load(atomic::Ordering::Acquire) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
|
||||
// Trezor event thread
|
||||
thread::Builder::new()
|
||||
.name("hw_wallet_trezor".to_string())
|
||||
.spawn(move || {
|
||||
if let Err(e) = t.update_devices() {
|
||||
debug!(target: "hw", "Trezor couldn't connect at startup, error: {}", e);
|
||||
}
|
||||
loop {
|
||||
usb_context_trezor.handle_events(Some(Duration::from_millis(500)))
|
||||
.unwrap_or_else(|e| debug!(target: "hw", "Trezor event handler error: {}", e));
|
||||
if thread_exiting_trezor.load(atomic::Ordering::Acquire) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
|
||||
Ok(HardwareWalletManager {
|
||||
update_thread: thread,
|
||||
exiting: exiting,
|
||||
ledger: ledger,
|
||||
trezor: trezor,
|
||||
@@ -259,10 +255,10 @@ impl HardwareWalletManager {
|
||||
|
||||
impl Drop for HardwareWalletManager {
|
||||
fn drop(&mut self) {
|
||||
// Indicate to the USB Hotplug handlers that they
|
||||
// shall terminate but don't wait for them to terminate.
|
||||
// If they don't terminate for some reason USB Hotplug events will be handled
|
||||
// even if the HardwareWalletManger has been dropped
|
||||
self.exiting.store(true, atomic::Ordering::Release);
|
||||
if let Some(thread) = self.update_thread.take() {
|
||||
thread.thread().unpark();
|
||||
thread.join().ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,23 +24,26 @@ use super::{WalletInfo, TransactionInfo, KeyPath};
|
||||
use bigint::hash::H256;
|
||||
use ethkey::{Address, Signature};
|
||||
use hidapi;
|
||||
use libusb;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use protobuf;
|
||||
use protobuf::{Message, ProtobufEnum};
|
||||
use std::cmp::{min, max};
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::Duration;
|
||||
use bigint::prelude::uint::U256;
|
||||
|
||||
use trezor_sys::messages::{EthereumAddress, PinMatrixAck, MessageType, EthereumTxRequest, EthereumSignTx, EthereumGetAddress, EthereumTxAck, ButtonAck};
|
||||
|
||||
const TREZOR_VID: u16 = 0x534c;
|
||||
const TREZOR_PIDS: [u16; 1] = [0x0001]; // Trezor v1, keeping this as an array to leave room for Trezor v2 which is in progress
|
||||
/// Trezor v1 vendor ID
|
||||
pub const TREZOR_VID: u16 = 0x534c;
|
||||
/// Trezor product IDs
|
||||
pub const TREZOR_PIDS: [u16; 1] = [0x0001];
|
||||
|
||||
const ETH_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003C, 0x80000000, 0, 0]; // m/44'/60'/0'/0/0
|
||||
const ETC_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003D, 0x80000000, 0, 0]; // m/44'/61'/0'/0/0
|
||||
|
||||
|
||||
/// Hardware wallet error.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
@@ -55,7 +58,7 @@ pub enum Error {
|
||||
/// The Message Type given in the trezor RPC call is not something we recognize
|
||||
BadMessageType,
|
||||
/// Trying to read from a closed device at the given path
|
||||
ClosedDevice(String),
|
||||
LockedDevice(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@@ -66,7 +69,7 @@ impl fmt::Display for Error {
|
||||
Error::KeyNotFound => write!(f, "Key not found"),
|
||||
Error::UserCancel => write!(f, "Operation has been cancelled"),
|
||||
Error::BadMessageType => write!(f, "Bad Message Type in RPC call"),
|
||||
Error::ClosedDevice(ref s) => write!(f, "Device is closed, needs PIN to perform operations: {}", s),
|
||||
Error::LockedDevice(ref s) => write!(f, "Device is locked, needs PIN to perform operations: {}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,11 +86,11 @@ impl From<protobuf::ProtobufError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// Ledger device manager.
|
||||
/// Ledger device manager
|
||||
pub struct Manager {
|
||||
usb: Arc<Mutex<hidapi::HidApi>>,
|
||||
devices: RwLock<Vec<Device>>,
|
||||
closed_devices: RwLock<Vec<String>>,
|
||||
locked_devices: RwLock<Vec<String>>,
|
||||
key_path: RwLock<KeyPath>,
|
||||
}
|
||||
|
||||
@@ -109,7 +112,7 @@ impl Manager {
|
||||
Manager {
|
||||
usb: hidapi,
|
||||
devices: RwLock::new(Vec::new()),
|
||||
closed_devices: RwLock::new(Vec::new()),
|
||||
locked_devices: RwLock::new(Vec::new()),
|
||||
key_path: RwLock::new(KeyPath::Ethereum),
|
||||
}
|
||||
}
|
||||
@@ -120,7 +123,7 @@ impl Manager {
|
||||
usb.refresh_devices();
|
||||
let devices = usb.devices();
|
||||
let mut new_devices = Vec::new();
|
||||
let mut closed_devices = Vec::new();
|
||||
let mut locked_devices = Vec::new();
|
||||
let mut error = None;
|
||||
for usb_device in devices {
|
||||
let is_trezor = usb_device.vendor_id == TREZOR_VID;
|
||||
@@ -139,7 +142,7 @@ impl Manager {
|
||||
}
|
||||
match self.read_device_info(&usb, &usb_device) {
|
||||
Ok(device) => new_devices.push(device),
|
||||
Err(Error::ClosedDevice(path)) => closed_devices.push(path.to_string()),
|
||||
Err(Error::LockedDevice(path)) => locked_devices.push(path.to_string()),
|
||||
Err(e) => {
|
||||
warn!("Error reading device: {:?}", e);
|
||||
error = Some(e);
|
||||
@@ -147,9 +150,9 @@ impl Manager {
|
||||
}
|
||||
}
|
||||
let count = new_devices.len();
|
||||
trace!("Got devices: {:?}, closed: {:?}", new_devices, closed_devices);
|
||||
trace!("Got devices: {:?}, closed: {:?}", new_devices, locked_devices);
|
||||
*self.devices.write() = new_devices;
|
||||
*self.closed_devices.write() = closed_devices;
|
||||
*self.locked_devices.write() = locked_devices;
|
||||
match error {
|
||||
Some(e) => Err(e),
|
||||
None => Ok(count),
|
||||
@@ -173,7 +176,7 @@ impl Manager {
|
||||
},
|
||||
})
|
||||
}
|
||||
Ok(None) => Err(Error::ClosedDevice(dev_info.path.clone())),
|
||||
Ok(None) => Err(Error::LockedDevice(dev_info.path.clone())),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
@@ -189,7 +192,7 @@ impl Manager {
|
||||
}
|
||||
|
||||
pub fn list_locked_devices(&self) -> Vec<String> {
|
||||
(*self.closed_devices.read()).clone()
|
||||
(*self.locked_devices.read()).clone()
|
||||
}
|
||||
|
||||
/// Get wallet info.
|
||||
@@ -200,16 +203,7 @@ impl Manager {
|
||||
fn open_path<R, F>(&self, f: F) -> Result<R, Error>
|
||||
where F: Fn() -> Result<R, &'static str>
|
||||
{
|
||||
let mut err = Error::KeyNotFound;
|
||||
// Try to open device a few times.
|
||||
for _ in 0..10 {
|
||||
match f() {
|
||||
Ok(handle) => return Ok(handle),
|
||||
Err(e) => err = From::from(e),
|
||||
}
|
||||
::std::thread::sleep(Duration::from_millis(200));
|
||||
}
|
||||
Err(err)
|
||||
f().map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn pin_matrix_ack(&self, device_path: &str, pin: &str) -> Result<bool, Error> {
|
||||
@@ -406,6 +400,42 @@ impl Manager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Trezor event handler
|
||||
/// A separate thread is handeling incoming events
|
||||
pub struct EventHandler {
|
||||
trezor: Weak<Manager>,
|
||||
}
|
||||
|
||||
impl EventHandler {
|
||||
// Trezor event handler constructor
|
||||
pub fn new(trezor: Weak<Manager>) -> Self {
|
||||
Self { trezor: trezor }
|
||||
}
|
||||
}
|
||||
|
||||
impl libusb::Hotplug for EventHandler {
|
||||
fn device_arrived(&mut self, _device: libusb::Device) {
|
||||
debug!(target: "hw", "Trezor V1 arrived");
|
||||
if let Some(trezor) = self.trezor.upgrade() {
|
||||
// Wait for the device to boot up
|
||||
::std::thread::sleep(Duration::from_millis(1000));
|
||||
if let Err(e) = trezor.update_devices() {
|
||||
debug!(target: "hw", "Trezor V1 connect error: {:?}", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn device_left(&mut self, _device: libusb::Device) {
|
||||
debug!(target: "hw", "Trezor V1 left");
|
||||
if let Some(trezor) = self.trezor.upgrade() {
|
||||
if let Err(e) = trezor.update_devices() {
|
||||
debug!(target: "hw", "Trezor V1 disconnect error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
/// This test can't be run without an actual trezor device connected
|
||||
|
||||
@@ -4,7 +4,7 @@ set -e
|
||||
# variables
|
||||
PVER="1-9"
|
||||
PTYPE="v1"
|
||||
TRACK="beta"
|
||||
TRACK="stable"
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
PRE_REPO="js-dist-paritytech/parity-${TRACK}-${PVER}-${PTYPE}.git"
|
||||
PRE_REPO_TOKEN="https://${GITHUB_JS_PRECOMPILED}:@github.com/${PRE_REPO}"
|
||||
|
||||
@@ -1 +1 @@
|
||||
// test script 25
|
||||
// test script 26
|
||||
|
||||
235
js/package-lock.json
generated
235
js/package-lock.json
generated
@@ -45,15 +45,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"@parity/dapp-dapp-methods": {
|
||||
"version": "github:js-dist-paritytech/dapp-dapp-methods#b649fb9056d49bbf4fde719f91a4cfcaf529f9f6",
|
||||
"version": "github:js-dist-paritytech/dapp-dapp-methods#01dcabc56ecea95cdc87dde81598b7e8469375d6",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@parity/api": "2.1.15",
|
||||
"@parity/mobx": "1.1.2",
|
||||
"@parity/ui": "3.0.22",
|
||||
"mobx": "3.5.1",
|
||||
"@parity/ui": "3.1.4",
|
||||
"mobx": "3.6.2",
|
||||
"mobx-react": "4.3.5",
|
||||
"prop-types": "15.6.0",
|
||||
"prop-types": "15.6.1",
|
||||
"react": "16.2.0",
|
||||
"react-dom": "16.2.0",
|
||||
"react-intl": "2.4.0",
|
||||
@@ -79,16 +79,97 @@
|
||||
"@parity/shared": "2.2.23"
|
||||
}
|
||||
},
|
||||
"@parity/ui": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@parity/ui/-/ui-3.1.4.tgz",
|
||||
"integrity": "sha512-aG79IOxMBeRsu92Zlq3QsR6Z6PAmlhmOdU9tQP+F9XB/44Y4sGxfSDNucGucWz/Jz0VGerJn53CoACa4Yj5uYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@parity/api": "2.1.15",
|
||||
"@parity/etherscan": "2.1.3",
|
||||
"@parity/mobx": "1.1.2",
|
||||
"@parity/shared": "2.2.23",
|
||||
"babel-runtime": "6.26.0",
|
||||
"bignumber.js": "4.1.0",
|
||||
"brace": "0.11.0",
|
||||
"date-difference": "1.0.0",
|
||||
"eventemitter3": "2.0.3",
|
||||
"file-saver": "1.3.3",
|
||||
"geopattern": "1.2.3",
|
||||
"js-sha3": "0.6.1",
|
||||
"keycode": "2.1.9",
|
||||
"lodash": "4.17.4",
|
||||
"moment": "2.19.2",
|
||||
"qrcode-generator": "1.3.1",
|
||||
"react-ace": "5.7.0",
|
||||
"react-copy-to-clipboard": "5.0.1",
|
||||
"react-datetime": "2.11.0",
|
||||
"react-dom": "16.1.1",
|
||||
"react-dropzone": "4.2.3",
|
||||
"react-element-to-jsx-string": "13.1.0",
|
||||
"react-event-listener": "0.5.2",
|
||||
"react-intl": "2.4.0",
|
||||
"react-markdown": "3.0.2",
|
||||
"react-portal": "4.0.0",
|
||||
"react-qr-reader": "2.0.1",
|
||||
"react-redux": "5.0.6",
|
||||
"react-router": "3.2.0",
|
||||
"react-tooltip": "3.4.0",
|
||||
"recharts": "1.0.0-beta.2",
|
||||
"redux": "3.7.2",
|
||||
"semantic-ui-css": "2.2.12",
|
||||
"semantic-ui-react": "0.76.0",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-dom": {
|
||||
"version": "16.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.1.tgz",
|
||||
"integrity": "sha512-q06jiwST8SEPAMIEkAsu7BgynEZtqF87VrTc70XsW7nxVhWEu2Y4MF5UfxxHQO/mNtQHQWP0YcFxmwm9oMrMaQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"semantic-ui-react": {
|
||||
"version": "0.76.0",
|
||||
"resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-0.76.0.tgz",
|
||||
"integrity": "sha512-CdiIT8n7ZwUlytZkYsQMnaVGmoIZI/mVs4lijvLcR568kcnlRkYYaFKhMLq5tFDQU6+QhdTD+8WebF7ov0Ql6Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "6.26.0",
|
||||
"classnames": "2.2.5",
|
||||
"lodash": "4.17.4",
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
|
||||
"integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==",
|
||||
"dev": true
|
||||
},
|
||||
"js-sha3": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz",
|
||||
"integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=",
|
||||
"dev": true
|
||||
},
|
||||
"mobx": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.5.1.tgz",
|
||||
"integrity": "sha1-jmguxTXPROBABbnjfi32asyXWkI=",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz",
|
||||
"integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.6.0",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
|
||||
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
|
||||
"version": "15.6.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
|
||||
"integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
@@ -105,7 +186,7 @@
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
@@ -117,7 +198,7 @@
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"semantic-ui-react": {
|
||||
@@ -130,21 +211,20 @@
|
||||
"classnames": "2.2.5",
|
||||
"fbjs": "0.8.16",
|
||||
"lodash": "4.17.4",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@parity/dapp-dapp-visible": {
|
||||
"version": "github:js-dist-paritytech/dapp-dapp-visible#28546f312ea9877ebeea9c52afea1e7ec943cd0d",
|
||||
"version": "github:js-dist-paritytech/dapp-dapp-visible#14e6499495a3421c4a6da4728b8d99dfa1656e1c",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@parity/api": "2.1.15",
|
||||
"@parity/mobx": "1.1.2",
|
||||
"@parity/ui": "3.0.22",
|
||||
"mobx": "3.5.1",
|
||||
"@parity/ui": "3.1.4",
|
||||
"mobx": "3.6.2",
|
||||
"mobx-react": "4.3.5",
|
||||
"prop-types": "15.6.0",
|
||||
"prop-types": "15.6.1",
|
||||
"react": "16.2.0",
|
||||
"react-dom": "16.2.0",
|
||||
"react-intl": "2.4.0",
|
||||
@@ -170,16 +250,97 @@
|
||||
"@parity/shared": "2.2.23"
|
||||
}
|
||||
},
|
||||
"@parity/ui": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@parity/ui/-/ui-3.1.4.tgz",
|
||||
"integrity": "sha512-aG79IOxMBeRsu92Zlq3QsR6Z6PAmlhmOdU9tQP+F9XB/44Y4sGxfSDNucGucWz/Jz0VGerJn53CoACa4Yj5uYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@parity/api": "2.1.15",
|
||||
"@parity/etherscan": "2.1.3",
|
||||
"@parity/mobx": "1.1.2",
|
||||
"@parity/shared": "2.2.23",
|
||||
"babel-runtime": "6.26.0",
|
||||
"bignumber.js": "4.1.0",
|
||||
"brace": "0.11.0",
|
||||
"date-difference": "1.0.0",
|
||||
"eventemitter3": "2.0.3",
|
||||
"file-saver": "1.3.3",
|
||||
"geopattern": "1.2.3",
|
||||
"js-sha3": "0.6.1",
|
||||
"keycode": "2.1.9",
|
||||
"lodash": "4.17.4",
|
||||
"moment": "2.19.2",
|
||||
"qrcode-generator": "1.3.1",
|
||||
"react-ace": "5.7.0",
|
||||
"react-copy-to-clipboard": "5.0.1",
|
||||
"react-datetime": "2.11.0",
|
||||
"react-dom": "16.1.1",
|
||||
"react-dropzone": "4.2.3",
|
||||
"react-element-to-jsx-string": "13.1.0",
|
||||
"react-event-listener": "0.5.2",
|
||||
"react-intl": "2.4.0",
|
||||
"react-markdown": "3.0.2",
|
||||
"react-portal": "4.0.0",
|
||||
"react-qr-reader": "2.0.1",
|
||||
"react-redux": "5.0.6",
|
||||
"react-router": "3.2.0",
|
||||
"react-tooltip": "3.4.0",
|
||||
"recharts": "1.0.0-beta.2",
|
||||
"redux": "3.7.2",
|
||||
"semantic-ui-css": "2.2.12",
|
||||
"semantic-ui-react": "0.76.0",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-dom": {
|
||||
"version": "16.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.1.tgz",
|
||||
"integrity": "sha512-q06jiwST8SEPAMIEkAsu7BgynEZtqF87VrTc70XsW7nxVhWEu2Y4MF5UfxxHQO/mNtQHQWP0YcFxmwm9oMrMaQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"semantic-ui-react": {
|
||||
"version": "0.76.0",
|
||||
"resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-0.76.0.tgz",
|
||||
"integrity": "sha512-CdiIT8n7ZwUlytZkYsQMnaVGmoIZI/mVs4lijvLcR568kcnlRkYYaFKhMLq5tFDQU6+QhdTD+8WebF7ov0Ql6Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "6.26.0",
|
||||
"classnames": "2.2.5",
|
||||
"lodash": "4.17.4",
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
|
||||
"integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==",
|
||||
"dev": true
|
||||
},
|
||||
"js-sha3": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz",
|
||||
"integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=",
|
||||
"dev": true
|
||||
},
|
||||
"mobx": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.5.1.tgz",
|
||||
"integrity": "sha1-jmguxTXPROBABbnjfi32asyXWkI=",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz",
|
||||
"integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.6.0",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
|
||||
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
|
||||
"version": "15.6.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
|
||||
"integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
@@ -196,7 +357,7 @@
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
@@ -208,7 +369,7 @@
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"semantic-ui-react": {
|
||||
@@ -221,7 +382,7 @@
|
||||
"classnames": "2.2.5",
|
||||
"fbjs": "0.8.16",
|
||||
"lodash": "4.17.4",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,9 +415,9 @@
|
||||
"@parity/mobx": "1.1.2",
|
||||
"@parity/ui": "3.0.22",
|
||||
"format-number": "3.0.0",
|
||||
"mobx": "3.5.1",
|
||||
"mobx": "3.6.2",
|
||||
"mobx-react": "4.3.5",
|
||||
"prop-types": "15.6.0",
|
||||
"prop-types": "15.6.1",
|
||||
"react": "16.2.0",
|
||||
"react-dom": "16.2.0",
|
||||
"react-intl": "2.4.0",
|
||||
@@ -284,15 +445,15 @@
|
||||
}
|
||||
},
|
||||
"mobx": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.5.1.tgz",
|
||||
"integrity": "sha1-jmguxTXPROBABbnjfi32asyXWkI=",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz",
|
||||
"integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.6.0",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
|
||||
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
|
||||
"version": "15.6.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
|
||||
"integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
@@ -309,7 +470,7 @@
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
@@ -321,7 +482,7 @@
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
"Parity"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "npm run build:inject && npm run build:app && npm run build:embed",
|
||||
"build": "npm run build:inject && npm run build:app:embed",
|
||||
"build:app": "webpack --config webpack/app",
|
||||
"build:inject": "webpack --config webpack/inject",
|
||||
"build:embed": "cross-env EMBED=1 node webpack/embed",
|
||||
"build:app:embed": "cross-env EMBED=1 node webpack/embed",
|
||||
"build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js",
|
||||
"ci:build": "cross-env NODE_ENV=production npm run build",
|
||||
"clean": "rimraf ./.build ./.coverage ./.happypack",
|
||||
|
||||
@@ -4,7 +4,7 @@ set -e
|
||||
# variables
|
||||
PVER="1-9"
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
BRANCH="beta"
|
||||
BRANCH="stable"
|
||||
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"
|
||||
|
||||
echo "*** [cargo] Setting up GitHub config for parity"
|
||||
|
||||
@@ -4,7 +4,7 @@ set -e
|
||||
# variables
|
||||
PVER="1-9"
|
||||
PTYPE="shell"
|
||||
TRACK="beta"
|
||||
TRACK="stable"
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
PRE_REPO="js-dist-paritytech/parity-${TRACK}-${PVER}-${PTYPE}.git"
|
||||
PRE_REPO_TOKEN="https://${GITHUB_JS_PRECOMPILED}:@github.com/${PRE_REPO}"
|
||||
|
||||
@@ -1 +1 @@
|
||||
// test script 31
|
||||
// test script 32
|
||||
|
||||
14
js/src/Dapps/blacklist.js
Normal file
14
js/src/Dapps/blacklist.js
Normal file
@@ -0,0 +1,14 @@
|
||||
module.exports = [
|
||||
// tokendeploy
|
||||
'0xf9f2d620c2e08f83e45555247146c62185e4ab7cf82a4b9002a265a0d020348f',
|
||||
// methodreg
|
||||
'0xf49089046f53f5d2e5f3513c1c32f5ff57d986e46309a42d2b249070e4e72c46',
|
||||
// dappreg
|
||||
'0x7bbc4f1a27628781b96213e781a1b8eec6982c1db8fac739af6e4c5a55862c03',
|
||||
// githubhint
|
||||
'0x058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75',
|
||||
// console
|
||||
'0xa635a9326814bded464190eddf0bdb90ce92d40ea2359cf553ea80e3c5a4076c',
|
||||
// registry
|
||||
'0xd1adaede68d344519025e2ff574650cd99d3830fe6d274c7a7843cdc00e17938'
|
||||
];
|
||||
@@ -29,6 +29,8 @@ import DappCard from './DappCard';
|
||||
|
||||
import styles from './dapps.css';
|
||||
|
||||
import BLACKLIST from './blacklist';
|
||||
|
||||
@observer
|
||||
class Dapps extends Component {
|
||||
static contextTypes = {
|
||||
@@ -53,8 +55,10 @@ class Dapps extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
renderSection = (apps) => (
|
||||
apps && apps.length > 0 &&
|
||||
renderSection = (_apps) => {
|
||||
const apps = _apps.filter(({ id }) => !BLACKLIST.includes(id));
|
||||
|
||||
return apps && apps.length > 0 &&
|
||||
<div className={ styles.dapps }>
|
||||
{
|
||||
apps.map((app, index) => (
|
||||
@@ -68,8 +72,8 @@ class Dapps extends Component {
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
</div>;
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
|
||||
@@ -19,6 +19,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const rimraf = require('rimraf');
|
||||
const flatten = require('lodash.flatten');
|
||||
const webpack = require('webpack');
|
||||
// const ReactIntlAggregatePlugin = require('react-intl-aggregate-webpack-plugin');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const WebpackErrorNotificationPlugin = require('webpack-error-notification');
|
||||
@@ -29,12 +30,14 @@ const rulesEs6 = require('./rules/es6');
|
||||
const rulesParity = require('./rules/parity');
|
||||
const Shared = require('./shared');
|
||||
|
||||
const BLACKLIST = require('../src/Dapps/blacklist');
|
||||
const DAPPS_BUILTIN = require('@parity/shared/lib/config/dappsBuiltin.json');
|
||||
const DAPPS_VIEWS = require('@parity/shared/lib/config/dappsViews.json');
|
||||
const DAPPS_ALL = []
|
||||
.concat(DAPPS_BUILTIN, DAPPS_VIEWS)
|
||||
.filter((dapp) => !dapp.skipBuild)
|
||||
.filter((dapp) => dapp.package);
|
||||
.filter((dapp) => dapp.package)
|
||||
.filter(({ id }) => !BLACKLIST.includes(id));
|
||||
|
||||
const FAVICON = path.resolve(__dirname, '../node_modules/@parity/shared/assets/images/parity-logo-black-no-text.png');
|
||||
|
||||
@@ -45,9 +48,10 @@ const EMBED = process.env.EMBED;
|
||||
const isProd = ENV === 'production';
|
||||
const isEmbed = EMBED === '1' || EMBED === 'true';
|
||||
|
||||
const entry = isEmbed
|
||||
? { embed: ['babel-polyfill', './embed.js'] }
|
||||
: { bundle: ['babel-polyfill', './index.parity.js'] };
|
||||
const entry = {
|
||||
embed: ['babel-polyfill', './embed.js'],
|
||||
bundle: ['babel-polyfill', './index.parity.js']
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
cache: !isProd,
|
||||
@@ -162,23 +166,30 @@ module.exports = {
|
||||
},
|
||||
|
||||
plugins: (function () {
|
||||
let plugins = Shared.getPlugins().concat(
|
||||
new WebpackErrorNotificationPlugin(),
|
||||
new ExtractTextPlugin({
|
||||
filename: `${isEmbed ? 'embed' : 'bundle'}.css`
|
||||
}),
|
||||
);
|
||||
|
||||
if (!isEmbed) {
|
||||
plugins = [].concat(
|
||||
plugins,
|
||||
let plugins = []
|
||||
.concat(Shared.getPlugins())
|
||||
.concat(
|
||||
new WebpackErrorNotificationPlugin(),
|
||||
new ExtractTextPlugin({
|
||||
filename: '[name].css',
|
||||
allChunks: true
|
||||
})
|
||||
)
|
||||
.concat(
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'Parity Bar',
|
||||
filename: 'embed.html',
|
||||
template: './index.parity.ejs',
|
||||
favicon: FAVICON,
|
||||
chunks: ['commons', 'embed']
|
||||
}),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'Parity',
|
||||
filename: 'index.html',
|
||||
template: './index.parity.ejs',
|
||||
favicon: FAVICON,
|
||||
chunks: ['bundle']
|
||||
chunks: ['commons', 'bundle']
|
||||
}),
|
||||
|
||||
new CopyWebpackPlugin(
|
||||
@@ -244,16 +255,11 @@ module.exports = {
|
||||
{}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (isEmbed) {
|
||||
plugins.push(
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'Parity Bar',
|
||||
filename: 'embed.html',
|
||||
template: './index.parity.ejs',
|
||||
favicon: FAVICON,
|
||||
chunks: ['embed']
|
||||
if (isProd) {
|
||||
plugins.unshift(
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'commons'
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ const webpack = require('webpack');
|
||||
const HappyPack = require('happypack');
|
||||
const PackageJson = require('../package.json');
|
||||
|
||||
const EMBED = process.env.EMBED;
|
||||
const ENV = process.env.NODE_ENV || 'development';
|
||||
const isProd = ENV === 'production';
|
||||
const UI_VERSION = PackageJson
|
||||
@@ -38,7 +37,6 @@ function getPlugins (_isProd = isProd) {
|
||||
const plugins = [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
EMBED: JSON.stringify(EMBED),
|
||||
NODE_ENV: JSON.stringify(ENV),
|
||||
RPC_ADDRESS: JSON.stringify(process.env.RPC_ADDRESS),
|
||||
PARITY_URL: JSON.stringify(process.env.PARITY_URL),
|
||||
|
||||
@@ -113,6 +113,9 @@ pub struct Params {
|
||||
/// See main EthashParams docs.
|
||||
#[serde(rename="maxCodeSize")]
|
||||
pub max_code_size: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(rename="maxCodeSizeTransition")]
|
||||
pub max_code_size_transition: Option<Uint>,
|
||||
/// Transaction permission contract address.
|
||||
#[serde(rename="transactionPermissionContract")]
|
||||
pub transaction_permission_contract: Option<Address>,
|
||||
|
||||
@@ -462,7 +462,7 @@
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
<string>1.9.3</string>
|
||||
<string>1.9.5</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 9
|
||||
!define VERSIONBUILD 3
|
||||
!define VERSIONBUILD 5
|
||||
!define ARGS ""
|
||||
!define FIRST_START_ARGS "--mode=passive ui"
|
||||
|
||||
|
||||
@@ -676,11 +676,15 @@ pub fn execute_impl(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>)
|
||||
let event_loop = EventLoop::spawn();
|
||||
|
||||
// the updater service
|
||||
let mut updater_fetch = fetch.clone();
|
||||
// parity binaries should be smaller than 128MB
|
||||
updater_fetch.set_limit(Some(128 * 1024 * 1024));
|
||||
|
||||
let updater = Updater::new(
|
||||
Arc::downgrade(&(service.client() as Arc<BlockChainClient>)),
|
||||
Arc::downgrade(&sync_provider),
|
||||
update_policy,
|
||||
fetch.clone(),
|
||||
updater_fetch,
|
||||
event_loop.remote(),
|
||||
);
|
||||
service.add_notify(updater.clone());
|
||||
|
||||
@@ -22,13 +22,10 @@ echo "Parity version: " $VER
|
||||
echo "Branch: " $CI_BUILD_REF_NAME
|
||||
echo "--------------------"
|
||||
|
||||
echo "Rhash version:"
|
||||
# NOTE for md5 and sha256 we want to display filename as well
|
||||
# hence we use --* instead of -p *
|
||||
MD5_BIN="rhash --md5"
|
||||
SHA256_BIN="rhash --sha256"
|
||||
# NOTE For SHA3 we need only hash (hence -p)
|
||||
SHA3_BIN="rhash -p %{sha3-256}"
|
||||
|
||||
set_env () {
|
||||
echo "Set ENVIROMENT"
|
||||
@@ -51,6 +48,12 @@ set_env_win () {
|
||||
echo "@ signtool sign /f "\%"1 /p "\%"2 /tr http://timestamp.comodoca.com /du https://parity.io "\%"3" > sign.cmd
|
||||
}
|
||||
build () {
|
||||
if [[ "windows" = $IDENT ]]
|
||||
then
|
||||
# This is a nasty hack till we figure out the proper cargo caching strategy
|
||||
echo "Remove index"
|
||||
rm -rf cargo/registry/index/*.
|
||||
fi
|
||||
echo "Build parity:"
|
||||
cargo build --target $PLATFORM --features final --release
|
||||
echo "Build evmbin:"
|
||||
@@ -70,14 +73,12 @@ strip_binaries () {
|
||||
calculate_checksums () {
|
||||
echo "Checksum calculation:"
|
||||
rhash --version
|
||||
|
||||
rm -rf *.md5
|
||||
rm -rf *.sha256
|
||||
|
||||
export SHA3="$($SHA3_BIN target/$PLATFORM/release/parity$S3WIN)"
|
||||
# NOTE rhash 1.3.1 doesnt support keccak, workaround
|
||||
if [ "$SHA3" == "%{sha3-256}" ]; then
|
||||
export SHA3="$(target/$PLATFORM/release/parity$S3WIN tools hash target/$PLATFORM/release/parity$S3WIN)"
|
||||
fi
|
||||
BIN="target/$PLATFORM/release/parity$S3WIN"
|
||||
export SHA3="$($BIN tools hash $BIN)"
|
||||
|
||||
echo "Parity file SHA3: $SHA3"
|
||||
$MD5_BIN target/$PLATFORM/release/parity$S3WIN > parity$S3WIN.md5
|
||||
@@ -312,7 +313,7 @@ case $BUILD_PLATFORM in
|
||||
snapcraft clean
|
||||
echo "Prepare snapcraft.yaml for build on Gitlab CI in Docker image"
|
||||
sed -i 's/git/'"$VER"'/g' snap/snapcraft.yaml
|
||||
if [[ "$CI_BUILD_REF_NAME" = "beta" || "$VER" == *1.9* ]];
|
||||
if [[ "$CI_BUILD_REF_NAME" = "stable" || "$VER" == *1.9* ]];
|
||||
then
|
||||
sed -i -e 's/grade: devel/grade: stable/' snap/snapcraft.yaml;
|
||||
fi
|
||||
|
||||
@@ -4,12 +4,12 @@ set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
if [[ "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" ]]; then
|
||||
export GIT_COMPARE=$CI_COMMIT_REF_NAME;
|
||||
export GIT_COMPARE=$CI_COMMIT_REF_NAME~;
|
||||
else
|
||||
export GIT_COMPARE=master;
|
||||
fi
|
||||
export JS_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep ^js/ | wc -l)"
|
||||
export JS_OLD_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep ^js-old/ | wc -l)"
|
||||
export JS_FILES_MODIFIED=1
|
||||
export JS_OLD_FILES_MODIFIED=1
|
||||
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ | wc -l)"
|
||||
|
||||
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"
|
||||
|
||||
@@ -18,6 +18,7 @@ use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::{PathBuf};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use ethcore::client::{BlockId, BlockChainClient, ChainNotify};
|
||||
use ethsync::{SyncProvider};
|
||||
@@ -85,6 +86,8 @@ struct UpdaterState {
|
||||
capability: CapState,
|
||||
|
||||
disabled: bool,
|
||||
|
||||
backoff: Option<(u32, Instant)>,
|
||||
}
|
||||
|
||||
/// Service for checking for updates and determining whether we can achieve consensus.
|
||||
@@ -216,7 +219,19 @@ impl Updater {
|
||||
let fetched = s.fetching.take().unwrap();
|
||||
let dest = self.updates_path(&Self::update_file_name(&fetched.version));
|
||||
if !dest.exists() {
|
||||
let b = result.map_err(|e| (format!("Unable to fetch update ({}): {:?}", fetched.version, e), false))?;
|
||||
let b = match result {
|
||||
Ok(b) => {
|
||||
s.backoff = None;
|
||||
b
|
||||
},
|
||||
Err(e) => {
|
||||
let mut n = s.backoff.map(|b| b.0 + 1).unwrap_or(1);
|
||||
s.backoff = Some((n, Instant::now() + Duration::from_secs(2usize.pow(n) as u64)));
|
||||
|
||||
return Err((format!("Unable to fetch update ({}): {:?}", fetched.version, e), false));
|
||||
},
|
||||
};
|
||||
|
||||
info!(target: "updater", "Fetched latest version ({}) OK to {}", fetched.version, b.display());
|
||||
fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| (format!("Unable to create updates path: {:?}", e), true))?;
|
||||
fs::copy(&b, &dest).map_err(|e| (format!("Unable to copy update: {:?}", e), true))?;
|
||||
@@ -287,12 +302,14 @@ impl Updater {
|
||||
drop(s);
|
||||
self.fetch_done(Ok(PathBuf::new()));
|
||||
} else {
|
||||
info!(target: "updater", "Attempting to get parity binary {}", b);
|
||||
s.fetching = Some(latest.track.clone());
|
||||
drop(s);
|
||||
let weak_self = self.weak_self.lock().clone();
|
||||
let f = move |r: Result<PathBuf, fetch::Error>| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) };
|
||||
self.fetcher.lock().as_ref().expect("Created on `new`; qed").fetch(b, Box::new(f));
|
||||
if s.backoff.iter().all(|&(_, instant)| Instant::now() >= instant) {
|
||||
info!(target: "updater", "Attempting to get parity binary {}", b);
|
||||
s.fetching = Some(latest.track.clone());
|
||||
drop(s);
|
||||
let weak_self = self.weak_self.lock().clone();
|
||||
let f = move |r: Result<PathBuf, fetch::Error>| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) };
|
||||
self.fetcher.lock().as_ref().expect("Created on `new`; qed").fetch(b, Box::new(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,6 +338,11 @@ impl Updater {
|
||||
}
|
||||
|
||||
let mut s = self.state.lock();
|
||||
|
||||
if s.latest != latest {
|
||||
s.backoff = None;
|
||||
}
|
||||
|
||||
s.latest = latest;
|
||||
s.capability = capability;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ description = "Ethcore utility library"
|
||||
homepage = "http://parity.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore-util"
|
||||
version = "1.9.0"
|
||||
version = "1.9.5"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
3
util/bloomchain/.gitignore
vendored
Normal file
3
util/bloomchain/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
target
|
||||
Cargo.lock
|
||||
*.swp
|
||||
15
util/bloomchain/Cargo.toml
Normal file
15
util/bloomchain/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
description = "Standalone blockchain bloom filter"
|
||||
homepage = "https://github.com/debris/bloomchain"
|
||||
name = "bloomchain"
|
||||
version = "0.2.0"
|
||||
authors = ["debris <marek.kotewicz@gmail.com>"]
|
||||
license = "MIT"
|
||||
keywords = ["ethereum", "ethcore", "bloom", "chain", "filter"]
|
||||
|
||||
[dependencies]
|
||||
ethcore-bigint = { path = "../bigint" }
|
||||
|
||||
[dev-dependencies]
|
||||
rustc-hex = "1.0"
|
||||
rand = "0.4"
|
||||
9
util/bloomchain/README.md
Normal file
9
util/bloomchain/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# bloomchain
|
||||
Standalone blockchain bloom filter.
|
||||
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
|
||||
[travis-image]: https://travis-ci.org/paritytech/bloomchain.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/paritytech/bloomchain
|
||||
|
||||
[Documentation](http://paritytech.github.io/bloomchain/bloomchain/index.html)
|
||||
188
util/bloomchain/src/chain.rs
Normal file
188
util/bloomchain/src/chain.rs
Normal file
@@ -0,0 +1,188 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ops::Range;
|
||||
use number::Number;
|
||||
use position::{Position, Manager as PositionManager};
|
||||
use Bloom;
|
||||
use filter::Filter;
|
||||
use config::Config;
|
||||
use database::BloomDatabase;
|
||||
|
||||
/// Prepares all bloom database operations.
|
||||
pub struct BloomChain<'a> {
|
||||
positioner: PositionManager,
|
||||
db: &'a BloomDatabase,
|
||||
}
|
||||
|
||||
impl<'a> BloomChain<'a> {
|
||||
/// Creates new bloom chain.
|
||||
pub fn new(config: Config, db: &'a BloomDatabase) -> Self {
|
||||
let positioner = PositionManager::new(config.elements_per_index, config.levels);
|
||||
|
||||
BloomChain {
|
||||
positioner: positioner,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal function which does bloom search recursively.
|
||||
fn blocks(&self, range: &Range<Number>, bloom: &Bloom, level: usize, offset: usize) -> Option<Vec<usize>> {
|
||||
let index = self.positioner.position(offset, level);
|
||||
|
||||
match self.db.bloom_at(&index) {
|
||||
None => return None,
|
||||
Some(level_bloom) => match level {
|
||||
// if we are on the lowest level
|
||||
0 if level_bloom.contains_bloom(bloom) => return Some(vec![offset]),
|
||||
// return None if current level doesnt contain given bloom
|
||||
_ if !level_bloom.contains_bloom(bloom) => return None,
|
||||
// continue processing && go down
|
||||
_ => ()
|
||||
}
|
||||
};
|
||||
|
||||
let level_size = self.positioner.level_size(level - 1);
|
||||
let from_position = self.positioner.position(range.start, level - 1);
|
||||
let to_position = self.positioner.position(range.end, level - 1);
|
||||
let res: Vec<usize> = self.positioner.lower_level_positions(&index).into_iter()
|
||||
// chose only blooms in range
|
||||
.filter(|li| li.index >= from_position.index && li.index <= to_position.index)
|
||||
// map them to offsets
|
||||
.map(|li| li.index * level_size)
|
||||
// get all blocks that may contain our bloom
|
||||
// filter existing ones
|
||||
.filter_map(|off| self.blocks(range, bloom, level - 1, off))
|
||||
// flatten nested structures
|
||||
.flat_map(|v| v)
|
||||
.collect();
|
||||
Some(res)
|
||||
}
|
||||
|
||||
/// Inserts the bloom at all filter levels.
|
||||
pub fn insert(&self, number: Number, bloom: Bloom) -> HashMap<Position, Bloom> {
|
||||
let mut result: HashMap<Position, Bloom> = HashMap::new();
|
||||
|
||||
for level in 0..self.positioner.levels() {
|
||||
let position = self.positioner.position(number, level);
|
||||
let new_bloom = match self.db.bloom_at(&position) {
|
||||
Some(mut old_bloom) => {
|
||||
old_bloom.accrue_bloom(&bloom);
|
||||
old_bloom
|
||||
},
|
||||
None => bloom.clone(),
|
||||
};
|
||||
|
||||
result.insert(position, new_bloom);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Resets data in range.
|
||||
/// Inserts new data.
|
||||
/// Inserted data may exceed reseted range.
|
||||
pub fn replace(&self, range: &Range<Number>, blooms: Vec<Bloom>) -> HashMap<Position, Bloom> {
|
||||
let mut result: HashMap<Position, Bloom> = HashMap::new();
|
||||
|
||||
// insert all new blooms at level 0
|
||||
for (i, bloom) in blooms.iter().enumerate() {
|
||||
result.insert(self.positioner.position(range.start + i, 0), bloom.clone());
|
||||
}
|
||||
|
||||
// reset the rest of blooms
|
||||
for reset_number in range.start + blooms.len()..(range.end + 1) {
|
||||
result.insert(self.positioner.position(reset_number, 0), Bloom::default());
|
||||
}
|
||||
|
||||
for level in 1..self.positioner.levels() {
|
||||
for i in 0..blooms.len() {
|
||||
|
||||
let index = self.positioner.position(range.start + i, level);
|
||||
let new_bloom = {
|
||||
// use new blooms before db blooms where necessary
|
||||
let bloom_at = | index | { result.get(&index).cloned().or_else(|| self.db.bloom_at(&index)) };
|
||||
|
||||
self.positioner.lower_level_positions(&index)
|
||||
.into_iter()
|
||||
// get blooms
|
||||
// filter existing ones
|
||||
.filter_map(bloom_at)
|
||||
// BitOr all of them
|
||||
.fold(Bloom::default(), |mut acc, bloom| {
|
||||
acc.accrue_bloom(&bloom);
|
||||
acc
|
||||
})
|
||||
};
|
||||
|
||||
result.insert(index, new_bloom);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Returns all numbers with given bloom.
|
||||
pub fn with_bloom(&self, range: &Range<Number>, bloom: &Bloom) -> Vec<Number> {
|
||||
let mut result = vec![];
|
||||
// lets start from highest level
|
||||
let max_level = self.positioner.max_level();
|
||||
let level_size = self.positioner.level_size(max_level);
|
||||
let from_position = self.positioner.position(range.start, max_level);
|
||||
let to_position = self.positioner.position(range.end, max_level);
|
||||
|
||||
for index in from_position.index..to_position.index + 1 {
|
||||
// offset will be used to calculate where we are right now
|
||||
let offset = level_size * index;
|
||||
|
||||
// go doooown!
|
||||
if let Some(blocks) = self.blocks(range, bloom, max_level, offset) {
|
||||
result.extend(blocks);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Filter the chain returing all numbers matching the filter.
|
||||
pub fn filter(&self, filter: &Filter) -> Vec<Number> {
|
||||
let range = filter.range();
|
||||
let mut blocks = filter.bloom_possibilities()
|
||||
.into_iter()
|
||||
.flat_map(|ref bloom| self.with_bloom(&range, bloom))
|
||||
.collect::<HashSet<Number>>()
|
||||
.into_iter()
|
||||
.collect::<Vec<Number>>();
|
||||
|
||||
blocks.sort();
|
||||
blocks
|
||||
}
|
||||
}
|
||||
|
||||
const BLOOM_SIZE: usize = 256;
|
||||
|
||||
pub trait BloomCompat {
|
||||
fn contains_bloom(&self, bloom: &Self) -> bool where Self: Sized;
|
||||
fn accrue_bloom(&mut self, bloom: &Self) where Self:Sized;
|
||||
}
|
||||
|
||||
impl BloomCompat for Bloom {
|
||||
fn contains_bloom(&self, bloom_ref: &Self) -> bool {
|
||||
assert_eq!(self.0.len(), BLOOM_SIZE);
|
||||
assert_eq!(bloom_ref.0.len(), BLOOM_SIZE);
|
||||
for i in 0..BLOOM_SIZE {
|
||||
let a = self.0[i];
|
||||
let b = bloom_ref.0[i];
|
||||
if (a & b) != b {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn accrue_bloom(&mut self, bloom_ref: &Self) {
|
||||
assert_eq!(self.0.len(), BLOOM_SIZE);
|
||||
assert_eq!(bloom_ref.0.len(), BLOOM_SIZE);
|
||||
for i in 0..BLOOM_SIZE {
|
||||
self.0[i] |= bloom_ref.0[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
17
util/bloomchain/src/config.rs
Normal file
17
util/bloomchain/src/config.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
/// `BloomChain` configuration.
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub struct Config {
|
||||
/// Number of levels.
|
||||
pub levels: usize,
|
||||
/// Number of elements in a single index.
|
||||
pub elements_per_index: usize,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Config {
|
||||
levels: 3,
|
||||
elements_per_index: 16,
|
||||
}
|
||||
}
|
||||
}
|
||||
7
util/bloomchain/src/database.rs
Normal file
7
util/bloomchain/src/database.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use position::Position;
|
||||
use Bloom;
|
||||
|
||||
/// Readonly `Bloom` database.
|
||||
pub trait BloomDatabase {
|
||||
fn bloom_at(&self, position: &Position) -> Option<Bloom>;
|
||||
}
|
||||
11
util/bloomchain/src/filter.rs
Normal file
11
util/bloomchain/src/filter.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use std::ops::Range;
|
||||
use Bloom;
|
||||
use number::Number;
|
||||
|
||||
/// Should be used to filter blocks from `BloomChain`.
|
||||
pub trait Filter {
|
||||
/// All bloom possibilities that we are searching for.
|
||||
fn bloom_possibilities(&self) -> Vec<Bloom>;
|
||||
/// Range of search.
|
||||
fn range(&self) -> Range<Number>;
|
||||
}
|
||||
31
util/bloomchain/src/group/bridge.rs
Normal file
31
util/bloomchain/src/group/bridge.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use Bloom;
|
||||
use config::Config;
|
||||
use database::BloomDatabase;
|
||||
use position::Position;
|
||||
use group::position::Manager as PositionManager;
|
||||
use super::BloomGroupDatabase;
|
||||
|
||||
/// Bridge between `BloomDatabase` and `BloomGroupDatabase`.
|
||||
pub struct GroupDatabaseBridge<'a> {
|
||||
positioner: PositionManager,
|
||||
db: &'a BloomGroupDatabase,
|
||||
}
|
||||
|
||||
impl<'a> GroupDatabaseBridge<'a> {
|
||||
pub fn new(config: Config, db: &'a BloomGroupDatabase) -> Self {
|
||||
let positioner = PositionManager::new(config.elements_per_index);
|
||||
|
||||
GroupDatabaseBridge {
|
||||
positioner: positioner,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BloomDatabase for GroupDatabaseBridge<'a> {
|
||||
fn bloom_at(&self, position: &Position) -> Option<Bloom> {
|
||||
let position = self.positioner.position(position);
|
||||
self.db.blooms_at(&position.group)
|
||||
.and_then(|group| group.blooms.into_iter().nth(position.number))
|
||||
}
|
||||
}
|
||||
70
util/bloomchain/src/group/chain.rs
Normal file
70
util/bloomchain/src/group/chain.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Range;
|
||||
use Bloom;
|
||||
use chain::BloomChain;
|
||||
use config::Config;
|
||||
use number::Number;
|
||||
use filter::Filter;
|
||||
use position::Position as BloomPosition;
|
||||
use super::{GroupDatabaseBridge, BloomGroupDatabase, BloomGroup, GroupPosition};
|
||||
use super::position::Manager as PositionManager;
|
||||
|
||||
/// Performs all bloom database operations using `BloomGroup`s.
|
||||
pub struct BloomGroupChain<'a> {
|
||||
config: Config,
|
||||
db: &'a BloomGroupDatabase,
|
||||
bridge: GroupDatabaseBridge<'a>,
|
||||
}
|
||||
|
||||
impl<'a> BloomGroupChain<'a> {
|
||||
pub fn new(config: Config, db: &'a BloomGroupDatabase) -> Self {
|
||||
let bridge = GroupDatabaseBridge::new(config, db);
|
||||
|
||||
BloomGroupChain {
|
||||
config: config,
|
||||
db: db,
|
||||
bridge: bridge,
|
||||
}
|
||||
}
|
||||
|
||||
fn group_blooms(&self, blooms: HashMap<BloomPosition, Bloom>) -> HashMap<GroupPosition, BloomGroup> {
|
||||
let positioner = PositionManager::new(self.config.elements_per_index);
|
||||
blooms.into_iter()
|
||||
.fold(HashMap::new(), | mut acc, (position, bloom) | {
|
||||
{
|
||||
let position = positioner.position(&position);
|
||||
let group = acc
|
||||
.entry(position.group.clone())
|
||||
.or_insert_with(|| self.db
|
||||
.blooms_at(&position.group)
|
||||
.unwrap_or_else(|| BloomGroup::new(self.config.elements_per_index))
|
||||
);
|
||||
assert_eq!(self.config.elements_per_index, group.blooms.len());
|
||||
group.blooms[position.number] = bloom;
|
||||
}
|
||||
acc
|
||||
})
|
||||
}
|
||||
|
||||
pub fn insert(&self, number: Number, bloom: Bloom) -> HashMap<GroupPosition, BloomGroup> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
let modified_blooms = bloom_chain.insert(number, bloom);
|
||||
self.group_blooms(modified_blooms)
|
||||
}
|
||||
|
||||
pub fn replace(&self, range: &Range<Number>, blooms: Vec<Bloom>) -> HashMap<GroupPosition, BloomGroup> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
let modified_blooms = bloom_chain.replace(range, blooms);
|
||||
self.group_blooms(modified_blooms)
|
||||
}
|
||||
|
||||
pub fn with_bloom(&self, range: &Range<Number>, bloom: &Bloom) -> Vec<Number> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
bloom_chain.with_bloom(range, bloom)
|
||||
}
|
||||
|
||||
pub fn filter(&self, filter: &Filter) -> Vec<Number> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
bloom_chain.filter(filter)
|
||||
}
|
||||
}
|
||||
6
util/bloomchain/src/group/database.rs
Normal file
6
util/bloomchain/src/group/database.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use group::{GroupPosition, BloomGroup};
|
||||
|
||||
/// Readonly `BloomGroup` database.
|
||||
pub trait BloomGroupDatabase {
|
||||
fn blooms_at(&self, position: &GroupPosition) -> Option<BloomGroup>;
|
||||
}
|
||||
17
util/bloomchain/src/group/group.rs
Normal file
17
util/bloomchain/src/group/group.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use Bloom;
|
||||
|
||||
/// Group of blooms that are in the same index.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BloomGroup {
|
||||
pub blooms: Vec<Bloom>,
|
||||
}
|
||||
|
||||
impl BloomGroup {
|
||||
pub fn new(size: usize) -> Self {
|
||||
let blooms = (0..size).into_iter().map(|_| Bloom::default()).collect();
|
||||
|
||||
BloomGroup {
|
||||
blooms: blooms
|
||||
}
|
||||
}
|
||||
}
|
||||
16
util/bloomchain/src/group/mod.rs
Normal file
16
util/bloomchain/src/group/mod.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
//! Bloom grouping.
|
||||
//!
|
||||
//! Optimization gathering together blooms that are in the same index and are likely to be retrived together.
|
||||
|
||||
mod bridge;
|
||||
mod chain;
|
||||
mod database;
|
||||
mod group;
|
||||
mod position;
|
||||
|
||||
pub use self::bridge::GroupDatabaseBridge;
|
||||
pub use self::chain::BloomGroupChain;
|
||||
|
||||
pub use self::database::BloomGroupDatabase;
|
||||
pub use self::group::BloomGroup;
|
||||
pub use self::position::GroupPosition;
|
||||
28
util/bloomchain/src/group/position/manager.rs
Normal file
28
util/bloomchain/src/group/position/manager.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use super::{Position, GroupPosition};
|
||||
use position::Position as BloomPosition;
|
||||
|
||||
pub struct Manager {
|
||||
index_size: usize
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn new(index_size: usize) -> Self {
|
||||
Manager {
|
||||
index_size: index_size
|
||||
}
|
||||
}
|
||||
|
||||
pub fn group_position(&self, pos: &BloomPosition) -> GroupPosition {
|
||||
GroupPosition {
|
||||
level: pos.level,
|
||||
index: pos.index / self.index_size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn position(&self, pos: &BloomPosition) -> Position {
|
||||
Position {
|
||||
group: self.group_position(pos),
|
||||
number: pos.index % self.index_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
5
util/bloomchain/src/group/position/mod.rs
Normal file
5
util/bloomchain/src/group/position/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod position;
|
||||
mod manager;
|
||||
|
||||
pub use self::position::{Position, GroupPosition};
|
||||
pub use self::manager::Manager;
|
||||
17
util/bloomchain/src/group/position/position.rs
Normal file
17
util/bloomchain/src/group/position/position.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
/// Uniquely identifies bloom group position.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct GroupPosition {
|
||||
/// Bloom level.
|
||||
pub level: usize,
|
||||
/// Index of the group.
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
/// Uniquely identifies bloom position including the position in the group.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct Position {
|
||||
/// Group position.
|
||||
pub group: GroupPosition,
|
||||
/// Number in group.
|
||||
pub number: usize,
|
||||
}
|
||||
17
util/bloomchain/src/lib.rs
Normal file
17
util/bloomchain/src/lib.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
extern crate ethcore_bigint as bigint;
|
||||
|
||||
mod chain;
|
||||
mod config;
|
||||
mod database;
|
||||
pub mod group;
|
||||
mod number;
|
||||
mod position;
|
||||
mod filter;
|
||||
|
||||
pub use bigint::hash::H2048 as Bloom;
|
||||
pub use chain::{BloomChain, BloomCompat};
|
||||
pub use config::Config;
|
||||
pub use database::BloomDatabase;
|
||||
pub use number::Number;
|
||||
pub use position::Position;
|
||||
pub use filter::Filter;
|
||||
2
util/bloomchain/src/number.rs
Normal file
2
util/bloomchain/src/number.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
/// Represents block number.
|
||||
pub type Number = usize;
|
||||
142
util/bloomchain/src/position/manager.rs
Normal file
142
util/bloomchain/src/position/manager.rs
Normal file
@@ -0,0 +1,142 @@
|
||||
//! Simplifies working with bloom indexes.
|
||||
|
||||
use super::Position;
|
||||
|
||||
/// Simplifies working with bloom indexes.
|
||||
pub struct Manager {
|
||||
index_size: usize,
|
||||
level_sizes: Vec<usize>,
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
/// Creates new indexer.
|
||||
pub fn new(index_size: usize, levels: usize) -> Self {
|
||||
if levels == 0 {
|
||||
panic!("Manager requires at least 1 level.");
|
||||
}
|
||||
|
||||
let mut level_sizes = vec![1];
|
||||
level_sizes.extend_from_slice(&(1..).into_iter()
|
||||
.scan(1, |acc, _| {
|
||||
*acc = *acc * index_size;
|
||||
Some(*acc)
|
||||
})
|
||||
.take(levels - 1)
|
||||
.collect::<Vec<usize>>());
|
||||
|
||||
Manager {
|
||||
index_size: index_size,
|
||||
level_sizes: level_sizes,
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafely get level size.
|
||||
pub fn level_size(&self, level: usize) -> usize {
|
||||
self.level_sizes[level as usize]
|
||||
}
|
||||
|
||||
/// Converts block number and level to `Position`.
|
||||
pub fn position(&self, block_number: usize, level: usize) -> Position {
|
||||
Position {
|
||||
level: level,
|
||||
index: block_number / self.level_size(level),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return bloom which are dependencies for given index.
|
||||
///
|
||||
/// Bloom indexes are ordered from lowest to highest.
|
||||
pub fn lower_level_positions(&self, index: &Position) -> Vec<Position> {
|
||||
// this is the lowest level
|
||||
if index.level == 0 {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let new_level = index.level - 1;
|
||||
let offset = self.index_size * index.index;
|
||||
|
||||
(0..self.index_size)
|
||||
.map(|i| Position {
|
||||
level: new_level,
|
||||
index: offset + i
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Return number of levels.
|
||||
pub fn levels(&self) -> usize {
|
||||
self.level_sizes.len()
|
||||
}
|
||||
|
||||
/// Returns max indexer level.
|
||||
pub fn max_level(&self) -> usize {
|
||||
self.level_sizes.len() - 1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use position::Position;
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_level_size() {
|
||||
let indexer = Manager::new(16, 3);
|
||||
assert_eq!(indexer.level_size(0), 1);
|
||||
assert_eq!(indexer.level_size(1), 16);
|
||||
assert_eq!(indexer.level_size(2), 256);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_position() {
|
||||
let indexer = Manager::new(16, 3);
|
||||
|
||||
let bi0 = indexer.position(0, 0);
|
||||
assert_eq!(bi0.level, 0);
|
||||
assert_eq!(bi0.index, 0);
|
||||
|
||||
let bi1 = indexer.position(1, 0);
|
||||
assert_eq!(bi1.level, 0);
|
||||
assert_eq!(bi1.index, 1);
|
||||
|
||||
let bi2 = indexer.position(2, 0);
|
||||
assert_eq!(bi2.level, 0);
|
||||
assert_eq!(bi2.index, 2);
|
||||
|
||||
let bi3 = indexer.position(3, 1);
|
||||
assert_eq!(bi3.level, 1);
|
||||
assert_eq!(bi3.index, 0);
|
||||
|
||||
let bi4 = indexer.position(15, 1);
|
||||
assert_eq!(bi4.level, 1);
|
||||
assert_eq!(bi4.index, 0);
|
||||
|
||||
let bi5 = indexer.position(16, 1);
|
||||
assert_eq!(bi5.level, 1);
|
||||
assert_eq!(bi5.index, 1);
|
||||
|
||||
let bi6 = indexer.position(255, 2);
|
||||
assert_eq!(bi6.level, 2);
|
||||
assert_eq!(bi6.index, 0);
|
||||
|
||||
let bi7 = indexer.position(256, 2);
|
||||
assert_eq!(bi7.level, 2);
|
||||
assert_eq!(bi7.index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lower_level_positions() {
|
||||
let indexer = Manager::new(16, 3);
|
||||
|
||||
let bi = indexer.position(256, 2);
|
||||
assert_eq!(bi.level, 2);
|
||||
assert_eq!(bi.index, 1);
|
||||
|
||||
let mut ebis = vec![];
|
||||
for i in 16..32 {
|
||||
ebis.push(Position { level: 1, index: i});
|
||||
}
|
||||
|
||||
let bis = indexer.lower_level_positions(&bi);
|
||||
assert_eq!(ebis, bis);
|
||||
}
|
||||
}
|
||||
5
util/bloomchain/src/position/mod.rs
Normal file
5
util/bloomchain/src/position/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
pub mod position;
|
||||
pub mod manager;
|
||||
|
||||
pub use self::position::Position;
|
||||
pub use self::manager::Manager;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user