Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d5b372f44 | ||
|
|
abb41f60f4 | ||
|
|
ec81d67009 | ||
|
|
2a7dc644b7 | ||
|
|
b00a21f39a | ||
|
|
e9396e158b |
@@ -54,8 +54,6 @@ test-audit:
|
||||
build-linux:
|
||||
stage: build
|
||||
only: *releaseable_branches
|
||||
variables:
|
||||
CARGO_TARGET: x86_64-unknown-linux-gnu
|
||||
script:
|
||||
- scripts/gitlab/build-unix.sh
|
||||
<<: *collect_artifacts
|
||||
@@ -97,6 +95,23 @@ publish-docker:
|
||||
script:
|
||||
- scripts/gitlab/publish-docker.sh parity
|
||||
|
||||
publish-snap:
|
||||
stage: publish
|
||||
only: *releaseable_branches
|
||||
image: parity/snapcraft:gitlab-ci
|
||||
variables:
|
||||
BUILD_ARCH: amd64
|
||||
cache: {}
|
||||
before_script: *determine_version
|
||||
dependencies:
|
||||
- build-linux
|
||||
tags:
|
||||
- rust-stable
|
||||
script:
|
||||
- scripts/gitlab/publish-snap.sh
|
||||
allow_failure: true
|
||||
<<: *collect_artifacts
|
||||
|
||||
publish-awss3:
|
||||
stage: publish
|
||||
only: *releaseable_branches
|
||||
@@ -121,7 +136,7 @@ publish-docs:
|
||||
script:
|
||||
- scripts/gitlab/publish-docs.sh
|
||||
tags:
|
||||
- shell
|
||||
- linux-docker
|
||||
|
||||
build-android:
|
||||
stage: optional
|
||||
@@ -131,8 +146,9 @@ build-android:
|
||||
script:
|
||||
- scripts/gitlab/build-unix.sh
|
||||
tags:
|
||||
- rust-arm
|
||||
- linux-docker
|
||||
allow_failure: true
|
||||
<<: *collect_artifacts
|
||||
|
||||
test-beta:
|
||||
stage: optional
|
||||
|
||||
78
Cargo.lock
generated
78
Cargo.lock
generated
@@ -276,7 +276,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethjson 0.1.0",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -504,7 +504,7 @@ name = "elastic-array"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -635,7 +635,7 @@ dependencies = [
|
||||
"fake-hardware-wallet 0.0.1",
|
||||
"hardware-wallet 1.12.0",
|
||||
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.2.0",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -716,7 +716,7 @@ dependencies = [
|
||||
"fastmap 0.1.0",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hasher 0.1.1",
|
||||
@@ -769,7 +769,7 @@ dependencies = [
|
||||
"ethkey 0.3.0",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -854,7 +854,7 @@ dependencies = [
|
||||
"ethkey 0.3.0",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -963,7 +963,7 @@ dependencies = [
|
||||
"ethkey 0.3.0",
|
||||
"fastmap 0.1.0",
|
||||
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hasher 0.1.1",
|
||||
"kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -987,7 +987,7 @@ dependencies = [
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.3.0",
|
||||
"evm 0.1.0",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1109,7 +1109,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1219,7 +1219,7 @@ name = "fixed-hash"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1246,6 +1246,11 @@ dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
@@ -1361,8 +1366,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[[package]]
|
||||
name = "heapsize"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
source = "git+https://github.com/cheme/heapsize.git?branch=ec-macfix#421df390a930cb523a09e5528e6fe57b534b3b26"
|
||||
dependencies = [
|
||||
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1569,6 +1575,25 @@ name = "itoa"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "jemalloc-sys"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jemallocator"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.10.2"
|
||||
@@ -1595,7 +1620,7 @@ dependencies = [
|
||||
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fastmap 0.1.0",
|
||||
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hasher 0.1.1",
|
||||
"kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1922,7 +1947,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "memory-cache"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1937,7 +1962,7 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2210,7 +2235,7 @@ version = "1.12.0"
|
||||
dependencies = [
|
||||
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic_hook 0.1.0",
|
||||
"parity-ethereum 2.2.5",
|
||||
"parity-ethereum 2.2.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2226,7 +2251,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-ethereum"
|
||||
version = "2.2.5"
|
||||
version = "2.2.9"
|
||||
dependencies = [
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2275,7 +2300,7 @@ dependencies = [
|
||||
"parity-rpc-client 1.4.0",
|
||||
"parity-runtime 0.1.0",
|
||||
"parity-updater 1.12.0",
|
||||
"parity-version 2.2.5",
|
||||
"parity-version 2.2.9",
|
||||
"parity-whisper 0.1.0",
|
||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2430,7 +2455,7 @@ dependencies = [
|
||||
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-runtime 0.1.0",
|
||||
"parity-updater 1.12.0",
|
||||
"parity-version 2.2.5",
|
||||
"parity-version 2.2.9",
|
||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2527,7 +2552,7 @@ dependencies = [
|
||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.12.0",
|
||||
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-version 2.2.5",
|
||||
"parity-version 2.2.9",
|
||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2537,7 +2562,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-version"
|
||||
version = "2.2.5"
|
||||
version = "2.2.9"
|
||||
dependencies = [
|
||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2803,7 +2828,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pwasm-utils"
|
||||
version = "0.2.2"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3745,7 +3770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
|
||||
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -3937,7 +3962,7 @@ dependencies = [
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pwasm-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
"wasmi 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -4155,6 +4180,7 @@ dependencies = [
|
||||
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb"
|
||||
"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
|
||||
"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.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
|
||||
@@ -4167,7 +4193,7 @@ dependencies = [
|
||||
"checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c"
|
||||
"checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1"
|
||||
"checksum hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d91261ee336dd046ac7df28306cb297b7a7228bd1ae25e9a57f4ed5e0ab628c7"
|
||||
"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
|
||||
"checksum heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)" = "<none>"
|
||||
"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
|
||||
"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
|
||||
"checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "<none>"
|
||||
@@ -4189,6 +4215,8 @@ dependencies = [
|
||||
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
|
||||
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
|
||||
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
|
||||
"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
|
||||
"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3"
|
||||
"checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1"
|
||||
"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
"checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "<none>"
|
||||
@@ -4279,7 +4307,7 @@ dependencies = [
|
||||
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
|
||||
"checksum protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "52fbc45bf6709565e44ef31847eb7407b3c3c80af811ee884a04da071dcca12b"
|
||||
"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07"
|
||||
"checksum pwasm-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "90d2b3c5bf24275fc77db6b14ec00a7a085d8ff9d1c4215fb6f6263e8d7b01bc"
|
||||
"checksum pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9135bed7b452e20dbb395a2d519abaf0c46d60e7ecc02daeeab447d29bada1"
|
||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
|
||||
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity-ethereum"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "2.2.5"
|
||||
version = "2.2.9"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
@@ -137,3 +137,6 @@ members = [
|
||||
"util/patricia-trie-ethereum",
|
||||
"util/fastmap",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
heapsize = { git = "https://github.com/cheme/heapsize.git", branch = "ec-macfix" }
|
||||
|
||||
@@ -69,7 +69,6 @@ pub use error::{Error, ErrorKind};
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::time::Duration;
|
||||
use ethereum_types::{H128, H256, U256, Address};
|
||||
use hash::keccak;
|
||||
use rlp::*;
|
||||
@@ -82,7 +81,7 @@ use ethcore::executed::{Executed};
|
||||
use transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction};
|
||||
use ethcore::{contract_address as ethcore_contract_address};
|
||||
use ethcore::client::{
|
||||
Client, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage, BlockId, CallContract
|
||||
Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId, CallContract
|
||||
};
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
|
||||
@@ -102,6 +101,12 @@ const INIT_VEC_LEN: usize = 16;
|
||||
/// Size of nonce cache
|
||||
const NONCE_CACHE_SIZE: usize = 128;
|
||||
|
||||
/// Version for the initial private contract wrapper
|
||||
const INITIAL_PRIVATE_CONTRACT_VER: usize = 1;
|
||||
|
||||
/// Version for the private contract notification about private state changes added
|
||||
const PRIVATE_CONTRACT_WITH_NOTIFICATION_VER: usize = 2;
|
||||
|
||||
/// Configurtion for private transaction provider
|
||||
#[derive(Default, PartialEq, Debug, Clone)]
|
||||
pub struct ProviderConfig {
|
||||
@@ -203,29 +208,29 @@ impl Provider where {
|
||||
bail!(ErrorKind::BadTransactonType);
|
||||
}
|
||||
Action::Call(contract) => {
|
||||
let data = signed_transaction.rlp_bytes();
|
||||
let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?;
|
||||
let private = PrivateTransaction::new(encrypted_transaction, contract);
|
||||
let data = signed_transaction.rlp_bytes();
|
||||
let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?;
|
||||
let private = PrivateTransaction::new(encrypted_transaction, contract);
|
||||
// TODO [ToDr] Using BlockId::Latest is bad here,
|
||||
// the block may change in the middle of execution
|
||||
// causing really weird stuff to happen.
|
||||
// We should retrieve hash and stick to that. IMHO
|
||||
// best would be to change the API and only allow H256 instead of BlockID
|
||||
// in private-tx to avoid such mistakes.
|
||||
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest)?;
|
||||
let private_state = self.execute_private_transaction(BlockId::Latest, &signed_transaction)?;
|
||||
trace!(target: "privatetx", "Private transaction created, encrypted transaction: {:?}, private state: {:?}", private, private_state);
|
||||
let contract_validators = self.get_validators(BlockId::Latest, &contract)?;
|
||||
trace!(target: "privatetx", "Required validators: {:?}", contract_validators);
|
||||
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
|
||||
trace!(target: "privatetx", "Hashed effective private state for sender: {:?}", private_state_hash);
|
||||
self.transactions_for_signing.write().add_transaction(private.hash(), signed_transaction, contract_validators, private_state, contract_nonce)?;
|
||||
self.broadcast_private_transaction(private.hash(), private.rlp_bytes());
|
||||
Ok(Receipt {
|
||||
hash: tx_hash,
|
||||
contract_address: Some(contract),
|
||||
status_code: 0,
|
||||
})
|
||||
// the block may change in the middle of execution
|
||||
// causing really weird stuff to happen.
|
||||
// We should retrieve hash and stick to that. IMHO
|
||||
// best would be to change the API and only allow H256 instead of BlockID
|
||||
// in private-tx to avoid such mistakes.
|
||||
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest)?;
|
||||
let private_state = self.execute_private_transaction(BlockId::Latest, &signed_transaction)?;
|
||||
trace!(target: "privatetx", "Private transaction created, encrypted transaction: {:?}, private state: {:?}", private, private_state);
|
||||
let contract_validators = self.get_validators(BlockId::Latest, &contract)?;
|
||||
trace!(target: "privatetx", "Required validators: {:?}", contract_validators);
|
||||
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
|
||||
trace!(target: "privatetx", "Hashed effective private state for sender: {:?}", private_state_hash);
|
||||
self.transactions_for_signing.write().add_transaction(private.hash(), signed_transaction, contract_validators, private_state, contract_nonce)?;
|
||||
self.broadcast_private_transaction(private.hash(), private.rlp_bytes());
|
||||
Ok(Receipt {
|
||||
hash: tx_hash,
|
||||
contract_address: Some(contract),
|
||||
status_code: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,27 +276,27 @@ impl Provider where {
|
||||
let tx_action = transaction.transaction.action.clone();
|
||||
if let Action::Call(contract) = tx_action {
|
||||
// TODO [ToDr] Usage of BlockId::Latest
|
||||
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest);
|
||||
if let Err(e) = contract_nonce {
|
||||
bail!("Cannot retrieve contract nonce: {:?}", e);
|
||||
}
|
||||
let contract_nonce = contract_nonce.expect("Error was checked before");
|
||||
let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction);
|
||||
if let Err(e) = private_state {
|
||||
bail!("Cannot retrieve private state: {:?}", e);
|
||||
}
|
||||
let private_state = private_state.expect("Error was checked before");
|
||||
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
|
||||
trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash);
|
||||
let password = find_account_password(&self.passwords, &*self.accounts, &validator_account);
|
||||
let signed_state = self.accounts.sign(validator_account, password, private_state_hash);
|
||||
if let Err(e) = signed_state {
|
||||
bail!("Cannot sign the state: {:?}", e);
|
||||
}
|
||||
let signed_state = signed_state.expect("Error was checked before");
|
||||
let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None);
|
||||
trace!(target: "privatetx", "Sending signature for private transaction: {:?}", signed_private_transaction);
|
||||
self.broadcast_signed_private_transaction(signed_private_transaction.hash(), signed_private_transaction.rlp_bytes());
|
||||
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest);
|
||||
if let Err(e) = contract_nonce {
|
||||
bail!("Cannot retrieve contract nonce: {:?}", e);
|
||||
}
|
||||
let contract_nonce = contract_nonce.expect("Error was checked before");
|
||||
let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction);
|
||||
if let Err(e) = private_state {
|
||||
bail!("Cannot retrieve private state: {:?}", e);
|
||||
}
|
||||
let private_state = private_state.expect("Error was checked before");
|
||||
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
|
||||
trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash);
|
||||
let password = find_account_password(&self.passwords, &*self.accounts, &validator_account);
|
||||
let signed_state = self.accounts.sign(validator_account, password, private_state_hash);
|
||||
if let Err(e) = signed_state {
|
||||
bail!("Cannot sign the state: {:?}", e);
|
||||
}
|
||||
let signed_state = signed_state.expect("Error was checked before");
|
||||
let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None);
|
||||
trace!(target: "privatetx", "Sending signature for private transaction: {:?}", signed_private_transaction);
|
||||
self.broadcast_signed_private_transaction(signed_private_transaction.hash(), signed_private_transaction.rlp_bytes());
|
||||
} else {
|
||||
bail!("Incorrect type of action for the transaction");
|
||||
}
|
||||
@@ -327,7 +332,7 @@ impl Provider where {
|
||||
let mut signatures = desc.received_signatures.clone();
|
||||
signatures.push(signed_tx.signature());
|
||||
let rsv: Vec<Signature> = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect();
|
||||
//Create public transaction
|
||||
// Create public transaction
|
||||
let public_tx = self.public_transaction(
|
||||
desc.state.clone(),
|
||||
&desc.original_transaction,
|
||||
@@ -336,7 +341,7 @@ impl Provider where {
|
||||
desc.original_transaction.gas_price
|
||||
)?;
|
||||
trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx);
|
||||
//Sign and add it to the queue
|
||||
// Sign and add it to the queue
|
||||
let chain_id = desc.original_transaction.chain_id();
|
||||
let hash = public_tx.hash(chain_id);
|
||||
let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?;
|
||||
@@ -350,13 +355,13 @@ impl Provider where {
|
||||
bail!(err);
|
||||
}
|
||||
}
|
||||
//Remove from store for signing
|
||||
// Remove from store for signing
|
||||
if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) {
|
||||
warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err);
|
||||
bail!(err);
|
||||
}
|
||||
} else {
|
||||
//Add signature to the store
|
||||
// Add signature to the store
|
||||
match self.transactions_for_signing.write().add_signature(&private_hash, signed_tx.signature()) {
|
||||
Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"),
|
||||
Err(err) => {
|
||||
@@ -684,12 +689,11 @@ fn find_account_password(passwords: &Vec<Password>, account_provider: &AccountPr
|
||||
}
|
||||
|
||||
impl ChainNotify for Provider {
|
||||
fn new_blocks(&self, imported: Vec<H256>, _invalid: Vec<H256>, _route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) {
|
||||
if !imported.is_empty() {
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if new_blocks.imported.is_empty() || new_blocks.has_more_blocks_to_import { return }
|
||||
trace!(target: "privatetx", "New blocks imported, try to prune the queue");
|
||||
if let Err(err) = self.process_verification_queue() {
|
||||
warn!(target: "privatetx", "Cannot prune private transactions queue. error: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "Kovan",
|
||||
"name": "Kovan Testnet",
|
||||
"dataDir": "kovan",
|
||||
"engine": {
|
||||
"authorityRound": {
|
||||
"params": {
|
||||
"stepDuration": "4",
|
||||
"stepDuration": "0x4",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"validators" : {
|
||||
"list": [
|
||||
@@ -19,10 +19,10 @@
|
||||
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
|
||||
]
|
||||
},
|
||||
"validateScoreTransition": 4301764,
|
||||
"validateStepTransition": 1500000,
|
||||
"maximumUncleCountTransition": 5067000,
|
||||
"maximumUncleCount": 0
|
||||
"validateScoreTransition": "0x41a3c4",
|
||||
"validateStepTransition": "0x16e360",
|
||||
"maximumUncleCountTransition": "0x4d50f8",
|
||||
"maximumUncleCount": "0x0"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -32,24 +32,26 @@
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x2A",
|
||||
"forkBlock": 4297256,
|
||||
"forkCanonHash": "0x0a66d93c2f727dca618fabaf70c39b37018c73d78b939d8b11efbbd09034778f",
|
||||
"eip155Transition": 1000000,
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": 6600000,
|
||||
"validateChainIdTransition": 1000000,
|
||||
"validateReceiptsTransition" : 1000000,
|
||||
"eip140Transition": 5067000,
|
||||
"eip211Transition": 5067000,
|
||||
"eip214Transition": 5067000,
|
||||
"eip658Transition": 5067000,
|
||||
"wasmActivationTransition": 6600000,
|
||||
"eip145Transition": 9200000,
|
||||
"eip1014Transition": 9200000,
|
||||
"eip1052Transition": 9200000,
|
||||
"eip1283Transition": 9200000,
|
||||
"kip4Transition": 9200000,
|
||||
"kip6Transition": 9200000
|
||||
"forkBlock": "0x9766dc",
|
||||
"forkCanonHash": "0xf2fa4bcc417ad374100c2035aa865ff60fb568a83db1b6f6cb8fb52cfebc28b5",
|
||||
"eip155Transition": "0xf4240",
|
||||
"maxCodeSize": "0x6000",
|
||||
"maxCodeSizeTransition": "0x64b540",
|
||||
"validateChainIdTransition": "0xf4240",
|
||||
"validateReceiptsTransition": "0xf4240",
|
||||
"eip98Transition": "0x0",
|
||||
"eip140Transition": "0x4d50f8",
|
||||
"eip211Transition": "0x4d50f8",
|
||||
"eip214Transition": "0x4d50f8",
|
||||
"eip658Transition": "0x4d50f8",
|
||||
"wasmActivationTransition": "0x64b540",
|
||||
"eip145Transition": "0x8c6180",
|
||||
"eip1014Transition": "0x8c6180",
|
||||
"eip1052Transition": "0x8c6180",
|
||||
"eip1283Transition": "0x8c6180",
|
||||
"eip1283DisableTransition": "0x9c7b61",
|
||||
"kip4Transition": "0x8c6180",
|
||||
"kip6Transition": "0x8c6180"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@@ -62,8 +64,8 @@
|
||||
"gasLimit": "0x5B8D80"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f90247a0434ba1ebe3bc9d9d12886f616afee0eb785dd00d78aa64502045b249c8a3cc33a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940010f94b296a852aaac52ea6c5ac72e03afd032da0d1c1137be913218840c44bdb8f5709a59d8608b05be0dc2401402e11ff1bf2ada0eb50a864e57e19bd4c8499725a6a3841f706ff5d743e64f1d06db903aca62eaba0d4d77727f7253c109e6f048fa5b1583b6c2911ad77f7d59d8947d38a96a67729b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe838ee001837a120083013502845bea4f689fde830200088f5061726974792d457468657265756d86312e32392e30826c698416fa93dab841c80b3e34bacdc91e01f6a76c64a920a65edfea86b84e0fd59c6d8dbd7758f2dc4e3cb446de8dc07f3d8cb71375a6315f401cd1ce54c56694e4e01f7e774555e701",
|
||||
"totalDifficulty": "3135776192732436705400032023148164213445066062",
|
||||
"header": "f90247a0017c9292a6abf6bb9aa48c30f8854dc0e9649bceaf19079b1aac50ebea4fa316a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794007733a1fe69cf3f2cf989f81c7b4cac1693387aa06b81f6633226562f466201f0d097877c903a650f7427aefa7433fb971f601287a0098141509099d91ed2c2e503d43db5b5412d51880994e8e03a86e1d7a9ca8e8ca0495f318f8bfdd4beb517d115ad5d5330aebafe70eb2b1cfb0ab029221a0f48c1b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe83975801837a120083035108845c2c49e49fde830202058f5061726974792d457468657265756d86312e33312e30826c6984170b1279b8413ee0655a59d1f7f8db39c22055c614346450e99965fef62efa43b21b20f0966e3e41eb65fcaf6f9ce3a34359dc064827e06f3a29d2c717f287234785d369e56f00",
|
||||
"totalDifficulty": "3324635628632492920129912637269655024947201711",
|
||||
"CHTs": [
|
||||
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
|
||||
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
|
||||
@@ -4636,19 +4638,379 @@
|
||||
"0x8b4f8964062d0f00e40a41d21852a2e22abba1f4cf75f594797e368e4df21f7d",
|
||||
"0x916993123d91b181d145e2668efed6eae3845fd76d4765df3a04d8adde8c7142",
|
||||
"0x21b91051b5c5fbd22164a655de8485cfc2a9eff58ed09d6fbbb454560898daed",
|
||||
"0xb52ca76065bcf43f06335977ab87d6c809dcf4e6cdfc452ac2018b77c64089a5"
|
||||
"0xb52ca76065bcf43f06335977ab87d6c809dcf4e6cdfc452ac2018b77c64089a5",
|
||||
"0x9437d47e7f7fb4c95aacd5e1322a9c7b457888dbfb1e485142cb16ba805b5ded",
|
||||
"0xb7cb3f7394fef7de5884e165c8441d441c98c1080865b604dd21766759f7fffa",
|
||||
"0xfaff33c1aae8882f3a9d84678b55b8945b037b1f05785f2874079da71caf4aa5",
|
||||
"0xe032d77db9e882bfb3d5adc89d9a9812fb9775f98c03765ffdf0c40d0dbf11f8",
|
||||
"0xc9c4ded5821040df911b23d92d8270fc83164531c9d631c4d8e228a71e189ba1",
|
||||
"0xa27f4dd47059fdd4afe78ce8c9029c9a7c0916d10cc7dba1ce011c886d2275bb",
|
||||
"0x6dd0d3b0e07535d8350cb888c75ca355c4abb07bfc6ceba3eae02095324679a0",
|
||||
"0xee4a3c6125a5e69848457d35f9614705b651c68857b03968bc5420a809d1d9b8",
|
||||
"0xc14947239d0a7061d796313aca233659059b13740e63f967f8bd4806feb895ff",
|
||||
"0x36d9ad9d6ad2e1a1aca489524303aaa8534b137c5e9ef708d589b7a75cbf6500",
|
||||
"0x497c4cf7509b12ebd34d5c0520a24ae1b6e1c5c050bb3412d7d1a702c48d07d3",
|
||||
"0xac81f9bcce95283b7f188f16eb68d22adb22dc1cff0853739c46f27523a653b7",
|
||||
"0x2f0818ee594d2d1fbfe9a6a03cf4ae08dee69fbb9c289c2789d792f14a3e4e7d",
|
||||
"0x9beb888d86489512a9d1d8d6461490e23599c1595aa5b4d4b113d18c0eb99697",
|
||||
"0x7708aa2a88f9b41cde9f338da6d2f9dde2b57f1538f7aeefb66a0e9dce488ff3",
|
||||
"0x548a59ae0782fc5202431a472a8dc5e21ac83b68dc88afb2b0afd56cd3e880dc",
|
||||
"0x271397f861034f73fe228e3921d835a313041c260a6c2ca3d0c28d407d17ba89",
|
||||
"0x732b95d3ebdf035182863a540bc002cef70f98b91f90ee8dcef2285a970ade6b",
|
||||
"0x605d419ecbcdaa05d6f09c9734469847f52164df26417d7807f959986b843869",
|
||||
"0xdc56e2800a637475662632ac37e9eec90d9f3962a454d6f32ee7f56426ab9f42",
|
||||
"0xdcd35988aa6982f14b3a2834f841c755ad42dcc61eb0dc6122f2aa9db65fcf92",
|
||||
"0x659b06e2aa0359e3743f59d2b128cf85bfabc20ac9d8c42a89d9cdda2bef7697",
|
||||
"0x45377222c3910f95b3f5d0adef823dc4184189cab9eed54b9997d2b30fdbae43",
|
||||
"0x15d66d0b9347f12bf9c408910edf41623f460244f309076d55cf969dc158b36e",
|
||||
"0xe5de2158113351c0ea314eb12b28f9502c307decf883ed480c53c1310c9f7c11",
|
||||
"0xc7342c08dd73fbe5801cc6c8764c53f924d6a77cd5a5b8bdbb22d2b6d3e0336e",
|
||||
"0xf10486dc44a10f7eec6739dd56e0f7519507777e78e3974d974ee0bd931f03d0",
|
||||
"0x5985752f0b3849e9cc6a5d38b65617be10b52b8fd0c2642c328b864d59a23f9f",
|
||||
"0xce899213bc8a178cbf2a8eb86f045f59895530b0af5e209b60553869000070f4",
|
||||
"0x724dd7b5e5d0e93017a62faffd534e423610c494ef0b5689304bc80a68df0e46",
|
||||
"0x318073daf925850c412d6a1f2db2d2093268896a88c49e822ccae4070b406408",
|
||||
"0x74fd03921ea801d4618fa7c2375c4369a15c7774564dfb0373b5913bdc9a6df8",
|
||||
"0xb10896436461c2660cfe36a60c433b32ef8a1e772f3f9c16ae243840a1aa3aa8",
|
||||
"0xecfc10478a368b186e4299447ec9d3ce27ca8386274c545f3edac3608ad6cd0d",
|
||||
"0x288c697b29a0d2c5d45b9507aaf62bc4bfecca1b34e1a5ce13a17711af0df3cd",
|
||||
"0x429fc79b89ad00887096417282a571de77fe73dbfd1564c13bec5830b38890cd",
|
||||
"0x4d859982815d597e31d0e5374d7077b59a4b9beec01040608bad05c6a9d0be2a",
|
||||
"0x1addc6e300b6120cd196bcb7340ca163879ac55f7c9069be77947aa01e778cf9",
|
||||
"0x2e648a4eefda9d35e26b148028a0b336ef7d75809454e36795edb9d3fdeff550",
|
||||
"0x814e65df8c720e8c9c7d64c76b6b9554328d6c780b5f3dff96aa3e29506e7e49",
|
||||
"0x4841c38f2a920bb1a072b9a7853dd7d2e44dcbc35e2737aa2f3cf6652dabfdd2",
|
||||
"0xdc63afe7974211db82b2602c26d6ace8d93f34736c0fa68eac3bd5d2c1af7484",
|
||||
"0x2052d12d3534c5d7693d420c8e080bcee99ce10ccebc7451272b7ef08f8a3dc2",
|
||||
"0x4985769df508ccc2add583d187095a8af4ca73a5be2506a506146e23dbc67d55",
|
||||
"0x4a6744d48fc2d85cc99e419483ec1111ccb6fc7ab13e4eba28a29269acb30952",
|
||||
"0x527b0514dd83336c0524add1f01799512517378b2045c4ed43ccc0e977553bac",
|
||||
"0xfc33e6a20033fff41a9b885dc5bbaa848a0f244fe89b4a1af261d382c544fbaa",
|
||||
"0xadce691a1b4224bd56682784ec106dc93af89185721db8b427eab6b0ff22776c",
|
||||
"0x0fdef2a9525541c1e96172c8a33ccc08ed759dc024d437b82126ff03b65e1684",
|
||||
"0x7aa9e8c1e9da3c68080f099281b367de26838ec7bcd474590ae101fcd68a7116",
|
||||
"0x7eb70f0a4c42726f5b3a67ab12bdf5b4e6bf5e4c347b6c32f6fd3a04c4a003e5",
|
||||
"0x546f5f3c2e44b7a61d6d0dafd802fcc114db7acb7f887f0dd0b1878979fd3eac",
|
||||
"0x5c5294fd77081b1a23037c34170b568358011be2fdc0e3ffa2230b1a017ec5b9",
|
||||
"0x6c854d3de1f2a28dd8f6320a534b915b032078377e3b880eaa8e9a3775768e2c",
|
||||
"0xc2be1a4c7a5351063084c5907f19e63f25e048f3e27648a6d9056d3d4b635c19",
|
||||
"0x5d0673ecaecd00cc8847827bbda1dd7bb21f537e5e10f10d8b5944496b55e9e6",
|
||||
"0x8a1bfbf9dd51b727c17e8920019caae599f53d37563935c584c84cbdebf942e2",
|
||||
"0x75649056bcd2a520811d8f9d5c0c629f492e93fcdcd298c0657a8c857fdf2cc6",
|
||||
"0x71421a3eb42eeba485fb90918511b0a430311856c27a968e52096c6cdaf0cce1",
|
||||
"0xdf19c2d595ec81bacaabd39217e100e6731f8bd7c3d6c5bfd987b27f89be146d",
|
||||
"0x573839677ae138670609c499107217fcae5de5fa9905c78a21b07f7a906a0a53",
|
||||
"0x1e8db73865049c1cde4004c2a60945edd9ce9847c360a2feb36205e1f1cbd5da",
|
||||
"0x52a602e7c2f462a39288465c733d2133b7f77a7a77d7e60e214d4d4eff917258",
|
||||
"0xdc30b1767c78f2ac953c5046e6440b7de488933cdece18fa3566f00d8a96c92f",
|
||||
"0xfc0baf76004e7d87b36ea52de7d886c9b3be44bb8063549bba31b63b87ac3f92",
|
||||
"0x3426c56db720ccd184f2e49385e96e5a37fd378cd486de8fadcc7d5e727aebb8",
|
||||
"0x39fc1cbf20cab093c75b42931fc6371e9851cc4357badb6961359e07b9d97fca",
|
||||
"0x6b3725ada81d881bbe245d4b55c7be12926b42d0e58dfc8fa38d54f68ff79ee4",
|
||||
"0x69bbab0d123bbf03499984698c162f9dfb81375f6bf9f2e643badcc8e0281ef8",
|
||||
"0x101cf365b31d4b37910433ffa265e1a978d4f80c478936809e1bcca7baff59b1",
|
||||
"0x65d26a27a34ca4ca98c2b5f609e4596344514698f2137547e815dfcf91f5bb36",
|
||||
"0x3b8598589a6ef43efe0b7a64832360ab02e150c4b4ec02f2a028d2522f4c0ba7",
|
||||
"0xd8776563bb522b42a25cb2714f9ea294fffa4c4fb5ad040a9458e10637861f34",
|
||||
"0xb1b85b8c9bea99a2bde16ab99b2d7e42571ba15dfeaf28a2897322bb444171b1",
|
||||
"0x803cc4e5c23bd3842736b36a425364416dc69a3efb95f3c7fdbf7782d6de7edc",
|
||||
"0xf5803ed2a130a19600ca887ad06813482b678ac0eee049cbb2e56e39a90d9867",
|
||||
"0xd3f6125b061023531cbd3d625c9382631e2fecc75945dd6f78f883353ec98962",
|
||||
"0x7b1d59f8c9869a9c73a09385c82762b86fcc995e75db00bda388e1423be19df4",
|
||||
"0x2b7a8289bf9f93c589866af1a224c34943433b6a5a571df7dc4524bcf2adde42",
|
||||
"0x9199d73dd306fc9038b36212c3ed7706d8b0f30cfcf3359408a8e6fd8ebab0a7",
|
||||
"0x0cc8446d21ccc31bee04addd48b50f394390ef3340745555f9d7ccc3c13eefbe",
|
||||
"0x80052b2097d7f836090ba9f94ad7c33066453d8ee62a2e215a82003ed92568f1",
|
||||
"0x231c2d4e6a6039342ac03f766fac9f0a587ef6828d071e63a1e3f660fff13263",
|
||||
"0xcfa0cae426e4b6b9422d72a687d50139654fc3351993b5d38ea4fc6f8944e662",
|
||||
"0x9dc837a60a2c18493fd3b40083996f18a44f37a7a762ca649bc5d8c8b272aaca",
|
||||
"0x30b4651c3496efed5997116b7a12f9cdc24040a4e110478f1a2330fbba48fbec",
|
||||
"0x99567d98d73fe92c81c69aa465bd62b02492839519f0380686349da64caaf758",
|
||||
"0x9618fd333f89357a22bb3101cc386003c2745f8a24b5affd2be9cc3c26a93e34",
|
||||
"0xe539d1a4de2a57dd65cea42302fac83aed570f2fd7a318c6d226dea58d5f94c1",
|
||||
"0xe69e3ef5d9d8cf08d3a354da7179d5bab9c68b4b6ea6a7e5a58cae9d901b5f35",
|
||||
"0x97cd995441161fe4f50a339c6323020db6f56b9221b549194a93b9895a043e59",
|
||||
"0x803e04ee8a22299e779491a6749b7d57973a59fe714d080f03749bccde30d5c6",
|
||||
"0xace95a4dc00b3fef757aa76445b1edc582246eeebb7c2bdc71fa648e06428485",
|
||||
"0x1c8bd27b857dd8dd5a671fb4aa6cec3c41ca1c747c9f86edca8f389ac637e09f",
|
||||
"0x554b4d1bbe92718dd1aba2a9d10f48f803287d2c26108bf3cab2574a91375511",
|
||||
"0xd5856bc0794ddc23049639fc438c360d66e4b3eb1f96516ba0c02c46cda8fb49",
|
||||
"0x25a4c78e490c1d5fc6c1252b2ba13ca9ad5113a5c64e02220969146c5bbe9730",
|
||||
"0xa8dd024efc7f03b61ff9926421107b54c42f5f9c936d956e9b6c6eb36f9b242b",
|
||||
"0x26d488bff06eff3fe1912ce985ced65325e09e1c01a95bc16d0df22481690640",
|
||||
"0x01b89e65f1a82ea7e456e96e2ddf29be42dced7c7ea9b12e841bd973506dcc25",
|
||||
"0xf0f5d3392e3fb73697e44755d38c84bd99394ec2ef9dec841049baf8166e6d55",
|
||||
"0x91c4f65d698130b132d0a33e44c27ea55f477cfb134224139ba0264b5737ed42",
|
||||
"0x1d2295b21e1bb810d35471fe17adc80e59c6c57b5037de90c88e99021ac78b24",
|
||||
"0x667cc89337d382967727f0740819a2f6298dd5f2b7b5e82dc45e3f1c15c5e998",
|
||||
"0x908ac480019af2d3c3017c413077a73905e27ec01721aa499c24fa7e13bf8ad9",
|
||||
"0xbeb7ebf8ffae71221e5ff149e3333fdefe6b11780d439b45a874129b2c25d71d",
|
||||
"0x235c2ed0e3fd286df5cabca5f0f61bfe356ad0d7c8bb9c642814d01f2fd26699",
|
||||
"0x22fc5189fb1945ae98d89e50b258514baaf525e8137e9581c99339e1097e33c1",
|
||||
"0x148256253b74711fc61f8af7d4efcf8694752426715a0a4c788556feb68c1a2d",
|
||||
"0x26ad59543cfd91bbe37cd8fd1995b81d0f095ac4e02cda0b4f5f40c9db6d320f",
|
||||
"0xee340b0f25450c23a5c9b16cd5aa59657a9992c1c341172bcc8c9038eb6789fe",
|
||||
"0x5da22a0b434f041d76be1d53ef63ae24031861dce1ff4baa3511d67664060bbd",
|
||||
"0x6009815cd4da0162884d0be4cfe6936f1b251f50e9c89d9fdc2f0af430012e11",
|
||||
"0x9342474f10ce871dfeb70fde89b181075b18e973d4806364d52f83f6be4d69f1",
|
||||
"0x3c4c598faaf3c9fa8b9c1bf856872e65e3d53435177992b29a7674198e7df000",
|
||||
"0xdf0d952cca28797dbb503cb8c7192e811a7dfc0797379391f839341e210078ee",
|
||||
"0xdd48052c8e9a9ec62a58a580abe1c420b89393bfffe53fbe6b7f9079b5ec4d3c",
|
||||
"0x028846c41592546d1d11375d00c1d10a18c06ee5f968b2ce8e8c42bee7aa263d",
|
||||
"0x4aa08dc77484d15f8423a1fb2df0fb0c67729de1d48e61831884e49d7697674d",
|
||||
"0x084c72f0f0fb1cdd4ff80ebc9379c9d29c8d1e35cc45901a67b231ac201ff9b4",
|
||||
"0xe904eec627d475fcb3e61b2db0366a24ebcc286ccda2b1614049fa17ae9a9d85",
|
||||
"0xc3fb5ed46f30f566b1d5547d5e00c4c999960dcbd1b60f0b337bff8da30c054d",
|
||||
"0x1503b399ce9dd9f1cd8005036006e4bae2b3f05fbb1393b8f5d868332605c98b",
|
||||
"0x70de442d35565513b92d8cdb95c6537f72d7e099e217af7c260fdf92499ecfae",
|
||||
"0xc6b86174c627fdb002d187feada8c72b9bc6b1fa5d11785988c72b06480ef1c8",
|
||||
"0x06212692407b9b701ed1b115a8ae1cf07668cd7498cbd7c5c58e9b52a0a0093e",
|
||||
"0xfdc722f761f07d5c52d36c147ab8e80a666af5aa77fdefa37e86c7b2518aca12",
|
||||
"0x7396bd40c5677c5f4388d956ec437071cd4352cac44b7b97eecebb6c5c99b507",
|
||||
"0xf634b80145415b2086d4a20746bef5c7d34034ac6601487792889be39bac54c8",
|
||||
"0xfb8cbee41b441d5424cbd12b064b04f5618f0b360b1c2ae5ffb90a0194e61106",
|
||||
"0xf77c56810755fe69822c1250295092fb8e7c88d789706d6769d0cbdeb386137b",
|
||||
"0x9e0f084e1184804e850784a4e376b8acbf58f4235a3829d49217c888e4e5d535",
|
||||
"0x6b39d6de64090febb49dc6f6a31eb606d8e278b7ff4fa9e1a9774d3d9dc71f81",
|
||||
"0xb5d9e67fd6cdd93c74536e5a74dac8eb8ea6914c2315c22e079d61eaecb18c29",
|
||||
"0xac3dbb4fa1da752bff5884154e02ab975e993201e69ef9ca532c8b1e00b1628b",
|
||||
"0x747b42a7005c41ae222f8c2ecd4bf7000c274366237e68b2e95a64cef3799ef2",
|
||||
"0x8f06b121d921274a0d8da269d19ffd6a417cec988f0018647966960ac822fd60",
|
||||
"0x13451d3ecba978d3c0d88c2dd4068cf060e949889ea514306c23a7a1ec574ca2",
|
||||
"0x737f8bd85cce3a392da15c8e68c3ea9748a6523ab92dba8d1c6c8081311c3ef7",
|
||||
"0x83cca9d97f8c4b2776b96d887c5ab1e8e6172970d6d237da98dd5c6ce07db7f3",
|
||||
"0xb5bb3dd88ecfe2e4ac4e4be2b605cc7c5e79024782628a95df33c4967dc8251a",
|
||||
"0x640c6050e63c965742cdfc6d3217eca459a24b3acf3a5ec64eed9bd7bbcefaad",
|
||||
"0xe74478890f186d41b5157dbcef1f2754a35a5af332095dd25d34caf01580062c",
|
||||
"0xfaabbc9703e049e49d1d22da051cfe6cae0697e7e728e954bd5abc40d0e2014c",
|
||||
"0x8aa4a19c4ec50a68a6541ecc11d4473cf02773a0ba7bb4012ccd76ae11ce8bf9",
|
||||
"0x01abdedb1886ec8220a4f6ce6a43863ab77215f03e8116b03f3efe44bee658b7",
|
||||
"0x18e44060426a05d3d9500b7d6ae6d99133109bac39942ab825ae81c551c0ef39",
|
||||
"0x19a60001bc92289e73d3a8320f7601eae1bcf70f65c3a43ff6af1b2c2c17355f",
|
||||
"0x2dbc82c8ba30fe69aa00c7abf129cd1a65e8fb9398b2ebca0843e526e001ce1b",
|
||||
"0xec773bb4cf7d35feb70ea19cb53cd64af2cd34c1e4f1e282bd3cd0b39720bd2e",
|
||||
"0xc966e10e5568661e0930bbff1561e2de413f9f89d984b46224ced75d57213401",
|
||||
"0x29658e4a7e4dec3e9a449902af34ab93fe760c6a1695c1a97e0a093e3d187782",
|
||||
"0x98b0b147d3f6a8a21dd9e3fe01082dc9031c193dec4def76e53ad1c13269c3d7",
|
||||
"0x288b646ad44d5f4ea299917a9b69c9c07b5ddc50e93d03fc1c1ed653599d7a7d",
|
||||
"0x87c26362fb801ef77354375eadedc1489a4fc39401521cb06b604fd9288e4d82",
|
||||
"0xa5cf4098a62d2dcc87e589c8269dc712e2ac2be5adf07ca33c520556d4da0cc1",
|
||||
"0x4f253c49f87e135e4a0941409fe70ec6b29f6b0d9aed3f654f5eee7f4eb0a486",
|
||||
"0x5370ae8dfa2a982dab86dfb45950a50ffd29039781b2b065ef5057f7b43b84d2",
|
||||
"0x044f950f82d97f0fa164ec4174c238203d15f4cf32dd739931c3e291e0902ed4",
|
||||
"0x792c3af8c8808b95f38d6e21979450e3ebeae129f0a9a9d0cf2951252801dd7d",
|
||||
"0x141e09e2ca0a96d50e7c12aae794ed0f22c0441fcc51d1c4e179f891cb06ee1e",
|
||||
"0xc475b7c5293efed9c9f0a5e1d8800e4dd10810bc7dd33c406da131b15524ee48",
|
||||
"0x0018d2c2e814bff6fa8f5e162de402db71dd9eea45d320f60e280a00aadafc2a",
|
||||
"0xc68336fc8904777bf8ec4d5a61f79f2e847c028889bce39ae0f307d11efad818",
|
||||
"0xd6439bee30ae288496a022e04f5c21b9b047edbb370ea3e33ed236a217c6ca0c",
|
||||
"0x03e096d6ce43823e4543ddbfd8f55528d49c38b5c701c520e95a51547b5b193b",
|
||||
"0xfb80f18124198c12b6359ea7805f110f9f25a6686e7a917c110ad511554e634b",
|
||||
"0xcf9a0aa896f5c54982a827e07314a81b58beb3de97fdf112ee1539ee47158f59",
|
||||
"0x948cb5dcc88a5502d82a292e7337d5d010055ae4964c09b2c6d55b0401e1781b",
|
||||
"0xb91614b49ef967aef3b113983cea703a60097e0cd4c0d9cf1ad6f36d594750a9",
|
||||
"0xe29abd32597fbfcffb8d185931986a8519fcabca73abfc5be6e42bc8b6439374",
|
||||
"0x9ebbe1b1037327c4f2f3c9b6191b6f28aaf9b04dc58f3314ec2c16ac1eaba9b7",
|
||||
"0x098529aee4331ef9ee00ee624912ed1a7cd8d63ebf27a96059f56e60ab9a95b2",
|
||||
"0xcab9578772277f3e1f7a6920b96df6ce3e6d7f60c42925b7bb1ac1d71d733718",
|
||||
"0x43cb7ebd27e7207228ecee10cfb11aefe077bf03053877b53c42a41e4f39f607",
|
||||
"0x12ef0a09e0f5dc9d89b01cfd66b34182e80821f0f9d86c80327086a9960ab9f8",
|
||||
"0x30bafa474c54d2912897a13911cd1df20988be102333bcb9fc54905789f87718",
|
||||
"0x383205a3e0b07e359127b28c3ad1b451564091893edc87d3d92e081111dd20e7",
|
||||
"0x74382d6b160ac8b1e7b86abf22cb943b43afc4480be4b09c87c8b796f22eafe9",
|
||||
"0xe84cbe2ed5a30d7b25ec540b1934577387626fb894e4248c719d417ff1b0f171",
|
||||
"0x068dd7e31af946d3427dd6822c22577886c32a7f1e3a3bc61ee061be7c456751",
|
||||
"0xff5309cf09f24f3666205ae09e542634bb848c47031ebc10079d96819095b60a",
|
||||
"0x82991fe8d442572aafde5e2f6d2c0ba0823ae72110c2f4b65a0d39244db460a0",
|
||||
"0xb86d9c8e378420595feae0f728e00736f5b72ffe37e289088c03235b3ae8f556",
|
||||
"0xd678cbfb25960efc5a64d48f2ada784a5b43123da5db8636804c2ab7d1a6cc36",
|
||||
"0x1ceacf6ae9acb6e7438e6971b133aa7a8ba7b648c130962c3f60b7449266f3ff",
|
||||
"0xe81d2bbf5efd047428040f86caa351a8785a0ee864e74760569318c997b25116",
|
||||
"0xde530285d36c4a50d0f91d48a42e9b85de919e51246b6aa54a55eb2041b17289",
|
||||
"0xd5b86ba5c24729d199007133a8000314476135cc5b84dbc49de41a7d9f3060c7",
|
||||
"0x95b2fc8a95f67d4d67cba712a98bb3b35fc4b92581f5eab9e737f2555592bf3d",
|
||||
"0x9808b933e2c732a2b4d6229467430cd73715ac93d1000c470dbe403d0f14b6ce",
|
||||
"0x8a708bd8ec41b6aeb1f822ed4892c4d685ae3fd1a752a0b79a10a6cf288c8a26",
|
||||
"0x689c7f32af0a20de771b9c03efeb6304b08a421cbc2f178b63cd284f3d74407f",
|
||||
"0x0375180a004265f4a38946353455c221785c3f6da1dcbde2c09c373fa42c434c",
|
||||
"0x764f8f063124e8226a65af4823b260354924781b339a93f6eeb0622e10333741",
|
||||
"0xd0a28ce8c50017ad2e0bf1c1f8193792228b879688f01354552e656272bd7936",
|
||||
"0x20b12fa78b655cce826e87bd18cf938917d37c306cb620afef671b0548b1e1d0",
|
||||
"0xc94540910d93236aff53413af46597dcb51c02508f14bf81817966ef32799c00",
|
||||
"0xeeda2d6df1baa5dd3cf904c4402e4e99aaaaa16b6f3a0832bffad5492fd9e725",
|
||||
"0x74de84a1158dfb1af0c1478cf0b048ae8b0ae00139588e91d37a6874b524522b",
|
||||
"0xe9c92a1b7b298d7222890fffbd5ae4d2f8a8e0c5519cd06c3e34fd94b1f12767",
|
||||
"0x18261f839aab59220f72e4e4bfa7a8dde2d3c5cd8c0179d2ff32a151f7af92c2",
|
||||
"0x35fd53473534a3bdbf0ada29529991bfe6ac1865cc6786306b92dc26a6aa8116",
|
||||
"0x6f40f093a08a00eefae4cb848462ba663b62f089005acb49a8f5ee3f1a767375",
|
||||
"0xb0d49e32ac2ddef6bf0729ce9212c4bcc053aaa7cf8dd6649247749bab68cfac",
|
||||
"0xb616c68f680b5cc9be3fc5bca40621514109dbc1316b848f1f3ce18b05e76d33",
|
||||
"0x3ac8fe2f016f98eaa25451e36ce4fcfcbd160c0306c57f2edea049cdf541538a",
|
||||
"0xb45e54eca70d4943eecaebfef3dc2219e79bdc71bddaec6adf53a1d058a65a30",
|
||||
"0x74284120c5fa1ddcb7c294533eedd0b1ca2703626b7361543cb8e2a922177aae",
|
||||
"0x8b15208a8b5d6ddfbe8b09148d497a5e3fc267b8f1d24272814d72f4826f8e88",
|
||||
"0x3f9d4dcd96d5c902d4ef5655c10620c3e5a25edfa6fa093b0546d05c7c724d8c",
|
||||
"0xf91ef06068659865a7c94e955f9c01ba4794214ebab33c9ec7030b2dfa47604a",
|
||||
"0xadd5bb3d2f06ada2edb35754833e1bf1e317edff3e33535e135e67b4e4c5fdca",
|
||||
"0x5aeb51beab2c98d3f77f2f04a39c2dfaed3ff759de9f5c16d4d88692a95eca60",
|
||||
"0xeab1ab2c49609df8e29041ffefea082f92941aefae697fd915b9aeee8665c57b",
|
||||
"0xbcf847e97f7f6fa5a16075ea54a67254e21fadeaa38d7aa42d16f223fd179faa",
|
||||
"0x07f25413e56e9dfbd9bedf4b0676755f0cdbbf10b8f13ac7ef360bef7ac905d1",
|
||||
"0x373e2f4dca323c9c4b4cd0cf4a1eb04ce7fd4d7548078200d9ffde2e3fa4cee7",
|
||||
"0x5b9fd47a0d9cb386ccdcb2755934bfb8b27be896e52afaf18a0d130bcdff5432",
|
||||
"0x1050a77797e0fc3a98c1d172496b8a3bbb2b045ebaa6b8b4af4e1542180f464c",
|
||||
"0xea29629a5b08050c92412a25506d4d6dd8ea0f6bd8c962422d8f4913090a6d2c",
|
||||
"0x1cc76b2b9f505bc358df15e285ac7cdde0009a2a19de9fcb5a44156ff76c5585",
|
||||
"0x03cbbc18173700023643a8d6d7ff57cb0503336794c5fbe0b705a95034b7af80",
|
||||
"0x9e2a5b70615a5c057d2956ac21838616ffd5cfb26fdf7398c4ad988a8cbc27ed",
|
||||
"0xb2ef5e7c15e169ad2ec00e254415f4fa6c1f0635f728a98724dca4335e1c7801",
|
||||
"0x50f9e432ed8c0c999685735ad95a4c2b3e0c0002d1159056392ed541ddca9b11",
|
||||
"0x40ecd3140c4c8b02ce66489b39842d92ca64d05c30a9eddbfe675dded3fb6f3f",
|
||||
"0xa1417d5ef7d185323ae3452fd99d54d5336f69ff866cfba06838da5efe273ebc",
|
||||
"0x93b51cb9e7c9ca4e5f67fae55992ef6b0869c8c2effc8d244791cd2275f5f136",
|
||||
"0xd9889fbd8c71e14316b5dfd46a6d049ec05127e5d3db6f0a31a935cb86b42d0f",
|
||||
"0x384e1275612d71431d80d155015010e22b8b14a0648328bf1b32f92b1673308b",
|
||||
"0x5eeac9b703836463fc0019c1b6f4be32282f4ade6778f897f6cf9d4c33e16085",
|
||||
"0x2bdd040915ac28a0a604b727f062cf49fd413c44bcfaa2cc5eaaa9224248ef51",
|
||||
"0xd7c85280a461c43df6c82f6ef60a973f2581c428394996191eeaa0d06a4b6473",
|
||||
"0xe57d7c71a989601a066f8447a5be928ad0ce47d5413eceb709761654a30667e4",
|
||||
"0xe1514ee44d1db8307cc08177a343887b5bd843cc510c5153b7f251aa10704f87",
|
||||
"0x2898a69c885bb4cfcffa45a8aa63a8e81a40d4e3a7e1ff218ca3b4c70b836e08",
|
||||
"0x27b66b51bb80e11582319b2fe176490daff05f0ce72a9dbfe79691676a455e0c",
|
||||
"0x321d7bade5b8a1adee64bb0362620d99a5528831cdc0f1bd0258c9d66e4515f1",
|
||||
"0x0a5443109753ff0845752dc998e82148d1de44d8347e51accd03cdbdcf405acd",
|
||||
"0x1ef3a558361ee68b83346d40624b13d3170519e10dd18f60b6c5d7804f3c2d1b",
|
||||
"0xf81fadde2aa798e6c151b35f764009d754f01aa0d8dacdd1a8f3109bd5d711d7",
|
||||
"0x1af5b4d637429fab034b33b5fb3add567b5896608bcdc9e8d86a7d7ce762b4c2",
|
||||
"0x8dcae50013fcabdc708c7b99c46fb4a68c75971775c135b7f7727bdf8db645a2",
|
||||
"0x74dd3719b6229c2f675e41bae47aa0de9587608e8ad76e9dd911d695cbe3727a",
|
||||
"0xca02fb569c275518e1cb95018a3b67dde118e82ade5cc9a43e118afa8da5e3d4",
|
||||
"0xd5a890bef2beb2920a7ac22be90d0ed203dcf6b37ed0b3d2cea1fcc8f68c6d98",
|
||||
"0x917c9cc04ac1f8afae96f0dc9b49161c352ed4e1da970e17d52fca31b8c1978a",
|
||||
"0x009f16eb012717beb87fcc2b4417c8096a621fddc2421d02d84d0bfe92cd3587",
|
||||
"0xe5ff9e2a1ffbcf1f53cf716b7caaa1317151ed8b81bd641bcf41eeadcdb0790f",
|
||||
"0x2dfd67dc149772d4aa52588315df62edbc8a9340f2b3afb367f7f1564c1b8503",
|
||||
"0x830df571a176933f6a72ac634933d61e602f744d1e3a046b7b639c9d2110580c",
|
||||
"0xb2a030fd70ad2290c69e9b41220c14800d9adc33d7f8af049120fc6526a654d4",
|
||||
"0x8a013c2432c60aa6315b1adc7155dd022df24129106cccbdf463273051ee0efc",
|
||||
"0x55040dc6b554877d752f2f0bf0d97f71b34583b3d939587106affdacaf5d7c0a",
|
||||
"0x251817e5c81aba6d675d47d688f19d5cb6957cea13ef3e15c66a6573b84af432",
|
||||
"0x708cc1d141308870ea3ac36e5781cbfa3b5af327c565231123496354b5a9e74b",
|
||||
"0x4efb2006e58b45c648d27654d45f1f797d4798217b2d0b54958fc576f115d81c",
|
||||
"0x7d1bc87fd32a1b2ce74fe3784be5c0fe2e625ceac523ad55da7ebcd3cd1cb94f",
|
||||
"0x575cc8bf8070ea53a54d027cb7d42eec9dffb85489013634350a96a434cb498b",
|
||||
"0xc69812969e85bcd2e7e048b4323a726691c78d1902c1f1dbdd3893c11b9df8f6",
|
||||
"0x6193928c0a4e47c9409c1af5d945a8c92c9e28a76570dfaaecfdda8071d6558d",
|
||||
"0xb8982114b6b5da8849c27ee7d23280e15aa780248ebd36e5d364f2a05ae1fe45",
|
||||
"0x49577950e5a3d4a06629686f9353adecdad6670fc9f4e6d3eaf6735296cc6775",
|
||||
"0x6444155176ebe3b62f028ad79f058271d5b317360c0b97b7fe8c2a642da88229",
|
||||
"0x9a3f0adf9c7b9380f60baf1d524590bec23b4d3790b3909ec8da3e79303252c7",
|
||||
"0x591f122777ae7a313b6c4ba8c052d483f2aa3a687b5d85ed39e19d7e0c0e6de2",
|
||||
"0xe3d68466d0747ab6245e5d8620eaae080a0f3c2aa34a56defe8adaef56d5474a",
|
||||
"0x8d0f53bb5f7610133f04a763263815e092e43b0016369866e959d22eca466d85",
|
||||
"0x8c8f0fff76977593112a64826f15ec0e909d9a1f1589e121a37f73d881e6b696",
|
||||
"0x9ab1411e7ef5b295ab1a9dfe4ee1cd1a740af5b7e4b0a0e9c4a5f37e803c7c94"
|
||||
]
|
||||
},
|
||||
"accounts": {
|
||||
"0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 5067000, "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 5067000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 5067000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
|
||||
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 5067000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
|
||||
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
|
||||
"0x0000000000000000000000000000000000000001": {
|
||||
"balance": "0x1",
|
||||
"builtin": {
|
||||
"name": "ecrecover",
|
||||
"pricing": {
|
||||
"linear": {
|
||||
"base": 3000,
|
||||
"word": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000002": {
|
||||
"balance": "0x1",
|
||||
"builtin": {
|
||||
"name": "sha256",
|
||||
"pricing": {
|
||||
"linear": {
|
||||
"base": 60,
|
||||
"word": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000003": {
|
||||
"balance": "0x1",
|
||||
"builtin": {
|
||||
"name": "ripemd160",
|
||||
"pricing": {
|
||||
"linear": {
|
||||
"base": 600,
|
||||
"word": 120
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000004": {
|
||||
"balance": "0x1",
|
||||
"builtin": {
|
||||
"name": "identity",
|
||||
"pricing": {
|
||||
"linear": {
|
||||
"base": 15,
|
||||
"word": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000005": {
|
||||
"builtin": {
|
||||
"name": "modexp",
|
||||
"activate_at": "0x4d50f8",
|
||||
"pricing": {
|
||||
"modexp": {
|
||||
"divisor": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000006": {
|
||||
"builtin": {
|
||||
"name": "alt_bn128_add",
|
||||
"activate_at": "0x4d50f8",
|
||||
"pricing": {
|
||||
"linear": {
|
||||
"base": 500,
|
||||
"word": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000007": {
|
||||
"builtin": {
|
||||
"name": "alt_bn128_mul",
|
||||
"activate_at": "0x4d50f8",
|
||||
"pricing": {
|
||||
"linear": {
|
||||
"base": 40000,
|
||||
"word": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x0000000000000000000000000000000000000008": {
|
||||
"builtin": {
|
||||
"name": "alt_bn128_pairing",
|
||||
"activate_at": "0x4d50f8",
|
||||
"pricing": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 100000,
|
||||
"pair": 80000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x00521965e7bd230323c423d96c657db5b79d099f": {
|
||||
"balance": "1606938044258990275541962092341162602522202993782792835301376"
|
||||
}
|
||||
},
|
||||
"nodes": [
|
||||
"enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303",
|
||||
|
||||
@@ -50,12 +50,10 @@
|
||||
"enode://6e3d1b39cbd2a9c4f053a27e68fd90d0bac83691dfdc4a13c59f2555078a71e63c5daaee5a82aa6db500512760a5456f86076bf8bbe8011c27c82ed7d6f5fb26@45.77.140.210:30303",
|
||||
"enode://f4698ad485a027497e1cc992bb5f7cecee2b32a44c47202738d8d0eecfab719541988d0cbcbc5ea94c6c959e5cddeb85fc6ae75fb63dc3bf87cdbe9e6f615e9d@206.156.242.64:30303",
|
||||
"enode://31dffed97f8fed1f34fe66453280a89cbeeda60cf28f6fbb212ebbefd7c7566a02c1c7d5c00bbbb49b9fa8a49f157e0f786f379ca9bcbf2fea24de70d70a22b6@206.156.242.61:30303",
|
||||
"enode://efe1a701595b7bfc20cc71a70dcdf1d731a5ca618cbc1bd0059edc6658d5958a2b243cc88112c7ded48f3d331a26a6a76b4d3f4a51260b5fb5d13f798e5786f0@206.156.242.62:30303",
|
||||
"enode://6bdc7553ab2e4914cb47774c1e6d8c8f47ac7c3981891f85f65d06f208ea1bc4d3bf982b330950e0a0cd127efd7145c4df7113159a1d4a06ed722e6c16d0ac6c@45.32.215.190:30303",
|
||||
"enode://872d82a24144bc007658fb6fac0dcdfb9b63aeb05ef563a06d0186f2d1e5ffbfc5c4f1244891a8a86ef70682b9d24382e654b305224883698862e2df647a4d23@45.76.236.247:30303",
|
||||
"enode://b11fbc6cde81c80be69508aca8ffea8460680a25a9c151b683293f8617282062b8e8e139bf91e88cedf60068a3cf927b0d48832fda5169b58a8f7ce442de6fb4@206.189.76.132:30303",
|
||||
"enode://96678da10ac83769ab3f63114a41b57b700476c5ac02719b878fa89909a936551bb7609aa09b068bf89903206fa03f23e1b5b9117ca278de304c2570b87dcb27@18.208.191.114:30303",
|
||||
"enode://47ee6bc6312210caa0087a5754221f7666e37ab2d5c10cfe386ecdf9e5f935fc55726b37d10f0eaf493f762a270445d3e6d569891c328759b8baeb39f6f6ed2d@34.224.215.151:30303"
|
||||
"enode://96678da10ac83769ab3f63114a41b57b700476c5ac02719b878fa89909a936551bb7609aa09b068bf89903206fa03f23e1b5b9117ca278de304c2570b87dcb27@35.175.15.164:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
|
||||
@@ -37,7 +37,12 @@
|
||||
"eip140Transition": "0x0",
|
||||
"eip211Transition": "0x0",
|
||||
"eip214Transition": "0x0",
|
||||
"eip658Transition": "0x0"
|
||||
"eip658Transition": "0x0",
|
||||
"eip145Transition": 6464300,
|
||||
"eip1014Transition": 6464300,
|
||||
"eip1052Transition": 6464300,
|
||||
"eip1283Transition": 6464300,
|
||||
"eip1283DisableTransition": 7026400
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@@ -51,19 +56,12 @@
|
||||
},
|
||||
"nodes": [
|
||||
"enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303",
|
||||
"enode://0171db265a569636372566e86cb7a69306fe5c15a8e2ed5bed4010012fa1d146ae4918a688cf1bd3fd98e8c2d5c3705d68ff941c88ab974ff52c7fc8606ce2f8@35.168.201.160:30303",
|
||||
"enode://9a4a3788471af17a8346da7fc41057f037da692d4fad0ac5023fc0c88cf64666d74ee9f6396012eec98cd6bc772418b42dddd823a38e359bbfdc4fc93ba38de8@34.229.128.189:30303",
|
||||
"enode://881e56dc71472376b65ddaad5e42ee73084c96eb368c1e219b4fbcd73ffa339703cca168b6620cb1eabb7b8dcfe72e563117670c7ce94298c20d04b709c65697@165.227.111.36:30303",
|
||||
"enode://8e3733fe1606b17dd743e7d4fdb7ec1e0b909aab3c5289beabcb36e9d3175ca05bb36a52589090d4899c85a9219622ea4cbb9541057b722be65241db557b51a8@52.201.214.63:30303",
|
||||
"enode://f1a5100a81cb73163ae450c584d06b1f644aa4fad4486c6aeb4c384b343c54bb66c744aa5f133af66ea1b25f0f4a454f04878f3e96ee4cd2390c047396d6357b@209.97.158.4:30303",
|
||||
"enode://0d1e0372f63a3f0b82d66635ea101ecc0f6797788a078805cc933dd93e6a22f7c9fa51ab4e2d21da02d04480ef19f3bbb9a2b41dd1c262085d295a354bb8b0f9@18.217.47.209:30303",
|
||||
"enode://ab083db73da15b3995ac9c68035cdb32901835a823cb848fccb672e43dd21f14428706118d6fe5b921d8e741f122f35aad0255bc86807b1d17bcfa1e86e40a14@165.227.37.104:30303",
|
||||
"enode://a2a8545ccceaa1152721a213e6aca912c6d89a37bc6eea73999fdb08a95c6f07a79057f7f41c75c128f58ed77a13985e5c33c8c50d6a3d60b50c43f5f69c1fcd@52.170.16.34:30303",
|
||||
"enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303",
|
||||
"enode://182ee200ca134dc4d6390f3d5aadbcd80df0f7f24335830335d142573eacce4eeb919d30e82c5df588034e167e6ba6dd11187502ac9264a71005127f6b146a99@159.203.95.241:30303",
|
||||
"enode://b022ff70b5fcaf9596ae5efed99a8198b4ae0578ee9d17b733609d803a75cef95d3a2a18e50dca9a7c3b26139f158c59eaf8b5fb8d1d331c9a46934a78acabe8@206.189.76.128:30303",
|
||||
"enode://4a16c9a597dad00c000523fc2f4302bb8bb7f05949ec0ea4a516f0c6de9e191662f650ab55ea2a05f5af0f0eeee879800074f7263328f09181c7156059b7b6b7@18.221.62.190:30303",
|
||||
"enode://6527003feb6b534a7fac297b92d2f368bdf679d8f489639006c78640bf3ead3cdbf88a88a7bec29e6e29510122f279adf094d1b1b6e9e5005c4584aeb482c4a0@35.172.215.190:30303",
|
||||
"enode://99f335f9dffe978f7a925590f011909f2db1a2b28b05a0dc10da47e285e3d20b2d827caee258607c707c5261d9ba5f7f5b899dd025315c0afbfd5536a91ccf73@18.209.18.86:30303"
|
||||
"enode://b022ff70b5fcaf9596ae5efed99a8198b4ae0578ee9d17b733609d803a75cef95d3a2a18e50dca9a7c3b26139f158c59eaf8b5fb8d1d331c9a46934a78acabe8@206.189.76.128:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Submodule ethcore/res/ethereum/tests updated: 2cd62aeec1...420f443477
@@ -1,42 +1,4 @@
|
||||
{ "block":
|
||||
[
|
||||
{
|
||||
"reference": "None",
|
||||
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
|
||||
"failing": "GeneralStateTest_stCreate2",
|
||||
"subtests": ["RevertInCreateInInitCreate2_d0g0v0_Constantinople"]
|
||||
},
|
||||
{
|
||||
"reference": "None",
|
||||
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
|
||||
"failing": "GeneralStateTest_stRevertTest",
|
||||
"subtests": ["RevertInCreateInInit_d0g0v0_Constantinople"]
|
||||
}
|
||||
],
|
||||
"state":
|
||||
[
|
||||
{
|
||||
"reference": "None",
|
||||
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
|
||||
"failing": "stCreate2Test",
|
||||
"subtests": {
|
||||
"RevertInCreateInInitCreate2": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "None",
|
||||
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
|
||||
"failing": "stRevertTest",
|
||||
"subtests": {
|
||||
"RevertInCreateInInit": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
{
|
||||
"block": [],
|
||||
"state": []
|
||||
}
|
||||
|
||||
@@ -114,19 +114,51 @@ impl ChainRoute {
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by `ChainNotify` `new_blocks()`
|
||||
pub struct NewBlocks {
|
||||
/// Imported blocks
|
||||
pub imported: Vec<H256>,
|
||||
/// Invalid blocks
|
||||
pub invalid: Vec<H256>,
|
||||
/// Route
|
||||
pub route: ChainRoute,
|
||||
/// Sealed
|
||||
pub sealed: Vec<H256>,
|
||||
/// Block bytes.
|
||||
pub proposed: Vec<Bytes>,
|
||||
/// Duration
|
||||
pub duration: Duration,
|
||||
/// Has more blocks to import
|
||||
pub has_more_blocks_to_import: bool,
|
||||
}
|
||||
|
||||
impl NewBlocks {
|
||||
/// Constructor
|
||||
pub fn new (
|
||||
imported: Vec<H256>,
|
||||
invalid: Vec<H256>,
|
||||
route: ChainRoute,
|
||||
sealed: Vec<H256>,
|
||||
proposed: Vec<Bytes>,
|
||||
duration: Duration,
|
||||
has_more_blocks_to_import: bool,
|
||||
) -> NewBlocks {
|
||||
NewBlocks {
|
||||
imported,
|
||||
invalid,
|
||||
route,
|
||||
sealed,
|
||||
proposed,
|
||||
duration,
|
||||
has_more_blocks_to_import,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents what has to be handled by actor listening to chain events
|
||||
pub trait ChainNotify : Send + Sync {
|
||||
/// fires when chain has new blocks.
|
||||
fn new_blocks(
|
||||
&self,
|
||||
_imported: Vec<H256>,
|
||||
_invalid: Vec<H256>,
|
||||
_route: ChainRoute,
|
||||
_sealed: Vec<H256>,
|
||||
// Block bytes.
|
||||
_proposed: Vec<Bytes>,
|
||||
_duration: Duration,
|
||||
) {
|
||||
fn new_blocks( &self, _new_blocks: NewBlocks) {
|
||||
// does nothing by default
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ use client::{
|
||||
use client::{
|
||||
BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient,
|
||||
TraceFilter, CallAnalytics, Mode,
|
||||
ChainNotify, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType,
|
||||
ChainNotify, NewBlocks, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType,
|
||||
IoClient, BadBlocks,
|
||||
};
|
||||
use client::bad_blocks;
|
||||
@@ -268,7 +268,7 @@ impl Importer {
|
||||
}
|
||||
|
||||
let max_blocks_to_import = client.config.max_round_blocks_to_import;
|
||||
let (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration, is_empty) = {
|
||||
let (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration, has_more_blocks_to_import) = {
|
||||
let mut imported_blocks = Vec::with_capacity(max_blocks_to_import);
|
||||
let mut invalid_blocks = HashSet::new();
|
||||
let mut proposed_blocks = Vec::with_capacity(max_blocks_to_import);
|
||||
@@ -322,26 +322,29 @@ impl Importer {
|
||||
if !invalid_blocks.is_empty() {
|
||||
self.block_queue.mark_as_bad(&invalid_blocks);
|
||||
}
|
||||
let is_empty = self.block_queue.mark_as_good(&imported_blocks);
|
||||
(imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, start.elapsed(), is_empty)
|
||||
let has_more_blocks_to_import = !self.block_queue.mark_as_good(&imported_blocks);
|
||||
(imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, start.elapsed(), has_more_blocks_to_import)
|
||||
};
|
||||
|
||||
{
|
||||
if !imported_blocks.is_empty() && is_empty {
|
||||
if !imported_blocks.is_empty() {
|
||||
let route = ChainRoute::from(import_results.as_ref());
|
||||
|
||||
if is_empty {
|
||||
if !has_more_blocks_to_import {
|
||||
self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, route.enacted(), route.retracted(), false);
|
||||
}
|
||||
|
||||
client.notify(|notify| {
|
||||
notify.new_blocks(
|
||||
NewBlocks::new(
|
||||
imported_blocks.clone(),
|
||||
invalid_blocks.clone(),
|
||||
route.clone(),
|
||||
Vec::new(),
|
||||
proposed_blocks.clone(),
|
||||
duration,
|
||||
has_more_blocks_to_import,
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -2164,11 +2167,8 @@ impl IoClient for Client {
|
||||
// NOTE To prevent race condition with import, make sure to check queued blocks first
|
||||
// (and attempt to acquire lock)
|
||||
let is_parent_pending = self.queued_ancient_blocks.read().0.contains(&parent_hash);
|
||||
if !is_parent_pending {
|
||||
let status = self.block_status(BlockId::Hash(parent_hash));
|
||||
if status == BlockStatus::Unknown {
|
||||
bail!(EthcoreErrorKind::Block(BlockError::UnknownParent(parent_hash)));
|
||||
}
|
||||
if !is_parent_pending && !self.chain.read().is_known(&parent_hash) {
|
||||
bail!(EthcoreErrorKind::Block(BlockError::UnknownParent(parent_hash)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2198,6 +2198,10 @@ impl IoClient for Client {
|
||||
);
|
||||
if let Err(e) = result {
|
||||
error!(target: "client", "Error importing ancient block: {}", e);
|
||||
|
||||
let mut queued = queued.write();
|
||||
queued.0.clear();
|
||||
queued.1.clear();
|
||||
}
|
||||
// remove from pending
|
||||
queued.write().0.remove(&hash);
|
||||
@@ -2305,7 +2309,11 @@ impl ScheduleInfo for Client {
|
||||
impl ImportSealedBlock for Client {
|
||||
fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult<H256> {
|
||||
let start = Instant::now();
|
||||
let raw = block.rlp_bytes();
|
||||
let header = block.header().clone();
|
||||
let hash = header.hash();
|
||||
self.notify(|n| n.block_pre_import(&raw, &hash, header.difficulty()));
|
||||
|
||||
let route = {
|
||||
// Do a super duper basic verification to detect potential bugs
|
||||
if let Err(e) = self.engine.verify_block_basic(&header) {
|
||||
@@ -2323,15 +2331,14 @@ impl ImportSealedBlock for Client {
|
||||
let block_data = block.rlp_bytes();
|
||||
|
||||
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
|
||||
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), header.hash());
|
||||
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), hash);
|
||||
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
|
||||
route
|
||||
};
|
||||
let h = header.hash();
|
||||
let route = ChainRoute::from([route].as_ref());
|
||||
self.importer.miner.chain_new_blocks(
|
||||
self,
|
||||
&[h],
|
||||
&[hash],
|
||||
&[],
|
||||
route.enacted(),
|
||||
route.retracted(),
|
||||
@@ -2339,16 +2346,19 @@ impl ImportSealedBlock for Client {
|
||||
);
|
||||
self.notify(|notify| {
|
||||
notify.new_blocks(
|
||||
vec![h],
|
||||
vec![],
|
||||
route.clone(),
|
||||
vec![h],
|
||||
vec![],
|
||||
start.elapsed(),
|
||||
NewBlocks::new(
|
||||
vec![hash],
|
||||
vec![],
|
||||
route.clone(),
|
||||
vec![hash],
|
||||
vec![],
|
||||
start.elapsed(),
|
||||
false
|
||||
)
|
||||
);
|
||||
});
|
||||
self.db.read().key_value().flush().expect("DB flush failed.");
|
||||
Ok(h)
|
||||
Ok(hash)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2357,12 +2367,15 @@ impl BroadcastProposalBlock for Client {
|
||||
const DURATION_ZERO: Duration = Duration::from_millis(0);
|
||||
self.notify(|notify| {
|
||||
notify.new_blocks(
|
||||
vec![],
|
||||
vec![],
|
||||
ChainRoute::default(),
|
||||
vec![],
|
||||
vec![block.rlp_bytes()],
|
||||
DURATION_ZERO,
|
||||
NewBlocks::new(
|
||||
vec![],
|
||||
vec![],
|
||||
ChainRoute::default(),
|
||||
vec![],
|
||||
vec![block.rlp_bytes()],
|
||||
DURATION_ZERO,
|
||||
false
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactResult};
|
||||
pub use self::io_message::ClientIoMessage;
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||
pub use self::chain_notify::{ChainNotify, ChainRoute, ChainRouteType, ChainMessageType};
|
||||
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
|
||||
pub use self::traits::{
|
||||
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
|
||||
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks,
|
||||
|
||||
@@ -1421,16 +1421,21 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
let mut finality_proof: Vec<_> = itertools::repeat_call(move || {
|
||||
chain(hash).and_then(|header| {
|
||||
hash = *header.parent_hash();
|
||||
if header.number() == 0 { return None }
|
||||
else { return Some(header) }
|
||||
if header.number() == 0 { None }
|
||||
else { Some(header) }
|
||||
})
|
||||
})
|
||||
.while_some()
|
||||
.take_while(|h| h.hash() != *finalized_hash)
|
||||
.collect();
|
||||
|
||||
let finalized_header = chain(*finalized_hash)
|
||||
.expect("header is finalized; finalized headers must exist in the chain; qed");
|
||||
let finalized_header = if *finalized_hash == chain_head.hash() {
|
||||
// chain closure only stores ancestry, but the chain head is also unfinalized.
|
||||
chain_head.clone()
|
||||
} else {
|
||||
chain(*finalized_hash)
|
||||
.expect("header is finalized; finalized headers must exist in the chain; qed")
|
||||
};
|
||||
|
||||
let signal_number = finalized_header.number();
|
||||
info!(target: "engine", "Applying validator set change signalled at block {}", signal_number);
|
||||
|
||||
@@ -116,7 +116,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
||||
where T: Tracer, V: VMTracer, B: StateBackend
|
||||
{
|
||||
fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> {
|
||||
self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into)
|
||||
if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? {
|
||||
self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into)
|
||||
} else {
|
||||
warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address);
|
||||
Ok(H256::zero())
|
||||
}
|
||||
}
|
||||
|
||||
fn storage_at(&self, key: &H256) -> vm::Result<H256> {
|
||||
|
||||
@@ -17,14 +17,13 @@
|
||||
//! Watcher for snapshot-related chain events.
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use client::{BlockInfo, Client, ChainNotify, ChainRoute, ClientIoMessage};
|
||||
use client::{BlockInfo, Client, ChainNotify, NewBlocks, ClientIoMessage};
|
||||
use ids::BlockId;
|
||||
|
||||
use io::IoChannel;
|
||||
use ethereum_types::H256;
|
||||
use bytes::Bytes;
|
||||
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use std::sync::Arc;
|
||||
|
||||
// helper trait for transforming hashes to numbers and checking if syncing.
|
||||
trait Oracle: Send + Sync {
|
||||
@@ -99,20 +98,12 @@ impl Watcher {
|
||||
}
|
||||
|
||||
impl ChainNotify for Watcher {
|
||||
fn new_blocks(
|
||||
&self,
|
||||
imported: Vec<H256>,
|
||||
_: Vec<H256>,
|
||||
_: ChainRoute,
|
||||
_: Vec<H256>,
|
||||
_: Vec<Bytes>,
|
||||
_duration: Duration)
|
||||
{
|
||||
if self.oracle.is_major_importing() { return }
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if self.oracle.is_major_importing() || new_blocks.has_more_blocks_to_import { return }
|
||||
|
||||
trace!(target: "snapshot_watcher", "{} imported", imported.len());
|
||||
trace!(target: "snapshot_watcher", "{} imported", new_blocks.imported.len());
|
||||
|
||||
let highest = imported.into_iter()
|
||||
let highest = new_blocks.imported.into_iter()
|
||||
.filter_map(|h| self.oracle.to_number(h))
|
||||
.filter(|&num| num >= self.period + self.history)
|
||||
.map(|num| num - self.history)
|
||||
@@ -130,7 +121,7 @@ impl ChainNotify for Watcher {
|
||||
mod tests {
|
||||
use super::{Broadcast, Oracle, Watcher};
|
||||
|
||||
use client::{ChainNotify, ChainRoute};
|
||||
use client::{ChainNotify, NewBlocks, ChainRoute};
|
||||
|
||||
use ethereum_types::{H256, U256};
|
||||
|
||||
@@ -170,14 +161,15 @@ mod tests {
|
||||
history: history,
|
||||
};
|
||||
|
||||
watcher.new_blocks(
|
||||
watcher.new_blocks(NewBlocks::new(
|
||||
hashes,
|
||||
vec![],
|
||||
ChainRoute::default(),
|
||||
vec![],
|
||||
vec![],
|
||||
DURATION_ZERO,
|
||||
);
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
// helper
|
||||
|
||||
@@ -120,6 +120,8 @@ pub struct CommonParams {
|
||||
pub eip1052_transition: BlockNumber,
|
||||
/// Number of first block where EIP-1283 rules begin.
|
||||
pub eip1283_transition: BlockNumber,
|
||||
/// Number of first block where EIP-1283 rules end.
|
||||
pub eip1283_disable_transition: BlockNumber,
|
||||
/// Number of first block where EIP-1014 rules begin.
|
||||
pub eip1014_transition: BlockNumber,
|
||||
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
|
||||
@@ -188,7 +190,7 @@ impl CommonParams {
|
||||
schedule.have_return_data = block_number >= self.eip211_transition;
|
||||
schedule.have_bitwise_shifting = block_number >= self.eip145_transition;
|
||||
schedule.have_extcodehash = block_number >= self.eip1052_transition;
|
||||
schedule.eip1283 = block_number >= self.eip1283_transition;
|
||||
schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition);
|
||||
if block_number >= self.eip210_transition {
|
||||
schedule.blockhash_gas = 800;
|
||||
}
|
||||
@@ -296,6 +298,10 @@ impl From<ethjson::spec::Params> for CommonParams {
|
||||
BlockNumber::max_value,
|
||||
Into::into,
|
||||
),
|
||||
eip1283_disable_transition: p.eip1283_disable_transition.map_or_else(
|
||||
BlockNumber::max_value,
|
||||
Into::into,
|
||||
),
|
||||
eip1014_transition: p.eip1014_transition.map_or_else(
|
||||
BlockNumber::max_value,
|
||||
Into::into,
|
||||
|
||||
@@ -447,6 +447,11 @@ impl Account {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the base storage root of this account is unchanged.
|
||||
pub fn is_base_storage_root_unchanged(&self) -> bool {
|
||||
self.original_storage_cache.is_none()
|
||||
}
|
||||
|
||||
/// Storage root where the account changes are based upon.
|
||||
pub fn base_storage_root(&self) -> H256 {
|
||||
self.storage_root
|
||||
|
||||
@@ -539,6 +539,13 @@ impl<B: Backend> State<B> {
|
||||
|a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce()))
|
||||
}
|
||||
|
||||
/// Whether the base storage root of an account remains unchanged.
|
||||
pub fn is_base_storage_root_unchanged(&self, a: &Address) -> TrieResult<bool> {
|
||||
Ok(self.ensure_cached(a, RequireCache::None, true,
|
||||
|a| a.as_ref().map(|account| account.is_base_storage_root_unchanged()))?
|
||||
.unwrap_or(true))
|
||||
}
|
||||
|
||||
/// Get the storage root of account `a`.
|
||||
pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> {
|
||||
self.ensure_cached(a, RequireCache::None, true,
|
||||
|
||||
@@ -29,7 +29,7 @@ use types::pruning_info::PruningInfo;
|
||||
use ethereum_types::{H256, H512, U256};
|
||||
use io::{TimerToken};
|
||||
use ethcore::ethstore::ethkey::Secret;
|
||||
use ethcore::client::{BlockChainClient, ChainNotify, ChainRoute, ChainMessageType};
|
||||
use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainMessageType};
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethcore::header::BlockNumber;
|
||||
use sync_io::NetSyncIo;
|
||||
@@ -498,14 +498,9 @@ impl ChainNotify for EthSync {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_blocks(&self,
|
||||
imported: Vec<H256>,
|
||||
invalid: Vec<H256>,
|
||||
route: ChainRoute,
|
||||
sealed: Vec<H256>,
|
||||
proposed: Vec<Bytes>,
|
||||
_duration: Duration)
|
||||
fn new_blocks(&self, new_blocks: NewBlocks)
|
||||
{
|
||||
if new_blocks.has_more_blocks_to_import { return }
|
||||
use light::net::Announcement;
|
||||
|
||||
self.network.with_context(self.subprotocol_name, |context| {
|
||||
@@ -513,12 +508,12 @@ impl ChainNotify for EthSync {
|
||||
&self.eth_handler.overlay);
|
||||
self.eth_handler.sync.write().chain_new_blocks(
|
||||
&mut sync_io,
|
||||
&imported,
|
||||
&invalid,
|
||||
route.enacted(),
|
||||
route.retracted(),
|
||||
&sealed,
|
||||
&proposed);
|
||||
&new_blocks.imported,
|
||||
&new_blocks.invalid,
|
||||
new_blocks.route.enacted(),
|
||||
new_blocks.route.retracted(),
|
||||
&new_blocks.sealed,
|
||||
&new_blocks.proposed);
|
||||
});
|
||||
|
||||
self.network.with_context(self.light_subprotocol_name, |context| {
|
||||
|
||||
@@ -45,13 +45,13 @@ fn accepts_service_transaction(client_id: &str) -> bool {
|
||||
// Parity versions starting from this will accept service-transactions
|
||||
const SERVICE_TRANSACTIONS_VERSION: (u32, u32) = (1u32, 6u32);
|
||||
// Parity client string prefix
|
||||
const LEGACY_CLIENT_ID_PREFIX: &'static str = "Parity/v";
|
||||
const PARITY_CLIENT_ID_PREFIX: &'static str = "Parity-Ethereum/v";
|
||||
|
||||
let splitted = if client_id.starts_with(LEGACY_CLIENT_ID_PREFIX) {
|
||||
client_id[LEGACY_CLIENT_ID_PREFIX.len()..].split('.')
|
||||
} else if client_id.starts_with(PARITY_CLIENT_ID_PREFIX) {
|
||||
client_id[PARITY_CLIENT_ID_PREFIX.len()..].split('.')
|
||||
const LEGACY_CLIENT_ID_PREFIX: &'static str = "Parity/";
|
||||
const PARITY_CLIENT_ID_PREFIX: &'static str = "Parity-Ethereum/";
|
||||
const VERSION_PREFIX: &'static str = "/v";
|
||||
|
||||
let idx = client_id.rfind(VERSION_PREFIX).map(|idx| idx + VERSION_PREFIX.len()).unwrap_or(client_id.len());
|
||||
let splitted = if client_id.starts_with(LEGACY_CLIENT_ID_PREFIX) || client_id.starts_with(PARITY_CLIENT_ID_PREFIX) {
|
||||
client_id[idx..].split('.')
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
@@ -599,7 +599,7 @@ mod tests {
|
||||
io.peers_info.insert(3, "Parity/v1.5".to_owned());
|
||||
// and peer#4 is Parity, accepting service transactions
|
||||
insert_dummy_peer(&mut sync, 4, block_hash);
|
||||
io.peers_info.insert(4, "Parity-Ethereum/v2.7.3-ABCDEFGH".to_owned());
|
||||
io.peers_info.insert(4, "Parity-Ethereum/ABCDEFGH/v2.7.3".to_owned());
|
||||
|
||||
// and new service transaction is propagated to peers
|
||||
SyncPropagator::propagate_new_transactions(&mut sync, &mut io, || true);
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
use std::collections::{VecDeque, HashSet, HashMap};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use ethereum_types::H256;
|
||||
use parking_lot::{RwLock, Mutex};
|
||||
use bytes::Bytes;
|
||||
use network::{self, PeerId, ProtocolId, PacketId, SessionInfo};
|
||||
use tests::snapshot::*;
|
||||
use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient,
|
||||
ClientConfig, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage};
|
||||
ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage};
|
||||
use ethcore::header::BlockNumber;
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethcore::spec::Spec;
|
||||
@@ -535,23 +534,18 @@ impl IoHandler<ClientIoMessage> for TestIoHandler {
|
||||
}
|
||||
|
||||
impl ChainNotify for EthPeer<EthcoreClient> {
|
||||
fn new_blocks(&self,
|
||||
imported: Vec<H256>,
|
||||
invalid: Vec<H256>,
|
||||
route: ChainRoute,
|
||||
sealed: Vec<H256>,
|
||||
proposed: Vec<Bytes>,
|
||||
_duration: Duration)
|
||||
fn new_blocks(&self, new_blocks: NewBlocks)
|
||||
{
|
||||
let (enacted, retracted) = route.into_enacted_retracted();
|
||||
if new_blocks.has_more_blocks_to_import { return }
|
||||
let (enacted, retracted) = new_blocks.route.into_enacted_retracted();
|
||||
|
||||
self.new_blocks_queue.write().push_back(NewBlockMessage {
|
||||
imported,
|
||||
invalid,
|
||||
imported: new_blocks.imported,
|
||||
invalid: new_blocks.invalid,
|
||||
enacted,
|
||||
retracted,
|
||||
sealed,
|
||||
proposed,
|
||||
sealed: new_blocks.sealed,
|
||||
proposed: new_blocks.proposed,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ ethereum-types = "0.4"
|
||||
log = "0.4"
|
||||
parity-wasm = "0.31"
|
||||
libc = "0.2"
|
||||
pwasm-utils = "0.2.2"
|
||||
pwasm-utils = "0.6.1"
|
||||
vm = { path = "../vm" }
|
||||
ethcore-logger = { path = "../../logger" }
|
||||
wasmi = "0.3.0"
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity Ethereum.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// Parity Ethereum 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,
|
||||
// Parity Ethereum 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/>.
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Spec params deserialization.
|
||||
|
||||
@@ -112,6 +112,10 @@ pub struct Params {
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="eip1283Transition")]
|
||||
pub eip1283_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="eip1283DisableTransition")]
|
||||
pub eip1283_disable_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="eip1014Transition")]
|
||||
pub eip1014_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
@@ -210,3 +214,4 @@ mod tests {
|
||||
let _deserialized: Params = serde_json::from_str(s).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ use std::time::{Instant, Duration};
|
||||
use atty;
|
||||
use ethcore::client::{
|
||||
BlockId, BlockChainClient, ChainInfo, BlockInfo, BlockChainInfo,
|
||||
BlockQueueInfo, ChainNotify, ChainRoute, ClientReport, Client, ClientIoMessage
|
||||
BlockQueueInfo, ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage
|
||||
};
|
||||
use ethcore::header::BlockNumber;
|
||||
use ethcore::snapshot::{RestorationStatus, SnapshotService as SS};
|
||||
@@ -38,7 +38,6 @@ use number_prefix::{binary_prefix, Standalone, Prefixed};
|
||||
use parity_rpc::is_major_importing_or_waiting;
|
||||
use parity_rpc::informant::RpcStats;
|
||||
use ethereum_types::H256;
|
||||
use bytes::Bytes;
|
||||
use parking_lot::{RwLock, Mutex};
|
||||
|
||||
/// Format byte counts to standard denominations.
|
||||
@@ -365,29 +364,30 @@ impl<T: InformantData> Informant<T> {
|
||||
}
|
||||
|
||||
impl ChainNotify for Informant<FullNodeInformantData> {
|
||||
fn new_blocks(&self, imported: Vec<H256>, _invalid: Vec<H256>, _route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, duration: Duration) {
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if new_blocks.has_more_blocks_to_import { return }
|
||||
let mut last_import = self.last_import.lock();
|
||||
let client = &self.target.client;
|
||||
|
||||
let importing = self.target.is_major_importing();
|
||||
let ripe = Instant::now() > *last_import + Duration::from_secs(1) && !importing;
|
||||
let txs_imported = imported.iter()
|
||||
.take(imported.len().saturating_sub(if ripe { 1 } else { 0 }))
|
||||
let txs_imported = new_blocks.imported.iter()
|
||||
.take(new_blocks.imported.len().saturating_sub(if ripe { 1 } else { 0 }))
|
||||
.filter_map(|h| client.block(BlockId::Hash(*h)))
|
||||
.map(|b| b.transactions_count())
|
||||
.sum();
|
||||
|
||||
if ripe {
|
||||
if let Some(block) = imported.last().and_then(|h| client.block(BlockId::Hash(*h))) {
|
||||
if let Some(block) = new_blocks.imported.last().and_then(|h| client.block(BlockId::Hash(*h))) {
|
||||
let header_view = block.header_view();
|
||||
let size = block.rlp().as_raw().len();
|
||||
let (skipped, skipped_txs) = (self.skipped.load(AtomicOrdering::Relaxed) + imported.len() - 1, self.skipped_txs.load(AtomicOrdering::Relaxed) + txs_imported);
|
||||
let (skipped, skipped_txs) = (self.skipped.load(AtomicOrdering::Relaxed) + new_blocks.imported.len() - 1, self.skipped_txs.load(AtomicOrdering::Relaxed) + txs_imported);
|
||||
info!(target: "import", "Imported {} {} ({} txs, {} Mgas, {} ms, {} KiB){}",
|
||||
Colour::White.bold().paint(format!("#{}", header_view.number())),
|
||||
Colour::White.bold().paint(format!("{}", header_view.hash())),
|
||||
Colour::Yellow.bold().paint(format!("{}", block.transactions_count())),
|
||||
Colour::Yellow.bold().paint(format!("{:.2}", header_view.gas_used().low_u64() as f32 / 1000000f32)),
|
||||
Colour::Purple.bold().paint(format!("{}", duration.as_milliseconds())),
|
||||
Colour::Purple.bold().paint(format!("{}", new_blocks.duration.as_milliseconds())),
|
||||
Colour::Blue.bold().paint(format!("{:.2}", size as f32 / 1024f32)),
|
||||
if skipped > 0 {
|
||||
format!(" + another {} block(s) containing {} tx(s)",
|
||||
@@ -403,7 +403,7 @@ impl ChainNotify for Informant<FullNodeInformantData> {
|
||||
*last_import = Instant::now();
|
||||
}
|
||||
} else {
|
||||
self.skipped.fetch_add(imported.len(), AtomicOrdering::Relaxed);
|
||||
self.skipped.fetch_add(new_blocks.imported.len(), AtomicOrdering::Relaxed);
|
||||
self.skipped_txs.fetch_add(txs_imported, AtomicOrdering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ use ethereum_types::{U256, Address};
|
||||
use hash::H256;
|
||||
use parking_lot::Mutex;
|
||||
use fastmap::H256FastMap;
|
||||
use std::collections::BTreeMap;
|
||||
use transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction};
|
||||
|
||||
use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch};
|
||||
@@ -310,9 +311,7 @@ impl LightFetch {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Get transaction logs
|
||||
pub fn logs(&self, filter: EthcoreFilter) -> impl Future<Item = Vec<Log>, Error = Error> + Send {
|
||||
use std::collections::BTreeMap;
|
||||
pub fn logs_no_tx_hash(&self, filter: EthcoreFilter) -> impl Future<Item = Vec<Log>, Error = Error> + Send {
|
||||
use jsonrpc_core::futures::stream::{self, Stream};
|
||||
|
||||
const MAX_BLOCK_RANGE: u64 = 1000;
|
||||
@@ -343,7 +342,7 @@ impl LightFetch {
|
||||
// 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;
|
||||
let mut block_index: usize = 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) {
|
||||
@@ -366,9 +365,9 @@ impl LightFetch {
|
||||
}
|
||||
}
|
||||
future::ok::<_,OnDemandError>(matches)
|
||||
}) // and then collect them into a vector.
|
||||
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
|
||||
})
|
||||
.map_err(errors::on_demand_error)
|
||||
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
|
||||
});
|
||||
|
||||
match maybe_future {
|
||||
@@ -378,6 +377,39 @@ impl LightFetch {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/// Get transaction logs
|
||||
pub fn logs(&self, filter: EthcoreFilter) -> impl Future<Item = Vec<Log>, Error = Error> + Send {
|
||||
use jsonrpc_core::futures::stream::{self, Stream};
|
||||
let fetcher_block = self.clone();
|
||||
self.logs_no_tx_hash(filter)
|
||||
// retrieve transaction hash.
|
||||
.and_then(move |mut result| {
|
||||
let mut blocks = BTreeMap::new();
|
||||
for log in result.iter() {
|
||||
let block_hash = log.block_hash.as_ref().expect("Previously initialized with value; qed");
|
||||
blocks.entry(block_hash.clone()).or_insert_with(|| {
|
||||
fetcher_block.block(BlockId::Hash(block_hash.clone().into()))
|
||||
});
|
||||
}
|
||||
// future get blocks (unordered it)
|
||||
stream::futures_unordered(blocks.into_iter().map(|(_, v)| v)).collect().map(move |blocks| {
|
||||
let transactions_per_block: BTreeMap<_, _> = blocks.iter()
|
||||
.map(|block| (block.hash(), block.transactions())).collect();
|
||||
for log in result.iter_mut() {
|
||||
let log_index: U256 = log.transaction_index.expect("Previously initialized with value; qed").into();
|
||||
let block_hash = log.block_hash.clone().expect("Previously initialized with value; qed").into();
|
||||
let tx_hash = transactions_per_block.get(&block_hash)
|
||||
// transaction index is from an enumerate call in log common so not need to check value
|
||||
.and_then(|txs| txs.get(log_index.as_usize()))
|
||||
.map(|tr| tr.hash().into());
|
||||
log.transaction_hash = tx_hash;
|
||||
}
|
||||
result
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Get a transaction by hash. also returns the index in the block.
|
||||
// Only returns transactions in the canonical chain.
|
||||
pub fn transaction_by_hash(&self, tx_hash: H256)
|
||||
|
||||
@@ -141,6 +141,33 @@ enum PendingTransactionId {
|
||||
Location(PendingOrBlock, usize)
|
||||
}
|
||||
|
||||
pub fn base_logs<C, M, T: StateInfo + 'static> (client: &C, miner: &M, filter: Filter) -> BoxFuture<Vec<Log>> where
|
||||
C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T>,
|
||||
M: MinerService<State=T> {
|
||||
let include_pending = filter.to_block == Some(BlockNumber::Pending);
|
||||
let filter: EthcoreFilter = match filter.try_into() {
|
||||
Ok(value) => value,
|
||||
Err(err) => return Box::new(future::err(err)),
|
||||
};
|
||||
let mut logs = match client.logs(filter.clone()) {
|
||||
Ok(logs) => logs
|
||||
.into_iter()
|
||||
.map(From::from)
|
||||
.collect::<Vec<Log>>(),
|
||||
Err(id) => return Box::new(future::err(errors::filter_block_not_found(id))),
|
||||
};
|
||||
|
||||
if include_pending {
|
||||
let best_block = client.chain_info().best_block_number;
|
||||
let pending = pending_logs(&*miner, best_block, &filter);
|
||||
logs.extend(pending);
|
||||
}
|
||||
|
||||
let logs = limit_logs(logs, filter.limit);
|
||||
|
||||
Box::new(future::ok(logs))
|
||||
}
|
||||
|
||||
impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> EthClient<C, SN, S, M, EM> where
|
||||
C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo,
|
||||
SN: SnapshotService,
|
||||
@@ -714,28 +741,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
}
|
||||
|
||||
fn logs(&self, filter: Filter) -> BoxFuture<Vec<Log>> {
|
||||
let include_pending = filter.to_block == Some(BlockNumber::Pending);
|
||||
let filter: EthcoreFilter = match filter.try_into() {
|
||||
Ok(value) => value,
|
||||
Err(err) => return Box::new(future::err(err)),
|
||||
};
|
||||
let mut logs = match self.client.logs(filter.clone()) {
|
||||
Ok(logs) => logs
|
||||
.into_iter()
|
||||
.map(From::from)
|
||||
.collect::<Vec<Log>>(),
|
||||
Err(id) => return Box::new(future::err(errors::filter_block_not_found(id))),
|
||||
};
|
||||
|
||||
if include_pending {
|
||||
let best_block = self.client.chain_info().best_block_number;
|
||||
let pending = pending_logs(&*self.miner, best_block, &filter);
|
||||
logs.extend(pending);
|
||||
}
|
||||
|
||||
let logs = limit_logs(logs, filter.limit);
|
||||
|
||||
Box::new(future::ok(logs))
|
||||
base_logs(&*self.client, &*self.miner, filter.into())
|
||||
}
|
||||
|
||||
fn work(&self, no_new_work_timeout: Trailing<u64>) -> Result<Work> {
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::collections::BTreeMap;
|
||||
use std::time::Duration;
|
||||
|
||||
use jsonrpc_core::{BoxFuture, Result, Error};
|
||||
use jsonrpc_core::futures::{self, Future, IntoFuture};
|
||||
@@ -34,14 +33,13 @@ use v1::types::{pubsub, RichHeader, Log};
|
||||
|
||||
use ethcore::encoded;
|
||||
use ethcore::filter::Filter as EthFilter;
|
||||
use ethcore::client::{BlockChainClient, ChainNotify, ChainRoute, ChainRouteType, BlockId};
|
||||
use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainRouteType, BlockId};
|
||||
use sync::LightSync;
|
||||
use light::cache::Cache;
|
||||
use light::on_demand::OnDemand;
|
||||
use light::client::{LightChainClient, LightChainNotify};
|
||||
use parity_runtime::Executor;
|
||||
use ethereum_types::H256;
|
||||
use bytes::Bytes;
|
||||
use parking_lot::{RwLock, Mutex};
|
||||
|
||||
type Client = Sink<pubsub::Result>;
|
||||
@@ -220,18 +218,10 @@ impl<C: LightClient> LightChainNotify for ChainNotificationHandler<C> {
|
||||
}
|
||||
|
||||
impl<C: BlockChainClient> ChainNotify for ChainNotificationHandler<C> {
|
||||
fn new_blocks(
|
||||
&self,
|
||||
_imported: Vec<H256>,
|
||||
_invalid: Vec<H256>,
|
||||
route: ChainRoute,
|
||||
_sealed: Vec<H256>,
|
||||
// Block bytes.
|
||||
_proposed: Vec<Bytes>,
|
||||
_duration: Duration,
|
||||
) {
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if self.heads_subscribers.read().is_empty() && self.logs_subscribers.read().is_empty() { return }
|
||||
const EXTRA_INFO_PROOF: &'static str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed";
|
||||
let headers = route.route()
|
||||
let headers = new_blocks.route.route()
|
||||
.iter()
|
||||
.filter_map(|&(hash, ref typ)| {
|
||||
match typ {
|
||||
@@ -249,7 +239,7 @@ impl<C: BlockChainClient> ChainNotify for ChainNotificationHandler<C> {
|
||||
self.notify_heads(&headers);
|
||||
|
||||
// We notify logs enacting and retracting as the order in route.
|
||||
self.notify_logs(route.route(), |filter, ex| {
|
||||
self.notify_logs(new_blocks.route.route(), |filter, ex| {
|
||||
match ex {
|
||||
&ChainRouteType::Enacted =>
|
||||
Ok(self.client.logs(filter).unwrap_or_default().into_iter().map(Into::into).collect()),
|
||||
|
||||
@@ -28,7 +28,7 @@ use ethcore::account_provider::AccountProvider;
|
||||
use ethcore_logger::RotatingLogger;
|
||||
|
||||
use jsonrpc_core::{Result, BoxFuture};
|
||||
use jsonrpc_core::futures::Future;
|
||||
use jsonrpc_core::futures::{future, Future};
|
||||
use jsonrpc_macros::Trailing;
|
||||
use v1::helpers::{self, errors, ipfs, SigningQueue, SignerService, NetworkSettings};
|
||||
use v1::helpers::dispatch::LightDispatcher;
|
||||
@@ -42,6 +42,7 @@ use v1::types::{
|
||||
BlockNumber, LightBlockNumber, ConsensusCapability, VersionInfo,
|
||||
OperationsInfo, ChainStatus,
|
||||
AccountInfo, HwAccountInfo, Header, RichHeader, Receipt,
|
||||
Log, Filter,
|
||||
};
|
||||
use Host;
|
||||
|
||||
@@ -414,4 +415,13 @@ impl Parity for ParityClient {
|
||||
fn submit_work_detail(&self, _nonce: H64, _pow_hash: H256, _mix_hash: H256) -> Result<H256> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
|
||||
fn logs_no_tx_hash(&self, filter: Filter) -> BoxFuture<Vec<Log>> {
|
||||
let filter = match filter.try_into() {
|
||||
Ok(value) => value,
|
||||
Err(err) => return Box::new(future::err(err)),
|
||||
};
|
||||
Box::new(self.fetcher().logs_no_tx_hash(filter)) as BoxFuture<_>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ use v1::types::{
|
||||
Peers, Transaction, RpcSettings, Histogram,
|
||||
TransactionStats, LocalTransactionStatus,
|
||||
BlockNumber, ConsensusCapability, VersionInfo,
|
||||
OperationsInfo, ChainStatus,
|
||||
OperationsInfo, ChainStatus, Log, Filter,
|
||||
AccountInfo, HwAccountInfo, RichHeader, Receipt,
|
||||
block_number_to_id
|
||||
};
|
||||
@@ -481,4 +481,10 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
|
||||
fn submit_work_detail(&self, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result<H256> {
|
||||
helpers::submit_work_detail(&self.client, &self.miner, nonce, pow_hash, mix_hash)
|
||||
}
|
||||
|
||||
fn logs_no_tx_hash(&self, filter: Filter) -> BoxFuture<Vec<Log>> {
|
||||
use v1::impls::eth::base_logs;
|
||||
// only specific impl for lightclient
|
||||
base_logs(&*self.client, &*self.miner, filter.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ use std::time::Duration;
|
||||
|
||||
use v1::{EthPubSub, EthPubSubClient, Metadata};
|
||||
|
||||
use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify, ChainRoute, ChainRouteType};
|
||||
use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify, NewBlocks, ChainRoute, ChainRouteType};
|
||||
use parity_runtime::Runtime;
|
||||
|
||||
const DURATION_ZERO: Duration = Duration::from_millis(0);
|
||||
@@ -57,13 +57,13 @@ fn should_subscribe_to_new_heads() {
|
||||
assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned()));
|
||||
|
||||
// Check notifications
|
||||
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO);
|
||||
handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO, true));
|
||||
let (res, receiver) = receiver.into_future().wait().unwrap();
|
||||
let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"author":"0x0000000000000000000000000000000000000000","difficulty":"0x1","extraData":"0x","gasLimit":"0xf4240","gasUsed":"0x0","hash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","number":"0x1","parentHash":"0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":[],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x1c9","stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","timestamp":"0x0","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"},"subscription":"0x416d77337e24399d"}}"#;
|
||||
assert_eq!(res, Some(response.into()));
|
||||
|
||||
// Notify about two blocks
|
||||
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h2, ChainRouteType::Enacted), (h3, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO);
|
||||
handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h2, ChainRouteType::Enacted), (h3, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO, true));
|
||||
|
||||
// Receive both
|
||||
let (res, receiver) = receiver.into_future().wait().unwrap();
|
||||
@@ -129,7 +129,7 @@ fn should_subscribe_to_logs() {
|
||||
assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned()));
|
||||
|
||||
// Check notifications (enacted)
|
||||
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO);
|
||||
handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO, false));
|
||||
let (res, receiver) = receiver.into_future().wait().unwrap();
|
||||
let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","removed":false,"topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned()
|
||||
+ &format!("0x{:x}", tx_hash)
|
||||
@@ -137,7 +137,7 @@ fn should_subscribe_to_logs() {
|
||||
assert_eq!(res, Some(response.into()));
|
||||
|
||||
// Check notifications (retracted)
|
||||
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Retracted)]), vec![], vec![], DURATION_ZERO);
|
||||
handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Retracted)]), vec![], vec![], DURATION_ZERO, false));
|
||||
let (res, receiver) = receiver.into_future().wait().unwrap();
|
||||
let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","removed":true,"topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned()
|
||||
+ &format!("0x{:x}", tx_hash)
|
||||
|
||||
@@ -20,13 +20,12 @@ use std::collections::BTreeMap;
|
||||
|
||||
use jsonrpc_core::{BoxFuture, Result};
|
||||
use jsonrpc_macros::Trailing;
|
||||
|
||||
use v1::types::{
|
||||
H64, H160, H256, H512, U256, Bytes, CallRequest,
|
||||
Peers, Transaction, RpcSettings, Histogram,
|
||||
TransactionStats, LocalTransactionStatus,
|
||||
BlockNumber, ConsensusCapability, VersionInfo,
|
||||
OperationsInfo, ChainStatus,
|
||||
OperationsInfo, ChainStatus, Log, Filter,
|
||||
AccountInfo, HwAccountInfo, RichHeader, Receipt,
|
||||
};
|
||||
|
||||
@@ -227,5 +226,11 @@ build_rpc_trait! {
|
||||
/// but returns block hash on success, and returns an explicit error message on failure).
|
||||
#[rpc(name = "parity_submitWorkDetail")]
|
||||
fn submit_work_detail(&self, H64, H256, H256) -> Result<H256>;
|
||||
|
||||
/// Returns logs matching given filter object.
|
||||
/// Is allowed to skip filling transaction hash for faster query.
|
||||
#[rpc(name = "parity_getLogsNoTransactionHash")]
|
||||
fn logs_no_tx_hash(&self, Filter) -> BoxFuture<Vec<Log>>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ impl<'a> Visitor<'a> for BytesVisitor {
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: Error {
|
||||
if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 {
|
||||
if value.len() >= 2 && value.starts_with("0x") && value.len() & 1 == 0 {
|
||||
Ok(Bytes::new(FromHex::from_hex(&value[2..]).map_err(|e| Error::custom(format!("Invalid hex: {}", e)))?))
|
||||
} else {
|
||||
Err(Error::custom("Invalid bytes format. Expected a 0x-prefixed hex string with even length"))
|
||||
@@ -101,6 +101,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_bytes_deserialize() {
|
||||
let bytes0: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""∀∂""#);
|
||||
let bytes1: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""""#);
|
||||
let bytes2: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0x123""#);
|
||||
let bytes3: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0xgg""#);
|
||||
@@ -109,6 +110,7 @@ mod tests {
|
||||
let bytes5: Bytes = serde_json::from_str(r#""0x12""#).unwrap();
|
||||
let bytes6: Bytes = serde_json::from_str(r#""0x0123""#).unwrap();
|
||||
|
||||
assert!(bytes0.is_err());
|
||||
assert!(bytes1.is_err());
|
||||
assert!(bytes2.is_err());
|
||||
assert!(bytes3.is_err());
|
||||
|
||||
@@ -129,7 +129,7 @@ macro_rules! impl_hash {
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
|
||||
if value.len() < 2 || &value[0..2] != "0x" {
|
||||
if value.len() < 2 || !value.starts_with("0x") {
|
||||
return Err(E::custom("expected a hex-encoded hash with 0x prefix"));
|
||||
}
|
||||
if value.len() != 2 + $size * 2 {
|
||||
|
||||
@@ -72,7 +72,7 @@ macro_rules! impl_uint {
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
if value.len() < 2 || &value[0..2] != "0x" {
|
||||
if value.len() < 2 || !value.starts_with("0x") {
|
||||
return Err(E::custom("expected a hex-encoded numbers with 0x prefix"))
|
||||
}
|
||||
|
||||
@@ -140,12 +140,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_fail_to_deserialize_decimals() {
|
||||
let deserialized0: Res = serde_json::from_str(r#""∀∂""#);
|
||||
let deserialized1: Res = serde_json::from_str(r#""""#);
|
||||
let deserialized2: Res = serde_json::from_str(r#""0""#);
|
||||
let deserialized3: Res = serde_json::from_str(r#""10""#);
|
||||
let deserialized4: Res = serde_json::from_str(r#""1000000""#);
|
||||
let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#);
|
||||
|
||||
assert!(deserialized0.is_err());
|
||||
assert!(deserialized1.is_err());
|
||||
assert!(deserialized2.is_err());
|
||||
assert!(deserialized3.is_err());
|
||||
|
||||
@@ -10,38 +10,36 @@ echo "CARGO_TARGET: " $CARGO_TARGET
|
||||
echo "CC: " $CC
|
||||
echo "CXX: " $CXX
|
||||
|
||||
echo "__________CARGO CONFIG__________"
|
||||
echo "_____ Building target: "$CARGO_TARGET" _____"
|
||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
||||
then
|
||||
# use build container's cargo config
|
||||
cat /.cargo/config
|
||||
# only thing we need for android
|
||||
time cargo build --target $CARGO_TARGET --release -p parity-clib --features final
|
||||
else
|
||||
mkdir -p .cargo
|
||||
rm -f .cargo/config
|
||||
echo "[target.$CARGO_TARGET]" >> .cargo/config
|
||||
echo "linker= \"$CC\"" >> .cargo/config
|
||||
cat .cargo/config
|
||||
time cargo build --target $CARGO_TARGET --release --features final
|
||||
time cargo build --target $CARGO_TARGET --release -p evmbin
|
||||
time cargo build --target $CARGO_TARGET --release -p ethstore-cli
|
||||
time cargo build --target $CARGO_TARGET --release -p ethkey-cli
|
||||
time cargo build --target $CARGO_TARGET --release -p whisper-cli
|
||||
fi
|
||||
|
||||
|
||||
echo "_____ Building target: "$CARGO_TARGET" _____"
|
||||
time cargo build --target $CARGO_TARGET --release --features final
|
||||
time cargo build --target $CARGO_TARGET --release -p evmbin
|
||||
time cargo build --target $CARGO_TARGET --release -p ethstore-cli
|
||||
time cargo build --target $CARGO_TARGET --release -p ethkey-cli
|
||||
time cargo build --target $CARGO_TARGET --release -p whisper-cli
|
||||
|
||||
echo "_____ Post-processing binaries _____"
|
||||
rm -rf artifacts
|
||||
mkdir -p artifacts
|
||||
cd artifacts
|
||||
mkdir -p $CARGO_TARGET
|
||||
cd $CARGO_TARGET
|
||||
cp -v ../../target/$CARGO_TARGET/release/parity ./parity
|
||||
cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm
|
||||
cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore
|
||||
cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey
|
||||
cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
|
||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
||||
then
|
||||
# only thing we need for android
|
||||
cp -v ../../target/$CARGO_TARGET/release/libparity.so ./libparity.so
|
||||
else
|
||||
cp -v ../../target/$CARGO_TARGET/release/parity ./parity
|
||||
cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm
|
||||
cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore
|
||||
cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey
|
||||
cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
|
||||
fi
|
||||
|
||||
|
||||
# stripping can also be done on release build time
|
||||
|
||||
@@ -7,6 +7,7 @@ clone_repos() {
|
||||
echo "__________Clone repos__________"
|
||||
git clone https://github.com/parity-js/jsonrpc.git jsonrpc
|
||||
git clone https://github.com/paritytech/wiki.git wiki
|
||||
git clone https://github.com/paritytech/parity-config-generator
|
||||
}
|
||||
|
||||
build_docs() {
|
||||
@@ -15,18 +16,25 @@ build_docs() {
|
||||
npm run build:markdown
|
||||
}
|
||||
|
||||
build_config() {
|
||||
echo "_______Build config docs______"
|
||||
yarn install
|
||||
AUTOGENSCRIPT=1 yarn generate-docs
|
||||
}
|
||||
|
||||
update_wiki_docs() {
|
||||
echo "__________Update WIKI docs__________"
|
||||
for file in $(ls jsonrpc/docs); do
|
||||
module_name=${file:0:-3}
|
||||
mv jsonrpc/docs/$file wiki/JSONRPC-$module_name-module.md
|
||||
done
|
||||
mv parity-config-generator/docs/config.md wiki/Configuring-Parity-Ethereum.md
|
||||
}
|
||||
|
||||
setup_git() {
|
||||
echo "__________Set github__________"
|
||||
git config user.email "devops@parity.com"
|
||||
git config user.name "Devops Parity"
|
||||
git config --global user.email "devops@parity.com"
|
||||
git config --global user.name "Devops Parity"
|
||||
}
|
||||
|
||||
set_remote_wiki() {
|
||||
@@ -38,13 +46,13 @@ commit_files() {
|
||||
git checkout -b rpcdoc-update-${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}
|
||||
git add .
|
||||
git commit -m "Update docs to ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}"
|
||||
git tag -a "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" -m "Update RPC docs to ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}"
|
||||
git tag -a -f "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" -m "Update RPC and config docs to ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}"
|
||||
}
|
||||
|
||||
upload_files() {
|
||||
echo "__________Upload files__________"
|
||||
git push origin HEAD
|
||||
git push --tags
|
||||
git push -q origin HEAD
|
||||
git push -q -f --tags
|
||||
}
|
||||
|
||||
RPC_TRAITS_DIR="rpc/src/v1/traits"
|
||||
@@ -56,6 +64,9 @@ cp $RPC_TRAITS_DIR/*.rs "jsonrpc/.parity/$RPC_TRAITS_DIR"
|
||||
cd jsonrpc
|
||||
build_docs
|
||||
cd ..
|
||||
cd parity-config-generator
|
||||
build_config
|
||||
cd ..
|
||||
update_wiki_docs
|
||||
cd wiki
|
||||
set_remote_wiki
|
||||
|
||||
40
scripts/gitlab/publish-snap.sh
Executable file
40
scripts/gitlab/publish-snap.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
# some necromancy:
|
||||
# gsub(/"/, "", $2) deletes "qoutes"
|
||||
# gsub(/ /, "", $2) deletes whitespaces
|
||||
TRACK=`awk -F '=' '/^track/ {gsub(/"/, "", $2); gsub(/ /, "", $2); print $2}' ./util/version/Cargo.toml`
|
||||
echo Track is: $TRACK
|
||||
|
||||
case ${TRACK} in
|
||||
nightly) export GRADE="devel" CHANNEL="edge";;
|
||||
beta) export GRADE="stable" CHANNEL="beta";;
|
||||
stable) export GRADE="stable" CHANNEL="stable";;
|
||||
*) echo "No release" && exit 0;;
|
||||
esac
|
||||
|
||||
SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap"
|
||||
|
||||
echo "__________Create snap package__________"
|
||||
echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME
|
||||
echo $VERSION:$GRADE:$BUILD_ARCH
|
||||
cat scripts/snap/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml
|
||||
cat snapcraft.yaml
|
||||
snapcraft --target-arch=$BUILD_ARCH
|
||||
ls *.snap
|
||||
|
||||
echo "__________Calculating checksums__________"
|
||||
rhash --sha256 $SNAP_PACKAGE -o $SNAP_PACKAGE".sha256"
|
||||
cat $SNAP_PACKAGE".sha256"
|
||||
|
||||
echo "__________Releasing snap package__________"
|
||||
echo "Release channel :" $CHANNEL " Branch/tag: " $CI_COMMIT_REF_NAME
|
||||
|
||||
echo $SNAPCRAFT_LOGIN_PARITY_BASE64 | base64 --decode > snapcraft.login
|
||||
snapcraft login --with snapcraft.login
|
||||
snapcraft push --release $CHANNEL $SNAP_PACKAGE
|
||||
snapcraft status parity
|
||||
snapcraft logout
|
||||
BIN
scripts/snap/icon.png
Normal file
BIN
scripts/snap/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
8
scripts/snap/parity.desktop
Normal file
8
scripts/snap/parity.desktop
Normal file
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Encoding=UTF-8
|
||||
Name=Parity Ethereum
|
||||
Comment=The fastest and most advanced Ethereum client.
|
||||
Exec=parity
|
||||
Icon=/usr/share/pixmaps/icon.png
|
||||
Terminal=true
|
||||
57
scripts/snap/snapcraft.template.yaml
Normal file
57
scripts/snap/snapcraft.template.yaml
Normal file
@@ -0,0 +1,57 @@
|
||||
name: parity
|
||||
version: $VERSION
|
||||
architectures: [$BUILD_ARCH]
|
||||
grade: $GRADE
|
||||
confinement: strict
|
||||
|
||||
summary: Fast, light, robust Ethereum implementation
|
||||
description: |
|
||||
Parity's goal is to be the fastest, lightest, and most secure Ethereum
|
||||
client. We are developing Parity using the sophisticated and cutting-edge
|
||||
Rust programming language. Parity is licensed under the GPLv3, and can be
|
||||
used for all your Ethereum needs.
|
||||
|
||||
apps:
|
||||
parity:
|
||||
command: parity
|
||||
plugs: [home, network, network-bind, mount-observe, x11, unity7, desktop, desktop-legacy, wayland]
|
||||
desktop: ./usr/share/applications/parity.desktop
|
||||
parity-evm:
|
||||
command: parity-evm
|
||||
plugs: [home, network, network-bind]
|
||||
ethkey:
|
||||
command: ethkey
|
||||
plugs: [home]
|
||||
ethstore:
|
||||
command: ethstore
|
||||
plugs: [home]
|
||||
whisper:
|
||||
command: whisper
|
||||
plugs: [home, network-bind]
|
||||
|
||||
icon: ./scripts/snap/icon.png
|
||||
|
||||
parts:
|
||||
desktop-icon:
|
||||
source: ./scripts/snap
|
||||
plugin: nil
|
||||
override-build: |
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/share/applications
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/share/pixmaps
|
||||
cp -v ./parity.desktop $SNAPCRAFT_PART_INSTALL/usr/share/applications/
|
||||
cp -v ./icon.png $SNAPCRAFT_PART_INSTALL/usr/share/pixmaps/
|
||||
parity:
|
||||
source: ./artifacts/$CARGO_TARGET
|
||||
plugin: nil
|
||||
override-build: |
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/bin
|
||||
cp -v parity $SNAPCRAFT_PART_INSTALL/usr/bin/parity
|
||||
cp -v parity-evm $SNAPCRAFT_PART_INSTALL/usr/bin/parity-evm
|
||||
cp -v ethkey $SNAPCRAFT_PART_INSTALL/usr/bin/ethkey
|
||||
cp -v ethstore $SNAPCRAFT_PART_INSTALL/usr/bin/ethstore
|
||||
cp -v whisper $SNAPCRAFT_PART_INSTALL/usr/bin/whisper
|
||||
stage-packages: [libc6, libudev1, libstdc++6, cmake, libdb]
|
||||
df:
|
||||
plugin: nil
|
||||
stage-packages: [coreutils]
|
||||
stage: [bin/df]
|
||||
@@ -16,12 +16,10 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::time::Duration;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use ethcore::client::{BlockId, ChainNotify, ChainRoute, CallContract};
|
||||
use ethereum_types::{H256, Address};
|
||||
use ethcore::client::{BlockId, ChainNotify, NewBlocks, CallContract};
|
||||
use ethereum_types::Address;
|
||||
use ethabi::FunctionOutputDecoder;
|
||||
use bytes::Bytes;
|
||||
use trusted_client::TrustedClient;
|
||||
use types::{Error, ServerKeyId, ContractAddress};
|
||||
|
||||
@@ -77,8 +75,9 @@ impl AclStorage for OnChainAclStorage {
|
||||
}
|
||||
|
||||
impl ChainNotify for OnChainAclStorage {
|
||||
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) {
|
||||
if !route.enacted().is_empty() || !route.retracted().is_empty() {
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if new_blocks.has_more_blocks_to_import { return }
|
||||
if !new_blocks.route.enacted().is_empty() || !new_blocks.route.retracted().is_empty() {
|
||||
self.contract.lock().update_contract_address()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
use std::sync::Arc;
|
||||
use std::net::SocketAddr;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::time::Duration;
|
||||
use parking_lot::Mutex;
|
||||
use ethabi::FunctionOutputDecoder;
|
||||
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, ChainRoute, CallContract};
|
||||
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, NewBlocks, CallContract};
|
||||
use ethereum_types::{H256, Address};
|
||||
use ethkey::public_to_address;
|
||||
use bytes::Bytes;
|
||||
@@ -151,8 +150,9 @@ impl KeyServerSet for OnChainKeyServerSet {
|
||||
}
|
||||
|
||||
impl ChainNotify for OnChainKeyServerSet {
|
||||
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) {
|
||||
let (enacted, retracted) = route.into_enacted_retracted();
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if new_blocks.has_more_blocks_to_import { return }
|
||||
let (enacted, retracted) = new_blocks.route.into_enacted_retracted();
|
||||
|
||||
if !enacted.is_empty() || !retracted.is_empty() {
|
||||
self.contract.lock().update(enacted, retracted)
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::time::Duration;
|
||||
use std::thread;
|
||||
use parking_lot::Mutex;
|
||||
use ethcore::client::{ChainNotify, ChainRoute};
|
||||
use ethcore::client::{ChainNotify, NewBlocks};
|
||||
use ethkey::{Public, public_to_address};
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
@@ -435,9 +434,10 @@ impl Drop for ServiceContractListener {
|
||||
}
|
||||
|
||||
impl ChainNotify for ServiceContractListener {
|
||||
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) {
|
||||
let enacted_len = route.enacted().len();
|
||||
if enacted_len == 0 && route.retracted().is_empty() {
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if new_blocks.has_more_blocks_to_import { return }
|
||||
let enacted_len = new_blocks.route.enacted().len();
|
||||
if enacted_len == 0 && new_blocks.route.retracted().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
8
test.sh
8
test.sh
@@ -35,9 +35,9 @@ validate () {
|
||||
if [ "$VALIDATE" -eq "1" ]
|
||||
then
|
||||
echo "________Validate build________"
|
||||
time cargo check $@ --no-default-features
|
||||
time cargo check $@ --manifest-path util/io/Cargo.toml --no-default-features
|
||||
time cargo check $@ --manifest-path util/io/Cargo.toml --features "mio"
|
||||
time cargo check $@ --locked --no-default-features
|
||||
time cargo check $@ --locked --manifest-path util/io/Cargo.toml --no-default-features
|
||||
time cargo check $@ --locked --manifest-path util/io/Cargo.toml --features "mio"
|
||||
|
||||
# Validate chainspecs
|
||||
echo "________Validate chainspecs________"
|
||||
@@ -71,7 +71,7 @@ cpp_test () {
|
||||
cargo_test () {
|
||||
echo "________Running Parity Full Test Suite________"
|
||||
git submodule update --init --recursive
|
||||
time cargo test $OPTIONS --features "$FEATURES" --all $@ -- --test-threads $THREADS
|
||||
time cargo test $OPTIONS --features "$FEATURES" --locked --all $@ -- --test-threads $THREADS
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,9 +25,8 @@ use parking_lot::{Mutex, MutexGuard};
|
||||
use rand::{self, Rng};
|
||||
use target_info::Target;
|
||||
|
||||
use bytes::Bytes;
|
||||
use ethcore::BlockNumber;
|
||||
use ethcore::client::{BlockId, BlockChainClient, ChainNotify, ChainRoute};
|
||||
use ethcore::client::{BlockId, BlockChainClient, ChainNotify, NewBlocks};
|
||||
use ethcore::filter::Filter;
|
||||
use ethereum_types::H256;
|
||||
use hash_fetch::{self as fetch, HashFetch};
|
||||
@@ -669,7 +668,8 @@ impl<O: OperationsClient, F: HashFetch, T: TimeProvider, R: GenRange> Updater<O,
|
||||
}
|
||||
|
||||
impl ChainNotify for Updater {
|
||||
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, _route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) {
|
||||
fn new_blocks(&self, new_blocks: NewBlocks) {
|
||||
if new_blocks.has_more_blocks_to_import { return }
|
||||
match (self.client.upgrade(), self.sync.as_ref().and_then(Weak::upgrade)) {
|
||||
(Some(ref c), Some(ref s)) if !s.status().is_syncing(c.queue_info()) => self.poll(),
|
||||
_ => {},
|
||||
|
||||
@@ -53,12 +53,15 @@ const REQUEST_BACKOFF: [Duration; 4] = [
|
||||
Duration::from_secs(64)
|
||||
];
|
||||
|
||||
const NODE_LAST_SEEN_TIMEOUT: Duration = Duration::from_secs(24*60*60);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NodeEntry {
|
||||
pub id: NodeId,
|
||||
pub endpoint: NodeEndpoint,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BucketEntry {
|
||||
pub address: NodeEntry,
|
||||
pub id_hash: H256,
|
||||
@@ -89,6 +92,12 @@ struct FindNodeRequest {
|
||||
answered: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum PingReason {
|
||||
Default,
|
||||
FromDiscoveryRequest(NodeId)
|
||||
}
|
||||
|
||||
struct PingRequest {
|
||||
// Time when the request was sent
|
||||
sent_at: Instant,
|
||||
@@ -99,8 +108,10 @@ struct PingRequest {
|
||||
// The hash Parity used to respond with (until rev 01f825b0e1f1c4c420197b51fc801cbe89284b29)
|
||||
#[deprecated()]
|
||||
deprecated_echo_hash: H256,
|
||||
reason: PingReason
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NodeBucket {
|
||||
nodes: VecDeque<BucketEntry>, //sorted by last active
|
||||
}
|
||||
@@ -178,7 +189,7 @@ impl<'a> Discovery<'a> {
|
||||
if self.node_buckets[dist].nodes.iter().any(|n| n.id_hash == id_hash) {
|
||||
return;
|
||||
}
|
||||
self.try_ping(e);
|
||||
self.try_ping(e, PingReason::Default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +232,7 @@ impl<'a> Discovery<'a> {
|
||||
} else { None }
|
||||
};
|
||||
if let Some(node) = ping {
|
||||
self.try_ping(node);
|
||||
self.try_ping(node, PingReason::Default);
|
||||
}
|
||||
Some(TableUpdates { added: added_map, removed: HashSet::new() })
|
||||
}
|
||||
@@ -244,7 +255,7 @@ impl<'a> Discovery<'a> {
|
||||
fn update_new_nodes(&mut self) {
|
||||
while self.in_flight_pings.len() < MAX_NODES_PING {
|
||||
match self.adding_nodes.pop() {
|
||||
Some(next) => self.try_ping(next),
|
||||
Some(next) => self.try_ping(next, PingReason::Default),
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
@@ -298,7 +309,7 @@ impl<'a> Discovery<'a> {
|
||||
None // a and b are equal, so log distance is -inf
|
||||
}
|
||||
|
||||
fn try_ping(&mut self, node: NodeEntry) {
|
||||
fn try_ping(&mut self, node: NodeEntry, reason: PingReason) {
|
||||
if !self.is_allowed(&node) {
|
||||
trace!(target: "discovery", "Node {:?} not allowed", node);
|
||||
return;
|
||||
@@ -313,7 +324,7 @@ impl<'a> Discovery<'a> {
|
||||
}
|
||||
|
||||
if self.in_flight_pings.len() < MAX_NODES_PING {
|
||||
self.ping(&node)
|
||||
self.ping(&node, reason)
|
||||
.unwrap_or_else(|e| {
|
||||
warn!(target: "discovery", "Error sending Ping packet: {:?}", e);
|
||||
});
|
||||
@@ -322,7 +333,7 @@ impl<'a> Discovery<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn ping(&mut self, node: &NodeEntry) -> Result<(), Error> {
|
||||
fn ping(&mut self, node: &NodeEntry, reason: PingReason) -> Result<(), Error> {
|
||||
let mut rlp = RlpStream::new_list(4);
|
||||
rlp.append(&PROTOCOL_VERSION);
|
||||
self.public_endpoint.to_rlp_list(&mut rlp);
|
||||
@@ -336,6 +347,7 @@ impl<'a> Discovery<'a> {
|
||||
node: node.clone(),
|
||||
echo_hash: hash,
|
||||
deprecated_echo_hash: old_parity_hash,
|
||||
reason: reason
|
||||
});
|
||||
|
||||
trace!(target: "discovery", "Sent Ping to {:?} ; node_id={:#x}", &node.endpoint, node.id);
|
||||
@@ -515,7 +527,7 @@ impl<'a> Discovery<'a> {
|
||||
if request.deprecated_echo_hash == echo_hash {
|
||||
trace!(target: "discovery", "Got Pong from an old parity-ethereum version.");
|
||||
}
|
||||
Some(request.node.clone())
|
||||
Some((request.node.clone(), request.reason.clone()))
|
||||
}
|
||||
};
|
||||
|
||||
@@ -529,7 +541,10 @@ impl<'a> Discovery<'a> {
|
||||
},
|
||||
};
|
||||
|
||||
if let Some(node) = expected_node {
|
||||
if let Some((node, ping_reason)) = expected_node {
|
||||
if let PingReason::FromDiscoveryRequest(target) = ping_reason {
|
||||
self.respond_with_discovery(target, &node)?;
|
||||
}
|
||||
Ok(self.update_node(node))
|
||||
} else {
|
||||
debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from);
|
||||
@@ -537,21 +552,59 @@ impl<'a> Discovery<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_find_node(&mut self, rlp: &Rlp, _node: &NodeId, from: &SocketAddr) -> Result<Option<TableUpdates>, Error> {
|
||||
fn on_find_node(&mut self, rlp: &Rlp, node_id: &NodeId, from: &SocketAddr) -> Result<Option<TableUpdates>, Error> {
|
||||
trace!(target: "discovery", "Got FindNode from {:?}", &from);
|
||||
let target: NodeId = rlp.val_at(0)?;
|
||||
let timestamp: u64 = rlp.val_at(1)?;
|
||||
self.check_timestamp(timestamp)?;
|
||||
|
||||
let node = NodeEntry {
|
||||
id: node_id.clone(),
|
||||
endpoint: NodeEndpoint {
|
||||
address: *from,
|
||||
udp_port: from.port()
|
||||
}
|
||||
};
|
||||
|
||||
if self.is_a_valid_known_node(&node) {
|
||||
self.respond_with_discovery(target, &node)?;
|
||||
} else {
|
||||
// Make sure the request source is actually there and responds to pings before actually responding
|
||||
self.try_ping(node, PingReason::FromDiscoveryRequest(target));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn is_a_valid_known_node(&self, node: &NodeEntry) -> bool {
|
||||
let id_hash = keccak(node.id);
|
||||
let dist = match Discovery::distance(&self.id_hash, &id_hash) {
|
||||
Some(dist) => dist,
|
||||
None => {
|
||||
debug!(target: "discovery", "Got an incoming discovery request from self: {:?}", node);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let bucket = &self.node_buckets[dist];
|
||||
if let Some(known_node) = bucket.nodes.iter().find(|n| n.address.id == node.id) {
|
||||
debug!(target: "discovery", "Found a known node in a bucket when processing discovery: {:?}/{:?}", known_node, node);
|
||||
(known_node.address.endpoint == node.endpoint) && (known_node.last_seen.elapsed() < NODE_LAST_SEEN_TIMEOUT)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn respond_with_discovery(&mut self, target: NodeId, node: &NodeEntry) -> Result<(), Error> {
|
||||
let nearest = self.nearest_node_entries(&target);
|
||||
if nearest.is_empty() {
|
||||
return Ok(None);
|
||||
return Ok(());
|
||||
}
|
||||
let mut packets = Discovery::prepare_neighbours_packets(&nearest);
|
||||
for p in packets.drain(..) {
|
||||
self.send_packet(PACKET_NEIGHBOURS, from, &p)?;
|
||||
self.send_packet(PACKET_NEIGHBOURS, &node.endpoint.address, &p)?;
|
||||
}
|
||||
trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &from);
|
||||
Ok(None)
|
||||
trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &node.endpoint);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepare_neighbours_packets(nearest: &[NodeEntry]) -> Vec<Bytes> {
|
||||
@@ -827,7 +880,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// After 4 discovery rounds, the first one should have learned about the rest.
|
||||
for _round in 0 .. 4 {
|
||||
for _round in 0 .. 5 {
|
||||
discovery_handlers[0].round();
|
||||
|
||||
let mut continue_loop = true;
|
||||
@@ -835,9 +888,9 @@ mod tests {
|
||||
continue_loop = false;
|
||||
|
||||
// Process all queued messages.
|
||||
for i in 0 .. 5 {
|
||||
let src = discovery_handlers[i].public_endpoint.address.clone();
|
||||
while let Some(datagram) = discovery_handlers[i].dequeue_send() {
|
||||
for i in 0 .. 20 {
|
||||
let src = discovery_handlers[i%5].public_endpoint.address.clone();
|
||||
while let Some(datagram) = discovery_handlers[i%5].dequeue_send() {
|
||||
let dest = discovery_handlers.iter_mut()
|
||||
.find(|disc| datagram.address == disc.public_endpoint.address)
|
||||
.unwrap();
|
||||
@@ -929,14 +982,14 @@ mod tests {
|
||||
let mut discovery = Discovery { request_backoff: &request_backoff, ..discovery };
|
||||
|
||||
for _ in 0..2 {
|
||||
discovery.ping(&node_entries[101]).unwrap();
|
||||
discovery.ping(&node_entries[101], PingReason::Default).unwrap();
|
||||
let num_nodes = total_bucket_nodes(&discovery.node_buckets);
|
||||
discovery.check_expired(Instant::now() + PING_TIMEOUT);
|
||||
let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets);
|
||||
assert_eq!(removed, 0);
|
||||
}
|
||||
|
||||
discovery.ping(&node_entries[101]).unwrap();
|
||||
discovery.ping(&node_entries[101], PingReason::Default).unwrap();
|
||||
let num_nodes = total_bucket_nodes(&discovery.node_buckets);
|
||||
discovery.check_expired(Instant::now() + PING_TIMEOUT);
|
||||
let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets);
|
||||
@@ -1123,7 +1176,7 @@ mod tests {
|
||||
let mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default());
|
||||
let mut discovery2 = Discovery::new(&key2, ep2.clone(), IpFilter::default());
|
||||
|
||||
discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }).unwrap();
|
||||
discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }, PingReason::Default).unwrap();
|
||||
let ping_data = discovery1.dequeue_send().unwrap();
|
||||
assert!(!discovery1.any_sends_queued());
|
||||
let data = &ping_data.payload[(32 + 65)..];
|
||||
|
||||
@@ -40,7 +40,7 @@ pub trait SocketAddrExt {
|
||||
fn is_documentation_s(&self) -> bool { false }
|
||||
fn is_global_multicast(&self) -> bool { false }
|
||||
fn is_other_multicast(&self) -> bool { false }
|
||||
|
||||
|
||||
fn is_reserved(&self) -> bool;
|
||||
fn is_usable_public(&self) -> bool;
|
||||
fn is_usable_private(&self) -> bool;
|
||||
@@ -50,38 +50,38 @@ pub trait SocketAddrExt {
|
||||
|
||||
impl SocketAddrExt for Ipv4Addr {
|
||||
fn is_global_s(&self) -> bool {
|
||||
!self.is_private() &&
|
||||
!self.is_loopback() &&
|
||||
!self.is_private() &&
|
||||
!self.is_loopback() &&
|
||||
!self.is_link_local() &&
|
||||
!self.is_broadcast() &&
|
||||
!self.is_broadcast() &&
|
||||
!self.is_documentation()
|
||||
}
|
||||
|
||||
// Used for communications between a service provider and its subscribers when using a carrier-grade NAT
|
||||
// Used for communications between a service provider and its subscribers when using a carrier-grade NAT
|
||||
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
||||
fn is_shared_space(&self) -> bool {
|
||||
*self >= Ipv4Addr::new(100, 64, 0, 0) &&
|
||||
*self >= Ipv4Addr::new(100, 64, 0, 0) &&
|
||||
*self <= Ipv4Addr::new(100, 127, 255, 255)
|
||||
}
|
||||
|
||||
// Used for the IANA IPv4 Special Purpose Address Registry
|
||||
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
||||
fn is_special_purpose(&self) -> bool {
|
||||
*self >= Ipv4Addr::new(192, 0, 0, 0) &&
|
||||
*self >= Ipv4Addr::new(192, 0, 0, 0) &&
|
||||
*self <= Ipv4Addr::new(192, 0, 0, 255)
|
||||
}
|
||||
|
||||
// Used for testing of inter-network communications between two separate subnets
|
||||
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
||||
fn is_benchmarking(&self) -> bool {
|
||||
*self >= Ipv4Addr::new(198, 18, 0, 0) &&
|
||||
*self >= Ipv4Addr::new(198, 18, 0, 0) &&
|
||||
*self <= Ipv4Addr::new(198, 19, 255, 255)
|
||||
}
|
||||
|
||||
// Reserved for future use
|
||||
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
||||
fn is_future_use(&self) -> bool {
|
||||
*self >= Ipv4Addr::new(240, 0, 0, 0) &&
|
||||
*self >= Ipv4Addr::new(240, 0, 0, 0) &&
|
||||
*self <= Ipv4Addr::new(255, 255, 255, 254)
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ impl SocketAddrExt for Ipv4Addr {
|
||||
!self.is_reserved() &&
|
||||
!self.is_private()
|
||||
}
|
||||
|
||||
|
||||
fn is_usable_private(&self) -> bool {
|
||||
self.is_private()
|
||||
}
|
||||
@@ -118,7 +118,7 @@ impl SocketAddrExt for Ipv4Addr {
|
||||
impl SocketAddrExt for Ipv6Addr {
|
||||
fn is_global_s(&self) -> bool {
|
||||
self.is_global_multicast() ||
|
||||
(!self.is_loopback() &&
|
||||
(!self.is_loopback() &&
|
||||
!self.is_unique_local_s() &&
|
||||
!self.is_unicast_link_local_s() &&
|
||||
!self.is_documentation_s() &&
|
||||
@@ -134,7 +134,7 @@ impl SocketAddrExt for Ipv6Addr {
|
||||
fn is_unicast_link_local_s(&self) -> bool {
|
||||
(self.segments()[0] & 0xffc0) == 0xfe80
|
||||
}
|
||||
|
||||
|
||||
// reserved for documentation (2001:db8::/32).
|
||||
fn is_documentation_s(&self) -> bool {
|
||||
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
|
||||
@@ -160,7 +160,7 @@ impl SocketAddrExt for Ipv6Addr {
|
||||
!self.is_reserved() &&
|
||||
!self.is_unique_local_s()
|
||||
}
|
||||
|
||||
|
||||
fn is_usable_private(&self) -> bool {
|
||||
self.is_unique_local_s()
|
||||
}
|
||||
@@ -194,7 +194,7 @@ impl SocketAddrExt for IpAddr {
|
||||
IpAddr::V6(ref ip) => ip.is_usable_public(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn is_usable_private(&self) -> bool {
|
||||
match *self {
|
||||
IpAddr::V4(ref ip) => ip.is_usable_private(),
|
||||
@@ -308,7 +308,15 @@ pub fn select_public_address(port: u16) -> SocketAddr {
|
||||
|
||||
pub fn map_external_address(local: &NodeEndpoint) -> Option<NodeEndpoint> {
|
||||
if let SocketAddr::V4(ref local_addr) = local.address {
|
||||
match search_gateway_from_timeout(*local_addr.ip(), Duration::new(5, 0)) {
|
||||
let local_ip = *local_addr.ip();
|
||||
let search_gateway_child = ::std::thread::spawn(move || {
|
||||
search_gateway_from_timeout(local_ip, Duration::new(5, 0))
|
||||
});
|
||||
let gateway_result = match search_gateway_child.join() {
|
||||
Err(_) => return None,
|
||||
Ok(gateway_result) => gateway_result,
|
||||
};
|
||||
match gateway_result {
|
||||
Err(ref err) => debug!("Gateway search error: {}", err),
|
||||
Ok(gateway) => {
|
||||
match gateway.get_external_ip() {
|
||||
@@ -425,32 +433,32 @@ fn ipv4_future_use() {
|
||||
fn ipv4_usable_public() {
|
||||
assert!(!Ipv4Addr::new(0,0,0,0).is_usable_public()); // unspecified
|
||||
assert!(Ipv4Addr::new(0,0,0,1).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(9,255,255,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(10,0,0,0).is_usable_public()); // private intra-network
|
||||
assert!(!Ipv4Addr::new(10,255,255,255).is_usable_public()); // private intra-network
|
||||
assert!(Ipv4Addr::new(11,0,0,0).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(100, 63, 255, 255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space
|
||||
assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space
|
||||
assert!(!Ipv4Addr::new(100, 127, 255, 255).is_usable_public()); // shared space
|
||||
assert!(Ipv4Addr::new(100, 128, 0, 0).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(126,255,255,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(127,0,0,0).is_usable_public()); // loopback
|
||||
assert!(!Ipv4Addr::new(127,255,255,255).is_usable_public()); // loopback
|
||||
assert!(Ipv4Addr::new(128,0,0,0).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(169,253,255,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(169,254,0,0).is_usable_public()); // link-local
|
||||
assert!(!Ipv4Addr::new(169,254,255,255).is_usable_public()); // link-local
|
||||
assert!(Ipv4Addr::new(169,255,0,0).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(172,15,255,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(172,16,0,0).is_usable_public()); // private intra-network
|
||||
assert!(!Ipv4Addr::new(172,31,255,255).is_usable_public()); // private intra-network
|
||||
assert!(Ipv4Addr::new(172,32,255,255).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(191,255,255,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(192,0,0,0).is_usable_public()); // special purpose
|
||||
assert!(!Ipv4Addr::new(192,0,0,255).is_usable_public()); // special purpose
|
||||
@@ -458,19 +466,19 @@ fn ipv4_usable_public() {
|
||||
|
||||
assert!(Ipv4Addr::new(192,0,1,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(192,0,2,0).is_usable_public()); // documentation
|
||||
assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation
|
||||
assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation
|
||||
assert!(Ipv4Addr::new(192,0,3,0).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(192,167,255,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(192,168,0,0).is_usable_public()); // private intra-network
|
||||
assert!(!Ipv4Addr::new(192,168,255,255).is_usable_public()); // private intra-network
|
||||
assert!(Ipv4Addr::new(192,169,0,0).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(198,17,255,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(198,18,0,0).is_usable_public()); // benchmarking
|
||||
assert!(!Ipv4Addr::new(198,19,255,255).is_usable_public()); // benchmarking
|
||||
assert!(Ipv4Addr::new(198,20,0,0).is_usable_public());
|
||||
|
||||
|
||||
assert!(Ipv4Addr::new(198,51,99,255).is_usable_public());
|
||||
assert!(!Ipv4Addr::new(198,51,100,0).is_usable_public()); // documentation
|
||||
assert!(!Ipv4Addr::new(198,51,100,255).is_usable_public()); // documentation
|
||||
@@ -485,7 +493,7 @@ fn ipv4_usable_public() {
|
||||
assert!(!Ipv4Addr::new(224,0,0,0).is_usable_public()); // multicast
|
||||
assert!(!Ipv4Addr::new(239, 255, 255, 255).is_usable_public()); // multicast
|
||||
assert!(!Ipv4Addr::new(240, 0, 0, 0).is_usable_public()); // future use
|
||||
assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use
|
||||
assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use
|
||||
assert!(!Ipv4Addr::new(255, 255, 255, 255).is_usable_public()); // limited broadcast
|
||||
}
|
||||
|
||||
@@ -495,12 +503,12 @@ fn ipv4_usable_private() {
|
||||
assert!(Ipv4Addr::new(10,0,0,0).is_usable_private()); // private intra-network
|
||||
assert!(Ipv4Addr::new(10,255,255,255).is_usable_private()); // private intra-network
|
||||
assert!(!Ipv4Addr::new(11,0,0,0).is_usable_private());
|
||||
|
||||
|
||||
assert!(!Ipv4Addr::new(172,15,255,255).is_usable_private());
|
||||
assert!(Ipv4Addr::new(172,16,0,0).is_usable_private()); // private intra-network
|
||||
assert!(Ipv4Addr::new(172,31,255,255).is_usable_private()); // private intra-network
|
||||
assert!(!Ipv4Addr::new(172,32,255,255).is_usable_private());
|
||||
|
||||
|
||||
assert!(!Ipv4Addr::new(192,167,255,255).is_usable_private());
|
||||
assert!(Ipv4Addr::new(192,168,0,0).is_usable_private()); // private intra-network
|
||||
assert!(Ipv4Addr::new(192,168,255,255).is_usable_private()); // private intra-network
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
[package]
|
||||
name = "parity-version"
|
||||
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
|
||||
version = "2.2.5"
|
||||
version = "2.2.9"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[package.metadata]
|
||||
# This versions track. Should be changed to `stable` or `beta` when on respective branches.
|
||||
# Used by auto-updater and for Parity version string.
|
||||
track = "beta"
|
||||
track = "stable"
|
||||
|
||||
# Network specific settings, used ONLY by auto-updater.
|
||||
# Latest supported fork blocks.
|
||||
# Indicates a critical release in this track (i.e. consensus issue).
|
||||
[package.metadata.networks]
|
||||
foundation = { forkBlock = 4370000, critical = false }
|
||||
ropsten = { forkBlock = 4230000, critical = false }
|
||||
kovan = { forkBlock = 6600000, critical = false }
|
||||
foundation = { forkBlock = 7280000, critical = false }
|
||||
ropsten = { forkBlock = 4939394, critical = false }
|
||||
kovan = { forkBlock = 10255201, critical = false }
|
||||
|
||||
[dependencies]
|
||||
parity-bytes = "0.1"
|
||||
|
||||
Reference in New Issue
Block a user