Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7dc4d349a1 | ||
|
47d7197fb9 | ||
|
e2e1d221d5 | ||
|
a0a2beddfe | ||
|
e7dc0bed16 | ||
|
6eae372524 |
@ -2,6 +2,7 @@ stages:
|
||||
- test
|
||||
- push-release
|
||||
- build
|
||||
- docs
|
||||
variables:
|
||||
RUST_BACKTRACE: "1"
|
||||
RUSTFLAGS: ""
|
||||
@ -220,6 +221,15 @@ test-rust-nightly:
|
||||
- rust
|
||||
- rust-nightly
|
||||
allow_failure: true
|
||||
json-rpc-docs:
|
||||
stage: docs
|
||||
only:
|
||||
- tags
|
||||
image: parity/rust:gitlab-ci
|
||||
script:
|
||||
- scripts/gitlab-rpc-docs.sh
|
||||
tags:
|
||||
- docs
|
||||
push-release:
|
||||
stage: push-release
|
||||
only:
|
||||
|
295
Cargo.lock
generated
295
Cargo.lock
generated
@ -76,7 +76,7 @@ name = "base64"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -85,7 +85,7 @@ name = "base64"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -94,9 +94,9 @@ name = "bincode"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -131,7 +131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "blooms-db"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -141,15 +141,16 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "bn"
|
||||
version = "0.4.4"
|
||||
source = "git+https://github.com/paritytech/bn#964b48fad5dffbaa124c2f10699e76faf5846c4e"
|
||||
source = "git+https://github.com/paritytech/bn#2a71dbde5ca93451c8da2135767896a64483759e"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -157,7 +158,7 @@ name = "bytes"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -217,6 +218,22 @@ dependencies = [
|
||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.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)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "common-types"
|
||||
version = "0.1.0"
|
||||
@ -231,14 +248,6 @@ dependencies = [
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "conv"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.3.2"
|
||||
@ -310,6 +319,11 @@ name = "crunchy"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ct-logs"
|
||||
version = "0.2.0"
|
||||
@ -328,11 +342,6 @@ dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "custom_derive"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "daemonize"
|
||||
version = "0.2.3"
|
||||
@ -351,20 +360,10 @@ name = "dir"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"app_dirs 1.2.1 (git+https://github.com/paritytech/app-dirs-rs)",
|
||||
"dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "0.8.3"
|
||||
@ -372,7 +371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -443,7 +442,7 @@ dependencies = [
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -471,8 +470,9 @@ version = "1.12.0"
|
||||
dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.2 (git+https://github.com/paritytech/parity-common)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -487,7 +487,7 @@ dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -498,7 +498,7 @@ dependencies = [
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"blooms-db 0.1.0",
|
||||
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"common-types 0.1.0",
|
||||
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -533,7 +533,7 @@ dependencies = [
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"memory-cache 0.1.0",
|
||||
"memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -608,7 +608,7 @@ dependencies = [
|
||||
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory-cache 0.1.0",
|
||||
"memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -617,9 +617,9 @@ dependencies = [
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"rlp_derive 0.1.0",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stats 0.1.0",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"triehash-ethereum 0.2.0",
|
||||
@ -713,7 +713,7 @@ dependencies = [
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"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)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -751,7 +751,7 @@ dependencies = [
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"rlp_derive 0.1.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -762,7 +762,7 @@ dependencies = [
|
||||
name = "ethcore-secretstore"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi-contract 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -784,7 +784,7 @@ dependencies = [
|
||||
"parity-crypto 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -836,6 +836,7 @@ dependencies = [
|
||||
name = "ethcore-sync"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"common-types 0.1.0",
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.12.0",
|
||||
"ethcore-io 1.12.0",
|
||||
@ -862,7 +863,7 @@ dependencies = [
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"trace-time 0.1.0",
|
||||
"triehash-ethereum 0.2.0",
|
||||
]
|
||||
@ -892,7 +893,7 @@ dependencies = [
|
||||
"ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -901,7 +902,7 @@ name = "ethereum-types-serialize"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -910,7 +911,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -919,7 +920,7 @@ dependencies = [
|
||||
name = "ethkey"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (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)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -931,7 +932,7 @@ dependencies = [
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"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)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -946,7 +947,7 @@ dependencies = [
|
||||
"panic_hook 0.1.0",
|
||||
"parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -967,10 +968,10 @@ dependencies = [
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"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)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.5 (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.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -987,7 +988,7 @@ dependencies = [
|
||||
"panic_hook 0.1.0",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1022,7 +1023,7 @@ dependencies = [
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
@ -1090,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fs-swap"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1173,7 +1174,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "hashdb"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1203,7 +1204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[[package]]
|
||||
name = "hidapi"
|
||||
version = "0.3.1"
|
||||
source = "git+https://github.com/paritytech/hidapi-rs#70ec4bd1b755ec5dd32ad2be0c8345864147c8bc"
|
||||
source = "git+https://github.com/paritytech/hidapi-rs#d4d323767d6f27cf5a3d73fbae0b0f2134d579bf"
|
||||
dependencies = [
|
||||
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1331,7 +1332,7 @@ dependencies = [
|
||||
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plain_hasher 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -1345,7 +1346,7 @@ source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#6b972
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1382,7 +1383,7 @@ source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#6b972
|
||||
dependencies = [
|
||||
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1437,7 +1438,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "keccak-hash"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1465,7 +1466,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kvdb"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -1474,7 +1475,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kvdb-memorydb"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1483,11 +1484,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kvdb-rocksdb"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fs-swap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1653,8 +1654,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memorydb"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -1804,39 +1805,11 @@ dependencies = [
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "node-health"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ntp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-reactor 0.1.0",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ntp"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"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.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.42"
|
||||
@ -1951,19 +1924,19 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-bytes"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
|
||||
[[package]]
|
||||
name = "parity-clib"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"parity-ethereum 2.0.0",
|
||||
"parity-ethereum 2.0.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-crypto"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1974,7 +1947,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-ethereum"
|
||||
version = "2.0.0"
|
||||
version = "2.0.5"
|
||||
dependencies = [
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2012,7 +1985,6 @@ dependencies = [
|
||||
"mem 0.1.0",
|
||||
"migration-rocksdb 0.1.0",
|
||||
"node-filter 1.12.0",
|
||||
"node-health 0.1.0",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic_hook 0.1.0",
|
||||
@ -2024,7 +1996,7 @@ dependencies = [
|
||||
"parity-rpc 1.12.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
"parity-updater 1.12.0",
|
||||
"parity-version 2.0.0",
|
||||
"parity-version 2.0.5",
|
||||
"parity-whisper 0.1.0",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.1 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -2037,7 +2009,7 @@ dependencies = [
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2099,7 +2071,7 @@ dependencies = [
|
||||
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2158,21 +2130,21 @@ dependencies = [
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"multihash 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"node-health 0.1.0",
|
||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parity-crypto 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-updater 1.12.0",
|
||||
"parity-version 2.0.0",
|
||||
"parity-version 2.0.5",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"plain_hasher 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stats 0.1.0",
|
||||
@ -2196,7 +2168,7 @@ dependencies = [
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc 1.12.0",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2234,7 +2206,7 @@ dependencies = [
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"parity-hash-fetch 1.12.0",
|
||||
"parity-version 2.0.0",
|
||||
"parity-version 2.0.5",
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2245,7 +2217,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-version"
|
||||
version = "2.0.0"
|
||||
version = "2.0.5"
|
||||
dependencies = [
|
||||
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -2260,7 +2232,7 @@ name = "parity-wasm"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2268,7 +2240,7 @@ name = "parity-whisper"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-network 1.12.0",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethkey 0.3.0",
|
||||
@ -2283,11 +2255,11 @@ dependencies = [
|
||||
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"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)",
|
||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2320,7 +2292,7 @@ dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2328,15 +2300,12 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "path"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
dependencies = [
|
||||
"dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
|
||||
[[package]]
|
||||
name = "patricia-trie"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.2.0 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -2411,7 +2380,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "plain_hasher"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2479,7 +2448,7 @@ dependencies = [
|
||||
"hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"primal-bit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2512,7 +2481,7 @@ dependencies = [
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethjson 0.1.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
@ -2524,7 +2493,7 @@ name = "pwasm-utils"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2561,6 +2530,23 @@ dependencies = [
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.0.1"
|
||||
@ -2647,9 +2633,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rlp"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2807,7 +2793,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.37"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -2835,7 +2821,7 @@ name = "serde_ignored"
|
||||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2846,7 +2832,7 @@ dependencies = [
|
||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2904,7 +2890,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.4.3"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2913,7 +2899,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "snappy"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73"
|
||||
source = "git+https://github.com/paritytech/rust-snappy#798408ffef8f86dd51481673aca10f5348d7491b"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
|
||||
@ -2922,9 +2908,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "snappy-sys"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73"
|
||||
source = "git+https://github.com/paritytech/rust-snappy#798408ffef8f86dd51481673aca10f5348d7491b"
|
||||
dependencies = [
|
||||
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -3284,7 +3270,7 @@ name = "toml"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3301,7 +3287,7 @@ dependencies = [
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"trace-time 0.1.0",
|
||||
]
|
||||
|
||||
@ -3324,7 +3310,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "trie-standardmap"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.2 (git+https://github.com/paritytech/parity-common)",
|
||||
@ -3335,7 +3321,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "triehash"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
|
||||
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
|
||||
dependencies = [
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3357,7 +3343,7 @@ name = "uint"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 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)",
|
||||
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3474,7 +3460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "vm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"common-types 0.1.0",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethjson 0.1.0",
|
||||
@ -3495,7 +3481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "wasm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-logger 1.12.0",
|
||||
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3511,7 +3497,7 @@ name = "wasmi"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3549,7 +3535,7 @@ dependencies = [
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic_hook 0.1.0",
|
||||
"parity-whisper 0.1.0",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -3587,7 +3573,7 @@ name = "ws"
|
||||
version = "0.7.5"
|
||||
source = "git+https://github.com/tomusdrw/ws-rs#f12d19c4c19422fc79af28a3181f598bc07ecd1e"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.6 (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.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3647,14 +3633,15 @@ dependencies = [
|
||||
"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 bn 0.4.4 (git+https://github.com/paritytech/bn)" = "<none>"
|
||||
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
|
||||
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
|
||||
"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9"
|
||||
"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
||||
"checksum cid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d85ee025368e69063c420cbb2ed9f852cb03a5e69b73be021e65726ce03585b6"
|
||||
"checksum clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f4a2b3bb7ef3c672d7c13d15613211d5a6976b6892c598b0fcb5d40765f19c2"
|
||||
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "95470235c31c726d72bf2e1f421adc1e65b9d561bf5529612cbe1a72da1467b3"
|
||||
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
||||
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
||||
"checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2"
|
||||
@ -3663,12 +3650,11 @@ dependencies = [
|
||||
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
||||
"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
|
||||
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
|
||||
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
|
||||
"checksum ct-logs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61cd11fb222fecf889f4531855c614548e92e8bd2eb178e35296885df5ee9a7c"
|
||||
"checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "<none>"
|
||||
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
|
||||
"checksum daemonize 0.2.3 (git+https://github.com/paritytech/daemonize)" = "<none>"
|
||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
||||
"checksum dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37a76dd8b997af7107d0bb69d43903cf37153a18266f8b3fdb9911f28efb5444"
|
||||
"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
|
||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||
"checksum edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a34f5204fbc13582de418611cf3a7dcdd07c6d312a5b631597ba72c06b9d9c9"
|
||||
@ -3688,7 +3674,7 @@ dependencies = [
|
||||
"checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576"
|
||||
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
"checksum fs-swap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67f816b2a5f8a6628764a4323d1a8d9ad5303266c4e4e4486ba680f477ba7e62"
|
||||
"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb"
|
||||
"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.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
|
||||
@ -3746,7 +3732,7 @@ dependencies = [
|
||||
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
|
||||
"checksum memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)" = "<none>"
|
||||
"checksum memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)" = "<none>"
|
||||
"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"
|
||||
"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe"
|
||||
@ -3759,7 +3745,6 @@ dependencies = [
|
||||
"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f"
|
||||
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
"checksum ntp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06b0d2de4a2cd60c3ac85c98a1fc23668bc97bef2b10b706bccd88efb229497d"
|
||||
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
||||
"checksum num-bigint 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "81b483ea42927c463e191802e7334556b48e7875297564c0e9951bd3a0ae53e3"
|
||||
"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
|
||||
@ -3803,6 +3788,8 @@ dependencies = [
|
||||
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
||||
"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "12397506224b2f93e6664ffc4f664b29be8208e5157d3d90b44f09b5fae470ea"
|
||||
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
|
||||
"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
|
||||
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
|
||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||
@ -3828,7 +3815,7 @@ dependencies = [
|
||||
"checksum sct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1137b767bbe1c4d30656993bdd97422ed41255d9400b105d735f8c7d9e800632"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
|
||||
"checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920"
|
||||
"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f"
|
||||
"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce"
|
||||
"checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
|
||||
@ -3842,7 +3829,7 @@ dependencies = [
|
||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||
"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d"
|
||||
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
|
||||
"checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"
|
||||
"checksum smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10"
|
||||
"checksum snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
|
||||
"checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
|
||||
"checksum socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "06dc9f86ee48652b7c80f3d254e3b9accb67a928c562c64d10d7b016d3d98dab"
|
||||
|
@ -2,7 +2,7 @@
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity-ethereum"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "2.0.0"
|
||||
version = "2.0.5"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
@ -32,7 +32,7 @@ futures-cpupool = "0.1"
|
||||
fdlimit = "0.1"
|
||||
ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" }
|
||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" }
|
||||
ethcore = { path = "ethcore", features = ["work-notify", "price-info", "stratum"] }
|
||||
ethcore = { path = "ethcore", features = ["parity"] }
|
||||
parity-bytes = { git = "https://github.com/paritytech/parity-common" }
|
||||
ethcore-io = { path = "util/io" }
|
||||
ethcore-light = { path = "ethcore/light" }
|
||||
@ -46,7 +46,6 @@ ethcore-transaction = { path = "ethcore/transaction" }
|
||||
ethereum-types = "0.3"
|
||||
node-filter = { path = "ethcore/node_filter" }
|
||||
ethkey = { path = "ethkey" }
|
||||
node-health = { path = "node-health" }
|
||||
rlp = { git = "https://github.com/paritytech/parity-common" }
|
||||
rpc-cli = { path = "rpc_cli" }
|
||||
parity-hash-fetch = { path = "hash-fetch" }
|
||||
@ -88,6 +87,7 @@ winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] }
|
||||
daemonize = { git = "https://github.com/paritytech/daemonize" }
|
||||
|
||||
[features]
|
||||
miner-debug = ["ethcore/miner-debug"]
|
||||
json-tests = ["ethcore/json-tests"]
|
||||
test-heavy = ["ethcore/test-heavy"]
|
||||
evm-debug = ["ethcore/evm-debug"]
|
||||
|
@ -5,7 +5,7 @@ WORKDIR /build
|
||||
# install tools and dependencies
|
||||
RUN apk add --no-cache gcc musl-dev pkgconfig g++ make curl \
|
||||
eudev-dev rust cargo git file binutils \
|
||||
libusb-dev linux-headers perl
|
||||
libusb-dev linux-headers perl cmake
|
||||
|
||||
# show backtraces
|
||||
ENV RUST_BACKTRACE 1
|
||||
|
@ -23,24 +23,6 @@ RUN /usr/local/android-ndk-r16b/build/tools/make-standalone-toolchain.sh \
|
||||
--arch=arm --install-dir=/opt/ndk-standalone --stl=libc++ --platform=android-26
|
||||
ENV PATH $PATH:/opt/ndk-standalone/bin
|
||||
|
||||
# Compiling OpenSSL for Android
|
||||
RUN cd /root && \
|
||||
git clone git://git.openssl.org/openssl.git && \
|
||||
cd openssl && \
|
||||
git checkout OpenSSL_1_1_0-stable
|
||||
ENV CROSS_SYSROOT /opt/ndk-standalone/sysroot
|
||||
RUN cd /root/openssl && \
|
||||
./Configure android-armeabi --cross-compile-prefix=arm-linux-androideabi- \
|
||||
-static no-stdio no-ui \
|
||||
-I/usr/local/android-ndk-r16b/sysroot/usr/include \
|
||||
-I/usr/local/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi \
|
||||
-L/usr/local/android-ndk-r16b/sysroot/usr/lib \
|
||||
--prefix=/opt/ndk-standalone/sysroot/usr
|
||||
RUN cd /root/openssl && \
|
||||
make build_libs && \
|
||||
make install_dev
|
||||
RUN rm -rf /root/openssl
|
||||
|
||||
# Compiling libudev for Android
|
||||
# This is the most hacky part of the process, as we need to apply a patch and pass specific
|
||||
# options that the compiler environment doesn't define.
|
||||
|
@ -3,7 +3,7 @@ WORKDIR /build
|
||||
|
||||
# install tools and dependencies
|
||||
RUN yum -y update&& \
|
||||
yum install -y git make gcc-c++ gcc file binutils
|
||||
yum install -y git make gcc-c++ gcc file binutils cmake
|
||||
|
||||
# install rustup
|
||||
RUN curl -sSf https://static.rust-lang.org/rustup.sh -o rustup.sh &&\
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:14.04
|
||||
FROM ubuntu:xenial
|
||||
MAINTAINER Parity Technologies <devops@parity.io>
|
||||
WORKDIR /build
|
||||
#ENV for build TAG
|
||||
@ -13,6 +13,7 @@ RUN apt-get update && \
|
||||
# add-apt-repository
|
||||
software-properties-common \
|
||||
make \
|
||||
cmake \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
@ -22,8 +23,6 @@ RUN apt-get update && \
|
||||
libc6-dev \
|
||||
binutils \
|
||||
file \
|
||||
openssl \
|
||||
libssl-dev \
|
||||
libudev-dev \
|
||||
pkg-config \
|
||||
dpkg-dev \
|
||||
@ -35,14 +34,13 @@ RUN apt-get update && \
|
||||
# show backtraces
|
||||
RUST_BACKTRACE=1 && \
|
||||
# build parity
|
||||
cd /build&&git clone https://github.com/paritytech/parity && \
|
||||
cd parity && \
|
||||
cd /build&&git clone https://github.com/paritytech/parity-ethereum && \
|
||||
cd parity-ethereum && \
|
||||
git pull&& \
|
||||
git checkout $BUILD_TAG && \
|
||||
cargo build --verbose --release --features final && \
|
||||
#ls /build/parity/target/release/parity && \
|
||||
strip /build/parity/target/release/parity && \
|
||||
file /build/parity/target/release/parity&&mkdir -p /parity&& cp /build/parity/target/release/parity /parity&&\
|
||||
strip /build/parity-ethereum/target/release/parity && \
|
||||
file /build/parity-ethereum/target/release/parity&&mkdir -p /parity&& cp /build/parity-ethereum/target/release/parity /parity&&\
|
||||
#cleanup Docker image
|
||||
rm -rf /root/.cargo&&rm -rf /root/.multirust&&rm -rf /root/.rustup&&rm -rf /build&&\
|
||||
apt-get purge -y \
|
||||
@ -51,6 +49,7 @@ cd /build&&git clone https://github.com/paritytech/parity && \
|
||||
# add-apt-repository
|
||||
software-properties-common \
|
||||
make \
|
||||
cmake \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
|
@ -6,7 +6,7 @@ RUN apt-get -y update && \
|
||||
apt-get install -y --force-yes --no-install-recommends \
|
||||
curl git make g++ gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \
|
||||
libc6-arm64-cross libc6-dev-arm64-cross wget file ca-certificates \
|
||||
binutils-aarch64-linux-gnu \
|
||||
binutils-aarch64-linux-gnu cmake \
|
||||
&& \
|
||||
apt-get clean
|
||||
|
||||
|
@ -6,7 +6,7 @@ RUN apt-get -y update && \
|
||||
apt-get install -y --force-yes --no-install-recommends \
|
||||
curl git make g++ gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf \
|
||||
libc6-dev-armhf-cross wget file ca-certificates \
|
||||
binutils-arm-linux-gnueabihf \
|
||||
binutils-arm-linux-gnueabihf cmake \
|
||||
&& \
|
||||
apt-get clean
|
||||
|
||||
|
@ -6,11 +6,11 @@ RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
g++ \
|
||||
build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
file \
|
||||
binutils \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
libudev-dev
|
||||
|
||||
|
@ -6,13 +6,14 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
[lib]
|
||||
|
||||
[dependencies]
|
||||
log = "0.3"
|
||||
keccak-hash = { git = "https://github.com/paritytech/parity-common" }
|
||||
primal = "0.2.3"
|
||||
parking_lot = "0.6"
|
||||
crunchy = "0.1.0"
|
||||
memmap = "0.6"
|
||||
either = "1.0.0"
|
||||
ethereum-types = "0.3"
|
||||
keccak-hash = { git = "https://github.com/paritytech/parity-common" }
|
||||
log = "0.4"
|
||||
memmap = "0.6"
|
||||
parking_lot = "0.6"
|
||||
primal = "0.2.3"
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3"
|
||||
|
@ -16,10 +16,11 @@
|
||||
|
||||
#![cfg_attr(feature = "benches", feature(test))]
|
||||
|
||||
extern crate primal;
|
||||
extern crate parking_lot;
|
||||
extern crate either;
|
||||
extern crate ethereum_types;
|
||||
extern crate memmap;
|
||||
extern crate parking_lot;
|
||||
extern crate primal;
|
||||
|
||||
#[macro_use]
|
||||
extern crate crunchy;
|
||||
@ -38,6 +39,7 @@ mod shared;
|
||||
pub use cache::{NodeCacheBuilder, OptimizeFor};
|
||||
pub use compute::{ProofOfWork, quick_get_difficulty, slow_hash_block_number};
|
||||
use compute::Light;
|
||||
use ethereum_types::{U256, U512};
|
||||
use keccak::H256;
|
||||
use parking_lot::Mutex;
|
||||
pub use seed_compute::SeedHashCompute;
|
||||
@ -136,6 +138,29 @@ impl EthashManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
|
||||
pub fn boundary_to_difficulty(boundary: ðereum_types::H256) -> U256 {
|
||||
difficulty_to_boundary_aux(&**boundary)
|
||||
}
|
||||
|
||||
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
|
||||
pub fn difficulty_to_boundary(difficulty: &U256) -> ethereum_types::H256 {
|
||||
difficulty_to_boundary_aux(difficulty).into()
|
||||
}
|
||||
|
||||
fn difficulty_to_boundary_aux<T: Into<U512>>(difficulty: T) -> ethereum_types::U256 {
|
||||
let difficulty = difficulty.into();
|
||||
|
||||
assert!(!difficulty.is_zero());
|
||||
|
||||
if difficulty == U512::one() {
|
||||
U256::max_value()
|
||||
} else {
|
||||
// difficulty > 1, so result should never overflow 256 bits
|
||||
U256::from((U512::one() << 256) / difficulty)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lru() {
|
||||
use tempdir::TempDir;
|
||||
@ -155,6 +180,43 @@ fn test_lru() {
|
||||
assert_eq!(ethash.cache.lock().prev_epoch.unwrap(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difficulty_to_boundary() {
|
||||
use ethereum_types::H256;
|
||||
use std::str::FromStr;
|
||||
|
||||
assert_eq!(difficulty_to_boundary(&U256::from(1)), H256::from(U256::max_value()));
|
||||
assert_eq!(difficulty_to_boundary(&U256::from(2)), H256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
assert_eq!(difficulty_to_boundary(&U256::from(4)), H256::from_str("4000000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
assert_eq!(difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difficulty_to_boundary_regression() {
|
||||
use ethereum_types::H256;
|
||||
|
||||
// the last bit was originally being truncated when performing the conversion
|
||||
// https://github.com/paritytech/parity-ethereum/issues/8397
|
||||
for difficulty in 1..9 {
|
||||
assert_eq!(U256::from(difficulty), boundary_to_difficulty(&difficulty_to_boundary(&difficulty.into())));
|
||||
assert_eq!(H256::from(difficulty), difficulty_to_boundary(&boundary_to_difficulty(&difficulty.into())));
|
||||
assert_eq!(U256::from(difficulty), boundary_to_difficulty(&boundary_to_difficulty(&difficulty.into()).into()));
|
||||
assert_eq!(H256::from(difficulty), difficulty_to_boundary(&difficulty_to_boundary(&difficulty.into()).into()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_difficulty_to_boundary_panics_on_zero() {
|
||||
difficulty_to_boundary(&U256::from(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_boundary_to_difficulty_panics_on_zero() {
|
||||
boundary_to_difficulty(ðereum_types::H256::from(0));
|
||||
}
|
||||
|
||||
#[cfg(feature = "benches")]
|
||||
mod benchmarks {
|
||||
extern crate test;
|
||||
|
@ -80,6 +80,17 @@ tempdir = "0.3"
|
||||
trie-standardmap = { git = "https://github.com/paritytech/parity-common" }
|
||||
|
||||
[features]
|
||||
parity = ["work-notify", "price-info", "stratum"]
|
||||
# Large optional features that are enabled by default for Parity,
|
||||
# but might be omitted for other dependent crates.
|
||||
work-notify = ["ethcore-miner/work-notify"]
|
||||
price-info = ["ethcore-miner/price-info"]
|
||||
stratum = ["ethcore-stratum"]
|
||||
|
||||
# Disables seal verification for mined blocks.
|
||||
# This allows you to submit any seal via RPC to test and benchmark
|
||||
# how fast pending block get's created while running on the mainnet.
|
||||
miner-debug = []
|
||||
# Display EVM debug traces.
|
||||
evm-debug = ["evm/evm-debug"]
|
||||
# Display EVM debug traces when running tests.
|
||||
@ -97,6 +108,3 @@ test-heavy = []
|
||||
benches = []
|
||||
# Compile test helpers
|
||||
test-helpers = ["tempdir"]
|
||||
work-notify = ["ethcore-miner/work-notify"]
|
||||
price-info = ["ethcore-miner/price-info"]
|
||||
stratum = ["ethcore-stratum"]
|
||||
|
@ -16,17 +16,16 @@
|
||||
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
extern crate ethcore_util as util;
|
||||
extern crate rand;
|
||||
extern crate bn;
|
||||
extern crate parity_crypto;
|
||||
extern crate ethereum_types;
|
||||
extern crate ethkey;
|
||||
extern crate parity_crypto;
|
||||
extern crate rand;
|
||||
extern crate rustc_hex;
|
||||
extern crate ethcore_bigint;
|
||||
extern crate test;
|
||||
|
||||
use self::test::{Bencher};
|
||||
use rand::{StdRng};
|
||||
use self::test::Bencher;
|
||||
use rand::StdRng;
|
||||
|
||||
#[bench]
|
||||
fn bn_128_pairing(b: &mut Bencher) {
|
||||
@ -62,8 +61,7 @@ fn bn_128_mul(b: &mut Bencher) {
|
||||
fn sha256(b: &mut Bencher) {
|
||||
use parity_crypto::digest::sha256;
|
||||
|
||||
let mut input: [u8; 256] = [0; 256];
|
||||
let mut out = [0; 32];
|
||||
let input = [0_u8; 256];
|
||||
|
||||
b.iter(|| {
|
||||
sha256(&input);
|
||||
@ -74,7 +72,7 @@ fn sha256(b: &mut Bencher) {
|
||||
fn ecrecover(b: &mut Bencher) {
|
||||
use rustc_hex::FromHex;
|
||||
use ethkey::{Signature, recover as ec_recover};
|
||||
use ethcore_bigint::hash::H256;
|
||||
use ethereum_types::H256;
|
||||
let input = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
|
||||
let hash = H256::from_slice(&input[0..32]);
|
||||
let v = H256::from_slice(&input[32..64]);
|
||||
|
@ -43,7 +43,7 @@ pub mod provider;
|
||||
mod types;
|
||||
|
||||
pub use self::cache::Cache;
|
||||
pub use self::provider::Provider;
|
||||
pub use self::provider::{Provider, MAX_HEADERS_PER_REQUEST};
|
||||
pub use self::transaction_queue::TransactionQueue;
|
||||
pub use types::request as request;
|
||||
|
||||
|
@ -70,9 +70,6 @@ const PROPAGATE_TIMEOUT_INTERVAL: Duration = Duration::from_secs(5);
|
||||
const RECALCULATE_COSTS_TIMEOUT: TimerToken = 3;
|
||||
const RECALCULATE_COSTS_INTERVAL: Duration = Duration::from_secs(60 * 60);
|
||||
|
||||
/// Max number of transactions in a single packet.
|
||||
const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64;
|
||||
|
||||
// minimum interval between updates.
|
||||
const UPDATE_INTERVAL: Duration = Duration::from_millis(5000);
|
||||
|
||||
@ -648,7 +645,7 @@ impl LightProtocol {
|
||||
fn propagate_transactions(&self, io: &IoContext) {
|
||||
if self.capabilities.read().tx_relay { return }
|
||||
|
||||
let ready_transactions = self.provider.ready_transactions(MAX_TRANSACTIONS_TO_PROPAGATE);
|
||||
let ready_transactions = self.provider.transactions_to_propagate();
|
||||
if ready_transactions.is_empty() { return }
|
||||
|
||||
trace!(target: "pip", "propagate transactions: {} ready", ready_transactions.len());
|
||||
|
@ -171,8 +171,8 @@ impl Provider for TestProvider {
|
||||
})
|
||||
}
|
||||
|
||||
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction> {
|
||||
self.0.client.ready_transactions(max_len)
|
||||
fn transactions_to_propagate(&self) -> Vec<PendingTransaction> {
|
||||
self.0.client.transactions_to_propagate()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,8 @@ fn guess_capabilities(requests: &[CheckedRequest]) -> Capabilities {
|
||||
caps.serve_headers = true,
|
||||
CheckedRequest::HeaderByHash(_, _) =>
|
||||
caps.serve_headers = true,
|
||||
CheckedRequest::HeaderWithAncestors(_, _) =>
|
||||
caps.serve_headers = true,
|
||||
CheckedRequest::TransactionIndex(_, _) => {} // hashes yield no info.
|
||||
CheckedRequest::Signal(_, _) =>
|
||||
caps.serve_headers = true,
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
//! Request types, verification, and verification errors.
|
||||
|
||||
use std::cmp;
|
||||
use std::sync::Arc;
|
||||
|
||||
use bytes::Bytes;
|
||||
@ -47,6 +48,8 @@ pub enum Request {
|
||||
HeaderProof(HeaderProof),
|
||||
/// A request for a header by hash.
|
||||
HeaderByHash(HeaderByHash),
|
||||
/// A request for a header by hash with a range of its ancestors.
|
||||
HeaderWithAncestors(HeaderWithAncestors),
|
||||
/// A request for the index of a transaction.
|
||||
TransactionIndex(TransactionIndex),
|
||||
/// A request for block receipts.
|
||||
@ -136,6 +139,7 @@ macro_rules! impl_single {
|
||||
// implement traits for each kind of request.
|
||||
impl_single!(HeaderProof, HeaderProof, (H256, U256));
|
||||
impl_single!(HeaderByHash, HeaderByHash, encoded::Header);
|
||||
impl_single!(HeaderWithAncestors, HeaderWithAncestors, Vec<encoded::Header>);
|
||||
impl_single!(TransactionIndex, TransactionIndex, net_request::TransactionIndexResponse);
|
||||
impl_single!(Receipts, BlockReceipts, Vec<Receipt>);
|
||||
impl_single!(Body, Body, encoded::Block);
|
||||
@ -246,6 +250,7 @@ impl From<encoded::Header> for HeaderRef {
|
||||
pub enum CheckedRequest {
|
||||
HeaderProof(HeaderProof, net_request::IncompleteHeaderProofRequest),
|
||||
HeaderByHash(HeaderByHash, net_request::IncompleteHeadersRequest),
|
||||
HeaderWithAncestors(HeaderWithAncestors, net_request::IncompleteHeadersRequest),
|
||||
TransactionIndex(TransactionIndex, net_request::IncompleteTransactionIndexRequest),
|
||||
Receipts(BlockReceipts, net_request::IncompleteReceiptsRequest),
|
||||
Body(Body, net_request::IncompleteBodyRequest),
|
||||
@ -267,6 +272,16 @@ impl From<Request> for CheckedRequest {
|
||||
};
|
||||
CheckedRequest::HeaderByHash(req, net_req)
|
||||
}
|
||||
Request::HeaderWithAncestors(req) => {
|
||||
let net_req = net_request::IncompleteHeadersRequest {
|
||||
start: req.block_hash.map(Into::into),
|
||||
skip: 0,
|
||||
max: req.ancestor_count + 1,
|
||||
reverse: true,
|
||||
};
|
||||
trace!(target: "on_demand", "HeaderWithAncestors Request, {:?}", net_req);
|
||||
CheckedRequest::HeaderWithAncestors(req, net_req)
|
||||
}
|
||||
Request::HeaderProof(req) => {
|
||||
let net_req = net_request::IncompleteHeaderProofRequest {
|
||||
num: req.num().into(),
|
||||
@ -335,6 +350,7 @@ impl CheckedRequest {
|
||||
match self {
|
||||
CheckedRequest::HeaderProof(_, req) => NetRequest::HeaderProof(req),
|
||||
CheckedRequest::HeaderByHash(_, req) => NetRequest::Headers(req),
|
||||
CheckedRequest::HeaderWithAncestors(_, req) => NetRequest::Headers(req),
|
||||
CheckedRequest::TransactionIndex(_, req) => NetRequest::TransactionIndex(req),
|
||||
CheckedRequest::Receipts(_, req) => NetRequest::Receipts(req),
|
||||
CheckedRequest::Body(_, req) => NetRequest::Body(req),
|
||||
@ -390,6 +406,27 @@ impl CheckedRequest {
|
||||
|
||||
None
|
||||
}
|
||||
CheckedRequest::HeaderWithAncestors(_, ref req) => {
|
||||
if req.skip != 1 || !req.reverse {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(&net_request::HashOrNumber::Hash(start)) = req.start.as_ref() {
|
||||
let mut result = Vec::with_capacity(req.max as usize);
|
||||
let mut hash = start;
|
||||
let mut cache = cache.lock();
|
||||
for _ in 0..req.max {
|
||||
match cache.block_header(&hash) {
|
||||
Some(header) => {
|
||||
hash = header.parent_hash();
|
||||
result.push(header);
|
||||
}
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
Some(Response::HeaderWithAncestors(result))
|
||||
} else { None }
|
||||
}
|
||||
CheckedRequest::Receipts(ref check, ref req) => {
|
||||
// empty transactions -> no receipts
|
||||
if check.0.as_ref().ok().map_or(false, |hdr| hdr.receipts_root() == KECCAK_NULL_RLP) {
|
||||
@ -458,6 +495,7 @@ macro_rules! match_me {
|
||||
match $me {
|
||||
CheckedRequest::HeaderProof($check, $req) => $e,
|
||||
CheckedRequest::HeaderByHash($check, $req) => $e,
|
||||
CheckedRequest::HeaderWithAncestors($check, $req) => $e,
|
||||
CheckedRequest::TransactionIndex($check, $req) => $e,
|
||||
CheckedRequest::Receipts($check, $req) => $e,
|
||||
CheckedRequest::Body($check, $req) => $e,
|
||||
@ -487,6 +525,15 @@ impl IncompleteRequest for CheckedRequest {
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
CheckedRequest::HeaderWithAncestors(ref check, ref req) => {
|
||||
req.check_outputs(&mut f)?;
|
||||
|
||||
// make sure the output given is definitively a hash.
|
||||
match check.block_hash {
|
||||
Field::BackReference(r, idx) => f(r, idx, OutputKind::Hash),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
CheckedRequest::TransactionIndex(_, ref req) => req.check_outputs(f),
|
||||
CheckedRequest::Receipts(_, ref req) => req.check_outputs(f),
|
||||
CheckedRequest::Body(_, ref req) => req.check_outputs(f),
|
||||
@ -507,15 +554,46 @@ impl IncompleteRequest for CheckedRequest {
|
||||
|
||||
fn complete(self) -> Result<Self::Complete, net_request::NoSuchOutput> {
|
||||
match self {
|
||||
CheckedRequest::HeaderProof(_, req) => req.complete().map(CompleteRequest::HeaderProof),
|
||||
CheckedRequest::HeaderByHash(_, req) => req.complete().map(CompleteRequest::Headers),
|
||||
CheckedRequest::TransactionIndex(_, req) => req.complete().map(CompleteRequest::TransactionIndex),
|
||||
CheckedRequest::Receipts(_, req) => req.complete().map(CompleteRequest::Receipts),
|
||||
CheckedRequest::Body(_, req) => req.complete().map(CompleteRequest::Body),
|
||||
CheckedRequest::Account(_, req) => req.complete().map(CompleteRequest::Account),
|
||||
CheckedRequest::Code(_, req) => req.complete().map(CompleteRequest::Code),
|
||||
CheckedRequest::Execution(_, req) => req.complete().map(CompleteRequest::Execution),
|
||||
CheckedRequest::Signal(_, req) => req.complete().map(CompleteRequest::Signal),
|
||||
CheckedRequest::HeaderProof(_, req) => {
|
||||
trace!(target: "on_demand", "HeaderProof request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::HeaderProof)
|
||||
}
|
||||
CheckedRequest::HeaderByHash(_, req) => {
|
||||
trace!(target: "on_demand", "HeaderByHash request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Headers)
|
||||
}
|
||||
CheckedRequest::HeaderWithAncestors(_, req) => {
|
||||
trace!(target: "on_demand", "HeaderWithAncestors request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Headers)
|
||||
}
|
||||
CheckedRequest::TransactionIndex(_, req) => {
|
||||
trace!(target: "on_demand", "TransactionIndex request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::TransactionIndex)
|
||||
}
|
||||
CheckedRequest::Receipts(_, req) => {
|
||||
trace!(target: "on_demand", "Receipt request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Receipts)
|
||||
}
|
||||
CheckedRequest::Body(_, req) => {
|
||||
trace!(target: "on_demand", "Block request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Body)
|
||||
}
|
||||
CheckedRequest::Account(_, req) => {
|
||||
trace!(target: "on_demand", "Account request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Account)
|
||||
}
|
||||
CheckedRequest::Code(_, req) => {
|
||||
trace!(target: "on_demand", "Code request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Code)
|
||||
}
|
||||
CheckedRequest::Execution(_, req) => {
|
||||
trace!(target: "on_demand", "Execution request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Execution)
|
||||
}
|
||||
CheckedRequest::Signal(_, req) => {
|
||||
trace!(target: "on_demand", "Signal request completed {:?}", req);
|
||||
req.complete().map(CompleteRequest::Signal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -551,6 +629,9 @@ impl net_request::CheckedRequest for CheckedRequest {
|
||||
CheckedRequest::HeaderByHash(ref prover, _) =>
|
||||
expect!((&NetResponse::Headers(ref res), &CompleteRequest::Headers(ref req)) =>
|
||||
prover.check_response(cache, &req.start, &res.headers).map(Response::HeaderByHash)),
|
||||
CheckedRequest::HeaderWithAncestors(ref prover, _) =>
|
||||
expect!((&NetResponse::Headers(ref res), &CompleteRequest::Headers(ref req)) =>
|
||||
prover.check_response(cache, &req.start, &res.headers).map(Response::HeaderWithAncestors)),
|
||||
CheckedRequest::TransactionIndex(ref prover, _) =>
|
||||
expect!((&NetResponse::TransactionIndex(ref res), _) =>
|
||||
prover.check_response(cache, res).map(Response::TransactionIndex)),
|
||||
@ -584,6 +665,8 @@ pub enum Response {
|
||||
HeaderProof((H256, U256)),
|
||||
/// Response to a header-by-hash request.
|
||||
HeaderByHash(encoded::Header),
|
||||
/// Response to a header-by-hash with ancestors request.
|
||||
HeaderWithAncestors(Vec<encoded::Header>),
|
||||
/// Response to a transaction-index request.
|
||||
TransactionIndex(net_request::TransactionIndexResponse),
|
||||
/// Response to a receipts request.
|
||||
@ -625,6 +708,10 @@ pub enum Error {
|
||||
Decoder(::rlp::DecoderError),
|
||||
/// Empty response.
|
||||
Empty,
|
||||
/// Response data length exceeds request max.
|
||||
TooManyResults(u64, u64),
|
||||
/// Response data is incomplete.
|
||||
TooFewResults(u64, u64),
|
||||
/// Trie lookup error (result of bad proof)
|
||||
Trie(TrieError),
|
||||
/// Bad inclusion proof
|
||||
@ -641,6 +728,8 @@ pub enum Error {
|
||||
WrongTrieRoot(H256, H256),
|
||||
/// Wrong response kind.
|
||||
WrongKind,
|
||||
/// Wrong sequence of headers.
|
||||
WrongHeaderSequence,
|
||||
}
|
||||
|
||||
impl From<::rlp::DecoderError> for Error {
|
||||
@ -701,6 +790,65 @@ impl HeaderProof {
|
||||
}
|
||||
}
|
||||
|
||||
/// Request for a header by hash with a range of ancestors.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct HeaderWithAncestors {
|
||||
/// Hash of the last block in the range to fetch.
|
||||
pub block_hash: Field<H256>,
|
||||
/// Number of headers before the last block to fetch in addition.
|
||||
pub ancestor_count: u64,
|
||||
}
|
||||
|
||||
impl HeaderWithAncestors {
|
||||
/// Check a response for the headers.
|
||||
pub fn check_response(
|
||||
&self,
|
||||
cache: &Mutex<::cache::Cache>,
|
||||
start: &net_request::HashOrNumber,
|
||||
headers: &[encoded::Header]
|
||||
) -> Result<Vec<encoded::Header>, Error> {
|
||||
let expected_hash = match (self.block_hash, start) {
|
||||
(Field::Scalar(ref h), &net_request::HashOrNumber::Hash(ref h2)) => {
|
||||
if h != h2 { return Err(Error::WrongHash(*h, *h2)) }
|
||||
*h
|
||||
}
|
||||
(_, &net_request::HashOrNumber::Hash(h2)) => h2,
|
||||
_ => return Err(Error::HeaderByNumber),
|
||||
};
|
||||
|
||||
let start_header = headers.first().ok_or(Error::Empty)?;
|
||||
let start_hash = start_header.hash();
|
||||
if start_hash != expected_hash {
|
||||
return Err(Error::WrongHash(expected_hash, start_hash));
|
||||
}
|
||||
|
||||
let expected_len = 1 + cmp::min(self.ancestor_count, start_header.number());
|
||||
let actual_len = headers.len() as u64;
|
||||
match actual_len.cmp(&expected_len) {
|
||||
cmp::Ordering::Less =>
|
||||
return Err(Error::TooFewResults(expected_len, actual_len)),
|
||||
cmp::Ordering::Greater =>
|
||||
return Err(Error::TooManyResults(expected_len, actual_len)),
|
||||
cmp::Ordering::Equal => (),
|
||||
};
|
||||
|
||||
for (header, prev_header) in headers.iter().zip(headers[1..].iter()) {
|
||||
if header.number() != prev_header.number() + 1 ||
|
||||
header.parent_hash() != prev_header.hash()
|
||||
{
|
||||
return Err(Error::WrongHeaderSequence)
|
||||
}
|
||||
}
|
||||
|
||||
let mut cache = cache.lock();
|
||||
for header in headers {
|
||||
cache.insert_block_header(header.hash(), header.clone());
|
||||
}
|
||||
|
||||
Ok(headers.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
/// Request for a header by hash.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct HeaderByHash(pub Field<H256>);
|
||||
@ -993,6 +1141,83 @@ mod tests {
|
||||
assert!(HeaderByHash(hash.into()).check_response(&cache, &hash.into(), &[raw_header]).is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_header_with_ancestors() {
|
||||
let mut last_header_hash = H256::default();
|
||||
let mut headers = (0..11).map(|num| {
|
||||
let mut header = Header::new();
|
||||
header.set_number(num);
|
||||
header.set_parent_hash(last_header_hash);
|
||||
|
||||
last_header_hash = header.hash();
|
||||
header
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
headers.reverse(); // because responses are in reverse order
|
||||
|
||||
let raw_headers = headers.iter()
|
||||
.map(|hdr| encoded::Header::new(::rlp::encode(hdr).into_vec()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut invalid_successor = Header::new();
|
||||
invalid_successor.set_number(11);
|
||||
invalid_successor.set_parent_hash(headers[1].hash());
|
||||
|
||||
let raw_invalid_successor = encoded::Header::new(::rlp::encode(&invalid_successor).into_vec());
|
||||
|
||||
let cache = Mutex::new(make_cache());
|
||||
|
||||
let header_with_ancestors = |hash, count| {
|
||||
HeaderWithAncestors {
|
||||
block_hash: hash,
|
||||
ancestor_count: count
|
||||
}
|
||||
};
|
||||
|
||||
// Correct responses
|
||||
assert!(header_with_ancestors(headers[0].hash().into(), 0)
|
||||
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]).is_ok());
|
||||
assert!(header_with_ancestors(headers[0].hash().into(), 2)
|
||||
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..3]).is_ok());
|
||||
assert!(header_with_ancestors(headers[0].hash().into(), 10)
|
||||
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]).is_ok());
|
||||
assert!(header_with_ancestors(headers[2].hash().into(), 2)
|
||||
.check_response(&cache, &headers[2].hash().into(), &raw_headers[2..5]).is_ok());
|
||||
assert!(header_with_ancestors(headers[2].hash().into(), 10)
|
||||
.check_response(&cache, &headers[2].hash().into(), &raw_headers[2..11]).is_ok());
|
||||
assert!(header_with_ancestors(invalid_successor.hash().into(), 0)
|
||||
.check_response(&cache, &invalid_successor.hash().into(), &[raw_invalid_successor.clone()]).is_ok());
|
||||
|
||||
// Incorrect responses
|
||||
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 0)
|
||||
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]),
|
||||
Err(Error::WrongHash(invalid_successor.hash(), headers[0].hash())));
|
||||
assert_eq!(header_with_ancestors(headers[0].hash().into(), 0)
|
||||
.check_response(&cache, &headers[0].hash().into(), &[]),
|
||||
Err(Error::Empty));
|
||||
assert_eq!(header_with_ancestors(headers[0].hash().into(), 10)
|
||||
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..10]),
|
||||
Err(Error::TooFewResults(11, 10)));
|
||||
assert_eq!(header_with_ancestors(headers[0].hash().into(), 9)
|
||||
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]),
|
||||
Err(Error::TooManyResults(10, 11)));
|
||||
|
||||
let response = &[raw_headers[0].clone(), raw_headers[2].clone()];
|
||||
assert_eq!(header_with_ancestors(headers[0].hash().into(), 1)
|
||||
.check_response(&cache, &headers[0].hash().into(), response),
|
||||
Err(Error::WrongHeaderSequence));
|
||||
|
||||
let response = &[raw_invalid_successor.clone(), raw_headers[0].clone()];
|
||||
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1)
|
||||
.check_response(&cache, &invalid_successor.hash().into(), response),
|
||||
Err(Error::WrongHeaderSequence));
|
||||
|
||||
let response = &[raw_invalid_successor.clone(), raw_headers[1].clone()];
|
||||
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1)
|
||||
.check_response(&cache, &invalid_successor.hash().into(), response),
|
||||
Err(Error::WrongHeaderSequence));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_body() {
|
||||
use rlp::RlpStream;
|
||||
|
@ -33,6 +33,9 @@ use transaction_queue::TransactionQueue;
|
||||
|
||||
use request;
|
||||
|
||||
/// Maximum allowed size of a headers request.
|
||||
pub const MAX_HEADERS_PER_REQUEST: u64 = 512;
|
||||
|
||||
/// Defines the operations that a provider for the light subprotocol must fulfill.
|
||||
pub trait Provider: Send + Sync {
|
||||
/// Provide current blockchain info.
|
||||
@ -54,7 +57,6 @@ pub trait Provider: Send + Sync {
|
||||
/// results within must adhere to the `skip` and `reverse` parameters.
|
||||
fn block_headers(&self, req: request::CompleteHeadersRequest) -> Option<request::HeadersResponse> {
|
||||
use request::HashOrNumber;
|
||||
const MAX_HEADERS_TO_SEND: u64 = 512;
|
||||
|
||||
if req.max == 0 { return None }
|
||||
|
||||
@ -83,7 +85,7 @@ pub trait Provider: Send + Sync {
|
||||
}
|
||||
};
|
||||
|
||||
let max = ::std::cmp::min(MAX_HEADERS_TO_SEND, req.max);
|
||||
let max = ::std::cmp::min(MAX_HEADERS_PER_REQUEST, req.max);
|
||||
|
||||
let headers: Vec<_> = (0u64..max)
|
||||
.map(|x: u64| x.saturating_mul(req.skip.saturating_add(1)))
|
||||
@ -128,7 +130,7 @@ pub trait Provider: Send + Sync {
|
||||
fn header_proof(&self, req: request::CompleteHeaderProofRequest) -> Option<request::HeaderProofResponse>;
|
||||
|
||||
/// Provide pending transactions.
|
||||
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction>;
|
||||
fn transactions_to_propagate(&self) -> Vec<PendingTransaction>;
|
||||
|
||||
/// Provide a proof-of-execution for the given transaction proof request.
|
||||
/// Returns a vector of all state items necessary to execute the transaction.
|
||||
@ -283,8 +285,8 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
|
||||
.map(|(_, proof)| ::request::ExecutionResponse { items: proof })
|
||||
}
|
||||
|
||||
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction> {
|
||||
BlockChainClient::ready_transactions(self, max_len)
|
||||
fn transactions_to_propagate(&self) -> Vec<PendingTransaction> {
|
||||
BlockChainClient::transactions_to_propagate(self)
|
||||
.into_iter()
|
||||
.map(|tx| tx.pending().clone())
|
||||
.collect()
|
||||
@ -370,12 +372,10 @@ impl<L: AsLightClient + Send + Sync> Provider for LightProvider<L> {
|
||||
None
|
||||
}
|
||||
|
||||
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction> {
|
||||
fn transactions_to_propagate(&self) -> Vec<PendingTransaction> {
|
||||
let chain_info = self.chain_info();
|
||||
let mut transactions = self.txqueue.read()
|
||||
.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp);
|
||||
transactions.truncate(max_len);
|
||||
transactions
|
||||
self.txqueue.read()
|
||||
.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -173,9 +173,9 @@
|
||||
"gasLimit": "0x1388",
|
||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f90207a0cdaf426b80edd4363b336b351cbfec8c38b44847cdbd814aa92e92bc9ec05333a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949435d50503aee35c8757ae4933f7a0ab56597805a03f28b2b384dbfd29bc0a10343e8a419e61b92782f880046170bf1d11455e94bba0f3712ef3ff24efe1afc7da11ffb2ca495a94fe7958f42e9f1599d66ed72af13ba06d01d03a15f807da601bd2dfde7490bbe91d9bb11c11eda435db9daad6e7b1efb9010000008c0000c000000000440100108040000082000800000000000000040801001004001000000010000000001000043300001000008000800000002000200040000000580c0004108000040c0008000006000000000280800080000800000000402000000a000000a810226200002881004000208006020000000510030000100040010100000086c20000000009000100000190008c80060000008000202080420008056040000000001000400001100010140822800220000c804004002000108000160001400200088082008000000412100010080205011000000800a0000810021005000000000002840000000400000000880000006000000000200002870bfca554dbc6398358b001837a137083473c8e845b27f4fd86436f72746578a0dbf31fd28bd8f69f1103196e1782a9dfb636bcfa726362ab0767235cb8d56e7188264402501145497f",
|
||||
"totalDifficulty": "4838383800145139949936",
|
||||
"hardcodedSync": {
|
||||
"header": "f9020ba0c7139a7f4b14c2e12dbe34aeb92711b37747bf8698ecdd6f2c3b1f5f3840e288a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452e44f279f4203dcf680395379e5f9990a69f13ca06e817f8a9b206f93a393da76a3ece2a74b98eaecc4dae0cfa8f409455e88ccb4a0d739197170d2bc6bbb24fac0ce695982090702082fe1541bb7634f018dfe87b3a038503b7299fb1c113a78b4a3a5dfd997ef32e7fbf722fc178dfcb21e1af1f7f5b9010000020000000000000008000000000010000000000000000000000000000200000002000000000008000000000000000000000000000000000000000000000000000000000000000001004008000000000000000000000000000080000000000008000000080000000000008000000000000000000000000000040210004000000010000000400000000001040000000200000000000000440008000000040000000000000000000000000010000000000000000000000000000000800000000000100002000000000000000000002000000000000000000000000000000000000080000000100000000000000000040400000000000000004000000000000000870c90e059b181c6835ee8018379fb9583065150845b833d198a7777772e62772e636f6da0171fc2d066507ea10c8c2d7bedd5ccc3f0dfb4d590a3998a614013326c0b213a88b4fd884826187393",
|
||||
"totalDifficulty": "6255555800944520547241",
|
||||
"CHTs": [
|
||||
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
|
||||
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
|
||||
@ -3014,7 +3014,206 @@
|
||||
"0x118b3ae7ad25ab96fe8a63973312c758d4ce9ecd39cc24913c26a65b4b5534de",
|
||||
"0x19cd088af8dbe2d3e6ca7987d9ee1564ea2256f482840b1d2f0da85060de9a86",
|
||||
"0x98bc07422cf8b0c4d1428afb759300d9a7637de2518528d34f7d237be7e863be",
|
||||
"0x0c64526b393066911c7da3f17f9e652cfa38112ae324e3c84416e811d3fe7cad"
|
||||
"0x0c64526b393066911c7da3f17f9e652cfa38112ae324e3c84416e811d3fe7cad",
|
||||
"0xa30cbfaf518996ba776b426a7068faad4ee49775db45565ebd327f9c679a45b4",
|
||||
"0xd3e1a807f5940ee1a321b20b7931bef90515132ea9959df94e55529e05802cab",
|
||||
"0x338aef579d9ec8acc1a0411c1674bcf213d03aa7d4bbc56707e081829ce30004",
|
||||
"0x68c7a603089a220273f019001a39bfa9194590a6fa6d8ba960ddf4888b105a6b",
|
||||
"0xd6a9d2c354e1dd77322800d24774eb03b589dd94bcdb3cc2b70437ed70411e6a",
|
||||
"0x39c017c42ad571564792bf5741b3ae786ff0c24ebcb5ee46882ce0545b8a2262",
|
||||
"0xf5caea6b23f4085c9f94c880d89b1c23eb69c03dc098b426143ae4b28969a2d8",
|
||||
"0x959eebc05ff0dfae8c7e6699f069b38b5f2e5bc8c155bc35fc7f578d2d112993",
|
||||
"0x199e90557d4d9e13c3e7a4b5b4ef6fe52cd2c724c36eaa44b7fa151efebbbeee",
|
||||
"0x0bfe35d253227696e76f92ff13e4c545c57fca51186a16f687e76d2e6707d34f",
|
||||
"0xadf8b7678f98b0e5009130d9d5d77add6e460b67b0529abc5315c44dadea0cb4",
|
||||
"0x86582f3a98b218939aefd7eea438ee278d1faaf41920e8c72922c46fd56f1c32",
|
||||
"0x001b728a4737fdd53cde20341fa0adec9aa8ab7c7c1db244fbd509a6c4f3f364",
|
||||
"0x9207900bfdd6c87e2ba8498c0372706799604a207930eeb331580459d17f89cb",
|
||||
"0xd2192fcf74cad70e6f7986a0b088de8658a14638a4c03d7ae616a88ceea00ba2",
|
||||
"0xbf6f6b91742eebe70204eb7a70196ef636fc2db4d4c4f89cd5826fbf990a945d",
|
||||
"0x5c1210951949402fe3b012577f1af0d3e285a0b39c3fe19c84f7930e003c06de",
|
||||
"0xa16d57f777f94f032f7f2f75b2e25ebd11559effee98b39a5a1e7cc804cfbf06",
|
||||
"0x1b9561fb8035ec6955454d6710f053d7ad3d8e0753aaac568ac3bc98f874465e",
|
||||
"0x1a622da786425e0b65b9083a451a419c75e16908fa04d89ddc2c11d94ffe65a0",
|
||||
"0xbfcb9b1d847eb40b6808e45bf3d2fb8f6588d6f103167be65f246d0733afd1f7",
|
||||
"0x2317640589ab9d52e7f5e8dda95ff3b1beceacc5832341e9053b71209bfad07f",
|
||||
"0xa10611b829dbb533e565ad01632b26b1fd642a4393e7fdd9b8f235f11bb606c8",
|
||||
"0xe4ea4173982f342e396356b0bb0eb47e6748461ecce0f34dbe8fc084cf6a9fbc",
|
||||
"0xd58399c0d0ae878338d2915eaf2d65f2d1e29eb8d551d254e68bce7a8235adcb",
|
||||
"0xc0c8b73ffc675a207f73903c49d81131e6831e4c8e071b988ed9f2a5d2277024",
|
||||
"0xe1ca77bafa66bb055c671978b3d1bd5df32f8e269330507f071afd627012b6af",
|
||||
"0x67a1093cbddf41264009d1dbbc33fbc25a337339be0727e70c512b585897749c",
|
||||
"0x0fd615782db5cf4c0a3686721cbc6245696c1bc9b403a9eaffae00968d2c8ece",
|
||||
"0xc3c2dcaee8954ca86d9b3e4e98c4bb4f6b6bc183f9eb062016c5a25b2280717b",
|
||||
"0x70265915f5ed94d589afafa3d0d0eab6310195cc690aa82bd65e4a488b398c58",
|
||||
"0xde3fead8ce29c04a86dcb081da2cabda5366d28de5ebfe2f8064780413f71edf",
|
||||
"0x0ae43394fcf6ebdabdcc1ede314fe779eb61a12eab807a9d3437d9167e2247e3",
|
||||
"0x3241127e2c7fbb3db9fe0c602b0c94e22c684b7910ffcf09c1c443e567f95e4d",
|
||||
"0xcb94ba286eeaa1129b490bb5891e603fd35e85c97c2132c1216d1774f9017f35",
|
||||
"0xbf396cd23c29ef21fb535880ef621457fb71981f856f2a09c494cd005d38f981",
|
||||
"0x3df0c90ed7aba260e820ca1d28ce1778149e163524e306309aa346bbadedcf2b",
|
||||
"0x66a2724f7481aa3ab83a8f1bae2caef8a7bc607c7ffd5bbb1cf3766741db804f",
|
||||
"0x7a0c3492f4022322e10d81bc10a5db9aceec81d1ab70cdffd31418b79d750fd2",
|
||||
"0x96a826cb667924ed75ec708bf07cf4c7c05f84a0132e154b71eaf6e193590e87",
|
||||
"0xcc7030fe617c318a31984d04e3d7f2ff2196894bc429f3f64bfd69b969dc9b56",
|
||||
"0x3fa94aae223f5aeb593246f1a93d6d694b48946c09d879e791f1188a9dedc4c0",
|
||||
"0xd49e51fc324fe58159575c0c24171f4eb1aaf58ed8e1311c3849538c8cec3ce1",
|
||||
"0xc474123906eae5cd48a10e0d93fcbbd653f0c6d25275f827d4fac51e696c3d91",
|
||||
"0xacd7b790a19026fa3f3b0a354878d4fcd79dc600f7ba5cedd2eefffe1ceda76c",
|
||||
"0x41b311a188cd7ce1444d258dc379994b81a895226276c7bfe5e6cb29a5f92142",
|
||||
"0xda0ae01db7f73f07fce46b94c24d6e400598378a6baf01123dd710c5425fb8c9",
|
||||
"0xe62e08175a02b575e28b9e029a838c365e3ce4278f60c2d3b5d529768a4b47c4",
|
||||
"0x99b804c8d0feda7f9df961527d634fb8b2d477a362e1d8158856885a13425fa9",
|
||||
"0xe73597be8ef7d78f862c7a94a8ccff17f559816eba2f830821c6f6436898f9fb",
|
||||
"0x36de9ee4c80853c865b16904cd8f6c0e9a99ff9e7bf05100bfbc76789cedd4d1",
|
||||
"0xf480b762872373102393461ff3a21323a1df799c315fd167780a45d7bfaae84e",
|
||||
"0x303b66babd21e72449cad413e04bdb0bc3ebcbb84a79dd30ed7c972c5341b82b",
|
||||
"0xbf111684fbe44a973594f31cdee2c94e807bff9cf7584c22dcd609d8234f6e62",
|
||||
"0x79b26cc3bbf49b6f25afbff7e97e4e45f2dcb359095fdbeb7fb7addee692afc3",
|
||||
"0x2839d620cc140ba838ecba6e7e52db8cf7b5cd4cf4857f72f3bfbc9b1cf0fbd9",
|
||||
"0x93074136f4eec367adcf27955d38efc0dc6da514693bfc97935c7871793e35ea",
|
||||
"0x21f5af18a4cf0096b6e6a3d4c98f4043cfee5c4ee085ce106f86b713160144b8",
|
||||
"0x90d16b403e2deca6cd5c80e52eba0b84b2875e1dfd75fffb1a2f82bc91eb6942",
|
||||
"0x8a5cb6854c19a865f51e3ee9eaf8e843a97b272f6467634ba40e547a435ef624",
|
||||
"0x9afe42a0dffca8ec063c83908fd6237d6130c9dfeab57078bdd02b6ac6d0ea07",
|
||||
"0xa05cc6108b475d3e68e280e98f514cfb6df4f004e1b7708fcfd4528d346bea6b",
|
||||
"0x71f10879b875caefab46669e8525b9c0487bbe3247e43a6cdb1dedbfb4d4ba33",
|
||||
"0x7debdafd2b1410469fd76e2a39dcd1b8f400292f5359ecd39186a5be0f9e44b8",
|
||||
"0x076f8741b668f3f715a7142f5c1592ffb58ca13e8612edc340619a1ca6ce3f2a",
|
||||
"0xe312bb85cd945eb45f72868e6651633964f22ce3ffcbd0f3701bf57ac0c13edd",
|
||||
"0xe6eae7aad7fed9c690a14eb7aa107c83a5e54736940ac6d82e251181e1103eae",
|
||||
"0x794c8ade9063600442f83d4be14d7bbb191c692314253a2c62dcb33f3e7d28bd",
|
||||
"0x6fd9db41dc1074a4349a6d3881757ad931bdf9ec261fc4e0a5ba9cfa5fafbf41",
|
||||
"0x37557ead7100564651992a919949af3f39f3eacc03aa0ea158dd59abc4e2a93d",
|
||||
"0x7a3b01cf210dfc42e4e41c95af1af357d15409fecae888abf4fa35149f44ed2e",
|
||||
"0x89e952ed9afda8aa0ff80ceb90e5857dc7fc3cb6259ac6089da5fed49223cf42",
|
||||
"0xf1ae8d3769142a1f3c8bc0ecf8454f05b09354a2ad5c921d0a6845417bc2f244",
|
||||
"0xa04e022b2afd83a1e14d0d67595070b29f196dcfc05d92b2ce7c582d67af4a00",
|
||||
"0xa3a0c85dfc3d8055a29de34492b3e231691bb6e9ca06684a205837ab9870c72e",
|
||||
"0xee2529ad0af60748cc0bd8d97189d878643a52710dd200f79f27d8a4a4c8c093",
|
||||
"0xac88fe07805a058f1341ed89795f0e5e9ace050de0742f863c1c9c63b17aed12",
|
||||
"0x8fddc716ab43397541f6b22644949c6d7214b01ca8223310a34840df37c47746",
|
||||
"0x3cbb4d1a2ea6fce170de64b1f4bbb8d9239fe191018b737e62eda77aeb7d0306",
|
||||
"0x3807421ad84d6f2f9d5d830364a0455d6846e114b87cd08a3cb9a33e40c7c084",
|
||||
"0x283199cbf0e1c997025bd36522619417d9e6184073b830fb22c3de106a68b598",
|
||||
"0xcbc85a7ee2122abad27b1f5a07bd15d864af382a62fd552092b7feec4d2e4856",
|
||||
"0x84586eae7108f2e1217d53be81f26bff7cc35409c64c1af827bb5263d813302f",
|
||||
"0x5d2d93535aa7db5e2204e419ecf4d7c0647ce40522806bd24ecf348eb49a1f17",
|
||||
"0x3a6118c84312f120c0d3e4ae4ec0b8103448da31953fa27a8400ed7e4875897e",
|
||||
"0x4a0d1639274d31dc5d9eb49338b204e9cc9610913c0320e7da74a02ed2486fb6",
|
||||
"0xa7770b7cf4f83c387344cff6ddd3441dd131333df0f210a57a271fc1a61f08f8",
|
||||
"0x35066ce607eafc9bdd3386097a98c844bda683ce29faf25708b1a2f3e25c9aca",
|
||||
"0x7068b1f5c017ff5b995f2c65db7daed3cd9fd0e658322ee2debbba7de3ebdd72",
|
||||
"0xfbcf8cec0ed675d12ab4fab45754fd00a329d19ad77afe4413a0581bb6dab8dd",
|
||||
"0x78035e412813b0a3f7e3f46bafe436b57b83278499fe8b8a1bdb3066f538d0b1",
|
||||
"0x28bfbcd7eb38793a1ea711b6dd73c55da0faee3a9707c743737f0692dc6b56a1",
|
||||
"0x9fb1607599329b61570a0daeb7b1a93210ac286e02a64ae309e1950cdd76c5e5",
|
||||
"0x8903d98196291218a50fe03a5cd51592e1b458315491d735187cb39d0e21f397",
|
||||
"0x97aa20d84821d36a44ce18eff501df95549c8266220ad612d0ba9d293d65271a",
|
||||
"0x3245e35a2c6d46002dbf5bfedee31fd28a88409edbc55ee1ef7972a249b1cce2",
|
||||
"0xd6149428168dbf78ab2f706f041a61e3074e3d18ed47bd343d54c3e4f2e051fe",
|
||||
"0x9f4a04d0e3a2b8773a258bfcdee5242e44761aa1a1d2f9a7162f04a2b85de6c8",
|
||||
"0x0162a3449c2be2a0a45a771027e5fb67169c5a56c4ef6f386093fa79f9942fce",
|
||||
"0x5c1196a72f2c6fb5771e0390ef25499acd52c6aeeac3615ff17dcf2c405069ca",
|
||||
"0x319097551b7df30bc67f5ee6f068cf3b34e71371b91635e9009af7acfe97e12d",
|
||||
"0x8b89e2e091824d0c3276128543991cf7c35a82bed4b92b4e67aeb4652033a823",
|
||||
"0x75d6dd431d5568625946b3578e68d47523518cb2e141369aee5273fb7cdc4013",
|
||||
"0xc473b7b23c164759487af8c96865f0f3af3f3e40e9607665f94f937c3334f604",
|
||||
"0x1f61783925fc03f3f5465f37aad2276c466ddb91a47db036f042c0b2edbbf643",
|
||||
"0x3f6370976528cc31e4d099711329d5c670a2538623621b164d470fd7ee2cfb17",
|
||||
"0x3705bd7548fcdeb0dbb3162394edb2adcd5128524eb837b71a04ff0c9c21c22b",
|
||||
"0xe15e99e427efae16230af47e59ff89b76df25db44fa2dfe95d2419b6de35ee7a",
|
||||
"0xbb4a17b5e4879b52e6a4838df9525ae01b168197db2910caea805011588559a7",
|
||||
"0x60e6cc67da461bafef5c3b7e4f9e964a24c3146c4fc22c2e046301e457d1cdfc",
|
||||
"0x72ef37234da6fe157e0e87b11528c3e41d115f10f1dcfce60e54d83c1406989a",
|
||||
"0x63c3a73812427f73be785d4690a6ff81912d3ac17c8d76970ded284383ec97a2",
|
||||
"0xf88c0457e00ec47c27ddc6d99fe6c0b82bf9249018a96b1c7e6b90e906adfaad",
|
||||
"0x9258fa102e450844e091b58dfff2fd05b8fa099d53667626e340fda7ff7f9bd1",
|
||||
"0x68adeaa1063528386db31407596442f815769731da8b560272ba3e1b8817a11a",
|
||||
"0x222a41b6e681d2acf8a9fbd9310d34145a3c49160c29681b95c85176abadddf2",
|
||||
"0x00745c4bb8cf5fb63700444f9258eb94e4b527ba8739fed4bbd7b13083854929",
|
||||
"0xf27199044245d103b296bb81188982baa87175843b06424e0b5fe9dc6e005705",
|
||||
"0xe00c3bfee8d71930faae9ca720f25f342ad166f438c07b0664c0c2d6b9f82c58",
|
||||
"0x05e2bd6caee8a926c0f61bd0e5553b304656cf4749f54bb45b72d2a84fcf2378",
|
||||
"0xcff8627a22e37d1087c3b858079a4f90a1fac65cd397dce26be8c3efe2515e1e",
|
||||
"0x4885a5f8fb2e367a9edb32b02ad4390a4ef8f317a0e7d3bcfd5eccb9d8d05b1d",
|
||||
"0x194638cb01699bfdb67b09ce5e2e8d5dbcfd403ae325a7a0311923ba5207c5b6",
|
||||
"0x20e7c0ec1db7ca6adeeeb0c7950b7911e1627bb173425c4eaa105cfcc9c43db6",
|
||||
"0x1010eb2f28d04da879c67f4c9e51fd480753081eac6123c5161502f3180764f0",
|
||||
"0x09a0d0aac41a4e2fadb48c1751011fb46774f10ee263567d823e275aa0a33ec3",
|
||||
"0xde190e4dde46d967a4e32ecfda15323c7f4081f40d5f245916055af44b008e81",
|
||||
"0x21870402899f8c05003a175f2c0d37fdfb52c9bda3eea3ac8616c832fd8ac173",
|
||||
"0xbec735492b66890aeb0ccb5611a84a908477269c2336e076c42cbb620cee8861",
|
||||
"0xb9daeedd739766f82a95505a9e71daa503a5f0c3ee1a6a97f842b2ffb6ddc6ad",
|
||||
"0x9f30d706fc86c7322a10a3c572df2ef4f2f49bcb49c5afc2c6299cf051e2e38f",
|
||||
"0x9dc1d641fab155885db408328e60c06d97a0e3327b64a18d46e7ced7cacff446",
|
||||
"0x252594a4da3cc4e794d954e88c15a2c847dd84d895eca06b9365a85a71fc46eb",
|
||||
"0x979ea7682319cb0674066b10eb7919a87ad1ec0618ddb24723f13c55899cbb6c",
|
||||
"0x570b4dce3b4613a8266688291f06bafa9d3b7828e3e6a9bfd27e7d2f3ba59125",
|
||||
"0x39e97e3c20af2dcfa347ec193cae2c00100effd4f3987bfe21973db8c5e11fc5",
|
||||
"0xf66b0859b41bf7dc53dd23762ecc593f4572a8a9f82b4c51257af1eda6344bcf",
|
||||
"0xfc32a5b84537ed5947874eca72d189f74676855be5ded4d32eac2ebc0c3a3306",
|
||||
"0xa89c577f12bedcc225cdfbf86ebe8112aef97b9c34a504dda52cea4f40f72be1",
|
||||
"0x67e4b71c08fd93f1c37cc60826c5d8c18e14b89a7f271e0828b114de39aff694",
|
||||
"0x342279789cd6a721f5f4866e3a16d19f88b24ac277563ec7b0716ecdf8dace3d",
|
||||
"0x220a5babb290dc16440f4b01bc117c41af5073110b1375cae0317f9fd364d44c",
|
||||
"0xbc1019eec10ff493e095915f66d46f0855b55aa681352774dc300d54147efb00",
|
||||
"0xa9cc80ffc08c2b4c38fa178e3ac56ef982d0487b7139ed241fdda3894f4b67e2",
|
||||
"0xb35267a4b6020a2e53e112f4ba7807ec50ba78a3b2d64fc3e3bfe918bb25bd9e",
|
||||
"0xd5021c0c199dbb1b61e5e0d4bcd59fd064ddb6d6611421e57161f9c37fba91f0",
|
||||
"0xea0af5bbcc015b06951c9ff3df3c233f4bdd6ef8eab97f0b3a9e10b01efd7a5a",
|
||||
"0xc060f20f45851e6de2fe1dcb6d8996add5335c34892f84a1db711d0c47c5da4a",
|
||||
"0xbd30199b078305b459565598fea6740a4d187e4813d3887f72d7958ebcc8da48",
|
||||
"0xeafa07e96737a0e53ee7a09bc1b394ae4c1ec6c937901a8066b0cb6b6908aff5",
|
||||
"0x68abed404e0a66ded23d152fc5544b14b0a4fe918a51b667f2dc827575c12136",
|
||||
"0x27da4b5111565097dba6e6dade4f0275ea8234b50f391aa270bb3cfb361e6331",
|
||||
"0x85126b95e3532b5045710f60d0aa3f6b0e801130722bc7d85a67479e0b1fba25",
|
||||
"0x658afe5a3d3b0916372785f952d92069045b747fc67be6c8bce3d695a434d058",
|
||||
"0x9017ad7725867d37402da5ef1727289abcdf9982a0c7dbd7fa6f175ef8ff5f90",
|
||||
"0x892a34192371a1de6d4c2ceabeff5aa9e26c3f41e74260d305872f366bdb73d1",
|
||||
"0x786a848c13f84c87ca554654f0ab35f7fea5014669d919595e087e6463c47253",
|
||||
"0xf1235641dd0ac33ed19e39ee58e282f2e0dd8edc0949e0510f2c65469d85e1ef",
|
||||
"0xa55273939373f7a4052d8bc36501fe17d9b571fd170041ada7b4385d49ecb5e6",
|
||||
"0x79ba81c39c2e7dad9768cdbf754242dc2b5b74fde750c32ee153ab121a633406",
|
||||
"0x74ef128355bdc842c1b109d4b1d3dc6f85a21a110b32fe1b4ce71cd282a20ba5",
|
||||
"0xf0a05137693ab9dae7624cbf4abce1554d4921014cda61584d649c66e9eb09f0",
|
||||
"0x5566a8d7495aae3cb42e66bcc683bb194f53894e3281812484bf36da583b7d9a",
|
||||
"0xbe65f10ed3eb5e862850eb4e30c73172f5417634b087b1dece7df97dda2857c9",
|
||||
"0x5ad40161397a2d0f53d71284d878e711b6d73930d2a79a789e4bf08223e9eeb9",
|
||||
"0x1a88c4e12ba89abf67c8f8de223964e4f3d0ee8951b9a1851c9172b278b956e8",
|
||||
"0xc1bae22721de65936975b20b01380c7707cb603622106a166c1472bdcaaaf94b",
|
||||
"0x68106522840c17b0e93b0cacfdbb1d2c5b219cb90aa61a5d0b04a0291caa4b82",
|
||||
"0x0e8a214b18b92fc025bd374a8d9859244b3855a7d3a364d1a0e092546a17b2b0",
|
||||
"0x584294fe2fc330adfcbbaf251480f2c727da2d38ce54ffcc1b363adb9c0fdb0a",
|
||||
"0xb86b9042acd8d6dd4eaa967b3dce6e4e49cbad95f4a7cfea95299da0cb3aecab",
|
||||
"0x99d4f215dabbe6bcd894d4ce7ee6d16a4543c38d9ab19a4f3b933f37eaa7fa5f",
|
||||
"0xd078bfda23ecf966b656aabf0bb69d27902d33773b2471145268426846a5a1b8",
|
||||
"0x87234af13d71e681c987c38fcc3661889b406e298e3a1ffbd5115fe6fe6e65c8",
|
||||
"0xb9f78fdabc8cd4fbb08fd1e1d00ed552c4bc7cba0672ce91c52deb2834a7b223",
|
||||
"0x76704df0766b51c9327acf08ffd35fb9c3f041b73808094b0d4ae1f7e7d7d0b8",
|
||||
"0xb5e4ec16c993e2ade6e951099512deb2f8fd07956e4d97dfc639a7eeef96d336",
|
||||
"0xc9c919862f5a82a5381e7def2883049fbbb99f24be9902152323811e32db40bc",
|
||||
"0x8df21edd784b8b776ffd603a6da87a6602e6424cb3905d977b909a7b10160abe",
|
||||
"0xd5c524bf24c3c8f2e9cccd5aff20b96fbb8f2045f37ef1014eeea1b82787361f",
|
||||
"0xb64756c799db5e1eca16416cb833605916a9bbbcb3c82a54def34f16e6fcfdaa",
|
||||
"0xfac273bab2facbfc28e2c53c03a44e69ddadfbf57b08499bb43855abae456f1c",
|
||||
"0x43f8990cdc4735bc47fd89cd23c9a99d5453885b1903d4b3185b6b0413735ff6",
|
||||
"0x7420a69d819df5f4106fc9e315e8c125c8876a3a1cae8ef7198a921c121792ec",
|
||||
"0x696861af19fa56f07d5e2eacffa3508cc3638b7acfe4789c002929dfdc47fc3a",
|
||||
"0x86c80d2150fca01803a41a900e66b764ce82af2e0ec19fde53971afbb6390ead",
|
||||
"0x9cf14af73b44b555ceec13119567723ae8e8af927a6f24846635ff5000acfec6",
|
||||
"0x95b50e682e4b6b2a08606a62bce427682ce484c2056d891dc206fae9e062d3f0",
|
||||
"0x789755e975f432a059cb5cbeb067c8f9dfd97b54d8d1a45a1e47592d9eb770d6",
|
||||
"0x87b682b780890ad3d542c76548d7d5287fb244291d62619ed079340293a245d6",
|
||||
"0x8c0155b066048d9e95f5eb1b6ecfcc179feb71ee0426301b03f778573eeee7a7",
|
||||
"0x0fe45f09ef25d05e5c42751a35714af86a5d7a4fa235956edaa36dd0e5ea7533",
|
||||
"0x3b5ee72615fcc04f48cec067ba2d1d9bc0e64c4cdf9d5bcf97c1a999ae940245",
|
||||
"0xcf773973676c9b0e31a549d78a6bbc79826c471b6fed42078d9b35a08d1d28a0",
|
||||
"0xd5ecadc4dba308c0d790adea1e118d6984716600091d341276311631acfbb267",
|
||||
"0xf344c0cf6516f0fa6617e48076726aefbdaaf5a31f67ad8199bc3f6e426bf904",
|
||||
"0x3f3d2d33f36ba9009e9a72f3f5bbcb5df5392a19fc7afc8d37823aaf52b03477",
|
||||
"0x346a89411f090d559ff90e670bf0a385b1b09f117fc9ffa18b09d3b6d5d8e45c",
|
||||
"0x5bc5689e2b4572b8ceea472cc7827e22cbfd018920beebf5c5b25f65f5cd5357"
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
|
@ -19,7 +19,7 @@
|
||||
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
|
||||
]
|
||||
},
|
||||
"validateScoreTransition": 1000000,
|
||||
"validateScoreTransition": 4301764,
|
||||
"validateStepTransition": 1500000,
|
||||
"maximumUncleCountTransition": 5067000,
|
||||
"maximumUncleCount": 0
|
||||
@ -56,8 +56,8 @@
|
||||
"gasLimit": "0x5B8D80"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f9023ea070413bfe3ceb9160c7dee87bf060a0cc5e324f7c539cfce4e78802ff805063b6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e4a10650e5a6d6001c38ff8e64f97016a1645ca0f8ac12c30b4fd0d27a1a50c090659014574b554ba6e9cdb76f57efbcfbd390a9a0b474ac6cc4673c17c5f511a8b43cc44dbb01bb028735830163667d7a3a2582b9a0bcd44b7c04fa24760df7d733ca8ecd99e8da89de0716e6017fffa434bfd7519ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd83755801837a11f88301d8de845b27471c96d583010b038650617269747986312e32362e31826c698416c9d1c7b8418bc805f23fb01fdd498b37df5519f49691d65160fe6a6794b8106e2ecc4782407f0dae3a512546b7d93e89bbb2a761c750553deeea1f9401231f56ae0ccb059201",
|
||||
"totalDifficulty": "2566410291882451733317698215999610733750372193",
|
||||
"header": "f9023ea00861b3771ffb84fce48b8ba3c54a09f81e91ccb38c401261f06d370098889a43a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e6d2b931f55a3f1701c7389d592a7778897879a071cc81d58cdd21d1e17f7389e55c530cd9f94cc15bb32af6477320682327dcffa06090021a7c09ae5e75e443410ebdb76de04f1eafb0ab910daae96ee6eec560eaa032510bf257dd03b11f3b4761b94b495a5b5a18cd6eb17c77785e0f46e2ffc882b901000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd8381e001837a12008306697a845b83bd6096d583010b068650617269747986312e32372e30826c698416e0ef58b841117e2088e2835bf2afcd5d48f42b3bf2a1f33435f21f089ead2a6bae7d01c1486e645b460bb3c726a827ff1eb50e0579f3410563bae090fc256cf1d8d594b82100",
|
||||
"totalDifficulty": "2845866505151538604560067685603735513869853136",
|
||||
"CHTs": [
|
||||
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
|
||||
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
|
||||
@ -3813,7 +3813,408 @@
|
||||
"0x5d71aff2a12d4f1d05c7f760d07b417a39eb0eaa72a01333befc6a2eb6b7d72a",
|
||||
"0x8dd7de9195d2852aeb6812638ba22e73ff5ca0a8ad921c6e924cae1dd5952255",
|
||||
"0x8f1828b4cdc6c38c112b1ffee7790953112dd2225ec82581a5095e5ae4d71cae",
|
||||
"0xfeac88ae6c8529e87a55a259f475b7d162d01e8fa5f36c90d4665dd6105b1743"
|
||||
"0xfeac88ae6c8529e87a55a259f475b7d162d01e8fa5f36c90d4665dd6105b1743",
|
||||
"0x2e37011bd97c6e8a24e130fdc2c60c39b14ab3eb426a4f654bf3158a19aca88b",
|
||||
"0xdb59b565de21902c50e2e204374ae1ce487656eb74145c103a86707b45a63eaf",
|
||||
"0xf75c26a7214acf2d050ff5c7cc8b76e1a90540410b5c8b2bc9edbfe8fb2268e6",
|
||||
"0x6ca7554f2abfd22951bec80f9d280abb6f060dde4a9a829ff7a0457d67a99edd",
|
||||
"0x0324bceb8b61fa7092396764d7e1933697806c6d785446e3bbab3fc3be0ab259",
|
||||
"0xeb4880f177e3e673f8ee04be1451a38bd8a2c0bac681d82a19327ae2d9769d32",
|
||||
"0xec6a868cd9fba9e4f5b0d4276f44aee71056fbb7f425f717d0ce9d1fa5442ded",
|
||||
"0xdc12b36d165eae197487ec930e35489545d2867b6fb9f8604d279337b6a8f949",
|
||||
"0xcf1241b1c9b054df34638e99447bb0359aa01ad13c38650b872f2d727e6f68f6",
|
||||
"0x713765e9b76c73c2de58c480600a7125972246fdcce2324993cd6bbe49cce67f",
|
||||
"0x81e096e97dd8bf1d206d0ed41c9feaad24d344323ff74707112ee8fac218994e",
|
||||
"0x8943c2246d5ae3e8db5fc012e9613642c6b713e5f2a89d00f09fa73246f88d5f",
|
||||
"0x5b2d0bcbd893fab4e58d4ef698d1e8d3001799b61e758b7711f319e2b8eaa645",
|
||||
"0xf3e4da2cf4579f52b7e4d632d93b79714487ef179a8f5d5c46af9154efad20fd",
|
||||
"0xa2348ea2cd7a5a32779e9d292a9428fa475fae790f08e42f7699ef5eb2489188",
|
||||
"0x62dd923966e02db7d0d27cfdd4aeac081f9827288c8b54d9f19035331a109f53",
|
||||
"0xaa1aafa8f9d9d3e0668eff761fbfc2657d1e1906c077d93200ec000643c6c272",
|
||||
"0xbf40cb21561989004434d6d908451d5b63045c89c2ac9b1eb617ec0054dc18be",
|
||||
"0xdae53edbb07fe84623451da0e25da631ad3465e5bc12ef8fd8323c8a72f57130",
|
||||
"0x685115b38f307f984c7c90e85d167d62b0ec2c924a0bca5f23b1cac12a8f72fa",
|
||||
"0x2ad7e8f86c872504d7c2c48b0db141955d770acc84222fd725ffbd2dc4095b1d",
|
||||
"0x9268b3b175aa6025b959b8fcdb416c39dd339e6f1fde3c427bd1bada36e4384c",
|
||||
"0x502ee814cecc8454abb95591b0d07ed5170db94af7fda8878b9b4287fd68c9f8",
|
||||
"0x6b19baf6b7eae36c0b1d2754645ff282fc2905802ca6394ac00bc22eb1582eb9",
|
||||
"0xecad17ae39f897ab38850cac40480b4fafcafd6624f8fdfcaa69849f3fa101ec",
|
||||
"0xb0804719b391b4b5f554a49f99df3a9d1c3a9884cefc268dcb27e3821aebe385",
|
||||
"0x3018401c9a31f97881852c1bd65a964bfd3011659725c849a8de4b5ad8f26490",
|
||||
"0x48a6b687e62a42dc44ecb56f4187e293d6f87d328b1edf409c8f2fa6568dfddc",
|
||||
"0x8e3bc1ec926a68e22ed525485186a4d9160a54bd3e80107bb77c09911564effa",
|
||||
"0xd7a7cce632e1746120476a3271ea09689380eb833d5538310fa0029f9174e0de",
|
||||
"0x7bae074c51f3b547568d18e85b73fcb9b5f8040ed5f96f3523f53197150517a4",
|
||||
"0x9ba39f376b9444dab04e0a52e4728ec842a0aa4880d9aa9819de3f0694f46e60",
|
||||
"0x40a2b84bd3d05d28d51a39deae5f23b4f7370c70ac70d1cc81224eac4939d69f",
|
||||
"0x2b9f57c8c43284ba929df8f896a966afbdd341f145b6b2b2fa98382950ad915d",
|
||||
"0xcaf3d2a336cf17c9b2d7116a14e654bcece012b07bc020ac30feb71d7f6cead1",
|
||||
"0xd3b68cf2337ca26a9c4bf6b6b286dc65bf66641d5e9c241f4c1b147994253ac5",
|
||||
"0xefc11a5944a8061c87f274515e810fee13f4c350c625a988c27ed276b6c55b6d",
|
||||
"0x7a93732151f7145059424aa823b24e26341cfa57f612e6de3bddbe23562ae918",
|
||||
"0x2594b625d0f5ed52425ccda4e7898a8a554300791027af6f3a19239a15868ea8",
|
||||
"0x1db00091145b1b0830983b5eaa5cd3d0e4ad71c09d1b2dc20c47815bc2de5917",
|
||||
"0x60563bce11f028691cf78da7326f22a4ab01d980020e61bcf2e4bdb5912b7b1d",
|
||||
"0xe6515bdf1f22469a4218f54791d12698d1bc555b3e54b04cf46b10effa8ce74c",
|
||||
"0x990831a56958a6bf131697e2f35ab2a45fa228eb7435c7e65814ba28778d513f",
|
||||
"0x1b6e4085f0e291a8ee4d7e90158dcf15702b4e6e634d1d3bb5c4bab11bf70068",
|
||||
"0xd0d4a6061bcab0f8e645ea16b285eee7f2ff84c7765d7543aa318edbced2408d",
|
||||
"0x2da1a609eb1b572a47f187dd5a1e9f4cb1e1885c841f91ca82137e01a9eb4288",
|
||||
"0x1293686df427f9ee1c2116000735642b3d09511cf2889dde21e1bee427d8c273",
|
||||
"0x8a990d66370eaab3a46d9e4fa9b7d0c621020cd3b897d9e5b3e5fea6a6979f3c",
|
||||
"0x10030534d5a06bce47d72998ad4c042f5e445a505920723d14b1d93a3a23af82",
|
||||
"0xf29a399e8879386e4c2bd8e873dc8aed612cfa8dfa9e5b56f9c51d4c4d1774ad",
|
||||
"0xb252062ccbb11c3181338d9912ed0d4dabcfa4d61860c211f2f702a641fe936e",
|
||||
"0x822c7abd11b80c862bd67d39e16a208c8462936ca86b5cd5dd20c51d35cbfbb1",
|
||||
"0x6b62aea651f1407f94906db704a364f70d827e0efba981a8515d1f515a46b266",
|
||||
"0xa57b7661c0471cbd7eb35becdf468622df8338a48a075b722ebc5550bbf6b9ae",
|
||||
"0xefc593d38afead5ee1fea5d8b41a52bd2a5b5a059774d0b951bb7eadaa41a46a",
|
||||
"0xa556e684c26e7fd6f902b82ecdf721fc292c35e0d2240c1f362c4861c366c4c6",
|
||||
"0xc9f274efc308d1e97ba9b59c92735d1ab2a72d033ed02a543dab301610e96e33",
|
||||
"0xd7b43559126f88c59392fc54e2b416d2a67014abce12ddf61764df989a897bd3",
|
||||
"0xc860842132de3d8c1d0ba2cdc0a7c2853ee568789f1190738862667e3539a958",
|
||||
"0x2f330354084635eb507cd54549ab89fecc41886d295b1d8c91efd8ca27fe4f7d",
|
||||
"0xda6edc97997b9cea1bc90662c6a8180fa03cef6189e09c86f36adb91400abe74",
|
||||
"0x0d2853b5a3f02ae9e4a1c5a0534a5329d2e877d4d77f60dddb36b84b4fdf7e2f",
|
||||
"0xf048b5acc9e9191ce0ab8c390bfe03d89cbed91db5b9e7c7452b01bf56bcf5ac",
|
||||
"0x30fb6f6093bf59794d37ddf850c315dd9491a4cf5df378b4468dca96acf78e77",
|
||||
"0xa04eeaa9d1d767c0f93553af3a259390a9576e8b6015ffa8f0e4fdf37f41f28e",
|
||||
"0x02411cd53ac55407e0d31520a8c3274a2f4d1fbb2541bb140f30f25843c76860",
|
||||
"0x65bc790d632d5fe2446c65325df875ba59af3c3aa7357bbbbf47c7e5f7663a7d",
|
||||
"0x5f364562fed351d932eff956c3ac489ea51ad2cb12a81bd8db4fe0b76e3cbb92",
|
||||
"0x104f7070d5da1aca5c8b20a96d36638e4b5f8be4e86be83f0aed7234fcece445",
|
||||
"0xb2fc7a73d8d859d531e51532928671ea59ae6538d4572fd5c2d76c70920aff7f",
|
||||
"0x7ebecf446825dd0010fbf47afce8b9c3b3901c839ec46269eb8744bd799699ca",
|
||||
"0xc64002b5a70f18b7c51ea3d3f5246fe8db16781e146d777aaa12f3b765d108e9",
|
||||
"0x9d136068c7002d2780abfefcaedc79424d3e89b17718ec369d9e64ab7b63a81f",
|
||||
"0x7b9819e62e92dcead89329bcb3f1a1d6bd10794d1a22d30c3d0369a264029543",
|
||||
"0x8a8c9e66f343d09d5b7897c491c851143ca4f337ddcb5c2b1462b150e22c6f47",
|
||||
"0x9d86faa1a5d355d6071e09c8cca50e2dd7e7dc117c2e4f6c0136a2789e84aa8b",
|
||||
"0x234e156c10a80422ca1aafd49d614e02b698a0d89a7080f87db5dd5169b419bf",
|
||||
"0xafbb572b8d9119ba8126fdd5a593663db3a3e6165a60f1f439902a6321a8d243",
|
||||
"0xcbfeb8af8c93b11eaddb05df2f2a8772da694f9cc16878d3154d0857f17274ae",
|
||||
"0x7253cf6bd2b4d158c2bd60acf5fda9dff6cbc6468ca9b549efcd824410d2e719",
|
||||
"0x67fa14af20fe738ec5c9414401149a1f198207969768a5b982454146ef720b85",
|
||||
"0x6c0ddef53c7d58839c3013f2accb72190b7dcc52fbe5d71f4a20f849dd72725f",
|
||||
"0x89e77c0dd9fcb4b4d4d10c25903ff5b905f5d64b6bed9a0736e9dc2035ade3eb",
|
||||
"0x42466344821fc29dcdb5fe7dcbda00b3779736ca90f87ca1802207f61633877b",
|
||||
"0x6e2303e8ed41e6d39488c57dff8d50c548a7079a26c3fb86d925c0aca5b8f67b",
|
||||
"0xb8a14969606442bd94048f2b2dc7b87662d801097537f51c8eb8f026c52f1fe9",
|
||||
"0xd7ee25e0bfd080d89c475942575fa055ce5ae268a6f01b916b399f6ff7e94a39",
|
||||
"0xaf5e7da13dc0ab08ba5185074657acaa2ce753a20a364f3a97d230c247bc8d1c",
|
||||
"0x92f9106bc9ccbb4e0b4c0d1b96c5bf347d856884eca91a0bcf29e896789fd9c2",
|
||||
"0x4bc12bfadacd6af0737646b813b1a4a9c005e97ef4b090bb74b7475b50c85dfe",
|
||||
"0x91e4ef72d0bdef33e2e2c8acbdd7926182568f559397bfc086b96979e7c4f53b",
|
||||
"0xb2f57e050021b238e0b47b0b46a641644645db5bbd987e8d957038655d1fa83a",
|
||||
"0xaf221401f4cfa3db7879237b40c68300060df9f65dbf68bb02694837eaa8af7a",
|
||||
"0x2dd280e98a0d6bc950b7f3f0bd11a9e74105d4d15463184a3f8c03d40f3193ef",
|
||||
"0x2538560e5b802a89a021685f994acbdb3181f25d0cae17160aedfc619ca2954b",
|
||||
"0x133cfa3f5d6a00f7392a6b0c6a97a9ba10ec50b24cfbbe6028995258cbaa065e",
|
||||
"0xc120807872f07adeb144905ff323ea79880389a2815f8441befbfa82835555b2",
|
||||
"0xa2c5c5a3cbf6db506dfc13285b07c24ca7e70d9e75d80fe711c3082ba119d77a",
|
||||
"0x837622b7bbb8bb18b3d42058426ef97e3fbc2842d2b64b339733b52313557562",
|
||||
"0x29eda2468556699747beef75f015e6772980056cf367b819d05a4822b7d54712",
|
||||
"0xc6ec29323368dc29a1d4c3c11e945ef7fdb56db78808c4c9688ab5f9eb7f27cd",
|
||||
"0x44b368ab63e1fe0e0da031a4e6628ed1a4fc69fa4083cc056dd9443400be3326",
|
||||
"0xf153dbc5fc03a89e80d2808ecd45e9fe6453d112508d32ffc6305d5a577d14d8",
|
||||
"0x32452c0d51df7a85eac3edec46bbfe376c971ac4df4512d7e050e6fa711373ca",
|
||||
"0x70cb25f3d60126cf0104a40b2a49b44ef8a42f60b93f929594938ac00647b639",
|
||||
"0xed63fb33d707b93e45e958d5d5f9d3f0898c3676e43eeca55c788cbb2df3170d",
|
||||
"0x93ff103a026350b0e9c2b30c36e079145892e8e3756678e8ae4b0065fb6a04ec",
|
||||
"0xa466cdf6063bfe155ed75c115484ce113227385eff2cdc07dd90405239842f3f",
|
||||
"0x2883c296d9ce6b1e6e7b4f471e841437603ecbb867570cbc46d86f0f26871600",
|
||||
"0xea5e5b84183a3a709a51c1c6f3e7b039c4663d7495b9bdcfbd4ecb0a95ea994c",
|
||||
"0xc0e97318bd3ee2957c09d6acedac77ce6b219608e5dd63ef512aa08d63c3a114",
|
||||
"0xd3ccc7fcd24076afdf6249f671de402b515a131913df2da17118be47b3720b33",
|
||||
"0x4f5be5a6edd66ec496207b33cefd00722f3167b9e6f2a44d9613c4c7d6541aba",
|
||||
"0xfecdd1844517d0523a7b45d7b51769728902b881b7fc308f486e850c870eef5b",
|
||||
"0x01a22dea1d0e25885e0a03e56489bcaf6747e712ceb5a42c74430fa6ffcc1c21",
|
||||
"0x06cc521a05ce856dc55041b90dc4bbafffee578c1c315b5cfa4cc2d1ccba891f",
|
||||
"0xac21d4b08fbf2891e0b3645b870695434fe703101f74e7fcf0d0e1304ce65b54",
|
||||
"0xd62584c47aa1d8554cc08cf675bed128e541df54900fbfae958877595ad168ff",
|
||||
"0xd8f1806ddaee8e729218fea1911efc5e663666ffb3acad4a2fda3757700d6d88",
|
||||
"0x9dab2acfe01506a185276145deeecdb5c8fe0937feacffd40fb25a83e8eecc72",
|
||||
"0xf0b74c6b1a441fc2ee8b2f25d2f03307164014d42a0784683a9d6cb7d2179064",
|
||||
"0x7d590f0bcc891e30996adf8583803a9dd1271442c3f0e69502addbd371437767",
|
||||
"0x3a66601fff95b0aa0d0660c12788ad56d2383cae290ceb2fb9ff41794abbc55a",
|
||||
"0x36e94b03402f18c689f5234973ce1e626a82aac085dbdd682b51cce21f8c1872",
|
||||
"0x00abd1d34c7e55f58681866558cb844c11faa55e8cac70ede75811f55341cfde",
|
||||
"0x9983fc20e63e77ec0680522035b03167403681674ec62293cd6b7fe360c69157",
|
||||
"0xe98b658fb8b6b7fba7463562f86348bf1e3534bc9148e8559423b3ee5ab68472",
|
||||
"0x77ea189d3a408a8c5b1792881d93ba7a471f90a976ed334cfbdf865ff94cf20f",
|
||||
"0xfbe2fb93b3ecb384679870205f2be2f47140f8d832f841ba8653e00d68056c82",
|
||||
"0x330f5f04314ae57097db5258d861b993cbdc2ca0522421917463b94636a99d1b",
|
||||
"0xa59cbefffd0e1cff04bd4004d21fbb64c4ca542b98220487ccc79a39a6a0fba8",
|
||||
"0xe08f21b0f5ab216c1009c904939515d0ef8d8ca80f8c3cd5465944bb6550e728",
|
||||
"0x37f1db42a7e99ea8b6d7f9ec5bfb39f9613cf79d98345816533b85726c64dab8",
|
||||
"0x8c226434c5115b7ac0f894d8c4389a1e38a3118fa0993b59a42291286b85bd7e",
|
||||
"0xa9977dc362eba9d32d13188dffa6cd0178e0b8c29cc24a3c04cd6cb0781fc133",
|
||||
"0x502a68fcd1c187d662ff6852179d7602b04b5ec3141ffb39841b571bbc6cce25",
|
||||
"0x09a716a32626ad3443d7f5f6e5fce5145e8b962a531464e36aae6356ae93b15f",
|
||||
"0x2c165daaf0e8a4433d8bf97091bb573f1a7cbc7e82f2af353af9c580fbffa8c6",
|
||||
"0xd8b47ed7ed3bb85bf44ac2b5e5916bbb282353f71dea6e172434f05cb1276c4b",
|
||||
"0x2bff102b5209c88370b2deaf941653c364a90b39a6c3402336b8b3c9b47731a9",
|
||||
"0xf6011e416be00e243d9b6b57df1bec2458d271b2a8a964292521f6f8bc7355de",
|
||||
"0x8f4a6d08359aa81c14391d8483bb8e621c24bac1e32b2c5c505d5617487bd06d",
|
||||
"0xd2f89aa90547e1956491879dd5924a50142d76460532f00423cfe70f36546873",
|
||||
"0x929b13fbde5275f999f145a273219d6f7f4c25ac29b4eab3f89d68305e7f4341",
|
||||
"0x1e7e79d55594c3555eb7d90e4b5bcc8b59ecd98848884b81ac5c2d53bebd5cbb",
|
||||
"0x11c2705c4a89fa9187f63dfc7a8bd4e2c087d6e937e777393f1e2856f6f00104",
|
||||
"0x294b40af144ac5046bd2a5451d1cc9900858e0e351f3f78b50b2dbc203111600",
|
||||
"0x26432c2ba81f919c085a4d2326c22bac341c17f456d8a93a1971c0fd741ea79a",
|
||||
"0xc488baa35e04ed6bf20753fcf856f31a98c00be65d51b73c6a5490d18fb89d71",
|
||||
"0x915e1768627ebbee21159a0562d8a5df69b05f057fdc8b4bb69bcadaeadf2ae6",
|
||||
"0x2303b2be6801e3fe8c02c0d0355069240da4f617b47a4ce6bbfaaae56a1e0915",
|
||||
"0x0e4af9d5e2cab6a62d9203979db08996bd1f111a315049859e2093e83e465262",
|
||||
"0xe54756890992736382616fceb3999d22ae462b9b5f8b1da072277da2df6b5f4b",
|
||||
"0xb5aa407d54e2ea651563333d3d330af0cf45a992bf89db0c229962454c4da4cf",
|
||||
"0x88832a6db2c8c3d899dc59154ca323c08c5eaa8c05d142978490246e7b4ba7ad",
|
||||
"0xdca9619220c991618eca5cb18b1c14c6fe4167614a8360c9e1737c93a129e714",
|
||||
"0x3fad9a66462792be9f771b39b6f64e537683a74441b85b53f9c5e6a2fb687100",
|
||||
"0x6dc5466ae00317d52511d9e153ffa37cb6060639a010c8db25b33aed702b486e",
|
||||
"0x2a2ca3148598d3106bae23b6f66a24e3e93afeb576d283ba6822220780008e95",
|
||||
"0x480f699ec76a16530e382c2e8d91c7edd3ec0d393ccdeb28c7d692eb52b0af96",
|
||||
"0x082d3f5dcff2a41e2fad715d64eef361271648bd976d895b40765089c544b65e",
|
||||
"0xed14dc5ed74dfdda8b45dfcfe99e8581767cac57505805a4945b79e2110bf92c",
|
||||
"0x6890d1a6c90f5c1020ea4439957ea54df3cc22f14e22047f63c9a93696210b95",
|
||||
"0x55ae4e30fc02206a0f389e03c0ef5b1409f8fe34d6a5dbd5487af608e3b82369",
|
||||
"0xa709e308a7899591337d59ea459098364c1d6638202047583851acc5e6df5017",
|
||||
"0xaed8371c95bccbe53effffee29f40a3e9656bc95cceefa364f7191415dbe15bd",
|
||||
"0xa7450bb8e1ff3c7b53bada0cb8ae783e561a3ef74cd3be0d19cb9ac5ae807aea",
|
||||
"0x9fdebd0ae46437e3421d7f0a95a76f47b34f0e0eda37d69c078ef5b44411c027",
|
||||
"0xa18a165a98307fb994401171c41e375a4637fcf2beeaec8c18fd24304b068570",
|
||||
"0x930f3cd1edb90c020c19a6f6a8b86c86981c3ebb8fc19073f09c345fa4b0ea6e",
|
||||
"0xe4c0549658dbbf4f541c60606c8b85dba190f58e5af0bcfbed101e0ff4a8f455",
|
||||
"0xcfd5428494534819ee14e002c69987fc54207917e83a2b6e97a1e1b801a5d939",
|
||||
"0x0cc3a6a2a5de66f64f5491908b5585eb3464fda42c7a58a9100a8cd0ce763b04",
|
||||
"0xcf635d0b4522c64a9b00902770ae33b618580983bb32b94134a69ca8f6c6258f",
|
||||
"0x2cf5c41cf911dff328ef15253a7419733a104cf9cd1846af43d5fdcd914b321c",
|
||||
"0x6d4ea125dbf83b8a9dcba40c4a81673a365ce81dd8eb1fc10510ee7e80a40b1f",
|
||||
"0x9c68f243fdf1738f9218c30664318278afa8f461c13bf5e1bf30133d3fa6347e",
|
||||
"0x62aa880648363c1f3b5bbba3e73dc58566870ddbde0911c5e11aca003a13b525",
|
||||
"0x286a2b6f2e35c2a6900a02d37d82263dc55a3c40d6c40488258af61f8cb8b589",
|
||||
"0x296136ec9fba18ad43a5435acbc3006e52a182aea1e3eb005f25ceaafde2d0de",
|
||||
"0x9ebd2127fa6f5f43a03fcad8dea37bde3893f627b48e63b9e2c6e33af811a95a",
|
||||
"0xe8e58e2b6fe45ba1881eef4ec1e1d954e12793ee68060d50b9c9502009725317",
|
||||
"0xf831613def863279307f637be60e9608179e9a148557585034d20816ed7d5553",
|
||||
"0x9ac311437bfcaa1c66e1c32fa18f8964ca9d9ffe3cb3be306b64519b35051e48",
|
||||
"0x931a4862f94054ec0f96037a225f1c3421ef99d8e4a8f774407cf913273bf4ec",
|
||||
"0x07dead0442ebccefbadb2859e0f462fe8d3e6677c7fd04b0f35165ceb017c171",
|
||||
"0xc4afb80e1dcb56ab83d5b20475d2212b6c55ab63fee058a914661657d2b1187e",
|
||||
"0xe198b8ed96c1b7dcefab5197036f1e5789ea6622dcca2d817e63537b00710b6f",
|
||||
"0x728b8b91918a059e3f46ec7658bc5948016f76ec200d91ec3a163bad8ad6bfd6",
|
||||
"0xacdebce23301e49e068c83a73ad8484d8af7a0c28d066e62787542e154b42559",
|
||||
"0x7f66807da0c2b155126b1d3a69488b10de7f0ca38f6cfe6fa670dce511a1f667",
|
||||
"0xabf510ce1a016b5b3d4610b3cc5c9dec43a6a66f3555a70e1c16cd451e8894c6",
|
||||
"0x56ee11eb3233fefdc056827fccbea1ff2be8a3f460038eef68a1c730bc1104cf",
|
||||
"0xbc4df43d4acd0fc2cea064abc5b5d1754b29073533652448d44c09adc1d32998",
|
||||
"0xf61b97d2d1e537a6d20438f4729bb59ffc8db6b7375c6e710b4be9e136f1e19d",
|
||||
"0xf89f04d5cde25522103d1e175d68dfb4955b4519a5c2cda1a041298579174be1",
|
||||
"0x702c60e25d6a10ac9657553e376f2385cc94737ee292a3ae671ec02af982ad84",
|
||||
"0x5194589410d5f02de764bba1c25da027861793270c956c56e67e017d89323799",
|
||||
"0xc448a3b8bb1b6efed04d84f82d63aa0c7ca19d3cbf817efe4db82b897ad6a019",
|
||||
"0xdee875d8c517db5cf20b745be7ea1d389612e47880657d003c6bfcfdbc8a6303",
|
||||
"0x0528ce8bc52f4878268be5e00b5028c9af85cf61a6279e75240e2adf7b498ac2",
|
||||
"0x6cc80f5c62a1510d9cc97ca8b4c6245938ddbefce782635dde0ca2516932fa21",
|
||||
"0x184f9e305ce4fa0bdb47ad00bc7d10691bfbd7cb13b9c9d4d82c37678e8df080",
|
||||
"0x69456f4aae64f57b3709d6c6701a1894802a4db96374da6b979b87aeaa5e301e",
|
||||
"0x60d1bd0acd9013472acc0b8ce0b90a088f35d5c19645146ed8b3c6330ec92052",
|
||||
"0x09f87c83c6be698b2eff45ffbeef79254e5ff8d3534831c79346e5b837110c1d",
|
||||
"0xc5fc2dab2c43c27132f31a915423a6d6a30a560e4aa266483ef2ef1ac48d0fba",
|
||||
"0x87a147b03150b429b0c86569db27ecde32c1bb9a48b1ea4426d8dfb895339673",
|
||||
"0x1a68fd5e6efa8e5183843fad88d6445fe8b07c01b884f30563ce527e6b10749d",
|
||||
"0x4123e02f2c2869bfd99f3138aac82bcf1923260ac28f33bc4ff2dfcd54c48e4b",
|
||||
"0x452345c2de5fb18422b4327a79053cfff33f277f0e3fc69bf2073d0bda4dfb74",
|
||||
"0x830eb26c402a88c6281b0a48a93ab16a64a8e4244f87d589b471a3ceb4577f6a",
|
||||
"0x84445f1f8805d911009a3e55ebda5e12ff347e5a34d0028ca44a2a26846ba903",
|
||||
"0xf91a600ecc8aa47f838a8d877487c15babc10ff97a5be8bbe4c3eb705fb04dc5",
|
||||
"0x01e749439d413c66340934dce9d4c55179375208069fefbf89aef7c3c7f02bb8",
|
||||
"0xacfb6917a7365046ccbad1ca8fdaccf8164c216ba8d96cf64af5340ee3aec2c7",
|
||||
"0xa1c20a4bb21a0a99f3a38818c05a3ba66e8321f24dcc7ab26487810be8211dbc",
|
||||
"0x7c88ea06f3c8cab9ac0b29376f53fff4b56672a1704520fbe8de0e3ca0bf8acc",
|
||||
"0xc19e59ef2361963b94bb211b8f6c172670ed83fce3d54b3e00d1a82f292d1d2f",
|
||||
"0x386ebf9ab1a551ddaf599d9384e70a34a961ec55d5f609c088c6fdbf38add80f",
|
||||
"0x8a635842c7d38cb2bae11ebe3f6ec09e2d41ef6b7093e4ea8cbf079df97f06e8",
|
||||
"0x2d12afbf38c0378d287693cc7fd49f3e068d454ac5ea7bc76f6b3e505bb09f27",
|
||||
"0x33b7eb72362caff0e54cd853549bc4a802345d774856558a8b128e494ec63948",
|
||||
"0x31eef3a0c2c9f586ad2305d8ed9831619ad6ce2aee9a16800cf4aa048b1d593d",
|
||||
"0xfbeb707dd62204a0f3a06ef9046fba5b3b88fff3a38b5b08cc3213f5965c69c8",
|
||||
"0xc8913325245c39d0609c6af407354e9d309c5d582c8957a90c86c944d2f5c6aa",
|
||||
"0xbedd0ccdb57b01e688c14d6230aa84f5912cf13a72839f654eede63ca05ff52e",
|
||||
"0x0b0b7435e02cbc3654eabd042c32409f4e178cb60f5e306ba041c985378cc286",
|
||||
"0x749b3fade2cbe924b3d76f2b9e216c1675e8687bf7ede81b090ea36a4468871a",
|
||||
"0x9a59125cd56262bf0b6d2393be4ba8f769b9d5a53b644a0700c9905dc4d91c14",
|
||||
"0xdd2001f6cbcaf2d29a7d022e6f723e4691390f56ed6a599cb58bee74c64c67a7",
|
||||
"0x05870eb07cf5d1c1013fedd8cbab73b7341e930a0c02e2dfe898d5299981e34d",
|
||||
"0xef78e2f60d74c818cbf8996913c08a7c5abedb3f0f7ca412737c071cd6a38ccc",
|
||||
"0x636a6d39d02bc22c139d9e203b1ae8b2dc485cb596641ba6e05929296e87ffc4",
|
||||
"0x8cd6e1340deed5cf75bb30c3183807b653c7ccca712f379d5f885ef1a4100945",
|
||||
"0x549d904ec260af5776c241a80c2075e31869b8da7026a078fe158c0b0d646b11",
|
||||
"0xc73927c3be804cdab32e543e78f38f8e0899d7f0418e0b37af336c2bb37269cd",
|
||||
"0x62a4d4dc610995d0f08756056ac199c3f0959674eee8d4503067b822e37bd1a5",
|
||||
"0x4b4a3cb0ac65532d63592978b1afe838cceb7cac04d30a58cd4d73af4b99d2de",
|
||||
"0x2c5aa96bb3b58a76b4acefd0275f9f7f82418501ac2c2052e0a5f43eaa4eed64",
|
||||
"0xd6b8f1a8e502a93e14a8177bd750fb7e7974b7527f50bee37690b523dbeb077e",
|
||||
"0xaf38bbf2941d5ac311f8ab4cec22642049473bb3a8493ecc27cce73dad188797",
|
||||
"0x778b83f79934655d67e52a38c09410e5b5cc28b26f4f70b84d2bdff5519bcc74",
|
||||
"0xcc016a4cf3d1f7119704551809e89c1b4f95d1dfc4cb7f95db2c5d2a6ff1036a",
|
||||
"0x6b904799fc1df35a787bd7b1ce4337697bad98b25b2bbf264a7bc68d452df41c",
|
||||
"0x915536046dad19310976f8d158795e4237bec7fd5c2d2fc8ab1fd6a3b5b75e43",
|
||||
"0xc84167f477d317ed1e6b1452cd746d43ed679f4ff2eae84b1676ae99d3bb0fca",
|
||||
"0x71758a9fb0e66a7a04a076569cd3bb41d5b91cd1cc26b21a773e67524af84e63",
|
||||
"0x54f60d40ea84652f938d2856533d82a7c0b91091a0ad009f48e599a917b52bb1",
|
||||
"0x618cec420aeabdbdedb8afba71b0d0408da5095ea3231455b6c817f9a585d437",
|
||||
"0x57cf387db60cc35262bfa939b0272af7c490720e496b5f8cbbed6b4b26397824",
|
||||
"0x7c8973551ad57c278a0d8702cfed004dac293e2b9464debdc48fa88be033ba5c",
|
||||
"0xc80eed1b2bf137a5574d40252d4d02d0e3f87618c79b764407d8009a2b4932e2",
|
||||
"0x09ab540be725d669810c498557b61a53b343104c5303cccaeb31e518782d64d0",
|
||||
"0xc996eeca57ce9a7ed79f6db45ecefe1710abc4b3e21dec8f707eb5f7632c9c43",
|
||||
"0x160af8ed3f5f55bfe0a9129da94ed002277580b297e29cbe23a962c41eed1cf4",
|
||||
"0xb8935e0d55dad821ba5605607cd6a025d6ff76ac3d9d855fbdb3d000ef864dec",
|
||||
"0x10f6dcd55318225d362a40859030fed3199ae015791ccf4c4bb343e7cb97822f",
|
||||
"0x6f3a76c93761f73bd148c57f2bd00670c20bbd19338b7fddbbca65e598b70ab5",
|
||||
"0x6e99e5531942dde6d881eac1f03c6fd2ba6f9d79b6f88408eca815d84ff48157",
|
||||
"0xb05ebff5d64b736d36b372da80fe28d6e76b64c74e1ca94f1a859936c7ecfe7b",
|
||||
"0x815a140ac8538595dd724ab2c31e13d30c03ed3b64d2cbc72871fe402c7c88b8",
|
||||
"0xf4376c81472e0b3995618f7845887159eec1e929b8a485c2693219f4d5ade069",
|
||||
"0x30ff47cd807666e5ac48659bbfdcf8883fc1c9ea4e9be8b397dbc969a82f8d95",
|
||||
"0x74e35254636ae2f72005ec69e62273e9cb7387fbd4234aa58184e11725e2f569",
|
||||
"0xb4f3de4e9a22e787077a53017e72bcc8ec26a1499c98305dabb61ce6582cbb09",
|
||||
"0x3a05acc943f2b7d0c93cb4c5fcbbfa3ab9e536a2cda7f1c325fe3748401b4f71",
|
||||
"0xd75d428c14fcc7ceb929328989235a5fc46f8ed3e0136d81dfc15866756455a1",
|
||||
"0x20833cf410b3a0626a6c7e07d5fe09bee17b218416725ec3fac716597e1f6576",
|
||||
"0xed31b1b593289be968e483888fc80e5c360beb66626702f388a0848bf104687a",
|
||||
"0xf55fdb35314f9b873a70bb207536eb2e22958ff9264f1e088b0dd82bb9358b2a",
|
||||
"0x701d2b5d8794e244d85366d13fa0382827ccbcf557ae2735bc3f88bcb5c778d9",
|
||||
"0x0492794944f7d179da85f68eec5ce4575a90b7a6f161ae199373ac4685c6c665",
|
||||
"0xb1fb246d93a6ca7a0ce6518a4d0cbaab074bf2ada05fad7a6d199cb830bebf8f",
|
||||
"0x77172f0acbcf0eb3ffc2e314b548210fc74c10826162b2d63195cb984d606623",
|
||||
"0xc9f684762b2378428ebf3dc8e207fe8d2b33c5a0ae1510ef44e2dda7e5979faa",
|
||||
"0xeb864bdea464cbc95b1e3a4be62231f91d1230179b7bf61f755abf5f05cbc9a3",
|
||||
"0x10fb3751407e792cd70fced2271f125d438d9cf3843d9ac6f89681616d0cb1ad",
|
||||
"0x79f96b934d4b22eb9315230c113fcfe0ee2828133e10b14cf2e9b3a8007dd7ec",
|
||||
"0xf8c0546c0c5eb3d9ee16295c5e0fb510a0ff3f55cb654313db2d8ec6195ee996",
|
||||
"0xcdc41342d4045064634291c9bbce68efd7227bc2832b372502fd4907f1957ca3",
|
||||
"0x7c09a67309e6a0993fe1cabb7528e5cab4ba6a79042b22b3a6cbb10778cdecc3",
|
||||
"0x7d5c881d1a199b82608d7e27456788164041cb1e5ece5e3b813db550cb402203",
|
||||
"0x4f7238409440404425f9f60c034696e4713bab4f4e507b76bdb2697d1117ad70",
|
||||
"0x8e8642cc65aae464b068178c4c2276dc8860b63cdd8f3447ba07a0e7a9b20c71",
|
||||
"0x59fd79b1b77ddb040cb6bd45f10ec5ebbc7ba421e14dd79755e568774010041f",
|
||||
"0xc8bfd004b479e0ac8e2e798045343198909a6f5657625028bd28af69de58d9d0",
|
||||
"0xb550f5483d01e8d32258708d82d463f28658d5155a15da214bb2c748e27365e6",
|
||||
"0xeb7de7083d7c73f3f443e6d009e97783ecefd77157b830cab2ae7d41a91b0b0c",
|
||||
"0x6f3145fafbfa23c5667b646b3b5fe12b0fb08e45f09e62e9254efed6ed812880",
|
||||
"0x66cbab429d401739e655ee55de9dc3ee6223230e38daadb1fee88da03c46197e",
|
||||
"0x410eb1081b98fc38f2447bcd358a0996bb9660f949b4d9d6a6596aa41de59557",
|
||||
"0x2fb84f43e9750be8f37cd293742776ec76d95170689710254d7847369626d6c8",
|
||||
"0xf1d6c7c8a81aeb7611531452bc46b69db1b56a31c1c835ec5b497b6f4aad2b8e",
|
||||
"0x1449b942575209a4bfcac57d594cba694bf494e98e154142d5423deb193ad2dc",
|
||||
"0xa14bbe0f97892409b86989212bf815a5024769707bb8fea7479417402a346f05",
|
||||
"0x1ebaf8a3c224720c6cb4079b8e355411f0181318dff7766faa204d4292e6593f",
|
||||
"0x70169dab4258b561057c427b3d31de403d87302180db843d3ac6fcece4a8bff6",
|
||||
"0xeafa1e0854e1d0dedffc92fe173f2333d3a0581199fd3c63ea69356206329d65",
|
||||
"0x54de1a943017c40959dbfc25e318b0055b0e041cb170b0f34e1fe76f41bf2f15",
|
||||
"0xb4ce2d897abe390b9b53be9809fbc1dce8d23c2d726dfa1d0e1419d8caf2c6a5",
|
||||
"0xca872995f8268bb0855fc685e69d590defd10fc6befb61a57ae75255ef92cc23",
|
||||
"0x3e3606562cdf9f8460c18efeca2d7f3649ac96fcd81d2bbd501e73a01c729f27",
|
||||
"0xec09b7014e049e25e0749f0a0899a2893605003f128bca3bfbe92a00c9dbbda8",
|
||||
"0x9421e443b91c741c80138137362f7b30dd9a0db6a815a3b4a799ec12ba6de4c4",
|
||||
"0x78c95ab7995ca6058f64f7fc4af9575923bfa70a092ad2268f0b2a3a20dcc247",
|
||||
"0x386b36edeea33668de333683b1ec3d9c665f150aa96cf78be27fdfd8f185479e",
|
||||
"0xc732d05a6122e07f7566a2a751adf5da1cd1ee23dc0b34c0cfe7cc12f0970c5f",
|
||||
"0x283d97620ed18ac85ab1d2c613d64df485b6efa26aa6efa71f840240a95cc240",
|
||||
"0xce779d27aacf6e512f5b52f96507325568f754b31db766cb4aede53c9e1845af",
|
||||
"0x50bbb90f2a3cf4c479be3e118936246db591f98e37caef06fbee553502b4c364",
|
||||
"0xcdf95c14c577f913331709c5d044fa536a4afbc06cd8d60ea7b5d9ac463e86e1",
|
||||
"0x3a7d03a8ed71d0ef15ed70677ece7a2ea32ad1e96ea5c3266a1d9f580efa862e",
|
||||
"0xda132c0fa137c542b06170fe085b483afdbc97c63b4546079262ed0fe1125c1b",
|
||||
"0xe4cc4056951325ee41cbb70fb823eccad0f266e032e839a2e3a8e851f0a6c73a",
|
||||
"0xc301415694835a5bf36e226ffa42d2fa8069dba6be6becbc2a7a6653c295e8a4",
|
||||
"0x1856c6fbe4494ba46fb87deed5c10e361a83ee73bfbc8f1b604c6fc0301f62db",
|
||||
"0x1b822bd73acd2fed2f8daf6936ddc8175507f373e701217b645cd6cb2ef2019f",
|
||||
"0xdaec59b4c520d6b5be4d82b1b1338a5dd55c9df443d697fbab750c337f6986d3",
|
||||
"0xce6ff73593693f7cda1159724457a2aebf0ca608105a5926fc98afe5010349b1",
|
||||
"0x53c50cc4da6192ddfa851aa104f92c865ce212a87500098d18100394140ad6ce",
|
||||
"0xf015a6887a543a0849a128cec761f10f7d94f7be083f739c767c727aa9ed95d1",
|
||||
"0xa54bdb8a7ce7327aee991715a7d673d403f2248574bbc0ae5aeb9a32b3d9528d",
|
||||
"0x47d46b4777a303430fa4e45305b31a113acb4aeebf205ca215447f9d27ea401b",
|
||||
"0x7a9504b64ca570814194b95acb8400357667122b5b1fa4cef386b35e28de2c61",
|
||||
"0xa63e5964474672c45b8b021b7cc408e30364c163c800fc302f342f119689e022",
|
||||
"0x988eaa51716d4cb523fdd5fed04dcc195c5fe00a8e4b6135fe70b6f09520bdb0",
|
||||
"0xfb8a8f98809114b3d433875844e5fe90cf0321b772aaf86863f96e8013b8de7c",
|
||||
"0xc893ef50496aa272414f6a06af7d53281fbc7265a3e389a42c7c49d32d24fc46",
|
||||
"0x4956f7747cb6489eeeb92b1c759f54d534397074c9cd017b2f5181187248449f",
|
||||
"0x4b48dfaa0b7984d4eea56cc40c5130936f98752e1c2d02762b5caab600c39691",
|
||||
"0x23df05dd92b7e6c024c02fef9cc6aef2ceea2d0a4827de1f87bc7eb4f8c8907c",
|
||||
"0x47ba2e8a2e5d4fd0bb04be0d76a2d553d4bbfc574d1b5c715393fea03672f4dd",
|
||||
"0xa8553d8cc2aa6cfa89c96564022be9e89aa5a6b0b98d88fb7976583cb2b4d2ef",
|
||||
"0xaa3e7684a3a9daeb343a10566c21ed1fccb46f4ac4b80efaa8725127468b7072",
|
||||
"0x55acb0e629a6b654ba723f330770a4238cee9aa9b98fc4536a7c8bcf6050b9e0",
|
||||
"0xcf2cc1a66e1d9e2fcd8709c6e695bef0ea95e4d14523d34a544adacaef0bf786",
|
||||
"0x6d955c9a59acd3c90593b8eb22dcd614a89ec947d554a0fc8323e817cea7b332",
|
||||
"0xe29b3ce7a0e8325135a33a1127d1db2f17637090712a0b440bcc3a3bd6301186",
|
||||
"0x47187e16fd16d67eb94e48e2f35eb520191ce412b95c1d18443487887700c516",
|
||||
"0xe2ea962ec229af7a26687783a7ba8f65490d9aed8f34bdf7aeb978c901f67c1f",
|
||||
"0xcbbc65451fd646ce67f78593806e3b66379d1a3aed301e6e67df9e3ecfd3cdea",
|
||||
"0xedc8308273c7ec9b50c8c328c62cda10e4e8505e3f67d134d0961d0fda239747",
|
||||
"0x57d5dda883a2dc7ef9b36453edcf481d97c06113d7a060131dd39133ded06e6a",
|
||||
"0x9392ffa1001ca3a85455471b660ee9d89c8d6d421fb4b00d7ef1eaef22747009",
|
||||
"0x0751d3a58d8bfce5febe6980c821c92f9bf5beb8685358375640f751fc5c8369",
|
||||
"0x6ad5fcb53f602b55dc728c7850f628ed5c500b65c6b0d22c077fc4df980d9306",
|
||||
"0xb9f2d92291fede8a3def3f527a8449f6e330d587df1ec3daedc1f42cdcbd6af2",
|
||||
"0x85eef96182742e4090221c1ac4433c106467e48f8c46ead864e6150d7d50946d",
|
||||
"0x6e800d685f7f68839978c124f300aedb6c34dd7ccd7b2dcd3144223d0e3db527",
|
||||
"0x9395edff6ff47843cda1e5cee061f449dcb7b5a0ca07daf9788079aa7c5b2ca3",
|
||||
"0xa2995f2cd9a79024f92ecfaac2cbb17a9325b3f54480bf2ae5f3d171132780f6",
|
||||
"0xef907147aaa023015d9b8f3e7414dd4b84e551af0d9f19fb918ad5f632096657",
|
||||
"0xa44d76467ee5fd7acc90c13bb12740b3fa8a0096ad0be0e3619841e67323c5ba",
|
||||
"0xaa574a790a0a50cdac6be3819be64c67427f5a891a0029333da60a01680d83f3",
|
||||
"0x531d9c8a5d68299fd55cfe498922d54af8b119500f7e6bc0c1b66b45234dab1d",
|
||||
"0x45cc89de803b6eea973d45c26b4b4287d322dae61163ecebdd3db92f8a40be52",
|
||||
"0xb305c50ca54418553d0a08c2a01908f3d413ee3eafb55eeb4cfe32aaad32597c",
|
||||
"0x5767e979f2322c81537baf5d300d24e736373eb399c0e7ae989fc0f177c40bcd",
|
||||
"0xe3646fedcf2aa89d6ab6a6a225cbfcf539317e4c59be2655b46f0d89142d9b18",
|
||||
"0x9edc1e15d3b2e5eb5f0b60f15e3b39b0be95ddf0bb6e4d18f4c52322b66c7867",
|
||||
"0x5bf071715890e9f227fc66c705e782add56e39eadd30dc982066fc067ac64fcd",
|
||||
"0xddb572bdf8c2ff6ce8a0d9b6b2c95cbb33dfa9b96bde4b74812ac016a93770e2",
|
||||
"0xf0687ab1fb94e49d1e113b1fb0127548d60ca1dcf341a1952d16dec090aa2736",
|
||||
"0x94308074a4ed0dda1ebaf569b6cd5b4b6f7e77bbc41c737c78462a1ab330e3c1",
|
||||
"0xa7141bddbfa78144aae11810acf034e48bffc3368c862d4f750112899150936d",
|
||||
"0x1560476607eb8c091ffbc0ec21cb3091c3385f9c83f8d27c4a301ac200a92820",
|
||||
"0x8c0b77737383dde0abf21d1350f0d2c285344720c314c564717ffa034acb1739",
|
||||
"0x2782b37efd53e9a34ed2742be32de2480de342a384d81bdf3359d3686a3b504f",
|
||||
"0x6e9848f3a434e019bc209a02ec769dc63e084b9c0f00472c218589dd3c256017",
|
||||
"0x721d8f1bc957b825d3abe06a6ad9d8bba2e03b915aa779ac42fd9e5bc247411a",
|
||||
"0xb937b6dbba5291fd35427afb0126ffd47962a07c3bbd6c77e4b80f6bf751c684",
|
||||
"0xa5461d8dd8d05bf13875c6b2b62c82d371163d2f8ca80c2c0ee4d94061355a7b",
|
||||
"0x58901227df5457e57c74db16ed72b9b6f9303de046e7adf6fc269db7ee9e0a28",
|
||||
"0x33cb303cd28fa770e6c9f067831cb1829a8ccce845ac6bdce7d3da5d4ba8f3d1",
|
||||
"0x3ea819ffcb3839d7a16ce09958849118a801152ecedc92de0ae5154f6c8a5d1f",
|
||||
"0x001ed88b63827a6c71d7214b42551990e3f313720d982ea5f1049ede4f9d228a",
|
||||
"0x2e346b0acbeeeb88e08ca6af0f2bcc3669e093475d8c224f23a45d4e2fca462c",
|
||||
"0xb4ed38878080e2128b706ca1ac4c92c0def02a8ec094d07312068c10f6b144ca",
|
||||
"0xd0d3c577cf73421791431a6f00452f33fd06f771de9ae2caa32ef2c93bd03951",
|
||||
"0xb3dc9827308478b197b3995e39aa930d40df8cb98fcb2958c6ff8ece2bbd4c16",
|
||||
"0x44547163a565de79110c1e42b81151a6e304df14953e648742558efa6f63672f",
|
||||
"0x487a072363419adfe51ce0b8be352c0f497e5720617e9a237500293459cb7bc0",
|
||||
"0xe7e9d6bbc5de3d62822c92cec484926d935038fff8be29ff3743008499000d9f",
|
||||
"0xe151cd789208eeaa791f146f7e7efd46c17e2f8aaf061ba5bdbd7357a32cea39",
|
||||
"0xf5e2de235cd7ecbc34828c244da80de6c9c452c253e6c876d9843bf5bc665daf",
|
||||
"0xd0bdde209238ddc6ccd1e06e6e69c2c16b38ebac8b9f3202d46bd6bebacdd893",
|
||||
"0x5c3cab37f5d83ad8fe9349ba88ead08f36e71f149f10642c819ae53b26ccb0a6",
|
||||
"0x1d069657a6a467ecb3a781a3d72a8b701faf497e1098fbb9c04ae29820fa4e75",
|
||||
"0x8fa114b013195af63e697432f3be7017ce8fd6e7ec26f23f832b003e82f17ce0",
|
||||
"0x2664fa9d45f83ddb5c8a758c6fa3201abe7ea14571c886815585c543f245b301",
|
||||
"0xd6c3528e946a4461efa56df07020008870ed64fde08cd72e7f8be581207f0d1a",
|
||||
"0xdc4c0f579f3e44278905dbc69610f7d1025e068f75e5475400d96c97297fe5a3",
|
||||
"0x06124cac7f9a1c10d48216905db968c9580b3744ff89b37b9b49e7308b04da8a",
|
||||
"0x5c0c6c98bce9c64b7b62d62ecf02f435ce54b76c58883da177611774c79d5fba",
|
||||
"0x424553682070092aa2ab3e454c66dac9d6bf6baae6379d91405a47fa48a3f200",
|
||||
"0x3d09aa437ff840909ec6024c1e407ee7b5622561e4991b76968c146ae1c4976b",
|
||||
"0x3ef50c81169af169c100f58f3afcb8e2f926d957b2adbaca8787be5d4e8d7233",
|
||||
"0x8783eaeb56ca2d7fec84e0e272b77271fdfd6c14452a2e1dd83de770c5d99a1a",
|
||||
"0x861024460895378ba100c5d0c05e62bb6cac8b21ae529ab5cab39eb6c6cabd90",
|
||||
"0x1c741ed9eda60e5ac585e2f48f06fb988367c2c40a0d8111bb04b260fe44ec6b"
|
||||
]
|
||||
},
|
||||
"accounts": {
|
||||
|
117
ethcore/res/ethereum/poacore.json
Normal file
117
ethcore/res/ethereum/poacore.json
Normal file
File diff suppressed because one or more lines are too long
125
ethcore/res/ethereum/poasokol.json
Normal file
125
ethcore/res/ethereum/poasokol.json
Normal file
File diff suppressed because one or more lines are too long
@ -52,9 +52,9 @@
|
||||
"extraData": "0x3535353535353535353535353535353535353535353535353535353535353535",
|
||||
"gasLimit": "0x1000000"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f90214a04d45aaeb1f0e00495b99f5fdc46c2c1e6b0fd48c693678de72afc1cb6f47a086a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794120c78af68df5957e776554d138a6b75f2c34b6ca0f2746b213421be4ec9cab40fa41aabfb4a3e8acccb6506d6cea4863774374dafa0225a348dfb2ef00db09da39b1a11b31741b6d14fd4456cdf4c2528961f398b74a09528322c1ce98449eed355ddabe0192fac920910a0d88965444b9efc1ac218eab901008000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000040000000000000000000000200000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000100000000000000000400000000000000000000000000000000000000000000000000000000000000000000008426e4d4518334e0018389545c8306529d845b284db896d583010a068650617269747986312e32362e32826c69a066f990a9ad374c2cb0017e96d3776e6c787f679d77c9079fe2b046279453d0f88851bec8da753bda19",
|
||||
"totalDifficulty": "8635599198809021",
|
||||
"hardcodedSync":{
|
||||
"header": "f9020fa0a415a8dcd55fe9c93372da415ff6897036e48cd3c1a5ff8ffe119eea1096ecd6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479443d58f2096e015db88e44346e73d8c59cb1753bda0100f05d66d36782b7c061c724d8d07619cc61053eda41badc8d2cb9292898ebaa00a60317b490365f40f0528e1f559b0f49facb6638c82a9490d368e963647c704a0118b536c3bdabf90273d527dfc26914c7878176fff16cee8fbb150e00ffcdd29b9010000000000000000040000002040000000000000000000000000000000000000000040020000000000010800000000000010000000000200000800000000600400000000080100c000004002080000000045000000008000080000000020000200404010010200010004000000000008020000008000000000000000108010440000800080000400010000080010820008000410800000100000000000000000000240244000000010000000000010010000000000002000000000000000000004000000020000001000002000000000000000013000000100000800008000200000104000000000000080000080200402010000000000000000001020000008008501602a8414833bc8018347b7a983476d40845b838083904d696e656420627920416e74506f6f6ca0f540bc9cfa258b97576bfb9a79518b2c07ed73a98bc6baa61cf7af4b40ad5b6988965658a406315a8a",
|
||||
"totalDifficulty": "9811143388018700",
|
||||
"CHTs": [
|
||||
"0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a",
|
||||
"0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc",
|
||||
@ -1747,7 +1747,228 @@
|
||||
"0x8baa0703e1a050c40f85dc850fe477881f432c951b1cc1b2b71ffb68ab7fe0d7",
|
||||
"0x14ca94dfd343548e32ef5659c043d6e28f0e577fd38da1ee12f11c08e281d775",
|
||||
"0xef25357970c76a8b72a6e52f49bc30651f711c7df70444d4667e80febc0e3b2a",
|
||||
"0x41b8b4ebd5919dad3bc609ded524b97403d88f019367f0f4f622561131644ffb"
|
||||
"0x41b8b4ebd5919dad3bc609ded524b97403d88f019367f0f4f622561131644ffb",
|
||||
"0xb29a8ad1157621d0120aedbd8dfeb4b318979bd43a5b018bf7b9ce33d85da312",
|
||||
"0x9ddf78b5d67ef40454867ed33de83a01cbd8c18fe09da3d9f991a196811dfccd",
|
||||
"0x3604121f9cfbb5cf552cf8bfc9a7958332eb97131158e4f40f4eda481e553991",
|
||||
"0xf1778830f694720a6f990f9d476b0f365e8a74880253b55ee16f5cbd6c8082a4",
|
||||
"0x89831626d154fbe84a4c62c3e2638cd00e42b3844c7c7b98cfad113abdbc5347",
|
||||
"0x650573f5ef274b2aeb40642e25fbd661cb0eff66245d7cc8f6fb9e9daa80fc12",
|
||||
"0x479f6c652173efe94abaa850bffe1557847b26f286467013a4d72973e05e8e54",
|
||||
"0x7096619d5716c34592ac2d9907ac28a74c6f6b1ebb1962a0217df82bf3e714d4",
|
||||
"0xb7c7edbd8ae7eed58e973dc0750adfd04042ed56baabf372b111fce3e4b4469a",
|
||||
"0x25529b597bd15317e55767b3fbfecad0657aaeda99f098186b41b70811f7af2a",
|
||||
"0xd790747b09f925fd155b7bbdb5ccd89d873277163e4fe7054bbf71c0b26b8072",
|
||||
"0x3aa0b221d1c4743a06692f645f38a8128d55f1c07cfa6e9711b0d2e0f2e0e738",
|
||||
"0x26fb5017218cbe4250d2ceae751e99b9a34d7befa162dc248ac008c5d1221e71",
|
||||
"0x0e4ada59854027601f8f81fbdceb95228db667eb65fed97cefbb35dba21d3b52",
|
||||
"0xd3be75ae2da3e271dd85cd8226d789aa12d108a4b0d2681462f6539637572e50",
|
||||
"0x6f041891c8219b508138f67c95a1765d08c5ec06b9ce585f52f837806fce0609",
|
||||
"0x9e106515d0e80b41397b2e8e98adbb7333e76265917339a62063a07d9a7ed311",
|
||||
"0x25f47483ecc5ec32f94b3dbcb4d42a4cdbf5c279e93567e14afc742a4619d3e0",
|
||||
"0x5d81afc54f6b68bd820dcc629ff7e9d8397da56ffedef9addab0eec620de0757",
|
||||
"0x36e192130485f248925d4b0d2fd98745a76099eb13f53093621d216d0aff0d6c",
|
||||
"0xb906e5e33b63f6cc355c13b8461a260ee25376ee96909fad2c6ac121ad831496",
|
||||
"0xd68e7e0d136e30f67ccb7c21e4dc43b0ad5536584e4b77c9da8d903a04e9d212",
|
||||
"0x5aa7847a4bddda7fbffa62325da920a21a11524ac1b691bc3b55e4d1790f24bc",
|
||||
"0x331f95f062ed1d38dd02b5ab6a95dd238ef97c5ee9777c938697340c902b4b5d",
|
||||
"0x8c6a580c8b07567f747bf20946023c3b581c51075cce5cd5d47b0d81d8922135",
|
||||
"0x8b89483810a49626f90846a0b49ad3e2172657dfa3003d58fa2a43d12c8f4090",
|
||||
"0x944f9a5754800a33d903c8a464d602fc9da6af8ff3990c3eb669ac9cd17891f9",
|
||||
"0xc75c82a2c1ecd875d16f343a58835d756740902c246d3b1deae97e49aa19f98b",
|
||||
"0x1d2e0f2f87ff2b08514b18855c343966d42e0f1a048ddd3d316dca6e06292db9",
|
||||
"0xa6508507463e53b3a840dd55ed9be57c8a56e1533c9001276750bdf19796f8ea",
|
||||
"0x01eb6b636b1852e8f9066c12d4e6b7b06b90a325be4d97e08f7f560bab4796a1",
|
||||
"0x8a0d77fb41f50808ff0a46dc9f3831a2b5093f55ec2e94a3d2e92373ff3b5695",
|
||||
"0xea3383ba1d30891d1e236db2b31373541f51a9e5c4b4d017cc4960480dd20311",
|
||||
"0x01129e8d7eff516a225cc0db090e4e38362d9eb2d0571ce00f4417836de2e375",
|
||||
"0x92feaefb7f9466814a0220e536fe5ee73560507d071e059827d406329e609f87",
|
||||
"0xac149150c11b3bdc660320a0e955f154fa3137549a73951207659e2b903c145b",
|
||||
"0xcb68cdb224f9b3b0b0f3ca0056e70817146c9ebc75876dd952e6ca8ea896f2ac",
|
||||
"0x157565282a12d790452e343c9762c2124456039729f3a8f97a2cee60d85628fa",
|
||||
"0x42eadc181d59d8d8b26b37e0e9c9052e45bde72090d330bf9cf21d9d3c7d9048",
|
||||
"0x1ea0ec8879b200e259a3a2a0f2a7aa292301784fa422f7c32ed5d945183948b2",
|
||||
"0x06aeb2956be9d74ae4ff0b8a6c1874ed8ba46a186616356dc060bea1cbe5c628",
|
||||
"0x814b0382b52a155a4e35639aeb3d8c859afc4fe5d151de3b0f1bac646e40f2eb",
|
||||
"0xb30bf3e85be41a2a9e53321ee9f03c7078516c72c7e2d8e7e3134de709b61c36",
|
||||
"0x1f97f5d334b5e6ebc72f5b846f24c7911f4fd1653f89b3477ce4b8108342810f",
|
||||
"0x84c6fd181c28ad159ff18d203d14f966668468c9ef0a5d6dbd863886a7e0af1e",
|
||||
"0x4b2e6947d55ea504bf205bae9dfc0e5402efd33757eea4da00a8ed2a6a3838ae",
|
||||
"0x85f31d45128bb91cd3490b58a0a641ef77246ea9c83de30fa89b621307fd96f3",
|
||||
"0xd362f5e6f8cbb216e66eaf49e4df25e01504ac729da86c530871a34e11d302f6",
|
||||
"0xb7860983b043bc13ce5a27135eea12ffaeff71879404b18af3079b98da156bf2",
|
||||
"0xf2ff82a679b2b90cb9f4a3bb903eb7ab36ee1c47cbe40024d8d570f5e16bbf4e",
|
||||
"0x7e34a7e6673146b6bb7f78593b6093ef15b8e9fd1271b33dc5f7d17876b31871",
|
||||
"0x725c97f83b4cf213296ef353e1c8d64854ef08983fd61320088b8d9e2ab33849",
|
||||
"0x18085800d10fc7845148835d0ef0ac980a82eeafc44e12bfa296f9c38fc6e19d",
|
||||
"0xc6c3cf95310cfd0254f0f8e93a3c25bad2b17df04f9c51a25927b80d02e06b69",
|
||||
"0x822213c1b03cf68ecadc0b7572d37266207d5fe4efd5e56a924b0a1aab8a8e84",
|
||||
"0x1ff46ffd2dd880cca76244f6af1fd8bddbb4b9ec58f86639821a16f2ff08f3a8",
|
||||
"0xe9d00df19d716dc859922f2e6c907263191c8e531498ea557869ea1115317c95",
|
||||
"0x6d3f1edebd562e9d1a236ed7a1d9104fd8f5a086cd78d35c7a65f27c269d98ca",
|
||||
"0xfea701ced5bca0d5043512700598d3eafa0b89dc02f3c157cd1d52bcf4d84d9b",
|
||||
"0x556c1cd8ff3ebc2ccd4eee9f1ad3837e346ecda961da17c0ee9cd4d084a47653",
|
||||
"0x5606be2fba065424af76c94d4156ea82f77d9872ddac7a4c2517957a169e58f9",
|
||||
"0x8d0223425b48487db1b371c966c7688435f4b9fcda75b088f0aac203d6657cb1",
|
||||
"0xfceb55d8f3048a3f2255562e0a9ee342439253abcd048fac151ef4b910048e22",
|
||||
"0x360f76e4f2ef49632e3bf8cfc3afeccff6917e98a48d3568148c3bb13f9d2d7e",
|
||||
"0xd87bbf8397204cc2af883362646b0ae95392303935ec1997ab052c194e0ef117",
|
||||
"0x9f1dad9dfecaaf117ab5277caf672b70540578e703c2024d3f23bb7cf8d6410b",
|
||||
"0x5e130ccb23b7b66dd2fbdd912d6006d2820071dafe2890f593f952028aaa19c0",
|
||||
"0xccd2f182107992fb9b002b87cdf7990cb2810b202b2ae5d6ef5e0b3bd69632e2",
|
||||
"0x4b40cd83205f8b946ca9f11fc3306872650e658e631511fd4080bc8ca749d913",
|
||||
"0x652acc59b71ca20bb65ca195d1a4b3e177f6a3985bdcd6120e1a45b7d4a0c7ca",
|
||||
"0x49a5e2580ceb329665244e489592aea27d54da8189a665d9435e037ea70c46a5",
|
||||
"0x379801356beb3a8e5fa7311792c69c7ac1f675a9c08c837f9f0e9f53c243d6a7",
|
||||
"0xfeff4543c70356b7d9767c26b228cac8452c95bc4875e92a60d7e6fc50468667",
|
||||
"0x82eb18827313399cb3b0d3c975eb9a9480c3aa5587ce72d321bedccaaab56115",
|
||||
"0xa644c582a751a6d8cbf30e59d6e770a6f441c017b486cdb23e6b9c48c614967d",
|
||||
"0x75e6f4d4185515a3c58dea60b55d5e50af053bb261db2d3de00f812a4072ee2c",
|
||||
"0x9018506876afe91cd2cded037f41c5ee8503fede2a59c47dfe7ea1b36c460f73",
|
||||
"0x0b8bc06bf211f715291846c6c34b805b6aee91ef4e8c63cf3d15ec79b44ddae8",
|
||||
"0x150e43fee00d798b8611d4e03838072d8b9c8ee3771e840ee2c161a541d6b643",
|
||||
"0xe98c938110bd4227c660a9bdccba3b5ce5b8414d909514502e8f354f96abce69",
|
||||
"0x0fdc3bd666d74a99e623f6d4957bcbfb17395bbdacb52b18ecf7aa5d2e4ad2ce",
|
||||
"0x2c72d738e803c0522b5f424731ad6327548ef08ded4caf4ae0466b2cf171ac4b",
|
||||
"0xa7709a082f8a2ed01e2e88c4a2d18930f510fe5b831d2a1bbb1a85a858f19e54",
|
||||
"0x8ccb960803f6b6e87515ec20a36734128da0dd6e65845013d89996070d3cbc69",
|
||||
"0x4ab2e49286c8505f32ca54314d1b5c3b2952578d191c69d1cc7ba78a000a01d4",
|
||||
"0x6bb792b52949c952f20b9d11274c8a05edb44c4070d949bdfddcb0eef2464454",
|
||||
"0xf61eccaeddac91487b2f5d7b3ec57d1ccbdd0e1307d2f624319fff525149941f",
|
||||
"0x2dcf01b0d9ce31c13c20959618f2e5e0c7f8c48521f00c12c99d28bfcf202f57",
|
||||
"0xb1e83745e6013706904b7322350c8b453aaaba0a61ba89f35eef8f19759ceeb4",
|
||||
"0x8a2cd4944bee70696aa216b453774f4d915dee4bb78c8f7ff55410cddec318fe",
|
||||
"0x49a78ff97bd4938cd030df23e5ff4d84ace59ef3fdc0099941d8ad7f82235894",
|
||||
"0x61e2096919419c8856a5473f135f4f9febb102f80eecc90ad60baaed77a99d29",
|
||||
"0xb95709562a26564e57cafa00d0969305ffdd0aea7e523ba90957a6cbad6ceb70",
|
||||
"0xb7a6438f176aed77a9c6470e28ab8cf19dad8f77dd3313cfbbbc9276761f454b",
|
||||
"0xc85a1c37b5a4e1e8ae67df31b369f0b44cdcf66418b42206e5b4a738a0a0bae7",
|
||||
"0xf034b0d125eb1bd1bbde1fe413aef80fdc136339eed062b97cb9da2f4bc94ba5",
|
||||
"0xcddbaba3e9e1680a2d1586a1e9e2268afb51b4894f2b41fb2eac5f667b6cb655",
|
||||
"0x971b2fbd25a97bc710c30b6b98efc90428a7e423c09fe772622e7ea37d18e49c",
|
||||
"0x8571bcf05c836a59a5d3216634ed1f691edb7bcddc7b5412bc513ae9e1fc0423",
|
||||
"0x0543d8abe5e1bd541a5bc994b0c7ea5a556575d2e9302d1dc36348ebb7ab9e82",
|
||||
"0xebd8f9095619980043f234bf4f7682534ae6a15b4584e9d1ae524138471467c3",
|
||||
"0xd0699a768c873ca5bd615ab5b0fd9c7c6c649c4245b58cb622210ac2bfcf3111",
|
||||
"0x35bd5a50b11033878751d985459657bd4c0206584cd1def98a355d7ffb0539f4",
|
||||
"0xd476d2b8b62b720520ba0990137629f83db9c6896f1e788fa5bf08614af1f2bb",
|
||||
"0x2a8034765c582c07580c0da45c4216bb513171d073a99cbca2fa2adc0c05dbf8",
|
||||
"0x084b45a575706daccfbbbcc321a9546b0c911861f2639d81f210b77680f60fb7",
|
||||
"0x499bfc54ba17718aa8f74ceb412dd9b6b6c7d1cbde4d8ad2385a5d5d77e98915",
|
||||
"0x8638684b06607afb53385f477f0f295453f14e36161da6dc7728336475303a9d",
|
||||
"0xa686ad8ccc3507627712d203f7ff3be65c289da67269388d0ad8949ad3a5a589",
|
||||
"0x6d262ff8babed3a603f400501cd77344585fff92e5bab5f5848873042ab87cb0",
|
||||
"0xb5755234055b3534fceeafcc84d0d77dac220d3466e1dbbbe7d7d44c345e1eec",
|
||||
"0x92a54b989a1aafd36f979ff0f1fc73f9b1508628f054430234f4460cd9f3959d",
|
||||
"0x1a48d9bb57e9a70b03c066c97ff9520c177b8361f2b3c343ac71fd8cbdbadba5",
|
||||
"0xc9e103919e8b6827a1fd57a3e99155a24810f524fb69a7e3fbf486707b2da690",
|
||||
"0x22a5ba2899ce696fe691a2c545b98ddecb7c0a844cff2375e50e0a0f0f9cf9b3",
|
||||
"0x154890ebebe7f014aa88f8da52c9713e2b0cc8b9b6c7d29b354afa000c2eb429",
|
||||
"0xf9a72e3ce36943a442d0dbc7a869a6344003d6a7ee4d344c1899ab8b96746a6b",
|
||||
"0x270fe45a526aa3bcc8e4a5be075610ae9b15d6fe48b04c6ff0c82a1c7f56e0d8",
|
||||
"0x9eacbdd695faa85bdbff10bcefcd5edfcc489c3380cb1c73ab5ca6cba2492995",
|
||||
"0xca15124d292e0465c7e50276cfd374c82391bb668d68a3b19c67fbb9e68b0bba",
|
||||
"0x9a8cfd3f1b8ad178c982feed1fc306dc996da3d928e99a6f8ad240e55f52cc3e",
|
||||
"0xc173b14778977c5d6dcb1079023c493406911c6d6791ad08104f847323aff7cf",
|
||||
"0x82b3e9b9a407ff0596aa7eabdeba10dded85fbf3258d12949ed4f46484e0f649",
|
||||
"0xb8a009c28a2328b7c95531bc64e072388d797130652ea0a84159c801af562a5f",
|
||||
"0x80e45ff8b60d28dbb45530b7b56e049e605d28087df7133766de0e151dfbd01c",
|
||||
"0x7667e9cd22c5427e6f37f215b1d9cd90b2659d5db0bb499daa382e09fcfd58e3",
|
||||
"0x825014f354bee6aa4cf5283f86e8293c0ea6faf07862abe2cfa12740a0d846d3",
|
||||
"0xbe9116073311dc303fa29f7a226ff79fd39ec2ffbd2d2270652b972a701aef54",
|
||||
"0xb3fd19eb6b0163156a350156b15e660853f68a903ea6ed758bf80b2fbc5a655b",
|
||||
"0x3c5a408909bf485e8c3d8e683d8ae4e7b7149d1f01874807428a3f88e1293d4f",
|
||||
"0xc759f51aceddb90e6e4273fb9439908592dea649f5202f530d15d455c5c8c7c8",
|
||||
"0x1fc97f79d1b1d72da309bf2027ae193f0594ecb77c07a472421baadda577a24c",
|
||||
"0x09c4fd284e5c0672ad031629e58fb2776d1e772c6041c91433f287304dfdcd1a",
|
||||
"0x8c6b40f8700a0638ca5b7bb003c2de6b54e731881a072988cb78ba89557db1d6",
|
||||
"0xcbc701507f4f970d8dbf15306d6ac5bdd46b6f58bfd2dd07db4ee01c65aab5f7",
|
||||
"0x6b911e52f43696cab429c0e511fc40011846af92a2631f4d3f2cd040567f021f",
|
||||
"0x4fa5373f6eeacba61818052da8a9787c4ed86be0bffe0672c0aea792cc3d2d49",
|
||||
"0x518ceeb36cf1a406b89040ab0c60e380068f5f6571d042d3bd9a9d7af1b12204",
|
||||
"0x82039214db7d3beae631682e9249b06f98e16153f864c2026a6edcb0727a6532",
|
||||
"0x9a9e534af83084007e54dadbce2a0224008a8c42356c2ea650606e8e72d2ad8d",
|
||||
"0xc4dc0b662ac8d4d987b8c2c65cd27fb8992f65d598bbc25f017c45b7032451f9",
|
||||
"0xa921f124b5275f07b2c064d477d5779963096632f03c54ac9c87917bc4aa6e52",
|
||||
"0xb4fe786c84a19c8db63117c421ce53244436d0c04384c62d508a88589f4e5c83",
|
||||
"0xd57ea382802130e3ee8e7671be2b40a1392ebc6528e2e10d9d51f2899ac7ea54",
|
||||
"0x224523fcd11abd078840803bbde2c3d1d359a0c2cfdd6f9110a93ac4d3c49845",
|
||||
"0x5da21f79c0f1030e2a5dbfa283becced75e7ff223ef14a6cb5527434503ac71a",
|
||||
"0x3e315746e89fd3e662f4dfe28245457c3b8a4ea6d9450b93639424a6d8ef7d41",
|
||||
"0xe142bd09a6967021c4c5a5c7491b0df3b1bcf13564ac934a2668e1b2252e4723",
|
||||
"0x2e9ab88b366cba155d1f6093e4edbbafd80032b07a192a35942aeea1bf0f1074",
|
||||
"0xbcbd1b446853135abae9f330d63a06119a93fb53b63c621941f5a74324c384a1",
|
||||
"0x7816de8933a433aa2719c99db24e692e6ac6551416b08f803302c7751fcfa3ee",
|
||||
"0x52c53032dd84842dff6580013ab1edca7c251598ba5fc8b903c40e3d9e537095",
|
||||
"0x771222b46cdcbeba729436ef39f81732aaf4893da720c1e7b59ebb3fd38ab9d6",
|
||||
"0xfc440de1896e1b2848f2cc5c7d62c0a6b0019008de8aab41df5395586d340d4c",
|
||||
"0x0df9b803307465e54cc77ee60dd6988e3d713d496ac0209509c5312ad0f19888",
|
||||
"0x88179429086844e69122c70b6af8b689abea11e13ba0809743532663e3047c3e",
|
||||
"0x503898d86c4038eb76124e18459e0d57ec25b177fc79bb87eeccce3fa75f0037",
|
||||
"0xf46efd490382e4e4a3ac0e10926b46ec56e833769acfe3879acffb13030cfe9d",
|
||||
"0x6efde5293a9d22e688165f2a51bb83e3b53584f9ef5bacc0bd1d99f5c7df18d4",
|
||||
"0xc03dc313d9be55674000d061851c139f4c57c6fb46106b98c3442832a51c5f3a",
|
||||
"0x8ec2accb7c89019d0fe2a31ddada0b8251ebe88a439de9d68be73c0994a6523a",
|
||||
"0x36ec73d7e8c0181f6335c668ad7713f8eed607e0c302b43413f904b26160bdc1",
|
||||
"0xa53e90d88a751a78397adc6d2fb4f93ad2b38f0ebd00b32932c4b2a39a276d9f",
|
||||
"0xea2a25111ca37a53c8fade1ef65097f0cb85e00881b1ff201d36c9151a8e1a0f",
|
||||
"0x8c1a24ac75821a4b0570c22b682c6030c678244b059ffd4b21e4d3cd05afb585",
|
||||
"0xd230d46b14f9586f7b1947add191a69ed381cb6fdaa9b28c28869da8c6724dc6",
|
||||
"0x4e8c717de6c94b4be274f052d9df627c945afe18df35c58a90a035759dce6b48",
|
||||
"0xdefefe94ca6d93b78ef9f92911eec4c2ae0c10148691755f1624f86445a3b2b2",
|
||||
"0xfa6c031ec69c7dac9f9b6524054806e2fa524c3200fdeac030d3bf7029ab776b",
|
||||
"0x9204683278cad559a3f9ed2ec1f6539f34efb17957830d0aaa92b73cd0994732",
|
||||
"0x2bb26a0cc5eb7424033e8bf552c7964573a0954e5b6aae32a51d95d951fc044b",
|
||||
"0xf6e3827687af53fc532ba163d7ebd5ce18ffa6384157982b6dfdb1f4be82faf5",
|
||||
"0x627bda246bf499f4498e8c512c8f601e36a1dcd778f21a598736f83b5b33fbd8",
|
||||
"0x5816773273e4ef45fbacbe920dc3420602d8134fffe302459891cd6e65627f6f",
|
||||
"0x7cd637fa8a5bb32dfd7c076c34e0e536d7c6710f1888f5ec18d64191a9930744",
|
||||
"0xfe016a6e9ffd59237b349a817ba8c36f7775fef6513c4d430fbfc20ce72fcb1d",
|
||||
"0x7c466b30cf23cb7115a3855d9d9c537c29f380ecfd7aaa0a6e59d9680bc43971",
|
||||
"0xc49551e5eb138d28f5557ea8e8a8bbc7c058084ba0edf8f6bf64471928ecde43",
|
||||
"0x7366cd68072f52c5644dc9fbe2e72339705dddd2b03690dd748265723944e754",
|
||||
"0xbfb7c3bed071283cc18cca4192e2bdc1f97aee9b7185d493a29f20ed4d52ae3d",
|
||||
"0x40c9fbfde126c8c92cf6d15a18be4b5a4da39ff60ce45cf5e9a2c1782244947a",
|
||||
"0x1358333dd1b82e7c805dced5dcc2edd5d5784fe8104b64eabc598096c26d05ed",
|
||||
"0x0a9777f7711b6d9f6cc6ad4a78b716199b57f026d1f30f04ded5d2cd8286322c",
|
||||
"0x7a848ef083a03e4112c75bef258633779cc495df4ac5529e12c8eadc484baad7",
|
||||
"0x17025c4c255f509163d11df3cac35c1de823e5ec71cfd66693393882d81fddb8",
|
||||
"0xed0a2fe0dfe85c7d606d0d1b355518a48220e91202ec1c1178c8b37c86e1c9cb",
|
||||
"0x4674e5e97dc0c615b03c34c702ceb07aec48cd7e8edc953a188d194a8cab35c1",
|
||||
"0xa004c31b7a6f6511d7eeda4c400c5ede847ce2ea4339641b6c419f688cc4e574",
|
||||
"0x1bb6c124e94df05e091f6aea45e7658351fd21318e91105274a15be4f7a7a632",
|
||||
"0xc365b8bab2d6b902508d075195a1e23b04c97e40217c4ffa49fe16bb13e5b575",
|
||||
"0x93c1383e2ab52ded5fc86e1b6f6e292c0d0977e8756e1fcbf87b099682060e25",
|
||||
"0x2921b874e3855d9afca966d5088e9b1cfe59f37db54bf0c1e8bc5c5a97e7ef6c",
|
||||
"0xfee916dad70495cb45c6ac632241a73869f0f553bf7172cc4e63fa382a5e1077",
|
||||
"0xc63d63b401941d11edf755d7b6564b4fcba1f84ed99cd08f1580faf2c224478c",
|
||||
"0x8069f00ca36baba06b310e28f6873e78b3ded25b456d95dad7eef4c517e7d096",
|
||||
"0x48dc0968af32e91a8a3f252bc0082d7c22f8dd9797e4fa774d5b5365386a4602",
|
||||
"0x861ffb24def147c4577aaa332aa2b5d3165542c4fd1e1882a9050e5de10f1f57",
|
||||
"0x9fdfb7305249e7a38068f8099b74c5584a2f2df3f0514371f20042a6c0d2c85e",
|
||||
"0x90212f15c5d6b686810e1895a139bbc26141181c3c472ee28ef9904553a2faed",
|
||||
"0xdf967dfde0b63153142628dae7522307afb35b24146d9fc1d35874914244eec8",
|
||||
"0xfb17a9d9e9a5ab6d742f55c0e8d80c5e5d722e9411e84bc47b1d2fe5fc33dd71",
|
||||
"0x56b2c30b802088f9ebf0918c7ce44b50a96a0eac98f89e1711f53452006259c2",
|
||||
"0x4c38b33bd4089a48a65369955540219b44af520000b8f8c346bdc96d47dc2479",
|
||||
"0x7d3487d3823204a94e557b7a942d7c657c1b49d9f40f2d739a9099d4438695b3",
|
||||
"0x2f82f94eb74aa2c0fb91bdb38ba0b416ce7e033c7e2a74aea113d201b225e24d",
|
||||
"0xce8ac4b2f0f74601280bc3df0f5955d033e5c511372d812b36dffbca4b2e4736",
|
||||
"0xb6ea6c89e91ecca1fbd723188a77370e9d23c3df8aac282cbcbe000b13d31b57",
|
||||
"0xb8b8b7cb900482562227a0a1256ddbe822cdcf134a196e29b1aa6fd92423a4ed",
|
||||
"0x0f47ab9f4985c3175e0a30a237d4f7c42db4a58f95344a86a818e459296610fe",
|
||||
"0xc26a55a23eb390fc83fbdc9f07ee3ce09e8a2b28bc09386323ffc0844e13be24",
|
||||
"0x1d5e97a7fdf5f34192e9b6dd255c41b63e24e1b4ef4ea43ae510fd1f50abb022",
|
||||
"0x58b6120c4f0a1004e51703e77decb1c85bdd40bc83654d3f8ce5f7e3b4b6ca25",
|
||||
"0xa2f4b27f5641d9294ee0411bcabc574f94b294ed8c50c9ae0c3d58caea7d6ba9",
|
||||
"0xc4d6d3a8b4debec7ec7f3e2a6e1c64de46ec1187ed6e87fa2d87412c9874a3a6",
|
||||
"0xfb59d9b66471893988d0fed17898fe2b7873d85aed217c20b6f438ed70fc340b",
|
||||
"0x850df664737f288ae16d701878ad04f399b367fccaa2ddbf975d77868bea7cf5",
|
||||
"0x4dfe47362c005896f82ac2d02a12ee9418693cd2f5d1bcfdc321980897171993",
|
||||
"0xb652952de1bf9e1174e5f6a37b069b437792672a37a9e0159c4f36b6e64306b4",
|
||||
"0xb72dd6cb5df1b00dbbd84e097e2da79af2ce60559697ab4c93b0a8b85b2ee406",
|
||||
"0xb96fd4a94ac30c10f757691f7f06f25a4900fe424f4eb7ccf322e2f95249b914",
|
||||
"0x99fd442599036f161ccef1ae8088c5ef694c1819f5b76d9d2fa8f979935f69f8"
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
|
@ -16,7 +16,16 @@
|
||||
"gasLimitBoundDivisor": "0x400",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID": "0x62121",
|
||||
"wasmActivationTransition": 4000000
|
||||
"wasmActivationTransition": 7250000,
|
||||
"eip140Transition": 7250000,
|
||||
"eip211Transition": 7250000,
|
||||
"eip214Transition": 7250000,
|
||||
"eip658Transition": 7250000,
|
||||
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": 7250000,
|
||||
|
||||
"registrar": "0xb8624dc8cb3ca3147c178ac4c21734eb49e04071"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@ -43,12 +52,22 @@
|
||||
},
|
||||
"0x4ba15b56452521c0826a35a6f2022e1210fc519b": {
|
||||
"balance": "0x7E37BE2022B2B09472D89C0000"
|
||||
}
|
||||
},
|
||||
|
||||
"0x0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "activate_at": 7250000, "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "activate_at": 7250000, "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0x0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "activate_at": 7250000, "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0x0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "activate_at": 7250000, "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 7250000, "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 7250000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 7250000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 7250000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
|
||||
},
|
||||
|
||||
"nodes": [
|
||||
"enode://147573f46fe9f5cc38fbe070089a31390baec5dd2827c8f2ef168833e4d0254fbee3969a02c5b9910ea5d5b23d86a6ed5eabcda17cc12007b7d9178b6c697aa5@37.120.168.56:30303",
|
||||
"enode://a370d5fd55959f20af6d1565b151a760c1372f5a2aaf674d4892cd4fd2de0d1f672781cd40e0d4e4b51c5823527ddec73b31cc14ac685449d9f0866996a16b9f@13.76.165.180:30303",
|
||||
"enode://da019fa5fb1fda105100d68a986938ec15ac5c6ff69d6e4ad3e350e377057f3e67e33aea5feb22d5cdcfc22041d141c8453c77baa64a216fff98f191ca76b3ec@18.220.108.238:30303",
|
||||
"enode://49498fb8cdcd79c813ccdaa9496a3a4be0a187a3183e99adbc04d9c90b9a62ad59f0b6832f6e43b48e63fbebf74ec5438eb0d6d9098330edf36413d276fedf81@13.80.148.117:30303"
|
||||
"enode://eda34244538d72f42605a6fc8b8a34b15714c683989e8b29dc9e7a2b2088da490a5b32f2c149bec5a5c482bf03ec2c4f38b833ae31e36fcb26fb05fd094b2a88@18.197.33.9:30303",
|
||||
"enode://12e903e900137b02b22e01f7918bd6e7310773c313e4e577281f35597e394a3e0b54c7314a8970a9776c5a3e5dc4daee289215dea3897bcb6d5cf0bb1dd2d356@18.197.31.231:30303",
|
||||
"enode://423fdb91b37ec0714af0c19f625ec4af3ada2844367a36e45a05703577a84f7f0e9483585d4950a35c9e3738dba8c6abd7e1ce278d9a1f3f28065bc009f409cd@52.221.203.209:30303",
|
||||
"enode://a9327d37d07799817d4a3e13d49fb4f5cc1486d4adf3ec8a6b98be62c4d7a5453914a5139dbe124809a388514cb0be37f9fa799539abe2250672f6d3d778b821@18.191.209.251:30303"
|
||||
]
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ impl ClientService {
|
||||
|
||||
let pruning = config.pruning;
|
||||
let client = Client::new(config, &spec, blockchain_db.clone(), miner.clone(), io_service.channel())?;
|
||||
miner.set_io_channel(io_service.channel());
|
||||
|
||||
let snapshot_params = SnapServiceParams {
|
||||
engine: spec.engine.clone(),
|
||||
|
@ -18,9 +18,9 @@
|
||||
|
||||
mod stores;
|
||||
|
||||
use self::stores::{AddressBook, DappsSettingsStore, NewDappsPolicy};
|
||||
use self::stores::AddressBook;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::time::{Instant, Duration};
|
||||
|
||||
@ -96,20 +96,6 @@ impl From<SSError> for SignError {
|
||||
/// `AccountProvider` errors.
|
||||
pub type Error = SSError;
|
||||
|
||||
/// Dapp identifier
|
||||
#[derive(Default, Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct DappId(String);
|
||||
|
||||
impl From<DappId> for String {
|
||||
fn from(id: DappId) -> String { id.0 }
|
||||
}
|
||||
impl From<String> for DappId {
|
||||
fn from(id: String) -> DappId { DappId(id) }
|
||||
}
|
||||
impl<'a> From<&'a str> for DappId {
|
||||
fn from(id: &'a str) -> DappId { DappId(id.to_owned()) }
|
||||
}
|
||||
|
||||
fn transient_sstore() -> EthMultiStore {
|
||||
EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")
|
||||
}
|
||||
@ -125,8 +111,6 @@ pub struct AccountProvider {
|
||||
unlocked: RwLock<HashMap<StoreAccountRef, AccountData>>,
|
||||
/// Address book.
|
||||
address_book: RwLock<AddressBook>,
|
||||
/// Dapps settings.
|
||||
dapps_settings: RwLock<DappsSettingsStore>,
|
||||
/// Accounts on disk
|
||||
sstore: Box<SecretStore>,
|
||||
/// Accounts unlocked with rolling tokens
|
||||
@ -167,7 +151,7 @@ impl AccountProvider {
|
||||
/// Creates new account provider.
|
||||
pub fn new(sstore: Box<SecretStore>, settings: AccountProviderSettings) -> Self {
|
||||
let mut hardware_store = None;
|
||||
|
||||
|
||||
if settings.enable_hardware_wallets {
|
||||
match HardwareWalletManager::new() {
|
||||
Ok(manager) => {
|
||||
@ -195,7 +179,6 @@ impl AccountProvider {
|
||||
unlocked_secrets: RwLock::new(HashMap::new()),
|
||||
unlocked: RwLock::new(HashMap::new()),
|
||||
address_book: RwLock::new(address_book),
|
||||
dapps_settings: RwLock::new(DappsSettingsStore::new(&sstore.local_path())),
|
||||
sstore: sstore,
|
||||
transient_sstore: transient_sstore(),
|
||||
hardware_store: hardware_store,
|
||||
@ -210,7 +193,6 @@ impl AccountProvider {
|
||||
unlocked_secrets: RwLock::new(HashMap::new()),
|
||||
unlocked: RwLock::new(HashMap::new()),
|
||||
address_book: RwLock::new(AddressBook::transient()),
|
||||
dapps_settings: RwLock::new(DappsSettingsStore::transient()),
|
||||
sstore: Box::new(EthStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")),
|
||||
transient_sstore: transient_sstore(),
|
||||
hardware_store: None,
|
||||
@ -290,9 +272,14 @@ impl AccountProvider {
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the address of default account.
|
||||
pub fn default_account(&self) -> Result<Address, Error> {
|
||||
Ok(self.accounts()?.first().cloned().unwrap_or_default())
|
||||
}
|
||||
|
||||
/// Returns addresses of hardware accounts.
|
||||
pub fn hardware_accounts(&self) -> Result<Vec<Address>, Error> {
|
||||
if let Some(accounts) = self.hardware_store.as_ref().map(|h| h.list_wallets()) {
|
||||
if let Some(accounts) = self.hardware_store.as_ref().map(|h| h.list_wallets()) {
|
||||
if !accounts.is_empty() {
|
||||
return Ok(accounts.into_iter().map(|a| a.address).collect());
|
||||
}
|
||||
@ -308,7 +295,7 @@ impl AccountProvider {
|
||||
Some(Ok(s)) => Ok(s),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Provide a pin to a locked hardware wallet on USB path to unlock it
|
||||
pub fn hardware_pin_matrix_ack(&self, path: &str, pin: &str) -> Result<bool, SignError> {
|
||||
match self.hardware_store.as_ref().map(|h| h.pin_matrix_ack(path, pin)) {
|
||||
@ -318,175 +305,6 @@ impl AccountProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets addresses of accounts exposed for unknown dapps.
|
||||
/// `None` means that all accounts will be visible.
|
||||
/// If not `None` or empty it will also override default account.
|
||||
pub fn set_new_dapps_addresses(&self, accounts: Option<Vec<Address>>) -> Result<(), Error> {
|
||||
let current_default = self.new_dapps_default_address()?;
|
||||
|
||||
self.dapps_settings.write().set_policy(match accounts {
|
||||
None => NewDappsPolicy::AllAccounts {
|
||||
default: current_default,
|
||||
},
|
||||
Some(accounts) => NewDappsPolicy::Whitelist(accounts),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets addresses of accounts exposed for unknown dapps.
|
||||
/// `None` means that all accounts will be visible.
|
||||
pub fn new_dapps_addresses(&self) -> Result<Option<Vec<Address>>, Error> {
|
||||
Ok(match self.dapps_settings.read().policy() {
|
||||
NewDappsPolicy::AllAccounts { .. } => None,
|
||||
NewDappsPolicy::Whitelist(accounts) => Some(accounts),
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets a default account for unknown dapps.
|
||||
/// This account will always be returned as the first one.
|
||||
pub fn set_new_dapps_default_address(&self, address: Address) -> Result<(), Error> {
|
||||
if !self.valid_addresses()?.contains(&address) {
|
||||
return Err(SSError::InvalidAccount.into());
|
||||
}
|
||||
|
||||
let mut settings = self.dapps_settings.write();
|
||||
let new_policy = match settings.policy() {
|
||||
NewDappsPolicy::AllAccounts { .. } => NewDappsPolicy::AllAccounts { default: address },
|
||||
NewDappsPolicy::Whitelist(list) => NewDappsPolicy::Whitelist(Self::insert_default(list, address)),
|
||||
};
|
||||
settings.set_policy(new_policy);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Inserts given address as first in the vector, preventing duplicates.
|
||||
fn insert_default(mut addresses: Vec<Address>, default: Address) -> Vec<Address> {
|
||||
if let Some(position) = addresses.iter().position(|address| address == &default) {
|
||||
addresses.swap(0, position);
|
||||
} else {
|
||||
addresses.insert(0, default);
|
||||
}
|
||||
|
||||
addresses
|
||||
}
|
||||
|
||||
/// Returns a list of accounts that new dapp should see.
|
||||
/// First account is always the default account.
|
||||
fn new_dapps_addresses_list(&self) -> Result<Vec<Address>, Error> {
|
||||
match self.dapps_settings.read().policy() {
|
||||
NewDappsPolicy::AllAccounts { default } => if default.is_zero() {
|
||||
self.accounts()
|
||||
} else {
|
||||
Ok(Self::insert_default(self.accounts()?, default))
|
||||
},
|
||||
NewDappsPolicy::Whitelist(accounts) => {
|
||||
let addresses = self.filter_addresses(accounts)?;
|
||||
if addresses.is_empty() {
|
||||
Ok(vec![self.accounts()?.get(0).cloned().unwrap_or(0.into())])
|
||||
} else {
|
||||
Ok(addresses)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a default account for new dapps
|
||||
/// Will return zero address in case the default is not set and there are no accounts configured.
|
||||
pub fn new_dapps_default_address(&self) -> Result<Address, Error> {
|
||||
Ok(self.new_dapps_addresses_list()?
|
||||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(0.into())
|
||||
)
|
||||
}
|
||||
|
||||
/// Gets a list of dapps recently requesting accounts.
|
||||
pub fn recent_dapps(&self) -> Result<HashMap<DappId, u64>, Error> {
|
||||
Ok(self.dapps_settings.read().recent_dapps())
|
||||
}
|
||||
|
||||
/// Marks dapp as recently used.
|
||||
pub fn note_dapp_used(&self, dapp: DappId) -> Result<(), Error> {
|
||||
let mut dapps = self.dapps_settings.write();
|
||||
dapps.mark_dapp_used(dapp.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets addresses visible for given dapp.
|
||||
pub fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<Address>, Error> {
|
||||
let accounts = self.dapps_settings.read().settings().get(&dapp).map(|settings| {
|
||||
(settings.accounts.clone(), settings.default.clone())
|
||||
});
|
||||
|
||||
match accounts {
|
||||
Some((Some(accounts), Some(default))) => self.filter_addresses(Self::insert_default(accounts, default)),
|
||||
Some((Some(accounts), None)) => self.filter_addresses(accounts),
|
||||
Some((None, Some(default))) => self.filter_addresses(Self::insert_default(self.new_dapps_addresses_list()?, default)),
|
||||
_ => self.new_dapps_addresses_list(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns default account for particular dapp falling back to other allowed accounts if necessary.
|
||||
pub fn dapp_default_address(&self, dapp: DappId) -> Result<Address, Error> {
|
||||
let dapp_default = self.dapp_addresses(dapp)?
|
||||
.get(0)
|
||||
.cloned();
|
||||
|
||||
match dapp_default {
|
||||
Some(default) => Ok(default),
|
||||
None => self.new_dapps_default_address(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets default address for given dapp.
|
||||
/// Does not alter dapp addresses, but this account will always be returned as the first one.
|
||||
pub fn set_dapp_default_address(&self, dapp: DappId, address: Address) -> Result<(), Error> {
|
||||
if !self.valid_addresses()?.contains(&address) {
|
||||
return Err(SSError::InvalidAccount.into());
|
||||
}
|
||||
|
||||
self.dapps_settings.write().set_default(dapp, address);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sets addresses visible for given dapp.
|
||||
/// If `None` - falls back to dapps addresses
|
||||
/// If not `None` and not empty it will also override default account.
|
||||
pub fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<Address>>) -> Result<(), Error> {
|
||||
let (addresses, default) = match addresses {
|
||||
Some(addresses) => {
|
||||
let addresses = self.filter_addresses(addresses)?;
|
||||
let default = addresses.get(0).cloned();
|
||||
(Some(addresses), default)
|
||||
},
|
||||
None => (None, None),
|
||||
};
|
||||
|
||||
let mut settings = self.dapps_settings.write();
|
||||
if let Some(default) = default {
|
||||
settings.set_default(dapp.clone(), default);
|
||||
}
|
||||
settings.set_accounts(dapp, addresses);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn valid_addresses(&self) -> Result<HashSet<Address>, Error> {
|
||||
Ok(self.addresses_info().into_iter()
|
||||
.map(|(address, _)| address)
|
||||
.chain(self.accounts()?)
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Removes addresses that are neither accounts nor in address book.
|
||||
fn filter_addresses(&self, addresses: Vec<Address>) -> Result<Vec<Address>, Error> {
|
||||
let valid = self.valid_addresses()?;
|
||||
|
||||
Ok(addresses.into_iter()
|
||||
.filter(|a| valid.contains(&a))
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns each address along with metadata.
|
||||
pub fn addresses_info(&self) -> HashMap<Address, AccountMeta> {
|
||||
self.address_book.read().get()
|
||||
@ -849,7 +667,7 @@ impl AccountProvider {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{AccountProvider, Unlock, DappId};
|
||||
use super::{AccountProvider, Unlock};
|
||||
use std::time::{Duration, Instant};
|
||||
use ethstore::ethkey::{Generator, Random, Address};
|
||||
use ethstore::{StoreAccountRef, Derivation};
|
||||
@ -977,96 +795,6 @@ mod tests {
|
||||
assert!(ap.sign_with_token(kp.address(), token, Default::default()).is_err(), "Second usage of the same token should fail.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_reset_dapp_addresses_to_default() {
|
||||
// given
|
||||
let ap = AccountProvider::transient_provider();
|
||||
let app = DappId("app1".into());
|
||||
// add accounts to address book
|
||||
ap.set_address_name(1.into(), "1".into());
|
||||
ap.set_address_name(2.into(), "2".into());
|
||||
// set `AllAccounts` policy
|
||||
ap.set_new_dapps_addresses(Some(vec![1.into(), 2.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||
|
||||
// Alter and check
|
||||
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 3.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
|
||||
|
||||
// Reset back to default
|
||||
ap.set_dapp_addresses(app.clone(), None).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_set_dapps_default_address() {
|
||||
// given
|
||||
let ap = AccountProvider::transient_provider();
|
||||
let app = DappId("app1".into());
|
||||
// set `AllAccounts` policy
|
||||
ap.set_new_dapps_addresses(None).unwrap();
|
||||
// add accounts to address book
|
||||
ap.set_address_name(1.into(), "1".into());
|
||||
ap.set_address_name(2.into(), "2".into());
|
||||
|
||||
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 2.into(), 3.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||
|
||||
// when setting empty list
|
||||
ap.set_dapp_addresses(app.clone(), Some(vec![])).unwrap();
|
||||
|
||||
// then default account is intact
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||
|
||||
// alter default account
|
||||
ap.set_dapp_default_address("app1".into(), 2.into()).unwrap();
|
||||
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![2.into()]);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 2.into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_set_dapps_policy_and_default_account() {
|
||||
// given
|
||||
let ap = AccountProvider::transient_provider();
|
||||
|
||||
// default_account should be always available
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), 0.into());
|
||||
|
||||
let address = ap.new_account(&"test".into()).unwrap();
|
||||
ap.set_address_name(1.into(), "1".into());
|
||||
|
||||
// Default account set to first account by default
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
|
||||
|
||||
// Even when returning nothing
|
||||
ap.set_new_dapps_addresses(Some(vec![])).unwrap();
|
||||
// Default account is still returned
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||
|
||||
// change to all
|
||||
ap.set_new_dapps_addresses(None).unwrap();
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||
|
||||
// change to non-existent account
|
||||
ap.set_new_dapps_addresses(Some(vec![2.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||
|
||||
// change to a addresses
|
||||
ap.set_new_dapps_addresses(Some(vec![1.into()])).unwrap();
|
||||
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![1.into()]);
|
||||
|
||||
// it overrides default account
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), 1.into());
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||
|
||||
ap.set_new_dapps_default_address(address).unwrap();
|
||||
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
|
||||
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_return_blacklisted_account() {
|
||||
// given
|
||||
|
@ -14,21 +14,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Address Book and Dapps Settings Store
|
||||
//! Address Book Store
|
||||
|
||||
use std::{fs, fmt, hash, ops};
|
||||
use std::sync::atomic::{self, AtomicUsize};
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use ethstore::ethkey::Address;
|
||||
use ethjson::misc::{
|
||||
AccountMeta,
|
||||
DappsSettings as JsonSettings,
|
||||
DappsHistory as JsonDappsHistory,
|
||||
NewDappsPolicy as JsonNewDappsPolicy,
|
||||
};
|
||||
use account_provider::DappId;
|
||||
use ethjson::misc::AccountMeta;
|
||||
|
||||
/// Disk-backed map from Address to String. Uses JSON.
|
||||
pub struct AddressBook {
|
||||
@ -88,214 +81,6 @@ impl AddressBook {
|
||||
}
|
||||
}
|
||||
|
||||
/// Dapps user settings
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
pub struct DappsSettings {
|
||||
/// A list of visible accounts
|
||||
pub accounts: Option<Vec<Address>>,
|
||||
/// Default account
|
||||
pub default: Option<Address>,
|
||||
}
|
||||
|
||||
impl From<JsonSettings> for DappsSettings {
|
||||
fn from(s: JsonSettings) -> Self {
|
||||
DappsSettings {
|
||||
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
|
||||
default: s.default.map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DappsSettings> for JsonSettings {
|
||||
fn from(s: DappsSettings) -> Self {
|
||||
JsonSettings {
|
||||
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
|
||||
default: s.default.map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dapps user settings
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum NewDappsPolicy {
|
||||
AllAccounts {
|
||||
default: Address,
|
||||
},
|
||||
Whitelist(Vec<Address>),
|
||||
}
|
||||
|
||||
impl From<JsonNewDappsPolicy> for NewDappsPolicy {
|
||||
fn from(s: JsonNewDappsPolicy) -> Self {
|
||||
match s {
|
||||
JsonNewDappsPolicy::AllAccounts { default } => NewDappsPolicy::AllAccounts {
|
||||
default: default.into(),
|
||||
},
|
||||
JsonNewDappsPolicy::Whitelist(accounts) => NewDappsPolicy::Whitelist(
|
||||
accounts.into_iter().map(Into::into).collect()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NewDappsPolicy> for JsonNewDappsPolicy {
|
||||
fn from(s: NewDappsPolicy) -> Self {
|
||||
match s {
|
||||
NewDappsPolicy::AllAccounts { default } => JsonNewDappsPolicy::AllAccounts {
|
||||
default: default.into(),
|
||||
},
|
||||
NewDappsPolicy::Whitelist(accounts) => JsonNewDappsPolicy::Whitelist(
|
||||
accounts.into_iter().map(Into::into).collect()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transient dapps data
|
||||
#[derive(Default, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct TransientDappsData {
|
||||
/// Timestamp of last access
|
||||
pub last_accessed: u64,
|
||||
}
|
||||
|
||||
impl From<JsonDappsHistory> for TransientDappsData {
|
||||
fn from(s: JsonDappsHistory) -> Self {
|
||||
TransientDappsData {
|
||||
last_accessed: s.last_accessed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransientDappsData> for JsonDappsHistory {
|
||||
fn from(s: TransientDappsData) -> Self {
|
||||
JsonDappsHistory {
|
||||
last_accessed: s.last_accessed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TimeProvider {
|
||||
Clock,
|
||||
Incremenetal(AtomicUsize)
|
||||
}
|
||||
|
||||
impl TimeProvider {
|
||||
fn get(&self) -> u64 {
|
||||
match *self {
|
||||
TimeProvider::Clock => {
|
||||
::std::time::UNIX_EPOCH.elapsed()
|
||||
.expect("Correct time is required to be set")
|
||||
.as_secs()
|
||||
|
||||
},
|
||||
TimeProvider::Incremenetal(ref time) => {
|
||||
time.fetch_add(1, atomic::Ordering::SeqCst) as u64
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_RECENT_DAPPS: usize = 50;
|
||||
|
||||
/// Disk-backed map from DappId to Settings. Uses JSON.
|
||||
pub struct DappsSettingsStore {
|
||||
/// Dapps Settings
|
||||
settings: DiskMap<DappId, DappsSettings>,
|
||||
/// New Dapps Policy
|
||||
policy: DiskMap<String, NewDappsPolicy>,
|
||||
/// Transient Data of recently Accessed Dapps
|
||||
history: DiskMap<DappId, TransientDappsData>,
|
||||
/// Time
|
||||
time: TimeProvider,
|
||||
}
|
||||
|
||||
impl DappsSettingsStore {
|
||||
/// Creates new store at given directory path.
|
||||
pub fn new(path: &Path) -> Self {
|
||||
let mut r = DappsSettingsStore {
|
||||
settings: DiskMap::new(path, "dapps_accounts.json".into()),
|
||||
policy: DiskMap::new(path, "dapps_policy.json".into()),
|
||||
history: DiskMap::new(path, "dapps_history.json".into()),
|
||||
time: TimeProvider::Clock,
|
||||
};
|
||||
r.settings.revert(JsonSettings::read);
|
||||
r.policy.revert(JsonNewDappsPolicy::read);
|
||||
r.history.revert(JsonDappsHistory::read);
|
||||
r
|
||||
}
|
||||
|
||||
/// Creates transient store (no changes are saved to disk).
|
||||
pub fn transient() -> Self {
|
||||
DappsSettingsStore {
|
||||
settings: DiskMap::transient(),
|
||||
policy: DiskMap::transient(),
|
||||
history: DiskMap::transient(),
|
||||
time: TimeProvider::Incremenetal(AtomicUsize::new(1)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get copy of the dapps settings
|
||||
pub fn settings(&self) -> HashMap<DappId, DappsSettings> {
|
||||
self.settings.clone()
|
||||
}
|
||||
|
||||
/// Returns current new dapps policy
|
||||
pub fn policy(&self) -> NewDappsPolicy {
|
||||
self.policy.get("default").cloned().unwrap_or(NewDappsPolicy::AllAccounts {
|
||||
default: 0.into(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns recent dapps with last accessed timestamp
|
||||
pub fn recent_dapps(&self) -> HashMap<DappId, u64> {
|
||||
self.history.iter().map(|(k, v)| (k.clone(), v.last_accessed)).collect()
|
||||
}
|
||||
|
||||
/// Marks recent dapp as used
|
||||
pub fn mark_dapp_used(&mut self, dapp: DappId) {
|
||||
{
|
||||
let entry = self.history.entry(dapp).or_insert_with(|| Default::default());
|
||||
entry.last_accessed = self.time.get();
|
||||
}
|
||||
// Clear extraneous entries
|
||||
while self.history.len() > MAX_RECENT_DAPPS {
|
||||
let min = self.history.iter()
|
||||
.min_by_key(|&(_, ref v)| v.last_accessed)
|
||||
.map(|(ref k, _)| k.clone())
|
||||
.cloned();
|
||||
|
||||
match min {
|
||||
Some(k) => self.history.remove(&k),
|
||||
None => break,
|
||||
};
|
||||
}
|
||||
self.history.save(JsonDappsHistory::write);
|
||||
}
|
||||
|
||||
/// Sets current new dapps policy
|
||||
pub fn set_policy(&mut self, policy: NewDappsPolicy) {
|
||||
self.policy.insert("default".into(), policy);
|
||||
self.policy.save(JsonNewDappsPolicy::write);
|
||||
}
|
||||
|
||||
/// Sets accounts for specific dapp.
|
||||
pub fn set_accounts(&mut self, id: DappId, accounts: Option<Vec<Address>>) {
|
||||
{
|
||||
let settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
settings.accounts = accounts;
|
||||
}
|
||||
self.settings.save(JsonSettings::write);
|
||||
}
|
||||
|
||||
/// Sets a default account for specific dapp.
|
||||
pub fn set_default(&mut self, id: DappId, default: Address) {
|
||||
{
|
||||
let settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
settings.default = Some(default);
|
||||
}
|
||||
self.settings.save(JsonSettings::write);
|
||||
}
|
||||
}
|
||||
|
||||
/// Disk-serializable HashMap
|
||||
#[derive(Debug)]
|
||||
struct DiskMap<K: hash::Hash + Eq, V> {
|
||||
@ -366,8 +151,7 @@ impl<K: hash::Hash + Eq, V> DiskMap<K, V> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{AddressBook, DappsSettingsStore, DappsSettings, NewDappsPolicy};
|
||||
use account_provider::DappId;
|
||||
use super::AddressBook;
|
||||
use std::collections::HashMap;
|
||||
use ethjson::misc::AccountMeta;
|
||||
use tempdir::TempDir;
|
||||
@ -398,63 +182,4 @@ mod tests {
|
||||
3.into() => AccountMeta{name: "Three".to_owned(), meta: "{}".to_owned(), uuid: None}
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_save_and_reload_dapps_settings() {
|
||||
// given
|
||||
let tempdir = TempDir::new("").unwrap();
|
||||
let mut b = DappsSettingsStore::new(tempdir.path());
|
||||
|
||||
// when
|
||||
b.set_accounts("dappOne".into(), Some(vec![1.into(), 2.into()]));
|
||||
|
||||
// then
|
||||
let b = DappsSettingsStore::new(tempdir.path());
|
||||
assert_eq!(b.settings(), hash_map![
|
||||
"dappOne".into() => DappsSettings {
|
||||
accounts: Some(vec![1.into(), 2.into()]),
|
||||
default: None,
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_maintain_a_map_of_recent_dapps() {
|
||||
let mut store = DappsSettingsStore::transient();
|
||||
assert!(store.recent_dapps().is_empty(), "Initially recent dapps should be empty.");
|
||||
|
||||
let dapp1: DappId = "dapp1".into();
|
||||
let dapp2: DappId = "dapp2".into();
|
||||
store.mark_dapp_used(dapp1.clone());
|
||||
let recent = store.recent_dapps();
|
||||
assert_eq!(recent.len(), 1);
|
||||
assert_eq!(recent.get(&dapp1), Some(&1));
|
||||
|
||||
store.mark_dapp_used(dapp2.clone());
|
||||
let recent = store.recent_dapps();
|
||||
assert_eq!(recent.len(), 2);
|
||||
assert_eq!(recent.get(&dapp1), Some(&1));
|
||||
assert_eq!(recent.get(&dapp2), Some(&2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_store_dapps_policy() {
|
||||
// given
|
||||
let tempdir = TempDir::new("").unwrap();
|
||||
let mut store = DappsSettingsStore::new(tempdir.path());
|
||||
|
||||
// Test default policy
|
||||
assert_eq!(store.policy(), NewDappsPolicy::AllAccounts {
|
||||
default: 0.into(),
|
||||
});
|
||||
|
||||
// when
|
||||
store.set_policy(NewDappsPolicy::Whitelist(vec![1.into(), 2.into()]));
|
||||
|
||||
// then
|
||||
let store = DappsSettingsStore::new(tempdir.path());
|
||||
assert_eq!(store.policy.clone(), hash_map![
|
||||
"default".into() => NewDappsPolicy::Whitelist(vec![1.into(), 2.into()])
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ use encoded;
|
||||
use engines::epoch::{Transition as EpochTransition, PendingTransition as PendingEpochTransition};
|
||||
use engines::ForkChoice;
|
||||
use ethereum_types::{H256, Bloom, BloomRef, U256};
|
||||
use error::Error as EthcoreError;
|
||||
use header::*;
|
||||
use heapsize::HeapSizeOf;
|
||||
use itertools::Itertools;
|
||||
@ -60,6 +61,21 @@ pub trait BlockChainDB: Send + Sync {
|
||||
|
||||
/// Trace blooms database.
|
||||
fn trace_blooms(&self) -> &blooms_db::Database;
|
||||
|
||||
/// Restore the DB from the given path
|
||||
fn restore(&self, new_db: &str) -> Result<(), EthcoreError> {
|
||||
// First, close the Blooms databases
|
||||
self.blooms().close()?;
|
||||
self.trace_blooms().close()?;
|
||||
|
||||
// Restore the key_value DB
|
||||
self.key_value().restore(new_db)?;
|
||||
|
||||
// Re-open the Blooms databases
|
||||
self.blooms().reopen()?;
|
||||
self.trace_blooms().reopen()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Generic database handler. This trait contains one function `open`. When called, it opens database with a
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::{HashSet, BTreeMap, VecDeque};
|
||||
use std::fmt;
|
||||
use std::cmp;
|
||||
use std::str::FromStr;
|
||||
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
||||
use std::sync::{Arc, Weak};
|
||||
@ -50,13 +50,16 @@ use client::{
|
||||
};
|
||||
use encoded;
|
||||
use engines::{EthEngine, EpochTransition, ForkChoice};
|
||||
use error::{ImportErrorKind, BlockImportErrorKind, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError};
|
||||
use error::{
|
||||
ImportErrorKind, BlockImportErrorKind, ExecutionError, CallError, BlockError, ImportResult,
|
||||
QueueError, QueueErrorKind, Error as EthcoreError
|
||||
};
|
||||
use vm::{EnvInfo, LastHashes};
|
||||
use evm::Schedule;
|
||||
use executive::{Executive, Executed, TransactOptions, contract_address};
|
||||
use factory::{Factories, VmFactory};
|
||||
use header::{BlockNumber, Header, ExtendedHeader};
|
||||
use io::{IoChannel, IoError};
|
||||
use io::IoChannel;
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use miner::{Miner, MinerService};
|
||||
use ethcore_miner::pool::VerifiedTransaction;
|
||||
@ -200,7 +203,7 @@ pub struct Client {
|
||||
|
||||
/// Flag changed by `sleep` and `wake_up` methods. Not to be confused with `enabled`.
|
||||
liveness: AtomicBool,
|
||||
io_channel: Mutex<IoChannel<ClientIoMessage>>,
|
||||
io_channel: RwLock<IoChannel<ClientIoMessage>>,
|
||||
|
||||
/// List of actors to be notified on certain chain events
|
||||
notify: RwLock<Vec<Weak<ChainNotify>>>,
|
||||
@ -761,7 +764,7 @@ impl Client {
|
||||
db: RwLock::new(db.clone()),
|
||||
state_db: RwLock::new(state_db),
|
||||
report: RwLock::new(Default::default()),
|
||||
io_channel: Mutex::new(message_channel),
|
||||
io_channel: RwLock::new(message_channel),
|
||||
notify: RwLock::new(Vec::new()),
|
||||
queue_transactions: IoChannelQueue::new(config.transaction_verification_queue_size),
|
||||
queue_ancient_blocks: IoChannelQueue::new(MAX_ANCIENT_BLOCKS_QUEUE_SIZE),
|
||||
@ -995,7 +998,7 @@ impl Client {
|
||||
|
||||
/// Replace io channel. Useful for testing.
|
||||
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
|
||||
*self.io_channel.lock() = io_channel;
|
||||
*self.io_channel.write() = io_channel;
|
||||
}
|
||||
|
||||
/// Get a copy of the best block's state.
|
||||
@ -1293,9 +1296,7 @@ impl snapshot::DatabaseRestore for Client {
|
||||
let mut tracedb = self.tracedb.write();
|
||||
self.importer.miner.clear();
|
||||
let db = self.db.write();
|
||||
db.key_value().restore(new_db)?;
|
||||
db.blooms().reopen()?;
|
||||
db.trace_blooms().reopen()?;
|
||||
db.restore(new_db)?;
|
||||
|
||||
let cache_size = state_db.cache_size();
|
||||
*state_db = StateDB::new(journaldb::new(db.key_value().clone(), self.pruning, ::db::COL_STATE), cache_size);
|
||||
@ -1952,7 +1953,25 @@ impl BlockChainClient for Client {
|
||||
(*self.build_last_hashes(&self.chain.read().best_block_hash())).clone()
|
||||
}
|
||||
|
||||
fn ready_transactions(&self, max_len: usize) -> Vec<Arc<VerifiedTransaction>> {
|
||||
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>> {
|
||||
const PROPAGATE_FOR_BLOCKS: u32 = 4;
|
||||
const MIN_TX_TO_PROPAGATE: usize = 256;
|
||||
|
||||
let block_gas_limit = *self.best_block_header().gas_limit();
|
||||
let min_tx_gas: U256 = self.latest_schedule().tx_gas.into();
|
||||
|
||||
let max_len = if min_tx_gas.is_zero() {
|
||||
usize::max_value()
|
||||
} else {
|
||||
cmp::max(
|
||||
MIN_TX_TO_PROPAGATE,
|
||||
cmp::min(
|
||||
(block_gas_limit / min_tx_gas) * PROPAGATE_FOR_BLOCKS,
|
||||
// never more than usize
|
||||
usize::max_value().into()
|
||||
).as_u64() as usize
|
||||
)
|
||||
};
|
||||
self.importer.miner.ready_transactions(self, max_len, ::miner::PendingOrdering::Priority)
|
||||
}
|
||||
|
||||
@ -2011,7 +2030,7 @@ impl IoClient for Client {
|
||||
fn queue_transactions(&self, transactions: Vec<Bytes>, peer_id: usize) {
|
||||
trace_time!("queue_transactions");
|
||||
let len = transactions.len();
|
||||
self.queue_transactions.queue(&mut self.io_channel.lock(), len, move |client| {
|
||||
self.queue_transactions.queue(&self.io_channel.read(), len, move |client| {
|
||||
trace_time!("import_queued_transactions");
|
||||
|
||||
let txs: Vec<UnverifiedTransaction> = transactions
|
||||
@ -2060,7 +2079,7 @@ impl IoClient for Client {
|
||||
|
||||
let queued = self.queued_ancient_blocks.clone();
|
||||
let lock = self.ancient_blocks_import_lock.clone();
|
||||
match self.queue_ancient_blocks.queue(&mut self.io_channel.lock(), 1, move |client| {
|
||||
self.queue_ancient_blocks.queue(&self.io_channel.read(), 1, move |client| {
|
||||
trace_time!("import_ancient_block");
|
||||
// Make sure to hold the lock here to prevent importing out of order.
|
||||
// We use separate lock, cause we don't want to block queueing.
|
||||
@ -2085,14 +2104,13 @@ impl IoClient for Client {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Ok(_) => Ok(hash),
|
||||
Err(e) => bail!(BlockImportErrorKind::Other(format!("{}", e))),
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(hash)
|
||||
}
|
||||
|
||||
fn queue_consensus_message(&self, message: Bytes) {
|
||||
match self.queue_consensus_message.queue(&mut self.io_channel.lock(), 1, move |client| {
|
||||
match self.queue_consensus_message.queue(&self.io_channel.read(), 1, move |client| {
|
||||
if let Err(e) = client.engine().handle_message(&message) {
|
||||
debug!(target: "poa", "Invalid message received: {}", e);
|
||||
}
|
||||
@ -2202,7 +2220,14 @@ impl ImportSealedBlock for Client {
|
||||
route
|
||||
};
|
||||
let route = ChainRoute::from([route].as_ref());
|
||||
self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), self.engine.seals_internally().is_some());
|
||||
self.importer.miner.chain_new_blocks(
|
||||
self,
|
||||
&[h.clone()],
|
||||
&[],
|
||||
route.enacted(),
|
||||
route.retracted(),
|
||||
self.engine.seals_internally().is_some(),
|
||||
);
|
||||
self.notify(|notify| {
|
||||
notify.new_blocks(
|
||||
vec![h.clone()],
|
||||
@ -2497,21 +2522,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum QueueError {
|
||||
Channel(IoError),
|
||||
Full(usize),
|
||||
}
|
||||
|
||||
impl fmt::Display for QueueError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
QueueError::Channel(ref c) => fmt::Display::fmt(c, fmt),
|
||||
QueueError::Full(limit) => write!(fmt, "The queue is full ({})", limit),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Queue some items to be processed by IO client.
|
||||
struct IoChannelQueue {
|
||||
currently_queued: Arc<AtomicUsize>,
|
||||
@ -2526,11 +2536,11 @@ impl IoChannelQueue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn queue<F>(&self, channel: &mut IoChannel<ClientIoMessage>, count: usize, fun: F) -> Result<(), QueueError> where
|
||||
pub fn queue<F>(&self, channel: &IoChannel<ClientIoMessage>, count: usize, fun: F) -> Result<(), QueueError> where
|
||||
F: Fn(&Client) + Send + Sync + 'static,
|
||||
{
|
||||
let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed);
|
||||
ensure!(queue_size < self.limit, QueueError::Full(self.limit));
|
||||
ensure!(queue_size < self.limit, QueueErrorKind::Full(self.limit));
|
||||
|
||||
let currently_queued = self.currently_queued.clone();
|
||||
let result = channel.send(ClientIoMessage::execute(move |client| {
|
||||
@ -2543,7 +2553,7 @@ impl IoChannelQueue {
|
||||
self.currently_queued.fetch_add(count, AtomicOrdering::SeqCst);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(QueueError::Channel(e)),
|
||||
Err(e) => bail!(QueueErrorKind::Channel(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -805,8 +805,8 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
self.traces.read().clone()
|
||||
}
|
||||
|
||||
fn ready_transactions(&self, max_len: usize) -> Vec<Arc<VerifiedTransaction>> {
|
||||
self.miner.ready_transactions(self, max_len, miner::PendingOrdering::Priority)
|
||||
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>> {
|
||||
self.miner.ready_transactions(self, 4096, miner::PendingOrdering::Priority)
|
||||
}
|
||||
|
||||
fn signing_chain_id(&self) -> Option<u64> { None }
|
||||
|
@ -320,8 +320,8 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra
|
||||
/// Get last hashes starting from best block.
|
||||
fn last_hashes(&self) -> LastHashes;
|
||||
|
||||
/// List all transactions that are allowed into the next block.
|
||||
fn ready_transactions(&self, max_len: usize) -> Vec<Arc<VerifiedTransaction>>;
|
||||
/// List all ready transactions that should be propagated to other peers.
|
||||
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>>;
|
||||
|
||||
/// Sorted list of transaction gas prices from at least last sample_size blocks.
|
||||
fn gas_price_corpus(&self, sample_size: usize) -> ::stats::Corpus<U256> {
|
||||
|
@ -984,8 +984,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
self.clear_empty_steps(parent_step);
|
||||
|
||||
// report any skipped primaries between the parent block and
|
||||
// the block we're sealing
|
||||
self.report_skipped(header, step, u64::from(parent_step) as usize, &*validators, set_number);
|
||||
// the block we're sealing, unless we have empty steps enabled
|
||||
if header.number() < self.empty_steps_transition {
|
||||
self.report_skipped(header, step, u64::from(parent_step) as usize, &*validators, set_number);
|
||||
}
|
||||
|
||||
let mut fields = vec![
|
||||
encode(&step).into_vec(),
|
||||
@ -1149,9 +1151,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
|
||||
// If empty step messages are enabled we will validate the messages in the seal, missing messages are not
|
||||
// reported as there's no way to tell whether the empty step message was never sent or simply not included.
|
||||
if header.number() >= self.empty_steps_transition {
|
||||
let validate_empty_steps = || -> Result<(), Error> {
|
||||
let empty_steps_len = if header.number() >= self.empty_steps_transition {
|
||||
let validate_empty_steps = || -> Result<usize, Error> {
|
||||
let empty_steps = header_empty_steps(header)?;
|
||||
let empty_steps_len = empty_steps.len();
|
||||
for empty_step in empty_steps {
|
||||
if empty_step.step <= parent_step || empty_step.step >= step {
|
||||
Err(EngineError::InsufficientProof(
|
||||
@ -1168,16 +1171,27 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
format!("invalid empty step proof: {:?}", empty_step)))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
Ok(empty_steps_len)
|
||||
};
|
||||
|
||||
if let err @ Err(_) = validate_empty_steps() {
|
||||
self.validators.report_benign(header.author(), set_number, header.number());
|
||||
return err;
|
||||
match validate_empty_steps() {
|
||||
Ok(len) => len,
|
||||
Err(err) => {
|
||||
self.validators.report_benign(header.author(), set_number, header.number());
|
||||
return Err(err);
|
||||
},
|
||||
}
|
||||
|
||||
} else {
|
||||
self.report_skipped(header, step, parent_step, &*validators, set_number);
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
if header.number() >= self.validate_score_transition {
|
||||
let expected_difficulty = calculate_score(parent_step.into(), step.into(), empty_steps_len.into());
|
||||
if header.difficulty() != &expected_difficulty {
|
||||
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() })));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1412,7 +1426,7 @@ mod tests {
|
||||
use engines::{Seal, Engine, EngineError, EthEngine};
|
||||
use engines::validator_set::TestSet;
|
||||
use error::{Error, ErrorKind};
|
||||
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep};
|
||||
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
|
||||
|
||||
#[test]
|
||||
fn has_valid_metadata() {
|
||||
@ -1518,12 +1532,15 @@ mod tests {
|
||||
|
||||
let engine = Spec::new_test_round().engine;
|
||||
|
||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||
// Two validators.
|
||||
// Spec starts with step 2.
|
||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(2), U256::zero()));
|
||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||
header.set_seal(vec![encode(&2usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||
assert!(engine.verify_block_external(&header).is_err());
|
||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(1), U256::zero()));
|
||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||
assert!(engine.verify_block_external(&header).is_ok());
|
||||
@ -1544,9 +1561,10 @@ mod tests {
|
||||
|
||||
let engine = Spec::new_test_round().engine;
|
||||
|
||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||
// Two validators.
|
||||
// Spec starts with step 2.
|
||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(1), U256::zero()));
|
||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||
assert!(engine.verify_block_external(&header).is_ok());
|
||||
@ -1573,8 +1591,10 @@ mod tests {
|
||||
// Two validators.
|
||||
// Spec starts with step 2.
|
||||
header.set_seal(vec![encode(&5usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||
header.set_difficulty(calculate_score(U256::from(4), U256::from(5), U256::zero()));
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||
header.set_seal(vec![encode(&3usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||
header.set_difficulty(calculate_score(U256::from(4), U256::from(3), U256::zero()));
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_err());
|
||||
}
|
||||
|
||||
@ -1608,6 +1628,7 @@ mod tests {
|
||||
parent_header.set_seal(vec![encode(&1usize).into_vec()]);
|
||||
parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
|
||||
let mut header: Header = Header::default();
|
||||
header.set_difficulty(calculate_score(U256::from(1), U256::from(3), U256::zero()));
|
||||
header.set_gas_limit("222222".parse::<U256>().unwrap());
|
||||
header.set_seal(vec![encode(&3usize).into_vec()]);
|
||||
|
||||
@ -1967,16 +1988,15 @@ mod tests {
|
||||
let empty_step3 = sealed_empty_step(engine, 3, &parent_header.hash());
|
||||
|
||||
let empty_steps = vec![empty_step2, empty_step3];
|
||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(4), U256::from(2)));
|
||||
let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap();
|
||||
header.set_seal(vec![
|
||||
encode(&4usize).into_vec(),
|
||||
encode(&(&*signature as &[u8])).into_vec(),
|
||||
::rlp::encode_list(&empty_steps).into_vec(),
|
||||
]);
|
||||
|
||||
assert!(match engine.verify_block_family(&header, &parent_header) {
|
||||
Ok(_) => true,
|
||||
_ => false,
|
||||
});
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -151,6 +151,24 @@ impl error::Error for BlockError {
|
||||
}
|
||||
}
|
||||
|
||||
error_chain! {
|
||||
types {
|
||||
QueueError, QueueErrorKind, QueueErrorResultExt, QueueErrorResult;
|
||||
}
|
||||
|
||||
errors {
|
||||
#[doc = "Queue is full"]
|
||||
Full(limit: usize) {
|
||||
description("Queue is full")
|
||||
display("The queue is full ({})", limit)
|
||||
}
|
||||
}
|
||||
|
||||
foreign_links {
|
||||
Channel(IoError) #[doc = "Io channel error"];
|
||||
}
|
||||
}
|
||||
|
||||
error_chain! {
|
||||
types {
|
||||
ImportError, ImportErrorKind, ImportErrorResultExt, ImportErrorResult;
|
||||
@ -184,6 +202,7 @@ error_chain! {
|
||||
|
||||
links {
|
||||
Import(ImportError, ImportErrorKind) #[doc = "Import error"];
|
||||
Queue(QueueError, QueueErrorKind) #[doc = "Io channel queue error"];
|
||||
}
|
||||
|
||||
foreign_links {
|
||||
|
@ -20,7 +20,7 @@ use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use hash::{KECCAK_EMPTY_LIST_RLP};
|
||||
use engines::block_reward::{self, RewardKind};
|
||||
use ethash::{quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
|
||||
use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
|
||||
use ethereum_types::{H256, H64, U256, Address};
|
||||
use unexpected::{OutOfBounds, Mismatch};
|
||||
use block::*;
|
||||
@ -280,11 +280,18 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
block_reward::apply_block_rewards(&rewards, block, &self.machine)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "miner-debug"))]
|
||||
fn verify_local_seal(&self, header: &Header) -> Result<(), Error> {
|
||||
self.verify_block_basic(header)
|
||||
.and_then(|_| self.verify_block_unordered(header))
|
||||
}
|
||||
|
||||
#[cfg(feature = "miner-debug")]
|
||||
fn verify_local_seal(&self, _header: &Header) -> Result<(), Error> {
|
||||
warn!("Skipping seal verification, running in miner testing mode.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_block_basic(&self, header: &Header) -> Result<(), Error> {
|
||||
// check the seal fields.
|
||||
let seal = Seal::parse_seal(header.seal())?;
|
||||
@ -295,7 +302,7 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
return Err(From::from(BlockError::DifficultyOutOfBounds(OutOfBounds { min: Some(min_difficulty), max: None, found: header.difficulty().clone() })))
|
||||
}
|
||||
|
||||
let difficulty = Ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
|
||||
let difficulty = ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
|
||||
&header.bare_hash().0,
|
||||
seal.nonce.low_u64(),
|
||||
&seal.mix_hash.0
|
||||
@ -317,7 +324,7 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
|
||||
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));
|
||||
let difficulty = ethash::boundary_to_difficulty(&H256(result.value));
|
||||
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)),
|
||||
@ -440,25 +447,6 @@ impl Ethash {
|
||||
}
|
||||
target
|
||||
}
|
||||
|
||||
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
|
||||
pub fn boundary_to_difficulty(boundary: &H256) -> U256 {
|
||||
let d = U256::from(*boundary);
|
||||
if d <= U256::one() {
|
||||
U256::max_value()
|
||||
} else {
|
||||
((U256::one() << 255) / d) << 1
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
|
||||
pub fn difficulty_to_boundary(difficulty: &U256) -> H256 {
|
||||
if *difficulty <= U256::one() {
|
||||
U256::max_value().into()
|
||||
} else {
|
||||
(((U256::one() << 255) / *difficulty) << 1).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u64) -> (u64, U256) {
|
||||
@ -759,16 +747,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difficulty_to_boundary() {
|
||||
// result of f(0) is undefined, so do not assert the result
|
||||
let _ = Ethash::difficulty_to_boundary(&U256::from(0));
|
||||
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(1)), H256::from(U256::max_value()));
|
||||
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(2)), H256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(4)), H256::from_str("4000000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn difficulty_frontier() {
|
||||
let machine = new_homestead_test_machine();
|
||||
|
@ -41,31 +41,31 @@ fn load_machine(b: &[u8]) -> EthereumMachine {
|
||||
Spec::load_machine(b).expect("chain spec is invalid")
|
||||
}
|
||||
|
||||
/// Create a new Foundation Olympic chain spec.
|
||||
pub fn new_olympic<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/olympic.json"))
|
||||
}
|
||||
|
||||
/// Create a new Foundation Mainnet chain spec.
|
||||
/// Create a new Foundation mainnet chain spec.
|
||||
pub fn new_foundation<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/foundation.json"))
|
||||
}
|
||||
|
||||
/// Create a new Classic Mainnet chain spec without the DAO hardfork.
|
||||
/// Create a new Classic mainnet chain spec without the DAO hardfork.
|
||||
pub fn new_classic<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/classic.json"))
|
||||
}
|
||||
|
||||
/// Create a new POA Network mainnet chain spec.
|
||||
pub fn new_poanet<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/poacore.json"))
|
||||
}
|
||||
|
||||
/// Create a new Tobalaba mainnet chain spec.
|
||||
pub fn new_tobalaba<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/tobalaba.json"))
|
||||
}
|
||||
|
||||
/// Create a new Expanse mainnet chain spec.
|
||||
pub fn new_expanse<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/expanse.json"))
|
||||
}
|
||||
|
||||
/// Create a new Tobalaba chain spec.
|
||||
pub fn new_tobalaba<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/tobalaba.json"))
|
||||
}
|
||||
|
||||
/// Create a new Musicoin mainnet chain spec.
|
||||
pub fn new_musicoin<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/musicoin.json"))
|
||||
@ -86,19 +86,29 @@ pub fn new_social<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/social.json"))
|
||||
}
|
||||
|
||||
/// Create a new Olympic testnet chain spec.
|
||||
pub fn new_olympic<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/olympic.json"))
|
||||
}
|
||||
|
||||
/// Create a new Morden testnet chain spec.
|
||||
pub fn new_morden<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/morden.json"))
|
||||
}
|
||||
|
||||
/// Create a new Ropsten testnet chain spec.
|
||||
pub fn new_ropsten<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/ropsten.json"))
|
||||
}
|
||||
|
||||
/// Create a new Kovan testnet chain spec.
|
||||
pub fn new_kovan<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/kovan.json"))
|
||||
}
|
||||
|
||||
/// Create a new Foundation Ropsten chain spec.
|
||||
pub fn new_ropsten<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/ropsten.json"))
|
||||
}
|
||||
|
||||
/// Create a new Morden chain spec.
|
||||
pub fn new_morden<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/morden.json"))
|
||||
/// Create a new POA Sokol testnet chain spec.
|
||||
pub fn new_sokol<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||
load(params.into(), include_bytes!("../../res/ethereum/poasokol.json"))
|
||||
}
|
||||
|
||||
// For tests
|
||||
|
@ -28,6 +28,7 @@ use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStat
|
||||
#[cfg(feature = "work-notify")]
|
||||
use ethcore_miner::work_notify::NotifyWork;
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use io::IoChannel;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use rayon::prelude::*;
|
||||
use transaction::{
|
||||
@ -44,7 +45,7 @@ use block::{ClosedBlock, IsBlock, Block, SealedBlock};
|
||||
use client::{
|
||||
BlockChain, ChainInfo, CallContract, BlockProducer, SealedBlockImporter, Nonce
|
||||
};
|
||||
use client::BlockId;
|
||||
use client::{BlockId, ClientIoMessage};
|
||||
use executive::contract_address;
|
||||
use header::{Header, BlockNumber};
|
||||
use miner;
|
||||
@ -96,7 +97,7 @@ const DEFAULT_MINIMAL_GAS_PRICE: u64 = 20_000_000_000;
|
||||
/// before stopping attempts to push more transactions to the block.
|
||||
/// This is an optimization that prevents traversing the entire pool
|
||||
/// in case we have only a fraction of available block gas limit left.
|
||||
const MAX_SKIPPED_TRANSACTIONS: usize = 8;
|
||||
const MAX_SKIPPED_TRANSACTIONS: usize = 128;
|
||||
|
||||
/// Configures the behaviour of the miner.
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -211,6 +212,7 @@ pub struct Miner {
|
||||
transaction_queue: Arc<TransactionQueue>,
|
||||
engine: Arc<EthEngine>,
|
||||
accounts: Option<Arc<AccountProvider>>,
|
||||
io_channel: RwLock<Option<IoChannel<ClientIoMessage>>>,
|
||||
}
|
||||
|
||||
impl Miner {
|
||||
@ -227,7 +229,12 @@ impl Miner {
|
||||
}
|
||||
|
||||
/// Creates new instance of miner Arc.
|
||||
pub fn new(options: MinerOptions, gas_pricer: GasPricer, spec: &Spec, accounts: Option<Arc<AccountProvider>>) -> Self {
|
||||
pub fn new(
|
||||
options: MinerOptions,
|
||||
gas_pricer: GasPricer,
|
||||
spec: &Spec,
|
||||
accounts: Option<Arc<AccountProvider>>,
|
||||
) -> Self {
|
||||
let limits = options.pool_limits.clone();
|
||||
let verifier_options = options.pool_verification_options.clone();
|
||||
let tx_queue_strategy = options.tx_queue_strategy;
|
||||
@ -251,6 +258,7 @@ impl Miner {
|
||||
transaction_queue: Arc::new(TransactionQueue::new(limits, verifier_options, tx_queue_strategy)),
|
||||
accounts,
|
||||
engine: spec.engine.clone(),
|
||||
io_channel: RwLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,6 +278,11 @@ impl Miner {
|
||||
}, GasPricer::new_fixed(minimal_gas_price), spec, accounts)
|
||||
}
|
||||
|
||||
/// Sets `IoChannel`
|
||||
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
|
||||
*self.io_channel.write() = Some(io_channel);
|
||||
}
|
||||
|
||||
/// Clear all pending block states
|
||||
pub fn clear(&self) {
|
||||
self.sealing.lock().queue.reset();
|
||||
@ -293,14 +306,15 @@ impl Miner {
|
||||
/// Retrieves an existing pending block iff it's not older than given block number.
|
||||
///
|
||||
/// NOTE: This will not prepare a new pending block if it's not existing.
|
||||
/// See `map_pending_block` for alternative behaviour.
|
||||
fn map_existing_pending_block<F, T>(&self, f: F, latest_block_number: BlockNumber) -> Option<T> where
|
||||
F: FnOnce(&ClosedBlock) -> T,
|
||||
{
|
||||
self.sealing.lock().queue
|
||||
.peek_last_ref()
|
||||
.and_then(|b| {
|
||||
if b.block().header().number() > latest_block_number {
|
||||
// to prevent a data race between block import and updating pending block
|
||||
// we allow the number to be equal.
|
||||
if b.block().header().number() >= latest_block_number {
|
||||
Some(f(b))
|
||||
} else {
|
||||
None
|
||||
@ -339,7 +353,7 @@ impl Miner {
|
||||
// if at least one was pushed successfully, close and enqueue new ClosedBlock;
|
||||
// otherwise, leave everything alone.
|
||||
// otherwise, author a fresh block.
|
||||
let mut open_block = match sealing.queue.pop_if(|b| b.block().header().parent_hash() == &best_hash) {
|
||||
let mut open_block = match sealing.queue.get_pending_if(|b| b.block().header().parent_hash() == &best_hash) {
|
||||
Some(old_block) => {
|
||||
trace!(target: "miner", "prepare_block: Already have previous work; updating and returning");
|
||||
// add transactions to old_block
|
||||
@ -384,7 +398,7 @@ impl Miner {
|
||||
let max_transactions = if min_tx_gas.is_zero() {
|
||||
usize::max_value()
|
||||
} else {
|
||||
(*open_block.block().header().gas_limit() / min_tx_gas).as_u64() as usize
|
||||
MAX_SKIPPED_TRANSACTIONS.saturating_add(cmp::min(*open_block.block().header().gas_limit() / min_tx_gas, u64::max_value().into()).as_u64() as usize)
|
||||
};
|
||||
|
||||
let pending: Vec<Arc<_>> = self.transaction_queue.pending(
|
||||
@ -589,7 +603,7 @@ impl Miner {
|
||||
{
|
||||
let mut sealing = self.sealing.lock();
|
||||
sealing.next_mandatory_reseal = Instant::now() + self.options.reseal_max_period;
|
||||
sealing.queue.push(block.clone());
|
||||
sealing.queue.set_pending(block.clone());
|
||||
sealing.queue.use_last_ref();
|
||||
}
|
||||
|
||||
@ -651,7 +665,7 @@ impl Miner {
|
||||
);
|
||||
let is_new = original_work_hash.map_or(true, |h| h != block_hash);
|
||||
|
||||
sealing.queue.push(block);
|
||||
sealing.queue.set_pending(block);
|
||||
|
||||
#[cfg(feature = "work-notify")]
|
||||
{
|
||||
@ -1042,10 +1056,12 @@ impl miner::MinerService for Miner {
|
||||
|
||||
// refuse to seal the first block of the chain if it contains hard forks
|
||||
// which should be on by default.
|
||||
if block.block().header().number() == 1 && self.engine.params().contains_bugfix_hard_fork() {
|
||||
warn!("Your chain specification contains one or more hard forks which are required to be \
|
||||
on by default. Please remove these forks and start your chain again.");
|
||||
return;
|
||||
if block.block().header().number() == 1 {
|
||||
if let Some(name) = self.engine.params().nonzero_bugfix_hard_fork() {
|
||||
warn!("Your chain specification contains one or more hard forks which are required to be \
|
||||
on by default. Please remove these forks and start your chain again: {}.", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
match self.engine.seals_internally() {
|
||||
@ -1058,7 +1074,7 @@ impl miner::MinerService for Miner {
|
||||
Some(false) => {
|
||||
trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now");
|
||||
// anyway, save the block for later use
|
||||
self.sealing.lock().queue.push(block);
|
||||
self.sealing.lock().queue.set_pending(block);
|
||||
},
|
||||
None => {
|
||||
trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work");
|
||||
@ -1176,7 +1192,32 @@ impl miner::MinerService for Miner {
|
||||
// (thanks to Ready), but culling can take significant amount of time,
|
||||
// so best to leave it after we create some work for miners to prevent increased
|
||||
// uncle rate.
|
||||
self.transaction_queue.cull(client);
|
||||
// If the io_channel is available attempt to offload culling to a separate task
|
||||
// to avoid blocking chain_new_blocks
|
||||
if let Some(ref channel) = *self.io_channel.read() {
|
||||
let queue = self.transaction_queue.clone();
|
||||
let nonce_cache = self.nonce_cache.clone();
|
||||
let engine = self.engine.clone();
|
||||
let accounts = self.accounts.clone();
|
||||
let refuse_service_transactions = self.options.refuse_service_transactions;
|
||||
|
||||
let cull = move |chain: &::client::Client| {
|
||||
let client = PoolClient::new(
|
||||
chain,
|
||||
&nonce_cache,
|
||||
&*engine,
|
||||
accounts.as_ref().map(|x| &**x),
|
||||
refuse_service_transactions,
|
||||
);
|
||||
queue.cull(client);
|
||||
};
|
||||
|
||||
if let Err(e) = channel.send(ClientIoMessage::execute(cull)) {
|
||||
warn!(target: "miner", "Error queueing cull: {:?}", e);
|
||||
}
|
||||
} else {
|
||||
self.transaction_queue.cull(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,11 @@
|
||||
|
||||
//! Blockchain access for transaction pool.
|
||||
|
||||
use std::fmt;
|
||||
use std::collections::HashMap;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use ethcore_miner::pool;
|
||||
@ -37,9 +40,9 @@ use miner;
|
||||
use miner::service_transaction_checker::ServiceTransactionChecker;
|
||||
|
||||
/// Cache for state nonces.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NonceCache {
|
||||
nonces: RwLock<HashMap<Address, U256>>,
|
||||
nonces: Arc<RwLock<HashMap<Address, U256>>>,
|
||||
limit: usize
|
||||
}
|
||||
|
||||
@ -47,7 +50,7 @@ impl NonceCache {
|
||||
/// Create new cache with a limit of `limit` entries.
|
||||
pub fn new(limit: usize) -> Self {
|
||||
NonceCache {
|
||||
nonces: RwLock::new(HashMap::with_capacity(limit / 2)),
|
||||
nonces: Arc::new(RwLock::new(HashMap::with_capacity(limit / 2))),
|
||||
limit,
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ use std::fmt;
|
||||
|
||||
use client::{Client, ImportSealedBlock};
|
||||
use ethereum_types::{H64, H256, clean_0x, U256};
|
||||
use ethereum::ethash::Ethash;
|
||||
use ethash::SeedHashCompute;
|
||||
use ethash::{self, SeedHashCompute};
|
||||
#[cfg(feature = "work-notify")]
|
||||
use ethcore_miner::work_notify::NotifyWork;
|
||||
#[cfg(feature = "work-notify")]
|
||||
@ -167,7 +166,7 @@ impl StratumJobDispatcher {
|
||||
/// Serializes payload for stratum service
|
||||
fn payload(&self, pow_hash: H256, difficulty: U256, number: u64) -> String {
|
||||
// TODO: move this to engine
|
||||
let target = Ethash::difficulty_to_boundary(&difficulty);
|
||||
let target = ethash::difficulty_to_boundary(&difficulty);
|
||||
let seed_hash = &self.seed_compute.lock().hash_block_number(number);
|
||||
let seed_hash = H256::from_slice(&seed_hash[..]);
|
||||
format!(
|
||||
|
@ -57,7 +57,7 @@ fn fmt_err<F: ::std::fmt::Display>(f: F) -> String {
|
||||
|
||||
/// Parameters common to ethereum-like blockchains.
|
||||
/// NOTE: when adding bugfix hard-fork parameters,
|
||||
/// add to `contains_bugfix_hard_fork`
|
||||
/// add to `nonzero_bugfix_hard_fork`
|
||||
///
|
||||
/// we define a "bugfix" hard fork as any hard fork which
|
||||
/// you would put on-by-default in a new chain.
|
||||
@ -188,13 +188,21 @@ impl CommonParams {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether these params contain any bug-fix hard forks.
|
||||
pub fn contains_bugfix_hard_fork(&self) -> bool {
|
||||
self.eip98_transition != 0 && self.eip155_transition != 0 &&
|
||||
self.validate_receipts_transition != 0 && self.eip86_transition != 0 &&
|
||||
self.eip140_transition != 0 && self.eip210_transition != 0 &&
|
||||
self.eip211_transition != 0 && self.eip214_transition != 0 &&
|
||||
self.validate_chain_id_transition != 0 && self.dust_protection_transition != 0
|
||||
/// Return Some if the current parameters contain a bugfix hard fork not on block 0.
|
||||
pub fn nonzero_bugfix_hard_fork(&self) -> Option<&str> {
|
||||
if self.eip155_transition != 0 {
|
||||
return Some("eip155Transition");
|
||||
}
|
||||
|
||||
if self.validate_receipts_transition != 0 {
|
||||
return Some("validateReceiptsTransition");
|
||||
}
|
||||
|
||||
if self.validate_chain_id_transition != 0 {
|
||||
return Some("validateChainIdTransition");
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,11 +334,11 @@ fn does_not_propagate_delayed_transactions() {
|
||||
|
||||
client.miner().import_own_transaction(&*client, tx0).unwrap();
|
||||
client.miner().import_own_transaction(&*client, tx1).unwrap();
|
||||
assert_eq!(0, client.ready_transactions(10).len());
|
||||
assert_eq!(0, client.transactions_to_propagate().len());
|
||||
assert_eq!(0, client.miner().ready_transactions(&*client, 10, PendingOrdering::Priority).len());
|
||||
push_blocks_to_client(&client, 53, 2, 2);
|
||||
client.flush_queue();
|
||||
assert_eq!(2, client.ready_transactions(10).len());
|
||||
assert_eq!(2, client.transactions_to_propagate().len());
|
||||
assert_eq!(2, client.miner().ready_transactions(&*client, 10, PendingOrdering::Priority).len());
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
[lib]
|
||||
|
||||
[dependencies]
|
||||
common-types = { path = "../types" }
|
||||
parity-bytes = { git = "https://github.com/paritytech/parity-common" }
|
||||
ethcore-network = { path = "../../util/network" }
|
||||
ethcore-network-devp2p = { path = "../../util/network-devp2p" }
|
||||
|
@ -24,6 +24,8 @@ use devp2p::NetworkService;
|
||||
use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
|
||||
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind,
|
||||
ConnectionFilter};
|
||||
|
||||
use types::pruning_info::PruningInfo;
|
||||
use ethereum_types::{H256, H512, U256};
|
||||
use io::{TimerToken};
|
||||
use ethcore::ethstore::ethkey::Secret;
|
||||
@ -39,7 +41,10 @@ use chain::{ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_62,
|
||||
PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3};
|
||||
use light::client::AsLightClient;
|
||||
use light::Provider;
|
||||
use light::net::{self as light_net, LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext};
|
||||
use light::net::{
|
||||
self as light_net, LightProtocol, Params as LightParams,
|
||||
Capabilities, Handler as LightHandler, EventContext, SampleStore,
|
||||
};
|
||||
use network::IpFilter;
|
||||
use private_tx::PrivateTxHandler;
|
||||
use transaction::UnverifiedTransaction;
|
||||
@ -256,11 +261,35 @@ pub struct EthSync {
|
||||
light_subprotocol_name: [u8; 3],
|
||||
}
|
||||
|
||||
fn light_params(
|
||||
network_id: u64,
|
||||
max_peers: u32,
|
||||
pruning_info: PruningInfo,
|
||||
sample_store: Option<Box<SampleStore>>,
|
||||
) -> LightParams {
|
||||
const MAX_LIGHTSERV_LOAD: f64 = 0.5;
|
||||
|
||||
let mut light_params = LightParams {
|
||||
network_id: network_id,
|
||||
config: Default::default(),
|
||||
capabilities: Capabilities {
|
||||
serve_headers: true,
|
||||
serve_chain_since: Some(pruning_info.earliest_chain),
|
||||
serve_state_since: Some(pruning_info.earliest_state),
|
||||
tx_relay: true,
|
||||
},
|
||||
sample_store: sample_store,
|
||||
};
|
||||
|
||||
let max_peers = ::std::cmp::max(max_peers, 1);
|
||||
light_params.config.load_share = MAX_LIGHTSERV_LOAD / max_peers as f64;
|
||||
|
||||
light_params
|
||||
}
|
||||
|
||||
impl EthSync {
|
||||
/// Creates and register protocol with the network service
|
||||
pub fn new(params: Params, connection_filter: Option<Arc<ConnectionFilter>>) -> Result<Arc<EthSync>, Error> {
|
||||
const MAX_LIGHTSERV_LOAD: f64 = 0.5;
|
||||
|
||||
let pruning_info = params.chain.pruning_info();
|
||||
let light_proto = match params.config.serve_light {
|
||||
false => None,
|
||||
@ -271,20 +300,12 @@ impl EthSync {
|
||||
.map(|mut p| { p.push("request_timings"); light_net::FileStore(p) })
|
||||
.map(|store| Box::new(store) as Box<_>);
|
||||
|
||||
let mut light_params = LightParams {
|
||||
network_id: params.config.network_id,
|
||||
config: Default::default(),
|
||||
capabilities: Capabilities {
|
||||
serve_headers: true,
|
||||
serve_chain_since: Some(pruning_info.earliest_chain),
|
||||
serve_state_since: Some(pruning_info.earliest_state),
|
||||
tx_relay: true,
|
||||
},
|
||||
sample_store: sample_store,
|
||||
};
|
||||
|
||||
let max_peers = ::std::cmp::min(params.network_config.max_peers, 1);
|
||||
light_params.config.load_share = MAX_LIGHTSERV_LOAD / max_peers as f64;
|
||||
let light_params = light_params(
|
||||
params.config.network_id,
|
||||
params.network_config.max_peers,
|
||||
pruning_info,
|
||||
sample_store,
|
||||
);
|
||||
|
||||
let mut light_proto = LightProtocol::new(params.provider, light_params);
|
||||
light_proto.add_handler(Arc::new(TxRelay(params.chain.clone())));
|
||||
@ -916,3 +937,19 @@ impl LightSyncProvider for LightSync {
|
||||
Default::default() // TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn light_params_load_share_depends_on_max_peers() {
|
||||
let pruning_info = PruningInfo {
|
||||
earliest_chain: 0,
|
||||
earliest_state: 0,
|
||||
};
|
||||
let params1 = light_params(0, 10, pruning_info.clone(), None);
|
||||
let params2 = light_params(0, 20, pruning_info, None);
|
||||
assert!(params1.config.load_share > params2.config.load_share)
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,11 @@ use std::cmp;
|
||||
use heapsize::HeapSizeOf;
|
||||
use ethereum_types::H256;
|
||||
use rlp::Rlp;
|
||||
use ethcore::block::Block;
|
||||
use ethcore::views::BlockView;
|
||||
use ethcore::header::{BlockNumber, Header as BlockHeader};
|
||||
use ethcore::client::{BlockStatus, BlockId, BlockImportError, BlockImportErrorKind};
|
||||
use ethcore::block::Block;
|
||||
use ethcore::error::{ImportErrorKind, BlockError};
|
||||
use ethcore::error::{ImportErrorKind, QueueErrorKind, BlockError};
|
||||
use sync_io::SyncIo;
|
||||
use blocks::BlockCollection;
|
||||
|
||||
@ -477,18 +477,19 @@ impl BlockDownloader {
|
||||
for block_and_receipts in blocks {
|
||||
let block = block_and_receipts.block;
|
||||
let receipts = block_and_receipts.receipts;
|
||||
|
||||
// Perform basic block verification
|
||||
if !Block::is_good(&block) {
|
||||
debug!(target: "sync", "Bad block rlp: {:?}", block);
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
|
||||
let (h, number, parent) = {
|
||||
let header = view!(BlockView, &block).header_view();
|
||||
(header.hash(), header.number(), header.parent_hash())
|
||||
};
|
||||
|
||||
// Perform basic block verification
|
||||
if !Block::is_good(&block) {
|
||||
debug!(target: "sync", "Bad block rlp {:?} : {:?}", h, block);
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if self.target_hash.as_ref().map_or(false, |t| t == &h) {
|
||||
self.state = State::Complete;
|
||||
trace!(target: "sync", "Sync target reached");
|
||||
@ -526,6 +527,10 @@ impl BlockDownloader {
|
||||
debug!(target: "sync", "Block temporarily invalid, restarting sync");
|
||||
break;
|
||||
},
|
||||
Err(BlockImportError(BlockImportErrorKind::Queue(QueueErrorKind::Full(limit)), _)) => {
|
||||
debug!(target: "sync", "Block import queue full ({}), restarting sync", limit);
|
||||
break;
|
||||
},
|
||||
Err(e) => {
|
||||
debug!(target: "sync", "Bad block {:?} : {:?}", h, e);
|
||||
bad = true;
|
||||
|
@ -149,12 +149,6 @@ const MAX_NEW_HASHES: usize = 64;
|
||||
const MAX_NEW_BLOCK_AGE: BlockNumber = 20;
|
||||
// maximal packet size with transactions (cannot be greater than 16MB - protocol limitation).
|
||||
const MAX_TRANSACTION_PACKET_SIZE: usize = 8 * 1024 * 1024;
|
||||
// Maximal number of transactions queried from miner to propagate.
|
||||
// This set is used to diff with transactions known by the peer and
|
||||
// we will send a difference of length up to `MAX_TRANSACTIONS_TO_PROPAGATE`.
|
||||
const MAX_TRANSACTIONS_TO_QUERY: usize = 4096;
|
||||
// Maximal number of transactions in sent in single packet.
|
||||
const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64;
|
||||
// Min number of blocks to be behind for a snapshot sync
|
||||
const SNAPSHOT_RESTORE_THRESHOLD: BlockNumber = 30000;
|
||||
const SNAPSHOT_MIN_PEERS: usize = 3;
|
||||
@ -761,14 +755,24 @@ impl ChainSync {
|
||||
}
|
||||
}
|
||||
|
||||
// Only ask for old blocks if the peer has a higher difficulty
|
||||
if force || higher_difficulty {
|
||||
// Only ask for old blocks if the peer has a higher difficulty than the last imported old block
|
||||
let last_imported_old_block_difficulty = self.old_blocks.as_mut().and_then(|d| {
|
||||
io.chain().block_total_difficulty(BlockId::Number(d.last_imported_block_number()))
|
||||
});
|
||||
|
||||
if force || last_imported_old_block_difficulty.map_or(true, |ld| peer_difficulty.map_or(true, |pd| pd > ld)) {
|
||||
if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) {
|
||||
SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::OldBlocks);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
trace!(target: "sync", "peer {} is not suitable for asking old blocks", peer_id);
|
||||
trace!(
|
||||
target: "sync",
|
||||
"peer {:?} is not suitable for requesting old blocks, last_imported_old_block_difficulty={:?}, peer_difficulty={:?}",
|
||||
peer_id,
|
||||
last_imported_old_block_difficulty,
|
||||
peer_difficulty
|
||||
);
|
||||
self.deactivate_peer(io, peer_id);
|
||||
}
|
||||
},
|
||||
|
@ -29,11 +29,9 @@ use transaction::SignedTransaction;
|
||||
use super::{
|
||||
random,
|
||||
ChainSync,
|
||||
MAX_TRANSACTION_PACKET_SIZE,
|
||||
MAX_PEER_LAG_PROPAGATION,
|
||||
MAX_PEERS_PROPAGATION,
|
||||
MAX_TRANSACTION_PACKET_SIZE,
|
||||
MAX_TRANSACTIONS_TO_PROPAGATE,
|
||||
MAX_TRANSACTIONS_TO_QUERY,
|
||||
MIN_PEERS_PROPAGATION,
|
||||
CONSENSUS_DATA_PACKET,
|
||||
NEW_BLOCK_HASHES_PACKET,
|
||||
@ -121,7 +119,7 @@ impl SyncPropagator {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let transactions = io.chain().ready_transactions(MAX_TRANSACTIONS_TO_QUERY);
|
||||
let transactions = io.chain().transactions_to_propagate();
|
||||
if transactions.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
@ -184,7 +182,6 @@ impl SyncPropagator {
|
||||
|
||||
// Get hashes of all transactions to send to this peer
|
||||
let to_send = all_transactions_hashes.difference(&peer_info.last_sent_transactions)
|
||||
.take(MAX_TRANSACTIONS_TO_PROPAGATE)
|
||||
.cloned()
|
||||
.collect::<HashSet<_>>();
|
||||
if to_send.is_empty() {
|
||||
@ -205,7 +202,7 @@ impl SyncPropagator {
|
||||
let appended = packet.append_raw_checked(&transaction.drain(), 1, MAX_TRANSACTION_PACKET_SIZE);
|
||||
if !appended {
|
||||
// Maximal packet size reached just proceed with sending
|
||||
debug!("Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len());
|
||||
debug!(target: "sync", "Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len());
|
||||
to_send = to_send.into_iter().take(pushed).collect();
|
||||
break;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
//! https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
|
||||
//!
|
||||
|
||||
extern crate common_types as types;
|
||||
extern crate ethcore_network as network;
|
||||
extern crate ethcore_network_devp2p as devp2p;
|
||||
extern crate parity_bytes as bytes;
|
||||
|
@ -1,53 +0,0 @@
|
||||
// Copyright 2015-2018 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/>.
|
||||
|
||||
//! Dapps settings de/serialization.
|
||||
|
||||
use hash;
|
||||
|
||||
/// Settings for specific dapp.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct DappsSettings {
|
||||
/// A list of accounts this Dapp can see.
|
||||
pub accounts: Option<Vec<hash::Address>>,
|
||||
/// Default account
|
||||
pub default: Option<hash::Address>,
|
||||
}
|
||||
|
||||
impl_serialization!(String => DappsSettings);
|
||||
|
||||
/// History for specific dapp.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct DappsHistory {
|
||||
/// Last accessed timestamp
|
||||
pub last_accessed: u64,
|
||||
}
|
||||
|
||||
impl_serialization!(String => DappsHistory);
|
||||
|
||||
/// Accounts policy for new dapps.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum NewDappsPolicy {
|
||||
/// All accounts are exposed by default.
|
||||
AllAccounts {
|
||||
/// Default account, which should be returned as the first one.
|
||||
default: hash::Address,
|
||||
},
|
||||
/// Only accounts listed here are exposed by default for new dapps.
|
||||
Whitelist(Vec<hash::Address>),
|
||||
}
|
||||
|
||||
impl_serialization!(String => NewDappsPolicy);
|
@ -48,7 +48,5 @@ macro_rules! impl_serialization {
|
||||
}
|
||||
|
||||
mod account_meta;
|
||||
mod dapps_settings;
|
||||
|
||||
pub use self::dapps_settings::{DappsSettings, DappsHistory, NewDappsPolicy};
|
||||
pub use self::account_meta::AccountMeta;
|
||||
|
@ -24,6 +24,7 @@ use hash::Address;
|
||||
pub struct EthashParams {
|
||||
/// See main EthashParams docs.
|
||||
#[serde(rename="minimumDifficulty")]
|
||||
#[serde(deserialize_with="uint::validate_non_zero")]
|
||||
pub minimum_difficulty: Uint,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(rename="difficultyBoundDivisor")]
|
||||
|
@ -143,6 +143,10 @@ impl txpool::Scoring<VerifiedTransaction> for NonceAndGasPrice {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn should_ignore_sender_limit(&self, new: &VerifiedTransaction) -> bool {
|
||||
new.priority().is_local()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -116,12 +116,11 @@ fn should_never_drop_local_transactions_from_different_senders() {
|
||||
let r1 = txq.import(TestClient::new(), vec![tx1].local());
|
||||
let r2 = txq.import(TestClient::new(), vec![tx2].local());
|
||||
assert_eq!(r1, vec![Ok(())]);
|
||||
// max-per-sender is reached, that's ok.
|
||||
assert_eq!(r2, vec![Err(transaction::Error::LimitReached)]);
|
||||
assert_eq!(txq.status().status.transaction_count, 1);
|
||||
assert_eq!(r2, vec![Ok(())]);
|
||||
assert_eq!(txq.status().status.transaction_count, 2);
|
||||
|
||||
// then
|
||||
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 1.into()));
|
||||
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 2.into()));
|
||||
|
||||
// when
|
||||
let tx1 = Tx::gas_price(2).signed();
|
||||
@ -134,8 +133,8 @@ fn should_never_drop_local_transactions_from_different_senders() {
|
||||
// then
|
||||
assert_eq!(res, vec![Ok(()), Ok(())]);
|
||||
assert_eq!(res2, vec![Ok(()), Ok(())]);
|
||||
assert_eq!(txq.status().status.transaction_count, 5);
|
||||
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 1.into()));
|
||||
assert_eq!(txq.status().status.transaction_count, 6);
|
||||
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 2.into()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -67,19 +67,10 @@ impl WorkPoster {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
|
||||
fn difficulty_to_boundary(difficulty: &U256) -> H256 {
|
||||
if *difficulty <= U256::one() {
|
||||
U256::max_value().into()
|
||||
} else {
|
||||
(((U256::one() << 255) / *difficulty) << 1).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl NotifyWork for WorkPoster {
|
||||
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) {
|
||||
// TODO: move this to engine
|
||||
let target = difficulty_to_boundary(&difficulty);
|
||||
let target = ethash::difficulty_to_boundary(&difficulty);
|
||||
let seed_hash = &self.seed_compute.lock().hash_block_number(number);
|
||||
let seed_hash = H256::from_slice(&seed_hash[..]);
|
||||
let body = format!(
|
||||
|
@ -1,18 +0,0 @@
|
||||
[package]
|
||||
name = "node-health"
|
||||
description = "Node's health status"
|
||||
version = "0.1.0"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.1"
|
||||
futures-cpupool = "0.1"
|
||||
log = "0.3"
|
||||
ntp = "0.5.0"
|
||||
parking_lot = "0.6"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
time = "0.1.35"
|
||||
|
||||
parity-reactor = { path = "../util/reactor" }
|
@ -1,122 +0,0 @@
|
||||
// Copyright 2015-2018 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/>.
|
||||
|
||||
//! Reporting node's health.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use futures::Future;
|
||||
use futures::sync::oneshot;
|
||||
use types::{HealthInfo, HealthStatus, Health};
|
||||
use time::{TimeChecker, MAX_DRIFT};
|
||||
use parity_reactor::Remote;
|
||||
use parking_lot::Mutex;
|
||||
use {SyncStatus};
|
||||
|
||||
const TIMEOUT: Duration = Duration::from_secs(5);
|
||||
const PROOF: &str = "Only one closure is invoked.";
|
||||
|
||||
/// A struct enabling you to query for node's health.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NodeHealth {
|
||||
sync_status: Arc<SyncStatus>,
|
||||
time: TimeChecker,
|
||||
remote: Remote,
|
||||
}
|
||||
|
||||
impl NodeHealth {
|
||||
/// Creates new `NodeHealth`.
|
||||
pub fn new(sync_status: Arc<SyncStatus>, time: TimeChecker, remote: Remote) -> Self {
|
||||
NodeHealth { sync_status, time, remote, }
|
||||
}
|
||||
|
||||
/// Query latest health report.
|
||||
pub fn health(&self) -> Box<Future<Item = Health, Error = ()> + Send> {
|
||||
trace!(target: "dapps", "Checking node health.");
|
||||
// Check timediff
|
||||
let sync_status = self.sync_status.clone();
|
||||
let time = self.time.time_drift();
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let tx = Arc::new(Mutex::new(Some(tx)));
|
||||
let tx2 = tx.clone();
|
||||
self.remote.spawn_with_timeout(
|
||||
move |_| time.then(move |result| {
|
||||
let _ = tx.lock().take().expect(PROOF).send(Ok(result));
|
||||
Ok(())
|
||||
}),
|
||||
TIMEOUT,
|
||||
move || {
|
||||
let _ = tx2.lock().take().expect(PROOF).send(Err(()));
|
||||
},
|
||||
);
|
||||
|
||||
Box::new(rx.map_err(|err| {
|
||||
warn!(target: "dapps", "Health request cancelled: {:?}", err);
|
||||
}).and_then(move |time| {
|
||||
// Check peers
|
||||
let peers = {
|
||||
let (connected, max) = sync_status.peers();
|
||||
let (status, message) = match connected {
|
||||
0 => {
|
||||
(HealthStatus::Bad, "You are not connected to any peers. There is most likely some network issue. Fix connectivity.".into())
|
||||
},
|
||||
1 => (HealthStatus::NeedsAttention, "You are connected to only one peer. Your node might not be reliable. Check your network connection.".into()),
|
||||
_ => (HealthStatus::Ok, "".into()),
|
||||
};
|
||||
HealthInfo { status, message, details: (connected, max) }
|
||||
};
|
||||
|
||||
// Check sync
|
||||
let sync = {
|
||||
let is_syncing = sync_status.is_major_importing();
|
||||
let (status, message) = if is_syncing {
|
||||
(HealthStatus::NeedsAttention, "Your node is still syncing, the values you see might be outdated. Wait until it's fully synced.".into())
|
||||
} else {
|
||||
(HealthStatus::Ok, "".into())
|
||||
};
|
||||
HealthInfo { status, message, details: is_syncing }
|
||||
};
|
||||
|
||||
// Check time
|
||||
let time = {
|
||||
let (status, message, details) = match time {
|
||||
Ok(Ok(diff)) if diff < MAX_DRIFT && diff > -MAX_DRIFT => {
|
||||
(HealthStatus::Ok, "".into(), diff)
|
||||
},
|
||||
Ok(Ok(diff)) => {
|
||||
(HealthStatus::Bad, format!(
|
||||
"Your clock is not in sync. Detected difference is too big for the protocol to work: {}ms. Synchronize your clock.",
|
||||
diff,
|
||||
), diff)
|
||||
},
|
||||
Ok(Err(err)) => {
|
||||
(HealthStatus::NeedsAttention, format!(
|
||||
"Unable to reach time API: {}. Make sure that your clock is synchronized.",
|
||||
err,
|
||||
), 0)
|
||||
},
|
||||
Err(_) => {
|
||||
(HealthStatus::NeedsAttention, "Time API request timed out. Make sure that the clock is synchronized.".into(), 0)
|
||||
},
|
||||
};
|
||||
|
||||
HealthInfo { status, message, details, }
|
||||
};
|
||||
|
||||
Ok(Health { peers, sync, time})
|
||||
}))
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
// Copyright 2015-2018 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/>.
|
||||
|
||||
//! Node Health status reporting.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
extern crate futures;
|
||||
extern crate futures_cpupool;
|
||||
extern crate ntp;
|
||||
extern crate time as time_crate;
|
||||
extern crate parity_reactor;
|
||||
extern crate parking_lot;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
mod health;
|
||||
mod time;
|
||||
mod types;
|
||||
|
||||
pub use futures_cpupool::CpuPool;
|
||||
pub use health::NodeHealth;
|
||||
pub use types::{Health, HealthInfo, HealthStatus};
|
||||
pub use time::{TimeChecker, Error};
|
||||
|
||||
/// Indicates sync status
|
||||
pub trait SyncStatus: ::std::fmt::Debug + Send + Sync {
|
||||
/// Returns true if there is a major sync happening.
|
||||
fn is_major_importing(&self) -> bool;
|
||||
|
||||
/// Returns number of connected and ideal peers.
|
||||
fn peers(&self) -> (usize, usize);
|
||||
}
|
@ -1,357 +0,0 @@
|
||||
// Copyright 2015-2018 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/>.
|
||||
|
||||
//! Periodically checks node's time drift using [SNTP](https://tools.ietf.org/html/rfc1769).
|
||||
//!
|
||||
//! An NTP packet is sent to the server with a local timestamp, the server then completes the packet, yielding the
|
||||
//! following timestamps:
|
||||
//!
|
||||
//! Timestamp Name ID When Generated
|
||||
//! ------------------------------------------------------------
|
||||
//! Originate Timestamp T1 time request sent by client
|
||||
//! Receive Timestamp T2 time request received at server
|
||||
//! Transmit Timestamp T3 time reply sent by server
|
||||
//! Destination Timestamp T4 time reply received at client
|
||||
//!
|
||||
//! The drift is defined as:
|
||||
//!
|
||||
//! drift = ((T2 - T1) + (T3 - T4)) / 2.
|
||||
//!
|
||||
|
||||
use std::io;
|
||||
use std::{fmt, mem, time};
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::atomic::{self, AtomicUsize};
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures::{self, Future};
|
||||
use futures::future::{self, IntoFuture};
|
||||
use futures_cpupool::{CpuPool, CpuFuture};
|
||||
use ntp;
|
||||
use parking_lot::RwLock;
|
||||
use time_crate::{Duration, Timespec};
|
||||
|
||||
/// Time checker error.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Error {
|
||||
/// No servers are currently available for a query.
|
||||
NoServersAvailable,
|
||||
/// There was an error when trying to reach the NTP server.
|
||||
Ntp(String),
|
||||
/// IO error when reading NTP response.
|
||||
Io(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::Error::*;
|
||||
|
||||
match *self {
|
||||
NoServersAvailable => write!(fmt, "No NTP servers available"),
|
||||
Ntp(ref err) => write!(fmt, "NTP error: {}", err),
|
||||
Io(ref err) => write!(fmt, "Connection Error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(err: io::Error) -> Self { Error::Io(format!("{}", err)) }
|
||||
}
|
||||
|
||||
impl From<ntp::errors::Error> for Error {
|
||||
fn from(err: ntp::errors::Error) -> Self { Error::Ntp(format!("{}", err)) }
|
||||
}
|
||||
|
||||
/// NTP time drift checker.
|
||||
pub trait Ntp {
|
||||
/// Returned Future.
|
||||
type Future: IntoFuture<Item=Duration, Error=Error>;
|
||||
|
||||
/// Returns the current time drift.
|
||||
fn drift(&self) -> Self::Future;
|
||||
}
|
||||
|
||||
const SERVER_MAX_POLL_INTERVAL_SECS: u64 = 60;
|
||||
#[derive(Debug)]
|
||||
struct Server {
|
||||
pub address: String,
|
||||
next_call: RwLock<time::Instant>,
|
||||
failures: AtomicUsize,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn is_available(&self) -> bool {
|
||||
*self.next_call.read() < time::Instant::now()
|
||||
}
|
||||
|
||||
pub fn report_success(&self) {
|
||||
self.failures.store(0, atomic::Ordering::SeqCst);
|
||||
self.update_next_call(1)
|
||||
}
|
||||
|
||||
pub fn report_failure(&self) {
|
||||
let errors = self.failures.fetch_add(1, atomic::Ordering::SeqCst);
|
||||
self.update_next_call(1 << errors)
|
||||
}
|
||||
|
||||
fn update_next_call(&self, delay: usize) {
|
||||
*self.next_call.write() = time::Instant::now() + time::Duration::from_secs(delay as u64 * SERVER_MAX_POLL_INTERVAL_SECS);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> From<T> for Server {
|
||||
fn from(t: T) -> Self {
|
||||
Server {
|
||||
address: t.as_ref().to_owned(),
|
||||
next_call: RwLock::new(time::Instant::now()),
|
||||
failures: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// NTP client using the SNTP algorithm for calculating drift.
|
||||
#[derive(Clone)]
|
||||
pub struct SimpleNtp {
|
||||
addresses: Vec<Arc<Server>>,
|
||||
pool: CpuPool,
|
||||
}
|
||||
|
||||
impl fmt::Debug for SimpleNtp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f
|
||||
.debug_struct("SimpleNtp")
|
||||
.field("addresses", &self.addresses)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl SimpleNtp {
|
||||
fn new<T: AsRef<str>>(addresses: &[T], pool: CpuPool) -> SimpleNtp {
|
||||
SimpleNtp {
|
||||
addresses: addresses.iter().map(Server::from).map(Arc::new).collect(),
|
||||
pool: pool,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ntp for SimpleNtp {
|
||||
type Future = future::Either<
|
||||
CpuFuture<Duration, Error>,
|
||||
future::FutureResult<Duration, Error>,
|
||||
>;
|
||||
|
||||
fn drift(&self) -> Self::Future {
|
||||
use self::future::Either::{A, B};
|
||||
|
||||
let server = self.addresses.iter().find(|server| server.is_available());
|
||||
server.map(|server| {
|
||||
let server = server.clone();
|
||||
A(self.pool.spawn_fn(move || {
|
||||
debug!(target: "dapps", "Fetching time from {}.", server.address);
|
||||
|
||||
match ntp::request(&server.address) {
|
||||
Ok(packet) => {
|
||||
let dest_time = ::time_crate::now_utc().to_timespec();
|
||||
let orig_time = Timespec::from(packet.orig_time);
|
||||
let recv_time = Timespec::from(packet.recv_time);
|
||||
let transmit_time = Timespec::from(packet.transmit_time);
|
||||
|
||||
let drift = ((recv_time - orig_time) + (transmit_time - dest_time)) / 2;
|
||||
|
||||
server.report_success();
|
||||
Ok(drift)
|
||||
},
|
||||
Err(err) => {
|
||||
server.report_failure();
|
||||
Err(err.into())
|
||||
},
|
||||
}
|
||||
}))
|
||||
}).unwrap_or_else(|| B(future::err(Error::NoServersAvailable)))
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE In a positive scenario first results will be seen after:
|
||||
// MAX_RESULTS * UPDATE_TIMEOUT_INCOMPLETE_SECS seconds.
|
||||
const MAX_RESULTS: usize = 4;
|
||||
const UPDATE_TIMEOUT_OK_SECS: u64 = 6 * 60 * 60;
|
||||
const UPDATE_TIMEOUT_WARN_SECS: u64 = 15 * 60;
|
||||
const UPDATE_TIMEOUT_ERR_SECS: u64 = 60;
|
||||
const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10;
|
||||
|
||||
/// Maximal valid time drift.
|
||||
pub const MAX_DRIFT: i64 = 10_000;
|
||||
|
||||
type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// A time checker.
|
||||
pub struct TimeChecker<N: Ntp = SimpleNtp> {
|
||||
ntp: N,
|
||||
last_result: Arc<RwLock<(time::Instant, VecDeque<Result<i64, Error>>)>>,
|
||||
}
|
||||
|
||||
impl TimeChecker<SimpleNtp> {
|
||||
/// Creates new time checker given the NTP server address.
|
||||
pub fn new<T: AsRef<str>>(ntp_addresses: &[T], pool: CpuPool) -> Self {
|
||||
let last_result = Arc::new(RwLock::new(
|
||||
// Assume everything is ok at the very beginning.
|
||||
(time::Instant::now(), vec![Ok(0)].into())
|
||||
));
|
||||
|
||||
let ntp = SimpleNtp::new(ntp_addresses, pool);
|
||||
|
||||
TimeChecker {
|
||||
ntp,
|
||||
last_result,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Ntp> TimeChecker<N> where <N::Future as IntoFuture>::Future: Send + 'static {
|
||||
/// Updates the time
|
||||
pub fn update(&self) -> BoxFuture<i64, Error> {
|
||||
trace!(target: "dapps", "Updating time from NTP.");
|
||||
let last_result = self.last_result.clone();
|
||||
Box::new(self.ntp.drift().into_future().then(move |res| {
|
||||
let res = res.map(|d| d.num_milliseconds());
|
||||
|
||||
if let Err(Error::NoServersAvailable) = res {
|
||||
debug!(target: "dapps", "No NTP servers available. Selecting an older result.");
|
||||
return select_result(last_result.read().1.iter());
|
||||
}
|
||||
|
||||
// Update the results.
|
||||
let mut results = mem::replace(&mut last_result.write().1, VecDeque::new());
|
||||
let has_all_results = results.len() >= MAX_RESULTS;
|
||||
let valid_till = time::Instant::now() + time::Duration::from_secs(
|
||||
match res {
|
||||
Ok(time) if has_all_results && time < MAX_DRIFT => UPDATE_TIMEOUT_OK_SECS,
|
||||
Ok(_) if has_all_results => UPDATE_TIMEOUT_WARN_SECS,
|
||||
Err(_) if has_all_results => UPDATE_TIMEOUT_ERR_SECS,
|
||||
_ => UPDATE_TIMEOUT_INCOMPLETE_SECS,
|
||||
}
|
||||
);
|
||||
|
||||
trace!(target: "dapps", "New time drift received: {:?}", res);
|
||||
// Push the result.
|
||||
results.push_back(res);
|
||||
while results.len() > MAX_RESULTS {
|
||||
results.pop_front();
|
||||
}
|
||||
|
||||
// Select a response and update last result.
|
||||
let res = select_result(results.iter());
|
||||
*last_result.write() = (valid_till, results);
|
||||
res
|
||||
}))
|
||||
}
|
||||
|
||||
/// Returns a current time drift or error if last request to NTP server failed.
|
||||
pub fn time_drift(&self) -> BoxFuture<i64, Error> {
|
||||
// return cached result
|
||||
{
|
||||
let res = self.last_result.read();
|
||||
if res.0 > time::Instant::now() {
|
||||
return Box::new(futures::done(select_result(res.1.iter())));
|
||||
}
|
||||
}
|
||||
// or update and return result
|
||||
self.update()
|
||||
}
|
||||
}
|
||||
|
||||
fn select_result<'a, T: Iterator<Item=&'a Result<i64, Error>>>(results: T) -> Result<i64, Error> {
|
||||
let mut min = None;
|
||||
for res in results {
|
||||
min = Some(match (min.take(), res) {
|
||||
(Some(Ok(min)), &Ok(ref new)) => Ok(::std::cmp::min(min, *new)),
|
||||
(Some(Ok(old)), &Err(_)) => Ok(old),
|
||||
(_, ref new) => (*new).clone(),
|
||||
})
|
||||
}
|
||||
|
||||
min.unwrap_or_else(|| Err(Error::Ntp("NTP server unavailable.".into())))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::time::Instant;
|
||||
use time::Duration;
|
||||
use futures::{future, Future};
|
||||
use super::{Ntp, TimeChecker, Error};
|
||||
use parking_lot::RwLock;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct FakeNtp(RefCell<Vec<Duration>>, Cell<u64>);
|
||||
impl FakeNtp {
|
||||
fn new() -> FakeNtp {
|
||||
FakeNtp(
|
||||
RefCell::new(vec![Duration::milliseconds(150)]),
|
||||
Cell::new(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ntp for FakeNtp {
|
||||
type Future = future::FutureResult<Duration, Error>;
|
||||
|
||||
fn drift(&self) -> Self::Future {
|
||||
self.1.set(self.1.get() + 1);
|
||||
future::ok(self.0.borrow_mut().pop().expect("Unexpected call to drift()."))
|
||||
}
|
||||
}
|
||||
|
||||
fn time_checker() -> TimeChecker<FakeNtp> {
|
||||
let last_result = Arc::new(RwLock::new(
|
||||
(Instant::now(), vec![Err(Error::Ntp("NTP server unavailable".into()))].into())
|
||||
));
|
||||
|
||||
TimeChecker {
|
||||
ntp: FakeNtp::new(),
|
||||
last_result: last_result,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_fetch_time_on_start() {
|
||||
// given
|
||||
let time = time_checker();
|
||||
|
||||
// when
|
||||
let diff = time.time_drift().wait().unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(diff, 150);
|
||||
assert_eq!(time.ntp.1.get(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_fetch_twice_if_timeout_has_not_passed() {
|
||||
// given
|
||||
let time = time_checker();
|
||||
|
||||
// when
|
||||
let diff1 = time.time_drift().wait().unwrap();
|
||||
let diff2 = time.time_drift().wait().unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(diff1, 150);
|
||||
assert_eq!(diff2, 150);
|
||||
assert_eq!(time.ntp.1.get(), 1);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
// Copyright 2015-2018 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/>.
|
||||
|
||||
//! Base health types.
|
||||
|
||||
/// Health API endpoint status.
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
pub enum HealthStatus {
|
||||
/// Everything's OK.
|
||||
#[serde(rename = "ok")]
|
||||
Ok,
|
||||
/// Node health need attention
|
||||
/// (the issue is not critical, but may need investigation)
|
||||
#[serde(rename = "needsAttention")]
|
||||
NeedsAttention,
|
||||
/// There is something bad detected with the node.
|
||||
#[serde(rename = "bad")]
|
||||
Bad,
|
||||
}
|
||||
|
||||
/// Represents a single check in node health.
|
||||
/// Cointains the status of that check and apropriate message and details.
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct HealthInfo<T> {
|
||||
/// Check status.
|
||||
pub status: HealthStatus,
|
||||
/// Human-readable message.
|
||||
pub message: String,
|
||||
/// Technical details of the check.
|
||||
pub details: T,
|
||||
}
|
||||
|
||||
/// Node Health status.
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Health {
|
||||
/// Status of peers.
|
||||
pub peers: HealthInfo<(usize, usize)>,
|
||||
/// Sync status.
|
||||
pub sync: HealthInfo<bool>,
|
||||
/// Time diff info.
|
||||
pub time: HealthInfo<i64>,
|
||||
}
|
@ -288,7 +288,7 @@ usage! {
|
||||
|
||||
ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(),
|
||||
"--chain=[CHAIN]",
|
||||
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, homestead, mainnet, morden, ropsten, classic, expanse, tobalaba, musicoin, ellaism, easthub, social, testnet, kovan or dev.",
|
||||
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, olympic, morden, ropsten, kovan, poasokol, testnet, or dev.",
|
||||
|
||||
ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| c.parity.as_ref()?.keys_path.clone(),
|
||||
"--keys-path=[PATH]",
|
||||
@ -700,11 +700,11 @@ usage! {
|
||||
"--price-update-period=[T]",
|
||||
"T will be allowed to pass between each gas price update. T may be daily, hourly, a number of seconds, or a time string of the form \"2 days\", \"30 minutes\" etc..",
|
||||
|
||||
ARG arg_gas_floor_target: (String) = "4700000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(),
|
||||
ARG arg_gas_floor_target: (String) = "8000000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(),
|
||||
"--gas-floor-target=[GAS]",
|
||||
"Amount of gas per block to target when sealing a new block.",
|
||||
|
||||
ARG arg_gas_cap: (String) = "6283184", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(),
|
||||
ARG arg_gas_cap: (String) = "10000000", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(),
|
||||
"--gas-cap=[GAS]",
|
||||
"A cap on how large we will raise the gas limit per block due to transaction volume.",
|
||||
|
||||
@ -794,10 +794,6 @@ usage! {
|
||||
"--no-config",
|
||||
"Don't load a configuration file.",
|
||||
|
||||
ARG arg_ntp_servers: (String) = "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123", or |c: &Config| c.misc.as_ref()?.ntp_servers.clone().map(|vec| vec.join(",")),
|
||||
"--ntp-servers=[HOSTS]",
|
||||
"Comma separated list of NTP servers to provide current time (host:port). Used to verify node health. Parity uses pool.ntp.org NTP servers; consider joining the pool: http://www.pool.ntp.org/join.html",
|
||||
|
||||
ARG arg_logging: (Option<String>) = None, or |c: &Config| c.misc.as_ref()?.logging.clone(),
|
||||
"-l, --logging=[LOGGING]",
|
||||
"Specify the logging level. Must conform to the same format as RUST_LOG.",
|
||||
@ -1077,6 +1073,10 @@ usage! {
|
||||
ARG arg_dapps_path: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_path.clone(),
|
||||
"--dapps-path=[PATH]",
|
||||
"Specify directory where dapps should be installed.",
|
||||
|
||||
ARG arg_ntp_servers: (Option<String>) = None, or |_| None,
|
||||
"--ntp-servers=[HOSTS]",
|
||||
"Does nothing; checking if clock is sync with NTP servers is now done on the UI.",
|
||||
}
|
||||
}
|
||||
|
||||
@ -1350,7 +1350,6 @@ struct Snapshots {
|
||||
#[derive(Default, Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct Misc {
|
||||
ntp_servers: Option<Vec<String>>,
|
||||
logging: Option<String>,
|
||||
log_file: Option<String>,
|
||||
color: Option<bool>,
|
||||
@ -1713,7 +1712,7 @@ mod tests {
|
||||
arg_reseal_max_period: 60000u64,
|
||||
flag_reseal_on_uncle: false,
|
||||
arg_work_queue_size: 20usize,
|
||||
arg_tx_gas_limit: Some("6283184".into()),
|
||||
arg_tx_gas_limit: Some("10000000".into()),
|
||||
arg_tx_time_limit: Some(100u64),
|
||||
arg_relay_set: "cheap".into(),
|
||||
arg_min_gas_price: Some(0u64),
|
||||
@ -1722,8 +1721,8 @@ mod tests {
|
||||
arg_poll_lifetime: 60u32,
|
||||
arg_usd_per_eth: "auto".into(),
|
||||
arg_price_update_period: "hourly".into(),
|
||||
arg_gas_floor_target: "4700000".into(),
|
||||
arg_gas_cap: "6283184".into(),
|
||||
arg_gas_floor_target: "8000000".into(),
|
||||
arg_gas_cap: "10000000".into(),
|
||||
arg_extra_data: Some("Parity".into()),
|
||||
flag_tx_queue_no_unfamiliar_locals: false,
|
||||
arg_tx_queue_size: 8192usize,
|
||||
@ -1818,7 +1817,7 @@ mod tests {
|
||||
flag_can_restart: false,
|
||||
|
||||
// -- Miscellaneous Options
|
||||
arg_ntp_servers: "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123".into(),
|
||||
arg_ntp_servers: None,
|
||||
flag_version: false,
|
||||
arg_logging: Some("own_tx=trace".into()),
|
||||
arg_log_file: Some("/var/log/parity.log".into()),
|
||||
@ -2024,7 +2023,6 @@ mod tests {
|
||||
disable_periodic: Some(true),
|
||||
}),
|
||||
misc: Some(Misc {
|
||||
ntp_servers: Some(vec!["0.parity.pool.ntp.org:123".into()]),
|
||||
logging: Some("own_tx=trace".into()),
|
||||
log_file: Some("/var/log/parity.log".into()),
|
||||
color: Some(true),
|
||||
|
@ -125,14 +125,14 @@ min_gas_price = 0
|
||||
usd_per_tx = "0.0001"
|
||||
usd_per_eth = "auto"
|
||||
price_update_period = "hourly"
|
||||
gas_floor_target = "4700000"
|
||||
gas_cap = "6283184"
|
||||
gas_floor_target = "8000000"
|
||||
gas_cap = "10000000"
|
||||
tx_queue_size = 8192
|
||||
tx_queue_gas = "off"
|
||||
tx_queue_strategy = "gas_factor"
|
||||
tx_queue_ban_count = 1
|
||||
tx_queue_ban_time = 180 #s
|
||||
tx_gas_limit = "6283184"
|
||||
tx_gas_limit = "10000000"
|
||||
tx_time_limit = 100 #ms
|
||||
tx_queue_no_unfamiliar_locals = false
|
||||
extra_data = "Parity"
|
||||
|
@ -75,7 +75,6 @@ scale_verifiers = false
|
||||
disable_periodic = true
|
||||
|
||||
[misc]
|
||||
ntp_servers = ["0.parity.pool.ntp.org:123"]
|
||||
logging = "own_tx=trace"
|
||||
log_file = "/var/log/parity.log"
|
||||
color = true
|
||||
|
@ -348,7 +348,6 @@ impl Configuration {
|
||||
miner_options: self.miner_options()?,
|
||||
gas_price_percentile: self.args.arg_gas_price_percentile,
|
||||
poll_lifetime: self.args.arg_poll_lifetime,
|
||||
ntp_servers: self.ntp_servers(),
|
||||
ws_conf: ws_conf,
|
||||
http_conf: http_conf,
|
||||
ipc_conf: ipc_conf,
|
||||
@ -574,10 +573,6 @@ impl Configuration {
|
||||
})
|
||||
}
|
||||
|
||||
fn ntp_servers(&self) -> Vec<String> {
|
||||
self.args.arg_ntp_servers.split(",").map(str::to_owned).collect()
|
||||
}
|
||||
|
||||
fn secretstore_config(&self) -> Result<SecretStoreConfiguration, String> {
|
||||
Ok(SecretStoreConfiguration {
|
||||
enabled: self.secretstore_enabled(),
|
||||
@ -939,7 +934,13 @@ impl Configuration {
|
||||
let is_using_base_path = self.args.arg_base_path.is_some();
|
||||
// If base_path is set and db_path is not we default to base path subdir instead of LOCAL.
|
||||
let base_db_path = if is_using_base_path && self.args.arg_db_path.is_none() {
|
||||
"$BASE/chains"
|
||||
if self.args.flag_light {
|
||||
"$BASE/chains_light"
|
||||
} else {
|
||||
"$BASE/chains"
|
||||
}
|
||||
} else if self.args.flag_light {
|
||||
self.args.arg_db_path.as_ref().map_or(dir::CHAINS_PATH_LIGHT, |s| &s)
|
||||
} else {
|
||||
self.args.arg_db_path.as_ref().map_or(dir::CHAINS_PATH, |s| &s)
|
||||
};
|
||||
@ -1362,12 +1363,6 @@ mod tests {
|
||||
miner_options: Default::default(),
|
||||
gas_price_percentile: 50,
|
||||
poll_lifetime: 60,
|
||||
ntp_servers: vec![
|
||||
"0.parity.pool.ntp.org:123".into(),
|
||||
"1.parity.pool.ntp.org:123".into(),
|
||||
"2.parity.pool.ntp.org:123".into(),
|
||||
"3.parity.pool.ntp.org:123".into(),
|
||||
],
|
||||
ws_conf: Default::default(),
|
||||
http_conf: Default::default(),
|
||||
ipc_conf: Default::default(),
|
||||
|
@ -225,6 +225,10 @@ pub fn find_deprecated(args: &Args) -> Vec<Deprecated> {
|
||||
result.push(Deprecated::Removed("--dapps-path"));
|
||||
}
|
||||
|
||||
if args.arg_ntp_servers.is_some() {
|
||||
result.push(Deprecated::Removed("--ntp-servers"));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
@ -256,6 +260,7 @@ mod tests {
|
||||
args.arg_dapps_pass = Some(Default::default());
|
||||
args.flag_dapps_apis_all = true;
|
||||
args.flag_fast_and_loose = true;
|
||||
args.arg_ntp_servers = Some(Default::default());
|
||||
args
|
||||
}), vec![
|
||||
Deprecated::DoesNothing("--warp"),
|
||||
@ -276,6 +281,7 @@ mod tests {
|
||||
Deprecated::Removed("--dapps-pass"),
|
||||
Deprecated::Replaced("--dapps-apis-all", "--jsonrpc-apis"),
|
||||
Deprecated::Removed("--fast-and-loose"),
|
||||
Deprecated::Removed("--ntp-servers"),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ use io::{TimerToken, IoContext, IoHandler};
|
||||
use light::Cache as LightDataCache;
|
||||
use light::client::{LightChainClient, LightChainNotify};
|
||||
use number_prefix::{binary_prefix, Standalone, Prefixed};
|
||||
use parity_rpc::{is_major_importing};
|
||||
use parity_rpc::is_major_importing_or_waiting;
|
||||
use parity_rpc::informant::RpcStats;
|
||||
use ethereum_types::H256;
|
||||
use bytes::Bytes;
|
||||
@ -128,7 +128,7 @@ impl InformantData for FullNodeInformantData {
|
||||
|
||||
fn is_major_importing(&self) -> bool {
|
||||
let state = self.sync.as_ref().map(|sync| sync.status().state);
|
||||
is_major_importing(state, self.client.queue_info())
|
||||
is_major_importing_or_waiting(state, self.client.queue_info(), false)
|
||||
}
|
||||
|
||||
fn report(&self) -> Report {
|
||||
@ -142,7 +142,8 @@ impl InformantData for FullNodeInformantData {
|
||||
cache_sizes.insert("queue", queue_info.mem_used);
|
||||
cache_sizes.insert("chain", blockchain_cache_info.total());
|
||||
|
||||
let (importing, sync_info) = match (self.sync.as_ref(), self.net.as_ref()) {
|
||||
let importing = self.is_major_importing();
|
||||
let sync_info = match (self.sync.as_ref(), self.net.as_ref()) {
|
||||
(Some(sync), Some(net)) => {
|
||||
let status = sync.status();
|
||||
let num_peers_range = net.num_peers_range();
|
||||
@ -150,16 +151,15 @@ impl InformantData for FullNodeInformantData {
|
||||
|
||||
cache_sizes.insert("sync", status.mem_used);
|
||||
|
||||
let importing = is_major_importing(Some(status.state), queue_info.clone());
|
||||
(importing, Some(SyncInfo {
|
||||
Some(SyncInfo {
|
||||
last_imported_block_number: status.last_imported_block_number.unwrap_or(chain_info.best_block_number),
|
||||
last_imported_old_block_number: status.last_imported_old_block_number,
|
||||
num_peers: status.num_peers,
|
||||
max_peers: status.current_max_peers(num_peers_range.start, num_peers_range.end - 1),
|
||||
snapshot_sync: status.is_snapshot_syncing(),
|
||||
}))
|
||||
})
|
||||
}
|
||||
_ => (is_major_importing(self.sync.as_ref().map(|s| s.status().state), queue_info.clone()), None),
|
||||
_ => None
|
||||
};
|
||||
|
||||
Report {
|
||||
|
@ -57,7 +57,6 @@ extern crate ethcore_transaction as transaction;
|
||||
extern crate ethereum_types;
|
||||
extern crate ethkey;
|
||||
extern crate kvdb;
|
||||
extern crate node_health;
|
||||
extern crate panic_hook;
|
||||
extern crate parity_hash_fetch as hash_fetch;
|
||||
extern crate parity_ipfs_api;
|
||||
@ -80,9 +79,6 @@ extern crate log as rlog;
|
||||
#[cfg(feature = "secretstore")]
|
||||
extern crate ethcore_secretstore;
|
||||
|
||||
#[cfg(feature = "dapps")]
|
||||
extern crate parity_dapps;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate pretty_assertions;
|
||||
|
@ -32,17 +32,19 @@ use user_defaults::UserDefaults;
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum SpecType {
|
||||
Foundation,
|
||||
Morden,
|
||||
Ropsten,
|
||||
Tobalaba,
|
||||
Kovan,
|
||||
Olympic,
|
||||
Classic,
|
||||
Poanet,
|
||||
Tobalaba,
|
||||
Expanse,
|
||||
Musicoin,
|
||||
Ellaism,
|
||||
Easthub,
|
||||
Social,
|
||||
Olympic,
|
||||
Morden,
|
||||
Ropsten,
|
||||
Kovan,
|
||||
Sokol,
|
||||
Dev,
|
||||
Custom(String),
|
||||
}
|
||||
@ -58,18 +60,20 @@ impl str::FromStr for SpecType {
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let spec = match s {
|
||||
"foundation" | "frontier" | "homestead" | "mainnet" => SpecType::Foundation,
|
||||
"frontier-dogmatic" | "homestead-dogmatic" | "classic" => SpecType::Classic,
|
||||
"morden" | "classic-testnet" => SpecType::Morden,
|
||||
"ropsten" => SpecType::Ropsten,
|
||||
"kovan" | "testnet" => SpecType::Kovan,
|
||||
"ethereum" | "frontier" | "homestead" | "byzantium" | "foundation" | "mainnet" => SpecType::Foundation,
|
||||
"classic" | "frontier-dogmatic" | "homestead-dogmatic" => SpecType::Classic,
|
||||
"poanet" | "poacore" => SpecType::Poanet,
|
||||
"tobalaba" => SpecType::Tobalaba,
|
||||
"olympic" => SpecType::Olympic,
|
||||
"expanse" => SpecType::Expanse,
|
||||
"musicoin" => SpecType::Musicoin,
|
||||
"ellaism" => SpecType::Ellaism,
|
||||
"easthub" => SpecType::Easthub,
|
||||
"social" => SpecType::Social,
|
||||
"olympic" => SpecType::Olympic,
|
||||
"morden" | "classic-testnet" => SpecType::Morden,
|
||||
"ropsten" => SpecType::Ropsten,
|
||||
"kovan" | "testnet" => SpecType::Kovan,
|
||||
"sokol" | "poasokol" => SpecType::Sokol,
|
||||
"dev" => SpecType::Dev,
|
||||
other => SpecType::Custom(other.into()),
|
||||
};
|
||||
@ -81,17 +85,19 @@ impl fmt::Display for SpecType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(match *self {
|
||||
SpecType::Foundation => "foundation",
|
||||
SpecType::Morden => "morden",
|
||||
SpecType::Ropsten => "ropsten",
|
||||
SpecType::Olympic => "olympic",
|
||||
SpecType::Classic => "classic",
|
||||
SpecType::Poanet => "poanet",
|
||||
SpecType::Tobalaba => "tobalaba",
|
||||
SpecType::Expanse => "expanse",
|
||||
SpecType::Musicoin => "musicoin",
|
||||
SpecType::Ellaism => "ellaism",
|
||||
SpecType::Easthub => "easthub",
|
||||
SpecType::Social => "social",
|
||||
SpecType::Olympic => "olympic",
|
||||
SpecType::Morden => "morden",
|
||||
SpecType::Ropsten => "ropsten",
|
||||
SpecType::Kovan => "kovan",
|
||||
SpecType::Tobalaba => "tobalaba",
|
||||
SpecType::Sokol => "sokol",
|
||||
SpecType::Dev => "dev",
|
||||
SpecType::Custom(ref custom) => custom,
|
||||
})
|
||||
@ -103,17 +109,19 @@ impl SpecType {
|
||||
let params = params.into();
|
||||
match *self {
|
||||
SpecType::Foundation => Ok(ethereum::new_foundation(params)),
|
||||
SpecType::Morden => Ok(ethereum::new_morden(params)),
|
||||
SpecType::Ropsten => Ok(ethereum::new_ropsten(params)),
|
||||
SpecType::Olympic => Ok(ethereum::new_olympic(params)),
|
||||
SpecType::Classic => Ok(ethereum::new_classic(params)),
|
||||
SpecType::Poanet => Ok(ethereum::new_poanet(params)),
|
||||
SpecType::Tobalaba => Ok(ethereum::new_tobalaba(params)),
|
||||
SpecType::Expanse => Ok(ethereum::new_expanse(params)),
|
||||
SpecType::Musicoin => Ok(ethereum::new_musicoin(params)),
|
||||
SpecType::Ellaism => Ok(ethereum::new_ellaism(params)),
|
||||
SpecType::Easthub => Ok(ethereum::new_easthub(params)),
|
||||
SpecType::Social => Ok(ethereum::new_social(params)),
|
||||
SpecType::Tobalaba => Ok(ethereum::new_tobalaba(params)),
|
||||
SpecType::Olympic => Ok(ethereum::new_olympic(params)),
|
||||
SpecType::Morden => Ok(ethereum::new_morden(params)),
|
||||
SpecType::Ropsten => Ok(ethereum::new_ropsten(params)),
|
||||
SpecType::Kovan => Ok(ethereum::new_kovan(params)),
|
||||
SpecType::Sokol => Ok(ethereum::new_sokol(params)),
|
||||
SpecType::Dev => Ok(Spec::new_instant()),
|
||||
SpecType::Custom(ref filename) => {
|
||||
let file = fs::File::open(filename).map_err(|e| format!("Could not load specification file at {}: {}", filename, e))?;
|
||||
@ -278,7 +286,7 @@ impl Default for MinerExtras {
|
||||
author: Default::default(),
|
||||
engine_signer: Default::default(),
|
||||
extra_data: version_data(),
|
||||
gas_range_target: (4_700_000.into(), 6_283_184.into()),
|
||||
gas_range_target: (8_000_000.into(), 10_000_000.into()),
|
||||
work_notify: Default::default(),
|
||||
}
|
||||
}
|
||||
@ -334,7 +342,7 @@ pub fn fatdb_switch_to_bool(switch: Switch, user_defaults: &UserDefaults, _algor
|
||||
}
|
||||
|
||||
pub fn mode_switch_to_bool(switch: Option<Mode>, user_defaults: &UserDefaults) -> Result<Mode, String> {
|
||||
Ok(switch.unwrap_or(user_defaults.mode.clone()))
|
||||
Ok(switch.unwrap_or(user_defaults.mode().clone()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -345,17 +353,31 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_spec_type_parsing() {
|
||||
assert_eq!(SpecType::Foundation, "foundation".parse().unwrap());
|
||||
assert_eq!(SpecType::Foundation, "frontier".parse().unwrap());
|
||||
assert_eq!(SpecType::Foundation, "homestead".parse().unwrap());
|
||||
assert_eq!(SpecType::Foundation, "byzantium".parse().unwrap());
|
||||
assert_eq!(SpecType::Foundation, "mainnet".parse().unwrap());
|
||||
assert_eq!(SpecType::Foundation, "foundation".parse().unwrap());
|
||||
assert_eq!(SpecType::Kovan, "testnet".parse().unwrap());
|
||||
assert_eq!(SpecType::Kovan, "kovan".parse().unwrap());
|
||||
assert_eq!(SpecType::Morden, "morden".parse().unwrap());
|
||||
assert_eq!(SpecType::Ropsten, "ropsten".parse().unwrap());
|
||||
assert_eq!(SpecType::Olympic, "olympic".parse().unwrap());
|
||||
assert_eq!(SpecType::Foundation, "ethereum".parse().unwrap());
|
||||
assert_eq!(SpecType::Classic, "classic".parse().unwrap());
|
||||
assert_eq!(SpecType::Classic, "frontier-dogmatic".parse().unwrap());
|
||||
assert_eq!(SpecType::Classic, "homestead-dogmatic".parse().unwrap());
|
||||
assert_eq!(SpecType::Poanet, "poanet".parse().unwrap());
|
||||
assert_eq!(SpecType::Poanet, "poacore".parse().unwrap());
|
||||
assert_eq!(SpecType::Tobalaba, "tobalaba".parse().unwrap());
|
||||
assert_eq!(SpecType::Expanse, "expanse".parse().unwrap());
|
||||
assert_eq!(SpecType::Musicoin, "musicoin".parse().unwrap());
|
||||
assert_eq!(SpecType::Ellaism, "ellaism".parse().unwrap());
|
||||
assert_eq!(SpecType::Easthub, "easthub".parse().unwrap());
|
||||
assert_eq!(SpecType::Social, "social".parse().unwrap());
|
||||
assert_eq!(SpecType::Olympic, "olympic".parse().unwrap());
|
||||
assert_eq!(SpecType::Morden, "morden".parse().unwrap());
|
||||
assert_eq!(SpecType::Morden, "classic-testnet".parse().unwrap());
|
||||
assert_eq!(SpecType::Ropsten, "ropsten".parse().unwrap());
|
||||
assert_eq!(SpecType::Kovan, "kovan".parse().unwrap());
|
||||
assert_eq!(SpecType::Kovan, "testnet".parse().unwrap());
|
||||
assert_eq!(SpecType::Sokol, "sokol".parse().unwrap());
|
||||
assert_eq!(SpecType::Sokol, "poasokol".parse().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -366,13 +388,19 @@ mod tests {
|
||||
#[test]
|
||||
fn test_spec_type_display() {
|
||||
assert_eq!(format!("{}", SpecType::Foundation), "foundation");
|
||||
assert_eq!(format!("{}", SpecType::Ropsten), "ropsten");
|
||||
assert_eq!(format!("{}", SpecType::Morden), "morden");
|
||||
assert_eq!(format!("{}", SpecType::Olympic), "olympic");
|
||||
assert_eq!(format!("{}", SpecType::Classic), "classic");
|
||||
assert_eq!(format!("{}", SpecType::Poanet), "poanet");
|
||||
assert_eq!(format!("{}", SpecType::Tobalaba), "tobalaba");
|
||||
assert_eq!(format!("{}", SpecType::Expanse), "expanse");
|
||||
assert_eq!(format!("{}", SpecType::Musicoin), "musicoin");
|
||||
assert_eq!(format!("{}", SpecType::Ellaism), "ellaism");
|
||||
assert_eq!(format!("{}", SpecType::Easthub), "easthub");
|
||||
assert_eq!(format!("{}", SpecType::Social), "social");
|
||||
assert_eq!(format!("{}", SpecType::Olympic), "olympic");
|
||||
assert_eq!(format!("{}", SpecType::Morden), "morden");
|
||||
assert_eq!(format!("{}", SpecType::Ropsten), "ropsten");
|
||||
assert_eq!(format!("{}", SpecType::Kovan), "kovan");
|
||||
assert_eq!(format!("{}", SpecType::Sokol), "sokol");
|
||||
assert_eq!(format!("{}", SpecType::Dev), "dev");
|
||||
assert_eq!(format!("{}", SpecType::Custom("foo/bar".into())), "foo/bar");
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ use std::str::FromStr;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
pub use parity_rpc::signer::SignerService;
|
||||
pub use parity_rpc::dapps::LocalDapp;
|
||||
|
||||
use ethcore_service::PrivateTxService;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
@ -35,7 +34,6 @@ use jsonrpc_core::{self as core, MetaIoHandler};
|
||||
use light::client::LightChainClient;
|
||||
use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache};
|
||||
use miner::external::ExternalMiner;
|
||||
use node_health::NodeHealth;
|
||||
use parity_reactor;
|
||||
use parity_rpc::dispatch::{FullDispatcher, LightDispatcher};
|
||||
use parity_rpc::informant::{ActivityNotifier, ClientNotifier};
|
||||
@ -225,7 +223,6 @@ pub struct FullDependencies {
|
||||
pub settings: Arc<NetworkSettings>,
|
||||
pub net_service: Arc<ManageNetwork>,
|
||||
pub updater: Arc<Updater>,
|
||||
pub health: NodeHealth,
|
||||
pub geth_compatibility: bool,
|
||||
pub ws_address: Option<Host>,
|
||||
pub fetch: FetchClient,
|
||||
@ -330,7 +327,6 @@ impl FullDependencies {
|
||||
self.sync.clone(),
|
||||
self.updater.clone(),
|
||||
self.net_service.clone(),
|
||||
self.health.clone(),
|
||||
self.secret_store.clone(),
|
||||
self.logger.clone(),
|
||||
self.settings.clone(),
|
||||
@ -431,7 +427,6 @@ pub struct LightDependencies<T> {
|
||||
pub secret_store: Arc<AccountProvider>,
|
||||
pub logger: Arc<RotatingLogger>,
|
||||
pub settings: Arc<NetworkSettings>,
|
||||
pub health: NodeHealth,
|
||||
pub on_demand: Arc<::light::on_demand::OnDemand>,
|
||||
pub cache: Arc<Mutex<LightDataCache>>,
|
||||
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
|
||||
@ -545,7 +540,6 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
|
||||
self.secret_store.clone(),
|
||||
self.logger.clone(),
|
||||
self.settings.clone(),
|
||||
self.health.clone(),
|
||||
signer,
|
||||
self.ws_address.clone(),
|
||||
self.gas_price_percentile,
|
||||
|
@ -15,7 +15,6 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::any::Any;
|
||||
use std::fmt;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::{Duration, Instant};
|
||||
use std::thread;
|
||||
@ -33,7 +32,6 @@ use ethcore_logger::{Config as LogConfig, RotatingLogger};
|
||||
use ethcore_service::ClientService;
|
||||
use ethereum_types::Address;
|
||||
use sync::{self, SyncConfig};
|
||||
#[cfg(feature = "work-notify")]
|
||||
use miner::work_notify::WorkPoster;
|
||||
use futures::IntoFuture;
|
||||
use futures_cpupool::CpuPool;
|
||||
@ -43,7 +41,6 @@ use journaldb::Algorithm;
|
||||
use light::Cache as LightDataCache;
|
||||
use miner::external::ExternalMiner;
|
||||
use node_filter::NodeFilter;
|
||||
use node_health;
|
||||
use parity_reactor::EventLoop;
|
||||
use parity_rpc::{Origin, Metadata, NetworkSettings, informant, is_major_importing};
|
||||
use updater::{UpdatePolicy, Updater};
|
||||
@ -96,7 +93,6 @@ pub struct RunCmd {
|
||||
pub miner_options: MinerOptions,
|
||||
pub gas_price_percentile: usize,
|
||||
pub poll_lifetime: u32,
|
||||
pub ntp_servers: Vec<String>,
|
||||
pub ws_conf: rpc::WsConfiguration,
|
||||
pub http_conf: rpc::HttpConfiguration,
|
||||
pub ipc_conf: rpc::IpcConfiguration,
|
||||
@ -189,7 +185,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
|
||||
cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
|
||||
|
||||
//print out running parity environment
|
||||
print_running_environment(&spec.name, &cmd.dirs, &db_dirs);
|
||||
print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
|
||||
|
||||
info!("Running in experimental {} mode.", Colour::Blue.bold().paint("Light Client"));
|
||||
|
||||
@ -288,28 +284,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
|
||||
|
||||
// the dapps server
|
||||
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config));
|
||||
let node_health = {
|
||||
struct LightSyncStatus(Arc<LightSync>);
|
||||
impl fmt::Debug for LightSyncStatus {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "Light Sync Status")
|
||||
}
|
||||
}
|
||||
impl node_health::SyncStatus for LightSyncStatus {
|
||||
fn is_major_importing(&self) -> bool { self.0.is_major_importing() }
|
||||
fn peers(&self) -> (usize, usize) {
|
||||
let peers = sync::LightSyncProvider::peer_numbers(&*self.0);
|
||||
(peers.connected, peers.max)
|
||||
}
|
||||
}
|
||||
|
||||
let sync_status = Arc::new(LightSyncStatus(light_sync.clone()));
|
||||
node_health::NodeHealth::new(
|
||||
sync_status.clone(),
|
||||
node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()),
|
||||
event_loop.remote(),
|
||||
)
|
||||
};
|
||||
|
||||
// start RPCs
|
||||
let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
|
||||
@ -317,7 +291,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
|
||||
client: client.clone(),
|
||||
sync: light_sync.clone(),
|
||||
net: light_sync.clone(),
|
||||
health: node_health,
|
||||
secret_store: account_provider,
|
||||
logger: logger,
|
||||
settings: Arc::new(cmd.net_settings),
|
||||
@ -429,7 +402,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
||||
}
|
||||
|
||||
//print out running parity environment
|
||||
print_running_environment(&spec.name, &cmd.dirs, &db_dirs);
|
||||
print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
|
||||
|
||||
// display info about used pruning algorithm
|
||||
info!("State DB configuration: {}{}{}",
|
||||
@ -504,19 +477,17 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
||||
cmd.miner_options,
|
||||
cmd.gas_pricer_conf.to_gas_pricer(fetch.clone(), cpu_pool.clone()),
|
||||
&spec,
|
||||
Some(account_provider.clone())
|
||||
Some(account_provider.clone()),
|
||||
|
||||
));
|
||||
miner.set_author(cmd.miner_extras.author, None).expect("Fails only if password is Some; password is None; qed");
|
||||
miner.set_gas_range_target(cmd.miner_extras.gas_range_target);
|
||||
miner.set_extra_data(cmd.miner_extras.extra_data);
|
||||
|
||||
#[cfg(feature = "work-notify")]
|
||||
{
|
||||
if !cmd.miner_extras.work_notify.is_empty() {
|
||||
miner.add_work_listener(Box::new(
|
||||
WorkPoster::new(&cmd.miner_extras.work_notify, fetch.clone(), event_loop.remote())
|
||||
));
|
||||
}
|
||||
if !cmd.miner_extras.work_notify.is_empty() {
|
||||
miner.add_work_listener(Box::new(
|
||||
WorkPoster::new(&cmd.miner_extras.work_notify, fetch.clone(), event_loop.remote())
|
||||
));
|
||||
}
|
||||
|
||||
let engine_signer = cmd.miner_extras.engine_signer;
|
||||
@ -721,40 +692,11 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
||||
let secret_store = account_provider.clone();
|
||||
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config));
|
||||
|
||||
// the dapps server
|
||||
let node_health = {
|
||||
let (sync, client) = (sync_provider.clone(), client.clone());
|
||||
|
||||
struct SyncStatus(Arc<sync::SyncProvider>, Arc<Client>, sync::NetworkConfiguration);
|
||||
impl fmt::Debug for SyncStatus {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "Dapps Sync Status")
|
||||
}
|
||||
}
|
||||
impl node_health::SyncStatus for SyncStatus {
|
||||
fn is_major_importing(&self) -> bool {
|
||||
is_major_importing(Some(self.0.status().state), self.1.queue_info())
|
||||
}
|
||||
fn peers(&self) -> (usize, usize) {
|
||||
let status = self.0.status();
|
||||
(status.num_peers, status.current_max_peers(self.2.min_peers, self.2.max_peers) as usize)
|
||||
}
|
||||
}
|
||||
|
||||
let sync_status = Arc::new(SyncStatus(sync, client, net_conf));
|
||||
node_health::NodeHealth::new(
|
||||
sync_status.clone(),
|
||||
node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()),
|
||||
event_loop.remote(),
|
||||
)
|
||||
};
|
||||
|
||||
let deps_for_rpc_apis = Arc::new(rpc_apis::FullDependencies {
|
||||
signer_service: signer_service,
|
||||
snapshot: snapshot_service.clone(),
|
||||
client: client.clone(),
|
||||
sync: sync_provider.clone(),
|
||||
health: node_health,
|
||||
net: manage_network.clone(),
|
||||
secret_store: secret_store,
|
||||
miner: miner.clone(),
|
||||
@ -824,13 +766,13 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
||||
user_defaults.pruning = algorithm;
|
||||
user_defaults.tracing = tracing;
|
||||
user_defaults.fat_db = fat_db;
|
||||
user_defaults.mode = mode;
|
||||
user_defaults.set_mode(mode);
|
||||
user_defaults.save(&user_defaults_path)?;
|
||||
|
||||
// tell client how to save the default mode if it gets changed.
|
||||
client.on_user_defaults_change(move |mode: Option<Mode>| {
|
||||
if let Some(mode) = mode {
|
||||
user_defaults.mode = mode;
|
||||
user_defaults.set_mode(mode);
|
||||
}
|
||||
let _ = user_defaults.save(&user_defaults_path); // discard failures - there's nothing we can do
|
||||
});
|
||||
@ -984,9 +926,9 @@ fn daemonize(_pid_file: String) -> Result<(), String> {
|
||||
Err("daemon is no supported on windows".into())
|
||||
}
|
||||
|
||||
fn print_running_environment(spec_name: &String, dirs: &Directories, db_dirs: &DatabaseDirectories) {
|
||||
fn print_running_environment(data_dir: &str, dirs: &Directories, db_dirs: &DatabaseDirectories) {
|
||||
info!("Starting {}", Colour::White.bold().paint(version()));
|
||||
info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(spec_name).to_string_lossy().into_owned()));
|
||||
info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(data_dir).to_string_lossy().into_owned()));
|
||||
info!("DB path {}", Colour::White.bold().paint(db_dirs.db_root_path().to_string_lossy().into_owned()));
|
||||
}
|
||||
|
||||
@ -1002,7 +944,7 @@ fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str,
|
||||
hardware_wallet_classic_key: spec == &SpecType::Classic,
|
||||
unlock_keep_secret: cfg.enable_fast_unlock,
|
||||
blacklisted_accounts: match *spec {
|
||||
SpecType::Morden | SpecType::Ropsten | SpecType::Kovan | SpecType::Dev => vec![],
|
||||
SpecType::Morden | SpecType::Ropsten | SpecType::Kovan | SpecType::Sokol | SpecType::Dev => vec![],
|
||||
_ => vec![
|
||||
"00a329c0648769a73afac7f9381e08fb43dbea72".into()
|
||||
],
|
||||
|
@ -17,12 +17,13 @@
|
||||
//! Parity upgrade logic
|
||||
|
||||
use semver::{Version, SemVerError};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::*;
|
||||
use std::fs::{self, File, create_dir_all};
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::{PathBuf, Path};
|
||||
use dir::{DatabaseDirectories, default_data_path, home_dir};
|
||||
use dir::{DatabaseDirectories, default_data_path};
|
||||
use dir::helpers::replace_home;
|
||||
use journaldb::Algorithm;
|
||||
|
||||
@ -105,7 +106,7 @@ fn with_locked_version<F>(db_path: Option<&str>, script: F) -> Result<usize, Err
|
||||
where F: Fn(&Version) -> Result<usize, Error>
|
||||
{
|
||||
let mut path = db_path.map_or({
|
||||
let mut path = home_dir().expect("Applications should have a home dir");
|
||||
let mut path = env::home_dir().expect("Applications should have a home dir");
|
||||
path.push(".parity");
|
||||
path
|
||||
}, PathBuf::from);
|
||||
|
@ -14,107 +14,130 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::collections::BTreeMap;
|
||||
use std::time::Duration;
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
use serde::de::{Error, Visitor, MapAccess};
|
||||
use serde::de::value::MapAccessDeserializer;
|
||||
use serde_json::Value;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde_json::de::from_reader;
|
||||
use serde_json::ser::to_string;
|
||||
use journaldb::Algorithm;
|
||||
use ethcore::client::Mode;
|
||||
use ethcore::client::{Mode as ClientMode};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Seconds(Duration);
|
||||
|
||||
impl Seconds {
|
||||
pub fn value(&self) -> u64 {
|
||||
self.0.as_secs()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Seconds {
|
||||
fn from(s: u64) -> Seconds {
|
||||
Seconds(Duration::from_secs(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Duration> for Seconds {
|
||||
fn from(d: Duration) -> Seconds {
|
||||
Seconds(d)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Duration> for Seconds {
|
||||
fn into(self) -> Duration {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Seconds {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_u64(self.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Seconds {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
let secs = u64::deserialize(deserializer)?;
|
||||
Ok(Seconds::from(secs))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase", tag = "mode")]
|
||||
pub enum Mode {
|
||||
Active,
|
||||
Passive {
|
||||
#[serde(rename = "mode.timeout")]
|
||||
timeout: Seconds,
|
||||
#[serde(rename = "mode.alarm")]
|
||||
alarm: Seconds,
|
||||
},
|
||||
Dark {
|
||||
#[serde(rename = "mode.timeout")]
|
||||
timeout: Seconds,
|
||||
},
|
||||
Offline,
|
||||
}
|
||||
|
||||
impl Into<ClientMode> for Mode {
|
||||
fn into(self) -> ClientMode {
|
||||
match self {
|
||||
Mode::Active => ClientMode::Active,
|
||||
Mode::Passive { timeout, alarm } => ClientMode::Passive(timeout.into(), alarm.into()),
|
||||
Mode::Dark { timeout } => ClientMode::Dark(timeout.into()),
|
||||
Mode::Offline => ClientMode::Off,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ClientMode> for Mode {
|
||||
fn from(mode: ClientMode) -> Mode {
|
||||
match mode {
|
||||
ClientMode::Active => Mode::Active,
|
||||
ClientMode::Passive(timeout, alarm) => Mode::Passive { timeout: timeout.into(), alarm: alarm.into() },
|
||||
ClientMode::Dark(timeout) => Mode::Dark { timeout: timeout.into() },
|
||||
ClientMode::Off => Mode::Offline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct UserDefaults {
|
||||
pub is_first_launch: bool,
|
||||
#[serde(with = "algorithm_serde")]
|
||||
pub pruning: Algorithm,
|
||||
pub tracing: bool,
|
||||
pub fat_db: bool,
|
||||
pub mode: Mode,
|
||||
#[serde(flatten)]
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
impl Serialize for UserDefaults {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
impl UserDefaults {
|
||||
pub fn mode(&self) -> ClientMode {
|
||||
self.mode.clone().into()
|
||||
}
|
||||
|
||||
pub fn set_mode(&mut self, mode: ClientMode) {
|
||||
self.mode = mode.into();
|
||||
}
|
||||
}
|
||||
|
||||
mod algorithm_serde {
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::Error;
|
||||
use journaldb::Algorithm;
|
||||
|
||||
pub fn serialize<S>(algorithm: &Algorithm, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer {
|
||||
let mut map: BTreeMap<String, Value> = BTreeMap::new();
|
||||
map.insert("is_first_launch".into(), Value::Bool(self.is_first_launch));
|
||||
map.insert("pruning".into(), Value::String(self.pruning.as_str().into()));
|
||||
map.insert("tracing".into(), Value::Bool(self.tracing));
|
||||
map.insert("fat_db".into(), Value::Bool(self.fat_db));
|
||||
let mode_str = match self.mode {
|
||||
Mode::Off => "offline",
|
||||
Mode::Dark(timeout) => {
|
||||
map.insert("mode.timeout".into(), Value::Number(timeout.as_secs().into()));
|
||||
"dark"
|
||||
},
|
||||
Mode::Passive(timeout, alarm) => {
|
||||
map.insert("mode.timeout".into(), Value::Number(timeout.as_secs().into()));
|
||||
map.insert("mode.alarm".into(), Value::Number(alarm.as_secs().into()));
|
||||
"passive"
|
||||
},
|
||||
Mode::Active => "active",
|
||||
};
|
||||
map.insert("mode".into(), Value::String(mode_str.into()));
|
||||
|
||||
map.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
struct UserDefaultsVisitor;
|
||||
|
||||
impl<'a> Deserialize<'a> for UserDefaults {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'a> {
|
||||
deserializer.deserialize_any(UserDefaultsVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visitor<'a> for UserDefaultsVisitor {
|
||||
type Value = UserDefaults;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "a valid UserDefaults object")
|
||||
algorithm.as_str().serialize(serializer)
|
||||
}
|
||||
|
||||
fn visit_map<V>(self, visitor: V) -> Result<Self::Value, V::Error> where V: MapAccess<'a> {
|
||||
let mut map: BTreeMap<String, Value> = Deserialize::deserialize(MapAccessDeserializer::new(visitor))?;
|
||||
let pruning: Value = map.remove("pruning").ok_or_else(|| Error::custom("missing pruning"))?;
|
||||
let pruning = pruning.as_str().ok_or_else(|| Error::custom("invalid pruning value"))?;
|
||||
let pruning = pruning.parse().map_err(|_| Error::custom("invalid pruning method"))?;
|
||||
let tracing: Value = map.remove("tracing").ok_or_else(|| Error::custom("missing tracing"))?;
|
||||
let tracing = tracing.as_bool().ok_or_else(|| Error::custom("invalid tracing value"))?;
|
||||
let fat_db: Value = map.remove("fat_db").unwrap_or_else(|| Value::Bool(false));
|
||||
let fat_db = fat_db.as_bool().ok_or_else(|| Error::custom("invalid fat_db value"))?;
|
||||
|
||||
let mode: Value = map.remove("mode").unwrap_or_else(|| Value::String("active".to_owned()));
|
||||
let mode = match mode.as_str().ok_or_else(|| Error::custom("invalid mode value"))? {
|
||||
"offline" => Mode::Off,
|
||||
"dark" => {
|
||||
let timeout = map.remove("mode.timeout").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))?;
|
||||
Mode::Dark(Duration::from_secs(timeout))
|
||||
},
|
||||
"passive" => {
|
||||
let timeout = map.remove("mode.timeout").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))?;
|
||||
let alarm = map.remove("mode.alarm").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.alarm value"))?;
|
||||
Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm))
|
||||
},
|
||||
"active" => Mode::Active,
|
||||
_ => { return Err(Error::custom("invalid mode value")); },
|
||||
};
|
||||
|
||||
let user_defaults = UserDefaults {
|
||||
is_first_launch: false,
|
||||
pruning: pruning,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
mode: mode,
|
||||
};
|
||||
|
||||
Ok(user_defaults)
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Algorithm, D::Error>
|
||||
where D: Deserializer<'de> {
|
||||
let pruning = String::deserialize(deserializer)?;
|
||||
pruning.parse().map_err(|_| Error::custom("invalid pruning method"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,11 +54,11 @@ ethkey = { path = "../ethkey" }
|
||||
ethstore = { path = "../ethstore" }
|
||||
fetch = { path = "../util/fetch" }
|
||||
keccak-hash = { git = "https://github.com/paritytech/parity-common" }
|
||||
node-health = { path = "../node-health" }
|
||||
parity-reactor = { path = "../util/reactor" }
|
||||
parity-updater = { path = "../updater" }
|
||||
parity-version = { path = "../util/version" }
|
||||
patricia-trie = { git = "https://github.com/paritytech/parity-common" }
|
||||
plain_hasher = { git = "https://github.com/paritytech/parity-common" }
|
||||
rlp = { git = "https://github.com/paritytech/parity-common" }
|
||||
stats = { path = "../util/stats" }
|
||||
vm = { path = "../ethcore/vm" }
|
||||
|
@ -50,8 +50,6 @@ impl TimeProvider for DefaultTimeProvider {
|
||||
const TIME_THRESHOLD: u64 = 7;
|
||||
/// minimal length of hash
|
||||
const TOKEN_LENGTH: usize = 16;
|
||||
/// special "initial" token used for authorization when there are no tokens yet.
|
||||
const INITIAL_TOKEN: &'static str = "initial";
|
||||
/// Separator between fields in serialized tokens file.
|
||||
const SEPARATOR: &'static str = ";";
|
||||
/// Number of seconds to keep unused tokens.
|
||||
@ -163,16 +161,6 @@ impl<T: TimeProvider> AuthCodes<T> {
|
||||
|
||||
let as_token = |code| keccak(format!("{}:{}", code, time));
|
||||
|
||||
// Check if it's the initial token.
|
||||
if self.is_empty() {
|
||||
let initial = &as_token(INITIAL_TOKEN) == hash;
|
||||
// Initial token can be used only once.
|
||||
if initial {
|
||||
let _ = self.generate_new();
|
||||
}
|
||||
return initial;
|
||||
}
|
||||
|
||||
// look for code
|
||||
for code in &mut self.codes {
|
||||
if &as_token(&code.code) == hash {
|
||||
@ -239,7 +227,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_true_if_code_is_initial_and_store_is_empty() {
|
||||
fn should_return_false_even_if_code_is_initial_and_store_is_empty() {
|
||||
// given
|
||||
let code = "initial";
|
||||
let time = 99;
|
||||
@ -250,7 +238,7 @@ mod tests {
|
||||
let res2 = codes.is_valid(&generate_hash(code, time), time);
|
||||
|
||||
// then
|
||||
assert_eq!(res1, true);
|
||||
assert_eq!(res1, false);
|
||||
assert_eq!(res2, false);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ pub trait HttpMetaExtractor: Send + Sync + 'static {
|
||||
/// Type of Metadata
|
||||
type Metadata: jsonrpc_core::Metadata;
|
||||
/// Extracts metadata from given params.
|
||||
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>, dapps_origin: Option<String>) -> Self::Metadata;
|
||||
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>) -> Self::Metadata;
|
||||
}
|
||||
|
||||
pub struct MetaExtractor<T> {
|
||||
@ -49,7 +49,6 @@ impl<M, T> http::MetaExtractor<M> for MetaExtractor<T> where
|
||||
|
||||
let origin = as_string(req.headers().get_raw("origin"));
|
||||
let user_agent = as_string(req.headers().get_raw("user-agent"));
|
||||
let dapps_origin = as_string(req.headers().get_raw("x-parity-origin"));
|
||||
self.extractor.read_metadata(origin, user_agent, dapps_origin)
|
||||
self.extractor.read_metadata(origin, user_agent)
|
||||
}
|
||||
}
|
||||
|
@ -60,11 +60,11 @@ extern crate ethkey;
|
||||
extern crate ethstore;
|
||||
extern crate fetch;
|
||||
extern crate keccak_hash as hash;
|
||||
extern crate node_health;
|
||||
extern crate parity_reactor;
|
||||
extern crate parity_updater as updater;
|
||||
extern crate parity_version as version;
|
||||
extern crate patricia_trie as trie;
|
||||
extern crate plain_hasher;
|
||||
extern crate rlp;
|
||||
extern crate stats;
|
||||
extern crate vm;
|
||||
@ -118,8 +118,8 @@ pub use http::{
|
||||
AccessControlAllowOrigin, Host, DomainsValidation
|
||||
};
|
||||
|
||||
pub use v1::{NetworkSettings, Metadata, Origin, informant, dispatch, signer, dapps};
|
||||
pub use v1::block_import::is_major_importing;
|
||||
pub use v1::{NetworkSettings, Metadata, Origin, informant, dispatch, signer};
|
||||
pub use v1::block_import::{is_major_importing, is_major_importing_or_waiting};
|
||||
pub use v1::extractors::{RpcExtractor, WsExtractor, WsStats, WsDispatcher};
|
||||
pub use authcodes::{AuthCodes, TimeProvider};
|
||||
pub use http_common::HttpMetaExtractor;
|
||||
|
@ -73,7 +73,7 @@ mod testsing {
|
||||
|
||||
// when
|
||||
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
|
||||
let expected = "34\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown via RPC\",\"id\":1}\n\n0\n\n";
|
||||
let expected = "4B\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / unknown agent via RPC\",\"id\":1}\n\n0\n\n";
|
||||
let res = request(server,
|
||||
&format!("\
|
||||
POST / HTTP/1.1\r\n\
|
||||
@ -98,7 +98,7 @@ mod testsing {
|
||||
|
||||
// when
|
||||
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
|
||||
let expected = "38\n{\"jsonrpc\":\"2.0\",\"result\":\"curl/7.16.3 via RPC\",\"id\":1}\n\n0\n\n";
|
||||
let expected = "49\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / curl/7.16.3 via RPC\",\"id\":1}\n\n0\n\n";
|
||||
let res = request(server,
|
||||
&format!("\
|
||||
POST / HTTP/1.1\r\n\
|
||||
@ -116,59 +116,4 @@ mod testsing {
|
||||
res.assert_status("HTTP/1.1 200 OK");
|
||||
assert_eq!(res.body, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_dapp_origin() {
|
||||
// given
|
||||
let (server, address) = serve();
|
||||
|
||||
// when
|
||||
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
|
||||
let expected = "3A\n{\"jsonrpc\":\"2.0\",\"result\":\"Dapp http://parity.io\",\"id\":1}\n\n0\n\n";
|
||||
let res = request(server,
|
||||
&format!("\
|
||||
POST / HTTP/1.1\r\n\
|
||||
Host: {}\r\n\
|
||||
Content-Type: application/json\r\n\
|
||||
Content-Length: {}\r\n\
|
||||
Origin: http://parity.io\r\n\
|
||||
Connection: close\r\n\
|
||||
User-Agent: curl/7.16.3\r\n\
|
||||
\r\n\
|
||||
{}
|
||||
", address, req.len(), req)
|
||||
);
|
||||
|
||||
// then
|
||||
res.assert_status("HTTP/1.1 200 OK");
|
||||
assert_eq!(res.body, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_extract_dapp_origin_from_extension() {
|
||||
// given
|
||||
let (server, address) = serve();
|
||||
|
||||
// when
|
||||
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
|
||||
let expected = "44\n{\"jsonrpc\":\"2.0\",\"result\":\"Dapp http://wallet.ethereum.org\",\"id\":1}\n\n0\n\n";
|
||||
let res = request(server,
|
||||
&format!("\
|
||||
POST / HTTP/1.1\r\n\
|
||||
Host: {}\r\n\
|
||||
Content-Type: application/json\r\n\
|
||||
Content-Length: {}\r\n\
|
||||
Origin: null\r\n\
|
||||
X-Parity-Origin: http://wallet.ethereum.org\r\n\
|
||||
Connection: close\r\n\
|
||||
User-Agent: curl/7.16.3\r\n\
|
||||
\r\n\
|
||||
{}
|
||||
", address, req.len(), req)
|
||||
);
|
||||
|
||||
// then
|
||||
res.assert_status("HTTP/1.1 200 OK");
|
||||
assert_eq!(res.body, expected);
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ mod testing {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_allow_initial_connection_but_only_once() {
|
||||
fn should_not_allow_initial_connection_even_once() {
|
||||
// given
|
||||
let (server, port, authcodes) = serve();
|
||||
let code = "initial";
|
||||
@ -160,26 +160,9 @@ mod testing {
|
||||
timestamp,
|
||||
)
|
||||
);
|
||||
let response2 = http_client::request(server.addr(),
|
||||
&format!("\
|
||||
GET / HTTP/1.1\r\n\
|
||||
Host: 127.0.0.1:{}\r\n\
|
||||
Connection: Close\r\n\
|
||||
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\
|
||||
Sec-WebSocket-Protocol:{:?}_{}\r\n\
|
||||
Sec-WebSocket-Version: 13\r\n\
|
||||
\r\n\
|
||||
{{}}
|
||||
",
|
||||
port,
|
||||
keccak(format!("{}:{}", code, timestamp)),
|
||||
timestamp,
|
||||
)
|
||||
);
|
||||
|
||||
// then
|
||||
assert_eq!(response1.status, "HTTP/1.1 101 Switching Protocols".to_owned());
|
||||
assert_eq!(response2.status, "HTTP/1.1 403 Forbidden".to_owned());
|
||||
http_client::assert_security_headers_present(&response2.headers, None);
|
||||
assert_eq!(response1.status, "HTTP/1.1 403 Forbidden".to_owned());
|
||||
http_client::assert_security_headers_present(&response1.headers, None);
|
||||
}
|
||||
}
|
||||
|
@ -36,14 +36,13 @@ pub struct RpcExtractor;
|
||||
impl HttpMetaExtractor for RpcExtractor {
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>, dapps_origin: Option<String>) -> Metadata {
|
||||
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>) -> Metadata {
|
||||
Metadata {
|
||||
origin: match (origin.as_ref().map(|s| s.as_str()), user_agent, dapps_origin) {
|
||||
(Some("null"), _, Some(dapp)) => Origin::Dapps(dapp.into()),
|
||||
(Some(dapp), _, _) => Origin::Dapps(dapp.to_owned().into()),
|
||||
(None, Some(service), _) => Origin::Rpc(service.into()),
|
||||
(None, _, _) => Origin::Rpc("unknown".into()),
|
||||
},
|
||||
origin: Origin::Rpc(
|
||||
format!("{} / {}",
|
||||
origin.unwrap_or("unknown origin".to_string()),
|
||||
user_agent.unwrap_or("unknown agent".to_string()))
|
||||
),
|
||||
session: None,
|
||||
}
|
||||
}
|
||||
@ -76,16 +75,15 @@ impl ws::MetaExtractor<Metadata> for WsExtractor {
|
||||
fn extract(&self, req: &ws::RequestContext) -> Metadata {
|
||||
let id = req.session_id as u64;
|
||||
|
||||
let dapp = req.origin.as_ref().map(|origin| (&**origin).into()).unwrap_or_default();
|
||||
let origin = match self.authcodes_path {
|
||||
Some(ref path) => {
|
||||
let authorization = req.protocols.get(0).and_then(|p| auth_token_hash(&path, p, true));
|
||||
match authorization {
|
||||
Some(id) => Origin::Signer { session: id.into(), dapp: dapp },
|
||||
None => Origin::Ws { session: id.into(), dapp: dapp },
|
||||
Some(id) => Origin::Signer { session: id.into() },
|
||||
None => Origin::Ws { session: id.into() },
|
||||
}
|
||||
},
|
||||
None => Origin::Ws { session: id.into(), dapp: dapp },
|
||||
None => Origin::Ws { session: id.into() },
|
||||
};
|
||||
let session = Some(Arc::new(Session::new(req.sender())));
|
||||
Metadata {
|
||||
@ -253,26 +251,13 @@ mod tests {
|
||||
let extractor = RpcExtractor;
|
||||
|
||||
// when
|
||||
let meta1 = extractor.read_metadata(None, None, None);
|
||||
let meta2 = extractor.read_metadata(None, Some("http://parity.io".to_owned()), None);
|
||||
let meta3 = extractor.read_metadata(None, Some("http://parity.io".to_owned()), Some("ignored".into()));
|
||||
let meta1 = extractor.read_metadata(None, None);
|
||||
let meta2 = extractor.read_metadata(None, Some("http://parity.io".to_owned()));
|
||||
let meta3 = extractor.read_metadata(None, Some("http://parity.io".to_owned()));
|
||||
|
||||
// then
|
||||
assert_eq!(meta1.origin, Origin::Rpc("unknown".into()));
|
||||
assert_eq!(meta2.origin, Origin::Rpc("http://parity.io".into()));
|
||||
assert_eq!(meta3.origin, Origin::Rpc("http://parity.io".into()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_dapps_origin() {
|
||||
// given
|
||||
let extractor = RpcExtractor;
|
||||
let dapp = "https://wallet.ethereum.org".to_owned();
|
||||
|
||||
// when
|
||||
let meta = extractor.read_metadata(Some("null".into()), None, Some(dapp.clone()));
|
||||
|
||||
// then
|
||||
assert_eq!(meta.origin, Origin::Dapps(dapp.into()));
|
||||
assert_eq!(meta1.origin, Origin::Rpc("unknown origin / unknown agent".into()));
|
||||
assert_eq!(meta2.origin, Origin::Rpc("unknown origin / http://parity.io".into()));
|
||||
assert_eq!(meta3.origin, Origin::Rpc("unknown origin / http://parity.io".into()));
|
||||
}
|
||||
}
|
||||
|
@ -19,16 +19,23 @@
|
||||
use ethcore::client::BlockQueueInfo;
|
||||
use sync::SyncState;
|
||||
|
||||
/// Check if client is during major sync or during block import.
|
||||
pub fn is_major_importing(sync_state: Option<SyncState>, queue_info: BlockQueueInfo) -> bool {
|
||||
/// Check if client is during major sync or during block import and allows defining whether 'waiting for peers' should
|
||||
/// be considered a syncing state.
|
||||
pub fn is_major_importing_or_waiting(sync_state: Option<SyncState>, queue_info: BlockQueueInfo, waiting_is_syncing_state: bool) -> bool {
|
||||
let is_syncing_state = sync_state.map_or(false, |s| match s {
|
||||
SyncState::Idle | SyncState::NewBlocks | SyncState::WaitingPeers => false,
|
||||
SyncState::Idle | SyncState::NewBlocks => false,
|
||||
SyncState::WaitingPeers if !waiting_is_syncing_state => false,
|
||||
_ => true,
|
||||
});
|
||||
let is_verifying = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3;
|
||||
is_verifying || is_syncing_state
|
||||
}
|
||||
|
||||
/// Check if client is during major sync or during block import.
|
||||
pub fn is_major_importing(sync_state: Option<SyncState>, queue_info: BlockQueueInfo) -> bool {
|
||||
is_major_importing_or_waiting(sync_state, queue_info, true)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ethcore::client::BlockQueueInfo;
|
||||
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2015-2018 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/>.
|
||||
|
||||
//! Dapps Service
|
||||
|
||||
use v1::types::LocalDapp;
|
||||
|
||||
/// Dapps Server service.
|
||||
pub trait DappsService: Send + Sync + 'static {
|
||||
/// List available local dapps.
|
||||
fn list_dapps(&self) -> Vec<LocalDapp>;
|
||||
/// Refresh local dapps list
|
||||
fn refresh_local_dapps(&self) -> bool;
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use ethcore::account_provider::{SignError as AccountError};
|
||||
use ethcore::client::BlockId;
|
||||
use ethcore::error::{Error as EthcoreError, ErrorKind, CallError};
|
||||
use jsonrpc_core::{futures, Error, ErrorCode, Value};
|
||||
use rlp::DecoderError;
|
||||
@ -100,6 +101,14 @@ pub fn request_rejected_limit() -> Error {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request_rejected_param_limit(limit: u64, items_desc: &str) -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::REQUEST_REJECTED_LIMIT),
|
||||
message: format!("Requested data size exceeds limit of {} {}.", limit, items_desc),
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn account<T: fmt::Debug>(error: &str, details: T) -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::ACCOUNT_ERROR),
|
||||
@ -211,14 +220,6 @@ pub fn signer_disabled() -> Error {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dapps_disabled() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
message: "Dapps Server is disabled. This API is not available.".into(),
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ws_disabled() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
@ -430,6 +431,19 @@ pub fn filter_not_found() -> Error {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filter_block_not_found(id: BlockId) -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), // Specified in EIP-234.
|
||||
message: "One of the blocks specified in filter (fromBlock, toBlock or blockHash) cannot be found".into(),
|
||||
data: Some(Value::String(match id {
|
||||
BlockId::Hash(hash) => format!("0x{:x}", hash),
|
||||
BlockId::Number(number) => format!("0x{:x}", number),
|
||||
BlockId::Earliest => "earliest".to_string(),
|
||||
BlockId::Latest => "latest".to_string(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
// on-demand sender cancelled.
|
||||
pub fn on_demand_cancel(_cancel: futures::sync::oneshot::Canceled) -> Error {
|
||||
internal("on-demand sender cancelled", "")
|
||||
|
@ -16,18 +16,14 @@
|
||||
|
||||
use transaction::{Transaction, SignedTransaction, Action};
|
||||
|
||||
use ethereum_types::U256;
|
||||
use jsonrpc_core::Error;
|
||||
use v1::helpers::CallRequest;
|
||||
|
||||
pub fn sign_call(request: CallRequest, gas_cap: bool) -> Result<SignedTransaction, Error> {
|
||||
let max_gas = 50_000_000.into();
|
||||
pub fn sign_call(request: CallRequest) -> Result<SignedTransaction, Error> {
|
||||
let max_gas = U256::from(50_000_000);
|
||||
let gas = match request.gas {
|
||||
Some(gas) if gas_cap && gas > max_gas => {
|
||||
warn!("Gas limit capped to {} (from {})", max_gas, gas);
|
||||
max_gas
|
||||
}
|
||||
Some(gas) => gas,
|
||||
None if gas_cap => max_gas,
|
||||
None => max_gas * 10,
|
||||
};
|
||||
let from = request.from.unwrap_or(0.into());
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
//! Helpers for fetching blockchain data either from the light client or the network.
|
||||
|
||||
use std::cmp;
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethcore::basic_account::BasicAccount;
|
||||
@ -31,7 +32,7 @@ use jsonrpc_macros::Trailing;
|
||||
|
||||
use light::cache::Cache;
|
||||
use light::client::LightChainClient;
|
||||
use light::cht;
|
||||
use light::{cht, MAX_HEADERS_PER_REQUEST};
|
||||
use light::on_demand::{
|
||||
request, OnDemand, HeaderRef, Request as OnDemandRequest,
|
||||
Response as OnDemandResponse, ExecutionResult,
|
||||
@ -42,12 +43,13 @@ use sync::LightSync;
|
||||
use ethereum_types::{U256, Address};
|
||||
use hash::H256;
|
||||
use parking_lot::Mutex;
|
||||
use plain_hasher::H256FastMap;
|
||||
use transaction::{Action, Transaction as EthTransaction, SignedTransaction, LocalizedTransaction};
|
||||
|
||||
use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch};
|
||||
use v1::types::{BlockNumber, CallRequest, Log, Transaction};
|
||||
|
||||
const NO_INVALID_BACK_REFS: &'static str = "Fails only on invalid back-references; back-references here known to be valid; qed";
|
||||
const NO_INVALID_BACK_REFS: &str = "Fails only on invalid back-references; back-references here known to be valid; qed";
|
||||
|
||||
/// Helper for fetching blockchain data either from the light client or the network
|
||||
/// as necessary.
|
||||
@ -207,7 +209,7 @@ impl LightFetch {
|
||||
}
|
||||
};
|
||||
|
||||
let from = req.from.unwrap_or(Address::zero());
|
||||
let from = req.from.unwrap_or_else(|| Address::zero());
|
||||
let nonce_fut = match req.nonce {
|
||||
Some(nonce) => Either::A(future::ok(Some(nonce))),
|
||||
None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))),
|
||||
@ -232,29 +234,16 @@ impl LightFetch {
|
||||
|
||||
// fetch missing transaction fields from the network.
|
||||
Box::new(nonce_fut.join(gas_price_fut).and_then(move |(nonce, gas_price)| {
|
||||
let action = req.to.map_or(Action::Create, Action::Call);
|
||||
let value = req.value.unwrap_or_else(U256::zero);
|
||||
let data = req.data.unwrap_or_default();
|
||||
|
||||
future::done(match (nonce, req.gas) {
|
||||
(Some(n), Some(gas)) => Ok((true, EthTransaction {
|
||||
nonce: n,
|
||||
action: action,
|
||||
gas: gas,
|
||||
gas_price: gas_price,
|
||||
value: value,
|
||||
data: data,
|
||||
})),
|
||||
(Some(n), None) => Ok((false, EthTransaction {
|
||||
nonce: n,
|
||||
action: action,
|
||||
gas: START_GAS.into(),
|
||||
gas_price: gas_price,
|
||||
value: value,
|
||||
data: data,
|
||||
})),
|
||||
(None, _) => Err(errors::unknown_block()),
|
||||
})
|
||||
future::done(
|
||||
Ok((req.gas.is_some(), EthTransaction {
|
||||
nonce: nonce.unwrap_or_default(),
|
||||
action: req.to.map_or(Action::Create, Action::Call),
|
||||
gas: req.gas.unwrap_or_else(|| START_GAS.into()),
|
||||
gas_price,
|
||||
value: req.value.unwrap_or_else(U256::zero),
|
||||
data: req.data.unwrap_or_default(),
|
||||
}))
|
||||
)
|
||||
}).join(header_fut).and_then(move |((gas_known, tx), hdr)| {
|
||||
// then request proved execution.
|
||||
// TODO: get last-hashes from network.
|
||||
@ -312,55 +301,67 @@ impl LightFetch {
|
||||
use std::collections::BTreeMap;
|
||||
use jsonrpc_core::futures::stream::{self, Stream};
|
||||
|
||||
// early exit for "to" block before "from" block.
|
||||
let best_number = self.client.chain_info().best_block_number;
|
||||
let block_number = |id| match id {
|
||||
BlockId::Earliest => Some(0),
|
||||
BlockId::Latest => Some(best_number),
|
||||
BlockId::Hash(h) => self.client.block_header(BlockId::Hash(h)).map(|hdr| hdr.number()),
|
||||
BlockId::Number(x) => Some(x),
|
||||
};
|
||||
const MAX_BLOCK_RANGE: u64 = 1000;
|
||||
|
||||
match (block_number(filter.to_block), block_number(filter.from_block)) {
|
||||
(Some(to), Some(from)) if to < from => return Either::A(future::ok(Vec::new())),
|
||||
(Some(_), Some(_)) => {},
|
||||
_ => return Either::A(future::err(errors::unknown_block())),
|
||||
}
|
||||
let fetcher = self.clone();
|
||||
self.headers_range_by_block_id(filter.from_block, filter.to_block, MAX_BLOCK_RANGE)
|
||||
.and_then(move |mut headers| {
|
||||
if headers.is_empty() {
|
||||
return Either::A(future::ok(Vec::new()));
|
||||
}
|
||||
|
||||
let maybe_future = self.sync.with_context(move |ctx| {
|
||||
// find all headers which match the filter, and fetch the receipts for each one.
|
||||
// match them with their numbers for easy sorting later.
|
||||
let bit_combos = filter.bloom_possibilities();
|
||||
let receipts_futures: Vec<_> = self.client.ancestry_iter(filter.to_block)
|
||||
.take_while(|ref hdr| BlockId::Number(hdr.number()) != filter.from_block)
|
||||
.take_while(|ref hdr| BlockId::Hash(hdr.hash()) != filter.from_block)
|
||||
.filter(|ref hdr| {
|
||||
let hdr_bloom = hdr.log_bloom();
|
||||
bit_combos.iter().find(|&bloom| hdr_bloom & *bloom == *bloom).is_some()
|
||||
})
|
||||
.map(|hdr| (hdr.number(), request::BlockReceipts(hdr.into())))
|
||||
.map(|(num, req)| self.on_demand.request(ctx, req).expect(NO_INVALID_BACK_REFS).map(move |x| (num, x)))
|
||||
.collect();
|
||||
let on_demand = &fetcher.on_demand;
|
||||
|
||||
// as the receipts come in, find logs within them which match the filter.
|
||||
// insert them into a BTreeMap to maintain order by number and block index.
|
||||
stream::futures_unordered(receipts_futures)
|
||||
.fold(BTreeMap::new(), move |mut matches, (num, receipts)| {
|
||||
for (block_index, log) in receipts.into_iter().flat_map(|r| r.logs).enumerate() {
|
||||
if filter.matches(&log) {
|
||||
matches.insert((num, block_index), log.into());
|
||||
}
|
||||
}
|
||||
future::ok(matches)
|
||||
}) // and then collect them into a vector.
|
||||
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
|
||||
.map_err(errors::on_demand_cancel)
|
||||
});
|
||||
let maybe_future = fetcher.sync.with_context(move |ctx| {
|
||||
// find all headers which match the filter, and fetch the receipts for each one.
|
||||
// match them with their numbers for easy sorting later.
|
||||
let bit_combos = filter.bloom_possibilities();
|
||||
let receipts_futures: Vec<_> = headers.drain(..)
|
||||
.filter(|ref hdr| {
|
||||
let hdr_bloom = hdr.log_bloom();
|
||||
bit_combos.iter().any(|bloom| hdr_bloom.contains_bloom(bloom))
|
||||
})
|
||||
.map(|hdr| (hdr.number(), hdr.hash(), request::BlockReceipts(hdr.into())))
|
||||
.map(|(num, hash, req)| on_demand.request(ctx, req).expect(NO_INVALID_BACK_REFS).map(move |x| (num, hash, x)))
|
||||
.collect();
|
||||
|
||||
match maybe_future {
|
||||
Some(fut) => Either::B(Either::A(fut)),
|
||||
None => Either::B(Either::B(future::err(errors::network_disabled()))),
|
||||
}
|
||||
// as the receipts come in, find logs within them which match the filter.
|
||||
// insert them into a BTreeMap to maintain order by number and block index.
|
||||
stream::futures_unordered(receipts_futures)
|
||||
.fold(BTreeMap::new(), move |mut matches, (num, hash, receipts)| {
|
||||
let mut block_index = 0;
|
||||
for (transaction_index, receipt) in receipts.into_iter().enumerate() {
|
||||
for (transaction_log_index, log) in receipt.logs.into_iter().enumerate() {
|
||||
if filter.matches(&log) {
|
||||
matches.insert((num, block_index), Log {
|
||||
address: log.address.into(),
|
||||
topics: log.topics.into_iter().map(Into::into).collect(),
|
||||
data: log.data.into(),
|
||||
block_hash: Some(hash.into()),
|
||||
block_number: Some(num.into()),
|
||||
// No way to easily retrieve transaction hash, so let's just skip it.
|
||||
transaction_hash: None,
|
||||
transaction_index: Some(transaction_index.into()),
|
||||
log_index: Some(block_index.into()),
|
||||
transaction_log_index: Some(transaction_log_index.into()),
|
||||
log_type: "mined".into(),
|
||||
removed: false,
|
||||
});
|
||||
}
|
||||
block_index += 1;
|
||||
}
|
||||
}
|
||||
future::ok(matches)
|
||||
}) // and then collect them into a vector.
|
||||
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
|
||||
.map_err(errors::on_demand_cancel)
|
||||
});
|
||||
|
||||
match maybe_future {
|
||||
Some(fut) => Either::B(Either::A(fut)),
|
||||
None => Either::B(Either::B(future::err(errors::network_disabled()))),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Get a transaction by hash. also returns the index in the block.
|
||||
@ -438,6 +439,150 @@ impl LightFetch {
|
||||
None => Box::new(future::err(errors::network_disabled())) as Box<Future<Item = _, Error = _> + Send>
|
||||
}
|
||||
}
|
||||
|
||||
fn headers_range_by_block_id(
|
||||
&self,
|
||||
from_block: BlockId,
|
||||
to_block: BlockId,
|
||||
max: u64
|
||||
) -> impl Future<Item = Vec<encoded::Header>, Error = Error> {
|
||||
let fetch_hashes = [from_block, to_block].iter()
|
||||
.filter_map(|block_id| match block_id {
|
||||
BlockId::Hash(hash) => Some(hash.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let best_number = self.client.chain_info().best_block_number;
|
||||
|
||||
let fetcher = self.clone();
|
||||
self.headers_by_hash(&fetch_hashes[..]).and_then(move |mut header_map| {
|
||||
let (from_block_num, to_block_num) = {
|
||||
let block_number = |id| match id {
|
||||
&BlockId::Earliest => 0,
|
||||
&BlockId::Latest => best_number,
|
||||
&BlockId::Hash(ref h) =>
|
||||
header_map.get(h).map(|hdr| hdr.number())
|
||||
.expect("from_block and to_block headers are fetched by hash; this closure is only called on from_block and to_block; qed"),
|
||||
&BlockId::Number(x) => x,
|
||||
};
|
||||
(block_number(&from_block), block_number(&to_block))
|
||||
};
|
||||
|
||||
if to_block_num < from_block_num {
|
||||
// early exit for "to" block before "from" block.
|
||||
return Either::A(future::err(errors::filter_block_not_found(to_block)));
|
||||
} else if to_block_num - from_block_num >= max {
|
||||
return Either::A(future::err(errors::request_rejected_param_limit(max, "blocks")));
|
||||
}
|
||||
|
||||
let to_header_hint = match to_block {
|
||||
BlockId::Hash(ref h) => header_map.remove(h),
|
||||
_ => None,
|
||||
};
|
||||
let headers_fut = fetcher.headers_range(from_block_num, to_block_num, to_header_hint);
|
||||
Either::B(headers_fut.map(move |headers| {
|
||||
// Validate from_block if it's a hash
|
||||
let last_hash = headers.last().map(|hdr| hdr.hash());
|
||||
match (last_hash, from_block) {
|
||||
(Some(h1), BlockId::Hash(h2)) if h1 != h2 => Vec::new(),
|
||||
_ => headers,
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
fn headers_by_hash(&self, hashes: &[H256]) -> impl Future<Item = H256FastMap<encoded::Header>, Error = Error> {
|
||||
let mut refs = H256FastMap::with_capacity_and_hasher(hashes.len(), Default::default());
|
||||
let mut reqs = Vec::with_capacity(hashes.len());
|
||||
|
||||
for hash in hashes {
|
||||
refs.entry(*hash).or_insert_with(|| {
|
||||
self.make_header_requests(BlockId::Hash(*hash), &mut reqs)
|
||||
.expect("make_header_requests never fails for BlockId::Hash; qed")
|
||||
});
|
||||
}
|
||||
|
||||
self.send_requests(reqs, move |res| {
|
||||
let headers = refs.drain()
|
||||
.map(|(hash, header_ref)| {
|
||||
let hdr = extract_header(&res, header_ref)
|
||||
.expect("these responses correspond to requests that header_ref belongs to; \
|
||||
qed");
|
||||
(hash, hdr)
|
||||
})
|
||||
.collect();
|
||||
headers
|
||||
})
|
||||
}
|
||||
|
||||
fn headers_range(
|
||||
&self,
|
||||
from_number: u64,
|
||||
to_number: u64,
|
||||
to_header_hint: Option<encoded::Header>
|
||||
) -> impl Future<Item = Vec<encoded::Header>, Error = Error> {
|
||||
let range_length = (to_number - from_number + 1) as usize;
|
||||
let mut headers: Vec<encoded::Header> = Vec::with_capacity(range_length);
|
||||
|
||||
let iter_start = match to_header_hint {
|
||||
Some(hdr) => {
|
||||
let block_id = BlockId::Hash(hdr.parent_hash());
|
||||
headers.push(hdr);
|
||||
block_id
|
||||
}
|
||||
None => BlockId::Number(to_number),
|
||||
};
|
||||
headers.extend(self.client.ancestry_iter(iter_start)
|
||||
.take_while(|hdr| hdr.number() >= from_number));
|
||||
|
||||
let fetcher = self.clone();
|
||||
future::loop_fn(headers, move |mut headers| {
|
||||
let remaining = range_length - headers.len();
|
||||
if remaining == 0 {
|
||||
return Either::A(future::ok(future::Loop::Break(headers)));
|
||||
}
|
||||
|
||||
let mut reqs: Vec<request::Request> = Vec::with_capacity(2);
|
||||
|
||||
let start_hash = if let Some(hdr) = headers.last() {
|
||||
hdr.parent_hash().into()
|
||||
} else {
|
||||
let cht_root = cht::block_to_cht_number(to_number)
|
||||
.and_then(|cht_num| fetcher.client.cht_root(cht_num as usize));
|
||||
|
||||
let cht_root = match cht_root {
|
||||
Some(cht_root) => cht_root,
|
||||
None => return Either::A(future::err(errors::unknown_block())),
|
||||
};
|
||||
|
||||
let header_proof = request::HeaderProof::new(to_number, cht_root)
|
||||
.expect("HeaderProof::new is Some(_) if cht::block_to_cht_number() is Some(_); \
|
||||
this would return above if block_to_cht_number returned None; qed");
|
||||
|
||||
let idx = reqs.len();
|
||||
let hash_ref = Field::back_ref(idx, 0);
|
||||
reqs.push(header_proof.into());
|
||||
|
||||
hash_ref
|
||||
};
|
||||
|
||||
let max = cmp::min(remaining as u64, MAX_HEADERS_PER_REQUEST);
|
||||
reqs.push(request::HeaderWithAncestors {
|
||||
block_hash: start_hash,
|
||||
ancestor_count: max - 1,
|
||||
}.into());
|
||||
|
||||
Either::B(fetcher.send_requests(reqs, |mut res| {
|
||||
match res.last_mut() {
|
||||
Some(&mut OnDemandResponse::HeaderWithAncestors(ref mut res_headers)) =>
|
||||
headers.extend(res_headers.drain(..)),
|
||||
_ => panic!("reqs has at least one entry; each request maps to a response; qed"),
|
||||
};
|
||||
future::Loop::Continue(headers)
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -18,7 +18,6 @@
|
||||
pub mod errors;
|
||||
|
||||
pub mod block_import;
|
||||
pub mod dapps;
|
||||
pub mod dispatch;
|
||||
pub mod fake_sign;
|
||||
pub mod ipfs;
|
||||
|
@ -17,9 +17,8 @@
|
||||
use std::collections::BTreeMap;
|
||||
use ethereum_types::{U256, Address};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use ethcore::account_provider::DappId;
|
||||
use v1::helpers::{ConfirmationRequest, ConfirmationPayload, oneshot, errors};
|
||||
use v1::types::{ConfirmationResponse, H160 as RpcH160, Origin, DappId as RpcDappId};
|
||||
use v1::types::{ConfirmationResponse, H160 as RpcH160, Origin};
|
||||
|
||||
use jsonrpc_core::Error;
|
||||
|
||||
@ -30,14 +29,6 @@ pub type ConfirmationResult = Result<ConfirmationResponse, Error>;
|
||||
pub enum DefaultAccount {
|
||||
/// Default account is known
|
||||
Provided(Address),
|
||||
/// Should use default account for dapp
|
||||
ForDapp(DappId),
|
||||
}
|
||||
|
||||
impl From<RpcDappId> for DefaultAccount {
|
||||
fn from(dapp_id: RpcDappId) -> Self {
|
||||
DefaultAccount::ForDapp(dapp_id.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RpcH160> for DefaultAccount {
|
||||
|
@ -21,20 +21,19 @@ use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
|
||||
use std::sync::Arc;
|
||||
|
||||
use rlp::{self, Rlp};
|
||||
use ethereum_types::{U256, H64, H160, H256, Address};
|
||||
use ethereum_types::{U256, H64, H256, Address};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use ethash::SeedHashCompute;
|
||||
use ethcore::account_provider::{AccountProvider, DappId};
|
||||
use ethash::{self, SeedHashCompute};
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo};
|
||||
use ethcore::ethereum::Ethash;
|
||||
use ethcore::filter::Filter as EthcoreFilter;
|
||||
use ethcore::header::{BlockNumber as EthBlockNumber};
|
||||
use ethcore::log_entry::LogEntry;
|
||||
use ethcore::miner::{self, MinerService};
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethcore::encoded;
|
||||
use sync::{SyncProvider};
|
||||
use sync::SyncProvider;
|
||||
use miner::external::ExternalMinerService;
|
||||
use transaction::{SignedTransaction, LocalizedTransaction};
|
||||
|
||||
@ -53,7 +52,7 @@ use v1::types::{
|
||||
};
|
||||
use v1::metadata::Metadata;
|
||||
|
||||
const EXTRA_INFO_PROOF: &'static str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed";
|
||||
const EXTRA_INFO_PROOF: &str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed";
|
||||
|
||||
/// Eth RPC options
|
||||
pub struct EthClientOptions {
|
||||
@ -400,13 +399,6 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> EthClient<C, SN, S
|
||||
Ok(Some(block))
|
||||
}
|
||||
|
||||
fn dapp_accounts(&self, dapp: DappId) -> Result<Vec<H160>> {
|
||||
self.accounts
|
||||
.note_dapp_used(dapp.clone())
|
||||
.and_then(|_| self.accounts.dapp_addresses(dapp))
|
||||
.map_err(|e| errors::account("Could not fetch accounts.", e))
|
||||
}
|
||||
|
||||
fn get_state(&self, number: BlockNumber) -> StateOrBlock {
|
||||
match number {
|
||||
BlockNumber::Num(num) => BlockId::Number(num).into(),
|
||||
@ -509,15 +501,17 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
}
|
||||
}
|
||||
|
||||
fn author(&self, meta: Metadata) -> Result<RpcH160> {
|
||||
let dapp = meta.dapp_id();
|
||||
|
||||
let mut miner = self.miner.authoring_params().author;
|
||||
fn author(&self) -> Result<RpcH160> {
|
||||
let miner = self.miner.authoring_params().author;
|
||||
if miner == 0.into() {
|
||||
miner = self.dapp_accounts(dapp.into())?.get(0).cloned().unwrap_or_default();
|
||||
self.accounts.accounts()
|
||||
.ok()
|
||||
.and_then(|a| a.first().cloned())
|
||||
.map(From::from)
|
||||
.ok_or_else(|| errors::account("No accounts were found", ""))
|
||||
} else {
|
||||
Ok(RpcH160::from(miner))
|
||||
}
|
||||
|
||||
Ok(RpcH160::from(miner))
|
||||
}
|
||||
|
||||
fn is_mining(&self) -> Result<bool> {
|
||||
@ -532,10 +526,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)))
|
||||
}
|
||||
|
||||
fn accounts(&self, meta: Metadata) -> Result<Vec<RpcH160>> {
|
||||
let dapp = meta.dapp_id();
|
||||
|
||||
let accounts = self.dapp_accounts(dapp.into())?;
|
||||
fn accounts(&self) -> Result<Vec<RpcH160>> {
|
||||
let accounts = self.accounts.accounts()
|
||||
.map_err(|e| errors::account("Could not fetch accounts.", e))?;
|
||||
Ok(accounts.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
@ -744,9 +737,11 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
|
||||
// check if we're still syncing and return empty strings in that case
|
||||
{
|
||||
//TODO: check if initial sync is complete here
|
||||
//let sync = self.sync;
|
||||
if /*sync.status().state != SyncState::Idle ||*/ self.client.queue_info().total_queue_size() > MAX_QUEUE_SIZE_TO_MINE_ON {
|
||||
let sync_status = self.sync.status();
|
||||
let queue_info = self.client.queue_info();
|
||||
let total_queue_size = queue_info.total_queue_size();
|
||||
|
||||
if sync_status.is_snapshot_syncing() || total_queue_size > MAX_QUEUE_SIZE_TO_MINE_ON {
|
||||
trace!(target: "miner", "Syncing. Cannot give any work.");
|
||||
return Err(errors::no_work());
|
||||
}
|
||||
@ -769,7 +764,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
})?;
|
||||
|
||||
let (pow_hash, number, timestamp, difficulty) = work;
|
||||
let target = Ethash::difficulty_to_boundary(&difficulty);
|
||||
let target = ethash::difficulty_to_boundary(&difficulty);
|
||||
let seed_hash = self.seed_compute.lock().hash_block_number(number);
|
||||
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
|
||||
@ -836,9 +831,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
self.send_raw_transaction(raw)
|
||||
}
|
||||
|
||||
fn call(&self, meta: Self::Metadata, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
|
||||
fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
|
||||
let request = CallRequest::into(request);
|
||||
let signed = try_bf!(fake_sign::sign_call(request, meta.is_dapp()));
|
||||
let signed = try_bf!(fake_sign::sign_call(request));
|
||||
|
||||
let num = num.unwrap_or_default();
|
||||
|
||||
@ -876,9 +871,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
))
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, meta: Self::Metadata, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
let request = CallRequest::into(request);
|
||||
let signed = try_bf!(fake_sign::sign_call(request, meta.is_dapp()));
|
||||
let signed = try_bf!(fake_sign::sign_call(request));
|
||||
let num = num.unwrap_or_default();
|
||||
|
||||
let (state, header) = if num == BlockNumber::Pending {
|
||||
|
@ -29,7 +29,7 @@ use light::client::LightChainClient;
|
||||
use light::{cht, TransactionQueue};
|
||||
use light::on_demand::{request, OnDemand};
|
||||
|
||||
use ethcore::account_provider::{AccountProvider, DappId};
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::encoded;
|
||||
use ethcore::filter::Filter as EthcoreFilter;
|
||||
use ethcore::ids::BlockId;
|
||||
@ -252,8 +252,12 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn author(&self, _meta: Self::Metadata) -> Result<RpcH160> {
|
||||
Ok(Default::default())
|
||||
fn author(&self) -> Result<RpcH160> {
|
||||
self.accounts.accounts()
|
||||
.ok()
|
||||
.and_then(|a| a.first().cloned())
|
||||
.map(From::from)
|
||||
.ok_or_else(|| errors::account("No accounts were found", ""))
|
||||
}
|
||||
|
||||
fn is_mining(&self) -> Result<bool> {
|
||||
@ -271,12 +275,8 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
.unwrap_or_else(Default::default))
|
||||
}
|
||||
|
||||
fn accounts(&self, meta: Metadata) -> Result<Vec<RpcH160>> {
|
||||
let dapp: DappId = meta.dapp_id().into();
|
||||
|
||||
self.accounts
|
||||
.note_dapp_used(dapp.clone())
|
||||
.and_then(|_| self.accounts.dapp_addresses(dapp))
|
||||
fn accounts(&self) -> Result<Vec<RpcH160>> {
|
||||
self.accounts.accounts()
|
||||
.map_err(|e| errors::account("Could not fetch accounts.", e))
|
||||
.map(|accs| accs.into_iter().map(Into::<RpcH160>::into).collect())
|
||||
}
|
||||
@ -398,7 +398,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
self.send_raw_transaction(raw)
|
||||
}
|
||||
|
||||
fn call(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
|
||||
fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
|
||||
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
|
||||
match res {
|
||||
Ok(exec) => Ok(exec.output.into()),
|
||||
@ -407,7 +407,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
// TODO: binary chop for more accurate estimates.
|
||||
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
|
||||
match res {
|
||||
|
@ -26,7 +26,6 @@ use ethstore::random_phrase;
|
||||
use sync::LightSyncProvider;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore_logger::RotatingLogger;
|
||||
use node_health::{NodeHealth, Health};
|
||||
use ethcore::ids::BlockId;
|
||||
|
||||
use light::client::LightChainClient;
|
||||
@ -44,7 +43,7 @@ use v1::types::{
|
||||
Peers, Transaction, RpcSettings, Histogram,
|
||||
TransactionStats, LocalTransactionStatus,
|
||||
BlockNumber, ConsensusCapability, VersionInfo,
|
||||
OperationsInfo, DappId, ChainStatus,
|
||||
OperationsInfo, ChainStatus,
|
||||
AccountInfo, HwAccountInfo, Header, RichHeader,
|
||||
};
|
||||
use Host;
|
||||
@ -56,7 +55,6 @@ pub struct ParityClient {
|
||||
accounts: Arc<AccountProvider>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
health: NodeHealth,
|
||||
signer: Option<Arc<SignerService>>,
|
||||
ws_address: Option<Host>,
|
||||
eip86_transition: u64,
|
||||
@ -71,7 +69,6 @@ impl ParityClient {
|
||||
accounts: Arc<AccountProvider>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
health: NodeHealth,
|
||||
signer: Option<Arc<SignerService>>,
|
||||
ws_address: Option<Host>,
|
||||
gas_price_percentile: usize,
|
||||
@ -81,7 +78,6 @@ impl ParityClient {
|
||||
accounts,
|
||||
logger,
|
||||
settings,
|
||||
health,
|
||||
signer,
|
||||
ws_address,
|
||||
eip86_transition: client.eip86_transition(),
|
||||
@ -105,13 +101,10 @@ impl ParityClient {
|
||||
impl Parity for ParityClient {
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn accounts_info(&self, dapp: Trailing<DappId>) -> Result<BTreeMap<H160, AccountInfo>> {
|
||||
let dapp = dapp.unwrap_or_default();
|
||||
|
||||
fn accounts_info(&self) -> Result<BTreeMap<H160, AccountInfo>> {
|
||||
let store = &self.accounts;
|
||||
let dapp_accounts = store
|
||||
.note_dapp_used(dapp.clone().into())
|
||||
.and_then(|_| store.dapp_addresses(dapp.into()))
|
||||
.accounts()
|
||||
.map_err(|e| errors::account("Could not fetch accounts.", e))?
|
||||
.into_iter().collect::<HashSet<_>>();
|
||||
|
||||
@ -142,10 +135,9 @@ impl Parity for ParityClient {
|
||||
Ok(store.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))?)
|
||||
}
|
||||
|
||||
fn default_account(&self, meta: Self::Metadata) -> Result<H160> {
|
||||
let dapp_id = meta.dapp_id();
|
||||
fn default_account(&self) -> Result<H160> {
|
||||
Ok(self.accounts
|
||||
.dapp_addresses(dapp_id.into())
|
||||
.accounts()
|
||||
.ok()
|
||||
.and_then(|accounts| accounts.get(0).cloned())
|
||||
.map(|acc| acc.into())
|
||||
@ -326,10 +318,6 @@ impl Parity for ParityClient {
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
fn dapps_url(&self) -> Result<String> {
|
||||
Err(errors::dapps_disabled())
|
||||
}
|
||||
|
||||
fn ws_url(&self) -> Result<String> {
|
||||
helpers::to_url(&self.ws_address)
|
||||
.ok_or_else(|| errors::ws_disabled())
|
||||
@ -433,12 +421,7 @@ impl Parity for ParityClient {
|
||||
ipfs::cid(content)
|
||||
}
|
||||
|
||||
fn call(&self, _meta: Self::Metadata, _requests: Vec<CallRequest>, _block: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
|
||||
fn call(&self, _requests: Vec<CallRequest>, _block: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn node_health(&self) -> BoxFuture<Health> {
|
||||
Box::new(self.health.health()
|
||||
.map_err(|err| errors::internal("Health API failure.", err)))
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ use jsonrpc_core::{Result, BoxFuture};
|
||||
use jsonrpc_core::futures::Future;
|
||||
use v1::helpers::errors;
|
||||
use v1::traits::ParitySet;
|
||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction, LocalDapp};
|
||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
|
||||
|
||||
/// Parity-specific rpc interface for operations altering the settings.
|
||||
pub struct ParitySetClient<F> {
|
||||
@ -137,14 +137,6 @@ impl<F: Fetch> ParitySet for ParitySetClient<F> {
|
||||
Box::new(self.pool.spawn(future))
|
||||
}
|
||||
|
||||
fn dapps_refresh(&self) -> Result<bool> {
|
||||
Err(errors::dapps_disabled())
|
||||
}
|
||||
|
||||
fn dapps_list(&self) -> Result<Vec<LocalDapp>> {
|
||||
Err(errors::dapps_disabled())
|
||||
}
|
||||
|
||||
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
@ -46,11 +46,11 @@ impl Traces for TracesClient {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn call(&self, _meta: Self::Metadata, _request: CallRequest, _flags: TraceOptions, _block: Trailing<BlockNumber>) -> Result<TraceResults> {
|
||||
fn call(&self, _request: CallRequest, _flags: TraceOptions, _block: Trailing<BlockNumber>) -> Result<TraceResults> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn call_many(&self, _meta: Self::Metadata, _request: Vec<(CallRequest, TraceOptions)>, _block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
|
||||
fn call_many(&self, _request: Vec<(CallRequest, TraceOptions)>, _block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,12 @@ use v1::traits::Net;
|
||||
|
||||
/// Net rpc implementation.
|
||||
pub struct NetClient<S: ?Sized> {
|
||||
sync: Arc<S>
|
||||
sync: Arc<S>,
|
||||
/// Cached `network_id`.
|
||||
///
|
||||
/// We cache it to avoid redundant aquire of sync read lock.
|
||||
/// https://github.com/paritytech/parity-ethereum/issues/8746
|
||||
network_id: u64,
|
||||
}
|
||||
|
||||
impl<S: ?Sized> NetClient<S> where S: SyncProvider {
|
||||
@ -30,17 +35,18 @@ impl<S: ?Sized> NetClient<S> where S: SyncProvider {
|
||||
pub fn new(sync: &Arc<S>) -> Self {
|
||||
NetClient {
|
||||
sync: sync.clone(),
|
||||
network_id: sync.status().network_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ?Sized> Net for NetClient<S> where S: SyncProvider + 'static {
|
||||
fn version(&self) -> Result<String> {
|
||||
Ok(format!("{}", self.sync.status().network_id).to_owned())
|
||||
Ok(format!("{}", self.network_id))
|
||||
}
|
||||
|
||||
fn peer_count(&self) -> Result<String> {
|
||||
Ok(format!("0x{:x}", self.sync.status().num_peers as u64).to_owned())
|
||||
Ok(format!("{:#x}", self.sync.status().num_peers as u64))
|
||||
}
|
||||
|
||||
fn is_listening(&self) -> Result<bool> {
|
||||
|
@ -32,10 +32,9 @@ use ethcore::ids::BlockId;
|
||||
use ethcore::miner::{self, MinerService};
|
||||
use ethcore::state::StateInfo;
|
||||
use ethcore_logger::RotatingLogger;
|
||||
use node_health::{NodeHealth, Health};
|
||||
use updater::{Service as UpdateService};
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_core::futures::{future, Future};
|
||||
use jsonrpc_core::futures::future;
|
||||
use jsonrpc_macros::Trailing;
|
||||
use v1::helpers::{self, errors, fake_sign, ipfs, SigningQueue, SignerService, NetworkSettings};
|
||||
use v1::metadata::Metadata;
|
||||
@ -45,7 +44,7 @@ use v1::types::{
|
||||
Peers, Transaction, RpcSettings, Histogram,
|
||||
TransactionStats, LocalTransactionStatus,
|
||||
BlockNumber, ConsensusCapability, VersionInfo,
|
||||
OperationsInfo, DappId, ChainStatus,
|
||||
OperationsInfo, ChainStatus,
|
||||
AccountInfo, HwAccountInfo, RichHeader,
|
||||
block_number_to_id
|
||||
};
|
||||
@ -58,7 +57,6 @@ pub struct ParityClient<C, M, U> {
|
||||
updater: Arc<U>,
|
||||
sync: Arc<SyncProvider>,
|
||||
net: Arc<ManageNetwork>,
|
||||
health: NodeHealth,
|
||||
accounts: Arc<AccountProvider>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
@ -77,7 +75,6 @@ impl<C, M, U> ParityClient<C, M, U> where
|
||||
sync: Arc<SyncProvider>,
|
||||
updater: Arc<U>,
|
||||
net: Arc<ManageNetwork>,
|
||||
health: NodeHealth,
|
||||
accounts: Arc<AccountProvider>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
@ -91,7 +88,6 @@ impl<C, M, U> ParityClient<C, M, U> where
|
||||
sync,
|
||||
updater,
|
||||
net,
|
||||
health,
|
||||
accounts,
|
||||
logger,
|
||||
settings,
|
||||
@ -110,12 +106,8 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
|
||||
{
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn accounts_info(&self, dapp: Trailing<DappId>) -> Result<BTreeMap<H160, AccountInfo>> {
|
||||
let dapp = dapp.unwrap_or_default();
|
||||
|
||||
let dapp_accounts = self.accounts
|
||||
.note_dapp_used(dapp.clone().into())
|
||||
.and_then(|_| self.accounts.dapp_addresses(dapp.into()))
|
||||
fn accounts_info(&self) -> Result<BTreeMap<H160, AccountInfo>> {
|
||||
let dapp_accounts = self.accounts.accounts()
|
||||
.map_err(|e| errors::account("Could not fetch accounts.", e))?
|
||||
.into_iter().collect::<HashSet<_>>();
|
||||
|
||||
@ -139,16 +131,13 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fn locked_hardware_accounts_info(&self) -> Result<Vec<String>> {
|
||||
self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))
|
||||
}
|
||||
|
||||
fn default_account(&self, meta: Self::Metadata) -> Result<H160> {
|
||||
let dapp_id = meta.dapp_id();
|
||||
|
||||
Ok(self.accounts
|
||||
.dapp_default_address(dapp_id.into())
|
||||
fn default_account(&self) -> Result<H160> {
|
||||
Ok(self.accounts.default_account()
|
||||
.map(Into::into)
|
||||
.ok()
|
||||
.unwrap_or_default())
|
||||
@ -347,10 +336,6 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
|
||||
)
|
||||
}
|
||||
|
||||
fn dapps_url(&self) -> Result<String> {
|
||||
Err(errors::dapps_disabled())
|
||||
}
|
||||
|
||||
fn ws_url(&self) -> Result<String> {
|
||||
helpers::to_url(&self.ws_address)
|
||||
.ok_or_else(|| errors::ws_disabled())
|
||||
@ -435,11 +420,11 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
|
||||
ipfs::cid(content)
|
||||
}
|
||||
|
||||
fn call(&self, meta: Self::Metadata, requests: Vec<CallRequest>, num: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
|
||||
fn call(&self, requests: Vec<CallRequest>, num: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
|
||||
let requests = requests
|
||||
.into_iter()
|
||||
.map(|request| Ok((
|
||||
fake_sign::sign_call(request.into(), meta.is_dapp())?,
|
||||
fake_sign::sign_call(request.into())?,
|
||||
Default::default()
|
||||
)))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
@ -470,9 +455,4 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
|
||||
.map(|res| res.into_iter().map(|res| res.output.into()).collect())
|
||||
.map_err(errors::call)
|
||||
}
|
||||
|
||||
fn node_health(&self) -> BoxFuture<Health> {
|
||||
Box::new(self.health.health()
|
||||
.map_err(|err| errors::internal("Health API failure.", err)))
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use ethcore::account_provider::AccountProvider;
|
||||
use jsonrpc_core::Result;
|
||||
use v1::helpers::errors;
|
||||
use v1::traits::ParityAccounts;
|
||||
use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, DappId, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo};
|
||||
use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo};
|
||||
use ethkey::Password;
|
||||
|
||||
/// Account management (personal) rpc implementation.
|
||||
@ -143,61 +143,6 @@ impl ParityAccounts for ParityAccountsClient {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<RpcH160>>) -> Result<bool> {
|
||||
self.accounts.set_dapp_addresses(dapp.into(), addresses.map(into_vec))
|
||||
.map_err(|e| errors::account("Couldn't set dapp addresses.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<RpcH160>> {
|
||||
self.accounts.dapp_addresses(dapp.into())
|
||||
.map_err(|e| errors::account("Couldn't get dapp addresses.", e))
|
||||
.map(into_vec)
|
||||
}
|
||||
|
||||
fn set_dapp_default_address(&self, dapp: DappId, address: RpcH160) -> Result<bool> {
|
||||
self.accounts.set_dapp_default_address(dapp.into(), address.into())
|
||||
.map_err(|e| errors::account("Couldn't set dapp default address.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn dapp_default_address(&self, dapp: DappId) -> Result<RpcH160> {
|
||||
self.accounts.dapp_default_address(dapp.into())
|
||||
.map_err(|e| errors::account("Couldn't get dapp default address.", e))
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn set_new_dapps_addresses(&self, addresses: Option<Vec<RpcH160>>) -> Result<bool> {
|
||||
self.accounts
|
||||
.set_new_dapps_addresses(addresses.map(into_vec))
|
||||
.map_err(|e| errors::account("Couldn't set dapps addresses.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn new_dapps_addresses(&self) -> Result<Option<Vec<RpcH160>>> {
|
||||
self.accounts.new_dapps_addresses()
|
||||
.map_err(|e| errors::account("Couldn't get dapps addresses.", e))
|
||||
.map(|accounts| accounts.map(into_vec))
|
||||
}
|
||||
|
||||
fn set_new_dapps_default_address(&self, address: RpcH160) -> Result<bool> {
|
||||
self.accounts.set_new_dapps_default_address(address.into())
|
||||
.map_err(|e| errors::account("Couldn't set new dapps default address.", e))
|
||||
.map(|_| true)
|
||||
}
|
||||
|
||||
fn new_dapps_default_address(&self) -> Result<RpcH160> {
|
||||
self.accounts.new_dapps_default_address()
|
||||
.map_err(|e| errors::account("Couldn't get new dapps default address.", e))
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn recent_dapps(&self) -> Result<BTreeMap<DappId, u64>> {
|
||||
self.accounts.recent_dapps()
|
||||
.map_err(|e| errors::account("Couldn't get recent dapps.", e))
|
||||
.map(|map| map.into_iter().map(|(k, v)| (k.into(), v)).collect())
|
||||
}
|
||||
|
||||
fn import_geth_accounts(&self, addresses: Vec<RpcH160>) -> Result<Vec<RpcH160>> {
|
||||
self.accounts
|
||||
.import_geth_accounts(into_vec(addresses), false)
|
||||
|
@ -31,7 +31,7 @@ use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_core::futures::Future;
|
||||
use v1::helpers::errors;
|
||||
use v1::traits::ParitySet;
|
||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction, LocalDapp};
|
||||
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
|
||||
|
||||
/// Parity-specific rpc interface for operations altering the settings.
|
||||
pub struct ParitySetClient<C, M, U, F = fetch::Client> {
|
||||
@ -182,14 +182,6 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
||||
Box::new(self.pool.spawn(future))
|
||||
}
|
||||
|
||||
fn dapps_refresh(&self) -> Result<bool> {
|
||||
Err(errors::dapps_disabled())
|
||||
}
|
||||
|
||||
fn dapps_list(&self) -> Result<Vec<LocalDapp>> {
|
||||
Err(errors::dapps_disabled())
|
||||
}
|
||||
|
||||
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>> {
|
||||
Ok(self.updater.upgrade_ready().map(Into::into))
|
||||
}
|
||||
|
@ -58,14 +58,14 @@ impl<D: Dispatcher> PersonalClient<D> {
|
||||
}
|
||||
|
||||
impl<D: Dispatcher + 'static> PersonalClient<D> {
|
||||
fn do_sign_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<(PendingTransaction, D)> {
|
||||
fn do_sign_transaction(&self, _meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<(PendingTransaction, D)> {
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
let accounts = self.accounts.clone();
|
||||
|
||||
let default = match request.from.as_ref() {
|
||||
Some(account) => Ok(account.clone().into()),
|
||||
None => accounts
|
||||
.dapp_default_address(meta.dapp_id().into())
|
||||
.default_account()
|
||||
.map_err(|e| errors::account("Cannot find default account.", e)),
|
||||
};
|
||||
|
||||
|
@ -100,14 +100,14 @@ impl Private for PrivateClient {
|
||||
})
|
||||
}
|
||||
|
||||
fn private_call(&self, meta: Self::Metadata, block_number: BlockNumber, request: CallRequest) -> Result<Bytes, Error> {
|
||||
fn private_call(&self, block_number: BlockNumber, request: CallRequest) -> Result<Bytes, Error> {
|
||||
let id = match block_number {
|
||||
BlockNumber::Pending => return Err(errors::private_message_block_id_not_supported()),
|
||||
num => block_number_to_id(num)
|
||||
};
|
||||
|
||||
let request = CallRequest::into(request);
|
||||
let signed = fake_sign::sign_call(request, meta.is_dapp())?;
|
||||
let signed = fake_sign::sign_call(request)?;
|
||||
let client = self.unwrap_manager()?;
|
||||
let executed_result = client.private_call(id, &signed).map_err(|e| errors::private_message(e))?;
|
||||
Ok(executed_result.output.into())
|
||||
|
@ -112,7 +112,6 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
|
||||
let accounts = self.accounts.clone();
|
||||
let default_account = match default_account {
|
||||
DefaultAccount::Provided(acc) => acc,
|
||||
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
|
||||
};
|
||||
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
@ -138,8 +137,8 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
|
||||
impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn compose_transaction(&self, meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
|
||||
let default_account = self.accounts.dapp_default_address(meta.dapp_id().into()).ok().unwrap_or_default();
|
||||
fn compose_transaction(&self, _meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
|
||||
let default_account = self.accounts.default_account().ok().unwrap_or_default();
|
||||
Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into))
|
||||
}
|
||||
|
||||
@ -164,7 +163,7 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
|
||||
let remote = self.remote.clone();
|
||||
let confirmations = self.confirmations.clone();
|
||||
|
||||
Box::new(self.dispatch(RpcConfirmationPayload::SendTransaction(request), meta.dapp_id().into(), meta.origin)
|
||||
Box::new(self.dispatch(RpcConfirmationPayload::SendTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()), meta.origin)
|
||||
.map(|result| match result {
|
||||
DispatchResult::Value(v) => RpcEither::Or(v),
|
||||
DispatchResult::Future(id, future) => {
|
||||
@ -221,7 +220,7 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
|
||||
fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> {
|
||||
let res = self.dispatch(
|
||||
RpcConfirmationPayload::SendTransaction(request),
|
||||
meta.dapp_id().into(),
|
||||
DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()),
|
||||
meta.origin,
|
||||
);
|
||||
|
||||
@ -236,7 +235,7 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
|
||||
fn sign_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcRichRawTransaction> {
|
||||
let res = self.dispatch(
|
||||
RpcConfirmationPayload::SignTransaction(request),
|
||||
meta.dapp_id().into(),
|
||||
DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()),
|
||||
meta.origin,
|
||||
);
|
||||
|
||||
|
@ -55,7 +55,6 @@ impl<D: Dispatcher + 'static> SigningUnsafeClient<D> {
|
||||
let accounts = self.accounts.clone();
|
||||
let default = match account {
|
||||
DefaultAccount::Provided(acc) => acc,
|
||||
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
|
||||
};
|
||||
|
||||
let dis = self.dispatcher.clone();
|
||||
@ -80,8 +79,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
|
||||
}))
|
||||
}
|
||||
|
||||
fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> {
|
||||
Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), meta.dapp_id().into())
|
||||
fn send_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> {
|
||||
Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()))
|
||||
.then(|res| match res {
|
||||
Ok(RpcConfirmationResponse::SendTransaction(hash)) => Ok(hash),
|
||||
Err(e) => Err(e),
|
||||
@ -89,8 +88,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
|
||||
}))
|
||||
}
|
||||
|
||||
fn sign_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcRichRawTransaction> {
|
||||
Box::new(self.handle(RpcConfirmationPayload::SignTransaction(request), meta.dapp_id().into())
|
||||
fn sign_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcRichRawTransaction> {
|
||||
Box::new(self.handle(RpcConfirmationPayload::SignTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()))
|
||||
.then(|res| match res {
|
||||
Ok(RpcConfirmationResponse::SignTransaction(tx)) => Ok(tx),
|
||||
Err(e) => Err(e),
|
||||
@ -102,9 +101,9 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
|
||||
impl<D: Dispatcher + 'static> ParitySigning for SigningUnsafeClient<D> {
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn compose_transaction(&self, meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
|
||||
fn compose_transaction(&self, _meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
|
||||
let accounts = self.accounts.clone();
|
||||
let default_account = accounts.dapp_default_address(meta.dapp_id().into()).ok().unwrap_or_default();
|
||||
let default_account = accounts.default_account().ok().unwrap_or_default();
|
||||
Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into))
|
||||
}
|
||||
|
||||
|
@ -87,11 +87,11 @@ impl<C, S> Traces for TracesClient<C> where
|
||||
.map(LocalizedTrace::from))
|
||||
}
|
||||
|
||||
fn call(&self, meta: Self::Metadata, request: CallRequest, flags: TraceOptions, block: Trailing<BlockNumber>) -> Result<TraceResults> {
|
||||
fn call(&self, request: CallRequest, flags: TraceOptions, block: Trailing<BlockNumber>) -> Result<TraceResults> {
|
||||
let block = block.unwrap_or_default();
|
||||
|
||||
let request = CallRequest::into(request);
|
||||
let signed = fake_sign::sign_call(request, meta.is_dapp())?;
|
||||
let signed = fake_sign::sign_call(request)?;
|
||||
|
||||
let id = match block {
|
||||
BlockNumber::Num(num) => BlockId::Number(num),
|
||||
@ -109,13 +109,13 @@ impl<C, S> Traces for TracesClient<C> where
|
||||
.map_err(errors::call)
|
||||
}
|
||||
|
||||
fn call_many(&self, meta: Self::Metadata, requests: Vec<(CallRequest, TraceOptions)>, block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
|
||||
fn call_many(&self, requests: Vec<(CallRequest, TraceOptions)>, block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
|
||||
let block = block.unwrap_or_default();
|
||||
|
||||
let requests = requests.into_iter()
|
||||
.map(|(request, flags)| {
|
||||
let request = CallRequest::into(request);
|
||||
let signed = fake_sign::sign_call(request, meta.is_dapp())?;
|
||||
let signed = fake_sign::sign_call(request)?;
|
||||
Ok((signed, to_call_analytics(flags)))
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user