Backports for Beta 2.3.3 (#10333)
* version: bump beta to 2.3.3 * import rpc transactions sequentially (#10051) * import rpc transactions sequentially * use impl trait in argument position, renamed ProspectiveDispatcher to WithPostSign * grouped imports * integrates PostSign with ProspectiveSigner * fix spaces, removed unnecessary type cast and duplicate polling * clean up code style * Apply suggestions from code review * Fix Windows build (#10284) * Don't run the CPP example on CI (#10285) * Don't run the CPP example on CI * Add comment * CI optimizations (#10297) * CI optimizations * fix stripping * new dockerfile * no need n submodule upd * review * moved dockerfile * it becomes large * onchain update depends on s3 * fix dependency * fix cache status * fix cache status * new cache status * fix publish job (#10317) * fix publish job * dashes and colonels * Add Statetest support for Constantinople Fix (#10323) * Update Ethereum tests repo to v6.0.0-beta.3 tag * Add spec for St.Peter's / ConstantinopleFix statetests * Properly handle check_epoch_end_signal errors (#10015) * Make check_epoch_end_signal to only use immutable data * Move check_epoch_end_signals out of commit_block * Make check_epoch_end_signals possible to fail * Actually return the error from check_epoch_end_signals * Remove a clone * Fix import error * cargo: fix compilation * fix(add helper for timestamp overflows) (#10330) * fix(add helper timestamp overflows) * fix(simplify code) * fix(make helper private) * Remove CallContract and RegistryInfo re-exports from `ethcore/client` (#10205) * Remove re-export of `CallContract` and `RegistryInfo` from `ethcore/client` * Remove CallContract and RegistryInfo re-exports again This was missed while fixing merge conflicts * fix(docker): fix not receives SIGINT (#10059) * fix(docker): fix not receives SIGINT * fix: update with reviews * update with review * update * update * snap: official image / test (#10168) * official image / test * fix / test * bit more necromancy * fix paths * add source bin/df /test * add source bin/df /test2 * something w paths /test * something w paths /test * add source-type /test * show paths /test * copy plugin /test * plugin -> nil * install rhash * no questions while installing rhash * publish snap only for release * Don't add discovery initiators to the node table (#10305) * Don't add discovery initiators to the node table * Use enums for tracking state of the nodes in discovery * Dont try to ping ourselves * Fix minor nits * Update timeouts when observing an outdated node * Extracted update_bucket_record from update_node * Fixed typo * Fix two final nits from @todr * Extract CallContract and RegistryInfo traits into their own crate (#10178) * Create call-contract crate * Add license * First attempt at using extracted CallContract trait * Remove unneeded `extern crate` calls * Move RegistryInfo trait into call-contract crate * Move service-transaction-checker from ethcore to ethcore-miner * Update Cargo.lock file * Re-export call_contract * Merge CallContract and RegistryInfo imports * Remove commented code * Add documentation to call_contract crate * Add TODO for removal of re-exports * Update call-contract crate description Co-Authored-By: HCastano <HCastano@users.noreply.github.com> * Rename call-contract crate to ethcore-call-contract * Remove CallContract and RegistryInfo re-exports from `ethcore/client` (#10205) * Remove re-export of `CallContract` and `RegistryInfo` from `ethcore/client` * Remove CallContract and RegistryInfo re-exports again This was missed while fixing merge conflicts * fixed: types::transaction::SignedTransaction; (#10229) * fix daemonize dependency * fix build * change docker image based on debian instead of ubuntu due to the chan… (#10336) * change docker image based on debian instead of ubuntu due to the changes of the build container * role back docker build image and docker deploy image to ubuntu:xenial based (#10338) * perform stripping during build (#10208) * perform stripping during build (#10208) * perform stripping during build * var RUSTFLAGS
This commit is contained in:
parent
a6c4b17303
commit
3b9b1a8f14
@ -2,11 +2,14 @@ stages:
|
|||||||
- test
|
- test
|
||||||
- build
|
- build
|
||||||
- publish
|
- publish
|
||||||
|
- publish-onchain
|
||||||
- optional
|
- optional
|
||||||
|
|
||||||
image: parity/rust:gitlab-ci
|
image: parity/rust:gitlab-ci
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
|
GIT_STRATEGY: fetch
|
||||||
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
CI_SERVER_NAME: "GitLab CI"
|
CI_SERVER_NAME: "GitLab CI"
|
||||||
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
|
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
|
||||||
CARGO_TARGET: x86_64-unknown-linux-gnu
|
CARGO_TARGET: x86_64-unknown-linux-gnu
|
||||||
@ -40,25 +43,29 @@ test-linux:
|
|||||||
variables:
|
variables:
|
||||||
RUN_TESTS: all
|
RUN_TESTS: all
|
||||||
script:
|
script:
|
||||||
- scripts/gitlab/test-all.sh stable
|
- scripts/gitlab/test-all.sh
|
||||||
|
- sccache -s
|
||||||
tags:
|
tags:
|
||||||
- rust-stable
|
- linux-docker
|
||||||
|
|
||||||
test-audit:
|
test-audit:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- scripts/gitlab/cargo-audit.sh
|
- set -e
|
||||||
|
- set -u
|
||||||
|
- cargo audit
|
||||||
tags:
|
tags:
|
||||||
- rust-stable
|
- linux-docker
|
||||||
|
|
||||||
build-linux:
|
build-linux:
|
||||||
stage: build
|
stage: build
|
||||||
only: *releaseable_branches
|
only: *releaseable_branches
|
||||||
script:
|
script:
|
||||||
- scripts/gitlab/build-unix.sh
|
- scripts/gitlab/build-unix.sh
|
||||||
|
- sccache -s
|
||||||
<<: *collect_artifacts
|
<<: *collect_artifacts
|
||||||
tags:
|
tags:
|
||||||
- rust-stable
|
- linux-docker
|
||||||
|
|
||||||
build-darwin:
|
build-darwin:
|
||||||
stage: build
|
stage: build
|
||||||
@ -96,9 +103,9 @@ publish-docker:
|
|||||||
- scripts/gitlab/publish-docker.sh parity
|
- scripts/gitlab/publish-docker.sh parity
|
||||||
|
|
||||||
publish-snap:
|
publish-snap:
|
||||||
stage: publish
|
stage: optional #publish
|
||||||
only: *releaseable_branches
|
only: *releaseable_branches
|
||||||
image: parity/snapcraft:gitlab-ci
|
image: snapcore/snapcraft
|
||||||
variables:
|
variables:
|
||||||
BUILD_ARCH: amd64
|
BUILD_ARCH: amd64
|
||||||
cache: {}
|
cache: {}
|
||||||
@ -112,7 +119,40 @@ publish-snap:
|
|||||||
allow_failure: true
|
allow_failure: true
|
||||||
<<: *collect_artifacts
|
<<: *collect_artifacts
|
||||||
|
|
||||||
publish-awss3:
|
publish-onnet-update:
|
||||||
|
stage: publish-onchain
|
||||||
|
only: *releaseable_branches
|
||||||
|
cache: {}
|
||||||
|
dependencies:
|
||||||
|
- build-linux
|
||||||
|
- build-darwin
|
||||||
|
- build-windows
|
||||||
|
- publish-awss3-release
|
||||||
|
before_script: *determine_version
|
||||||
|
script:
|
||||||
|
- scripts/gitlab/publish-onnet-update.sh
|
||||||
|
tags:
|
||||||
|
- linux-docker
|
||||||
|
|
||||||
|
# configures aws for fast uploads/syncs
|
||||||
|
.s3-before-script: &s3-before-script
|
||||||
|
before_script:
|
||||||
|
- mkdir -p ${HOME}/.aws
|
||||||
|
- |
|
||||||
|
cat > ${HOME}/.aws/config <<EOC
|
||||||
|
[default]
|
||||||
|
s3 =
|
||||||
|
max_concurrent_requests = 20
|
||||||
|
max_queue_size = 10000
|
||||||
|
multipart_threshold = 64MB
|
||||||
|
multipart_chunksize = 16MB
|
||||||
|
max_bandwidth = 50MB/s
|
||||||
|
use_accelerate_endpoint = false
|
||||||
|
addressing_style = path
|
||||||
|
EOC
|
||||||
|
|
||||||
|
publish-awss3-release:
|
||||||
|
image: parity/awscli:latest
|
||||||
stage: publish
|
stage: publish
|
||||||
only: *releaseable_branches
|
only: *releaseable_branches
|
||||||
cache: {}
|
cache: {}
|
||||||
@ -120,11 +160,25 @@ publish-awss3:
|
|||||||
- build-linux
|
- build-linux
|
||||||
- build-darwin
|
- build-darwin
|
||||||
- build-windows
|
- build-windows
|
||||||
before_script: *determine_version
|
variables:
|
||||||
|
GIT_STRATEGY: none
|
||||||
|
<<: *s3-before-script
|
||||||
script:
|
script:
|
||||||
- scripts/gitlab/publish-awss3.sh
|
- echo "__________Push binaries to AWS S3____________"
|
||||||
|
- case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in
|
||||||
|
(beta|stable|nightly)
|
||||||
|
export BUCKET=releases.parity.io/ethereum;
|
||||||
|
;;
|
||||||
|
(*)
|
||||||
|
export BUCKET=builds-parity;
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
- aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/
|
||||||
|
after_script:
|
||||||
|
- aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/
|
||||||
|
--recursive --human-readable --summarize
|
||||||
tags:
|
tags:
|
||||||
- shell
|
- linux-docker
|
||||||
|
|
||||||
publish-docs:
|
publish-docs:
|
||||||
stage: publish
|
stage: publish
|
||||||
@ -150,22 +204,3 @@ build-android:
|
|||||||
allow_failure: true
|
allow_failure: true
|
||||||
<<: *collect_artifacts
|
<<: *collect_artifacts
|
||||||
|
|
||||||
test-beta:
|
|
||||||
stage: optional
|
|
||||||
variables:
|
|
||||||
RUN_TESTS: cargo
|
|
||||||
script:
|
|
||||||
- scripts/gitlab/test-all.sh beta
|
|
||||||
tags:
|
|
||||||
- rust-beta
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
test-nightly:
|
|
||||||
stage: optional
|
|
||||||
variables:
|
|
||||||
RUN_TESTS: all
|
|
||||||
script:
|
|
||||||
- scripts/gitlab/test-all.sh nightly
|
|
||||||
tags:
|
|
||||||
- rust-nightly
|
|
||||||
allow_failure: true
|
|
||||||
|
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -695,6 +695,7 @@ dependencies = [
|
|||||||
"ethash 1.12.0",
|
"ethash 1.12.0",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
"ethcore-bloom-journal 0.1.0",
|
"ethcore-bloom-journal 0.1.0",
|
||||||
|
"ethcore-call-contract 0.1.0",
|
||||||
"ethcore-db 0.1.0",
|
"ethcore-db 0.1.0",
|
||||||
"ethcore-io 1.12.0",
|
"ethcore-io 1.12.0",
|
||||||
"ethcore-miner 1.12.0",
|
"ethcore-miner 1.12.0",
|
||||||
@ -784,6 +785,15 @@ dependencies = [
|
|||||||
"siphasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"siphasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethcore-call-contract"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"common-types 0.1.0",
|
||||||
|
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-db"
|
name = "ethcore-db"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -879,7 +889,11 @@ dependencies = [
|
|||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
|
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.12.0",
|
"ethash 1.12.0",
|
||||||
|
"ethcore-call-contract 0.1.0",
|
||||||
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethkey 0.3.0",
|
"ethkey 0.3.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
@ -933,6 +947,7 @@ dependencies = [
|
|||||||
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"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)",
|
||||||
|
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -962,6 +977,7 @@ dependencies = [
|
|||||||
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
|
"ethcore-call-contract 0.1.0",
|
||||||
"ethcore-io 1.12.0",
|
"ethcore-io 1.12.0",
|
||||||
"ethcore-miner 1.12.0",
|
"ethcore-miner 1.12.0",
|
||||||
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1000,6 +1016,7 @@ dependencies = [
|
|||||||
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
|
"ethcore-call-contract 0.1.0",
|
||||||
"ethcore-sync 1.12.0",
|
"ethcore-sync 1.12.0",
|
||||||
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethkey 0.3.0",
|
"ethkey 0.3.0",
|
||||||
@ -2271,7 +2288,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2376,7 +2393,7 @@ dependencies = [
|
|||||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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.3.2",
|
"parity-ethereum 2.3.3",
|
||||||
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2394,7 +2411,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ethereum"
|
name = "parity-ethereum"
|
||||||
version = "2.3.2"
|
version = "2.3.3"
|
||||||
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)",
|
||||||
@ -2408,6 +2425,7 @@ dependencies = [
|
|||||||
"docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
|
"ethcore-call-contract 0.1.0",
|
||||||
"ethcore-db 0.1.0",
|
"ethcore-db 0.1.0",
|
||||||
"ethcore-io 1.12.0",
|
"ethcore-io 1.12.0",
|
||||||
"ethcore-light 1.12.0",
|
"ethcore-light 1.12.0",
|
||||||
@ -2444,7 +2462,7 @@ dependencies = [
|
|||||||
"parity-rpc 1.12.0",
|
"parity-rpc 1.12.0",
|
||||||
"parity-runtime 0.1.0",
|
"parity-runtime 0.1.0",
|
||||||
"parity-updater 1.12.0",
|
"parity-updater 1.12.0",
|
||||||
"parity-version 2.3.2",
|
"parity-version 2.3.3",
|
||||||
"parity-whisper 0.1.0",
|
"parity-whisper 0.1.0",
|
||||||
"parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.7.0 (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)",
|
||||||
@ -2596,7 +2614,7 @@ dependencies = [
|
|||||||
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-runtime 0.1.0",
|
"parity-runtime 0.1.0",
|
||||||
"parity-updater 1.12.0",
|
"parity-updater 1.12.0",
|
||||||
"parity-version 2.3.2",
|
"parity-version 2.3.3",
|
||||||
"parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2694,7 +2712,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.3.2",
|
"parity-version 2.3.3",
|
||||||
"parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.7.0 (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)",
|
||||||
@ -2704,7 +2722,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-version"
|
name = "parity-version"
|
||||||
version = "2.3.2"
|
version = "2.3.3"
|
||||||
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.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
13
Cargo.toml
13
Cargo.toml
@ -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.3.2"
|
version = "2.3.3"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
@ -34,6 +34,7 @@ ethcore = { path = "ethcore", features = ["parity"] }
|
|||||||
parity-bytes = "0.1"
|
parity-bytes = "0.1"
|
||||||
common-types = { path = "ethcore/types" }
|
common-types = { path = "ethcore/types" }
|
||||||
ethcore-blockchain = { path = "ethcore/blockchain" }
|
ethcore-blockchain = { path = "ethcore/blockchain" }
|
||||||
|
ethcore-call-contract = { path = "ethcore/call-contract"}
|
||||||
ethcore-db = { path = "ethcore/db" }
|
ethcore-db = { path = "ethcore/db" }
|
||||||
ethcore-io = { path = "util/io" }
|
ethcore-io = { path = "util/io" }
|
||||||
ethcore-light = { path = "ethcore/light" }
|
ethcore-light = { path = "ethcore/light" }
|
||||||
@ -79,12 +80,12 @@ ipnetwork = "0.12.6"
|
|||||||
tempdir = "0.3"
|
tempdir = "0.3"
|
||||||
fake-fetch = { path = "util/fake-fetch" }
|
fake-fetch = { path = "util/fake-fetch" }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
|
||||||
winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] }
|
|
||||||
|
|
||||||
[target.'cfg(not(windows))'.dependencies]
|
[target.'cfg(not(windows))'.dependencies]
|
||||||
daemonize = "0.3"
|
daemonize = "0.3"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
miner-debug = ["ethcore/miner-debug"]
|
miner-debug = ["ethcore/miner-debug"]
|
||||||
json-tests = ["ethcore/json-tests"]
|
json-tests = ["ethcore/json-tests"]
|
||||||
@ -132,6 +133,10 @@ members = [
|
|||||||
"evmbin",
|
"evmbin",
|
||||||
"parity-clib",
|
"parity-clib",
|
||||||
"whisper/cli",
|
"whisper/cli",
|
||||||
|
"util/triehash-ethereum",
|
||||||
|
"util/keccak-hasher",
|
||||||
|
"util/patricia-trie-ethereum",
|
||||||
|
"util/fastmap"
|
||||||
]
|
]
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
|
@ -21,6 +21,7 @@ ethabi-derive = "6.0"
|
|||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
ethcore-blockchain = { path = "./blockchain" }
|
ethcore-blockchain = { path = "./blockchain" }
|
||||||
ethcore-bloom-journal = { path = "../util/bloom" }
|
ethcore-bloom-journal = { path = "../util/bloom" }
|
||||||
|
ethcore-call-contract = { path = "./call-contract" }
|
||||||
ethcore-db = { path = "./db" }
|
ethcore-db = { path = "./db" }
|
||||||
ethcore-io = { path = "../util/io" }
|
ethcore-io = { path = "../util/io" }
|
||||||
ethcore-miner = { path = "../miner" }
|
ethcore-miner = { path = "../miner" }
|
||||||
|
11
ethcore/call-contract/Cargo.toml
Normal file
11
ethcore/call-contract/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "ethcore-call-contract"
|
||||||
|
version = "0.1.0"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
types = { path = "../types", package = "common-types" }
|
||||||
|
ethereum-types = "0.4"
|
||||||
|
bytes = { version = "0.1", package = "parity-bytes" }
|
33
ethcore/call-contract/src/call_contract.rs
Normal file
33
ethcore/call-contract/src/call_contract.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity Ethereum.
|
||||||
|
|
||||||
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Provides CallContract and RegistryInfo traits
|
||||||
|
|
||||||
|
use bytes::Bytes;
|
||||||
|
use ethereum_types::Address;
|
||||||
|
use types::ids::BlockId;
|
||||||
|
|
||||||
|
/// Provides `call_contract` method
|
||||||
|
pub trait CallContract {
|
||||||
|
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
|
||||||
|
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides information on a blockchain service and it's registry
|
||||||
|
pub trait RegistryInfo {
|
||||||
|
/// Get the address of a particular blockchain service, if available.
|
||||||
|
fn registry_address(&self, name: String, block: BlockId) -> Option<Address>;
|
||||||
|
}
|
27
ethcore/call-contract/src/lib.rs
Normal file
27
ethcore/call-contract/src/lib.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity Ethereum.
|
||||||
|
|
||||||
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
//! Call Contract module
|
||||||
|
//!
|
||||||
|
//! This crate exposes traits required to call contracts at particular block.
|
||||||
|
//! All utilities that depend on on-chain data should use those traits to access it.
|
||||||
|
|
||||||
|
pub mod call_contract;
|
||||||
|
|
||||||
|
// Re-export
|
||||||
|
pub use self::call_contract::*;
|
@ -12,6 +12,7 @@ ethabi = "6.0"
|
|||||||
ethabi-contract = "6.0"
|
ethabi-contract = "6.0"
|
||||||
ethabi-derive = "6.0"
|
ethabi-derive = "6.0"
|
||||||
ethcore = { path = ".." }
|
ethcore = { path = ".." }
|
||||||
|
ethcore-call-contract = { path = "../call-contract" }
|
||||||
ethcore-io = { path = "../../util/io" }
|
ethcore-io = { path = "../../util/io" }
|
||||||
ethcore-miner = { path = "../../miner" }
|
ethcore-miner = { path = "../../miner" }
|
||||||
ethereum-types = "0.4"
|
ethereum-types = "0.4"
|
||||||
|
@ -28,6 +28,7 @@ mod error;
|
|||||||
extern crate common_types as types;
|
extern crate common_types as types;
|
||||||
extern crate ethabi;
|
extern crate ethabi;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
|
extern crate ethcore_call_contract as call_contract;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
extern crate ethcore_miner;
|
extern crate ethcore_miner;
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
@ -82,11 +83,12 @@ use types::transaction::{SignedTransaction, Transaction, Action, UnverifiedTrans
|
|||||||
use ethcore::{contract_address as ethcore_contract_address};
|
use ethcore::{contract_address as ethcore_contract_address};
|
||||||
use ethcore::client::{
|
use ethcore::client::{
|
||||||
Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId,
|
Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId,
|
||||||
CallContract, Call, BlockInfo
|
Call, BlockInfo
|
||||||
};
|
};
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
|
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
|
||||||
use ethcore::trace::{Tracer, VMTracer};
|
use ethcore::trace::{Tracer, VMTracer};
|
||||||
|
use call_contract::CallContract;
|
||||||
use rustc_hex::FromHex;
|
use rustc_hex::FromHex;
|
||||||
use ethkey::Password;
|
use ethkey::Password;
|
||||||
use ethabi::FunctionOutputDecoder;
|
use ethabi::FunctionOutputDecoder;
|
||||||
|
65
ethcore/res/ethereum/st_peters_test.json
Normal file
65
ethcore/res/ethereum/st_peters_test.json
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"name": "St. Peter's (test)",
|
||||||
|
"engine": {
|
||||||
|
"Ethash": {
|
||||||
|
"params": {
|
||||||
|
"minimumDifficulty": "0x020000",
|
||||||
|
"difficultyBoundDivisor": "0x0800",
|
||||||
|
"durationLimit": "0x0d",
|
||||||
|
"blockReward": "0x1BC16D674EC80000",
|
||||||
|
"homesteadTransition": "0x0",
|
||||||
|
"eip100bTransition": "0x0",
|
||||||
|
"difficultyBombDelays": {
|
||||||
|
"0": 5000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x0400",
|
||||||
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
|
"accountStartNonce": "0x00",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"networkID" : "0x1",
|
||||||
|
"maxCodeSize": 24576,
|
||||||
|
"maxCodeSizeTransition": "0x0",
|
||||||
|
"eip150Transition": "0x0",
|
||||||
|
"eip160Transition": "0x0",
|
||||||
|
"eip161abcTransition": "0x0",
|
||||||
|
"eip161dTransition": "0x0",
|
||||||
|
"eip140Transition": "0x0",
|
||||||
|
"eip211Transition": "0x0",
|
||||||
|
"eip214Transition": "0x0",
|
||||||
|
"eip155Transition": "0x0",
|
||||||
|
"eip658Transition": "0x0",
|
||||||
|
"eip145Transition": "0x0",
|
||||||
|
"eip1014Transition": "0x0",
|
||||||
|
"eip1052Transition": "0x0",
|
||||||
|
"eip1283DisableTransition": "0x0"
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"seal": {
|
||||||
|
"ethereum": {
|
||||||
|
"nonce": "0x0000000000000042",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"difficulty": "0x400000000",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
|
||||||
|
"gasLimit": "0x1388"
|
||||||
|
},
|
||||||
|
"accounts": {
|
||||||
|
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
|
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
|
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
|
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } },
|
||||||
|
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit 420f443477caa8516f1f9ee8122fafc3415c0f34
|
Subproject commit 725dbc73a54649e22a00330bd0f4d6699a5060e5
|
@ -23,6 +23,7 @@ use std::time::{Instant, Duration};
|
|||||||
|
|
||||||
use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
|
use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
use ethcore_miner::pool::VerifiedTransaction;
|
use ethcore_miner::pool::VerifiedTransaction;
|
||||||
use ethereum_types::{H256, Address, U256};
|
use ethereum_types::{H256, Address, U256};
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
@ -46,8 +47,8 @@ use vm::{EnvInfo, LastHashes};
|
|||||||
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
|
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
|
||||||
use client::ancient_import::AncientVerifier;
|
use client::ancient_import::AncientVerifier;
|
||||||
use client::{
|
use client::{
|
||||||
Nonce, Balance, ChainInfo, BlockInfo, CallContract, TransactionInfo,
|
Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo,
|
||||||
RegistryInfo, ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock,
|
ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock,
|
||||||
BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call,
|
BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call,
|
||||||
AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter,
|
AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter,
|
||||||
ClientIoMessage,
|
ClientIoMessage,
|
||||||
@ -59,7 +60,8 @@ use client::{
|
|||||||
IoClient, BadBlocks,
|
IoClient, BadBlocks,
|
||||||
};
|
};
|
||||||
use client::bad_blocks;
|
use client::bad_blocks;
|
||||||
use engines::{EthEngine, EpochTransition, ForkChoice};
|
use engines::{EthEngine, EpochTransition, ForkChoice, EngineError};
|
||||||
|
use engines::epoch::PendingTransition;
|
||||||
use error::{
|
use error::{
|
||||||
ImportErrorKind, ExecutionError, CallError, BlockError,
|
ImportErrorKind, ExecutionError, CallError, BlockError,
|
||||||
QueueError, QueueErrorKind, Error as EthcoreError, EthcoreResult, ErrorKind as EthcoreErrorKind
|
QueueError, QueueErrorKind, Error as EthcoreError, EthcoreResult, ErrorKind as EthcoreErrorKind
|
||||||
@ -291,8 +293,8 @@ impl Importer {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.check_and_lock_block(block, client) {
|
match self.check_and_lock_block(&bytes, block, client) {
|
||||||
Ok(closed_block) => {
|
Ok((closed_block, pending)) => {
|
||||||
if self.engine.is_proposal(&header) {
|
if self.engine.is_proposal(&header) {
|
||||||
self.block_queue.mark_as_good(&[hash]);
|
self.block_queue.mark_as_good(&[hash]);
|
||||||
proposed_blocks.push(bytes);
|
proposed_blocks.push(bytes);
|
||||||
@ -301,7 +303,7 @@ impl Importer {
|
|||||||
|
|
||||||
let transactions_len = closed_block.transactions().len();
|
let transactions_len = closed_block.transactions().len();
|
||||||
|
|
||||||
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), client);
|
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client);
|
||||||
import_results.push(route);
|
import_results.push(route);
|
||||||
|
|
||||||
client.report.write().accrue_block(&header, transactions_len);
|
client.report.write().accrue_block(&header, transactions_len);
|
||||||
@ -353,7 +355,7 @@ impl Importer {
|
|||||||
imported
|
imported
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_and_lock_block(&self, block: PreverifiedBlock, client: &Client) -> EthcoreResult<LockedBlock> {
|
fn check_and_lock_block(&self, bytes: &[u8], block: PreverifiedBlock, client: &Client) -> EthcoreResult<(LockedBlock, Option<PendingTransition>)> {
|
||||||
let engine = &*self.engine;
|
let engine = &*self.engine;
|
||||||
let header = block.header.clone();
|
let header = block.header.clone();
|
||||||
|
|
||||||
@ -437,7 +439,15 @@ impl Importer {
|
|||||||
bail!(e);
|
bail!(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(locked_block)
|
let pending = self.check_epoch_end_signal(
|
||||||
|
&header,
|
||||||
|
bytes,
|
||||||
|
locked_block.receipts(),
|
||||||
|
locked_block.state().db(),
|
||||||
|
client
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok((locked_block, pending))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Import a block with transaction receipts.
|
/// Import a block with transaction receipts.
|
||||||
@ -469,7 +479,8 @@ impl Importer {
|
|||||||
// it is for reconstructing the state transition.
|
// it is for reconstructing the state transition.
|
||||||
//
|
//
|
||||||
// The header passed is from the original block data and is sealed.
|
// The header passed is from the original block data and is sealed.
|
||||||
fn commit_block<B>(&self, block: B, header: &Header, block_data: encoded::Block, client: &Client) -> ImportRoute where B: Drain {
|
// TODO: should return an error if ImportRoute is none, issue #9910
|
||||||
|
fn commit_block<B>(&self, block: B, header: &Header, block_data: encoded::Block, pending: Option<PendingTransition>, client: &Client) -> ImportRoute where B: Drain {
|
||||||
let hash = &header.hash();
|
let hash = &header.hash();
|
||||||
let number = header.number();
|
let number = header.number();
|
||||||
let parent = header.parent_hash();
|
let parent = header.parent_hash();
|
||||||
@ -524,15 +535,9 @@ impl Importer {
|
|||||||
|
|
||||||
// check epoch end signal, potentially generating a proof on the current
|
// check epoch end signal, potentially generating a proof on the current
|
||||||
// state.
|
// state.
|
||||||
self.check_epoch_end_signal(
|
if let Some(pending) = pending {
|
||||||
&header,
|
chain.insert_pending_transition(&mut batch, header.hash(), pending);
|
||||||
block_data.raw(),
|
}
|
||||||
&receipts,
|
|
||||||
&state,
|
|
||||||
&chain,
|
|
||||||
&mut batch,
|
|
||||||
client
|
|
||||||
);
|
|
||||||
|
|
||||||
state.journal_under(&mut batch, number, hash).expect("DB commit failed");
|
state.journal_under(&mut batch, number, hash).expect("DB commit failed");
|
||||||
|
|
||||||
@ -587,10 +592,8 @@ impl Importer {
|
|||||||
block_bytes: &[u8],
|
block_bytes: &[u8],
|
||||||
receipts: &[Receipt],
|
receipts: &[Receipt],
|
||||||
state_db: &StateDB,
|
state_db: &StateDB,
|
||||||
chain: &BlockChain,
|
|
||||||
batch: &mut DBTransaction,
|
|
||||||
client: &Client,
|
client: &Client,
|
||||||
) {
|
) -> EthcoreResult<Option<PendingTransition>> {
|
||||||
use engines::EpochChange;
|
use engines::EpochChange;
|
||||||
|
|
||||||
let hash = header.hash();
|
let hash = header.hash();
|
||||||
@ -601,7 +604,6 @@ impl Importer {
|
|||||||
|
|
||||||
match self.engine.signals_epoch_end(header, auxiliary) {
|
match self.engine.signals_epoch_end(header, auxiliary) {
|
||||||
EpochChange::Yes(proof) => {
|
EpochChange::Yes(proof) => {
|
||||||
use engines::epoch::PendingTransition;
|
|
||||||
use engines::Proof;
|
use engines::Proof;
|
||||||
|
|
||||||
let proof = match proof {
|
let proof = match proof {
|
||||||
@ -638,11 +640,9 @@ impl Importer {
|
|||||||
.transact(&transaction, options);
|
.transact(&transaction, options);
|
||||||
|
|
||||||
let res = match res {
|
let res = match res {
|
||||||
Err(ExecutionError::Internal(e)) =>
|
|
||||||
Err(format!("Internal error: {}", e)),
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
trace!(target: "client", "Proved call failed: {}", e);
|
trace!(target: "client", "Proved call failed: {}", e);
|
||||||
Ok((Vec::new(), state.drop().1.extract_proof()))
|
Err(e.to_string())
|
||||||
}
|
}
|
||||||
Ok(res) => Ok((res.output, state.drop().1.extract_proof())),
|
Ok(res) => Ok((res.output, state.drop().1.extract_proof())),
|
||||||
};
|
};
|
||||||
@ -655,7 +655,7 @@ impl Importer {
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!(target: "client", "Failed to generate transition proof for block {}: {}", hash, e);
|
warn!(target: "client", "Failed to generate transition proof for block {}: {}", hash, e);
|
||||||
warn!(target: "client", "Snapshots produced by this client may be incomplete");
|
warn!(target: "client", "Snapshots produced by this client may be incomplete");
|
||||||
Vec::new()
|
return Err(EngineError::FailedSystemCall(e).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -663,13 +663,13 @@ impl Importer {
|
|||||||
|
|
||||||
debug!(target: "client", "Block {} signals epoch end.", hash);
|
debug!(target: "client", "Block {} signals epoch end.", hash);
|
||||||
|
|
||||||
let pending = PendingTransition { proof: proof };
|
Ok(Some(PendingTransition { proof: proof }))
|
||||||
chain.insert_pending_transition(batch, hash, pending);
|
|
||||||
},
|
},
|
||||||
EpochChange::No => {},
|
EpochChange::No => Ok(None),
|
||||||
EpochChange::Unsure(_) => {
|
EpochChange::Unsure(_) => {
|
||||||
warn!(target: "client", "Detected invalid engine implementation.");
|
warn!(target: "client", "Detected invalid engine implementation.");
|
||||||
warn!(target: "client", "Engine claims to require more block data, but everything provided.");
|
warn!(target: "client", "Engine claims to require more block data, but everything provided.");
|
||||||
|
Err(EngineError::InvalidEngine.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2328,7 +2328,20 @@ impl ImportSealedBlock for Client {
|
|||||||
|
|
||||||
let block_data = block.rlp_bytes();
|
let block_data = block.rlp_bytes();
|
||||||
|
|
||||||
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
|
let pending = self.importer.check_epoch_end_signal(
|
||||||
|
&header,
|
||||||
|
&block_data,
|
||||||
|
block.receipts(),
|
||||||
|
block.state().db(),
|
||||||
|
self
|
||||||
|
)?;
|
||||||
|
let route = self.importer.commit_block(
|
||||||
|
block,
|
||||||
|
&header,
|
||||||
|
encoded::Block::new(block_data),
|
||||||
|
pending,
|
||||||
|
self
|
||||||
|
);
|
||||||
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), hash);
|
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), 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
|
||||||
|
@ -93,6 +93,7 @@ impl<'a> EvmTestClient<'a> {
|
|||||||
ForkSpec::EIP158 => Some(ethereum::new_eip161_test()),
|
ForkSpec::EIP158 => Some(ethereum::new_eip161_test()),
|
||||||
ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()),
|
ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()),
|
||||||
ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()),
|
ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()),
|
||||||
|
ForkSpec::ConstantinopleFix => Some(ethereum::new_constantinople_fix_test()),
|
||||||
ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()),
|
ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()),
|
||||||
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
|
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ pub use self::io_message::ClientIoMessage;
|
|||||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||||
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
|
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
|
||||||
pub use self::traits::{
|
pub use self::traits::{
|
||||||
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
|
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
|
||||||
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks,
|
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks,
|
||||||
};
|
};
|
||||||
pub use state::StateInfo;
|
pub use state::StateInfo;
|
||||||
|
@ -49,8 +49,9 @@ use types::views::BlockView;
|
|||||||
use vm::Schedule;
|
use vm::Schedule;
|
||||||
|
|
||||||
use block::{OpenBlock, SealedBlock, ClosedBlock};
|
use block::{OpenBlock, SealedBlock, ClosedBlock};
|
||||||
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
use client::{
|
use client::{
|
||||||
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, CallContract, TransactionInfo, RegistryInfo,
|
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, TransactionInfo,
|
||||||
PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode,
|
PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode,
|
||||||
TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics,
|
TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics,
|
||||||
ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock,
|
ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock,
|
||||||
|
@ -19,6 +19,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use blockchain::{BlockReceipts, TreeRoute};
|
use blockchain::{BlockReceipts, TreeRoute};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
use ethcore_miner::pool::VerifiedTransaction;
|
use ethcore_miner::pool::VerifiedTransaction;
|
||||||
use ethereum_types::{H256, U256, Address};
|
use ethereum_types::{H256, U256, Address};
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
@ -157,12 +158,6 @@ pub trait StateClient {
|
|||||||
/// Provides various blockchain information, like block header, chain state etc.
|
/// Provides various blockchain information, like block header, chain state etc.
|
||||||
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
|
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
|
||||||
|
|
||||||
/// Provides information on a blockchain service and it's registry
|
|
||||||
pub trait RegistryInfo {
|
|
||||||
/// Get the address of a particular blockchain service, if available.
|
|
||||||
fn registry_address(&self, name: String, block: BlockId) -> Option<Address>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
|
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
|
||||||
/// Provides methods to import block into blockchain
|
/// Provides methods to import block into blockchain
|
||||||
pub trait ImportBlock {
|
pub trait ImportBlock {
|
||||||
@ -170,12 +165,6 @@ pub trait ImportBlock {
|
|||||||
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
|
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides `call_contract` method
|
|
||||||
pub trait CallContract {
|
|
||||||
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
|
|
||||||
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides `call` and `call_many` methods
|
/// Provides `call` and `call_many` methods
|
||||||
pub trait Call {
|
pub trait Call {
|
||||||
/// Type representing chain state
|
/// Type representing chain state
|
||||||
|
@ -81,6 +81,8 @@ pub enum EngineError {
|
|||||||
MalformedMessage(String),
|
MalformedMessage(String),
|
||||||
/// Requires client ref, but none registered.
|
/// Requires client ref, but none registered.
|
||||||
RequiresClient,
|
RequiresClient,
|
||||||
|
/// Invalid engine specification or implementation.
|
||||||
|
InvalidEngine,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for EngineError {
|
impl fmt::Display for EngineError {
|
||||||
@ -96,6 +98,7 @@ impl fmt::Display for EngineError {
|
|||||||
FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg),
|
FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg),
|
||||||
MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg),
|
MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg),
|
||||||
RequiresClient => format!("Call requires client but none registered"),
|
RequiresClient => format!("Call requires client but none registered"),
|
||||||
|
InvalidEngine => format!("Invalid engine specification or implementation"),
|
||||||
};
|
};
|
||||||
|
|
||||||
f.write_fmt(format_args!("Engine error ({})", msg))
|
f.write_fmt(format_args!("Engine error ({})", msg))
|
||||||
|
@ -145,7 +145,8 @@ mod tests {
|
|||||||
use miner::MinerService;
|
use miner::MinerService;
|
||||||
use types::ids::BlockId;
|
use types::ids::BlockId;
|
||||||
use test_helpers::generate_dummy_client_with_spec_and_accounts;
|
use test_helpers::generate_dummy_client_with_spec_and_accounts;
|
||||||
use client::{BlockChainClient, ChainInfo, BlockInfo, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use client::{BlockChainClient, ChainInfo, BlockInfo};
|
||||||
use super::super::ValidatorSet;
|
use super::super::ValidatorSet;
|
||||||
use super::ValidatorContract;
|
use super::ValidatorContract;
|
||||||
|
|
||||||
|
@ -90,6 +90,8 @@ pub enum BlockError {
|
|||||||
InvalidNumber(Mismatch<BlockNumber>),
|
InvalidNumber(Mismatch<BlockNumber>),
|
||||||
/// Block number isn't sensible.
|
/// Block number isn't sensible.
|
||||||
RidiculousNumber(OutOfBounds<BlockNumber>),
|
RidiculousNumber(OutOfBounds<BlockNumber>),
|
||||||
|
/// Timestamp header overflowed
|
||||||
|
TimestampOverflow,
|
||||||
/// Too many transactions from a particular address.
|
/// Too many transactions from a particular address.
|
||||||
TooManyTransactions(Address),
|
TooManyTransactions(Address),
|
||||||
/// Parent given is unknown.
|
/// Parent given is unknown.
|
||||||
@ -139,6 +141,7 @@ impl fmt::Display for BlockError {
|
|||||||
UnknownParent(ref hash) => format!("Unknown parent: {}", hash),
|
UnknownParent(ref hash) => format!("Unknown parent: {}", hash),
|
||||||
UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash),
|
UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash),
|
||||||
UnknownEpochTransition(ref num) => format!("Unknown transition to epoch number: {}", num),
|
UnknownEpochTransition(ref num) => format!("Unknown transition to epoch number: {}", num),
|
||||||
|
TimestampOverflow => format!("Timestamp overflow"),
|
||||||
TooManyTransactions(ref address) => format!("Too many transactions from: {}", address),
|
TooManyTransactions(ref address) => format!("Too many transactions from: {}", address),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,6 +148,9 @@ pub fn new_byzantium_test() -> Spec { load(None, include_bytes!("../../res/ether
|
|||||||
/// Create a new Foundation Constantinople era spec.
|
/// Create a new Foundation Constantinople era spec.
|
||||||
pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/ethereum/constantinople_test.json")) }
|
pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/ethereum/constantinople_test.json")) }
|
||||||
|
|
||||||
|
/// Create a new Foundation St. Peter's (Contantinople Fix) era spec.
|
||||||
|
pub fn new_constantinople_fix_test() -> Spec { load(None, include_bytes!("../../res/ethereum/st_peters_test.json")) }
|
||||||
|
|
||||||
/// Create a new Musicoin-MCIP3-era spec.
|
/// Create a new Musicoin-MCIP3-era spec.
|
||||||
pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../../res/ethereum/mcip3_test.json")) }
|
pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../../res/ethereum/mcip3_test.json")) }
|
||||||
|
|
||||||
@ -168,6 +171,9 @@ pub fn new_byzantium_test_machine() -> EthereumMachine { load_machine(include_by
|
|||||||
/// Create a new Foundation Constantinople era spec.
|
/// Create a new Foundation Constantinople era spec.
|
||||||
pub fn new_constantinople_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/constantinople_test.json")) }
|
pub fn new_constantinople_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/constantinople_test.json")) }
|
||||||
|
|
||||||
|
/// Create a new Foundation St. Peter's (Contantinople Fix) era spec.
|
||||||
|
pub fn new_constantinople_fix_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/st_peters_test.json")) }
|
||||||
|
|
||||||
/// Create a new Musicoin-MCIP3-era spec.
|
/// Create a new Musicoin-MCIP3-era spec.
|
||||||
pub fn new_mcip3_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) }
|
pub fn new_mcip3_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) }
|
||||||
|
|
||||||
|
@ -165,6 +165,7 @@ mod state_tests {
|
|||||||
declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"}
|
declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"}
|
||||||
declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"}
|
declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"}
|
||||||
declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"}
|
declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"}
|
||||||
|
declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"}
|
||||||
declare_test!{GeneralStateTest_stShift, "GeneralStateTests/stShift/"}
|
declare_test!{GeneralStateTest_stShift, "GeneralStateTests/stShift/"}
|
||||||
declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"}
|
declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"}
|
||||||
declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"}
|
declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"}
|
||||||
@ -177,7 +178,6 @@ mod state_tests {
|
|||||||
declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"}
|
declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"}
|
||||||
declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"}
|
declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"}
|
||||||
declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"}
|
declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"}
|
||||||
declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"}
|
|
||||||
|
|
||||||
// Attempts to send a transaction that requires more than current balance:
|
// Attempts to send a transaction that requires more than current balance:
|
||||||
// Tx:
|
// Tx:
|
||||||
|
@ -66,6 +66,7 @@ extern crate ethabi;
|
|||||||
extern crate ethash;
|
extern crate ethash;
|
||||||
extern crate ethcore_blockchain as blockchain;
|
extern crate ethcore_blockchain as blockchain;
|
||||||
extern crate ethcore_bloom_journal as bloom_journal;
|
extern crate ethcore_bloom_journal as bloom_journal;
|
||||||
|
extern crate ethcore_call_contract as call_contract;
|
||||||
extern crate ethcore_db as db;
|
extern crate ethcore_db as db;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
extern crate ethcore_miner;
|
extern crate ethcore_miner;
|
||||||
|
@ -30,7 +30,8 @@ use vm::{EnvInfo, Schedule, CreateContractAddress};
|
|||||||
|
|
||||||
use block::{ExecutedBlock, IsBlock};
|
use block::{ExecutedBlock, IsBlock};
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use client::{BlockInfo, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use client::BlockInfo;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use executive::Executive;
|
use executive::Executive;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
|
@ -21,6 +21,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use ansi_term::Colour;
|
use ansi_term::Colour;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use call_contract::CallContract;
|
||||||
use ethcore_miner::gas_pricer::GasPricer;
|
use ethcore_miner::gas_pricer::GasPricer;
|
||||||
use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy};
|
use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy};
|
||||||
#[cfg(feature = "work-notify")]
|
#[cfg(feature = "work-notify")]
|
||||||
@ -48,7 +49,7 @@ use using_queue::{UsingQueue, GetAction};
|
|||||||
use account_provider::{AccountProvider, SignError as AccountError};
|
use account_provider::{AccountProvider, SignError as AccountError};
|
||||||
use block::{ClosedBlock, IsBlock, SealedBlock};
|
use block::{ClosedBlock, IsBlock, SealedBlock};
|
||||||
use client::{
|
use client::{
|
||||||
BlockChain, ChainInfo, CallContract, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
|
BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
|
||||||
};
|
};
|
||||||
use client::{BlockId, ClientIoMessage};
|
use client::{BlockId, ClientIoMessage};
|
||||||
use engines::{EthEngine, Seal};
|
use engines::{EthEngine, Seal};
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
//! Keeps track of transactions and currently sealed pending block.
|
//! Keeps track of transactions and currently sealed pending block.
|
||||||
|
|
||||||
mod miner;
|
mod miner;
|
||||||
mod service_transaction_checker;
|
|
||||||
|
|
||||||
pub mod pool_client;
|
pub mod pool_client;
|
||||||
#[cfg(feature = "stratum")]
|
#[cfg(feature = "stratum")]
|
||||||
@ -43,8 +42,9 @@ use types::header::Header;
|
|||||||
use types::receipt::RichReceipt;
|
use types::receipt::RichReceipt;
|
||||||
|
|
||||||
use block::SealedBlock;
|
use block::SealedBlock;
|
||||||
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
use client::{
|
use client::{
|
||||||
CallContract, RegistryInfo, ScheduleInfo,
|
ScheduleInfo,
|
||||||
BlockChain, BlockProducer, SealedBlockImporter, ChainInfo,
|
BlockChain, BlockProducer, SealedBlockImporter, ChainInfo,
|
||||||
AccountData, Nonce,
|
AccountData, Nonce,
|
||||||
};
|
};
|
||||||
|
@ -25,6 +25,7 @@ use std::{
|
|||||||
use ethereum_types::{H256, U256, Address};
|
use ethereum_types::{H256, U256, Address};
|
||||||
use ethcore_miner::pool;
|
use ethcore_miner::pool;
|
||||||
use ethcore_miner::pool::client::NonceClient;
|
use ethcore_miner::pool::client::NonceClient;
|
||||||
|
use ethcore_miner::service_transaction_checker::ServiceTransactionChecker;
|
||||||
use types::transaction::{
|
use types::transaction::{
|
||||||
self,
|
self,
|
||||||
UnverifiedTransaction,
|
UnverifiedTransaction,
|
||||||
@ -34,10 +35,10 @@ use types::header::Header;
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use client::{TransactionId, BlockInfo, CallContract, Nonce};
|
use call_contract::CallContract;
|
||||||
|
use client::{TransactionId, BlockInfo, Nonce};
|
||||||
use engines::EthEngine;
|
use engines::EthEngine;
|
||||||
use miner;
|
use miner;
|
||||||
use miner::service_transaction_checker::ServiceTransactionChecker;
|
|
||||||
use transaction_ext::Transaction;
|
use transaction_ext::Transaction;
|
||||||
|
|
||||||
/// Cache for state nonces.
|
/// Cache for state nonces.
|
||||||
|
@ -1289,6 +1289,13 @@ impl<B: Backend> fmt::Debug for State<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl State<StateDB> {
|
||||||
|
/// Get a reference to the underlying state DB.
|
||||||
|
pub fn db(&self) -> &StateDB {
|
||||||
|
&self.db
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: cloning for `State` shouldn't be possible in general; Remove this and use
|
// TODO: cloning for `State` shouldn't be possible in general; Remove this and use
|
||||||
// checkpoints where possible.
|
// checkpoints where possible.
|
||||||
impl Clone for State<StateDB> {
|
impl Clone for State<StateDB> {
|
||||||
|
@ -20,7 +20,8 @@ use ethereum_types::{H256, U256, Address};
|
|||||||
use lru_cache::LruCache;
|
use lru_cache::LruCache;
|
||||||
use ethabi::FunctionOutputDecoder;
|
use ethabi::FunctionOutputDecoder;
|
||||||
|
|
||||||
use client::{BlockInfo, CallContract, BlockId};
|
use call_contract::CallContract;
|
||||||
|
use client::{BlockInfo, BlockId};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
use types::transaction::{Action, SignedTransaction};
|
use types::transaction::{Action, SignedTransaction};
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
//! Canonical verifier.
|
//! Canonical verifier.
|
||||||
|
|
||||||
use client::{BlockInfo, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use client::BlockInfo;
|
||||||
use engines::EthEngine;
|
use engines::EthEngine;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use types::header::Header;
|
use types::header::Header;
|
||||||
|
@ -28,7 +28,8 @@ pub use self::canon_verifier::CanonVerifier;
|
|||||||
pub use self::noop_verifier::NoopVerifier;
|
pub use self::noop_verifier::NoopVerifier;
|
||||||
pub use self::queue::{BlockQueue, Config as QueueConfig, VerificationQueue, QueueInfo};
|
pub use self::queue::{BlockQueue, Config as QueueConfig, VerificationQueue, QueueInfo};
|
||||||
|
|
||||||
use client::{BlockInfo, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use client::BlockInfo;
|
||||||
|
|
||||||
/// Verifier type.
|
/// Verifier type.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
//! No-op verifier.
|
//! No-op verifier.
|
||||||
|
|
||||||
use client::{BlockInfo, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use client::BlockInfo;
|
||||||
use engines::EthEngine;
|
use engines::EthEngine;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use types::header::Header;
|
use types::header::Header;
|
||||||
|
@ -32,13 +32,33 @@ use triehash::ordered_trie_root;
|
|||||||
use unexpected::{Mismatch, OutOfBounds};
|
use unexpected::{Mismatch, OutOfBounds};
|
||||||
|
|
||||||
use blockchain::*;
|
use blockchain::*;
|
||||||
use client::{BlockInfo, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use client::BlockInfo;
|
||||||
use engines::EthEngine;
|
use engines::EthEngine;
|
||||||
use error::{BlockError, Error};
|
use error::{BlockError, Error};
|
||||||
use types::{BlockNumber, header::Header};
|
use types::{BlockNumber, header::Header};
|
||||||
use types::transaction::SignedTransaction;
|
use types::transaction::SignedTransaction;
|
||||||
use verification::queue::kind::blocks::Unverified;
|
use verification::queue::kind::blocks::Unverified;
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns `Ok<SystemTime>` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because
|
||||||
|
/// it is platform specific, may be i32 or i64.
|
||||||
|
///
|
||||||
|
/// `Err<BlockError::TimestampOver` otherwise.
|
||||||
|
///
|
||||||
|
// FIXME: @niklasad1 - remove this when and use `SystemTime::checked_add`
|
||||||
|
// when https://github.com/rust-lang/rust/issues/55940 is stabilized.
|
||||||
|
fn timestamp_checked_add(sys: SystemTime, d2: Duration) -> Result<SystemTime, BlockError> {
|
||||||
|
let d1 = sys.duration_since(UNIX_EPOCH).map_err(|_| BlockError::TimestampOverflow)?;
|
||||||
|
let total_time = d1.checked_add(d2).ok_or(BlockError::TimestampOverflow)?;
|
||||||
|
|
||||||
|
if total_time.as_secs() <= i32::max_value() as u64 {
|
||||||
|
Ok(sys + d2)
|
||||||
|
} else {
|
||||||
|
Err(BlockError::TimestampOverflow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Preprocessed block data gathered in `verify_block_unordered` call
|
/// Preprocessed block data gathered in `verify_block_unordered` call
|
||||||
pub struct PreverifiedBlock {
|
pub struct PreverifiedBlock {
|
||||||
/// Populated block header
|
/// Populated block header
|
||||||
@ -305,7 +325,7 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool,
|
|||||||
const ACCEPTABLE_DRIFT: Duration = Duration::from_secs(15);
|
const ACCEPTABLE_DRIFT: Duration = Duration::from_secs(15);
|
||||||
let max_time = SystemTime::now() + ACCEPTABLE_DRIFT;
|
let max_time = SystemTime::now() + ACCEPTABLE_DRIFT;
|
||||||
let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9;
|
let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9;
|
||||||
let timestamp = UNIX_EPOCH + Duration::from_secs(header.timestamp());
|
let timestamp = timestamp_checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp()))?;
|
||||||
|
|
||||||
if timestamp > invalid_threshold {
|
if timestamp > invalid_threshold {
|
||||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp })))
|
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp })))
|
||||||
@ -327,8 +347,8 @@ fn verify_parent(header: &Header, parent: &Header, engine: &EthEngine) -> Result
|
|||||||
let gas_limit_divisor = engine.params().gas_limit_bound_divisor;
|
let gas_limit_divisor = engine.params().gas_limit_bound_divisor;
|
||||||
|
|
||||||
if !engine.is_timestamp_valid(header.timestamp(), parent.timestamp()) {
|
if !engine.is_timestamp_valid(header.timestamp(), parent.timestamp()) {
|
||||||
let min = SystemTime::now() + Duration::from_secs(parent.timestamp() + 1);
|
let min = timestamp_checked_add(SystemTime::now(), Duration::from_secs(parent.timestamp().saturating_add(1)))?;
|
||||||
let found = SystemTime::now() + Duration::from_secs(header.timestamp());
|
let found = timestamp_checked_add(SystemTime::now(), Duration::from_secs(header.timestamp()))?;
|
||||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found })))
|
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found })))
|
||||||
}
|
}
|
||||||
if header.number() != parent.number() + 1 {
|
if header.number() != parent.number() + 1 {
|
||||||
@ -742,7 +762,8 @@ mod tests {
|
|||||||
check_fail_timestamp(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc), false);
|
check_fail_timestamp(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc), false);
|
||||||
|
|
||||||
header = good.clone();
|
header = good.clone();
|
||||||
header.set_timestamp(2450000000);
|
// will return `BlockError::TimestampOverflow` when timestamp > `i32::max_value()`
|
||||||
|
header.set_timestamp(i32::max_value() as u64);
|
||||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), false);
|
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), false);
|
||||||
|
|
||||||
header = good.clone();
|
header = good.clone();
|
||||||
@ -814,4 +835,11 @@ mod tests {
|
|||||||
check_fail(unordered_test(&create_test_block_with_data(&header, &bad_transactions, &[]), &engine), TooManyTransactions(keypair.address()));
|
check_fail(unordered_test(&create_test_block_with_data(&header, &bad_transactions, &[]), &engine), TooManyTransactions(keypair.address()));
|
||||||
unordered_test(&create_test_block_with_data(&header, &good_transactions, &[]), &engine).unwrap();
|
unordered_test(&create_test_block_with_data(&header, &good_transactions, &[]), &engine).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_add_systime_dur() {
|
||||||
|
assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 + 1, 0)).is_err());
|
||||||
|
assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64, 0)).is_ok());
|
||||||
|
assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 - 1, 1_000_000_000)).is_ok());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
//! A generic verifier trait.
|
//! A generic verifier trait.
|
||||||
|
|
||||||
use client::{BlockInfo, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use client::BlockInfo;
|
||||||
use engines::EthEngine;
|
use engines::EthEngine;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use types::header::Header;
|
use types::header::Header;
|
||||||
|
@ -30,6 +30,7 @@ pub enum ForkSpec {
|
|||||||
Homestead,
|
Homestead,
|
||||||
Byzantium,
|
Byzantium,
|
||||||
Constantinople,
|
Constantinople,
|
||||||
|
ConstantinopleFix,
|
||||||
EIP158ToByzantiumAt5,
|
EIP158ToByzantiumAt5,
|
||||||
FrontierToHomesteadAt5,
|
FrontierToHomesteadAt5,
|
||||||
HomesteadToDaoAt5,
|
HomesteadToDaoAt5,
|
||||||
|
@ -17,6 +17,10 @@ url = { version = "1", optional = true }
|
|||||||
ansi_term = "0.10"
|
ansi_term = "0.10"
|
||||||
common-types = { path = "../ethcore/types" }
|
common-types = { path = "../ethcore/types" }
|
||||||
error-chain = "0.12"
|
error-chain = "0.12"
|
||||||
|
ethabi = "6.0"
|
||||||
|
ethabi-derive = "6.0"
|
||||||
|
ethabi-contract = "6.0"
|
||||||
|
ethcore-call-contract = { path = "../ethcore/call-contract" }
|
||||||
ethereum-types = "0.4"
|
ethereum-types = "0.4"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
heapsize = "0.4"
|
heapsize = "0.4"
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
extern crate common_types as types;
|
extern crate common_types as types;
|
||||||
|
extern crate ethabi;
|
||||||
|
extern crate ethcore_call_contract as call_contract;
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate heapsize;
|
extern crate heapsize;
|
||||||
@ -33,6 +35,10 @@ extern crate price_info;
|
|||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate transaction_pool as txpool;
|
extern crate transaction_pool as txpool;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate ethabi_contract;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate ethabi_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -52,5 +58,6 @@ pub mod external;
|
|||||||
pub mod gas_price_calibrator;
|
pub mod gas_price_calibrator;
|
||||||
pub mod gas_pricer;
|
pub mod gas_pricer;
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
|
pub mod service_transaction_checker;
|
||||||
#[cfg(feature = "work-notify")]
|
#[cfg(feature = "work-notify")]
|
||||||
pub mod work_notify;
|
pub mod work_notify;
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
//! A service transactions contract checker.
|
//! A service transactions contract checker.
|
||||||
|
|
||||||
use client::{RegistryInfo, CallContract, BlockId};
|
use call_contract::{CallContract, RegistryInfo};
|
||||||
|
use types::ids::BlockId;
|
||||||
use types::transaction::SignedTransaction;
|
use types::transaction::SignedTransaction;
|
||||||
use ethabi::FunctionOutputDecoder;
|
use ethabi::FunctionOutputDecoder;
|
||||||
|
|
@ -43,8 +43,9 @@ extern crate toml;
|
|||||||
extern crate blooms_db;
|
extern crate blooms_db;
|
||||||
extern crate cli_signer;
|
extern crate cli_signer;
|
||||||
extern crate common_types as types;
|
extern crate common_types as types;
|
||||||
extern crate ethcore;
|
|
||||||
extern crate parity_bytes as bytes;
|
extern crate parity_bytes as bytes;
|
||||||
|
extern crate ethcore;
|
||||||
|
extern crate ethcore_call_contract as call_contract;
|
||||||
extern crate ethcore_db;
|
extern crate ethcore_db;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
extern crate ethcore_light as light;
|
extern crate ethcore_light as light;
|
||||||
|
@ -21,8 +21,9 @@ use std::thread;
|
|||||||
|
|
||||||
use ansi_term::Colour;
|
use ansi_term::Colour;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use call_contract::CallContract;
|
||||||
use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
|
use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
|
||||||
use ethcore::client::{BlockId, CallContract, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo};
|
use ethcore::client::{BlockId, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo};
|
||||||
use ethstore::ethkey;
|
use ethstore::ethkey;
|
||||||
use ethcore::miner::{stratum, Miner, MinerService, MinerOptions};
|
use ethcore::miner::{stratum, Miner, MinerService, MinerOptions};
|
||||||
use ethcore::snapshot::{self, SnapshotConfiguration};
|
use ethcore::snapshot::{self, SnapshotConfiguration};
|
||||||
|
@ -41,11 +41,11 @@ use types::basic_account::BasicAccount;
|
|||||||
use types::ids::BlockId;
|
use types::ids::BlockId;
|
||||||
|
|
||||||
use jsonrpc_core::{BoxFuture, Result, Error};
|
use jsonrpc_core::{BoxFuture, Result, Error};
|
||||||
use jsonrpc_core::futures::{future, Future, Poll, Async};
|
use jsonrpc_core::futures::{future, Future, Poll, Async, IntoFuture};
|
||||||
use jsonrpc_core::futures::future::Either;
|
use jsonrpc_core::futures::future::Either;
|
||||||
use v1::helpers::{errors, nonce, TransactionRequest, FilledTransactionRequest, ConfirmationPayload};
|
use v1::helpers::{errors, nonce, TransactionRequest, FilledTransactionRequest, ConfirmationPayload};
|
||||||
use v1::types::{
|
use v1::types::{
|
||||||
H256 as RpcH256, H520 as RpcH520, Bytes as RpcBytes,
|
H520 as RpcH520, Bytes as RpcBytes,
|
||||||
RichRawTransaction as RpcRichRawTransaction,
|
RichRawTransaction as RpcRichRawTransaction,
|
||||||
ConfirmationPayload as RpcConfirmationPayload,
|
ConfirmationPayload as RpcConfirmationPayload,
|
||||||
ConfirmationResponse,
|
ConfirmationResponse,
|
||||||
@ -69,12 +69,20 @@ pub trait Dispatcher: Send + Sync + Clone {
|
|||||||
fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool)
|
fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool)
|
||||||
-> BoxFuture<FilledTransactionRequest>;
|
-> BoxFuture<FilledTransactionRequest>;
|
||||||
|
|
||||||
/// Sign the given transaction request without dispatching, fetching appropriate nonce.
|
/// Sign the given transaction request, fetching appropriate nonce and executing the PostSign action
|
||||||
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
|
fn sign<P>(
|
||||||
-> BoxFuture<WithToken<SignedTransaction>>;
|
&self,
|
||||||
|
accounts: Arc<AccountProvider>,
|
||||||
|
filled: FilledTransactionRequest,
|
||||||
|
password: SignWith,
|
||||||
|
post_sign: P
|
||||||
|
) -> BoxFuture<P::Item>
|
||||||
|
where
|
||||||
|
P: PostSign + 'static,
|
||||||
|
<P::Out as futures::future::IntoFuture>::Future: Send;
|
||||||
|
|
||||||
/// Converts a `SignedTransaction` into `RichRawTransaction`
|
/// Converts a `SignedTransaction` into `RichRawTransaction`
|
||||||
fn enrich(&self, SignedTransaction) -> RpcRichRawTransaction;
|
fn enrich(&self, signed: SignedTransaction) -> RpcRichRawTransaction;
|
||||||
|
|
||||||
/// "Dispatch" a local transaction.
|
/// "Dispatch" a local transaction.
|
||||||
fn dispatch_transaction(&self, signed_transaction: PendingTransaction)
|
fn dispatch_transaction(&self, signed_transaction: PendingTransaction)
|
||||||
@ -164,19 +172,30 @@ impl<C: miner::BlockChainClient + BlockChainClient, M: MinerService> Dispatcher
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
|
fn sign<P>(
|
||||||
-> BoxFuture<WithToken<SignedTransaction>>
|
&self,
|
||||||
|
accounts: Arc<AccountProvider>,
|
||||||
|
filled: FilledTransactionRequest,
|
||||||
|
password: SignWith,
|
||||||
|
post_sign: P
|
||||||
|
) -> BoxFuture<P::Item>
|
||||||
|
where
|
||||||
|
P: PostSign + 'static,
|
||||||
|
<P::Out as futures::future::IntoFuture>::Future: Send
|
||||||
{
|
{
|
||||||
let chain_id = self.client.signing_chain_id();
|
let chain_id = self.client.signing_chain_id();
|
||||||
|
|
||||||
if let Some(nonce) = filled.nonce {
|
if let Some(nonce) = filled.nonce {
|
||||||
return Box::new(future::done(sign_transaction(&*accounts, filled, chain_id, nonce, password)));
|
let future = sign_transaction(&*accounts, filled, chain_id, nonce, password)
|
||||||
}
|
.into_future()
|
||||||
|
.and_then(move |signed| post_sign.execute(signed));
|
||||||
|
Box::new(future)
|
||||||
|
} else {
|
||||||
let state = self.state_nonce(&filled.from);
|
let state = self.state_nonce(&filled.from);
|
||||||
let reserved = self.nonces.lock().reserve(filled.from, state);
|
let reserved = self.nonces.lock().reserve(filled.from, state);
|
||||||
|
|
||||||
Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password))
|
Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password, post_sign))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
|
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
|
||||||
@ -396,12 +415,24 @@ impl Dispatcher for LightDispatcher {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
|
fn sign<P>(
|
||||||
-> BoxFuture<WithToken<SignedTransaction>>
|
&self,
|
||||||
|
accounts: Arc<AccountProvider>,
|
||||||
|
filled: FilledTransactionRequest,
|
||||||
|
password: SignWith,
|
||||||
|
post_sign: P
|
||||||
|
) -> BoxFuture<P::Item>
|
||||||
|
where
|
||||||
|
P: PostSign + 'static,
|
||||||
|
<P::Out as futures::future::IntoFuture>::Future: Send
|
||||||
{
|
{
|
||||||
let chain_id = self.client.signing_chain_id();
|
let chain_id = self.client.signing_chain_id();
|
||||||
let nonce = filled.nonce.expect("nonce is always provided; qed");
|
let nonce = filled.nonce.expect("nonce is always provided; qed");
|
||||||
Box::new(future::done(sign_transaction(&*accounts, filled, chain_id, nonce, password)))
|
|
||||||
|
let future = sign_transaction(&*accounts, filled, chain_id, nonce, password)
|
||||||
|
.into_future()
|
||||||
|
.and_then(move |signed| post_sign.execute(signed));
|
||||||
|
Box::new(future)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
|
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
|
||||||
@ -449,28 +480,60 @@ fn sign_transaction(
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum ProspectiveSignerState {
|
enum ProspectiveSignerState {
|
||||||
TryProspectiveSign,
|
TryProspectiveSign,
|
||||||
|
WaitForPostSign,
|
||||||
WaitForNonce,
|
WaitForNonce,
|
||||||
Finish,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProspectiveSigner {
|
struct ProspectiveSigner<P: PostSign> {
|
||||||
accounts: Arc<AccountProvider>,
|
accounts: Arc<AccountProvider>,
|
||||||
filled: FilledTransactionRequest,
|
filled: FilledTransactionRequest,
|
||||||
chain_id: Option<u64>,
|
chain_id: Option<u64>,
|
||||||
reserved: nonce::Reserved,
|
reserved: nonce::Reserved,
|
||||||
password: SignWith,
|
password: SignWith,
|
||||||
state: ProspectiveSignerState,
|
state: ProspectiveSignerState,
|
||||||
prospective: Option<Result<WithToken<SignedTransaction>>>,
|
prospective: Option<WithToken<SignedTransaction>>,
|
||||||
ready: Option<nonce::Ready>,
|
ready: Option<nonce::Ready>,
|
||||||
|
post_sign: Option<P>,
|
||||||
|
post_sign_future: Option<<P::Out as IntoFuture>::Future>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProspectiveSigner {
|
/// action to execute after signing
|
||||||
|
/// e.g importing a transaction into the chain
|
||||||
|
pub trait PostSign: Send {
|
||||||
|
/// item that this PostSign returns
|
||||||
|
type Item: Send;
|
||||||
|
/// incase you need to perform async PostSign actions
|
||||||
|
type Out: IntoFuture<Item = Self::Item, Error = Error> + Send;
|
||||||
|
/// perform an action with the signed transaction
|
||||||
|
fn execute(self, signer: WithToken<SignedTransaction>) -> Self::Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PostSign for () {
|
||||||
|
type Item = WithToken<SignedTransaction>;
|
||||||
|
type Out = Result<Self::Item>;
|
||||||
|
fn execute(self, signed: WithToken<SignedTransaction>) -> Self::Out {
|
||||||
|
Ok(signed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: Send, T: Send> PostSign for F
|
||||||
|
where F: FnOnce(WithToken<SignedTransaction>) -> Result<T>
|
||||||
|
{
|
||||||
|
type Item = T;
|
||||||
|
type Out = Result<Self::Item>;
|
||||||
|
fn execute(self, signed: WithToken<SignedTransaction>) -> Self::Out {
|
||||||
|
(self)(signed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: PostSign> ProspectiveSigner<P> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
accounts: Arc<AccountProvider>,
|
accounts: Arc<AccountProvider>,
|
||||||
filled: FilledTransactionRequest,
|
filled: FilledTransactionRequest,
|
||||||
chain_id: Option<u64>,
|
chain_id: Option<u64>,
|
||||||
reserved: nonce::Reserved,
|
reserved: nonce::Reserved,
|
||||||
password: SignWith,
|
password: SignWith,
|
||||||
|
post_sign: P
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// If the account is permanently unlocked we can try to sign
|
// If the account is permanently unlocked we can try to sign
|
||||||
// using prospective nonce. This should speed up sending
|
// using prospective nonce. This should speed up sending
|
||||||
@ -491,6 +554,8 @@ impl ProspectiveSigner {
|
|||||||
},
|
},
|
||||||
prospective: None,
|
prospective: None,
|
||||||
ready: None,
|
ready: None,
|
||||||
|
post_sign: Some(post_sign),
|
||||||
|
post_sign_future: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,8 +574,8 @@ impl ProspectiveSigner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for ProspectiveSigner {
|
impl<P: PostSign> Future for ProspectiveSigner<P> {
|
||||||
type Item = WithToken<SignedTransaction>;
|
type Item = P::Item;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
@ -523,32 +588,45 @@ impl Future for ProspectiveSigner {
|
|||||||
match self.poll_reserved()? {
|
match self.poll_reserved()? {
|
||||||
Async::NotReady => {
|
Async::NotReady => {
|
||||||
self.state = WaitForNonce;
|
self.state = WaitForNonce;
|
||||||
self.prospective = Some(self.sign(self.reserved.prospective_value()));
|
self.prospective = Some(self.sign(self.reserved.prospective_value())?);
|
||||||
},
|
},
|
||||||
Async::Ready(nonce) => {
|
Async::Ready(nonce) => {
|
||||||
self.state = Finish;
|
self.state = WaitForPostSign;
|
||||||
self.prospective = Some(self.sign(nonce.value()));
|
self.post_sign_future = Some(self.post_sign.take()
|
||||||
|
.expect("post_sign is set on creation; qed")
|
||||||
|
.execute(self.sign(nonce.value())?)
|
||||||
|
.into_future());
|
||||||
self.ready = Some(nonce);
|
self.ready = Some(nonce);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
WaitForNonce => {
|
WaitForNonce => {
|
||||||
let nonce = try_ready!(self.poll_reserved());
|
let nonce = try_ready!(self.poll_reserved());
|
||||||
let result = match (self.prospective.take(), nonce.matches_prospective()) {
|
let prospective = match (self.prospective.take(), nonce.matches_prospective()) {
|
||||||
(Some(prospective), true) => prospective,
|
(Some(prospective), true) => prospective,
|
||||||
_ => self.sign(nonce.value()),
|
_ => self.sign(nonce.value())?,
|
||||||
};
|
};
|
||||||
self.state = Finish;
|
|
||||||
self.prospective = Some(result);
|
|
||||||
self.ready = Some(nonce);
|
self.ready = Some(nonce);
|
||||||
|
self.state = WaitForPostSign;
|
||||||
|
self.post_sign_future = Some(self.post_sign.take()
|
||||||
|
.expect("post_sign is set on creation; qed")
|
||||||
|
.execute(prospective)
|
||||||
|
.into_future());
|
||||||
},
|
},
|
||||||
Finish => {
|
WaitForPostSign => {
|
||||||
if let (Some(result), Some(nonce)) = (self.prospective.take(), self.ready.take()) {
|
if let Some(mut fut) = self.post_sign_future.as_mut() {
|
||||||
// Mark nonce as used on successful signing
|
match fut.poll()? {
|
||||||
return result.map(move |tx| {
|
Async::Ready(item) => {
|
||||||
|
let nonce = self.ready
|
||||||
|
.take()
|
||||||
|
.expect("nonce is set before state transitions to WaitForPostSign; qed");
|
||||||
nonce.mark_used();
|
nonce.mark_used();
|
||||||
Async::Ready(tx)
|
return Ok(Async::Ready(item))
|
||||||
})
|
},
|
||||||
|
Async::NotReady => {
|
||||||
|
return Ok(Async::NotReady)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("Poll after ready.");
|
panic!("Poll after ready.");
|
||||||
}
|
}
|
||||||
@ -655,19 +733,21 @@ pub fn execute<D: Dispatcher + 'static>(
|
|||||||
match payload {
|
match payload {
|
||||||
ConfirmationPayload::SendTransaction(request) => {
|
ConfirmationPayload::SendTransaction(request) => {
|
||||||
let condition = request.condition.clone().map(Into::into);
|
let condition = request.condition.clone().map(Into::into);
|
||||||
Box::new(dispatcher.sign(accounts, request, pass)
|
let cloned_dispatcher = dispatcher.clone();
|
||||||
.map(move |v| v.map(move |tx| PendingTransaction::new(tx, condition)))
|
let post_sign = move |with_token_signed: WithToken<SignedTransaction>| {
|
||||||
.map(WithToken::into_tuple)
|
let (signed, token) = with_token_signed.into_tuple();
|
||||||
.map(|(tx, token)| (tx, token, dispatcher))
|
let signed_transaction = PendingTransaction::new(signed, condition);
|
||||||
.and_then(|(tx, tok, dispatcher)| {
|
cloned_dispatcher.dispatch_transaction(signed_transaction)
|
||||||
dispatcher.dispatch_transaction(tx)
|
.map(|hash| (hash, token))
|
||||||
.map(RpcH256::from)
|
};
|
||||||
.map(ConfirmationResponse::SendTransaction)
|
let future = dispatcher.sign(accounts, request, pass, post_sign)
|
||||||
.map(move |h| WithToken::from((h, tok)))
|
.map(|(hash, token)| {
|
||||||
}))
|
WithToken::from((ConfirmationResponse::SendTransaction(hash.into()), token))
|
||||||
|
});
|
||||||
|
Box::new(future)
|
||||||
},
|
},
|
||||||
ConfirmationPayload::SignTransaction(request) => {
|
ConfirmationPayload::SignTransaction(request) => {
|
||||||
Box::new(dispatcher.sign(accounts, request, pass)
|
Box::new(dispatcher.sign(accounts, request, pass, ())
|
||||||
.map(move |result| result
|
.map(move |result| result
|
||||||
.map(move |tx| dispatcher.enrich(tx))
|
.map(move |tx| dispatcher.enrich(tx))
|
||||||
.map(ConfirmationResponse::SignTransaction)
|
.map(ConfirmationResponse::SignTransaction)
|
||||||
|
@ -18,16 +18,17 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use bytes::{Bytes, ToPretty};
|
use bytes::Bytes;
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use types::transaction::PendingTransaction;
|
use types::transaction::PendingTransaction;
|
||||||
|
use types::transaction::SignedTransaction;
|
||||||
use ethereum_types::{H520, U128, Address};
|
use ethereum_types::{H520, U128, Address};
|
||||||
use ethkey::{public_to_address, recover, Signature};
|
use ethkey::{public_to_address, recover, Signature};
|
||||||
|
|
||||||
use jsonrpc_core::{BoxFuture, Result};
|
use jsonrpc_core::{BoxFuture, Result};
|
||||||
use jsonrpc_core::futures::{future, Future};
|
use jsonrpc_core::futures::{future, Future};
|
||||||
use v1::helpers::{errors, eip191};
|
use v1::helpers::{errors, eip191};
|
||||||
use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith};
|
use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith, PostSign, WithToken};
|
||||||
use v1::traits::Personal;
|
use v1::traits::Personal;
|
||||||
use v1::types::{
|
use v1::types::{
|
||||||
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128,
|
H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U128 as RpcU128,
|
||||||
@ -68,7 +69,16 @@ impl<D: Dispatcher> PersonalClient<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Dispatcher + 'static> PersonalClient<D> {
|
impl<D: Dispatcher + 'static> PersonalClient<D> {
|
||||||
fn do_sign_transaction(&self, _meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<(PendingTransaction, D)> {
|
fn do_sign_transaction<P>(
|
||||||
|
&self,
|
||||||
|
_meta: Metadata,
|
||||||
|
request: TransactionRequest,
|
||||||
|
password: String,
|
||||||
|
post_sign: P
|
||||||
|
) -> BoxFuture<P::Item>
|
||||||
|
where P: PostSign + 'static,
|
||||||
|
<P::Out as futures::future::IntoFuture>::Future: Send
|
||||||
|
{
|
||||||
let dispatcher = self.dispatcher.clone();
|
let dispatcher = self.dispatcher.clone();
|
||||||
let accounts = self.accounts.clone();
|
let accounts = self.accounts.clone();
|
||||||
|
|
||||||
@ -86,11 +96,7 @@ impl<D: Dispatcher + 'static> PersonalClient<D> {
|
|||||||
|
|
||||||
Box::new(dispatcher.fill_optional_fields(request.into(), default, false)
|
Box::new(dispatcher.fill_optional_fields(request.into(), default, false)
|
||||||
.and_then(move |filled| {
|
.and_then(move |filled| {
|
||||||
let condition = filled.condition.clone().map(Into::into);
|
dispatcher.sign(accounts, filled, SignWith::Password(password.into()), post_sign)
|
||||||
dispatcher.sign(accounts, filled, SignWith::Password(password.into()))
|
|
||||||
.map(|tx| tx.into_value())
|
|
||||||
.map(move |tx| PendingTransaction::new(tx, condition))
|
|
||||||
.map(move |tx| (tx, dispatcher))
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -223,18 +229,26 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn sign_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<RpcRichRawTransaction> {
|
fn sign_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<RpcRichRawTransaction> {
|
||||||
Box::new(self.do_sign_transaction(meta, request, password)
|
let condition = request.condition.clone().map(Into::into);
|
||||||
.map(|(pending_tx, dispatcher)| dispatcher.enrich(pending_tx.transaction)))
|
let dispatcher = self.dispatcher.clone();
|
||||||
|
Box::new(self.do_sign_transaction(meta, request, password, ())
|
||||||
|
.map(move |tx| PendingTransaction::new(tx.into_value(), condition))
|
||||||
|
.map(move |pending_tx| dispatcher.enrich(pending_tx.transaction)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<RpcH256> {
|
fn send_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<RpcH256> {
|
||||||
Box::new(self.do_sign_transaction(meta, request, password)
|
let condition = request.condition.clone().map(Into::into);
|
||||||
.and_then(|(pending_tx, dispatcher)| {
|
let dispatcher = self.dispatcher.clone();
|
||||||
let chain_id = pending_tx.chain_id();
|
Box::new(self.do_sign_transaction(meta, request, password, move |signed: WithToken<SignedTransaction>| {
|
||||||
trace!(target: "miner", "send_transaction: dispatching tx: {} for chain ID {:?}",
|
dispatcher.dispatch_transaction(
|
||||||
::rlp::encode(&*pending_tx).pretty(), chain_id);
|
PendingTransaction::new(
|
||||||
|
signed.into_value(),
|
||||||
dispatcher.dispatch_transaction(pending_tx).map(Into::into)
|
condition
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.and_then(|hash| {
|
||||||
|
Ok(RpcH256::from(hash))
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
FROM ubuntu:xenial
|
FROM ubuntu:xenial
|
||||||
MAINTAINER Parity Technologies <devops@parity.io>
|
LABEL MAINTAINER="Parity Technologies <devops-team@parity.io>"
|
||||||
#set ENVIROMENT
|
|
||||||
ARG 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 curl jq
|
RUN apt update && apt install -y --no-install-recommends openssl libudev-dev file curl jq
|
||||||
@ -11,26 +8,24 @@ RUN apt update && apt install -y --no-install-recommends openssl libudev-dev fil
|
|||||||
ENV RUST_BACKTRACE 1
|
ENV RUST_BACKTRACE 1
|
||||||
|
|
||||||
# cleanup Docker image
|
# cleanup Docker image
|
||||||
RUN apt autoremove -y
|
RUN apt autoremove -y \
|
||||||
RUN apt clean -y
|
&& apt clean -y \
|
||||||
RUN rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*
|
&& 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
|
||||||
|
|
||||||
|
WORKDIR /home/parity
|
||||||
|
|
||||||
#add TARGET to docker image
|
# add parity-ethereum to docker image
|
||||||
COPY artifacts/x86_64-unknown-linux-gnu/$TARGET /bin/$TARGET
|
COPY artifacts/x86_64-unknown-linux-gnu/parity /bin/parity
|
||||||
|
|
||||||
# Build a shell script because the ENTRYPOINT command doesn't like using ENV
|
|
||||||
RUN echo "#!/bin/bash \n ${TARGET} \$@" > ./entrypoint.sh
|
|
||||||
RUN chmod +x ./entrypoint.sh
|
|
||||||
|
|
||||||
COPY scripts/docker/hub/check_sync.sh /check_sync.sh
|
COPY scripts/docker/hub/check_sync.sh /check_sync.sh
|
||||||
|
|
||||||
# switch to user parity here
|
# switch to user parity here
|
||||||
USER parity
|
USER parity
|
||||||
|
|
||||||
# setup ENTRYPOINT
|
VOLUME [ "/home/parity/.local/share/io.parity.ethereum" ]
|
||||||
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 ["/bin/parity"]
|
||||||
|
@ -9,11 +9,12 @@ echo "CARGO_HOME: " $CARGO_HOME
|
|||||||
echo "CARGO_TARGET: " $CARGO_TARGET
|
echo "CARGO_TARGET: " $CARGO_TARGET
|
||||||
echo "CC: " $CC
|
echo "CC: " $CC
|
||||||
echo "CXX: " $CXX
|
echo "CXX: " $CXX
|
||||||
|
#strip ON
|
||||||
|
export RUSTFLAGS=" -C link-arg=-s"
|
||||||
|
|
||||||
echo "_____ Building target: "$CARGO_TARGET" _____"
|
echo "_____ Building target: "$CARGO_TARGET" _____"
|
||||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
||||||
then
|
then
|
||||||
# only thing we need for android
|
|
||||||
time cargo build --target $CARGO_TARGET --release -p parity-clib --features final
|
time cargo build --target $CARGO_TARGET --release -p parity-clib --features final
|
||||||
else
|
else
|
||||||
time cargo build --target $CARGO_TARGET --release --features final
|
time cargo build --target $CARGO_TARGET --release --features final
|
||||||
@ -24,14 +25,11 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "_____ Post-processing binaries _____"
|
echo "_____ Post-processing binaries _____"
|
||||||
rm -rf artifacts
|
mkdir -p artifacts/$CARGO_TARGET
|
||||||
mkdir -p artifacts
|
cd artifacts/$CARGO_TARGET
|
||||||
cd artifacts
|
|
||||||
mkdir -p $CARGO_TARGET
|
|
||||||
cd $CARGO_TARGET
|
|
||||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
||||||
then
|
then
|
||||||
# only thing we need for android
|
|
||||||
cp -v ../../target/$CARGO_TARGET/release/libparity.so ./libparity.so
|
cp -v ../../target/$CARGO_TARGET/release/libparity.so ./libparity.so
|
||||||
else
|
else
|
||||||
cp -v ../../target/$CARGO_TARGET/release/parity ./parity
|
cp -v ../../target/$CARGO_TARGET/release/parity ./parity
|
||||||
@ -41,16 +39,6 @@ else
|
|||||||
cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
|
cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# stripping can also be done on release build time
|
|
||||||
# export RUSTFLAGS="${RUSTFLAGS} -C link-arg=-s"
|
|
||||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
|
||||||
then
|
|
||||||
arm-linux-androideabi-strip -v ./*
|
|
||||||
else
|
|
||||||
strip -v ./*
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "_____ Calculating checksums _____"
|
echo "_____ Calculating checksums _____"
|
||||||
for binary in $(ls)
|
for binary in $(ls)
|
||||||
do
|
do
|
||||||
@ -62,4 +50,3 @@ do
|
|||||||
./parity tools hash $binary > $binary.sha3
|
./parity tools hash $binary > $binary.sha3
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e # fail on any error
|
|
||||||
set -u # treat unset variables as error
|
|
||||||
|
|
||||||
cargo install cargo-audit
|
|
||||||
cargo audit
|
|
@ -36,19 +36,3 @@ do
|
|||||||
esac
|
esac
|
||||||
cd ..
|
cd ..
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "__________Push binaries to AWS S3____________"
|
|
||||||
aws configure set aws_access_key_id $s3_key
|
|
||||||
aws configure set aws_secret_access_key $s3_secret
|
|
||||||
|
|
||||||
case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in
|
|
||||||
(beta|stable|nightly)
|
|
||||||
export S3_BUCKET=releases.parity.io/ethereum;
|
|
||||||
;;
|
|
||||||
(*)
|
|
||||||
export S3_BUCKET=builds-parity;
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
aws s3 sync ./ s3://$S3_BUCKET/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/
|
|
||||||
|
|
@ -21,7 +21,19 @@ SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap"
|
|||||||
echo "__________Create snap package__________"
|
echo "__________Create snap package__________"
|
||||||
echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME
|
echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME
|
||||||
echo $VERSION:$GRADE:$BUILD_ARCH
|
echo $VERSION:$GRADE:$BUILD_ARCH
|
||||||
cat scripts/snap/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml
|
# cat scripts/snap/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml
|
||||||
|
# a bit more necromancy (substitutions):
|
||||||
|
pwd
|
||||||
|
cd /builds/$CI_PROJECT_PATH/scripts/snap/
|
||||||
|
sed -e 's/$VERSION/'"$VERSION"'/g' \
|
||||||
|
-e 's/$GRADE/'"$GRADE"'/g' \
|
||||||
|
-e 's/$BUILD_ARCH/'"$BUILD_ARCH"'/g' \
|
||||||
|
-e 's/$CARGO_TARGET/'"$CARGO_TARGET"'/g' \
|
||||||
|
snapcraft.template.yaml > /builds/$CI_PROJECT_PATH/snapcraft.yaml
|
||||||
|
cd /builds/$CI_PROJECT_PATH
|
||||||
|
pwd
|
||||||
|
apt update
|
||||||
|
apt install -y --no-install-recommends rhash
|
||||||
cat snapcraft.yaml
|
cat snapcraft.yaml
|
||||||
snapcraft --target-arch=$BUILD_ARCH
|
snapcraft --target-arch=$BUILD_ARCH
|
||||||
ls *.snap
|
ls *.snap
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# ARGUMENT $1 Rust flavor to test with (stable/beta/nightly)
|
|
||||||
|
|
||||||
set -e # fail on any error
|
set -e # fail on any error
|
||||||
set -u # treat unset variables as error
|
set -u # treat unset variables as error
|
||||||
|
|
||||||
@ -27,9 +25,6 @@ then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rustup default $1
|
|
||||||
|
|
||||||
git submodule update --init --recursive
|
|
||||||
rustup show
|
rustup show
|
||||||
|
|
||||||
exec ./test.sh
|
exec ./test.sh
|
||||||
|
@ -50,8 +50,4 @@ parts:
|
|||||||
cp -v ethkey $SNAPCRAFT_PART_INSTALL/usr/bin/ethkey
|
cp -v ethkey $SNAPCRAFT_PART_INSTALL/usr/bin/ethkey
|
||||||
cp -v ethstore $SNAPCRAFT_PART_INSTALL/usr/bin/ethstore
|
cp -v ethstore $SNAPCRAFT_PART_INSTALL/usr/bin/ethstore
|
||||||
cp -v whisper $SNAPCRAFT_PART_INSTALL/usr/bin/whisper
|
cp -v whisper $SNAPCRAFT_PART_INSTALL/usr/bin/whisper
|
||||||
stage-packages: [libc6, libudev1, libstdc++6, cmake, libdb]
|
stage-packages: [libc6, libudev1, libstdc++6, cmake, libdb5.3]
|
||||||
df:
|
|
||||||
plugin: nil
|
|
||||||
stage-packages: [coreutils]
|
|
||||||
stage: [bin/df]
|
|
||||||
|
@ -8,6 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
common-types = { path = "../ethcore/types" }
|
common-types = { path = "../ethcore/types" }
|
||||||
|
ethcore-call-contract = { path = "../ethcore/call-contract" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
parking_lot = "0.7"
|
parking_lot = "0.7"
|
||||||
hyper = { version = "0.12", default-features = false }
|
hyper = { version = "0.12", default-features = false }
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use ethcore::client::{BlockId, ChainNotify, NewBlocks, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use ethcore::client::{BlockId, ChainNotify, NewBlocks};
|
||||||
use ethereum_types::Address;
|
use ethereum_types::Address;
|
||||||
use ethabi::FunctionOutputDecoder;
|
use ethabi::FunctionOutputDecoder;
|
||||||
use trusted_client::TrustedClient;
|
use trusted_client::TrustedClient;
|
||||||
|
@ -18,8 +18,9 @@ use std::sync::Arc;
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
use call_contract::CallContract;
|
||||||
use ethabi::FunctionOutputDecoder;
|
use ethabi::FunctionOutputDecoder;
|
||||||
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, NewBlocks, CallContract};
|
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, NewBlocks};
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use ethkey::public_to_address;
|
use ethkey::public_to_address;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
@ -18,6 +18,7 @@ extern crate byteorder;
|
|||||||
extern crate common_types;
|
extern crate common_types;
|
||||||
extern crate ethabi;
|
extern crate ethabi;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
|
extern crate ethcore_call_contract as call_contract;
|
||||||
extern crate ethcore_sync as sync;
|
extern crate ethcore_sync as sync;
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate ethkey;
|
extern crate ethkey;
|
||||||
|
@ -19,7 +19,8 @@ use parking_lot::RwLock;
|
|||||||
use common_types::filter::Filter;
|
use common_types::filter::Filter;
|
||||||
use ethabi::RawLog;
|
use ethabi::RawLog;
|
||||||
use ethabi::FunctionOutputDecoder;
|
use ethabi::FunctionOutputDecoder;
|
||||||
use ethcore::client::{Client, BlockChainClient, BlockId, CallContract};
|
use call_contract::CallContract;
|
||||||
|
use ethcore::client::{Client, BlockChainClient, BlockId};
|
||||||
use ethkey::{Public, public_to_address};
|
use ethkey::{Public, public_to_address};
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use call_contract::RegistryInfo;
|
||||||
use common_types::transaction::{Transaction, SignedTransaction, Action};
|
use common_types::transaction::{Transaction, SignedTransaction, Action};
|
||||||
use ethereum_types::Address;
|
use ethereum_types::Address;
|
||||||
use ethcore::client::{Client, BlockChainClient, ChainInfo, Nonce, BlockId, RegistryInfo};
|
use ethcore::client::{Client, BlockChainClient, ChainInfo, Nonce, BlockId};
|
||||||
use ethcore::miner::{Miner, MinerService};
|
use ethcore::miner::{Miner, MinerService};
|
||||||
use sync::SyncProvider;
|
use sync::SyncProvider;
|
||||||
use helpers::{get_confirmed_block_hash, REQUEST_CONFIRMATIONS_REQUIRED};
|
use helpers::{get_confirmed_block_hash, REQUEST_CONFIRMATIONS_REQUIRED};
|
||||||
|
23
test.sh
23
test.sh
@ -1,33 +1,12 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Running Parity Full Test Suite
|
# Running Parity Full Test Suite
|
||||||
|
echo "________Running test.sh________"
|
||||||
|
|
||||||
FEATURES="json-tests,ci-skip-issue"
|
FEATURES="json-tests,ci-skip-issue"
|
||||||
OPTIONS="--release"
|
OPTIONS="--release"
|
||||||
VALIDATE=1
|
VALIDATE=1
|
||||||
THREADS=8
|
THREADS=8
|
||||||
|
|
||||||
case $1 in
|
|
||||||
--no-json)
|
|
||||||
FEATURES="ipc"
|
|
||||||
shift # past argument=value
|
|
||||||
;;
|
|
||||||
--no-release)
|
|
||||||
OPTIONS=""
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--no-validate)
|
|
||||||
VALIDATE=0
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--no-run)
|
|
||||||
OPTIONS="--no-run"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# unknown option
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ serde = "1.0"
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
error-chain = { version = "0.12", default-features = false }
|
error-chain = { version = "0.12", default-features = false }
|
||||||
|
lru-cache = "0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
|
@ -20,6 +20,7 @@ use std::collections::{HashSet, HashMap, VecDeque};
|
|||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
||||||
|
use lru_cache::LruCache;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
use ethereum_types::{H256, H520};
|
use ethereum_types::{H256, H520};
|
||||||
use rlp::{Rlp, RlpStream};
|
use rlp::{Rlp, RlpStream};
|
||||||
@ -55,6 +56,8 @@ const REQUEST_BACKOFF: [Duration; 4] = [
|
|||||||
|
|
||||||
const NODE_LAST_SEEN_TIMEOUT: Duration = Duration::from_secs(24*60*60);
|
const NODE_LAST_SEEN_TIMEOUT: Duration = Duration::from_secs(24*60*60);
|
||||||
|
|
||||||
|
const OBSERVED_NODES_MAX_SIZE: usize = 10_000;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct NodeEntry {
|
pub struct NodeEntry {
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
@ -95,7 +98,27 @@ struct FindNodeRequest {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
enum PingReason {
|
enum PingReason {
|
||||||
Default,
|
Default,
|
||||||
FromDiscoveryRequest(NodeId)
|
FromDiscoveryRequest(NodeId, NodeValidity),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
enum NodeCategory {
|
||||||
|
Bucket,
|
||||||
|
Observed
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
enum NodeValidity {
|
||||||
|
Ourselves,
|
||||||
|
ValidNode(NodeCategory),
|
||||||
|
ExpiredNode(NodeCategory),
|
||||||
|
UnknownNode
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum BucketError {
|
||||||
|
Ourselves,
|
||||||
|
NotInTheBucket{node_entry: NodeEntry, bucket_distance: usize},
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PingRequest {
|
struct PingRequest {
|
||||||
@ -145,6 +168,12 @@ pub struct Discovery<'a> {
|
|||||||
discovery_id: NodeId,
|
discovery_id: NodeId,
|
||||||
discovery_nodes: HashSet<NodeId>,
|
discovery_nodes: HashSet<NodeId>,
|
||||||
node_buckets: Vec<NodeBucket>,
|
node_buckets: Vec<NodeBucket>,
|
||||||
|
|
||||||
|
// Sometimes we don't want to add nodes to the NodeTable, but still want to
|
||||||
|
// keep track of them to avoid excessive pinging (happens when an unknown node sends
|
||||||
|
// a discovery request to us -- the node might be on a different net).
|
||||||
|
other_observed_nodes: LruCache<NodeId, (NodeEndpoint, Instant)>,
|
||||||
|
|
||||||
in_flight_pings: HashMap<NodeId, PingRequest>,
|
in_flight_pings: HashMap<NodeId, PingRequest>,
|
||||||
in_flight_find_nodes: HashMap<NodeId, FindNodeRequest>,
|
in_flight_find_nodes: HashMap<NodeId, FindNodeRequest>,
|
||||||
send_queue: VecDeque<Datagram>,
|
send_queue: VecDeque<Datagram>,
|
||||||
@ -171,6 +200,7 @@ impl<'a> Discovery<'a> {
|
|||||||
discovery_id: NodeId::new(),
|
discovery_id: NodeId::new(),
|
||||||
discovery_nodes: HashSet::new(),
|
discovery_nodes: HashSet::new(),
|
||||||
node_buckets: (0..ADDRESS_BITS).map(|_| NodeBucket::new()).collect(),
|
node_buckets: (0..ADDRESS_BITS).map(|_| NodeBucket::new()).collect(),
|
||||||
|
other_observed_nodes: LruCache::new(OBSERVED_NODES_MAX_SIZE),
|
||||||
in_flight_pings: HashMap::new(),
|
in_flight_pings: HashMap::new(),
|
||||||
in_flight_find_nodes: HashMap::new(),
|
in_flight_find_nodes: HashMap::new(),
|
||||||
send_queue: VecDeque::new(),
|
send_queue: VecDeque::new(),
|
||||||
@ -200,41 +230,53 @@ impl<'a> Discovery<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_node(&mut self, e: NodeEntry) -> Option<TableUpdates> {
|
fn update_bucket_record(&mut self, e: NodeEntry) -> Result<(), BucketError> {
|
||||||
trace!(target: "discovery", "Inserting {:?}", &e);
|
|
||||||
let id_hash = keccak(e.id);
|
let id_hash = keccak(e.id);
|
||||||
let dist = match Discovery::distance(&self.id_hash, &id_hash) {
|
let dist = match Discovery::distance(&self.id_hash, &id_hash) {
|
||||||
Some(dist) => dist,
|
Some(dist) => dist,
|
||||||
None => {
|
None => {
|
||||||
debug!(target: "discovery", "Attempted to update own entry: {:?}", e);
|
debug!(target: "discovery", "Attempted to update own entry: {:?}", e);
|
||||||
return None;
|
return Err(BucketError::Ourselves);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut added_map = HashMap::new();
|
|
||||||
let ping = {
|
|
||||||
let bucket = &mut self.node_buckets[dist];
|
let bucket = &mut self.node_buckets[dist];
|
||||||
let updated = if let Some(node) = bucket.nodes.iter_mut().find(|n| n.address.id == e.id) {
|
bucket.nodes.iter_mut().find(|n| n.address.id == e.id)
|
||||||
node.address = e.clone();
|
.map_or(Err(BucketError::NotInTheBucket{node_entry: e.clone(), bucket_distance: dist}.into()), |entry| {
|
||||||
node.last_seen = Instant::now();
|
entry.address = e;
|
||||||
node.backoff_until = Instant::now();
|
entry.last_seen = Instant::now();
|
||||||
node.fail_count = 0;
|
entry.backoff_until = Instant::now();
|
||||||
true
|
entry.fail_count = 0;
|
||||||
} else { false };
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if !updated {
|
fn update_node(&mut self, e: NodeEntry) -> Option<TableUpdates> {
|
||||||
added_map.insert(e.id, e.clone());
|
trace!(target: "discovery", "Inserting {:?}", &e);
|
||||||
bucket.nodes.push_front(BucketEntry::new(e));
|
|
||||||
|
|
||||||
|
match self.update_bucket_record(e) {
|
||||||
|
Ok(()) => None,
|
||||||
|
Err(BucketError::Ourselves) => None,
|
||||||
|
Err(BucketError::NotInTheBucket{node_entry, bucket_distance}) => Some((node_entry, bucket_distance))
|
||||||
|
}.map(|(node_entry, bucket_distance)| {
|
||||||
|
trace!(target: "discovery", "Adding a new node {:?} into our bucket {}", &node_entry, bucket_distance);
|
||||||
|
|
||||||
|
let mut added = HashMap::with_capacity(1);
|
||||||
|
added.insert(node_entry.id, node_entry.clone());
|
||||||
|
|
||||||
|
let node_to_ping = {
|
||||||
|
let bucket = &mut self.node_buckets[bucket_distance];
|
||||||
|
bucket.nodes.push_front(BucketEntry::new(node_entry));
|
||||||
if bucket.nodes.len() > BUCKET_SIZE {
|
if bucket.nodes.len() > BUCKET_SIZE {
|
||||||
select_bucket_ping(bucket.nodes.iter())
|
select_bucket_ping(bucket.nodes.iter())
|
||||||
} else { None }
|
} else {
|
||||||
} else { None }
|
None
|
||||||
};
|
|
||||||
if let Some(node) = ping {
|
|
||||||
self.try_ping(node, PingReason::Default);
|
|
||||||
}
|
}
|
||||||
Some(TableUpdates { added: added_map, removed: HashSet::new() })
|
};
|
||||||
|
if let Some(node) = node_to_ping {
|
||||||
|
self.try_ping(node, PingReason::Default);
|
||||||
|
};
|
||||||
|
TableUpdates{added, removed: HashSet::new()}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts the discovery process at round 0
|
/// Starts the discovery process at round 0
|
||||||
@ -541,10 +583,28 @@ impl<'a> Discovery<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some((node, ping_reason)) = expected_node {
|
if let Some((node, ping_reason)) = expected_node {
|
||||||
if let PingReason::FromDiscoveryRequest(target) = ping_reason {
|
if let PingReason::FromDiscoveryRequest(target, validity) = ping_reason {
|
||||||
self.respond_with_discovery(target, &node)?;
|
self.respond_with_discovery(target, &node)?;
|
||||||
|
// kirushik: I would prefer to probe the network id of the remote node here, and add it to the nodes list if it's on "our" net --
|
||||||
|
// but `on_packet` happens synchronously, so doing the full TCP handshake ceremony here is a bad idea.
|
||||||
|
// So instead we just LRU-caching most recently seen nodes to avoid unnecessary pinging
|
||||||
|
match validity {
|
||||||
|
NodeValidity::ValidNode(NodeCategory::Bucket) | NodeValidity::ExpiredNode(NodeCategory::Bucket) => {
|
||||||
|
trace!(target: "discovery", "Updating node {:?} in our Kad buckets", &node);
|
||||||
|
self.update_bucket_record(node).unwrap_or_else(|error| {
|
||||||
|
debug!(target: "discovery", "Error occured when processing ping from a bucket node: {:?}", &error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
NodeValidity::UnknownNode | NodeValidity::ExpiredNode(NodeCategory::Observed) | NodeValidity::ValidNode(NodeCategory::Observed)=> {
|
||||||
|
trace!(target: "discovery", "Updating node {:?} in the list of other_observed_nodes", &node);
|
||||||
|
self.other_observed_nodes.insert(node.id, (node.endpoint, Instant::now()));
|
||||||
|
},
|
||||||
|
NodeValidity::Ourselves => (),
|
||||||
}
|
}
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
Ok(self.update_node(node))
|
Ok(self.update_node(node))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from);
|
debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@ -565,31 +625,41 @@ impl<'a> Discovery<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.is_a_valid_known_node(&node) {
|
match self.check_validity(&node) {
|
||||||
self.respond_with_discovery(target, &node)?;
|
NodeValidity::Ourselves => (), // It makes no sense to respond to the discovery request from ourselves
|
||||||
} else {
|
NodeValidity::ValidNode(_) => self.respond_with_discovery(target, &node)?,
|
||||||
// Make sure the request source is actually there and responds to pings before actually responding
|
// Make sure the request source is actually there and responds to pings before actually responding
|
||||||
self.try_ping(node, PingReason::FromDiscoveryRequest(target));
|
invalidity_reason => self.try_ping(node, PingReason::FromDiscoveryRequest(target, invalidity_reason))
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_a_valid_known_node(&self, node: &NodeEntry) -> bool {
|
fn check_validity(&mut self, node: &NodeEntry) -> NodeValidity {
|
||||||
let id_hash = keccak(node.id);
|
let id_hash = keccak(node.id);
|
||||||
let dist = match Discovery::distance(&self.id_hash, &id_hash) {
|
let dist = match Discovery::distance(&self.id_hash, &id_hash) {
|
||||||
Some(dist) => dist,
|
Some(dist) => dist,
|
||||||
None => {
|
None => {
|
||||||
debug!(target: "discovery", "Got an incoming discovery request from self: {:?}", node);
|
debug!(target: "discovery", "Got an incoming discovery request from self: {:?}", node);
|
||||||
return false;
|
return NodeValidity::Ourselves;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let bucket = &self.node_buckets[dist];
|
let bucket = &self.node_buckets[dist];
|
||||||
if let Some(known_node) = bucket.nodes.iter().find(|n| n.address.id == node.id) {
|
if let Some(known_node) = bucket.nodes.iter().find(|n| n.address.id == node.id) {
|
||||||
debug!(target: "discovery", "Found a known node in a bucket when processing discovery: {:?}/{:?}", known_node, node);
|
debug!(target: "discovery", "Found a known node in a bucket when processing discovery: {:?}/{:?}", known_node, node);
|
||||||
(known_node.address.endpoint == node.endpoint) && (known_node.last_seen.elapsed() < NODE_LAST_SEEN_TIMEOUT)
|
match ((known_node.address.endpoint == node.endpoint), (known_node.last_seen.elapsed() < NODE_LAST_SEEN_TIMEOUT)) {
|
||||||
|
(true, true) => NodeValidity::ValidNode(NodeCategory::Bucket),
|
||||||
|
(true, false) => NodeValidity::ExpiredNode(NodeCategory::Bucket),
|
||||||
|
_ => NodeValidity::UnknownNode
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
self.other_observed_nodes.get_mut(&node.id).map_or(NodeValidity::UnknownNode, |(endpoint, observed_at)| {
|
||||||
|
match ((node.endpoint==*endpoint), (observed_at.elapsed() < NODE_LAST_SEEN_TIMEOUT)) {
|
||||||
|
(true, true) => NodeValidity::ValidNode(NodeCategory::Observed),
|
||||||
|
(true, false) => NodeValidity::ExpiredNode(NodeCategory::Observed),
|
||||||
|
_ => NodeValidity::UnknownNode
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ extern crate keccak_hash as hash;
|
|||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate parity_snappy as snappy;
|
extern crate parity_snappy as snappy;
|
||||||
|
extern crate lru_cache;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
@ -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.3.2"
|
version = "2.3.3"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user