Backports for stable 2.1.7 (#9975)
* version: bump stable to 2.1.7 * Adjust requests costs for light client (#9925) * PIP Table Cost relative to average peers instead of max peers * Add tracing in PIP new_cost_table * Update stat peer_count * Use number of leeching peers for Light serve costs * Fix test::light_params_load_share_depends_on_max_peers (wrong type) * Remove (now) useless test * Remove `load_share` from LightParams.Config Prevent div. by 0 * Add LEECHER_COUNT_FACTOR * PR Grumble: u64 to u32 for f64 casting * Prevent u32 overflow for avg_peer_count * Add tests for LightSync::Statistics * Fix empty steps (#9939) * Don't send empty step twice or empty step then block. * Perform basic validation of locally sealed blocks. * Don't include empty step twice. * prevent silent errors in daemon mode, closes #9367 (#9946) * Fix light client informant while syncing (#9932) * Add `is_idle` to LightSync to check importing status * Use SyncStateWrapper to make sure is_idle gets updates * Update is_major_import to use verified queue size as well * Add comment for `is_idle` * Add Debug to `SyncStateWrapper` * `fn get` -> `fn into_inner` * ci: rearrange pipeline by logic (#9970) * ci: rearrange pipeline by logic * ci: rename docs script * Add readiness check for docker container (#9804) * Update Dockerfile Since parity is built for "mission critical use", I thought other operators may see the need for this. Adding the `curl` and `jq` commands allows for an extremely simple health check to be usable in container orchestrators. For example. Here is a health check for a parity docker container running in Kubernetes. This can be setup as a readiness Probe that would prevent clustered nodes that aren't ready from serving traffic. ```bash #!/bin/bash ETH_SYNCING=$(curl -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:8545 -H 'Content-Type: application/json') RESULT=$(echo "$ETH_SYNCING | jq -r .result) if [ "$RESULT" == "false" ]; then echo "Parity is ready to start accepting traffic" exit 0 else echo "Parity is still syncing the blockchain" exit 1 fi ``` * add sync check script * Fix docker script (#9854) * Dockerfile: change source path of the newly added check_sync.sh (#9869) * Do not use the home directory as the working dir in docker (#9834) * Do not create a home directory. * Re-add -m flag * fix docker build (#9971) * bump smallvec to 0.6 in ethcore-light, ethstore and whisper (#9588) * bump smallvec to 0.6 in ethcore-light, ethstore and whisper * bump transaction-pool * Fix test. * patch cargo to use tokio-proto from git repo this makes sure we no longer depend on smallvec 0.2.1 which is affected by https://github.com/servo/rust-smallvec/issues/96 * use patched version of untrusted 0.5.1 * ci: allow audit to fail
This commit is contained in:
parent
491f17f149
commit
126208cc74
@ -43,6 +43,14 @@ test-linux:
|
|||||||
tags:
|
tags:
|
||||||
- rust-stable
|
- rust-stable
|
||||||
|
|
||||||
|
test-audit:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- scripts/gitlab/cargo-audit.sh
|
||||||
|
tags:
|
||||||
|
- rust-stable
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
build-linux:
|
build-linux:
|
||||||
stage: build
|
stage: build
|
||||||
only: *releaseable_branches
|
only: *releaseable_branches
|
||||||
@ -103,25 +111,18 @@ publish-awss3:
|
|||||||
tags:
|
tags:
|
||||||
- shell
|
- shell
|
||||||
|
|
||||||
docs-jsonrpc:
|
publish-docs:
|
||||||
stage: optional
|
stage: publish
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
except:
|
except:
|
||||||
- nightly
|
- nightly
|
||||||
cache: {}
|
cache: {}
|
||||||
script:
|
script:
|
||||||
- scripts/gitlab/docs-jsonrpc.sh
|
- scripts/gitlab/publish-docs.sh
|
||||||
tags:
|
tags:
|
||||||
- shell
|
- shell
|
||||||
|
|
||||||
cargo-audit:
|
|
||||||
stage: optional
|
|
||||||
script:
|
|
||||||
- scripts/gitlab/cargo-audit.sh
|
|
||||||
tags:
|
|
||||||
- rust-stable
|
|
||||||
|
|
||||||
build-android:
|
build-android:
|
||||||
stage: optional
|
stage: optional
|
||||||
image: parity/rust-android:gitlab-ci
|
image: parity/rust-android:gitlab-ci
|
||||||
@ -131,6 +132,7 @@ build-android:
|
|||||||
- scripts/gitlab/build-unix.sh
|
- scripts/gitlab/build-unix.sh
|
||||||
tags:
|
tags:
|
||||||
- rust-arm
|
- rust-arm
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
test-beta:
|
test-beta:
|
||||||
stage: optional
|
stage: optional
|
||||||
@ -140,6 +142,7 @@ test-beta:
|
|||||||
- scripts/gitlab/test-all.sh beta
|
- scripts/gitlab/test-all.sh beta
|
||||||
tags:
|
tags:
|
||||||
- rust-beta
|
- rust-beta
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
test-nightly:
|
test-nightly:
|
||||||
stage: optional
|
stage: optional
|
||||||
@ -149,3 +152,4 @@ test-nightly:
|
|||||||
- scripts/gitlab/test-all.sh nightly
|
- scripts/gitlab/test-all.sh nightly
|
||||||
tags:
|
tags:
|
||||||
- rust-nightly
|
- rust-nightly
|
||||||
|
allow_failure: true
|
||||||
|
77
Cargo.lock
generated
77
Cargo.lock
generated
@ -642,7 +642,7 @@ dependencies = [
|
|||||||
"rlp_derive 0.1.0",
|
"rlp_derive 0.1.0",
|
||||||
"serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"stats 0.1.0",
|
"stats 0.1.0",
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"triehash-ethereum 0.2.0",
|
"triehash-ethereum 0.2.0",
|
||||||
@ -689,7 +689,7 @@ dependencies = [
|
|||||||
"rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transaction-pool 1.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -779,7 +779,7 @@ dependencies = [
|
|||||||
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transaction-pool 1.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -817,7 +817,7 @@ dependencies = [
|
|||||||
"tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-proto 0.1.1 (git+https://github.com/tokio-rs/tokio-proto.git?rev=56c720e)",
|
||||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -889,7 +889,6 @@ dependencies = [
|
|||||||
"rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"triehash-ethereum 0.2.0",
|
"triehash-ethereum 0.2.0",
|
||||||
]
|
]
|
||||||
@ -996,7 +995,7 @@ dependencies = [
|
|||||||
"serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1289,7 +1288,7 @@ dependencies = [
|
|||||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-proto 0.1.1 (git+https://github.com/tokio-rs/tokio-proto.git?rev=56c720e)",
|
||||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1306,7 +1305,7 @@ dependencies = [
|
|||||||
"rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-proto 0.1.1 (git+https://github.com/tokio-rs/tokio-proto.git?rev=56c720e)",
|
||||||
"tokio-rustls 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-rustls 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"webpki-roots 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"webpki-roots 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2008,7 +2007,7 @@ version = "1.12.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"panic_hook 0.1.0",
|
"panic_hook 0.1.0",
|
||||||
"parity-ethereum 2.1.6",
|
"parity-ethereum 2.1.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2024,7 +2023,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ethereum"
|
name = "parity-ethereum"
|
||||||
version = "2.1.6"
|
version = "2.1.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2074,7 +2073,7 @@ dependencies = [
|
|||||||
"parity-rpc 1.12.0",
|
"parity-rpc 1.12.0",
|
||||||
"parity-rpc-client 1.4.0",
|
"parity-rpc-client 1.4.0",
|
||||||
"parity-updater 1.12.0",
|
"parity-updater 1.12.0",
|
||||||
"parity-version 2.1.6",
|
"parity-version 2.1.7",
|
||||||
"parity-whisper 0.1.0",
|
"parity-whisper 0.1.0",
|
||||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2239,7 +2238,7 @@ dependencies = [
|
|||||||
"parity-crypto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-crypto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
"parity-updater 1.12.0",
|
"parity-updater 1.12.0",
|
||||||
"parity-version 2.1.6",
|
"parity-version 2.1.7",
|
||||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"patricia-trie 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"patricia-trie 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2254,7 +2253,7 @@ dependencies = [
|
|||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transaction-pool 1.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vm 0.1.0",
|
"vm 0.1.0",
|
||||||
]
|
]
|
||||||
@ -2329,7 +2328,7 @@ dependencies = [
|
|||||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-hash-fetch 1.12.0",
|
"parity-hash-fetch 1.12.0",
|
||||||
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-version 2.1.6",
|
"parity-version 2.1.7",
|
||||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2339,7 +2338,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-version"
|
name = "parity-version"
|
||||||
version = "2.1.6"
|
version = "2.1.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-bytes 0.1.0 (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.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rlp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2381,7 +2380,7 @@ dependencies = [
|
|||||||
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2807,7 +2806,7 @@ dependencies = [
|
|||||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (git+https://github.com/paritytech/untrusted?branch=0.5)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2914,7 +2913,7 @@ dependencies = [
|
|||||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.12.1 (git+https://github.com/paritytech/ring)",
|
"ring 0.12.1 (git+https://github.com/paritytech/ring)",
|
||||||
"sct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"sct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (git+https://github.com/paritytech/untrusted?branch=0.5)",
|
||||||
"webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2952,7 +2951,7 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring 0.12.1 (git+https://github.com/paritytech/ring)",
|
"ring 0.12.1 (git+https://github.com/paritytech/ring)",
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (git+https://github.com/paritytech/untrusted?branch=0.5)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3049,18 +3048,10 @@ name = "slab"
|
|||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
|
||||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
@ -3137,11 +3128,6 @@ dependencies = [
|
|||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "take"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target_info"
|
name = "target_info"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -3364,15 +3350,12 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-proto"
|
name = "tokio-proto"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/tokio-rs/tokio-proto.git?rev=56c720e#56c720ea3c74efa8f39e36c24e609628222b16a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -3414,7 +3397,7 @@ dependencies = [
|
|||||||
"futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-proto 0.1.1 (git+https://github.com/tokio-rs/tokio-proto.git?rev=56c720e)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3536,12 +3519,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "transaction-pool"
|
name = "transaction-pool"
|
||||||
version = "1.13.2"
|
version = "1.13.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3668,7 +3651,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/paritytech/untrusted?branch=0.5#6e8e92cd31b23272685f340cfde481cb68ac1243"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
@ -3781,7 +3764,7 @@ version = "0.17.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring 0.12.1 (git+https://github.com/paritytech/ring)",
|
"ring 0.12.1 (git+https://github.com/paritytech/ring)",
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (git+https://github.com/paritytech/untrusted?branch=0.5)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3789,7 +3772,7 @@ name = "webpki-roots"
|
|||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (git+https://github.com/paritytech/untrusted?branch=0.5)",
|
||||||
"webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4135,7 +4118,6 @@ dependencies = [
|
|||||||
"checksum slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dbdd334bd28d328dad1c41b0ea662517883d8880d8533895ef96c8003dec9c4"
|
"checksum slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dbdd334bd28d328dad1c41b0ea662517883d8880d8533895ef96c8003dec9c4"
|
||||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||||
"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
|
"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
|
||||||
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
|
|
||||||
"checksum smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10"
|
"checksum smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10"
|
||||||
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
|
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
|
||||||
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
|
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
|
||||||
@ -4145,7 +4127,6 @@ dependencies = [
|
|||||||
"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
|
"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
|
||||||
"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
|
"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
|
||||||
"checksum syn 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9056ebe7f2d6a38bc63171816fd1d3430da5a43896de21676dc5c0a4b8274a11"
|
"checksum syn 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9056ebe7f2d6a38bc63171816fd1d3430da5a43896de21676dc5c0a4b8274a11"
|
||||||
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
|
|
||||||
"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe"
|
"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe"
|
||||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||||
"checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0"
|
"checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0"
|
||||||
@ -4168,7 +4149,7 @@ dependencies = [
|
|||||||
"checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135"
|
"checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135"
|
||||||
"checksum tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6cc2de7725863c86ac71b0b9068476fec50834f055a243558ef1655bbd34cb"
|
"checksum tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6cc2de7725863c86ac71b0b9068476fec50834f055a243558ef1655bbd34cb"
|
||||||
"checksum tokio-named-pipes 0.1.0 (git+https://github.com/nikvolf/tokio-named-pipes)" = "<none>"
|
"checksum tokio-named-pipes 0.1.0 (git+https://github.com/nikvolf/tokio-named-pipes)" = "<none>"
|
||||||
"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389"
|
"checksum tokio-proto 0.1.1 (git+https://github.com/tokio-rs/tokio-proto.git?rev=56c720e)" = "<none>"
|
||||||
"checksum tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bfbaf9f260635649ec26b6fb4aded03887295ffcd999f6e43fd2c4758f758ea"
|
"checksum tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bfbaf9f260635649ec26b6fb4aded03887295ffcd999f6e43fd2c4758f758ea"
|
||||||
"checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a"
|
"checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a"
|
||||||
"checksum tokio-rustls 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9263e472d976e4345e50c6cce4cfe6b17c71593ea593cce1df26f1efd36debb"
|
"checksum tokio-rustls 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9263e472d976e4345e50c6cce4cfe6b17c71593ea593cce1df26f1efd36debb"
|
||||||
@ -4182,7 +4163,7 @@ dependencies = [
|
|||||||
"checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89"
|
"checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89"
|
||||||
"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
|
"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
|
||||||
"checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9"
|
"checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9"
|
||||||
"checksum transaction-pool 1.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fdb8870eea404a57e2f62056ac45067a53a6207fd31866122356481d3c2e1a30"
|
"checksum transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e5866e5126b14358f1d7af4bf51a0be677a363799b90e655edcec8254edef1d2"
|
||||||
"checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e"
|
"checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e"
|
||||||
"checksum trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)" = "<none>"
|
"checksum trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)" = "<none>"
|
||||||
"checksum trie-standardmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e26f52976a57a0859616d6fcec87092ac35d08eabbd78dc3dabee93b480ea5f"
|
"checksum trie-standardmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e26f52976a57a0859616d6fcec87092ac35d08eabbd78dc3dabee93b480ea5f"
|
||||||
@ -4198,7 +4179,7 @@ dependencies = [
|
|||||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||||
"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
|
"checksum untrusted 0.5.1 (git+https://github.com/paritytech/untrusted?branch=0.5)" = "<none>"
|
||||||
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
|
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
|
||||||
"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
|
"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
|
||||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
description = "Parity Ethereum client"
|
description = "Parity Ethereum client"
|
||||||
name = "parity-ethereum"
|
name = "parity-ethereum"
|
||||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||||
version = "2.1.6"
|
version = "2.1.7"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
@ -140,3 +140,5 @@ members = [
|
|||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
ring = { git = "https://github.com/paritytech/ring" }
|
ring = { git = "https://github.com/paritytech/ring" }
|
||||||
|
tokio-proto = { git = "https://github.com/tokio-rs/tokio-proto.git", rev = "56c720e" }
|
||||||
|
untrusted = { git = "https://github.com/paritytech/untrusted", branch = "0.5" }
|
||||||
|
@ -23,7 +23,7 @@ vm = { path = "../vm" }
|
|||||||
fastmap = { path = "../../util/fastmap" }
|
fastmap = { path = "../../util/fastmap" }
|
||||||
rlp = { version = "0.2.4", features = ["ethereum"] }
|
rlp = { version = "0.2.4", features = ["ethereum"] }
|
||||||
rlp_derive = { path = "../../util/rlp_derive" }
|
rlp_derive = { path = "../../util/rlp_derive" }
|
||||||
smallvec = "0.4"
|
smallvec = "0.6"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
itertools = "0.5"
|
itertools = "0.5"
|
||||||
|
@ -28,7 +28,7 @@ use parking_lot::{Mutex, RwLock};
|
|||||||
use provider::Provider;
|
use provider::Provider;
|
||||||
use request::{Request, NetworkRequests as Requests, Response};
|
use request::{Request, NetworkRequests as Requests, Response};
|
||||||
use rlp::{RlpStream, Rlp};
|
use rlp::{RlpStream, Rlp};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{BitOr, BitAnd, Not};
|
use std::ops::{BitOr, BitAnd, Not};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -38,7 +38,7 @@ use std::time::{Duration, Instant};
|
|||||||
use self::request_credits::{Credits, FlowParams};
|
use self::request_credits::{Credits, FlowParams};
|
||||||
use self::context::{Ctx, TickCtx};
|
use self::context::{Ctx, TickCtx};
|
||||||
use self::error::Punishment;
|
use self::error::Punishment;
|
||||||
use self::load_timer::{LoadDistribution, NullStore};
|
use self::load_timer::{LoadDistribution, NullStore, MOVING_SAMPLE_SIZE};
|
||||||
use self::request_set::RequestSet;
|
use self::request_set::RequestSet;
|
||||||
use self::id_guard::IdGuard;
|
use self::id_guard::IdGuard;
|
||||||
|
|
||||||
@ -70,6 +70,16 @@ const PROPAGATE_TIMEOUT_INTERVAL: Duration = Duration::from_secs(5);
|
|||||||
const RECALCULATE_COSTS_TIMEOUT: TimerToken = 3;
|
const RECALCULATE_COSTS_TIMEOUT: TimerToken = 3;
|
||||||
const RECALCULATE_COSTS_INTERVAL: Duration = Duration::from_secs(60 * 60);
|
const RECALCULATE_COSTS_INTERVAL: Duration = Duration::from_secs(60 * 60);
|
||||||
|
|
||||||
|
const STATISTICS_TIMEOUT: TimerToken = 4;
|
||||||
|
const STATISTICS_INTERVAL: Duration = Duration::from_secs(15);
|
||||||
|
|
||||||
|
/// Maximum load share for the light server
|
||||||
|
pub const MAX_LIGHTSERV_LOAD: f64 = 0.5;
|
||||||
|
|
||||||
|
/// Factor to multiply leecher count to cater for
|
||||||
|
/// extra sudden connections (should be >= 1.0)
|
||||||
|
pub const LEECHER_COUNT_FACTOR: f64 = 1.25;
|
||||||
|
|
||||||
// minimum interval between updates.
|
// minimum interval between updates.
|
||||||
const UPDATE_INTERVAL: Duration = Duration::from_millis(5000);
|
const UPDATE_INTERVAL: Duration = Duration::from_millis(5000);
|
||||||
|
|
||||||
@ -256,18 +266,18 @@ pub trait Handler: Send + Sync {
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// How many stored seconds of credits peers should be able to accumulate.
|
/// How many stored seconds of credits peers should be able to accumulate.
|
||||||
pub max_stored_seconds: u64,
|
pub max_stored_seconds: u64,
|
||||||
/// How much of the total load capacity each peer should be allowed to take.
|
/// The network config median peers (used as default peer count)
|
||||||
pub load_share: f64,
|
pub median_peers: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
const LOAD_SHARE: f64 = 1.0 / 25.0;
|
const MEDIAN_PEERS: f64 = 25.0;
|
||||||
const MAX_ACCUMULATED: u64 = 60 * 5; // only charge for 5 minutes.
|
const MAX_ACCUMULATED: u64 = 60 * 5; // only charge for 5 minutes.
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
max_stored_seconds: MAX_ACCUMULATED,
|
max_stored_seconds: MAX_ACCUMULATED,
|
||||||
load_share: LOAD_SHARE,
|
median_peers: MEDIAN_PEERS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,6 +345,42 @@ mod id_guard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provides various statistics that could
|
||||||
|
/// be used to compute costs
|
||||||
|
pub struct Statistics {
|
||||||
|
/// Samples of peer count
|
||||||
|
peer_counts: VecDeque<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Statistics {
|
||||||
|
/// Create a new Statistics instance
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Statistics {
|
||||||
|
peer_counts: VecDeque::with_capacity(MOVING_SAMPLE_SIZE),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a new peer_count sample
|
||||||
|
pub fn add_peer_count(&mut self, peer_count: usize) {
|
||||||
|
while self.peer_counts.len() >= MOVING_SAMPLE_SIZE {
|
||||||
|
self.peer_counts.pop_front();
|
||||||
|
}
|
||||||
|
self.peer_counts.push_back(peer_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the average peer count from previous samples. Is always >= 1.0
|
||||||
|
pub fn avg_peer_count(&self) -> f64 {
|
||||||
|
let len = self.peer_counts.len();
|
||||||
|
if len == 0 {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
let avg = self.peer_counts.iter()
|
||||||
|
.fold(0, |sum: u32, &v| sum.saturating_add(v as u32)) as f64
|
||||||
|
/ len as f64;
|
||||||
|
avg.max(1.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This is an implementation of the light ethereum network protocol, abstracted
|
/// This is an implementation of the light ethereum network protocol, abstracted
|
||||||
/// over a `Provider` of data and a p2p network.
|
/// over a `Provider` of data and a p2p network.
|
||||||
///
|
///
|
||||||
@ -359,6 +405,7 @@ pub struct LightProtocol {
|
|||||||
req_id: AtomicUsize,
|
req_id: AtomicUsize,
|
||||||
sample_store: Box<SampleStore>,
|
sample_store: Box<SampleStore>,
|
||||||
load_distribution: LoadDistribution,
|
load_distribution: LoadDistribution,
|
||||||
|
statistics: RwLock<Statistics>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LightProtocol {
|
impl LightProtocol {
|
||||||
@ -369,9 +416,11 @@ impl LightProtocol {
|
|||||||
let genesis_hash = provider.chain_info().genesis_hash;
|
let genesis_hash = provider.chain_info().genesis_hash;
|
||||||
let sample_store = params.sample_store.unwrap_or_else(|| Box::new(NullStore));
|
let sample_store = params.sample_store.unwrap_or_else(|| Box::new(NullStore));
|
||||||
let load_distribution = LoadDistribution::load(&*sample_store);
|
let load_distribution = LoadDistribution::load(&*sample_store);
|
||||||
|
// Default load share relative to median peers
|
||||||
|
let load_share = MAX_LIGHTSERV_LOAD / params.config.median_peers;
|
||||||
let flow_params = FlowParams::from_request_times(
|
let flow_params = FlowParams::from_request_times(
|
||||||
|kind| load_distribution.expected_time(kind),
|
|kind| load_distribution.expected_time(kind),
|
||||||
params.config.load_share,
|
load_share,
|
||||||
Duration::from_secs(params.config.max_stored_seconds),
|
Duration::from_secs(params.config.max_stored_seconds),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -389,6 +438,7 @@ impl LightProtocol {
|
|||||||
req_id: AtomicUsize::new(0),
|
req_id: AtomicUsize::new(0),
|
||||||
sample_store,
|
sample_store,
|
||||||
load_distribution,
|
load_distribution,
|
||||||
|
statistics: RwLock::new(Statistics::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,6 +458,16 @@ impl LightProtocol {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the number of active light peers downloading from the
|
||||||
|
/// node
|
||||||
|
pub fn leecher_count(&self) -> usize {
|
||||||
|
let credit_limit = *self.flow_params.read().limit();
|
||||||
|
// Count the number of peers that used some credit
|
||||||
|
self.peers.read().iter()
|
||||||
|
.filter(|(_, p)| p.lock().local_credits.current() < credit_limit)
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
|
||||||
/// Make a request to a peer.
|
/// Make a request to a peer.
|
||||||
///
|
///
|
||||||
/// Fails on: nonexistent peer, network error, peer not server,
|
/// Fails on: nonexistent peer, network error, peer not server,
|
||||||
@ -772,12 +832,16 @@ impl LightProtocol {
|
|||||||
fn begin_new_cost_period(&self, io: &IoContext) {
|
fn begin_new_cost_period(&self, io: &IoContext) {
|
||||||
self.load_distribution.end_period(&*self.sample_store);
|
self.load_distribution.end_period(&*self.sample_store);
|
||||||
|
|
||||||
|
let avg_peer_count = self.statistics.read().avg_peer_count();
|
||||||
|
// Load share relative to average peer count +LEECHER_COUNT_FACTOR%
|
||||||
|
let load_share = MAX_LIGHTSERV_LOAD / (avg_peer_count * LEECHER_COUNT_FACTOR);
|
||||||
let new_params = Arc::new(FlowParams::from_request_times(
|
let new_params = Arc::new(FlowParams::from_request_times(
|
||||||
|kind| self.load_distribution.expected_time(kind),
|
|kind| self.load_distribution.expected_time(kind),
|
||||||
self.config.load_share,
|
load_share,
|
||||||
Duration::from_secs(self.config.max_stored_seconds),
|
Duration::from_secs(self.config.max_stored_seconds),
|
||||||
));
|
));
|
||||||
*self.flow_params.write() = new_params.clone();
|
*self.flow_params.write() = new_params.clone();
|
||||||
|
trace!(target: "pip", "New cost period: avg_peers={} ; cost_table:{:?}", avg_peer_count, new_params.cost_table());
|
||||||
|
|
||||||
let peers = self.peers.read();
|
let peers = self.peers.read();
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
@ -797,6 +861,11 @@ impl LightProtocol {
|
|||||||
peer_info.awaiting_acknowledge = Some((now, new_params.clone()));
|
peer_info.awaiting_acknowledge = Some((now, new_params.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tick_statistics(&self) {
|
||||||
|
let leecher_count = self.leecher_count();
|
||||||
|
self.statistics.write().add_peer_count(leecher_count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LightProtocol {
|
impl LightProtocol {
|
||||||
@ -1099,6 +1168,8 @@ impl NetworkProtocolHandler for LightProtocol {
|
|||||||
.expect("Error registering sync timer.");
|
.expect("Error registering sync timer.");
|
||||||
io.register_timer(RECALCULATE_COSTS_TIMEOUT, RECALCULATE_COSTS_INTERVAL)
|
io.register_timer(RECALCULATE_COSTS_TIMEOUT, RECALCULATE_COSTS_INTERVAL)
|
||||||
.expect("Error registering request timer interval token.");
|
.expect("Error registering request timer interval token.");
|
||||||
|
io.register_timer(STATISTICS_TIMEOUT, STATISTICS_INTERVAL)
|
||||||
|
.expect("Error registering statistics timer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) {
|
fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) {
|
||||||
@ -1119,6 +1190,7 @@ impl NetworkProtocolHandler for LightProtocol {
|
|||||||
TICK_TIMEOUT => self.tick_handlers(&io),
|
TICK_TIMEOUT => self.tick_handlers(&io),
|
||||||
PROPAGATE_TIMEOUT => self.propagate_transactions(&io),
|
PROPAGATE_TIMEOUT => self.propagate_transactions(&io),
|
||||||
RECALCULATE_COSTS_TIMEOUT => self.begin_new_cost_period(&io),
|
RECALCULATE_COSTS_TIMEOUT => self.begin_new_cost_period(&io),
|
||||||
|
STATISTICS_TIMEOUT => self.tick_statistics(),
|
||||||
_ => warn!(target: "pip", "received timeout on unknown token {}", timer),
|
_ => warn!(target: "pip", "received timeout on unknown token {}", timer),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,10 @@ use ethcore::client::{EachBlockWith, TestBlockChainClient};
|
|||||||
use ethcore::encoded;
|
use ethcore::encoded;
|
||||||
use ethcore::ids::BlockId;
|
use ethcore::ids::BlockId;
|
||||||
use ethereum_types::{H256, U256, Address};
|
use ethereum_types::{H256, U256, Address};
|
||||||
use net::{LightProtocol, Params, packet, Peer};
|
use net::{LightProtocol, Params, packet, Peer, Statistics};
|
||||||
use net::context::IoContext;
|
use net::context::IoContext;
|
||||||
use net::status::{Capabilities, Status};
|
use net::status::{Capabilities, Status};
|
||||||
|
use net::load_timer::MOVING_SAMPLE_SIZE;
|
||||||
use network::{PeerId, NodeId};
|
use network::{PeerId, NodeId};
|
||||||
use provider::Provider;
|
use provider::Provider;
|
||||||
use request;
|
use request;
|
||||||
@ -780,3 +781,34 @@ fn get_transaction_index() {
|
|||||||
let expected = Expect::Respond(packet::RESPONSE, response);
|
let expected = Expect::Respond(packet::RESPONSE, response);
|
||||||
proto.handle_packet(&expected, 1, packet::REQUEST, &request_body);
|
proto.handle_packet(&expected, 1, packet::REQUEST, &request_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sync_statistics() {
|
||||||
|
let mut stats = Statistics::new();
|
||||||
|
|
||||||
|
// Empty set should return 1.0
|
||||||
|
assert_eq!(stats.avg_peer_count(), 1.0);
|
||||||
|
|
||||||
|
// Average < 1.0 should return 1.0
|
||||||
|
stats.add_peer_count(0);
|
||||||
|
assert_eq!(stats.avg_peer_count(), 1.0);
|
||||||
|
|
||||||
|
stats = Statistics::new();
|
||||||
|
|
||||||
|
const N: f64 = 50.0;
|
||||||
|
|
||||||
|
for i in 1..(N as usize + 1) {
|
||||||
|
stats.add_peer_count(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the average for the sum 1..N
|
||||||
|
assert_eq!(stats.avg_peer_count(), N * (N + 1.0) / 2.0 / N);
|
||||||
|
|
||||||
|
for _ in 1..(MOVING_SAMPLE_SIZE + 1) {
|
||||||
|
stats.add_peer_count(40);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it returns the average of the last
|
||||||
|
// `MOVING_SAMPLE_SIZE` values
|
||||||
|
assert_eq!(stats.avg_peer_count(), 40.0);
|
||||||
|
}
|
||||||
|
@ -2252,24 +2252,33 @@ impl ImportSealedBlock for Client {
|
|||||||
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult {
|
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult {
|
||||||
let h = block.header().hash();
|
let h = block.header().hash();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
let header = block.header().clone();
|
||||||
let route = {
|
let route = {
|
||||||
|
// Do a super duper basic verification to detect potential bugs
|
||||||
|
if let Err(e) = self.engine.verify_block_basic(&header) {
|
||||||
|
self.importer.bad_blocks.report(
|
||||||
|
block.rlp_bytes(),
|
||||||
|
format!("Detected an issue with locally sealed block: {}", e),
|
||||||
|
);
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
|
||||||
// scope for self.import_lock
|
// scope for self.import_lock
|
||||||
let _import_lock = self.importer.import_lock.lock();
|
let _import_lock = self.importer.import_lock.lock();
|
||||||
trace_time!("import_sealed_block");
|
trace_time!("import_sealed_block");
|
||||||
|
|
||||||
let number = block.header().number();
|
|
||||||
let block_data = block.rlp_bytes();
|
let block_data = block.rlp_bytes();
|
||||||
let header = block.header().clone();
|
|
||||||
|
|
||||||
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
|
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
|
||||||
trace!(target: "client", "Imported sealed block #{} ({})", number, h);
|
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), header.hash());
|
||||||
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
|
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
|
||||||
route
|
route
|
||||||
};
|
};
|
||||||
|
let h = header.hash();
|
||||||
let route = ChainRoute::from([route].as_ref());
|
let route = ChainRoute::from([route].as_ref());
|
||||||
self.importer.miner.chain_new_blocks(
|
self.importer.miner.chain_new_blocks(
|
||||||
self,
|
self,
|
||||||
&[h.clone()],
|
&[h],
|
||||||
&[],
|
&[],
|
||||||
route.enacted(),
|
route.enacted(),
|
||||||
route.retracted(),
|
route.retracted(),
|
||||||
@ -2277,10 +2286,10 @@ impl ImportSealedBlock for Client {
|
|||||||
);
|
);
|
||||||
self.notify(|notify| {
|
self.notify(|notify| {
|
||||||
notify.new_blocks(
|
notify.new_blocks(
|
||||||
vec![h.clone()],
|
vec![h],
|
||||||
vec![],
|
vec![],
|
||||||
route.clone(),
|
route.clone(),
|
||||||
vec![h.clone()],
|
vec![h],
|
||||||
vec![],
|
vec![],
|
||||||
start.elapsed(),
|
start.elapsed(),
|
||||||
);
|
);
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
//! A blockchain engine that supports a non-instant BFT proof-of-authority.
|
//! A blockchain engine that supports a non-instant BFT proof-of-authority.
|
||||||
|
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
||||||
use std::fmt;
|
use std::{cmp, fmt};
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
||||||
@ -122,10 +122,10 @@ struct Step {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Step {
|
impl Step {
|
||||||
fn load(&self) -> usize { self.inner.load(AtomicOrdering::SeqCst) }
|
fn load(&self) -> u64 { self.inner.load(AtomicOrdering::SeqCst) as u64 }
|
||||||
fn duration_remaining(&self) -> Duration {
|
fn duration_remaining(&self) -> Duration {
|
||||||
let now = unix_now();
|
let now = unix_now();
|
||||||
let expected_seconds = (self.load() as u64)
|
let expected_seconds = self.load()
|
||||||
.checked_add(1)
|
.checked_add(1)
|
||||||
.and_then(|ctr| ctr.checked_mul(self.duration as u64))
|
.and_then(|ctr| ctr.checked_mul(self.duration as u64))
|
||||||
.map(Duration::from_secs);
|
.map(Duration::from_secs);
|
||||||
@ -161,8 +161,8 @@ impl Step {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_future(&self, given: usize) -> Result<(), Option<OutOfBounds<u64>>> {
|
fn check_future(&self, given: u64) -> Result<(), Option<OutOfBounds<u64>>> {
|
||||||
const REJECTED_STEP_DRIFT: usize = 4;
|
const REJECTED_STEP_DRIFT: u64 = 4;
|
||||||
|
|
||||||
// Verify if the step is correct.
|
// Verify if the step is correct.
|
||||||
if given <= self.load() {
|
if given <= self.load() {
|
||||||
@ -181,8 +181,8 @@ impl Step {
|
|||||||
let d = self.duration as u64;
|
let d = self.duration as u64;
|
||||||
Err(Some(OutOfBounds {
|
Err(Some(OutOfBounds {
|
||||||
min: None,
|
min: None,
|
||||||
max: Some(d * current as u64),
|
max: Some(d * current),
|
||||||
found: d * given as u64,
|
found: d * given,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -191,8 +191,8 @@ impl Step {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||||
fn calculate_score(parent_step: U256, current_step: U256, current_empty_steps: U256) -> U256 {
|
fn calculate_score(parent_step: u64, current_step: u64, current_empty_steps: usize) -> U256 {
|
||||||
U256::from(U128::max_value()) + parent_step - current_step + current_empty_steps
|
U256::from(U128::max_value()) + U256::from(parent_step) - U256::from(current_step) + U256::from(current_empty_steps)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EpochManager {
|
struct EpochManager {
|
||||||
@ -283,13 +283,26 @@ impl EpochManager {
|
|||||||
/// A message broadcast by authorities when it's their turn to seal a block but there are no
|
/// A message broadcast by authorities when it's their turn to seal a block but there are no
|
||||||
/// transactions. Other authorities accumulate these messages and later include them in the seal as
|
/// transactions. Other authorities accumulate these messages and later include them in the seal as
|
||||||
/// proof.
|
/// proof.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
struct EmptyStep {
|
struct EmptyStep {
|
||||||
signature: H520,
|
signature: H520,
|
||||||
step: usize,
|
step: u64,
|
||||||
parent_hash: H256,
|
parent_hash: H256,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for EmptyStep {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Ord for EmptyStep {
|
||||||
|
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
||||||
|
self.step.cmp(&other.step)
|
||||||
|
.then_with(|| self.parent_hash.cmp(&other.parent_hash))
|
||||||
|
.then_with(|| self.signature.cmp(&other.signature))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EmptyStep {
|
impl EmptyStep {
|
||||||
fn from_sealed(sealed_empty_step: SealedEmptyStep, parent_hash: &H256) -> EmptyStep {
|
fn from_sealed(sealed_empty_step: SealedEmptyStep, parent_hash: &H256) -> EmptyStep {
|
||||||
let signature = sealed_empty_step.signature;
|
let signature = sealed_empty_step.signature;
|
||||||
@ -352,7 +365,7 @@ pub fn empty_step_full_rlp(signature: &H520, empty_step_rlp: &[u8]) -> Vec<u8> {
|
|||||||
s.out()
|
s.out()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty_step_rlp(step: usize, parent_hash: &H256) -> Vec<u8> {
|
pub fn empty_step_rlp(step: u64, parent_hash: &H256) -> Vec<u8> {
|
||||||
let mut s = RlpStream::new_list(2);
|
let mut s = RlpStream::new_list(2);
|
||||||
s.append(&step).append(parent_hash);
|
s.append(&step).append(parent_hash);
|
||||||
s.out()
|
s.out()
|
||||||
@ -364,7 +377,7 @@ pub fn empty_step_rlp(step: usize, parent_hash: &H256) -> Vec<u8> {
|
|||||||
/// empty message is included.
|
/// empty message is included.
|
||||||
struct SealedEmptyStep {
|
struct SealedEmptyStep {
|
||||||
signature: H520,
|
signature: H520,
|
||||||
step: usize,
|
step: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for SealedEmptyStep {
|
impl Encodable for SealedEmptyStep {
|
||||||
@ -398,7 +411,7 @@ pub struct AuthorityRound {
|
|||||||
validators: Box<ValidatorSet>,
|
validators: Box<ValidatorSet>,
|
||||||
validate_score_transition: u64,
|
validate_score_transition: u64,
|
||||||
validate_step_transition: u64,
|
validate_step_transition: u64,
|
||||||
empty_steps: Mutex<Vec<EmptyStep>>,
|
empty_steps: Mutex<BTreeSet<EmptyStep>>,
|
||||||
epoch_manager: Mutex<EpochManager>,
|
epoch_manager: Mutex<EpochManager>,
|
||||||
immediate_transitions: bool,
|
immediate_transitions: bool,
|
||||||
block_reward: U256,
|
block_reward: U256,
|
||||||
@ -493,7 +506,7 @@ fn header_expected_seal_fields(header: &Header, empty_steps_transition: u64) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_step(header: &Header, empty_steps_transition: u64) -> Result<usize, ::rlp::DecoderError> {
|
fn header_step(header: &Header, empty_steps_transition: u64) -> Result<u64, ::rlp::DecoderError> {
|
||||||
let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition);
|
let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition);
|
||||||
Rlp::new(&header.seal().get(0).expect(
|
Rlp::new(&header.seal().get(0).expect(
|
||||||
&format!("was either checked with verify_block_basic or is genesis; has {} fields; qed (Make sure the spec file has a correct genesis seal)", expected_seal_fields))).as_val()
|
&format!("was either checked with verify_block_basic or is genesis; has {} fields; qed (Make sure the spec file has a correct genesis seal)", expected_seal_fields))).as_val()
|
||||||
@ -532,17 +545,17 @@ fn header_empty_steps_signers(header: &Header, empty_steps_transition: u64) -> R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step_proposer(validators: &ValidatorSet, bh: &H256, step: usize) -> Address {
|
fn step_proposer(validators: &ValidatorSet, bh: &H256, step: u64) -> Address {
|
||||||
let proposer = validators.get(bh, step);
|
let proposer = validators.get(bh, step as usize);
|
||||||
trace!(target: "engine", "Fetched proposer for step {}: {}", step, proposer);
|
trace!(target: "engine", "Fetched proposer for step {}: {}", step, proposer);
|
||||||
proposer
|
proposer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_step_proposer(validators: &ValidatorSet, bh: &H256, step: usize, address: &Address) -> bool {
|
fn is_step_proposer(validators: &ValidatorSet, bh: &H256, step: u64, address: &Address) -> bool {
|
||||||
step_proposer(validators, bh, step) == *address
|
step_proposer(validators, bh, step) == *address
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_timestamp(step: &Step, header_step: usize) -> Result<(), BlockError> {
|
fn verify_timestamp(step: &Step, header_step: u64) -> Result<(), BlockError> {
|
||||||
match step.check_future(header_step) {
|
match step.check_future(header_step) {
|
||||||
Err(None) => {
|
Err(None) => {
|
||||||
trace!(target: "engine", "verify_timestamp: block from the future");
|
trace!(target: "engine", "verify_timestamp: block from the future");
|
||||||
@ -563,7 +576,7 @@ fn verify_external(header: &Header, validators: &ValidatorSet, empty_steps_trans
|
|||||||
let header_step = header_step(header, empty_steps_transition)?;
|
let header_step = header_step(header, empty_steps_transition)?;
|
||||||
|
|
||||||
let proposer_signature = header_signature(header, empty_steps_transition)?;
|
let proposer_signature = header_signature(header, empty_steps_transition)?;
|
||||||
let correct_proposer = validators.get(header.parent_hash(), header_step);
|
let correct_proposer = validators.get(header.parent_hash(), header_step as usize);
|
||||||
let is_invalid_proposer = *header.author() != correct_proposer || {
|
let is_invalid_proposer = *header.author() != correct_proposer || {
|
||||||
let empty_steps_rlp = if header.number() >= empty_steps_transition {
|
let empty_steps_rlp = if header.number() >= empty_steps_transition {
|
||||||
Some(header_empty_steps_raw(header))
|
Some(header_empty_steps_raw(header))
|
||||||
@ -633,13 +646,13 @@ impl AuthorityRound {
|
|||||||
panic!("authority_round: step duration can't be zero")
|
panic!("authority_round: step duration can't be zero")
|
||||||
}
|
}
|
||||||
let should_timeout = our_params.start_step.is_none();
|
let should_timeout = our_params.start_step.is_none();
|
||||||
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / (our_params.step_duration as u64))) as usize;
|
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / (our_params.step_duration as u64)));
|
||||||
let engine = Arc::new(
|
let engine = Arc::new(
|
||||||
AuthorityRound {
|
AuthorityRound {
|
||||||
transition_service: IoService::<()>::start()?,
|
transition_service: IoService::<()>::start()?,
|
||||||
step: Arc::new(PermissionedStep {
|
step: Arc::new(PermissionedStep {
|
||||||
inner: Step {
|
inner: Step {
|
||||||
inner: AtomicUsize::new(initial_step),
|
inner: AtomicUsize::new(initial_step as usize),
|
||||||
calibrate: our_params.start_step.is_none(),
|
calibrate: our_params.start_step.is_none(),
|
||||||
duration: our_params.step_duration,
|
duration: our_params.step_duration,
|
||||||
},
|
},
|
||||||
@ -650,7 +663,7 @@ impl AuthorityRound {
|
|||||||
validators: our_params.validators,
|
validators: our_params.validators,
|
||||||
validate_score_transition: our_params.validate_score_transition,
|
validate_score_transition: our_params.validate_score_transition,
|
||||||
validate_step_transition: our_params.validate_step_transition,
|
validate_step_transition: our_params.validate_step_transition,
|
||||||
empty_steps: Mutex::new(Vec::new()),
|
empty_steps: Default::default(),
|
||||||
epoch_manager: Mutex::new(EpochManager::blank()),
|
epoch_manager: Mutex::new(EpochManager::blank()),
|
||||||
immediate_transitions: our_params.immediate_transitions,
|
immediate_transitions: our_params.immediate_transitions,
|
||||||
block_reward: our_params.block_reward,
|
block_reward: our_params.block_reward,
|
||||||
@ -698,22 +711,41 @@ impl AuthorityRound {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty_steps(&self, from_step: U256, to_step: U256, parent_hash: H256) -> Vec<EmptyStep> {
|
fn empty_steps(&self, from_step: u64, to_step: u64, parent_hash: H256) -> Vec<EmptyStep> {
|
||||||
self.empty_steps.lock().iter().filter(|e| {
|
let from = EmptyStep {
|
||||||
U256::from(e.step) > from_step &&
|
step: from_step + 1,
|
||||||
U256::from(e.step) < to_step &&
|
parent_hash,
|
||||||
e.parent_hash == parent_hash
|
signature: Default::default(),
|
||||||
}).cloned().collect()
|
};
|
||||||
|
let to = EmptyStep {
|
||||||
|
step: to_step,
|
||||||
|
parent_hash: Default::default(),
|
||||||
|
signature: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if from >= to {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.empty_steps.lock()
|
||||||
|
.range(from..to)
|
||||||
|
.filter(|e| e.parent_hash == parent_hash)
|
||||||
|
.cloned()
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_empty_steps(&self, step: U256) {
|
fn clear_empty_steps(&self, step: u64) {
|
||||||
// clear old `empty_steps` messages
|
// clear old `empty_steps` messages
|
||||||
self.empty_steps.lock().retain(|e| U256::from(e.step) > step);
|
let mut empty_steps = self.empty_steps.lock();
|
||||||
|
*empty_steps = empty_steps.split_off(&EmptyStep {
|
||||||
|
step: step + 1,
|
||||||
|
parent_hash: Default::default(),
|
||||||
|
signature: Default::default(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_empty_step_message(&self, empty_step: EmptyStep) {
|
fn handle_empty_step_message(&self, empty_step: EmptyStep) {
|
||||||
let mut empty_steps = self.empty_steps.lock();
|
self.empty_steps.lock().insert(empty_step);
|
||||||
empty_steps.push(empty_step);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_empty_step(&self, parent_hash: &H256) {
|
fn generate_empty_step(&self, parent_hash: &H256) {
|
||||||
@ -743,7 +775,7 @@ impl AuthorityRound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_skipped(&self, header: &Header, current_step: usize, parent_step: usize, validators: &ValidatorSet, set_number: u64) {
|
fn report_skipped(&self, header: &Header, current_step: u64, parent_step: u64, validators: &ValidatorSet, set_number: u64) {
|
||||||
// we're building on top of the genesis block so don't report any skipped steps
|
// we're building on top of the genesis block so don't report any skipped steps
|
||||||
if header.number() == 1 {
|
if header.number() == 1 {
|
||||||
return;
|
return;
|
||||||
@ -873,12 +905,12 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
let current_step = self.step.inner.load();
|
let current_step = self.step.inner.load();
|
||||||
|
|
||||||
let current_empty_steps_len = if header.number() >= self.empty_steps_transition {
|
let current_empty_steps_len = if header.number() >= self.empty_steps_transition {
|
||||||
self.empty_steps(parent_step.into(), current_step.into(), parent.hash()).len()
|
self.empty_steps(parent_step, current_step, parent.hash()).len()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let score = calculate_score(parent_step.into(), current_step.into(), current_empty_steps_len.into());
|
let score = calculate_score(parent_step, current_step, current_empty_steps_len);
|
||||||
header.set_difficulty(score);
|
header.set_difficulty(score);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -922,8 +954,8 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
let parent_step: U256 = header_step(parent, self.empty_steps_transition)
|
let parent_step = header_step(parent, self.empty_steps_transition)
|
||||||
.expect("Header has been verified; qed").into();
|
.expect("Header has been verified; qed");
|
||||||
|
|
||||||
let step = self.step.inner.load();
|
let step = self.step.inner.load();
|
||||||
|
|
||||||
@ -958,7 +990,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
if is_step_proposer(&*validators, header.parent_hash(), step, header.author()) {
|
if is_step_proposer(&*validators, header.parent_hash(), step, header.author()) {
|
||||||
// this is guarded against by `can_propose` unless the block was signed
|
// this is guarded against by `can_propose` unless the block was signed
|
||||||
// on the same step (implies same key) and on a different node.
|
// on the same step (implies same key) and on a different node.
|
||||||
if parent_step == step.into() {
|
if parent_step == step {
|
||||||
warn!("Attempted to seal block on the same step as parent. Is this authority sealing with more than one node?");
|
warn!("Attempted to seal block on the same step as parent. Is this authority sealing with more than one node?");
|
||||||
return Seal::None;
|
return Seal::None;
|
||||||
}
|
}
|
||||||
@ -970,7 +1002,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
block.transactions().is_empty() &&
|
block.transactions().is_empty() &&
|
||||||
empty_steps.len() < self.maximum_empty_steps {
|
empty_steps.len() < self.maximum_empty_steps {
|
||||||
|
|
||||||
self.generate_empty_step(header.parent_hash());
|
if self.step.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) {
|
||||||
|
self.generate_empty_step(header.parent_hash());
|
||||||
|
}
|
||||||
|
|
||||||
return Seal::None;
|
return Seal::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -994,7 +1029,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
// report any skipped primaries between the parent block and
|
// report any skipped primaries between the parent block and
|
||||||
// the block we're sealing, unless we have empty steps enabled
|
// the block we're sealing, unless we have empty steps enabled
|
||||||
if header.number() < self.empty_steps_transition {
|
if header.number() < self.empty_steps_transition {
|
||||||
self.report_skipped(header, step, u64::from(parent_step) as usize, &*validators, set_number);
|
self.report_skipped(header, step, parent_step, &*validators, set_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut fields = vec![
|
let mut fields = vec![
|
||||||
@ -1534,12 +1569,12 @@ mod tests {
|
|||||||
|
|
||||||
// Two validators.
|
// Two validators.
|
||||||
// Spec starts with step 2.
|
// Spec starts with step 2.
|
||||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(2), U256::zero()));
|
header.set_difficulty(calculate_score(0, 2, 0));
|
||||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||||
header.set_seal(vec![encode(&2usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
header.set_seal(vec![encode(&2usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||||
assert!(engine.verify_block_external(&header).is_err());
|
assert!(engine.verify_block_external(&header).is_err());
|
||||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(1), U256::zero()));
|
header.set_difficulty(calculate_score(0, 1, 0));
|
||||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||||
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||||
@ -1563,7 +1598,7 @@ mod tests {
|
|||||||
|
|
||||||
// Two validators.
|
// Two validators.
|
||||||
// Spec starts with step 2.
|
// Spec starts with step 2.
|
||||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(1), U256::zero()));
|
header.set_difficulty(calculate_score(0, 1, 0));
|
||||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||||
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||||
@ -1591,10 +1626,10 @@ mod tests {
|
|||||||
// Two validators.
|
// Two validators.
|
||||||
// Spec starts with step 2.
|
// Spec starts with step 2.
|
||||||
header.set_seal(vec![encode(&5usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
header.set_seal(vec![encode(&5usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||||
header.set_difficulty(calculate_score(U256::from(4), U256::from(5), U256::zero()));
|
header.set_difficulty(calculate_score(4, 5, 0));
|
||||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||||
header.set_seal(vec![encode(&3usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
header.set_seal(vec![encode(&3usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||||
header.set_difficulty(calculate_score(U256::from(4), U256::from(3), U256::zero()));
|
header.set_difficulty(calculate_score(4, 3, 0));
|
||||||
assert!(engine.verify_block_family(&header, &parent_header).is_err());
|
assert!(engine.verify_block_family(&header, &parent_header).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1628,7 +1663,7 @@ mod tests {
|
|||||||
parent_header.set_seal(vec![encode(&1usize).into_vec()]);
|
parent_header.set_seal(vec![encode(&1usize).into_vec()]);
|
||||||
parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
|
parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
|
||||||
let mut header: Header = Header::default();
|
let mut header: Header = Header::default();
|
||||||
header.set_difficulty(calculate_score(U256::from(1), U256::from(3), U256::zero()));
|
header.set_difficulty(calculate_score(1, 3, 0));
|
||||||
header.set_gas_limit("222222".parse::<U256>().unwrap());
|
header.set_gas_limit("222222".parse::<U256>().unwrap());
|
||||||
header.set_seal(vec![encode(&3usize).into_vec()]);
|
header.set_seal(vec![encode(&3usize).into_vec()]);
|
||||||
|
|
||||||
@ -1742,14 +1777,14 @@ mod tests {
|
|||||||
(spec, tap, accounts)
|
(spec, tap, accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty_step(engine: &EthEngine, step: usize, parent_hash: &H256) -> EmptyStep {
|
fn empty_step(engine: &EthEngine, step: u64, parent_hash: &H256) -> EmptyStep {
|
||||||
let empty_step_rlp = super::empty_step_rlp(step, parent_hash);
|
let empty_step_rlp = super::empty_step_rlp(step, parent_hash);
|
||||||
let signature = engine.sign(keccak(&empty_step_rlp)).unwrap().into();
|
let signature = engine.sign(keccak(&empty_step_rlp)).unwrap().into();
|
||||||
let parent_hash = parent_hash.clone();
|
let parent_hash = parent_hash.clone();
|
||||||
EmptyStep { step, signature, parent_hash }
|
EmptyStep { step, signature, parent_hash }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sealed_empty_step(engine: &EthEngine, step: usize, parent_hash: &H256) -> SealedEmptyStep {
|
fn sealed_empty_step(engine: &EthEngine, step: u64, parent_hash: &H256) -> SealedEmptyStep {
|
||||||
let empty_step_rlp = super::empty_step_rlp(step, parent_hash);
|
let empty_step_rlp = super::empty_step_rlp(step, parent_hash);
|
||||||
let signature = engine.sign(keccak(&empty_step_rlp)).unwrap().into();
|
let signature = engine.sign(keccak(&empty_step_rlp)).unwrap().into();
|
||||||
SealedEmptyStep { signature, step }
|
SealedEmptyStep { signature, step }
|
||||||
@ -1785,6 +1820,11 @@ mod tests {
|
|||||||
|
|
||||||
// we've received the message
|
// we've received the message
|
||||||
assert!(notify.messages.read().contains(&empty_step_rlp));
|
assert!(notify.messages.read().contains(&empty_step_rlp));
|
||||||
|
let len = notify.messages.read().len();
|
||||||
|
|
||||||
|
// make sure that we don't generate empty step for the second time
|
||||||
|
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
|
||||||
|
assert_eq!(len, notify.messages.read().len());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1999,7 +2039,7 @@ mod tests {
|
|||||||
let empty_step3 = sealed_empty_step(engine, 3, &parent_header.hash());
|
let empty_step3 = sealed_empty_step(engine, 3, &parent_header.hash());
|
||||||
|
|
||||||
let empty_steps = vec![empty_step2, empty_step3];
|
let empty_steps = vec![empty_step2, empty_step3];
|
||||||
header.set_difficulty(calculate_score(U256::from(0), U256::from(4), U256::from(2)));
|
header.set_difficulty(calculate_score(0, 4, 2));
|
||||||
let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap();
|
let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap();
|
||||||
header.set_seal(vec![
|
header.set_seal(vec![
|
||||||
encode(&4usize).into_vec(),
|
encode(&4usize).into_vec(),
|
||||||
@ -2114,4 +2154,52 @@ mod tests {
|
|||||||
BTreeMap::default(),
|
BTreeMap::default(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_empty_steps() {
|
||||||
|
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||||
|
let params = AuthorityRoundParams {
|
||||||
|
step_duration: 4,
|
||||||
|
start_step: Some(1),
|
||||||
|
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||||
|
validate_score_transition: 0,
|
||||||
|
validate_step_transition: 0,
|
||||||
|
immediate_transitions: true,
|
||||||
|
maximum_uncle_count_transition: 0,
|
||||||
|
maximum_uncle_count: 0,
|
||||||
|
empty_steps_transition: 0,
|
||||||
|
maximum_empty_steps: 10,
|
||||||
|
block_reward: Default::default(),
|
||||||
|
block_reward_contract_transition: 0,
|
||||||
|
block_reward_contract: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut c_params = ::spec::CommonParams::default();
|
||||||
|
c_params.gas_limit_bound_divisor = 5.into();
|
||||||
|
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
||||||
|
let engine = AuthorityRound::new(params, machine).unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
let parent_hash: H256 = 1.into();
|
||||||
|
let signature = H520::default();
|
||||||
|
let step = |step: u64| EmptyStep {
|
||||||
|
step,
|
||||||
|
parent_hash,
|
||||||
|
signature,
|
||||||
|
};
|
||||||
|
|
||||||
|
engine.handle_empty_step_message(step(1));
|
||||||
|
engine.handle_empty_step_message(step(3));
|
||||||
|
engine.handle_empty_step_message(step(2));
|
||||||
|
engine.handle_empty_step_message(step(1));
|
||||||
|
|
||||||
|
assert_eq!(engine.empty_steps(0, 4, parent_hash), vec![step(1), step(2), step(3)]);
|
||||||
|
assert_eq!(engine.empty_steps(2, 3, parent_hash), vec![]);
|
||||||
|
assert_eq!(engine.empty_steps(2, 4, parent_hash), vec![step(3)]);
|
||||||
|
|
||||||
|
engine.clear_empty_steps(2);
|
||||||
|
|
||||||
|
assert_eq!(engine.empty_steps(0, 3, parent_hash), vec![]);
|
||||||
|
assert_eq!(engine.empty_steps(0, 4, parent_hash), vec![step(3)]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ env_logger = "0.5"
|
|||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
heapsize = "0.4"
|
heapsize = "0.4"
|
||||||
semver = "0.9"
|
semver = "0.9"
|
||||||
smallvec = { version = "0.4", features = ["heapsizeof"] }
|
|
||||||
parking_lot = "0.6"
|
parking_lot = "0.6"
|
||||||
trace-time = "0.1"
|
trace-time = "0.1"
|
||||||
ipnetwork = "0.12.6"
|
ipnetwork = "0.12.6"
|
||||||
|
@ -264,12 +264,10 @@ pub struct EthSync {
|
|||||||
|
|
||||||
fn light_params(
|
fn light_params(
|
||||||
network_id: u64,
|
network_id: u64,
|
||||||
max_peers: u32,
|
median_peers: f64,
|
||||||
pruning_info: PruningInfo,
|
pruning_info: PruningInfo,
|
||||||
sample_store: Option<Box<SampleStore>>,
|
sample_store: Option<Box<SampleStore>>,
|
||||||
) -> LightParams {
|
) -> LightParams {
|
||||||
const MAX_LIGHTSERV_LOAD: f64 = 0.5;
|
|
||||||
|
|
||||||
let mut light_params = LightParams {
|
let mut light_params = LightParams {
|
||||||
network_id: network_id,
|
network_id: network_id,
|
||||||
config: Default::default(),
|
config: Default::default(),
|
||||||
@ -282,9 +280,7 @@ fn light_params(
|
|||||||
sample_store: sample_store,
|
sample_store: sample_store,
|
||||||
};
|
};
|
||||||
|
|
||||||
let max_peers = ::std::cmp::max(max_peers, 1);
|
light_params.config.median_peers = median_peers;
|
||||||
light_params.config.load_share = MAX_LIGHTSERV_LOAD / max_peers as f64;
|
|
||||||
|
|
||||||
light_params
|
light_params
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,9 +297,10 @@ impl EthSync {
|
|||||||
.map(|mut p| { p.push("request_timings"); light_net::FileStore(p) })
|
.map(|mut p| { p.push("request_timings"); light_net::FileStore(p) })
|
||||||
.map(|store| Box::new(store) as Box<_>);
|
.map(|store| Box::new(store) as Box<_>);
|
||||||
|
|
||||||
|
let median_peers = (params.network_config.min_peers + params.network_config.max_peers) as f64 / 2.0;
|
||||||
let light_params = light_params(
|
let light_params = light_params(
|
||||||
params.config.network_id,
|
params.config.network_id,
|
||||||
params.network_config.max_peers,
|
median_peers,
|
||||||
pruning_info,
|
pruning_info,
|
||||||
sample_store,
|
sample_store,
|
||||||
);
|
);
|
||||||
@ -940,19 +937,3 @@ impl LightSyncProvider for LightSync {
|
|||||||
Default::default() // TODO
|
Default::default() // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn light_params_load_share_depends_on_max_peers() {
|
|
||||||
let pruning_info = PruningInfo {
|
|
||||||
earliest_chain: 0,
|
|
||||||
earliest_state: 0,
|
|
||||||
};
|
|
||||||
let params1 = light_params(0, 10, pruning_info.clone(), None);
|
|
||||||
let params2 = light_params(0, 20, pruning_info, None);
|
|
||||||
assert!(params1.config.load_share > params2.config.load_share)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::collections::{HashSet, HashMap, hash_map};
|
use std::collections::{HashSet, HashMap, hash_map};
|
||||||
use smallvec::SmallVec;
|
|
||||||
use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP};
|
use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP};
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
@ -29,8 +28,6 @@ use transaction::UnverifiedTransaction;
|
|||||||
|
|
||||||
known_heap_size!(0, HeaderId);
|
known_heap_size!(0, HeaderId);
|
||||||
|
|
||||||
type SmallHashVec = SmallVec<[H256; 1]>;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
pub struct SyncHeader {
|
pub struct SyncHeader {
|
||||||
pub bytes: Bytes,
|
pub bytes: Bytes,
|
||||||
@ -157,7 +154,7 @@ pub struct BlockCollection {
|
|||||||
/// Used to map body to header.
|
/// Used to map body to header.
|
||||||
header_ids: HashMap<HeaderId, H256>,
|
header_ids: HashMap<HeaderId, H256>,
|
||||||
/// Used to map receipts root to headers.
|
/// Used to map receipts root to headers.
|
||||||
receipt_ids: HashMap<H256, SmallHashVec>,
|
receipt_ids: HashMap<H256, Vec<H256>>,
|
||||||
/// First block in `blocks`.
|
/// First block in `blocks`.
|
||||||
head: Option<H256>,
|
head: Option<H256>,
|
||||||
/// Set of block header hashes being downloaded
|
/// Set of block header hashes being downloaded
|
||||||
@ -519,7 +516,7 @@ impl BlockCollection {
|
|||||||
let receipts_stream = RlpStream::new_list(0);
|
let receipts_stream = RlpStream::new_list(0);
|
||||||
(Some(receipts_stream.out()), receipt_root)
|
(Some(receipts_stream.out()), receipt_root)
|
||||||
} else {
|
} else {
|
||||||
self.receipt_ids.entry(receipt_root).or_insert_with(|| SmallHashVec::new()).push(hash);
|
self.receipt_ids.entry(receipt_root).or_insert_with(Vec::new).push(hash);
|
||||||
(None, receipt_root)
|
(None, receipt_root)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -35,7 +35,6 @@ extern crate fastmap;
|
|||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate semver;
|
extern crate semver;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
extern crate smallvec;
|
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate ipnetwork;
|
extern crate ipnetwork;
|
||||||
extern crate keccak_hash as hash;
|
extern crate keccak_hash as hash;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
|
|
||||||
@ -213,6 +214,44 @@ enum SyncState {
|
|||||||
Rounds(SyncRound),
|
Rounds(SyncRound),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A wrapper around the SyncState that makes sure to
|
||||||
|
/// update the giving reference to `is_idle`
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct SyncStateWrapper {
|
||||||
|
state: SyncState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SyncStateWrapper {
|
||||||
|
/// Create a new wrapper for SyncState::Idle
|
||||||
|
pub fn idle() -> Self {
|
||||||
|
SyncStateWrapper {
|
||||||
|
state: SyncState::Idle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the new state's value, making sure `is_idle` gets updated
|
||||||
|
pub fn set(&mut self, state: SyncState, is_idle_handle: &mut bool) {
|
||||||
|
*is_idle_handle = match state {
|
||||||
|
SyncState::Idle => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
self.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the internal state's value
|
||||||
|
pub fn into_inner(self) -> SyncState {
|
||||||
|
self.state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for SyncStateWrapper {
|
||||||
|
type Target = SyncState;
|
||||||
|
|
||||||
|
fn deref(&self) -> &SyncState {
|
||||||
|
&self.state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ResponseCtx<'a> {
|
struct ResponseCtx<'a> {
|
||||||
peer: PeerId,
|
peer: PeerId,
|
||||||
req_id: ReqId,
|
req_id: ReqId,
|
||||||
@ -235,7 +274,9 @@ pub struct LightSync<L: AsLightClient> {
|
|||||||
pending_reqs: Mutex<HashMap<ReqId, PendingReq>>, // requests from this handler
|
pending_reqs: Mutex<HashMap<ReqId, PendingReq>>, // requests from this handler
|
||||||
client: Arc<L>,
|
client: Arc<L>,
|
||||||
rng: Mutex<OsRng>,
|
rng: Mutex<OsRng>,
|
||||||
state: Mutex<SyncState>,
|
state: Mutex<SyncStateWrapper>,
|
||||||
|
// We duplicate this state tracking to avoid deadlocks in `is_major_importing`.
|
||||||
|
is_idle: Mutex<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -309,16 +350,17 @@ impl<L: AsLightClient + Send + Sync> Handler for LightSync<L> {
|
|||||||
|
|
||||||
if new_best.is_none() {
|
if new_best.is_none() {
|
||||||
debug!(target: "sync", "No peers remain. Reverting to idle");
|
debug!(target: "sync", "No peers remain. Reverting to idle");
|
||||||
*self.state.lock() = SyncState::Idle;
|
self.set_state(&mut self.state.lock(), SyncState::Idle);
|
||||||
} else {
|
} else {
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
|
|
||||||
*state = match mem::replace(&mut *state, SyncState::Idle) {
|
let next_state = match mem::replace(&mut *state, SyncStateWrapper::idle()).into_inner() {
|
||||||
SyncState::Idle => SyncState::Idle,
|
SyncState::Idle => SyncState::Idle,
|
||||||
SyncState::AncestorSearch(search) =>
|
SyncState::AncestorSearch(search) =>
|
||||||
SyncState::AncestorSearch(search.requests_abandoned(unfulfilled)),
|
SyncState::AncestorSearch(search.requests_abandoned(unfulfilled)),
|
||||||
SyncState::Rounds(round) => SyncState::Rounds(round.requests_abandoned(unfulfilled)),
|
SyncState::Rounds(round) => SyncState::Rounds(round.requests_abandoned(unfulfilled)),
|
||||||
};
|
};
|
||||||
|
self.set_state(&mut state, next_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.maintain_sync(ctx.as_basic());
|
self.maintain_sync(ctx.as_basic());
|
||||||
@ -390,12 +432,13 @@ impl<L: AsLightClient + Send + Sync> Handler for LightSync<L> {
|
|||||||
data: headers,
|
data: headers,
|
||||||
};
|
};
|
||||||
|
|
||||||
*state = match mem::replace(&mut *state, SyncState::Idle) {
|
let next_state = match mem::replace(&mut *state, SyncStateWrapper::idle()).into_inner() {
|
||||||
SyncState::Idle => SyncState::Idle,
|
SyncState::Idle => SyncState::Idle,
|
||||||
SyncState::AncestorSearch(search) =>
|
SyncState::AncestorSearch(search) =>
|
||||||
SyncState::AncestorSearch(search.process_response(&ctx, &*self.client)),
|
SyncState::AncestorSearch(search.process_response(&ctx, &*self.client)),
|
||||||
SyncState::Rounds(round) => SyncState::Rounds(round.process_response(&ctx)),
|
SyncState::Rounds(round) => SyncState::Rounds(round.process_response(&ctx)),
|
||||||
};
|
};
|
||||||
|
self.set_state(&mut state, next_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.maintain_sync(ctx.as_basic());
|
self.maintain_sync(ctx.as_basic());
|
||||||
@ -408,12 +451,18 @@ impl<L: AsLightClient + Send + Sync> Handler for LightSync<L> {
|
|||||||
|
|
||||||
// private helpers
|
// private helpers
|
||||||
impl<L: AsLightClient> LightSync<L> {
|
impl<L: AsLightClient> LightSync<L> {
|
||||||
|
/// Sets the LightSync's state, and update
|
||||||
|
/// `is_idle`
|
||||||
|
fn set_state(&self, state: &mut SyncStateWrapper, next_state: SyncState) {
|
||||||
|
state.set(next_state, &mut self.is_idle.lock());
|
||||||
|
}
|
||||||
|
|
||||||
// Begins a search for the common ancestor and our best block.
|
// Begins a search for the common ancestor and our best block.
|
||||||
// does not lock state, instead has a mutable reference to it passed.
|
// does not lock state, instead has a mutable reference to it passed.
|
||||||
fn begin_search(&self, state: &mut SyncState) {
|
fn begin_search(&self, state: &mut SyncStateWrapper) {
|
||||||
if let None = *self.best_seen.lock() {
|
if let None = *self.best_seen.lock() {
|
||||||
// no peers.
|
// no peers.
|
||||||
*state = SyncState::Idle;
|
self.set_state(state, SyncState::Idle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +471,8 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
|
|
||||||
trace!(target: "sync", "Beginning search for common ancestor from {:?}",
|
trace!(target: "sync", "Beginning search for common ancestor from {:?}",
|
||||||
(chain_info.best_block_number, chain_info.best_block_hash));
|
(chain_info.best_block_number, chain_info.best_block_hash));
|
||||||
*state = SyncState::AncestorSearch(AncestorSearch::begin(chain_info.best_block_number));
|
let next_state = SyncState::AncestorSearch(AncestorSearch::begin(chain_info.best_block_number));
|
||||||
|
self.set_state(state, next_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handles request dispatch, block import, state machine transitions, and timeouts.
|
// handles request dispatch, block import, state machine transitions, and timeouts.
|
||||||
@ -435,7 +485,7 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
let chain_info = client.chain_info();
|
let chain_info = client.chain_info();
|
||||||
|
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
debug!(target: "sync", "Maintaining sync ({:?})", &*state);
|
debug!(target: "sync", "Maintaining sync ({:?})", **state);
|
||||||
|
|
||||||
// drain any pending blocks into the queue.
|
// drain any pending blocks into the queue.
|
||||||
{
|
{
|
||||||
@ -445,11 +495,12 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
loop {
|
loop {
|
||||||
if client.queue_info().is_full() { break }
|
if client.queue_info().is_full() { break }
|
||||||
|
|
||||||
*state = match mem::replace(&mut *state, SyncState::Idle) {
|
let next_state = match mem::replace(&mut *state, SyncStateWrapper::idle()).into_inner() {
|
||||||
SyncState::Rounds(round)
|
SyncState::Rounds(round)
|
||||||
=> SyncState::Rounds(round.drain(&mut sink, Some(DRAIN_AMOUNT))),
|
=> SyncState::Rounds(round.drain(&mut sink, Some(DRAIN_AMOUNT))),
|
||||||
other => other,
|
other => other,
|
||||||
};
|
};
|
||||||
|
self.set_state(&mut state, next_state);
|
||||||
|
|
||||||
if sink.is_empty() { break }
|
if sink.is_empty() { break }
|
||||||
trace!(target: "sync", "Drained {} headers to import", sink.len());
|
trace!(target: "sync", "Drained {} headers to import", sink.len());
|
||||||
@ -483,15 +534,15 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
let network_score = other.as_ref().map(|target| target.head_td);
|
let network_score = other.as_ref().map(|target| target.head_td);
|
||||||
trace!(target: "sync", "No target to sync to. Network score: {:?}, Local score: {:?}",
|
trace!(target: "sync", "No target to sync to. Network score: {:?}, Local score: {:?}",
|
||||||
network_score, best_td);
|
network_score, best_td);
|
||||||
*state = SyncState::Idle;
|
self.set_state(&mut state, SyncState::Idle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match mem::replace(&mut *state, SyncState::Idle) {
|
match mem::replace(&mut *state, SyncStateWrapper::idle()).into_inner() {
|
||||||
SyncState::Rounds(SyncRound::Abort(reason, remaining)) => {
|
SyncState::Rounds(SyncRound::Abort(reason, remaining)) => {
|
||||||
if remaining.len() > 0 {
|
if remaining.len() > 0 {
|
||||||
*state = SyncState::Rounds(SyncRound::Abort(reason, remaining));
|
self.set_state(&mut state, SyncState::Rounds(SyncRound::Abort(reason, remaining)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +556,7 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
AbortReason::NoResponses => {}
|
AbortReason::NoResponses => {}
|
||||||
AbortReason::TargetReached => {
|
AbortReason::TargetReached => {
|
||||||
debug!(target: "sync", "Sync target reached. Going idle");
|
debug!(target: "sync", "Sync target reached. Going idle");
|
||||||
*state = SyncState::Idle;
|
self.set_state(&mut state, SyncState::Idle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,15 +565,15 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
self.begin_search(&mut state);
|
self.begin_search(&mut state);
|
||||||
}
|
}
|
||||||
SyncState::AncestorSearch(AncestorSearch::FoundCommon(num, hash)) => {
|
SyncState::AncestorSearch(AncestorSearch::FoundCommon(num, hash)) => {
|
||||||
*state = SyncState::Rounds(SyncRound::begin((num, hash), sync_target));
|
self.set_state(&mut state, SyncState::Rounds(SyncRound::begin((num, hash), sync_target)));
|
||||||
}
|
}
|
||||||
SyncState::AncestorSearch(AncestorSearch::Genesis) => {
|
SyncState::AncestorSearch(AncestorSearch::Genesis) => {
|
||||||
// Same here.
|
// Same here.
|
||||||
let g_hash = chain_info.genesis_hash;
|
let g_hash = chain_info.genesis_hash;
|
||||||
*state = SyncState::Rounds(SyncRound::begin((0, g_hash), sync_target));
|
self.set_state(&mut state, SyncState::Rounds(SyncRound::begin((0, g_hash), sync_target)));
|
||||||
}
|
}
|
||||||
SyncState::Idle => self.begin_search(&mut state),
|
SyncState::Idle => self.begin_search(&mut state),
|
||||||
other => *state = other, // restore displaced state.
|
other => self.set_state(&mut state, other), // restore displaced state.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,12 +594,13 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
}
|
}
|
||||||
drop(pending_reqs);
|
drop(pending_reqs);
|
||||||
|
|
||||||
*state = match mem::replace(&mut *state, SyncState::Idle) {
|
let next_state = match mem::replace(&mut *state, SyncStateWrapper::idle()).into_inner() {
|
||||||
SyncState::Idle => SyncState::Idle,
|
SyncState::Idle => SyncState::Idle,
|
||||||
SyncState::AncestorSearch(search) =>
|
SyncState::AncestorSearch(search) =>
|
||||||
SyncState::AncestorSearch(search.requests_abandoned(&unfulfilled)),
|
SyncState::AncestorSearch(search.requests_abandoned(&unfulfilled)),
|
||||||
SyncState::Rounds(round) => SyncState::Rounds(round.requests_abandoned(&unfulfilled)),
|
SyncState::Rounds(round) => SyncState::Rounds(round.requests_abandoned(&unfulfilled)),
|
||||||
};
|
};
|
||||||
|
self.set_state(&mut state, next_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,34 +657,14 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
*state = match mem::replace(&mut *state, SyncState::Idle) {
|
let next_state = match mem::replace(&mut *state, SyncStateWrapper::idle()).into_inner() {
|
||||||
SyncState::Rounds(round) =>
|
SyncState::Rounds(round) =>
|
||||||
SyncState::Rounds(round.dispatch_requests(dispatcher)),
|
SyncState::Rounds(round.dispatch_requests(dispatcher)),
|
||||||
SyncState::AncestorSearch(search) =>
|
SyncState::AncestorSearch(search) =>
|
||||||
SyncState::AncestorSearch(search.dispatch_request(dispatcher)),
|
SyncState::AncestorSearch(search.dispatch_request(dispatcher)),
|
||||||
other => other,
|
other => other,
|
||||||
};
|
};
|
||||||
}
|
self.set_state(&mut state, next_state);
|
||||||
}
|
|
||||||
|
|
||||||
fn is_major_importing_do_wait(&self, wait: bool) -> bool {
|
|
||||||
const EMPTY_QUEUE: usize = 3;
|
|
||||||
|
|
||||||
if self.client.as_light_client().queue_info().unverified_queue_size > EMPTY_QUEUE {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let mg_state = if wait {
|
|
||||||
self.state.lock()
|
|
||||||
} else {
|
|
||||||
if let Some(mg_state) = self.state.try_lock() {
|
|
||||||
mg_state
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
match *mg_state {
|
|
||||||
SyncState::Idle => false,
|
|
||||||
_ => true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -651,7 +683,8 @@ impl<L: AsLightClient> LightSync<L> {
|
|||||||
pending_reqs: Mutex::new(HashMap::new()),
|
pending_reqs: Mutex::new(HashMap::new()),
|
||||||
client: client,
|
client: client,
|
||||||
rng: Mutex::new(OsRng::new()?),
|
rng: Mutex::new(OsRng::new()?),
|
||||||
state: Mutex::new(SyncState::Idle),
|
state: Mutex::new(SyncStateWrapper::idle()),
|
||||||
|
is_idle: Mutex::new(true),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -666,9 +699,6 @@ pub trait SyncInfo {
|
|||||||
|
|
||||||
/// Whether major sync is underway.
|
/// Whether major sync is underway.
|
||||||
fn is_major_importing(&self) -> bool;
|
fn is_major_importing(&self) -> bool;
|
||||||
|
|
||||||
/// Whether major sync is underway, skipping some synchronization.
|
|
||||||
fn is_major_importing_no_sync(&self) -> bool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L: AsLightClient> SyncInfo for LightSync<L> {
|
impl<L: AsLightClient> SyncInfo for LightSync<L> {
|
||||||
@ -681,11 +711,13 @@ impl<L: AsLightClient> SyncInfo for LightSync<L> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_major_importing(&self) -> bool {
|
fn is_major_importing(&self) -> bool {
|
||||||
self.is_major_importing_do_wait(true)
|
const EMPTY_QUEUE: usize = 3;
|
||||||
}
|
|
||||||
|
|
||||||
fn is_major_importing_no_sync(&self) -> bool {
|
let queue_info = self.client.as_light_client().queue_info();
|
||||||
self.is_major_importing_do_wait(false)
|
let is_verifying = queue_info.unverified_queue_size + queue_info.verified_queue_size > EMPTY_QUEUE;
|
||||||
|
let is_syncing = !*self.is_idle.lock();
|
||||||
|
|
||||||
|
is_verifying || is_syncing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ parking_lot = "0.6"
|
|||||||
parity-crypto = "0.1"
|
parity-crypto = "0.1"
|
||||||
ethereum-types = "0.4"
|
ethereum-types = "0.4"
|
||||||
dir = { path = "../util/dir" }
|
dir = { path = "../util/dir" }
|
||||||
smallvec = "0.4"
|
smallvec = "0.6"
|
||||||
parity-wordlist = "1.0"
|
parity-wordlist = "1.0"
|
||||||
tempdir = "0.3"
|
tempdir = "0.3"
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() {
|
|||||||
// when
|
// when
|
||||||
let tx1 = Tx::gas_price(2).signed();
|
let tx1 = Tx::gas_price(2).signed();
|
||||||
let tx2 = Tx::gas_price(2).signed();
|
let tx2 = Tx::gas_price(2).signed();
|
||||||
|
let sender = tx2.sender();
|
||||||
let tx3 = Tx::gas_price(1).signed();
|
let tx3 = Tx::gas_price(1).signed();
|
||||||
let tx4 = Tx::gas_price(3).signed();
|
let tx4 = Tx::gas_price(3).signed();
|
||||||
let res = txq.import(TestClient::new(), vec![tx1, tx2].retracted());
|
let res = txq.import(TestClient::new(), vec![tx1, tx2].retracted());
|
||||||
@ -90,7 +91,8 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() {
|
|||||||
Ok(())
|
Ok(())
|
||||||
]);
|
]);
|
||||||
assert_eq!(txq.status().status.transaction_count, 3);
|
assert_eq!(txq.status().status.transaction_count, 3);
|
||||||
// First inserted transacton got dropped because of limit
|
// tx2 transacton got dropped because of limit
|
||||||
|
// tx1 and tx1' are kept, because they have lower insertion_ids so they are preferred.
|
||||||
assert_eq!(txq.next_nonce(TestClient::new(), &sender), None);
|
assert_eq!(txq.next_nonce(TestClient::new(), &sender), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ impl InformantData for LightNodeInformantData {
|
|||||||
fn executes_transactions(&self) -> bool { false }
|
fn executes_transactions(&self) -> bool { false }
|
||||||
|
|
||||||
fn is_major_importing(&self) -> bool {
|
fn is_major_importing(&self) -> bool {
|
||||||
self.sync.is_major_importing_no_sync()
|
self.sync.is_major_importing()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report(&self) -> Report {
|
fn report(&self) -> Report {
|
||||||
|
@ -396,11 +396,6 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
|||||||
// create dirs used by parity
|
// create dirs used by parity
|
||||||
cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
|
cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
|
||||||
|
|
||||||
// run in daemon mode
|
|
||||||
if let Some(pid_file) = cmd.daemon {
|
|
||||||
daemonize(pid_file)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
//print out running parity environment
|
//print out running parity environment
|
||||||
print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
|
print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
|
||||||
|
|
||||||
@ -800,6 +795,12 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
|||||||
client.set_exit_handler(on_client_rq);
|
client.set_exit_handler(on_client_rq);
|
||||||
updater.set_exit_handler(on_updater_rq);
|
updater.set_exit_handler(on_updater_rq);
|
||||||
|
|
||||||
|
// run in daemon mode
|
||||||
|
if let Some(pid_file) = cmd.daemon {
|
||||||
|
info!("Running as a daemon process!");
|
||||||
|
daemonize(pid_file)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(RunningClient {
|
Ok(RunningClient {
|
||||||
inner: RunningClientInner::Full {
|
inner: RunningClientInner::Full {
|
||||||
rpc: rpc_direct,
|
rpc: rpc_direct,
|
||||||
|
@ -5,7 +5,7 @@ ARG TARGET
|
|||||||
ENV TARGET ${TARGET}
|
ENV TARGET ${TARGET}
|
||||||
|
|
||||||
# install tools and dependencies
|
# install tools and dependencies
|
||||||
RUN apt update && apt install -y --no-install-recommends openssl libudev-dev file
|
RUN apt update && apt install -y --no-install-recommends openssl libudev-dev file curl jq
|
||||||
|
|
||||||
# show backtraces
|
# show backtraces
|
||||||
ENV RUST_BACKTRACE 1
|
ENV RUST_BACKTRACE 1
|
||||||
@ -18,19 +18,19 @@ RUN rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*
|
|||||||
RUN groupadd -g 1000 parity \
|
RUN groupadd -g 1000 parity \
|
||||||
&& useradd -m -u 1000 -g parity -s /bin/sh parity
|
&& useradd -m -u 1000 -g parity -s /bin/sh parity
|
||||||
|
|
||||||
USER parity
|
|
||||||
|
|
||||||
WORKDIR /home/parity
|
|
||||||
|
|
||||||
ENV PATH "~/bin:${PATH}"
|
|
||||||
|
|
||||||
#add TARGET to docker image
|
#add TARGET to docker image
|
||||||
COPY artifacts/x86_64-unknown-linux-gnu/$TARGET ./bin/$TARGET
|
COPY artifacts/x86_64-unknown-linux-gnu/$TARGET /bin/$TARGET
|
||||||
|
|
||||||
# Build a shell script because the ENTRYPOINT command doesn't like using ENV
|
# Build a shell script because the ENTRYPOINT command doesn't like using ENV
|
||||||
RUN echo "#!/bin/bash \n ${TARGET} \$@" > ./entrypoint.sh
|
RUN echo "#!/bin/bash \n ${TARGET} \$@" > ./entrypoint.sh
|
||||||
RUN chmod +x ./entrypoint.sh
|
RUN chmod +x ./entrypoint.sh
|
||||||
|
|
||||||
|
COPY scripts/docker/hub/check_sync.sh /check_sync.sh
|
||||||
|
|
||||||
|
# switch to user parity here
|
||||||
|
USER parity
|
||||||
|
|
||||||
# setup ENTRYPOINT
|
# setup ENTRYPOINT
|
||||||
EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp
|
EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp
|
||||||
ENTRYPOINT ["./entrypoint.sh"]
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
|
13
scripts/docker/hub/check_sync.sh
Executable file
13
scripts/docker/hub/check_sync.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# checks if parity has a fully synced blockchain
|
||||||
|
|
||||||
|
ETH_SYNCING=$(curl -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:8545 -H 'Content-Type: application/json')
|
||||||
|
RESULT=$(echo "$ETH_SYNCING" | jq -r .result)
|
||||||
|
|
||||||
|
if [ "$RESULT" == "false" ]; then
|
||||||
|
echo "Parity is ready to start accepting traffic"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Parity is still syncing the blockchain"
|
||||||
|
exit 1
|
||||||
|
fi
|
@ -3,7 +3,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "parity-version"
|
name = "parity-version"
|
||||||
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
|
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
|
||||||
version = "2.1.6"
|
version = "2.1.7"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ serde = "1.0"
|
|||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
slab = "0.3"
|
slab = "0.3"
|
||||||
smallvec = "0.4"
|
smallvec = "0.6"
|
||||||
tiny-keccak = "1.4"
|
tiny-keccak = "1.4"
|
||||||
|
|
||||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" }
|
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" }
|
||||||
|
Loading…
Reference in New Issue
Block a user