Compare commits

..

9 Commits

Author SHA1 Message Date
Afri Schoedon
7b1d3e180c Backports for Stable 2.2.10 (#10332)
* version: bump stable to 2.2.10

* 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

* Additional tests for uint deserialization. (#10279)

* 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

* fix(add helper for timestamp overflows) (#10330)

* fix(add helper timestamp overflows)

* fix(simplify code)

* fix(make helper private)

* 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

* 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

* fix(docker-aarch64) : cross-compile config (#9798)

* fix(docker-aarch64) : cross-compile config (#9798)

* ci: remove trailing double newline from dockerfile
2019-02-13 11:00:15 +01:00
Kirill Pimenov
cc91e95f03 Additional error for invalid gas (#10327) (#10329)
* Tag sensible place (ECHECH)

* Additional overflows checks.
2019-02-12 10:53:01 +01:00
Afri Schoedon
5d5b372f44 version: bump stable to 2.2.9 (#10282) 2019-02-03 12:44:08 +01:00
Kirill Pimenov
abb41f60f4 Additional tests for uint deserialization. (#10281) 2019-02-03 12:43:13 +01:00
Afri Schoedon
ec81d67009 Stable: Macos heapsize force jemalloc (#10234) (#10258)
* Macos heapsize force jemalloc (#10234)

* Switch to non prefixed malloc_size_of on macos

* Fix

* Testing darwin build

* Fix import

* conflict

* switch heapsize deps commit

* switch heapsize commit

* Rename branch

* Restore gitlab ci to origin

* test for mac

* mac tests?

* Switch of macos CI tests.

* Update Cargo.lock

Co-Authored-By: 5chdn <5chdn@users.noreply.github.com>
2019-01-30 12:01:55 +01:00
Afri Schoedon
2a7dc644b7 Stable Backports 2.2.8 (#10224)
* version: bump stable to 2.2.8

* Update for Android cross-compilation. (#10180)

* build-unix update

* .gitlab-ci update

* Update build-unix.sh

add android postprocessing

* path to android lib

libparity.so

* fix path to libparity

* add android lib to artifacts

* Cancel Constantinople HF on POA Core (#10198)

* Add EIP-1283 disable transition (#10214)

* Enable St-Peters-Fork ("Constantinople Fix") (#10223)

* ethcore: disable eip-1283 on kovan block 10255201

* ethcore: disable eip-1283 on ropsten block 4939394

* ethcore: enable st-peters-fork on mainnet block 7280000

* ethcore: fix kovan chain spec

* version: update fork blocks

* ethcore: disable eip-1283 on sokol block 7026400
2019-01-22 12:32:56 +01:00
Afri Schoedon
b00a21f39a backports for stable 2.2.7 (#10163)
* version: bump stable to 2.2.7

* version: mark 2.2 track stable

* version: mark update critical on all networks

* version: commit cargo lock

* Ping nodes from discovery (#10167)

* snap: fix path in script (#10157)

* snap: fix path in script

* debug, revert me

* fix

* necromancer awk magic

* awk necromancy and path fixing

* working track selection

* Fix _cannot recursively call into `Core`_ issue (#10144)

* Change igd to github:maufl/rust-igd

* Run `igd::search_gateway_from_timeout` from own thread

* Handle the case for contract creation on an empty but exist account with storage items (#10065)

* Add is_base_storage_root_unchanged

* Fix compile, use a shortcut for check, and remove ignored tests

* Add a warn!

* Update ethereum/tests to v6.0.0-beta.2

* grumble: use {:#x} instead of 0x{:x}

Co-Authored-By: sorpaas <accounts@that.world>

* version: bump fork blocks for kovan and foundation (#10186)

* pull constantinople on ethereum network (#10189)

* ethcore: pull constantinople on ethereum network

* version: mark update as critical

* ethcore: remove constantinople alltogether from chain spec

* version: revert fork block for ethereum
2019-01-15 22:25:31 +01:00
Afri Schoedon
e9396e158b beta backports v2.2.6 (#10113)
* version: bump beta to v2.2.6

* Update pwasm-utils to 0.6.1 (#10134)

* version: mark upgrade critical on kovan

* Identity fix (#10128)

* fix #10125

fix service transaction version detection if --identity is enabled, change test to match how --identity actually works

* fix wrong var

* get the index of  v, not /

* idx, not idx.len()

* Update ethcore/sync/src/chain/propagator.rs

Co-Authored-By: joshua-mir <43032097+joshua-mir@users.noreply.github.com>

* Update ethcore/sync/src/chain/propagator.rs

Co-Authored-By: joshua-mir <43032097+joshua-mir@users.noreply.github.com>

* change version prefix to a const

* space

Co-Authored-By: joshua-mir <43032097+joshua-mir@users.noreply.github.com>

* [Hit return to continue]

* ethcore: update hardcoded headers for foundation

* ethcore: update hardcoded headers for ropsten

* ethcore: update hardcoded headers for kovan

* ethcore: use consistant formatting

* ethcore: restore spaces after colon in chain spec

* ethcore: fix bootnodes in chain specs

* ethcore: fix bootnodes in chain specs

* ethcore: enforce newline at the end of chainspecs

* Follow-up to #10105 (#10107)

* HF in POA Sokol (2019-01-04) (#10077)

* HF in POA Sokol (2019-01-04)

https://github.com/poanetwork/poa-chain-spec/pull/91

* Update POA Core bootnodes

* Autogen docs for the "Configuring Parity Ethereum" wiki page. (#10067)

* publish docs changes for autogen config docs

* Update publish-docs.sh

adding an environment variable so js knows not to download git master and just grab the local repo

* Update publish-docs.sh

made some changes making this unnecessary

* fix env variable

env variable passes to node properly now

* use yarn

* test pipeline, revert me

* fix test pipeline, revert me

* change runner tag

* change runner tag 2

* change runner tag

* global git config

* supress upload_files output

* Update .gitlab-ci.yml

reverting testing changes

* Replace tag if exists

Very unlikely to be important/useful

* Autogen docs for the "Configuring Parity Ethereum" wiki page. (#10067)

* publish docs changes for autogen config docs

* Update publish-docs.sh

adding an environment variable so js knows not to download git master and just grab the local repo

* Update publish-docs.sh

made some changes making this unnecessary

* fix env variable

env variable passes to node properly now

* use yarn

* test pipeline, revert me

* fix test pipeline, revert me

* change runner tag

* change runner tag 2

* change runner tag

* global git config

* supress upload_files output

* Update .gitlab-ci.yml

reverting testing changes

* Replace tag if exists

Very unlikely to be important/useful

* finality: dont require chain head to be in the chain (#10054)

* Fill transaction hash on ethGetLog of light client. (#9938)

* Fill transaction hash on ethGetLog of light client. This is enifficient
but we keep align with spec.

* Using better variables names.

* Expose old fast light get log as `parity_getLogsLight`.

* Update rpc/src/v1/helpers/light_fetch.rs

Fix indent.

Co-Authored-By: cheme <emericchevalier.pro@gmail.com>

* Factor common code between light_logs and logs.

* Remove useless check

* Rename parity light logs to 'parity_getLogsNoTransactionHash'.
Fix indent and extra white lines.

* Use vec instead of tree map to avoid inner function.

* better loop

* fix pubsub new_blocks notifications to include all blocks (#9987)

Fix: new blocks notifications sometimes missing in pubsub RPC

Implement new struct to pass to `new_blocks()` with extra parameter - `has_more_blocks_to_import`, which was previously used to determine whether the notification should be sent. Now it's up to each implementation to decide what to do.

Updated all implementations to behave as before, except `eth_pubsub`, which will send notification even when the queue is not empty.

Update tests.

* Revert part of 70a6db7

* HF in POA Core (2019-01-18) - Constantinople (#10155)

https://github.com/poanetwork/poa-chain-spec/pull/100

* ci: re-enable snap publishing (#10142)

* ci: enable snap publishing~

* ci: add publish snap script

* ci: add snapcraft skeleton

* ci: group export statements

* ci: enable snaps on pr branch

* ci: enable snaps on pr branch

* ci: set default BUILD_ARCH

* ci: enable snaps on pr branch

* ci: enable snaps on pr branch

* ci: add libdb to snap

* ci: reinitiate gitlabci

* ci: reinitiate publish-snap script

* ci: fix yaml syntax

* cargo/gitlab env vars

* debug, revert me

* version?

* debug vars

* vars

* vars fix

* vars fix

* revert

* Update scripts/gitlab/publish-snap.sh

Co-Authored-By: 5chdn <5chdn@users.noreply.github.com>

* ci: read track from cargo toml

* Make sure parent block is not in importing queue when importing ancient blocks (#10138)

* Make sure parent block is not in importing queue when importing ancient blocks

* Clear queue when an ancient import fails

* Lock only once in clear

* Add comments why queued check is needed

* Should push the value back to the queue

* Directly check in chain.read()

* Remove extra empty line

* Revert unused verification change
2019-01-09 15:15:57 +01:00
Thibaut Sardan
7fbcdfeed4 Backports for beta 2.2.5 (#10047)
* bump beta to 2.2.5

* Fix empty steps (#9939)

* Don't send empty step twice or empty step then block.

* Perform basic validation of locally sealed blocks.

* Don't include empty step twice.

* Strict empty steps validation (#10041)

* Add two failings tests for strict empty steps.

* Implement strict validation of empty steps.

* ethcore: enable constantinople on ethereum (#10031)

* ethcore: change blockreward to 2e18 for foundation after constantinople

* ethcore: delay diff bomb by 2e6 blocks for foundation after constantinople

* ethcore: enable eip-{145,1014,1052,1283} for foundation after constantinople

* Change test miner max memory to malloc reports. (#10024)

* Fix: test corpus_inaccessible panic (#10019)

If system uptime is less than the duration in the test, thread
will panic due to: 'overflow when subtracting duration from instant'.

Changed duration to 20 seconds to make it unlikely the test will
fail due to this condition.

Since no operations that carry a similar risk of panic occur outside
of the tests, it doesn't seem warranted to depend on an external crate
to fix this.

* Bump crossbeam. (#10048)
2018-12-13 17:52:49 +01:00
78 changed files with 20990 additions and 18944 deletions

View File

@@ -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,27 +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
variables:
CARGO_TARGET: x86_64-unknown-linux-gnu
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
@@ -97,19 +102,83 @@ publish-docker:
script: script:
- scripts/gitlab/publish-docker.sh parity - scripts/gitlab/publish-docker.sh parity
publish-awss3: publish-snap:
stage: publish stage: optional #publish
only: *releaseable_branches only: *releaseable_branches
image: snapcore/snapcraft
variables:
BUILD_ARCH: amd64
cache: {} cache: {}
before_script: *determine_version
dependencies:
- build-linux
tags:
- rust-stable
script:
- scripts/gitlab/publish-snap.sh
allow_failure: true
<<: *collect_artifacts
publish-onnet-update:
stage: publish-onchain
only: *releaseable_branches
cache: {}
dependencies: dependencies:
- build-linux - build-linux
- build-darwin - build-darwin
- build-windows - build-windows
- publish-awss3-release
before_script: *determine_version before_script: *determine_version
script: script:
- scripts/gitlab/publish-awss3.sh - scripts/gitlab/publish-onnet-update.sh
tags: tags:
- shell - 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
only: *releaseable_branches
cache: {}
dependencies:
- build-linux
- build-darwin
- build-windows
variables:
GIT_STRATEGY: none
<<: *s3-before-script
script:
- 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:
- linux-docker
publish-docs: publish-docs:
stage: publish stage: publish
@@ -121,7 +190,7 @@ publish-docs:
script: script:
- scripts/gitlab/publish-docs.sh - scripts/gitlab/publish-docs.sh
tags: tags:
- shell - linux-docker
build-android: build-android:
stage: optional stage: optional
@@ -131,25 +200,7 @@ build-android:
script: script:
- scripts/gitlab/build-unix.sh - scripts/gitlab/build-unix.sh
tags: tags:
- rust-arm - linux-docker
allow_failure: true allow_failure: true
<<: *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

137
Cargo.lock generated
View File

@@ -276,7 +276,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"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)",
"ethjson 0.1.0", "ethjson 0.1.0",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)",
@@ -286,8 +286,26 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam" name = "crossbeam"
version = "0.3.2" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-channel"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
@@ -298,6 +316,15 @@ dependencies = [
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "crossbeam-deque"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
version = "0.6.1" version = "0.6.1"
@@ -334,6 +361,19 @@ dependencies = [
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "crossbeam-epoch"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.2.2" version = "0.2.2"
@@ -347,6 +387,14 @@ name = "crossbeam-utils"
version = "0.5.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crossbeam-utils"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crunchy" name = "crunchy"
version = "0.1.6" version = "0.1.6"
@@ -456,7 +504,7 @@ name = "elastic-array"
version = "0.10.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
] ]
[[package]] [[package]]
@@ -566,7 +614,7 @@ dependencies = [
"bn 0.4.4 (git+https://github.com/paritytech/bn)", "bn 0.4.4 (git+https://github.com/paritytech/bn)",
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0", "common-types 0.1.0",
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (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 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -587,7 +635,7 @@ dependencies = [
"fake-hardware-wallet 0.0.1", "fake-hardware-wallet 0.0.1",
"hardware-wallet 1.12.0", "hardware-wallet 1.12.0",
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"journaldb 0.2.0", "journaldb 0.2.0",
"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)",
@@ -668,7 +716,7 @@ dependencies = [
"fastmap 0.1.0", "fastmap 0.1.0",
"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)",
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.1.1", "keccak-hasher 0.1.1",
@@ -721,7 +769,7 @@ dependencies = [
"ethkey 0.3.0", "ethkey 0.3.0",
"fetch 0.1.0", "fetch 0.1.0",
"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)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -770,6 +818,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)",
@@ -806,7 +855,7 @@ dependencies = [
"ethkey 0.3.0", "ethkey 0.3.0",
"fetch 0.1.0", "fetch 0.1.0",
"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)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -915,7 +964,7 @@ dependencies = [
"ethkey 0.3.0", "ethkey 0.3.0",
"fastmap 0.1.0", "fastmap 0.1.0",
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"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)",
"keccak-hasher 0.1.1", "keccak-hasher 0.1.1",
"kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -939,7 +988,7 @@ dependencies = [
"ethjson 0.1.0", "ethjson 0.1.0",
"ethkey 0.3.0", "ethkey 0.3.0",
"evm 0.1.0", "evm 0.1.0",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1061,7 +1110,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1171,7 +1220,7 @@ name = "fixed-hash"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1198,6 +1247,11 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "fs_extra"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "fuchsia-zircon" name = "fuchsia-zircon"
version = "0.3.3" version = "0.3.3"
@@ -1313,8 +1367,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "heapsize" name = "heapsize"
version = "0.4.2" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/cheme/heapsize.git?branch=ec-macfix#421df390a930cb523a09e5528e6fe57b534b3b26"
dependencies = [ dependencies = [
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -1521,6 +1576,25 @@ name = "itoa"
version = "0.4.3" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "jemalloc-sys"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jemallocator"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.10.2" version = "0.10.2"
@@ -1547,7 +1621,7 @@ dependencies = [
"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)",
"fastmap 0.1.0", "fastmap 0.1.0",
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"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)",
"keccak-hasher 0.1.1", "keccak-hasher 0.1.1",
"kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1874,7 +1948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "memory-cache" name = "memory-cache"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -1889,7 +1963,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -2162,7 +2236,7 @@ version = "1.12.0"
dependencies = [ dependencies = [
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0", "panic_hook 0.1.0",
"parity-ethereum 2.2.4", "parity-ethereum 2.2.10",
] ]
[[package]] [[package]]
@@ -2178,7 +2252,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-ethereum" name = "parity-ethereum"
version = "2.2.4" version = "2.2.10"
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)",
@@ -2227,7 +2301,7 @@ dependencies = [
"parity-rpc-client 1.4.0", "parity-rpc-client 1.4.0",
"parity-runtime 0.1.0", "parity-runtime 0.1.0",
"parity-updater 1.12.0", "parity-updater 1.12.0",
"parity-version 2.2.4", "parity-version 2.2.10",
"parity-whisper 0.1.0", "parity-whisper 0.1.0",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2382,7 +2456,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.2.4", "parity-version 2.2.10",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.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)",
@@ -2479,7 +2553,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.2.4", "parity-version 2.2.10",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2489,7 +2563,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-version" name = "parity-version"
version = "2.2.4" version = "2.2.10"
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)",
@@ -2755,7 +2829,7 @@ dependencies = [
[[package]] [[package]]
name = "pwasm-utils" name = "pwasm-utils"
version = "0.2.2" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3697,7 +3771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -3889,7 +3963,7 @@ dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
"parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pwasm-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0", "vm 0.1.0",
"wasmi 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -4067,13 +4141,17 @@ dependencies = [
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" "checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
"checksum combine 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc1d011beeed29187b8db2ac3925c8dd4d3e87db463dc9d2d2833985388fc5bc" "checksum combine 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc1d011beeed29187b8db2ac3925c8dd4d3e87db463dc9d2d2833985388fc5bc"
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7408247b1b87f480890f28b670c5f8d9a8a4274833433fe74dc0dfd46d33650"
"checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-deque 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7792c4a9b5a4222f654e3728a3dd945aacc24d2c3a1a096ed265d80e4929cb9a"
"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" "checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1"
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" "checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9"
"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
"checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa" "checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa"
@@ -4103,6 +4181,7 @@ dependencies = [
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" "checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb"
"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
@@ -4115,7 +4194,7 @@ dependencies = [
"checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c" "checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c"
"checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" "checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1"
"checksum hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d91261ee336dd046ac7df28306cb297b7a7228bd1ae25e9a57f4ed5e0ab628c7" "checksum hashdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d91261ee336dd046ac7df28306cb297b7a7228bd1ae25e9a57f4ed5e0ab628c7"
"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)" = "<none>"
"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
"checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "<none>" "checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "<none>"
@@ -4137,6 +4216,8 @@ dependencies = [
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3"
"checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1" "checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1"
"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
"checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "<none>" "checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-2.2)" = "<none>"
@@ -4227,7 +4308,7 @@ dependencies = [
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" "checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
"checksum protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "52fbc45bf6709565e44ef31847eb7407b3c3c80af811ee884a04da071dcca12b" "checksum protobuf 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "52fbc45bf6709565e44ef31847eb7407b3c3c80af811ee884a04da071dcca12b"
"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07"
"checksum pwasm-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "90d2b3c5bf24275fc77db6b14ec00a7a085d8ff9d1c4215fb6f6263e8d7b01bc" "checksum pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9135bed7b452e20dbb395a2d519abaf0c46d60e7ecc02daeeab447d29bada1"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"

View File

@@ -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.2.4" version = "2.2.10"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
@@ -137,3 +137,6 @@ members = [
"util/patricia-trie-ethereum", "util/patricia-trie-ethereum",
"util/fastmap", "util/fastmap",
] ]
[patch.crates-io]
heapsize = { git = "https://github.com/cheme/heapsize.git", branch = "ec-macfix" }

View File

@@ -12,7 +12,7 @@ blooms-db = { path = "../util/blooms-db" }
bn = { git = "https://github.com/paritytech/bn", default-features = false } bn = { git = "https://github.com/paritytech/bn", default-features = false }
byteorder = "1.0" byteorder = "1.0"
common-types = { path = "types" } common-types = { path = "types" }
crossbeam = "0.3" crossbeam = "0.4"
ethash = { path = "../ethash" } ethash = { path = "../ethash" }
ethcore-bloom-journal = { path = "../util/bloom" } ethcore-bloom-journal = { path = "../util/bloom" }
parity-bytes = "0.1" parity-bytes = "0.1"

View File

@@ -571,10 +571,10 @@ impl<Cost: CostType> Interpreter<Cost> {
let out_size = self.stack.pop_back(); let out_size = self.stack.pop_back();
// Add stipend (only CALL|CALLCODE when value > 0) // Add stipend (only CALL|CALLCODE when value > 0)
let call_gas = call_gas + value.map_or_else(|| Cost::from(0), |val| match val.is_zero() { let call_gas = call_gas.overflow_add(value.map_or_else(|| Cost::from(0), |val| match val.is_zero() {
false => Cost::from(ext.schedule().call_stipend), false => Cost::from(ext.schedule().call_stipend),
true => Cost::from(0), true => Cost::from(0),
}); })).0;
// Get sender & receive addresses, check if we have balance // Get sender & receive addresses, check if we have balance
let (sender_address, receive_address, has_balance, call_type) = match instruction { let (sender_address, receive_address, has_balance, call_type) = match instruction {

View File

@@ -179,14 +179,15 @@ mod tests {
#[test] #[test]
fn corpus_inaccessible() { fn corpus_inaccessible() {
let mut cache = Cache::new(Default::default(), Duration::from_secs(5 * 3600)); let duration = Duration::from_secs(20);
let mut cache = Cache::new(Default::default(), duration.clone());
cache.set_gas_price_corpus(vec![].into()); cache.set_gas_price_corpus(vec![].into());
assert_eq!(cache.gas_price_corpus(), Some(vec![].into())); assert_eq!(cache.gas_price_corpus(), Some(vec![].into()));
{ {
let corpus_time = &mut cache.corpus.as_mut().unwrap().1; let corpus_time = &mut cache.corpus.as_mut().unwrap().1;
*corpus_time = *corpus_time - Duration::from_secs(6 * 3600); *corpus_time = *corpus_time - duration;
} }
assert!(cache.gas_price_corpus().is_none()); assert!(cache.gas_price_corpus().is_none());
} }

View File

@@ -95,7 +95,7 @@ impl AccountTransactions {
} }
fn next_nonce(&self) -> U256 { fn next_nonce(&self) -> U256 {
self.current.last().map(|last| last.nonce + 1) self.current.last().map(|last| last.nonce.saturating_add(1.into()))
.unwrap_or_else(|| *self.cur_nonce.value()) .unwrap_or_else(|| *self.cur_nonce.value())
} }
@@ -107,7 +107,7 @@ impl AccountTransactions {
while let Some(tx) = self.future.remove(&next_nonce) { while let Some(tx) = self.future.remove(&next_nonce) {
promoted.push(tx.hash); promoted.push(tx.hash);
self.current.push(tx); self.current.push(tx);
next_nonce = next_nonce + 1; next_nonce = next_nonce.saturating_add(1.into());
} }
promoted promoted

View File

@@ -69,7 +69,6 @@ pub use error::{Error, ErrorKind};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::time::Duration;
use ethereum_types::{H128, H256, U256, Address}; use ethereum_types::{H128, H256, U256, Address};
use hash::keccak; use hash::keccak;
use rlp::*; use rlp::*;
@@ -82,7 +81,7 @@ use ethcore::executed::{Executed};
use transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}; use transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction};
use ethcore::{contract_address as ethcore_contract_address}; use ethcore::{contract_address as ethcore_contract_address};
use ethcore::client::{ use ethcore::client::{
Client, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage, BlockId, CallContract Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId, CallContract
}; };
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};
@@ -102,6 +101,12 @@ const INIT_VEC_LEN: usize = 16;
/// Size of nonce cache /// Size of nonce cache
const NONCE_CACHE_SIZE: usize = 128; const NONCE_CACHE_SIZE: usize = 128;
/// Version for the initial private contract wrapper
const INITIAL_PRIVATE_CONTRACT_VER: usize = 1;
/// Version for the private contract notification about private state changes added
const PRIVATE_CONTRACT_WITH_NOTIFICATION_VER: usize = 2;
/// Configurtion for private transaction provider /// Configurtion for private transaction provider
#[derive(Default, PartialEq, Debug, Clone)] #[derive(Default, PartialEq, Debug, Clone)]
pub struct ProviderConfig { pub struct ProviderConfig {
@@ -203,29 +208,29 @@ impl Provider where {
bail!(ErrorKind::BadTransactonType); bail!(ErrorKind::BadTransactonType);
} }
Action::Call(contract) => { Action::Call(contract) => {
let data = signed_transaction.rlp_bytes(); let data = signed_transaction.rlp_bytes();
let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?; let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?;
let private = PrivateTransaction::new(encrypted_transaction, contract); let private = PrivateTransaction::new(encrypted_transaction, contract);
// TODO [ToDr] Using BlockId::Latest is bad here, // TODO [ToDr] Using BlockId::Latest is bad here,
// the block may change in the middle of execution // the block may change in the middle of execution
// causing really weird stuff to happen. // causing really weird stuff to happen.
// We should retrieve hash and stick to that. IMHO // We should retrieve hash and stick to that. IMHO
// best would be to change the API and only allow H256 instead of BlockID // best would be to change the API and only allow H256 instead of BlockID
// in private-tx to avoid such mistakes. // in private-tx to avoid such mistakes.
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest)?; let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest)?;
let private_state = self.execute_private_transaction(BlockId::Latest, &signed_transaction)?; let private_state = self.execute_private_transaction(BlockId::Latest, &signed_transaction)?;
trace!(target: "privatetx", "Private transaction created, encrypted transaction: {:?}, private state: {:?}", private, private_state); trace!(target: "privatetx", "Private transaction created, encrypted transaction: {:?}, private state: {:?}", private, private_state);
let contract_validators = self.get_validators(BlockId::Latest, &contract)?; let contract_validators = self.get_validators(BlockId::Latest, &contract)?;
trace!(target: "privatetx", "Required validators: {:?}", contract_validators); trace!(target: "privatetx", "Required validators: {:?}", contract_validators);
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
trace!(target: "privatetx", "Hashed effective private state for sender: {:?}", private_state_hash); trace!(target: "privatetx", "Hashed effective private state for sender: {:?}", private_state_hash);
self.transactions_for_signing.write().add_transaction(private.hash(), signed_transaction, contract_validators, private_state, contract_nonce)?; self.transactions_for_signing.write().add_transaction(private.hash(), signed_transaction, contract_validators, private_state, contract_nonce)?;
self.broadcast_private_transaction(private.hash(), private.rlp_bytes()); self.broadcast_private_transaction(private.hash(), private.rlp_bytes());
Ok(Receipt { Ok(Receipt {
hash: tx_hash, hash: tx_hash,
contract_address: Some(contract), contract_address: Some(contract),
status_code: 0, status_code: 0,
}) })
} }
} }
} }
@@ -271,27 +276,27 @@ impl Provider where {
let tx_action = transaction.transaction.action.clone(); let tx_action = transaction.transaction.action.clone();
if let Action::Call(contract) = tx_action { if let Action::Call(contract) = tx_action {
// TODO [ToDr] Usage of BlockId::Latest // TODO [ToDr] Usage of BlockId::Latest
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest); let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest);
if let Err(e) = contract_nonce { if let Err(e) = contract_nonce {
bail!("Cannot retrieve contract nonce: {:?}", e); bail!("Cannot retrieve contract nonce: {:?}", e);
} }
let contract_nonce = contract_nonce.expect("Error was checked before"); let contract_nonce = contract_nonce.expect("Error was checked before");
let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction); let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction);
if let Err(e) = private_state { if let Err(e) = private_state {
bail!("Cannot retrieve private state: {:?}", e); bail!("Cannot retrieve private state: {:?}", e);
} }
let private_state = private_state.expect("Error was checked before"); let private_state = private_state.expect("Error was checked before");
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash); trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash);
let password = find_account_password(&self.passwords, &*self.accounts, &validator_account); let password = find_account_password(&self.passwords, &*self.accounts, &validator_account);
let signed_state = self.accounts.sign(validator_account, password, private_state_hash); let signed_state = self.accounts.sign(validator_account, password, private_state_hash);
if let Err(e) = signed_state { if let Err(e) = signed_state {
bail!("Cannot sign the state: {:?}", e); bail!("Cannot sign the state: {:?}", e);
} }
let signed_state = signed_state.expect("Error was checked before"); let signed_state = signed_state.expect("Error was checked before");
let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None); let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None);
trace!(target: "privatetx", "Sending signature for private transaction: {:?}", signed_private_transaction); trace!(target: "privatetx", "Sending signature for private transaction: {:?}", signed_private_transaction);
self.broadcast_signed_private_transaction(signed_private_transaction.hash(), signed_private_transaction.rlp_bytes()); self.broadcast_signed_private_transaction(signed_private_transaction.hash(), signed_private_transaction.rlp_bytes());
} else { } else {
bail!("Incorrect type of action for the transaction"); bail!("Incorrect type of action for the transaction");
} }
@@ -327,7 +332,7 @@ impl Provider where {
let mut signatures = desc.received_signatures.clone(); let mut signatures = desc.received_signatures.clone();
signatures.push(signed_tx.signature()); signatures.push(signed_tx.signature());
let rsv: Vec<Signature> = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect(); let rsv: Vec<Signature> = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect();
//Create public transaction // Create public transaction
let public_tx = self.public_transaction( let public_tx = self.public_transaction(
desc.state.clone(), desc.state.clone(),
&desc.original_transaction, &desc.original_transaction,
@@ -336,7 +341,7 @@ impl Provider where {
desc.original_transaction.gas_price desc.original_transaction.gas_price
)?; )?;
trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx); trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx);
//Sign and add it to the queue // Sign and add it to the queue
let chain_id = desc.original_transaction.chain_id(); let chain_id = desc.original_transaction.chain_id();
let hash = public_tx.hash(chain_id); let hash = public_tx.hash(chain_id);
let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?; let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?;
@@ -350,13 +355,13 @@ impl Provider where {
bail!(err); bail!(err);
} }
} }
//Remove from store for signing // Remove from store for signing
if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) { if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) {
warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err); warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err);
bail!(err); bail!(err);
} }
} else { } else {
//Add signature to the store // Add signature to the store
match self.transactions_for_signing.write().add_signature(&private_hash, signed_tx.signature()) { match self.transactions_for_signing.write().add_signature(&private_hash, signed_tx.signature()) {
Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"), Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"),
Err(err) => { Err(err) => {
@@ -684,12 +689,11 @@ fn find_account_password(passwords: &Vec<Password>, account_provider: &AccountPr
} }
impl ChainNotify for Provider { impl ChainNotify for Provider {
fn new_blocks(&self, imported: Vec<H256>, _invalid: Vec<H256>, _route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) { fn new_blocks(&self, new_blocks: NewBlocks) {
if !imported.is_empty() { if new_blocks.imported.is_empty() || new_blocks.has_more_blocks_to_import { return }
trace!(target: "privatetx", "New blocks imported, try to prune the queue"); trace!(target: "privatetx", "New blocks imported, try to prune the queue");
if let Err(err) = self.process_verification_queue() { if let Err(err) = self.process_verification_queue() {
warn!(target: "privatetx", "Cannot prune private transactions queue. error: {:?}", err); warn!(target: "privatetx", "Cannot prune private transactions queue. error: {:?}", err);
}
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
{ {
"name": "Kovan", "name": "Kovan Testnet",
"dataDir": "kovan", "dataDir": "kovan",
"engine": { "engine": {
"authorityRound": { "authorityRound": {
"params": { "params": {
"stepDuration": "4", "stepDuration": "0x4",
"blockReward": "0x4563918244F40000", "blockReward": "0x4563918244F40000",
"validators" : { "validators" : {
"list": [ "list": [
@@ -19,10 +19,10 @@
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
] ]
}, },
"validateScoreTransition": 4301764, "validateScoreTransition": "0x41a3c4",
"validateStepTransition": 1500000, "validateStepTransition": "0x16e360",
"maximumUncleCountTransition": 5067000, "maximumUncleCountTransition": "0x4d50f8",
"maximumUncleCount": 0 "maximumUncleCount": "0x0"
} }
} }
}, },
@@ -32,24 +32,26 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x2A", "networkID" : "0x2A",
"forkBlock": 4297256, "forkBlock": "0x9766dc",
"forkCanonHash": "0x0a66d93c2f727dca618fabaf70c39b37018c73d78b939d8b11efbbd09034778f", "forkCanonHash": "0xf2fa4bcc417ad374100c2035aa865ff60fb568a83db1b6f6cb8fb52cfebc28b5",
"eip155Transition": 1000000, "eip155Transition": "0xf4240",
"maxCodeSize": 24576, "maxCodeSize": "0x6000",
"maxCodeSizeTransition": 6600000, "maxCodeSizeTransition": "0x64b540",
"validateChainIdTransition": 1000000, "validateChainIdTransition": "0xf4240",
"validateReceiptsTransition" : 1000000, "validateReceiptsTransition": "0xf4240",
"eip140Transition": 5067000, "eip98Transition": "0x0",
"eip211Transition": 5067000, "eip140Transition": "0x4d50f8",
"eip214Transition": 5067000, "eip211Transition": "0x4d50f8",
"eip658Transition": 5067000, "eip214Transition": "0x4d50f8",
"wasmActivationTransition": 6600000, "eip658Transition": "0x4d50f8",
"eip145Transition": 9200000, "wasmActivationTransition": "0x64b540",
"eip1014Transition": 9200000, "eip145Transition": "0x8c6180",
"eip1052Transition": 9200000, "eip1014Transition": "0x8c6180",
"eip1283Transition": 9200000, "eip1052Transition": "0x8c6180",
"kip4Transition": 9200000, "eip1283Transition": "0x8c6180",
"kip6Transition": 9200000 "eip1283DisableTransition": "0x9c7b61",
"kip4Transition": "0x8c6180",
"kip6Transition": "0x8c6180"
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@@ -62,8 +64,8 @@
"gasLimit": "0x5B8D80" "gasLimit": "0x5B8D80"
}, },
"hardcodedSync": { "hardcodedSync": {
"header": "f90247a0434ba1ebe3bc9d9d12886f616afee0eb785dd00d78aa64502045b249c8a3cc33a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940010f94b296a852aaac52ea6c5ac72e03afd032da0d1c1137be913218840c44bdb8f5709a59d8608b05be0dc2401402e11ff1bf2ada0eb50a864e57e19bd4c8499725a6a3841f706ff5d743e64f1d06db903aca62eaba0d4d77727f7253c109e6f048fa5b1583b6c2911ad77f7d59d8947d38a96a67729b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe838ee001837a120083013502845bea4f689fde830200088f5061726974792d457468657265756d86312e32392e30826c698416fa93dab841c80b3e34bacdc91e01f6a76c64a920a65edfea86b84e0fd59c6d8dbd7758f2dc4e3cb446de8dc07f3d8cb71375a6315f401cd1ce54c56694e4e01f7e774555e701", "header": "f90247a0017c9292a6abf6bb9aa48c30f8854dc0e9649bceaf19079b1aac50ebea4fa316a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794007733a1fe69cf3f2cf989f81c7b4cac1693387aa06b81f6633226562f466201f0d097877c903a650f7427aefa7433fb971f601287a0098141509099d91ed2c2e503d43db5b5412d51880994e8e03a86e1d7a9ca8e8ca0495f318f8bfdd4beb517d115ad5d5330aebafe70eb2b1cfb0ab029221a0f48c1b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe83975801837a120083035108845c2c49e49fde830202058f5061726974792d457468657265756d86312e33312e30826c6984170b1279b8413ee0655a59d1f7f8db39c22055c614346450e99965fef62efa43b21b20f0966e3e41eb65fcaf6f9ce3a34359dc064827e06f3a29d2c717f287234785d369e56f00",
"totalDifficulty": "3135776192732436705400032023148164213445066062", "totalDifficulty": "3324635628632492920129912637269655024947201711",
"CHTs": [ "CHTs": [
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac", "0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02", "0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
@@ -4636,19 +4638,379 @@
"0x8b4f8964062d0f00e40a41d21852a2e22abba1f4cf75f594797e368e4df21f7d", "0x8b4f8964062d0f00e40a41d21852a2e22abba1f4cf75f594797e368e4df21f7d",
"0x916993123d91b181d145e2668efed6eae3845fd76d4765df3a04d8adde8c7142", "0x916993123d91b181d145e2668efed6eae3845fd76d4765df3a04d8adde8c7142",
"0x21b91051b5c5fbd22164a655de8485cfc2a9eff58ed09d6fbbb454560898daed", "0x21b91051b5c5fbd22164a655de8485cfc2a9eff58ed09d6fbbb454560898daed",
"0xb52ca76065bcf43f06335977ab87d6c809dcf4e6cdfc452ac2018b77c64089a5" "0xb52ca76065bcf43f06335977ab87d6c809dcf4e6cdfc452ac2018b77c64089a5",
"0x9437d47e7f7fb4c95aacd5e1322a9c7b457888dbfb1e485142cb16ba805b5ded",
"0xb7cb3f7394fef7de5884e165c8441d441c98c1080865b604dd21766759f7fffa",
"0xfaff33c1aae8882f3a9d84678b55b8945b037b1f05785f2874079da71caf4aa5",
"0xe032d77db9e882bfb3d5adc89d9a9812fb9775f98c03765ffdf0c40d0dbf11f8",
"0xc9c4ded5821040df911b23d92d8270fc83164531c9d631c4d8e228a71e189ba1",
"0xa27f4dd47059fdd4afe78ce8c9029c9a7c0916d10cc7dba1ce011c886d2275bb",
"0x6dd0d3b0e07535d8350cb888c75ca355c4abb07bfc6ceba3eae02095324679a0",
"0xee4a3c6125a5e69848457d35f9614705b651c68857b03968bc5420a809d1d9b8",
"0xc14947239d0a7061d796313aca233659059b13740e63f967f8bd4806feb895ff",
"0x36d9ad9d6ad2e1a1aca489524303aaa8534b137c5e9ef708d589b7a75cbf6500",
"0x497c4cf7509b12ebd34d5c0520a24ae1b6e1c5c050bb3412d7d1a702c48d07d3",
"0xac81f9bcce95283b7f188f16eb68d22adb22dc1cff0853739c46f27523a653b7",
"0x2f0818ee594d2d1fbfe9a6a03cf4ae08dee69fbb9c289c2789d792f14a3e4e7d",
"0x9beb888d86489512a9d1d8d6461490e23599c1595aa5b4d4b113d18c0eb99697",
"0x7708aa2a88f9b41cde9f338da6d2f9dde2b57f1538f7aeefb66a0e9dce488ff3",
"0x548a59ae0782fc5202431a472a8dc5e21ac83b68dc88afb2b0afd56cd3e880dc",
"0x271397f861034f73fe228e3921d835a313041c260a6c2ca3d0c28d407d17ba89",
"0x732b95d3ebdf035182863a540bc002cef70f98b91f90ee8dcef2285a970ade6b",
"0x605d419ecbcdaa05d6f09c9734469847f52164df26417d7807f959986b843869",
"0xdc56e2800a637475662632ac37e9eec90d9f3962a454d6f32ee7f56426ab9f42",
"0xdcd35988aa6982f14b3a2834f841c755ad42dcc61eb0dc6122f2aa9db65fcf92",
"0x659b06e2aa0359e3743f59d2b128cf85bfabc20ac9d8c42a89d9cdda2bef7697",
"0x45377222c3910f95b3f5d0adef823dc4184189cab9eed54b9997d2b30fdbae43",
"0x15d66d0b9347f12bf9c408910edf41623f460244f309076d55cf969dc158b36e",
"0xe5de2158113351c0ea314eb12b28f9502c307decf883ed480c53c1310c9f7c11",
"0xc7342c08dd73fbe5801cc6c8764c53f924d6a77cd5a5b8bdbb22d2b6d3e0336e",
"0xf10486dc44a10f7eec6739dd56e0f7519507777e78e3974d974ee0bd931f03d0",
"0x5985752f0b3849e9cc6a5d38b65617be10b52b8fd0c2642c328b864d59a23f9f",
"0xce899213bc8a178cbf2a8eb86f045f59895530b0af5e209b60553869000070f4",
"0x724dd7b5e5d0e93017a62faffd534e423610c494ef0b5689304bc80a68df0e46",
"0x318073daf925850c412d6a1f2db2d2093268896a88c49e822ccae4070b406408",
"0x74fd03921ea801d4618fa7c2375c4369a15c7774564dfb0373b5913bdc9a6df8",
"0xb10896436461c2660cfe36a60c433b32ef8a1e772f3f9c16ae243840a1aa3aa8",
"0xecfc10478a368b186e4299447ec9d3ce27ca8386274c545f3edac3608ad6cd0d",
"0x288c697b29a0d2c5d45b9507aaf62bc4bfecca1b34e1a5ce13a17711af0df3cd",
"0x429fc79b89ad00887096417282a571de77fe73dbfd1564c13bec5830b38890cd",
"0x4d859982815d597e31d0e5374d7077b59a4b9beec01040608bad05c6a9d0be2a",
"0x1addc6e300b6120cd196bcb7340ca163879ac55f7c9069be77947aa01e778cf9",
"0x2e648a4eefda9d35e26b148028a0b336ef7d75809454e36795edb9d3fdeff550",
"0x814e65df8c720e8c9c7d64c76b6b9554328d6c780b5f3dff96aa3e29506e7e49",
"0x4841c38f2a920bb1a072b9a7853dd7d2e44dcbc35e2737aa2f3cf6652dabfdd2",
"0xdc63afe7974211db82b2602c26d6ace8d93f34736c0fa68eac3bd5d2c1af7484",
"0x2052d12d3534c5d7693d420c8e080bcee99ce10ccebc7451272b7ef08f8a3dc2",
"0x4985769df508ccc2add583d187095a8af4ca73a5be2506a506146e23dbc67d55",
"0x4a6744d48fc2d85cc99e419483ec1111ccb6fc7ab13e4eba28a29269acb30952",
"0x527b0514dd83336c0524add1f01799512517378b2045c4ed43ccc0e977553bac",
"0xfc33e6a20033fff41a9b885dc5bbaa848a0f244fe89b4a1af261d382c544fbaa",
"0xadce691a1b4224bd56682784ec106dc93af89185721db8b427eab6b0ff22776c",
"0x0fdef2a9525541c1e96172c8a33ccc08ed759dc024d437b82126ff03b65e1684",
"0x7aa9e8c1e9da3c68080f099281b367de26838ec7bcd474590ae101fcd68a7116",
"0x7eb70f0a4c42726f5b3a67ab12bdf5b4e6bf5e4c347b6c32f6fd3a04c4a003e5",
"0x546f5f3c2e44b7a61d6d0dafd802fcc114db7acb7f887f0dd0b1878979fd3eac",
"0x5c5294fd77081b1a23037c34170b568358011be2fdc0e3ffa2230b1a017ec5b9",
"0x6c854d3de1f2a28dd8f6320a534b915b032078377e3b880eaa8e9a3775768e2c",
"0xc2be1a4c7a5351063084c5907f19e63f25e048f3e27648a6d9056d3d4b635c19",
"0x5d0673ecaecd00cc8847827bbda1dd7bb21f537e5e10f10d8b5944496b55e9e6",
"0x8a1bfbf9dd51b727c17e8920019caae599f53d37563935c584c84cbdebf942e2",
"0x75649056bcd2a520811d8f9d5c0c629f492e93fcdcd298c0657a8c857fdf2cc6",
"0x71421a3eb42eeba485fb90918511b0a430311856c27a968e52096c6cdaf0cce1",
"0xdf19c2d595ec81bacaabd39217e100e6731f8bd7c3d6c5bfd987b27f89be146d",
"0x573839677ae138670609c499107217fcae5de5fa9905c78a21b07f7a906a0a53",
"0x1e8db73865049c1cde4004c2a60945edd9ce9847c360a2feb36205e1f1cbd5da",
"0x52a602e7c2f462a39288465c733d2133b7f77a7a77d7e60e214d4d4eff917258",
"0xdc30b1767c78f2ac953c5046e6440b7de488933cdece18fa3566f00d8a96c92f",
"0xfc0baf76004e7d87b36ea52de7d886c9b3be44bb8063549bba31b63b87ac3f92",
"0x3426c56db720ccd184f2e49385e96e5a37fd378cd486de8fadcc7d5e727aebb8",
"0x39fc1cbf20cab093c75b42931fc6371e9851cc4357badb6961359e07b9d97fca",
"0x6b3725ada81d881bbe245d4b55c7be12926b42d0e58dfc8fa38d54f68ff79ee4",
"0x69bbab0d123bbf03499984698c162f9dfb81375f6bf9f2e643badcc8e0281ef8",
"0x101cf365b31d4b37910433ffa265e1a978d4f80c478936809e1bcca7baff59b1",
"0x65d26a27a34ca4ca98c2b5f609e4596344514698f2137547e815dfcf91f5bb36",
"0x3b8598589a6ef43efe0b7a64832360ab02e150c4b4ec02f2a028d2522f4c0ba7",
"0xd8776563bb522b42a25cb2714f9ea294fffa4c4fb5ad040a9458e10637861f34",
"0xb1b85b8c9bea99a2bde16ab99b2d7e42571ba15dfeaf28a2897322bb444171b1",
"0x803cc4e5c23bd3842736b36a425364416dc69a3efb95f3c7fdbf7782d6de7edc",
"0xf5803ed2a130a19600ca887ad06813482b678ac0eee049cbb2e56e39a90d9867",
"0xd3f6125b061023531cbd3d625c9382631e2fecc75945dd6f78f883353ec98962",
"0x7b1d59f8c9869a9c73a09385c82762b86fcc995e75db00bda388e1423be19df4",
"0x2b7a8289bf9f93c589866af1a224c34943433b6a5a571df7dc4524bcf2adde42",
"0x9199d73dd306fc9038b36212c3ed7706d8b0f30cfcf3359408a8e6fd8ebab0a7",
"0x0cc8446d21ccc31bee04addd48b50f394390ef3340745555f9d7ccc3c13eefbe",
"0x80052b2097d7f836090ba9f94ad7c33066453d8ee62a2e215a82003ed92568f1",
"0x231c2d4e6a6039342ac03f766fac9f0a587ef6828d071e63a1e3f660fff13263",
"0xcfa0cae426e4b6b9422d72a687d50139654fc3351993b5d38ea4fc6f8944e662",
"0x9dc837a60a2c18493fd3b40083996f18a44f37a7a762ca649bc5d8c8b272aaca",
"0x30b4651c3496efed5997116b7a12f9cdc24040a4e110478f1a2330fbba48fbec",
"0x99567d98d73fe92c81c69aa465bd62b02492839519f0380686349da64caaf758",
"0x9618fd333f89357a22bb3101cc386003c2745f8a24b5affd2be9cc3c26a93e34",
"0xe539d1a4de2a57dd65cea42302fac83aed570f2fd7a318c6d226dea58d5f94c1",
"0xe69e3ef5d9d8cf08d3a354da7179d5bab9c68b4b6ea6a7e5a58cae9d901b5f35",
"0x97cd995441161fe4f50a339c6323020db6f56b9221b549194a93b9895a043e59",
"0x803e04ee8a22299e779491a6749b7d57973a59fe714d080f03749bccde30d5c6",
"0xace95a4dc00b3fef757aa76445b1edc582246eeebb7c2bdc71fa648e06428485",
"0x1c8bd27b857dd8dd5a671fb4aa6cec3c41ca1c747c9f86edca8f389ac637e09f",
"0x554b4d1bbe92718dd1aba2a9d10f48f803287d2c26108bf3cab2574a91375511",
"0xd5856bc0794ddc23049639fc438c360d66e4b3eb1f96516ba0c02c46cda8fb49",
"0x25a4c78e490c1d5fc6c1252b2ba13ca9ad5113a5c64e02220969146c5bbe9730",
"0xa8dd024efc7f03b61ff9926421107b54c42f5f9c936d956e9b6c6eb36f9b242b",
"0x26d488bff06eff3fe1912ce985ced65325e09e1c01a95bc16d0df22481690640",
"0x01b89e65f1a82ea7e456e96e2ddf29be42dced7c7ea9b12e841bd973506dcc25",
"0xf0f5d3392e3fb73697e44755d38c84bd99394ec2ef9dec841049baf8166e6d55",
"0x91c4f65d698130b132d0a33e44c27ea55f477cfb134224139ba0264b5737ed42",
"0x1d2295b21e1bb810d35471fe17adc80e59c6c57b5037de90c88e99021ac78b24",
"0x667cc89337d382967727f0740819a2f6298dd5f2b7b5e82dc45e3f1c15c5e998",
"0x908ac480019af2d3c3017c413077a73905e27ec01721aa499c24fa7e13bf8ad9",
"0xbeb7ebf8ffae71221e5ff149e3333fdefe6b11780d439b45a874129b2c25d71d",
"0x235c2ed0e3fd286df5cabca5f0f61bfe356ad0d7c8bb9c642814d01f2fd26699",
"0x22fc5189fb1945ae98d89e50b258514baaf525e8137e9581c99339e1097e33c1",
"0x148256253b74711fc61f8af7d4efcf8694752426715a0a4c788556feb68c1a2d",
"0x26ad59543cfd91bbe37cd8fd1995b81d0f095ac4e02cda0b4f5f40c9db6d320f",
"0xee340b0f25450c23a5c9b16cd5aa59657a9992c1c341172bcc8c9038eb6789fe",
"0x5da22a0b434f041d76be1d53ef63ae24031861dce1ff4baa3511d67664060bbd",
"0x6009815cd4da0162884d0be4cfe6936f1b251f50e9c89d9fdc2f0af430012e11",
"0x9342474f10ce871dfeb70fde89b181075b18e973d4806364d52f83f6be4d69f1",
"0x3c4c598faaf3c9fa8b9c1bf856872e65e3d53435177992b29a7674198e7df000",
"0xdf0d952cca28797dbb503cb8c7192e811a7dfc0797379391f839341e210078ee",
"0xdd48052c8e9a9ec62a58a580abe1c420b89393bfffe53fbe6b7f9079b5ec4d3c",
"0x028846c41592546d1d11375d00c1d10a18c06ee5f968b2ce8e8c42bee7aa263d",
"0x4aa08dc77484d15f8423a1fb2df0fb0c67729de1d48e61831884e49d7697674d",
"0x084c72f0f0fb1cdd4ff80ebc9379c9d29c8d1e35cc45901a67b231ac201ff9b4",
"0xe904eec627d475fcb3e61b2db0366a24ebcc286ccda2b1614049fa17ae9a9d85",
"0xc3fb5ed46f30f566b1d5547d5e00c4c999960dcbd1b60f0b337bff8da30c054d",
"0x1503b399ce9dd9f1cd8005036006e4bae2b3f05fbb1393b8f5d868332605c98b",
"0x70de442d35565513b92d8cdb95c6537f72d7e099e217af7c260fdf92499ecfae",
"0xc6b86174c627fdb002d187feada8c72b9bc6b1fa5d11785988c72b06480ef1c8",
"0x06212692407b9b701ed1b115a8ae1cf07668cd7498cbd7c5c58e9b52a0a0093e",
"0xfdc722f761f07d5c52d36c147ab8e80a666af5aa77fdefa37e86c7b2518aca12",
"0x7396bd40c5677c5f4388d956ec437071cd4352cac44b7b97eecebb6c5c99b507",
"0xf634b80145415b2086d4a20746bef5c7d34034ac6601487792889be39bac54c8",
"0xfb8cbee41b441d5424cbd12b064b04f5618f0b360b1c2ae5ffb90a0194e61106",
"0xf77c56810755fe69822c1250295092fb8e7c88d789706d6769d0cbdeb386137b",
"0x9e0f084e1184804e850784a4e376b8acbf58f4235a3829d49217c888e4e5d535",
"0x6b39d6de64090febb49dc6f6a31eb606d8e278b7ff4fa9e1a9774d3d9dc71f81",
"0xb5d9e67fd6cdd93c74536e5a74dac8eb8ea6914c2315c22e079d61eaecb18c29",
"0xac3dbb4fa1da752bff5884154e02ab975e993201e69ef9ca532c8b1e00b1628b",
"0x747b42a7005c41ae222f8c2ecd4bf7000c274366237e68b2e95a64cef3799ef2",
"0x8f06b121d921274a0d8da269d19ffd6a417cec988f0018647966960ac822fd60",
"0x13451d3ecba978d3c0d88c2dd4068cf060e949889ea514306c23a7a1ec574ca2",
"0x737f8bd85cce3a392da15c8e68c3ea9748a6523ab92dba8d1c6c8081311c3ef7",
"0x83cca9d97f8c4b2776b96d887c5ab1e8e6172970d6d237da98dd5c6ce07db7f3",
"0xb5bb3dd88ecfe2e4ac4e4be2b605cc7c5e79024782628a95df33c4967dc8251a",
"0x640c6050e63c965742cdfc6d3217eca459a24b3acf3a5ec64eed9bd7bbcefaad",
"0xe74478890f186d41b5157dbcef1f2754a35a5af332095dd25d34caf01580062c",
"0xfaabbc9703e049e49d1d22da051cfe6cae0697e7e728e954bd5abc40d0e2014c",
"0x8aa4a19c4ec50a68a6541ecc11d4473cf02773a0ba7bb4012ccd76ae11ce8bf9",
"0x01abdedb1886ec8220a4f6ce6a43863ab77215f03e8116b03f3efe44bee658b7",
"0x18e44060426a05d3d9500b7d6ae6d99133109bac39942ab825ae81c551c0ef39",
"0x19a60001bc92289e73d3a8320f7601eae1bcf70f65c3a43ff6af1b2c2c17355f",
"0x2dbc82c8ba30fe69aa00c7abf129cd1a65e8fb9398b2ebca0843e526e001ce1b",
"0xec773bb4cf7d35feb70ea19cb53cd64af2cd34c1e4f1e282bd3cd0b39720bd2e",
"0xc966e10e5568661e0930bbff1561e2de413f9f89d984b46224ced75d57213401",
"0x29658e4a7e4dec3e9a449902af34ab93fe760c6a1695c1a97e0a093e3d187782",
"0x98b0b147d3f6a8a21dd9e3fe01082dc9031c193dec4def76e53ad1c13269c3d7",
"0x288b646ad44d5f4ea299917a9b69c9c07b5ddc50e93d03fc1c1ed653599d7a7d",
"0x87c26362fb801ef77354375eadedc1489a4fc39401521cb06b604fd9288e4d82",
"0xa5cf4098a62d2dcc87e589c8269dc712e2ac2be5adf07ca33c520556d4da0cc1",
"0x4f253c49f87e135e4a0941409fe70ec6b29f6b0d9aed3f654f5eee7f4eb0a486",
"0x5370ae8dfa2a982dab86dfb45950a50ffd29039781b2b065ef5057f7b43b84d2",
"0x044f950f82d97f0fa164ec4174c238203d15f4cf32dd739931c3e291e0902ed4",
"0x792c3af8c8808b95f38d6e21979450e3ebeae129f0a9a9d0cf2951252801dd7d",
"0x141e09e2ca0a96d50e7c12aae794ed0f22c0441fcc51d1c4e179f891cb06ee1e",
"0xc475b7c5293efed9c9f0a5e1d8800e4dd10810bc7dd33c406da131b15524ee48",
"0x0018d2c2e814bff6fa8f5e162de402db71dd9eea45d320f60e280a00aadafc2a",
"0xc68336fc8904777bf8ec4d5a61f79f2e847c028889bce39ae0f307d11efad818",
"0xd6439bee30ae288496a022e04f5c21b9b047edbb370ea3e33ed236a217c6ca0c",
"0x03e096d6ce43823e4543ddbfd8f55528d49c38b5c701c520e95a51547b5b193b",
"0xfb80f18124198c12b6359ea7805f110f9f25a6686e7a917c110ad511554e634b",
"0xcf9a0aa896f5c54982a827e07314a81b58beb3de97fdf112ee1539ee47158f59",
"0x948cb5dcc88a5502d82a292e7337d5d010055ae4964c09b2c6d55b0401e1781b",
"0xb91614b49ef967aef3b113983cea703a60097e0cd4c0d9cf1ad6f36d594750a9",
"0xe29abd32597fbfcffb8d185931986a8519fcabca73abfc5be6e42bc8b6439374",
"0x9ebbe1b1037327c4f2f3c9b6191b6f28aaf9b04dc58f3314ec2c16ac1eaba9b7",
"0x098529aee4331ef9ee00ee624912ed1a7cd8d63ebf27a96059f56e60ab9a95b2",
"0xcab9578772277f3e1f7a6920b96df6ce3e6d7f60c42925b7bb1ac1d71d733718",
"0x43cb7ebd27e7207228ecee10cfb11aefe077bf03053877b53c42a41e4f39f607",
"0x12ef0a09e0f5dc9d89b01cfd66b34182e80821f0f9d86c80327086a9960ab9f8",
"0x30bafa474c54d2912897a13911cd1df20988be102333bcb9fc54905789f87718",
"0x383205a3e0b07e359127b28c3ad1b451564091893edc87d3d92e081111dd20e7",
"0x74382d6b160ac8b1e7b86abf22cb943b43afc4480be4b09c87c8b796f22eafe9",
"0xe84cbe2ed5a30d7b25ec540b1934577387626fb894e4248c719d417ff1b0f171",
"0x068dd7e31af946d3427dd6822c22577886c32a7f1e3a3bc61ee061be7c456751",
"0xff5309cf09f24f3666205ae09e542634bb848c47031ebc10079d96819095b60a",
"0x82991fe8d442572aafde5e2f6d2c0ba0823ae72110c2f4b65a0d39244db460a0",
"0xb86d9c8e378420595feae0f728e00736f5b72ffe37e289088c03235b3ae8f556",
"0xd678cbfb25960efc5a64d48f2ada784a5b43123da5db8636804c2ab7d1a6cc36",
"0x1ceacf6ae9acb6e7438e6971b133aa7a8ba7b648c130962c3f60b7449266f3ff",
"0xe81d2bbf5efd047428040f86caa351a8785a0ee864e74760569318c997b25116",
"0xde530285d36c4a50d0f91d48a42e9b85de919e51246b6aa54a55eb2041b17289",
"0xd5b86ba5c24729d199007133a8000314476135cc5b84dbc49de41a7d9f3060c7",
"0x95b2fc8a95f67d4d67cba712a98bb3b35fc4b92581f5eab9e737f2555592bf3d",
"0x9808b933e2c732a2b4d6229467430cd73715ac93d1000c470dbe403d0f14b6ce",
"0x8a708bd8ec41b6aeb1f822ed4892c4d685ae3fd1a752a0b79a10a6cf288c8a26",
"0x689c7f32af0a20de771b9c03efeb6304b08a421cbc2f178b63cd284f3d74407f",
"0x0375180a004265f4a38946353455c221785c3f6da1dcbde2c09c373fa42c434c",
"0x764f8f063124e8226a65af4823b260354924781b339a93f6eeb0622e10333741",
"0xd0a28ce8c50017ad2e0bf1c1f8193792228b879688f01354552e656272bd7936",
"0x20b12fa78b655cce826e87bd18cf938917d37c306cb620afef671b0548b1e1d0",
"0xc94540910d93236aff53413af46597dcb51c02508f14bf81817966ef32799c00",
"0xeeda2d6df1baa5dd3cf904c4402e4e99aaaaa16b6f3a0832bffad5492fd9e725",
"0x74de84a1158dfb1af0c1478cf0b048ae8b0ae00139588e91d37a6874b524522b",
"0xe9c92a1b7b298d7222890fffbd5ae4d2f8a8e0c5519cd06c3e34fd94b1f12767",
"0x18261f839aab59220f72e4e4bfa7a8dde2d3c5cd8c0179d2ff32a151f7af92c2",
"0x35fd53473534a3bdbf0ada29529991bfe6ac1865cc6786306b92dc26a6aa8116",
"0x6f40f093a08a00eefae4cb848462ba663b62f089005acb49a8f5ee3f1a767375",
"0xb0d49e32ac2ddef6bf0729ce9212c4bcc053aaa7cf8dd6649247749bab68cfac",
"0xb616c68f680b5cc9be3fc5bca40621514109dbc1316b848f1f3ce18b05e76d33",
"0x3ac8fe2f016f98eaa25451e36ce4fcfcbd160c0306c57f2edea049cdf541538a",
"0xb45e54eca70d4943eecaebfef3dc2219e79bdc71bddaec6adf53a1d058a65a30",
"0x74284120c5fa1ddcb7c294533eedd0b1ca2703626b7361543cb8e2a922177aae",
"0x8b15208a8b5d6ddfbe8b09148d497a5e3fc267b8f1d24272814d72f4826f8e88",
"0x3f9d4dcd96d5c902d4ef5655c10620c3e5a25edfa6fa093b0546d05c7c724d8c",
"0xf91ef06068659865a7c94e955f9c01ba4794214ebab33c9ec7030b2dfa47604a",
"0xadd5bb3d2f06ada2edb35754833e1bf1e317edff3e33535e135e67b4e4c5fdca",
"0x5aeb51beab2c98d3f77f2f04a39c2dfaed3ff759de9f5c16d4d88692a95eca60",
"0xeab1ab2c49609df8e29041ffefea082f92941aefae697fd915b9aeee8665c57b",
"0xbcf847e97f7f6fa5a16075ea54a67254e21fadeaa38d7aa42d16f223fd179faa",
"0x07f25413e56e9dfbd9bedf4b0676755f0cdbbf10b8f13ac7ef360bef7ac905d1",
"0x373e2f4dca323c9c4b4cd0cf4a1eb04ce7fd4d7548078200d9ffde2e3fa4cee7",
"0x5b9fd47a0d9cb386ccdcb2755934bfb8b27be896e52afaf18a0d130bcdff5432",
"0x1050a77797e0fc3a98c1d172496b8a3bbb2b045ebaa6b8b4af4e1542180f464c",
"0xea29629a5b08050c92412a25506d4d6dd8ea0f6bd8c962422d8f4913090a6d2c",
"0x1cc76b2b9f505bc358df15e285ac7cdde0009a2a19de9fcb5a44156ff76c5585",
"0x03cbbc18173700023643a8d6d7ff57cb0503336794c5fbe0b705a95034b7af80",
"0x9e2a5b70615a5c057d2956ac21838616ffd5cfb26fdf7398c4ad988a8cbc27ed",
"0xb2ef5e7c15e169ad2ec00e254415f4fa6c1f0635f728a98724dca4335e1c7801",
"0x50f9e432ed8c0c999685735ad95a4c2b3e0c0002d1159056392ed541ddca9b11",
"0x40ecd3140c4c8b02ce66489b39842d92ca64d05c30a9eddbfe675dded3fb6f3f",
"0xa1417d5ef7d185323ae3452fd99d54d5336f69ff866cfba06838da5efe273ebc",
"0x93b51cb9e7c9ca4e5f67fae55992ef6b0869c8c2effc8d244791cd2275f5f136",
"0xd9889fbd8c71e14316b5dfd46a6d049ec05127e5d3db6f0a31a935cb86b42d0f",
"0x384e1275612d71431d80d155015010e22b8b14a0648328bf1b32f92b1673308b",
"0x5eeac9b703836463fc0019c1b6f4be32282f4ade6778f897f6cf9d4c33e16085",
"0x2bdd040915ac28a0a604b727f062cf49fd413c44bcfaa2cc5eaaa9224248ef51",
"0xd7c85280a461c43df6c82f6ef60a973f2581c428394996191eeaa0d06a4b6473",
"0xe57d7c71a989601a066f8447a5be928ad0ce47d5413eceb709761654a30667e4",
"0xe1514ee44d1db8307cc08177a343887b5bd843cc510c5153b7f251aa10704f87",
"0x2898a69c885bb4cfcffa45a8aa63a8e81a40d4e3a7e1ff218ca3b4c70b836e08",
"0x27b66b51bb80e11582319b2fe176490daff05f0ce72a9dbfe79691676a455e0c",
"0x321d7bade5b8a1adee64bb0362620d99a5528831cdc0f1bd0258c9d66e4515f1",
"0x0a5443109753ff0845752dc998e82148d1de44d8347e51accd03cdbdcf405acd",
"0x1ef3a558361ee68b83346d40624b13d3170519e10dd18f60b6c5d7804f3c2d1b",
"0xf81fadde2aa798e6c151b35f764009d754f01aa0d8dacdd1a8f3109bd5d711d7",
"0x1af5b4d637429fab034b33b5fb3add567b5896608bcdc9e8d86a7d7ce762b4c2",
"0x8dcae50013fcabdc708c7b99c46fb4a68c75971775c135b7f7727bdf8db645a2",
"0x74dd3719b6229c2f675e41bae47aa0de9587608e8ad76e9dd911d695cbe3727a",
"0xca02fb569c275518e1cb95018a3b67dde118e82ade5cc9a43e118afa8da5e3d4",
"0xd5a890bef2beb2920a7ac22be90d0ed203dcf6b37ed0b3d2cea1fcc8f68c6d98",
"0x917c9cc04ac1f8afae96f0dc9b49161c352ed4e1da970e17d52fca31b8c1978a",
"0x009f16eb012717beb87fcc2b4417c8096a621fddc2421d02d84d0bfe92cd3587",
"0xe5ff9e2a1ffbcf1f53cf716b7caaa1317151ed8b81bd641bcf41eeadcdb0790f",
"0x2dfd67dc149772d4aa52588315df62edbc8a9340f2b3afb367f7f1564c1b8503",
"0x830df571a176933f6a72ac634933d61e602f744d1e3a046b7b639c9d2110580c",
"0xb2a030fd70ad2290c69e9b41220c14800d9adc33d7f8af049120fc6526a654d4",
"0x8a013c2432c60aa6315b1adc7155dd022df24129106cccbdf463273051ee0efc",
"0x55040dc6b554877d752f2f0bf0d97f71b34583b3d939587106affdacaf5d7c0a",
"0x251817e5c81aba6d675d47d688f19d5cb6957cea13ef3e15c66a6573b84af432",
"0x708cc1d141308870ea3ac36e5781cbfa3b5af327c565231123496354b5a9e74b",
"0x4efb2006e58b45c648d27654d45f1f797d4798217b2d0b54958fc576f115d81c",
"0x7d1bc87fd32a1b2ce74fe3784be5c0fe2e625ceac523ad55da7ebcd3cd1cb94f",
"0x575cc8bf8070ea53a54d027cb7d42eec9dffb85489013634350a96a434cb498b",
"0xc69812969e85bcd2e7e048b4323a726691c78d1902c1f1dbdd3893c11b9df8f6",
"0x6193928c0a4e47c9409c1af5d945a8c92c9e28a76570dfaaecfdda8071d6558d",
"0xb8982114b6b5da8849c27ee7d23280e15aa780248ebd36e5d364f2a05ae1fe45",
"0x49577950e5a3d4a06629686f9353adecdad6670fc9f4e6d3eaf6735296cc6775",
"0x6444155176ebe3b62f028ad79f058271d5b317360c0b97b7fe8c2a642da88229",
"0x9a3f0adf9c7b9380f60baf1d524590bec23b4d3790b3909ec8da3e79303252c7",
"0x591f122777ae7a313b6c4ba8c052d483f2aa3a687b5d85ed39e19d7e0c0e6de2",
"0xe3d68466d0747ab6245e5d8620eaae080a0f3c2aa34a56defe8adaef56d5474a",
"0x8d0f53bb5f7610133f04a763263815e092e43b0016369866e959d22eca466d85",
"0x8c8f0fff76977593112a64826f15ec0e909d9a1f1589e121a37f73d881e6b696",
"0x9ab1411e7ef5b295ab1a9dfe4ee1cd1a740af5b7e4b0a0e9c4a5f37e803c7c94"
] ]
}, },
"accounts": { "accounts": {
"0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, "0x0000000000000000000000000000000000000001": {
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "balance": "0x1",
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "builtin": {
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "name": "ecrecover",
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 5067000, "pricing": { "modexp": { "divisor": 20 } } } }, "pricing": {
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 5067000, "pricing": { "linear": { "base": 500, "word": 0 } } } }, "linear": {
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 5067000, "pricing": { "linear": { "base": 40000, "word": 0 } } } }, "base": 3000,
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 5067000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }, "word": 0
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" } }
}
}
},
"0x0000000000000000000000000000000000000002": {
"balance": "0x1",
"builtin": {
"name": "sha256",
"pricing": {
"linear": {
"base": 60,
"word": 12
}
}
}
},
"0x0000000000000000000000000000000000000003": {
"balance": "0x1",
"builtin": {
"name": "ripemd160",
"pricing": {
"linear": {
"base": 600,
"word": 120
}
}
}
},
"0x0000000000000000000000000000000000000004": {
"balance": "0x1",
"builtin": {
"name": "identity",
"pricing": {
"linear": {
"base": 15,
"word": 3
}
}
}
},
"0x0000000000000000000000000000000000000005": {
"builtin": {
"name": "modexp",
"activate_at": "0x4d50f8",
"pricing": {
"modexp": {
"divisor": 20
}
}
}
},
"0x0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x4d50f8",
"pricing": {
"linear": {
"base": 500,
"word": 0
}
}
}
},
"0x0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x4d50f8",
"pricing": {
"linear": {
"base": 40000,
"word": 0
}
}
}
},
"0x0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x4d50f8",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
}
}
}
},
"0x00521965e7bd230323c423d96c657db5b79d099f": {
"balance": "1606938044258990275541962092341162602522202993782792835301376"
}
}, },
"nodes": [ "nodes": [
"enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303", "enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303",

View File

@@ -50,12 +50,10 @@
"enode://6e3d1b39cbd2a9c4f053a27e68fd90d0bac83691dfdc4a13c59f2555078a71e63c5daaee5a82aa6db500512760a5456f86076bf8bbe8011c27c82ed7d6f5fb26@45.77.140.210:30303", "enode://6e3d1b39cbd2a9c4f053a27e68fd90d0bac83691dfdc4a13c59f2555078a71e63c5daaee5a82aa6db500512760a5456f86076bf8bbe8011c27c82ed7d6f5fb26@45.77.140.210:30303",
"enode://f4698ad485a027497e1cc992bb5f7cecee2b32a44c47202738d8d0eecfab719541988d0cbcbc5ea94c6c959e5cddeb85fc6ae75fb63dc3bf87cdbe9e6f615e9d@206.156.242.64:30303", "enode://f4698ad485a027497e1cc992bb5f7cecee2b32a44c47202738d8d0eecfab719541988d0cbcbc5ea94c6c959e5cddeb85fc6ae75fb63dc3bf87cdbe9e6f615e9d@206.156.242.64:30303",
"enode://31dffed97f8fed1f34fe66453280a89cbeeda60cf28f6fbb212ebbefd7c7566a02c1c7d5c00bbbb49b9fa8a49f157e0f786f379ca9bcbf2fea24de70d70a22b6@206.156.242.61:30303", "enode://31dffed97f8fed1f34fe66453280a89cbeeda60cf28f6fbb212ebbefd7c7566a02c1c7d5c00bbbb49b9fa8a49f157e0f786f379ca9bcbf2fea24de70d70a22b6@206.156.242.61:30303",
"enode://efe1a701595b7bfc20cc71a70dcdf1d731a5ca618cbc1bd0059edc6658d5958a2b243cc88112c7ded48f3d331a26a6a76b4d3f4a51260b5fb5d13f798e5786f0@206.156.242.62:30303",
"enode://6bdc7553ab2e4914cb47774c1e6d8c8f47ac7c3981891f85f65d06f208ea1bc4d3bf982b330950e0a0cd127efd7145c4df7113159a1d4a06ed722e6c16d0ac6c@45.32.215.190:30303", "enode://6bdc7553ab2e4914cb47774c1e6d8c8f47ac7c3981891f85f65d06f208ea1bc4d3bf982b330950e0a0cd127efd7145c4df7113159a1d4a06ed722e6c16d0ac6c@45.32.215.190:30303",
"enode://872d82a24144bc007658fb6fac0dcdfb9b63aeb05ef563a06d0186f2d1e5ffbfc5c4f1244891a8a86ef70682b9d24382e654b305224883698862e2df647a4d23@45.76.236.247:30303", "enode://872d82a24144bc007658fb6fac0dcdfb9b63aeb05ef563a06d0186f2d1e5ffbfc5c4f1244891a8a86ef70682b9d24382e654b305224883698862e2df647a4d23@45.76.236.247:30303",
"enode://b11fbc6cde81c80be69508aca8ffea8460680a25a9c151b683293f8617282062b8e8e139bf91e88cedf60068a3cf927b0d48832fda5169b58a8f7ce442de6fb4@206.189.76.132:30303", "enode://b11fbc6cde81c80be69508aca8ffea8460680a25a9c151b683293f8617282062b8e8e139bf91e88cedf60068a3cf927b0d48832fda5169b58a8f7ce442de6fb4@206.189.76.132:30303",
"enode://96678da10ac83769ab3f63114a41b57b700476c5ac02719b878fa89909a936551bb7609aa09b068bf89903206fa03f23e1b5b9117ca278de304c2570b87dcb27@18.208.191.114:30303", "enode://96678da10ac83769ab3f63114a41b57b700476c5ac02719b878fa89909a936551bb7609aa09b068bf89903206fa03f23e1b5b9117ca278de304c2570b87dcb27@35.175.15.164:30303"
"enode://47ee6bc6312210caa0087a5754221f7666e37ab2d5c10cfe386ecdf9e5f935fc55726b37d10f0eaf493f762a270445d3e6d569891c328759b8baeb39f6f6ed2d@34.224.215.151:30303"
], ],
"accounts": { "accounts": {
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } },

View File

@@ -37,7 +37,12 @@
"eip140Transition": "0x0", "eip140Transition": "0x0",
"eip211Transition": "0x0", "eip211Transition": "0x0",
"eip214Transition": "0x0", "eip214Transition": "0x0",
"eip658Transition": "0x0" "eip658Transition": "0x0",
"eip145Transition": 6464300,
"eip1014Transition": 6464300,
"eip1052Transition": 6464300,
"eip1283Transition": 6464300,
"eip1283DisableTransition": 7026400
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@@ -51,19 +56,12 @@
}, },
"nodes": [ "nodes": [
"enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303", "enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303",
"enode://0171db265a569636372566e86cb7a69306fe5c15a8e2ed5bed4010012fa1d146ae4918a688cf1bd3fd98e8c2d5c3705d68ff941c88ab974ff52c7fc8606ce2f8@35.168.201.160:30303", "enode://f1a5100a81cb73163ae450c584d06b1f644aa4fad4486c6aeb4c384b343c54bb66c744aa5f133af66ea1b25f0f4a454f04878f3e96ee4cd2390c047396d6357b@209.97.158.4:30303",
"enode://9a4a3788471af17a8346da7fc41057f037da692d4fad0ac5023fc0c88cf64666d74ee9f6396012eec98cd6bc772418b42dddd823a38e359bbfdc4fc93ba38de8@34.229.128.189:30303",
"enode://881e56dc71472376b65ddaad5e42ee73084c96eb368c1e219b4fbcd73ffa339703cca168b6620cb1eabb7b8dcfe72e563117670c7ce94298c20d04b709c65697@165.227.111.36:30303",
"enode://8e3733fe1606b17dd743e7d4fdb7ec1e0b909aab3c5289beabcb36e9d3175ca05bb36a52589090d4899c85a9219622ea4cbb9541057b722be65241db557b51a8@52.201.214.63:30303",
"enode://0d1e0372f63a3f0b82d66635ea101ecc0f6797788a078805cc933dd93e6a22f7c9fa51ab4e2d21da02d04480ef19f3bbb9a2b41dd1c262085d295a354bb8b0f9@18.217.47.209:30303", "enode://0d1e0372f63a3f0b82d66635ea101ecc0f6797788a078805cc933dd93e6a22f7c9fa51ab4e2d21da02d04480ef19f3bbb9a2b41dd1c262085d295a354bb8b0f9@18.217.47.209:30303",
"enode://ab083db73da15b3995ac9c68035cdb32901835a823cb848fccb672e43dd21f14428706118d6fe5b921d8e741f122f35aad0255bc86807b1d17bcfa1e86e40a14@165.227.37.104:30303", "enode://ab083db73da15b3995ac9c68035cdb32901835a823cb848fccb672e43dd21f14428706118d6fe5b921d8e741f122f35aad0255bc86807b1d17bcfa1e86e40a14@165.227.37.104:30303",
"enode://a2a8545ccceaa1152721a213e6aca912c6d89a37bc6eea73999fdb08a95c6f07a79057f7f41c75c128f58ed77a13985e5c33c8c50d6a3d60b50c43f5f69c1fcd@52.170.16.34:30303",
"enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303", "enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303",
"enode://182ee200ca134dc4d6390f3d5aadbcd80df0f7f24335830335d142573eacce4eeb919d30e82c5df588034e167e6ba6dd11187502ac9264a71005127f6b146a99@159.203.95.241:30303", "enode://182ee200ca134dc4d6390f3d5aadbcd80df0f7f24335830335d142573eacce4eeb919d30e82c5df588034e167e6ba6dd11187502ac9264a71005127f6b146a99@159.203.95.241:30303",
"enode://b022ff70b5fcaf9596ae5efed99a8198b4ae0578ee9d17b733609d803a75cef95d3a2a18e50dca9a7c3b26139f158c59eaf8b5fb8d1d331c9a46934a78acabe8@206.189.76.128:30303", "enode://b022ff70b5fcaf9596ae5efed99a8198b4ae0578ee9d17b733609d803a75cef95d3a2a18e50dca9a7c3b26139f158c59eaf8b5fb8d1d331c9a46934a78acabe8@206.189.76.128:30303"
"enode://4a16c9a597dad00c000523fc2f4302bb8bb7f05949ec0ea4a516f0c6de9e191662f650ab55ea2a05f5af0f0eeee879800074f7263328f09181c7156059b7b6b7@18.221.62.190:30303",
"enode://6527003feb6b534a7fac297b92d2f368bdf679d8f489639006c78640bf3ead3cdbf88a88a7bec29e6e29510122f279adf094d1b1b6e9e5005c4584aeb482c4a0@35.172.215.190:30303",
"enode://99f335f9dffe978f7a925590f011909f2db1a2b28b05a0dc10da47e285e3d20b2d827caee258607c707c5261d9ba5f7f5b899dd025315c0afbfd5536a91ccf73@18.209.18.86:30303"
], ],
"accounts": { "accounts": {
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } },

File diff suppressed because it is too large Load Diff

View 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 } } } }
}
}

View File

@@ -1,42 +1,4 @@
{ "block": {
[ "block": [],
{ "state": []
"reference": "None",
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
"failing": "GeneralStateTest_stCreate2",
"subtests": ["RevertInCreateInInitCreate2_d0g0v0_Constantinople"]
},
{
"reference": "None",
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
"failing": "GeneralStateTest_stRevertTest",
"subtests": ["RevertInCreateInInit_d0g0v0_Constantinople"]
}
],
"state":
[
{
"reference": "None",
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
"failing": "stCreate2Test",
"subtests": {
"RevertInCreateInInitCreate2": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "None",
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
"failing": "stRevertTest",
"subtests": {
"RevertInCreateInInit": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
}
}
}
]
} }

View File

@@ -114,19 +114,51 @@ impl ChainRoute {
} }
} }
/// Used by `ChainNotify` `new_blocks()`
pub struct NewBlocks {
/// Imported blocks
pub imported: Vec<H256>,
/// Invalid blocks
pub invalid: Vec<H256>,
/// Route
pub route: ChainRoute,
/// Sealed
pub sealed: Vec<H256>,
/// Block bytes.
pub proposed: Vec<Bytes>,
/// Duration
pub duration: Duration,
/// Has more blocks to import
pub has_more_blocks_to_import: bool,
}
impl NewBlocks {
/// Constructor
pub fn new (
imported: Vec<H256>,
invalid: Vec<H256>,
route: ChainRoute,
sealed: Vec<H256>,
proposed: Vec<Bytes>,
duration: Duration,
has_more_blocks_to_import: bool,
) -> NewBlocks {
NewBlocks {
imported,
invalid,
route,
sealed,
proposed,
duration,
has_more_blocks_to_import,
}
}
}
/// Represents what has to be handled by actor listening to chain events /// Represents what has to be handled by actor listening to chain events
pub trait ChainNotify : Send + Sync { pub trait ChainNotify : Send + Sync {
/// fires when chain has new blocks. /// fires when chain has new blocks.
fn new_blocks( fn new_blocks( &self, _new_blocks: NewBlocks) {
&self,
_imported: Vec<H256>,
_invalid: Vec<H256>,
_route: ChainRoute,
_sealed: Vec<H256>,
// Block bytes.
_proposed: Vec<Bytes>,
_duration: Duration,
) {
// does nothing by default // does nothing by default
} }

View File

@@ -44,7 +44,7 @@ use client::{
use client::{ use client::{
BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient,
TraceFilter, CallAnalytics, Mode, TraceFilter, CallAnalytics, Mode,
ChainNotify, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType, ChainNotify, NewBlocks, ChainRoute, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType,
IoClient, BadBlocks, IoClient, BadBlocks,
}; };
use client::bad_blocks; use client::bad_blocks;
@@ -268,7 +268,7 @@ impl Importer {
} }
let max_blocks_to_import = client.config.max_round_blocks_to_import; let max_blocks_to_import = client.config.max_round_blocks_to_import;
let (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration, is_empty) = { let (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration, has_more_blocks_to_import) = {
let mut imported_blocks = Vec::with_capacity(max_blocks_to_import); let mut imported_blocks = Vec::with_capacity(max_blocks_to_import);
let mut invalid_blocks = HashSet::new(); let mut invalid_blocks = HashSet::new();
let mut proposed_blocks = Vec::with_capacity(max_blocks_to_import); let mut proposed_blocks = Vec::with_capacity(max_blocks_to_import);
@@ -322,26 +322,29 @@ impl Importer {
if !invalid_blocks.is_empty() { if !invalid_blocks.is_empty() {
self.block_queue.mark_as_bad(&invalid_blocks); self.block_queue.mark_as_bad(&invalid_blocks);
} }
let is_empty = self.block_queue.mark_as_good(&imported_blocks); let has_more_blocks_to_import = !self.block_queue.mark_as_good(&imported_blocks);
(imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, start.elapsed(), is_empty) (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, start.elapsed(), has_more_blocks_to_import)
}; };
{ {
if !imported_blocks.is_empty() && is_empty { if !imported_blocks.is_empty() {
let route = ChainRoute::from(import_results.as_ref()); let route = ChainRoute::from(import_results.as_ref());
if is_empty { if !has_more_blocks_to_import {
self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, route.enacted(), route.retracted(), false); self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, route.enacted(), route.retracted(), false);
} }
client.notify(|notify| { client.notify(|notify| {
notify.new_blocks( notify.new_blocks(
NewBlocks::new(
imported_blocks.clone(), imported_blocks.clone(),
invalid_blocks.clone(), invalid_blocks.clone(),
route.clone(), route.clone(),
Vec::new(), Vec::new(),
proposed_blocks.clone(), proposed_blocks.clone(),
duration, duration,
has_more_blocks_to_import,
)
); );
}); });
} }
@@ -2164,11 +2167,8 @@ impl IoClient for Client {
// NOTE To prevent race condition with import, make sure to check queued blocks first // NOTE To prevent race condition with import, make sure to check queued blocks first
// (and attempt to acquire lock) // (and attempt to acquire lock)
let is_parent_pending = self.queued_ancient_blocks.read().0.contains(&parent_hash); let is_parent_pending = self.queued_ancient_blocks.read().0.contains(&parent_hash);
if !is_parent_pending { if !is_parent_pending && !self.chain.read().is_known(&parent_hash) {
let status = self.block_status(BlockId::Hash(parent_hash)); bail!(EthcoreErrorKind::Block(BlockError::UnknownParent(parent_hash)));
if status == BlockStatus::Unknown {
bail!(EthcoreErrorKind::Block(BlockError::UnknownParent(parent_hash)));
}
} }
} }
@@ -2198,6 +2198,10 @@ impl IoClient for Client {
); );
if let Err(e) = result { if let Err(e) = result {
error!(target: "client", "Error importing ancient block: {}", e); error!(target: "client", "Error importing ancient block: {}", e);
let mut queued = queued.write();
queued.0.clear();
queued.1.clear();
} }
// remove from pending // remove from pending
queued.write().0.remove(&hash); queued.write().0.remove(&hash);
@@ -2342,12 +2346,15 @@ impl ImportSealedBlock for Client {
); );
self.notify(|notify| { self.notify(|notify| {
notify.new_blocks( notify.new_blocks(
vec![hash], NewBlocks::new(
vec![], vec![hash],
route.clone(), vec![],
vec![hash], route.clone(),
vec![], vec![hash],
start.elapsed(), vec![],
start.elapsed(),
false
)
); );
}); });
self.db.read().key_value().flush().expect("DB flush failed."); self.db.read().key_value().flush().expect("DB flush failed.");
@@ -2360,12 +2367,15 @@ impl BroadcastProposalBlock for Client {
const DURATION_ZERO: Duration = Duration::from_millis(0); const DURATION_ZERO: Duration = Duration::from_millis(0);
self.notify(|notify| { self.notify(|notify| {
notify.new_blocks( notify.new_blocks(
vec![], NewBlocks::new(
vec![], vec![],
ChainRoute::default(), vec![],
vec![], ChainRoute::default(),
vec![block.rlp_bytes()], vec![],
DURATION_ZERO, vec![block.rlp_bytes()],
DURATION_ZERO,
false
)
); );
}); });
} }

View File

@@ -87,6 +87,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,
} }

View File

@@ -34,7 +34,7 @@ pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactResult};
pub use self::io_message::ClientIoMessage; pub use self::io_message::ClientIoMessage;
#[cfg(any(test, feature = "test-helpers"))] #[cfg(any(test, feature = "test-helpers"))]
pub use self::test_client::{TestBlockChainClient, EachBlockWith}; pub use self::test_client::{TestBlockChainClient, EachBlockWith};
pub use self::chain_notify::{ChainNotify, ChainRoute, ChainRouteType, ChainMessageType}; pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
pub use self::traits::{ pub use self::traits::{
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks, StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks,

View File

@@ -81,6 +81,8 @@ pub struct AuthorityRoundParams {
pub empty_steps_transition: u64, pub empty_steps_transition: u64,
/// Number of accepted empty steps. /// Number of accepted empty steps.
pub maximum_empty_steps: usize, pub maximum_empty_steps: usize,
/// Transition block to strict empty steps validation.
pub strict_empty_steps_transition: u64,
} }
const U16_MAX: usize = ::std::u16::MAX as usize; const U16_MAX: usize = ::std::u16::MAX as usize;
@@ -110,6 +112,7 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into), maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
empty_steps_transition: p.empty_steps_transition.map_or(u64::max_value(), |n| ::std::cmp::max(n.into(), 1)), empty_steps_transition: p.empty_steps_transition.map_or(u64::max_value(), |n| ::std::cmp::max(n.into(), 1)),
maximum_empty_steps: p.maximum_empty_steps.map_or(0, Into::into), maximum_empty_steps: p.maximum_empty_steps.map_or(0, Into::into),
strict_empty_steps_transition: p.strict_empty_steps_transition.map_or(0, Into::into),
} }
} }
} }
@@ -421,6 +424,7 @@ pub struct AuthorityRound {
maximum_uncle_count_transition: u64, maximum_uncle_count_transition: u64,
maximum_uncle_count: usize, maximum_uncle_count: usize,
empty_steps_transition: u64, empty_steps_transition: u64,
strict_empty_steps_transition: u64,
maximum_empty_steps: usize, maximum_empty_steps: usize,
machine: EthereumMachine, machine: EthereumMachine,
} }
@@ -674,6 +678,7 @@ impl AuthorityRound {
maximum_uncle_count: our_params.maximum_uncle_count, maximum_uncle_count: our_params.maximum_uncle_count,
empty_steps_transition: our_params.empty_steps_transition, empty_steps_transition: our_params.empty_steps_transition,
maximum_empty_steps: our_params.maximum_empty_steps, maximum_empty_steps: our_params.maximum_empty_steps,
strict_empty_steps_transition: our_params.strict_empty_steps_transition,
machine: machine, machine: machine,
}); });
@@ -1250,8 +1255,11 @@ impl Engine<EthereumMachine> for AuthorityRound {
// reported as there's no way to tell whether the empty step message was never sent or simply not included. // reported as there's no way to tell whether the empty step message was never sent or simply not included.
let empty_steps_len = if header.number() >= self.empty_steps_transition { let empty_steps_len = if header.number() >= self.empty_steps_transition {
let validate_empty_steps = || -> Result<usize, Error> { let validate_empty_steps = || -> Result<usize, Error> {
let strict_empty_steps = header.number() >= self.strict_empty_steps_transition;
let empty_steps = header_empty_steps(header)?; let empty_steps = header_empty_steps(header)?;
let empty_steps_len = empty_steps.len(); let empty_steps_len = empty_steps.len();
let mut prev_empty_step = 0;
for empty_step in empty_steps { for empty_step in empty_steps {
if empty_step.step <= parent_step || empty_step.step >= step { if empty_step.step <= parent_step || empty_step.step >= step {
Err(EngineError::InsufficientProof( Err(EngineError::InsufficientProof(
@@ -1267,7 +1275,20 @@ impl Engine<EthereumMachine> for AuthorityRound {
Err(EngineError::InsufficientProof( Err(EngineError::InsufficientProof(
format!("invalid empty step proof: {:?}", empty_step)))?; format!("invalid empty step proof: {:?}", empty_step)))?;
} }
if strict_empty_steps {
if empty_step.step <= prev_empty_step {
Err(EngineError::InsufficientProof(format!(
"{} empty step: {:?}",
if empty_step.step == prev_empty_step { "duplicate" } else { "unordered" },
empty_step
)))?;
}
prev_empty_step = empty_step.step;
}
} }
Ok(empty_steps_len) Ok(empty_steps_len)
}; };
@@ -1400,16 +1421,21 @@ impl Engine<EthereumMachine> for AuthorityRound {
let mut finality_proof: Vec<_> = itertools::repeat_call(move || { let mut finality_proof: Vec<_> = itertools::repeat_call(move || {
chain(hash).and_then(|header| { chain(hash).and_then(|header| {
hash = *header.parent_hash(); hash = *header.parent_hash();
if header.number() == 0 { return None } if header.number() == 0 { None }
else { return Some(header) } else { Some(header) }
}) })
}) })
.while_some() .while_some()
.take_while(|h| h.hash() != *finalized_hash) .take_while(|h| h.hash() != *finalized_hash)
.collect(); .collect();
let finalized_header = chain(*finalized_hash) let finalized_header = if *finalized_hash == chain_head.hash() {
.expect("header is finalized; finalized headers must exist in the chain; qed"); // chain closure only stores ancestry, but the chain head is also unfinalized.
chain_head.clone()
} else {
chain(*finalized_hash)
.expect("header is finalized; finalized headers must exist in the chain; qed")
};
let signal_number = finalized_header.number(); let signal_number = finalized_header.number();
info!(target: "engine", "Applying validator set change signalled at block {}", signal_number); info!(target: "engine", "Applying validator set change signalled at block {}", signal_number);
@@ -1518,10 +1544,40 @@ mod tests {
use spec::Spec; use spec::Spec;
use transaction::{Action, Transaction}; use transaction::{Action, Transaction};
use engines::{Seal, Engine, EngineError, EthEngine}; use engines::{Seal, Engine, EngineError, EthEngine};
use engines::validator_set::TestSet; use engines::validator_set::{TestSet, SimpleList};
use error::{Error, ErrorKind}; use error::{Error, ErrorKind};
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score}; use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
fn aura<F>(f: F) -> Arc<AuthorityRound> where
F: FnOnce(&mut AuthorityRoundParams),
{
let mut params = AuthorityRoundParams {
step_duration: 1,
start_step: Some(1),
validators: Box::new(TestSet::default()),
validate_score_transition: 0,
validate_step_transition: 0,
immediate_transitions: true,
maximum_uncle_count_transition: 0,
maximum_uncle_count: 0,
empty_steps_transition: u64::max_value(),
maximum_empty_steps: 0,
block_reward: Default::default(),
block_reward_contract_transition: 0,
block_reward_contract: Default::default(),
strict_empty_steps_transition: 0,
};
// mutate aura params
f(&mut params);
// create engine
let mut c_params = ::spec::CommonParams::default();
c_params.gas_limit_bound_divisor = 5.into();
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
AuthorityRound::new(params, machine).unwrap()
}
#[test] #[test]
fn has_valid_metadata() { fn has_valid_metadata() {
let engine = Spec::new_test_round().engine; let engine = Spec::new_test_round().engine;
@@ -1695,28 +1751,9 @@ mod tests {
#[test] #[test]
fn reports_skipped() { fn reports_skipped() {
let last_benign = Arc::new(AtomicUsize::new(0)); let last_benign = Arc::new(AtomicUsize::new(0));
let params = AuthorityRoundParams { let aura = aura(|p| {
step_duration: 1, p.validators = Box::new(TestSet::new(Default::default(), last_benign.clone()));
start_step: Some(1), });
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
validate_score_transition: 0,
validate_step_transition: 0,
immediate_transitions: true,
maximum_uncle_count_transition: 0,
maximum_uncle_count: 0,
empty_steps_transition: u64::max_value(),
maximum_empty_steps: 0,
block_reward: Default::default(),
block_reward_contract_transition: 0,
block_reward_contract: Default::default(),
};
let aura = {
let mut c_params = ::spec::CommonParams::default();
c_params.gas_limit_bound_divisor = 5.into();
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
AuthorityRound::new(params, machine).unwrap()
};
let mut parent_header: Header = Header::default(); let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&1usize)]); parent_header.set_seal(vec![encode(&1usize)]);
@@ -1745,29 +1782,9 @@ mod tests {
#[test] #[test]
fn test_uncles_transition() { fn test_uncles_transition() {
let last_benign = Arc::new(AtomicUsize::new(0)); let aura = aura(|params| {
let params = AuthorityRoundParams { params.maximum_uncle_count_transition = 1;
step_duration: 1, });
start_step: Some(1),
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
validate_score_transition: 0,
validate_step_transition: 0,
immediate_transitions: true,
maximum_uncle_count_transition: 1,
maximum_uncle_count: 0,
empty_steps_transition: u64::max_value(),
maximum_empty_steps: 0,
block_reward: Default::default(),
block_reward_contract_transition: 0,
block_reward_contract: Default::default(),
};
let aura = {
let mut c_params = ::spec::CommonParams::default();
c_params.gas_limit_bound_divisor = 5.into();
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
AuthorityRound::new(params, machine).unwrap()
};
assert_eq!(aura.maximum_uncle_count(0), 2); assert_eq!(aura.maximum_uncle_count(0), 2);
assert_eq!(aura.maximum_uncle_count(1), 0); assert_eq!(aura.maximum_uncle_count(1), 0);
@@ -1801,27 +1818,9 @@ mod tests {
#[test] #[test]
#[should_panic(expected="authority_round: step duration can't be zero")] #[should_panic(expected="authority_round: step duration can't be zero")]
fn test_step_duration_zero() { fn test_step_duration_zero() {
let last_benign = Arc::new(AtomicUsize::new(0)); aura(|params| {
let params = AuthorityRoundParams { params.step_duration = 0;
step_duration: 0, });
start_step: Some(1),
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
validate_score_transition: 0,
validate_step_transition: 0,
immediate_transitions: true,
maximum_uncle_count_transition: 0,
maximum_uncle_count: 0,
empty_steps_transition: u64::max_value(),
maximum_empty_steps: 0,
block_reward: Default::default(),
block_reward_contract_transition: 0,
block_reward_contract: Default::default(),
};
let mut c_params = ::spec::CommonParams::default();
c_params.gas_limit_bound_divisor = 5.into();
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
AuthorityRound::new(params, machine).unwrap();
} }
fn setup_empty_steps() -> (Spec, Arc<AccountProvider>, Vec<Address>) { fn setup_empty_steps() -> (Spec, Arc<AccountProvider>, Vec<Address>) {
@@ -1849,6 +1848,23 @@ mod tests {
SealedEmptyStep { signature, step } SealedEmptyStep { signature, step }
} }
fn set_empty_steps_seal(header: &mut Header, step: u64, block_signature: &ethkey::Signature, empty_steps: &[SealedEmptyStep]) {
header.set_seal(vec![
encode(&(step as usize)),
encode(&(&**block_signature as &[u8])),
::rlp::encode_list(&empty_steps),
]);
}
fn assert_insufficient_proof<T: ::std::fmt::Debug>(result: Result<T, Error>, contains: &str) {
match result {
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) =>{
assert!(s.contains(contains), "Expected {:?} to contain {:?}", s, contains);
},
e => assert!(false, "Unexpected result: {:?}", e),
}
}
#[test] #[test]
fn broadcast_empty_step_message() { fn broadcast_empty_step_message() {
let (spec, tap, accounts) = setup_empty_steps(); let (spec, tap, accounts) = setup_empty_steps();
@@ -2050,46 +2066,31 @@ mod tests {
// empty step with invalid step // empty step with invalid step
let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 2 }]; let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 2 }];
header.set_seal(vec![ set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
encode(&2usize),
encode(&(&*signature as &[u8])),
::rlp::encode_list(&empty_steps),
]);
assert!(match engine.verify_block_family(&header, &parent_header) { assert_insufficient_proof(
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) engine.verify_block_family(&header, &parent_header),
if s.contains("invalid step") => true, "invalid step"
_ => false, );
});
// empty step with invalid signature // empty step with invalid signature
let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 1 }]; let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 1 }];
header.set_seal(vec![ set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
encode(&2usize),
encode(&(&*signature as &[u8])),
::rlp::encode_list(&empty_steps),
]);
assert!(match engine.verify_block_family(&header, &parent_header) { assert_insufficient_proof(
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) engine.verify_block_family(&header, &parent_header),
if s.contains("invalid empty step proof") => true, "invalid empty step proof"
_ => false, );
});
// empty step with valid signature from incorrect proposer for step // empty step with valid signature from incorrect proposer for step
engine.set_signer(tap.clone(), addr1, "1".into()); engine.set_signer(tap.clone(), addr1, "1".into());
let empty_steps = vec![sealed_empty_step(engine, 1, &parent_header.hash())]; let empty_steps = vec![sealed_empty_step(engine, 1, &parent_header.hash())];
header.set_seal(vec![ set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
encode(&2usize),
encode(&(&*signature as &[u8])),
::rlp::encode_list(&empty_steps),
]);
assert!(match engine.verify_block_family(&header, &parent_header) { assert_insufficient_proof(
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) engine.verify_block_family(&header, &parent_header),
if s.contains("invalid empty step proof") => true, "invalid empty step proof"
_ => false, );
});
// valid empty steps // valid empty steps
engine.set_signer(tap.clone(), addr1, "1".into()); engine.set_signer(tap.clone(), addr1, "1".into());
@@ -2100,11 +2101,7 @@ mod tests {
let empty_steps = vec![empty_step2, empty_step3]; let empty_steps = vec![empty_step2, empty_step3];
header.set_difficulty(calculate_score(0, 4, 2)); header.set_difficulty(calculate_score(0, 4, 2));
let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap(); let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap();
header.set_seal(vec![ set_empty_steps_seal(&mut header, 4, &signature, &empty_steps);
encode(&4usize),
encode(&(&*signature as &[u8])),
::rlp::encode_list(&empty_steps),
]);
assert!(engine.verify_block_family(&header, &parent_header).is_ok()); assert!(engine.verify_block_family(&header, &parent_header).is_ok());
} }
@@ -2216,28 +2213,11 @@ mod tests {
#[test] #[test]
fn test_empty_steps() { fn test_empty_steps() {
let last_benign = Arc::new(AtomicUsize::new(0)); let engine = aura(|p| {
let params = AuthorityRoundParams { p.step_duration = 4;
step_duration: 4, p.empty_steps_transition = 0;
start_step: Some(1), p.maximum_empty_steps = 0;
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())), });
validate_score_transition: 0,
validate_step_transition: 0,
immediate_transitions: true,
maximum_uncle_count_transition: 0,
maximum_uncle_count: 0,
empty_steps_transition: 0,
maximum_empty_steps: 10,
block_reward: Default::default(),
block_reward_contract_transition: 0,
block_reward_contract: Default::default(),
};
let mut c_params = ::spec::CommonParams::default();
c_params.gas_limit_bound_divisor = 5.into();
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
let engine = AuthorityRound::new(params, machine).unwrap();
let parent_hash: H256 = 1.into(); let parent_hash: H256 = 1.into();
let signature = H520::default(); let signature = H520::default();
@@ -2261,4 +2241,85 @@ mod tests {
assert_eq!(engine.empty_steps(0, 3, parent_hash), vec![]); assert_eq!(engine.empty_steps(0, 3, parent_hash), vec![]);
assert_eq!(engine.empty_steps(0, 4, parent_hash), vec![step(3)]); assert_eq!(engine.empty_steps(0, 4, parent_hash), vec![step(3)]);
} }
#[test]
fn should_reject_duplicate_empty_steps() {
// given
let (_spec, tap, accounts) = setup_empty_steps();
let engine = aura(|p| {
p.validators = Box::new(SimpleList::new(accounts.clone()));
p.step_duration = 4;
p.empty_steps_transition = 0;
p.maximum_empty_steps = 0;
});
let mut parent = Header::default();
parent.set_seal(vec![encode(&0usize)]);
let mut header = Header::default();
header.set_number(parent.number() + 1);
header.set_parent_hash(parent.hash());
header.set_author(accounts[0]);
// when
engine.set_signer(tap.clone(), accounts[1], "0".into());
let empty_steps = vec![
sealed_empty_step(&*engine, 1, &parent.hash()),
sealed_empty_step(&*engine, 1, &parent.hash()),
];
let step = 2;
let signature = tap.sign(accounts[0], Some("1".into()), header.bare_hash()).unwrap();
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
header.set_difficulty(calculate_score(0, step, empty_steps.len()));
// then
assert_insufficient_proof(
engine.verify_block_family(&header, &parent),
"duplicate empty step"
);
}
#[test]
fn should_reject_empty_steps_out_of_order() {
// given
let (_spec, tap, accounts) = setup_empty_steps();
let engine = aura(|p| {
p.validators = Box::new(SimpleList::new(accounts.clone()));
p.step_duration = 4;
p.empty_steps_transition = 0;
p.maximum_empty_steps = 0;
});
let mut parent = Header::default();
parent.set_seal(vec![encode(&0usize)]);
let mut header = Header::default();
header.set_number(parent.number() + 1);
header.set_parent_hash(parent.hash());
header.set_author(accounts[0]);
// when
engine.set_signer(tap.clone(), accounts[1], "0".into());
let es1 = sealed_empty_step(&*engine, 1, &parent.hash());
engine.set_signer(tap.clone(), accounts[0], "1".into());
let es2 = sealed_empty_step(&*engine, 2, &parent.hash());
let mut empty_steps = vec![es2, es1];
let step = 3;
let signature = tap.sign(accounts[1], Some("0".into()), header.bare_hash()).unwrap();
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
header.set_difficulty(calculate_score(0, step, empty_steps.len()));
// then make sure it's rejected because of the order
assert_insufficient_proof(
engine.verify_block_family(&header, &parent),
"unordered empty step"
);
// now try to fix the order
empty_steps.reverse();
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
assert_eq!(engine.verify_block_family(&header, &parent).unwrap(), ());
}
} }

View File

@@ -34,12 +34,18 @@ pub struct TestSet {
last_benign: Arc<AtomicUsize>, last_benign: Arc<AtomicUsize>,
} }
impl Default for TestSet {
fn default() -> Self {
TestSet::new(Default::default(), Default::default())
}
}
impl TestSet { impl TestSet {
pub fn new(last_malicious: Arc<AtomicUsize>, last_benign: Arc<AtomicUsize>) -> Self { pub fn new(last_malicious: Arc<AtomicUsize>, last_benign: Arc<AtomicUsize>) -> Self {
TestSet { TestSet {
validator: SimpleList::new(vec![Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()]), validator: SimpleList::new(vec![Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()]),
last_malicious: last_malicious, last_malicious,
last_benign: last_benign, last_benign,
} }
} }
} }

View File

@@ -89,6 +89,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.
@@ -138,6 +140,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),
}; };

View File

@@ -143,6 +143,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")) }
@@ -163,6 +166,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")) }

View File

@@ -311,7 +311,7 @@ impl<'a> CallCreateExecutive<'a> {
let prev_bal = state.balance(&params.address)?; let prev_bal = state.balance(&params.address)?;
if let ActionValue::Transfer(val) = params.value { if let ActionValue::Transfer(val) = params.value {
state.sub_balance(&params.sender, &val, &mut substate.to_cleanup_mode(&schedule))?; state.sub_balance(&params.sender, &val, &mut substate.to_cleanup_mode(&schedule))?;
state.new_contract(&params.address, val + prev_bal, nonce_offset)?; state.new_contract(&params.address, val.saturating_add(prev_bal), nonce_offset)?;
} else { } else {
state.new_contract(&params.address, prev_bal, nonce_offset)?; state.new_contract(&params.address, prev_bal, nonce_offset)?;
} }
@@ -979,7 +979,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || { scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer)
}).expect("Sub-thread creation cannot fail; the host might run out of resources; qed") }).expect("Sub-thread creation cannot fail; the host might run out of resources; qed")
}).join() }).join().expect("Sub-thread never panics; qed")
} }
} }
@@ -1063,7 +1063,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || { scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer) self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer)
}).expect("Sub-thread creation cannot fail; the host might run out of resources; qed") }).expect("Sub-thread creation cannot fail; the host might run out of resources; qed")
}).join() }).join().expect("Sub-thread never panics; qed")
} }
} }
@@ -1102,9 +1102,13 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) >> 1); let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) >> 1);
let gas_left = gas_left_prerefund + refunded; let gas_left = gas_left_prerefund + refunded;
let gas_used = t.gas - gas_left; let gas_used = t.gas.saturating_sub(gas_left);
let refund_value = gas_left * t.gas_price; let (refund_value, overflow_1) = gas_left.overflowing_mul(t.gas_price);
let fees_value = gas_used * t.gas_price; let (fees_value, overflow_2) = gas_used.overflowing_mul(t.gas_price);
if overflow_1 || overflow_2 {
return Err(ExecutionError::TransactionMalformed("U256 Overflow".to_string()));
}
trace!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n", trace!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n",
t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value); t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value);
@@ -1122,7 +1126,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
} }
// perform garbage-collection // perform garbage-collection
let min_balance = if schedule.kill_dust != CleanDustMode::Off { Some(U256::from(schedule.tx_gas) * t.gas_price) } else { None }; let min_balance = if schedule.kill_dust != CleanDustMode::Off { Some(U256::from(schedule.tx_gas).overflowing_mul(t.gas_price).0) } else { None };
self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?; self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?;
match result { match result {

View File

@@ -116,7 +116,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend where T: Tracer, V: VMTracer, B: StateBackend
{ {
fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> { fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> {
self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into) if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? {
self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into)
} else {
warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address);
Ok(H256::zero())
}
} }
fn storage_at(&self, key: &H256) -> vm::Result<H256> { fn storage_at(&self, key: &H256) -> vm::Result<H256> {

View File

@@ -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:

View File

@@ -192,11 +192,11 @@ pub fn take_snapshot<W: SnapshotWriter + Send>(
state_guards.push(state_guard); state_guards.push(state_guard);
} }
let block_hashes = block_guard.join()?; let block_hashes = block_guard.join().expect("Sub-thread never panics; qed")?;
let mut state_hashes = Vec::new(); let mut state_hashes = Vec::new();
for guard in state_guards { for guard in state_guards {
let part_state_hashes = guard.join()?; let part_state_hashes = guard.join().expect("Sub-thread never panics; qed")?;
state_hashes.extend(part_state_hashes); state_hashes.extend(part_state_hashes);
} }

View File

@@ -17,14 +17,13 @@
//! Watcher for snapshot-related chain events. //! Watcher for snapshot-related chain events.
use parking_lot::Mutex; use parking_lot::Mutex;
use client::{BlockInfo, Client, ChainNotify, ChainRoute, ClientIoMessage}; use client::{BlockInfo, Client, ChainNotify, NewBlocks, ClientIoMessage};
use ids::BlockId; use ids::BlockId;
use io::IoChannel; use io::IoChannel;
use ethereum_types::H256; use ethereum_types::H256;
use bytes::Bytes;
use std::{sync::Arc, time::Duration}; use std::sync::Arc;
// helper trait for transforming hashes to numbers and checking if syncing. // helper trait for transforming hashes to numbers and checking if syncing.
trait Oracle: Send + Sync { trait Oracle: Send + Sync {
@@ -99,20 +98,12 @@ impl Watcher {
} }
impl ChainNotify for Watcher { impl ChainNotify for Watcher {
fn new_blocks( fn new_blocks(&self, new_blocks: NewBlocks) {
&self, if self.oracle.is_major_importing() || new_blocks.has_more_blocks_to_import { return }
imported: Vec<H256>,
_: Vec<H256>,
_: ChainRoute,
_: Vec<H256>,
_: Vec<Bytes>,
_duration: Duration)
{
if self.oracle.is_major_importing() { return }
trace!(target: "snapshot_watcher", "{} imported", imported.len()); trace!(target: "snapshot_watcher", "{} imported", new_blocks.imported.len());
let highest = imported.into_iter() let highest = new_blocks.imported.into_iter()
.filter_map(|h| self.oracle.to_number(h)) .filter_map(|h| self.oracle.to_number(h))
.filter(|&num| num >= self.period + self.history) .filter(|&num| num >= self.period + self.history)
.map(|num| num - self.history) .map(|num| num - self.history)
@@ -130,7 +121,7 @@ impl ChainNotify for Watcher {
mod tests { mod tests {
use super::{Broadcast, Oracle, Watcher}; use super::{Broadcast, Oracle, Watcher};
use client::{ChainNotify, ChainRoute}; use client::{ChainNotify, NewBlocks, ChainRoute};
use ethereum_types::{H256, U256}; use ethereum_types::{H256, U256};
@@ -170,14 +161,15 @@ mod tests {
history: history, history: history,
}; };
watcher.new_blocks( watcher.new_blocks(NewBlocks::new(
hashes, hashes,
vec![], vec![],
ChainRoute::default(), ChainRoute::default(),
vec![], vec![],
vec![], vec![],
DURATION_ZERO, DURATION_ZERO,
); false
));
} }
// helper // helper

View File

@@ -120,6 +120,8 @@ pub struct CommonParams {
pub eip1052_transition: BlockNumber, pub eip1052_transition: BlockNumber,
/// Number of first block where EIP-1283 rules begin. /// Number of first block where EIP-1283 rules begin.
pub eip1283_transition: BlockNumber, pub eip1283_transition: BlockNumber,
/// Number of first block where EIP-1283 rules end.
pub eip1283_disable_transition: BlockNumber,
/// Number of first block where EIP-1014 rules begin. /// Number of first block where EIP-1014 rules begin.
pub eip1014_transition: BlockNumber, pub eip1014_transition: BlockNumber,
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
@@ -188,7 +190,7 @@ impl CommonParams {
schedule.have_return_data = block_number >= self.eip211_transition; schedule.have_return_data = block_number >= self.eip211_transition;
schedule.have_bitwise_shifting = block_number >= self.eip145_transition; schedule.have_bitwise_shifting = block_number >= self.eip145_transition;
schedule.have_extcodehash = block_number >= self.eip1052_transition; schedule.have_extcodehash = block_number >= self.eip1052_transition;
schedule.eip1283 = block_number >= self.eip1283_transition; schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition);
if block_number >= self.eip210_transition { if block_number >= self.eip210_transition {
schedule.blockhash_gas = 800; schedule.blockhash_gas = 800;
} }
@@ -296,6 +298,10 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value, BlockNumber::max_value,
Into::into, Into::into,
), ),
eip1283_disable_transition: p.eip1283_disable_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip1014_transition: p.eip1014_transition.map_or_else( eip1014_transition: p.eip1014_transition.map_or_else(
BlockNumber::max_value, BlockNumber::max_value,
Into::into, Into::into,

View File

@@ -447,6 +447,11 @@ impl Account {
} }
} }
/// Whether the base storage root of this account is unchanged.
pub fn is_base_storage_root_unchanged(&self) -> bool {
self.original_storage_cache.is_none()
}
/// Storage root where the account changes are based upon. /// Storage root where the account changes are based upon.
pub fn base_storage_root(&self) -> H256 { pub fn base_storage_root(&self) -> H256 {
self.storage_root self.storage_root
@@ -457,12 +462,12 @@ impl Account {
/// Increment the nonce of the account by one. /// Increment the nonce of the account by one.
pub fn inc_nonce(&mut self) { pub fn inc_nonce(&mut self) {
self.nonce = self.nonce + U256::from(1u8); self.nonce = self.nonce.saturating_add(U256::from(1u8));
} }
/// Increase account balance. /// Increase account balance.
pub fn add_balance(&mut self, x: &U256) { pub fn add_balance(&mut self, x: &U256) {
self.balance = self.balance + *x; self.balance = self.balance.saturating_add(*x);
} }
/// Decrease account balance. /// Decrease account balance.

View File

@@ -500,7 +500,12 @@ impl<B: Backend> State<B> {
/// it will have its code reset, ready for `init_code()`. /// it will have its code reset, ready for `init_code()`.
pub fn new_contract(&mut self, contract: &Address, balance: U256, nonce_offset: U256) -> TrieResult<()> { pub fn new_contract(&mut self, contract: &Address, balance: U256, nonce_offset: U256) -> TrieResult<()> {
let original_storage_root = self.original_storage_root(contract)?; let original_storage_root = self.original_storage_root(contract)?;
self.insert_cache(contract, AccountEntry::new_dirty(Some(Account::new_contract(balance, self.account_start_nonce + nonce_offset, original_storage_root)))); let (nonce, overflow) = self.account_start_nonce.overflowing_add(nonce_offset);
if overflow {
return Err(Box::new(TrieError::DecoderError(H256::from(contract),
rlp::DecoderError::Custom("Nonce overflow".into()))));
}
self.insert_cache(contract, AccountEntry::new_dirty(Some(Account::new_contract(balance, nonce, original_storage_root))));
Ok(()) Ok(())
} }
@@ -539,6 +544,13 @@ impl<B: Backend> State<B> {
|a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce())) |a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce()))
} }
/// Whether the base storage root of an account remains unchanged.
pub fn is_base_storage_root_unchanged(&self, a: &Address) -> TrieResult<bool> {
Ok(self.ensure_cached(a, RequireCache::None, true,
|a| a.as_ref().map(|account| account.is_base_storage_root_unchanged()))?
.unwrap_or(true))
}
/// Get the storage root of account `a`. /// Get the storage root of account `a`.
pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> { pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true, self.ensure_cached(a, RequireCache::None, true,

View File

@@ -39,6 +39,25 @@ use header::{BlockNumber, Header};
use transaction::SignedTransaction; use 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 +324,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 +346,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 {
@@ -734,7 +753,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();
@@ -806,4 +826,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());
}
} }

View File

@@ -29,7 +29,7 @@ use types::pruning_info::PruningInfo;
use ethereum_types::{H256, H512, U256}; use ethereum_types::{H256, H512, U256};
use io::{TimerToken}; use io::{TimerToken};
use ethcore::ethstore::ethkey::Secret; use ethcore::ethstore::ethkey::Secret;
use ethcore::client::{BlockChainClient, ChainNotify, ChainRoute, ChainMessageType}; use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainMessageType};
use ethcore::snapshot::SnapshotService; use ethcore::snapshot::SnapshotService;
use ethcore::header::BlockNumber; use ethcore::header::BlockNumber;
use sync_io::NetSyncIo; use sync_io::NetSyncIo;
@@ -498,14 +498,9 @@ impl ChainNotify for EthSync {
} }
} }
fn new_blocks(&self, fn new_blocks(&self, new_blocks: NewBlocks)
imported: Vec<H256>,
invalid: Vec<H256>,
route: ChainRoute,
sealed: Vec<H256>,
proposed: Vec<Bytes>,
_duration: Duration)
{ {
if new_blocks.has_more_blocks_to_import { return }
use light::net::Announcement; use light::net::Announcement;
self.network.with_context(self.subprotocol_name, |context| { self.network.with_context(self.subprotocol_name, |context| {
@@ -513,12 +508,12 @@ impl ChainNotify for EthSync {
&self.eth_handler.overlay); &self.eth_handler.overlay);
self.eth_handler.sync.write().chain_new_blocks( self.eth_handler.sync.write().chain_new_blocks(
&mut sync_io, &mut sync_io,
&imported, &new_blocks.imported,
&invalid, &new_blocks.invalid,
route.enacted(), new_blocks.route.enacted(),
route.retracted(), new_blocks.route.retracted(),
&sealed, &new_blocks.sealed,
&proposed); &new_blocks.proposed);
}); });
self.network.with_context(self.light_subprotocol_name, |context| { self.network.with_context(self.light_subprotocol_name, |context| {

View File

@@ -45,13 +45,13 @@ fn accepts_service_transaction(client_id: &str) -> bool {
// Parity versions starting from this will accept service-transactions // Parity versions starting from this will accept service-transactions
const SERVICE_TRANSACTIONS_VERSION: (u32, u32) = (1u32, 6u32); const SERVICE_TRANSACTIONS_VERSION: (u32, u32) = (1u32, 6u32);
// Parity client string prefix // Parity client string prefix
const LEGACY_CLIENT_ID_PREFIX: &'static str = "Parity/v"; const LEGACY_CLIENT_ID_PREFIX: &'static str = "Parity/";
const PARITY_CLIENT_ID_PREFIX: &'static str = "Parity-Ethereum/v"; const PARITY_CLIENT_ID_PREFIX: &'static str = "Parity-Ethereum/";
const VERSION_PREFIX: &'static str = "/v";
let splitted = if client_id.starts_with(LEGACY_CLIENT_ID_PREFIX) {
client_id[LEGACY_CLIENT_ID_PREFIX.len()..].split('.') let idx = client_id.rfind(VERSION_PREFIX).map(|idx| idx + VERSION_PREFIX.len()).unwrap_or(client_id.len());
} else if client_id.starts_with(PARITY_CLIENT_ID_PREFIX) { let splitted = if client_id.starts_with(LEGACY_CLIENT_ID_PREFIX) || client_id.starts_with(PARITY_CLIENT_ID_PREFIX) {
client_id[PARITY_CLIENT_ID_PREFIX.len()..].split('.') client_id[idx..].split('.')
} else { } else {
return false; return false;
}; };
@@ -599,7 +599,7 @@ mod tests {
io.peers_info.insert(3, "Parity/v1.5".to_owned()); io.peers_info.insert(3, "Parity/v1.5".to_owned());
// and peer#4 is Parity, accepting service transactions // and peer#4 is Parity, accepting service transactions
insert_dummy_peer(&mut sync, 4, block_hash); insert_dummy_peer(&mut sync, 4, block_hash);
io.peers_info.insert(4, "Parity-Ethereum/v2.7.3-ABCDEFGH".to_owned()); io.peers_info.insert(4, "Parity-Ethereum/ABCDEFGH/v2.7.3".to_owned());
// and new service transaction is propagated to peers // and new service transaction is propagated to peers
SyncPropagator::propagate_new_transactions(&mut sync, &mut io, || true); SyncPropagator::propagate_new_transactions(&mut sync, &mut io, || true);

View File

@@ -16,14 +16,13 @@
use std::collections::{VecDeque, HashSet, HashMap}; use std::collections::{VecDeque, HashSet, HashMap};
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use ethereum_types::H256; use ethereum_types::H256;
use parking_lot::{RwLock, Mutex}; use parking_lot::{RwLock, Mutex};
use bytes::Bytes; use bytes::Bytes;
use network::{self, PeerId, ProtocolId, PacketId, SessionInfo}; use network::{self, PeerId, ProtocolId, PacketId, SessionInfo};
use tests::snapshot::*; use tests::snapshot::*;
use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient, use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreClient,
ClientConfig, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage}; ClientConfig, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage};
use ethcore::header::BlockNumber; use ethcore::header::BlockNumber;
use ethcore::snapshot::SnapshotService; use ethcore::snapshot::SnapshotService;
use ethcore::spec::Spec; use ethcore::spec::Spec;
@@ -535,23 +534,18 @@ impl IoHandler<ClientIoMessage> for TestIoHandler {
} }
impl ChainNotify for EthPeer<EthcoreClient> { impl ChainNotify for EthPeer<EthcoreClient> {
fn new_blocks(&self, fn new_blocks(&self, new_blocks: NewBlocks)
imported: Vec<H256>,
invalid: Vec<H256>,
route: ChainRoute,
sealed: Vec<H256>,
proposed: Vec<Bytes>,
_duration: Duration)
{ {
let (enacted, retracted) = route.into_enacted_retracted(); if new_blocks.has_more_blocks_to_import { return }
let (enacted, retracted) = new_blocks.route.into_enacted_retracted();
self.new_blocks_queue.write().push_back(NewBlockMessage { self.new_blocks_queue.write().push_back(NewBlockMessage {
imported, imported: new_blocks.imported,
invalid, invalid: new_blocks.invalid,
enacted, enacted,
retracted, retracted,
sealed, sealed: new_blocks.sealed,
proposed, proposed: new_blocks.proposed,
}); });
} }

View File

@@ -9,7 +9,7 @@ ethereum-types = "0.4"
log = "0.4" log = "0.4"
parity-wasm = "0.31" parity-wasm = "0.31"
libc = "0.2" libc = "0.2"
pwasm-utils = "0.2.2" pwasm-utils = "0.6.1"
vm = { path = "../vm" } vm = { path = "../vm" }
ethcore-logger = { path = "../../logger" } ethcore-logger = { path = "../../logger" }
wasmi = "0.3.0" wasmi = "0.3.0"

View File

@@ -68,6 +68,8 @@ pub struct AuthorityRoundParams {
/// Maximum number of accepted empty steps. /// Maximum number of accepted empty steps.
#[serde(rename="maximumEmptySteps")] #[serde(rename="maximumEmptySteps")]
pub maximum_empty_steps: Option<Uint>, pub maximum_empty_steps: Option<Uint>,
/// Strict validation of empty steps transition block.
pub strict_empty_steps_transition: Option<Uint>,
} }
/// Authority engine deserialization. /// Authority engine deserialization.

View File

@@ -1,18 +1,18 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd. // Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity Ethereum.
// Parity is free software: you can redistribute it and/or modify // Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// Parity is distributed in the hope that it will be useful, // Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Spec params deserialization. //! Spec params deserialization.
@@ -112,6 +112,10 @@ pub struct Params {
/// See `CommonParams` docs. /// See `CommonParams` docs.
#[serde(rename="eip1283Transition")] #[serde(rename="eip1283Transition")]
pub eip1283_transition: Option<Uint>, pub eip1283_transition: Option<Uint>,
/// See `CommonParams` docs.
#[serde(rename="eip1283DisableTransition")]
pub eip1283_disable_transition: Option<Uint>,
/// See `CommonParams` docs.
#[serde(rename="eip1014Transition")] #[serde(rename="eip1014Transition")]
pub eip1014_transition: Option<Uint>, pub eip1014_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
@@ -210,3 +214,4 @@ mod tests {
let _deserialized: Params = serde_json::from_str(s).unwrap(); let _deserialized: Params = serde_json::from_str(s).unwrap();
} }
} }

View File

@@ -30,6 +30,7 @@ pub enum ForkSpec {
Homestead, Homestead,
Byzantium, Byzantium,
Constantinople, Constantinople,
ConstantinopleFix,
EIP158ToByzantiumAt5, EIP158ToByzantiumAt5,
FrontierToHomesteadAt5, FrontierToHomesteadAt5,
HomesteadToDaoAt5, HomesteadToDaoAt5,

View File

@@ -474,7 +474,7 @@ impl TransactionQueue {
self.pool.read().pending_from_sender(state_readiness, address) self.pool.read().pending_from_sender(state_readiness, address)
.last() .last()
.map(|tx| tx.signed().nonce + 1) .map(|tx| tx.signed().nonce.saturating_add(U256::from(1)))
} }
/// Retrieve a transaction from the pool. /// Retrieve a transaction from the pool.

View File

@@ -95,7 +95,7 @@ impl<C: NonceClient> txpool::Ready<VerifiedTransaction> for State<C> {
}, },
cmp::Ordering::Less => txpool::Readiness::Stale, cmp::Ordering::Less => txpool::Readiness::Stale,
cmp::Ordering::Equal => { cmp::Ordering::Equal => {
*nonce = *nonce + 1; *nonce = nonce.saturating_add(U256::from(1));
txpool::Readiness::Ready txpool::Readiness::Ready
}, },
} }
@@ -159,7 +159,7 @@ impl<C: Fn(&Address) -> Option<U256>> txpool::Ready<VerifiedTransaction> for Opt
cmp::Ordering::Greater => txpool::Readiness::Future, cmp::Ordering::Greater => txpool::Readiness::Future,
cmp::Ordering::Less => txpool::Readiness::Stale, cmp::Ordering::Less => txpool::Readiness::Stale,
cmp::Ordering::Equal => { cmp::Ordering::Equal => {
*nonce = *nonce + 1; *nonce = nonce.saturating_add(U256::from(1));
txpool::Readiness::Ready txpool::Readiness::Ready
}, },
} }

View File

@@ -26,12 +26,18 @@ pub mod client;
use self::tx::{Tx, TxExt, PairExt}; use self::tx::{Tx, TxExt, PairExt};
use self::client::TestClient; use self::client::TestClient;
// max mem for 3 transaction, this is relative
// to the global use allocator, the value is currently
// set to reflect malloc usage.
// 50 was enough when using jmalloc.
const TEST_QUEUE_MAX_MEM: usize = 80;
fn new_queue() -> TransactionQueue { fn new_queue() -> TransactionQueue {
TransactionQueue::new( TransactionQueue::new(
txpool::Options { txpool::Options {
max_count: 3, max_count: 3,
max_per_sender: 3, max_per_sender: 3,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -49,7 +55,7 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() {
txpool::Options { txpool::Options {
max_count: 3, max_count: 3,
max_per_sender: 1, max_per_sender: 1,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -103,7 +109,7 @@ fn should_never_drop_local_transactions_from_different_senders() {
txpool::Options { txpool::Options {
max_count: 3, max_count: 3,
max_per_sender: 1, max_per_sender: 1,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -477,7 +483,7 @@ fn should_prefer_current_transactions_when_hitting_the_limit() {
txpool::Options { txpool::Options {
max_count: 1, max_count: 1,
max_per_sender: 2, max_per_sender: 2,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -707,7 +713,7 @@ fn should_accept_local_transactions_below_min_gas_price() {
txpool::Options { txpool::Options {
max_count: 3, max_count: 3,
max_per_sender: 3, max_per_sender: 3,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 10.into(), minimal_gas_price: 10.into(),
@@ -890,7 +896,7 @@ fn should_include_local_transaction_to_a_full_pool() {
txpool::Options { txpool::Options {
max_count: 1, max_count: 1,
max_per_sender: 2, max_per_sender: 2,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -922,7 +928,7 @@ fn should_avoid_verifying_transaction_already_in_pool() {
txpool::Options { txpool::Options {
max_count: 1, max_count: 1,
max_per_sender: 2, max_per_sender: 2,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -957,7 +963,7 @@ fn should_avoid_reverifying_recently_rejected_transactions() {
txpool::Options { txpool::Options {
max_count: 1, max_count: 1,
max_per_sender: 2, max_per_sender: 2,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -999,7 +1005,7 @@ fn should_reject_early_in_case_gas_price_is_less_than_min_effective() {
txpool::Options { txpool::Options {
max_count: 1, max_count: 1,
max_per_sender: 2, max_per_sender: 2,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),
@@ -1039,7 +1045,7 @@ fn should_not_reject_early_in_case_gas_price_is_less_than_min_effective() {
txpool::Options { txpool::Options {
max_count: 1, max_count: 1,
max_per_sender: 2, max_per_sender: 2,
max_mem_usage: 50 max_mem_usage: TEST_QUEUE_MAX_MEM
}, },
verifier::Options { verifier::Options {
minimal_gas_price: 1.into(), minimal_gas_price: 1.into(),

View File

@@ -283,7 +283,19 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
} }
} }
let cost = transaction.value + transaction.gas_price * transaction.gas; let (full_gas_price, overflow_1) = transaction.gas_price.overflowing_mul(transaction.gas);
let (cost, overflow_2) = transaction.value.overflowing_add(full_gas_price);
if overflow_1 || overflow_2 {
trace!(
target: "txqueue",
"[{:?}] Rejected tx, price overflow",
hash
);
bail!(transaction::Error::InsufficientBalance {
cost: U256::max_value(),
balance: account_details.balance,
});
}
if account_details.balance < cost { if account_details.balance < cost {
debug!( debug!(
target: "txqueue", target: "txqueue",

View File

@@ -25,7 +25,7 @@ use std::time::{Instant, Duration};
use atty; use atty;
use ethcore::client::{ use ethcore::client::{
BlockId, BlockChainClient, ChainInfo, BlockInfo, BlockChainInfo, BlockId, BlockChainClient, ChainInfo, BlockInfo, BlockChainInfo,
BlockQueueInfo, ChainNotify, ChainRoute, ClientReport, Client, ClientIoMessage BlockQueueInfo, ChainNotify, NewBlocks, ClientReport, Client, ClientIoMessage
}; };
use ethcore::header::BlockNumber; use ethcore::header::BlockNumber;
use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::{RestorationStatus, SnapshotService as SS};
@@ -38,7 +38,6 @@ use number_prefix::{binary_prefix, Standalone, Prefixed};
use parity_rpc::is_major_importing_or_waiting; use parity_rpc::is_major_importing_or_waiting;
use parity_rpc::informant::RpcStats; use parity_rpc::informant::RpcStats;
use ethereum_types::H256; use ethereum_types::H256;
use bytes::Bytes;
use parking_lot::{RwLock, Mutex}; use parking_lot::{RwLock, Mutex};
/// Format byte counts to standard denominations. /// Format byte counts to standard denominations.
@@ -365,29 +364,30 @@ impl<T: InformantData> Informant<T> {
} }
impl ChainNotify for Informant<FullNodeInformantData> { impl ChainNotify for Informant<FullNodeInformantData> {
fn new_blocks(&self, imported: Vec<H256>, _invalid: Vec<H256>, _route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, duration: Duration) { fn new_blocks(&self, new_blocks: NewBlocks) {
if new_blocks.has_more_blocks_to_import { return }
let mut last_import = self.last_import.lock(); let mut last_import = self.last_import.lock();
let client = &self.target.client; let client = &self.target.client;
let importing = self.target.is_major_importing(); let importing = self.target.is_major_importing();
let ripe = Instant::now() > *last_import + Duration::from_secs(1) && !importing; let ripe = Instant::now() > *last_import + Duration::from_secs(1) && !importing;
let txs_imported = imported.iter() let txs_imported = new_blocks.imported.iter()
.take(imported.len().saturating_sub(if ripe { 1 } else { 0 })) .take(new_blocks.imported.len().saturating_sub(if ripe { 1 } else { 0 }))
.filter_map(|h| client.block(BlockId::Hash(*h))) .filter_map(|h| client.block(BlockId::Hash(*h)))
.map(|b| b.transactions_count()) .map(|b| b.transactions_count())
.sum(); .sum();
if ripe { if ripe {
if let Some(block) = imported.last().and_then(|h| client.block(BlockId::Hash(*h))) { if let Some(block) = new_blocks.imported.last().and_then(|h| client.block(BlockId::Hash(*h))) {
let header_view = block.header_view(); let header_view = block.header_view();
let size = block.rlp().as_raw().len(); let size = block.rlp().as_raw().len();
let (skipped, skipped_txs) = (self.skipped.load(AtomicOrdering::Relaxed) + imported.len() - 1, self.skipped_txs.load(AtomicOrdering::Relaxed) + txs_imported); let (skipped, skipped_txs) = (self.skipped.load(AtomicOrdering::Relaxed) + new_blocks.imported.len() - 1, self.skipped_txs.load(AtomicOrdering::Relaxed) + txs_imported);
info!(target: "import", "Imported {} {} ({} txs, {} Mgas, {} ms, {} KiB){}", info!(target: "import", "Imported {} {} ({} txs, {} Mgas, {} ms, {} KiB){}",
Colour::White.bold().paint(format!("#{}", header_view.number())), Colour::White.bold().paint(format!("#{}", header_view.number())),
Colour::White.bold().paint(format!("{}", header_view.hash())), Colour::White.bold().paint(format!("{}", header_view.hash())),
Colour::Yellow.bold().paint(format!("{}", block.transactions_count())), Colour::Yellow.bold().paint(format!("{}", block.transactions_count())),
Colour::Yellow.bold().paint(format!("{:.2}", header_view.gas_used().low_u64() as f32 / 1000000f32)), Colour::Yellow.bold().paint(format!("{:.2}", header_view.gas_used().low_u64() as f32 / 1000000f32)),
Colour::Purple.bold().paint(format!("{}", duration.as_milliseconds())), Colour::Purple.bold().paint(format!("{}", new_blocks.duration.as_milliseconds())),
Colour::Blue.bold().paint(format!("{:.2}", size as f32 / 1024f32)), Colour::Blue.bold().paint(format!("{:.2}", size as f32 / 1024f32)),
if skipped > 0 { if skipped > 0 {
format!(" + another {} block(s) containing {} tx(s)", format!(" + another {} block(s) containing {} tx(s)",
@@ -403,7 +403,7 @@ impl ChainNotify for Informant<FullNodeInformantData> {
*last_import = Instant::now(); *last_import = Instant::now();
} }
} else { } else {
self.skipped.fetch_add(imported.len(), AtomicOrdering::Relaxed); self.skipped.fetch_add(new_blocks.imported.len(), AtomicOrdering::Relaxed);
self.skipped_txs.fetch_add(txs_imported, AtomicOrdering::Relaxed); self.skipped_txs.fetch_add(txs_imported, AtomicOrdering::Relaxed);
} }
} }

View File

@@ -41,11 +41,11 @@ use sync::LightSync;
use transaction::{Action, SignedTransaction, PendingTransaction, Transaction, Error as TransactionError}; use transaction::{Action, SignedTransaction, PendingTransaction, Transaction, Error as TransactionError};
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 reserved = self.nonces.lock().reserve(filled.from, state);
Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password, post_sign))
} }
let state = self.state_nonce(&filled.from);
let reserved = self.nonces.lock().reserve(filled.from, state);
Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password))
} }
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) => {
nonce.mark_used(); let nonce = self.ready
Async::Ready(tx) .take()
}) .expect("nonce is set before state transitions to WaitForPostSign; qed");
nonce.mark_used();
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)

View File

@@ -46,6 +46,7 @@ use ethereum_types::{U256, Address};
use hash::H256; use hash::H256;
use parking_lot::Mutex; use parking_lot::Mutex;
use fastmap::H256FastMap; use fastmap::H256FastMap;
use std::collections::BTreeMap;
use transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction}; use transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction};
use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch}; use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch};
@@ -310,9 +311,7 @@ impl LightFetch {
})) }))
} }
/// Get transaction logs pub fn logs_no_tx_hash(&self, filter: EthcoreFilter) -> impl Future<Item = Vec<Log>, Error = Error> + Send {
pub fn logs(&self, filter: EthcoreFilter) -> impl Future<Item = Vec<Log>, Error = Error> + Send {
use std::collections::BTreeMap;
use jsonrpc_core::futures::stream::{self, Stream}; use jsonrpc_core::futures::stream::{self, Stream};
const MAX_BLOCK_RANGE: u64 = 1000; const MAX_BLOCK_RANGE: u64 = 1000;
@@ -343,7 +342,7 @@ impl LightFetch {
// insert them into a BTreeMap to maintain order by number and block index. // insert them into a BTreeMap to maintain order by number and block index.
stream::futures_unordered(receipts_futures) stream::futures_unordered(receipts_futures)
.fold(BTreeMap::new(), move |mut matches, (num, hash, receipts)| { .fold(BTreeMap::new(), move |mut matches, (num, hash, receipts)| {
let mut block_index = 0; let mut block_index: usize = 0;
for (transaction_index, receipt) in receipts.into_iter().enumerate() { for (transaction_index, receipt) in receipts.into_iter().enumerate() {
for (transaction_log_index, log) in receipt.logs.into_iter().enumerate() { for (transaction_log_index, log) in receipt.logs.into_iter().enumerate() {
if filter.matches(&log) { if filter.matches(&log) {
@@ -366,9 +365,9 @@ impl LightFetch {
} }
} }
future::ok::<_,OnDemandError>(matches) future::ok::<_,OnDemandError>(matches)
}) // and then collect them into a vector. })
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
.map_err(errors::on_demand_error) .map_err(errors::on_demand_error)
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
}); });
match maybe_future { match maybe_future {
@@ -378,6 +377,39 @@ impl LightFetch {
}) })
} }
/// Get transaction logs
pub fn logs(&self, filter: EthcoreFilter) -> impl Future<Item = Vec<Log>, Error = Error> + Send {
use jsonrpc_core::futures::stream::{self, Stream};
let fetcher_block = self.clone();
self.logs_no_tx_hash(filter)
// retrieve transaction hash.
.and_then(move |mut result| {
let mut blocks = BTreeMap::new();
for log in result.iter() {
let block_hash = log.block_hash.as_ref().expect("Previously initialized with value; qed");
blocks.entry(block_hash.clone()).or_insert_with(|| {
fetcher_block.block(BlockId::Hash(block_hash.clone().into()))
});
}
// future get blocks (unordered it)
stream::futures_unordered(blocks.into_iter().map(|(_, v)| v)).collect().map(move |blocks| {
let transactions_per_block: BTreeMap<_, _> = blocks.iter()
.map(|block| (block.hash(), block.transactions())).collect();
for log in result.iter_mut() {
let log_index: U256 = log.transaction_index.expect("Previously initialized with value; qed").into();
let block_hash = log.block_hash.clone().expect("Previously initialized with value; qed").into();
let tx_hash = transactions_per_block.get(&block_hash)
// transaction index is from an enumerate call in log common so not need to check value
.and_then(|txs| txs.get(log_index.as_usize()))
.map(|tr| tr.hash().into());
log.transaction_hash = tx_hash;
}
result
})
})
}
// Get a transaction by hash. also returns the index in the block. // Get a transaction by hash. also returns the index in the block.
// Only returns transactions in the canonical chain. // Only returns transactions in the canonical chain.
pub fn transaction_by_hash(&self, tx_hash: H256) pub fn transaction_by_hash(&self, tx_hash: H256)

View File

@@ -141,6 +141,33 @@ enum PendingTransactionId {
Location(PendingOrBlock, usize) Location(PendingOrBlock, usize)
} }
pub fn base_logs<C, M, T: StateInfo + 'static> (client: &C, miner: &M, filter: Filter) -> BoxFuture<Vec<Log>> where
C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T>,
M: MinerService<State=T> {
let include_pending = filter.to_block == Some(BlockNumber::Pending);
let filter: EthcoreFilter = match filter.try_into() {
Ok(value) => value,
Err(err) => return Box::new(future::err(err)),
};
let mut logs = match client.logs(filter.clone()) {
Ok(logs) => logs
.into_iter()
.map(From::from)
.collect::<Vec<Log>>(),
Err(id) => return Box::new(future::err(errors::filter_block_not_found(id))),
};
if include_pending {
let best_block = client.chain_info().best_block_number;
let pending = pending_logs(&*miner, best_block, &filter);
logs.extend(pending);
}
let logs = limit_logs(logs, filter.limit);
Box::new(future::ok(logs))
}
impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> EthClient<C, SN, S, M, EM> where impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> EthClient<C, SN, S, M, EM> where
C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo, C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo,
SN: SnapshotService, SN: SnapshotService,
@@ -714,28 +741,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
} }
fn logs(&self, filter: Filter) -> BoxFuture<Vec<Log>> { fn logs(&self, filter: Filter) -> BoxFuture<Vec<Log>> {
let include_pending = filter.to_block == Some(BlockNumber::Pending); base_logs(&*self.client, &*self.miner, filter.into())
let filter: EthcoreFilter = match filter.try_into() {
Ok(value) => value,
Err(err) => return Box::new(future::err(err)),
};
let mut logs = match self.client.logs(filter.clone()) {
Ok(logs) => logs
.into_iter()
.map(From::from)
.collect::<Vec<Log>>(),
Err(id) => return Box::new(future::err(errors::filter_block_not_found(id))),
};
if include_pending {
let best_block = self.client.chain_info().best_block_number;
let pending = pending_logs(&*self.miner, best_block, &filter);
logs.extend(pending);
}
let logs = limit_logs(logs, filter.limit);
Box::new(future::ok(logs))
} }
fn work(&self, no_new_work_timeout: Trailing<u64>) -> Result<Work> { fn work(&self, no_new_work_timeout: Trailing<u64>) -> Result<Work> {

View File

@@ -18,7 +18,6 @@
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::time::Duration;
use jsonrpc_core::{BoxFuture, Result, Error}; use jsonrpc_core::{BoxFuture, Result, Error};
use jsonrpc_core::futures::{self, Future, IntoFuture}; use jsonrpc_core::futures::{self, Future, IntoFuture};
@@ -34,14 +33,13 @@ use v1::types::{pubsub, RichHeader, Log};
use ethcore::encoded; use ethcore::encoded;
use ethcore::filter::Filter as EthFilter; use ethcore::filter::Filter as EthFilter;
use ethcore::client::{BlockChainClient, ChainNotify, ChainRoute, ChainRouteType, BlockId}; use ethcore::client::{BlockChainClient, ChainNotify, NewBlocks, ChainRouteType, BlockId};
use sync::LightSync; use sync::LightSync;
use light::cache::Cache; use light::cache::Cache;
use light::on_demand::OnDemand; use light::on_demand::OnDemand;
use light::client::{LightChainClient, LightChainNotify}; use light::client::{LightChainClient, LightChainNotify};
use parity_runtime::Executor; use parity_runtime::Executor;
use ethereum_types::H256; use ethereum_types::H256;
use bytes::Bytes;
use parking_lot::{RwLock, Mutex}; use parking_lot::{RwLock, Mutex};
type Client = Sink<pubsub::Result>; type Client = Sink<pubsub::Result>;
@@ -220,18 +218,10 @@ impl<C: LightClient> LightChainNotify for ChainNotificationHandler<C> {
} }
impl<C: BlockChainClient> ChainNotify for ChainNotificationHandler<C> { impl<C: BlockChainClient> ChainNotify for ChainNotificationHandler<C> {
fn new_blocks( fn new_blocks(&self, new_blocks: NewBlocks) {
&self, if self.heads_subscribers.read().is_empty() && self.logs_subscribers.read().is_empty() { return }
_imported: Vec<H256>,
_invalid: Vec<H256>,
route: ChainRoute,
_sealed: Vec<H256>,
// Block bytes.
_proposed: Vec<Bytes>,
_duration: Duration,
) {
const EXTRA_INFO_PROOF: &'static str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed"; const EXTRA_INFO_PROOF: &'static str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed";
let headers = route.route() let headers = new_blocks.route.route()
.iter() .iter()
.filter_map(|&(hash, ref typ)| { .filter_map(|&(hash, ref typ)| {
match typ { match typ {
@@ -249,7 +239,7 @@ impl<C: BlockChainClient> ChainNotify for ChainNotificationHandler<C> {
self.notify_heads(&headers); self.notify_heads(&headers);
// We notify logs enacting and retracting as the order in route. // We notify logs enacting and retracting as the order in route.
self.notify_logs(route.route(), |filter, ex| { self.notify_logs(new_blocks.route.route(), |filter, ex| {
match ex { match ex {
&ChainRouteType::Enacted => &ChainRouteType::Enacted =>
Ok(self.client.logs(filter).unwrap_or_default().into_iter().map(Into::into).collect()), Ok(self.client.logs(filter).unwrap_or_default().into_iter().map(Into::into).collect()),

View File

@@ -28,7 +28,7 @@ use ethcore::account_provider::AccountProvider;
use ethcore_logger::RotatingLogger; use ethcore_logger::RotatingLogger;
use jsonrpc_core::{Result, BoxFuture}; use jsonrpc_core::{Result, BoxFuture};
use jsonrpc_core::futures::Future; use jsonrpc_core::futures::{future, Future};
use jsonrpc_macros::Trailing; use jsonrpc_macros::Trailing;
use v1::helpers::{self, errors, ipfs, SigningQueue, SignerService, NetworkSettings}; use v1::helpers::{self, errors, ipfs, SigningQueue, SignerService, NetworkSettings};
use v1::helpers::dispatch::LightDispatcher; use v1::helpers::dispatch::LightDispatcher;
@@ -42,6 +42,7 @@ use v1::types::{
BlockNumber, LightBlockNumber, ConsensusCapability, VersionInfo, BlockNumber, LightBlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, ChainStatus, OperationsInfo, ChainStatus,
AccountInfo, HwAccountInfo, Header, RichHeader, Receipt, AccountInfo, HwAccountInfo, Header, RichHeader, Receipt,
Log, Filter,
}; };
use Host; use Host;
@@ -414,4 +415,13 @@ impl Parity for ParityClient {
fn submit_work_detail(&self, _nonce: H64, _pow_hash: H256, _mix_hash: H256) -> Result<H256> { fn submit_work_detail(&self, _nonce: H64, _pow_hash: H256, _mix_hash: H256) -> Result<H256> {
Err(errors::light_unimplemented(None)) Err(errors::light_unimplemented(None))
} }
fn logs_no_tx_hash(&self, filter: Filter) -> BoxFuture<Vec<Log>> {
let filter = match filter.try_into() {
Ok(value) => value,
Err(err) => return Box::new(future::err(err)),
};
Box::new(self.fetcher().logs_no_tx_hash(filter)) as BoxFuture<_>
}
} }

View File

@@ -44,7 +44,7 @@ use v1::types::{
Peers, Transaction, RpcSettings, Histogram, Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus, TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo, BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, ChainStatus, OperationsInfo, ChainStatus, Log, Filter,
AccountInfo, HwAccountInfo, RichHeader, Receipt, AccountInfo, HwAccountInfo, RichHeader, Receipt,
block_number_to_id block_number_to_id
}; };
@@ -481,4 +481,10 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
fn submit_work_detail(&self, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result<H256> { fn submit_work_detail(&self, nonce: H64, pow_hash: H256, mix_hash: H256) -> Result<H256> {
helpers::submit_work_detail(&self.client, &self.miner, nonce, pow_hash, mix_hash) helpers::submit_work_detail(&self.client, &self.miner, nonce, pow_hash, mix_hash)
} }
fn logs_no_tx_hash(&self, filter: Filter) -> BoxFuture<Vec<Log>> {
use v1::impls::eth::base_logs;
// only specific impl for lightclient
base_logs(&*self.client, &*self.miner, filter.into())
}
} }

View File

@@ -18,7 +18,7 @@
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 transaction::PendingTransaction; use transaction::PendingTransaction;
use ethereum_types::{H520, U128, Address}; use ethereum_types::{H520, U128, Address};
@@ -27,7 +27,7 @@ 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,
@@ -41,6 +41,7 @@ use v1::types::{
use v1::metadata::Metadata; use v1::metadata::Metadata;
use eip712::{EIP712, hash_structured_data}; use eip712::{EIP712, hash_structured_data};
use jsonrpc_core::types::Value; use jsonrpc_core::types::Value;
use transaction::SignedTransaction;
/// Account management (personal) rpc implementation. /// Account management (personal) rpc implementation.
pub struct PersonalClient<D: Dispatcher> { pub struct PersonalClient<D: Dispatcher> {
@@ -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))
}) })
) )
} }

View File

@@ -24,7 +24,7 @@ use std::time::Duration;
use v1::{EthPubSub, EthPubSubClient, Metadata}; use v1::{EthPubSub, EthPubSubClient, Metadata};
use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify, ChainRoute, ChainRouteType}; use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify, NewBlocks, ChainRoute, ChainRouteType};
use parity_runtime::Runtime; use parity_runtime::Runtime;
const DURATION_ZERO: Duration = Duration::from_millis(0); const DURATION_ZERO: Duration = Duration::from_millis(0);
@@ -57,13 +57,13 @@ fn should_subscribe_to_new_heads() {
assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned())); assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned()));
// Check notifications // Check notifications
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO); handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO, true));
let (res, receiver) = receiver.into_future().wait().unwrap(); let (res, receiver) = receiver.into_future().wait().unwrap();
let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"author":"0x0000000000000000000000000000000000000000","difficulty":"0x1","extraData":"0x","gasLimit":"0xf4240","gasUsed":"0x0","hash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","number":"0x1","parentHash":"0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":[],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x1c9","stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","timestamp":"0x0","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"},"subscription":"0x416d77337e24399d"}}"#; let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"author":"0x0000000000000000000000000000000000000000","difficulty":"0x1","extraData":"0x","gasLimit":"0xf4240","gasUsed":"0x0","hash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","number":"0x1","parentHash":"0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":[],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x1c9","stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","timestamp":"0x0","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"},"subscription":"0x416d77337e24399d"}}"#;
assert_eq!(res, Some(response.into())); assert_eq!(res, Some(response.into()));
// Notify about two blocks // Notify about two blocks
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h2, ChainRouteType::Enacted), (h3, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO); handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h2, ChainRouteType::Enacted), (h3, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO, true));
// Receive both // Receive both
let (res, receiver) = receiver.into_future().wait().unwrap(); let (res, receiver) = receiver.into_future().wait().unwrap();
@@ -129,7 +129,7 @@ fn should_subscribe_to_logs() {
assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned())); assert_eq!(io.handle_request_sync(request, metadata.clone()), Some(response.to_owned()));
// Check notifications (enacted) // Check notifications (enacted)
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO); handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Enacted)]), vec![], vec![], DURATION_ZERO, false));
let (res, receiver) = receiver.into_future().wait().unwrap(); let (res, receiver) = receiver.into_future().wait().unwrap();
let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","removed":false,"topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned() let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","removed":false,"topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned()
+ &format!("0x{:x}", tx_hash) + &format!("0x{:x}", tx_hash)
@@ -137,7 +137,7 @@ fn should_subscribe_to_logs() {
assert_eq!(res, Some(response.into())); assert_eq!(res, Some(response.into()));
// Check notifications (retracted) // Check notifications (retracted)
handler.new_blocks(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Retracted)]), vec![], vec![], DURATION_ZERO); handler.new_blocks(NewBlocks::new(vec![], vec![], ChainRoute::new(vec![(h1, ChainRouteType::Retracted)]), vec![], vec![], DURATION_ZERO, false));
let (res, receiver) = receiver.into_future().wait().unwrap(); let (res, receiver) = receiver.into_future().wait().unwrap();
let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","removed":true,"topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned() let response = r#"{"jsonrpc":"2.0","method":"eth_subscription","params":{"result":{"address":"0x0000000000000000000000000000000000000005","blockHash":"0x3457d2fa2e3dd33c78ac681cf542e429becf718859053448748383af67e23218","blockNumber":"0x1","data":"0x","logIndex":"0x0","removed":true,"topics":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":""#.to_owned()
+ &format!("0x{:x}", tx_hash) + &format!("0x{:x}", tx_hash)

View File

@@ -20,13 +20,12 @@ use std::collections::BTreeMap;
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_macros::Trailing; use jsonrpc_macros::Trailing;
use v1::types::{ use v1::types::{
H64, H160, H256, H512, U256, Bytes, CallRequest, H64, H160, H256, H512, U256, Bytes, CallRequest,
Peers, Transaction, RpcSettings, Histogram, Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus, TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo, BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, ChainStatus, OperationsInfo, ChainStatus, Log, Filter,
AccountInfo, HwAccountInfo, RichHeader, Receipt, AccountInfo, HwAccountInfo, RichHeader, Receipt,
}; };
@@ -227,5 +226,11 @@ build_rpc_trait! {
/// but returns block hash on success, and returns an explicit error message on failure). /// but returns block hash on success, and returns an explicit error message on failure).
#[rpc(name = "parity_submitWorkDetail")] #[rpc(name = "parity_submitWorkDetail")]
fn submit_work_detail(&self, H64, H256, H256) -> Result<H256>; fn submit_work_detail(&self, H64, H256, H256) -> Result<H256>;
/// Returns logs matching given filter object.
/// Is allowed to skip filling transaction hash for faster query.
#[rpc(name = "parity_getLogsNoTransactionHash")]
fn logs_no_tx_hash(&self, Filter) -> BoxFuture<Vec<Log>>;
} }
} }

View File

@@ -74,7 +74,7 @@ impl<'a> Visitor<'a> for BytesVisitor {
} }
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: Error { fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: Error {
if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 { if value.len() >= 2 && value.starts_with("0x") && value.len() & 1 == 0 {
Ok(Bytes::new(FromHex::from_hex(&value[2..]).map_err(|e| Error::custom(format!("Invalid hex: {}", e)))?)) Ok(Bytes::new(FromHex::from_hex(&value[2..]).map_err(|e| Error::custom(format!("Invalid hex: {}", e)))?))
} else { } else {
Err(Error::custom("Invalid bytes format. Expected a 0x-prefixed hex string with even length")) Err(Error::custom("Invalid bytes format. Expected a 0x-prefixed hex string with even length"))
@@ -101,6 +101,7 @@ mod tests {
#[test] #[test]
fn test_bytes_deserialize() { fn test_bytes_deserialize() {
let bytes0: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""∀∂""#);
let bytes1: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""""#); let bytes1: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""""#);
let bytes2: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0x123""#); let bytes2: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0x123""#);
let bytes3: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0xgg""#); let bytes3: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0xgg""#);
@@ -109,6 +110,7 @@ mod tests {
let bytes5: Bytes = serde_json::from_str(r#""0x12""#).unwrap(); let bytes5: Bytes = serde_json::from_str(r#""0x12""#).unwrap();
let bytes6: Bytes = serde_json::from_str(r#""0x0123""#).unwrap(); let bytes6: Bytes = serde_json::from_str(r#""0x0123""#).unwrap();
assert!(bytes0.is_err());
assert!(bytes1.is_err()); assert!(bytes1.is_err());
assert!(bytes2.is_err()); assert!(bytes2.is_err());
assert!(bytes3.is_err()); assert!(bytes3.is_err());

View File

@@ -129,7 +129,7 @@ macro_rules! impl_hash {
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error { fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
if value.len() < 2 || &value[0..2] != "0x" { if value.len() < 2 || !value.starts_with("0x") {
return Err(E::custom("expected a hex-encoded hash with 0x prefix")); return Err(E::custom("expected a hex-encoded hash with 0x prefix"));
} }
if value.len() != 2 + $size * 2 { if value.len() != 2 + $size * 2 {

View File

@@ -72,7 +72,7 @@ macro_rules! impl_uint {
} }
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error { fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
if value.len() < 2 || &value[0..2] != "0x" { if value.len() < 2 || !value.starts_with("0x") {
return Err(E::custom("expected a hex-encoded numbers with 0x prefix")) return Err(E::custom("expected a hex-encoded numbers with 0x prefix"))
} }
@@ -140,12 +140,14 @@ mod tests {
#[test] #[test]
fn should_fail_to_deserialize_decimals() { fn should_fail_to_deserialize_decimals() {
let deserialized0: Res = serde_json::from_str(r#""∀∂""#);
let deserialized1: Res = serde_json::from_str(r#""""#); let deserialized1: Res = serde_json::from_str(r#""""#);
let deserialized2: Res = serde_json::from_str(r#""0""#); let deserialized2: Res = serde_json::from_str(r#""0""#);
let deserialized3: Res = serde_json::from_str(r#""10""#); let deserialized3: Res = serde_json::from_str(r#""10""#);
let deserialized4: Res = serde_json::from_str(r#""1000000""#); let deserialized4: Res = serde_json::from_str(r#""1000000""#);
let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#); let deserialized5: Res = serde_json::from_str(r#""1000000000000000000""#);
assert!(deserialized0.is_err());
assert!(deserialized1.is_err()); assert!(deserialized1.is_err());
assert!(deserialized2.is_err()); assert!(deserialized2.is_err());
assert!(deserialized3.is_err()); assert!(deserialized3.is_err());

View File

@@ -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
@@ -10,31 +7,25 @@ RUN apt update && apt install -y --no-install-recommends openssl libudev-dev fil
# show backtraces # show backtraces
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 WORKDIR /home/parity
ENV PATH "~/bin:${PATH}" # add parity-ethereum to docker image
COPY artifacts/x86_64-unknown-linux-gnu/parity /bin/parity
#add TARGET to docker image
COPY artifacts/x86_64-unknown-linux-gnu/$TARGET ./bin/$TARGET
# 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"]

View File

@@ -1,14 +1,30 @@
FROM ubuntu:14.04 FROM ubuntu:xenial
WORKDIR /build WORKDIR /build
# install aarch64(armv8) dependencies and tools
RUN dpkg --add-architecture arm64
RUN echo '# source urls for arm64 \n\
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial main \n\
deb-src [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial main \n\
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main \n\
deb-src [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main \n\
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-security main \n\
deb-src [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-security main \n # end arm64 section' >> /etc/apt/sources.list &&\
sed -r 's/deb h/deb \[arch=amd64\] h/g' /etc/apt/sources.list > /tmp/sources-tmp.list && \
cp /tmp/sources-tmp.list /etc/apt/sources.list&& \
sed -r 's/deb-src h/deb-src \[arch=amd64\] h/g' /etc/apt/sources.list > /tmp/sources-tmp.list&&cat /etc/apt/sources.list &&\
cp /tmp/sources-tmp.list /etc/apt/sources.list&& echo "next"&&cat /etc/apt/sources.list
# install tools and dependencies # install tools and dependencies
RUN apt-get -y update && \ RUN apt-get -y update && \
apt-get install -y --force-yes --no-install-recommends \ apt-get upgrade -y && \
curl git make g++ gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ apt-get install -y --no-install-recommends \
libc6-arm64-cross libc6-dev-arm64-cross wget file ca-certificates \ curl make cmake file ca-certificates \
binutils-aarch64-linux-gnu cmake3 libudev-dev \ g++ gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \
&& \ libc6-dev-arm64-cross binutils-aarch64-linux-gnu \
apt-get clean libudev-dev libudev-dev:arm64 \
&& \
apt-get clean
# install rustup # install rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
@@ -30,14 +46,14 @@ RUN rustc -vV && cargo -V
# build parity # build parity
ADD . /build/parity ADD . /build/parity
RUN cd parity && \ RUN cd parity && \
mkdir -p .cargo && \ mkdir -p .cargo && \
echo '[target.aarch64-unknown-linux-gnu]\n\ echo '[target.aarch64-unknown-linux-gnu]\n\
linker = "aarch64-linux-gnu-gcc"\n'\ linker = "aarch64-linux-gnu-gcc"\n'\
>>.cargo/config && \ >>.cargo/config && \
cat .cargo/config && \ cat .cargo/config && \
cargo build --target aarch64-unknown-linux-gnu --release --verbose && \ cargo build --target aarch64-unknown-linux-gnu --release --verbose && \
ls /build/parity/target/aarch64-unknown-linux-gnu/release/parity && \ ls /build/parity/target/aarch64-unknown-linux-gnu/release/parity && \
/usr/bin/aarch64-linux-gnu-strip /build/parity/target/aarch64-unknown-linux-gnu/release/parity /usr/bin/aarch64-linux-gnu-strip /build/parity/target/aarch64-unknown-linux-gnu/release/parity
RUN file /build/parity/target/aarch64-unknown-linux-gnu/release/parity RUN file /build/parity/target/aarch64-unknown-linux-gnu/release/parity

View File

@@ -9,48 +9,34 @@ 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
echo "__________CARGO CONFIG__________" export RUSTFLAGS=" -C link-arg=-s"
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
then
# use build container's cargo config
cat /.cargo/config
else
mkdir -p .cargo
rm -f .cargo/config
echo "[target.$CARGO_TARGET]" >> .cargo/config
echo "linker= \"$CC\"" >> .cargo/config
cat .cargo/config
fi
echo "_____ Building target: "$CARGO_TARGET" _____" echo "_____ Building target: "$CARGO_TARGET" _____"
time cargo build --target $CARGO_TARGET --release --features final
time cargo build --target $CARGO_TARGET --release -p evmbin
time cargo build --target $CARGO_TARGET --release -p ethstore-cli
time cargo build --target $CARGO_TARGET --release -p ethkey-cli
time cargo build --target $CARGO_TARGET --release -p whisper-cli
echo "_____ Post-processing binaries _____"
rm -rf artifacts
mkdir -p artifacts
cd artifacts
mkdir -p $CARGO_TARGET
cd $CARGO_TARGET
cp -v ../../target/$CARGO_TARGET/release/parity ./parity
cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm
cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore
cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey
cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
# stripping can also be done on release build time
# export RUSTFLAGS="${RUSTFLAGS} -C link-arg=-s"
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ] if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
then then
arm-linux-androideabi-strip -v ./* time cargo build --target $CARGO_TARGET --release -p parity-clib --features final
else else
strip -v ./* time cargo build --target $CARGO_TARGET --release --features final
time cargo build --target $CARGO_TARGET --release -p evmbin
time cargo build --target $CARGO_TARGET --release -p ethstore-cli
time cargo build --target $CARGO_TARGET --release -p ethkey-cli
time cargo build --target $CARGO_TARGET --release -p whisper-cli
fi
echo "_____ Post-processing binaries _____"
mkdir -p artifacts/$CARGO_TARGET
cd artifacts/$CARGO_TARGET
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
then
cp -v ../../target/$CARGO_TARGET/release/libparity.so ./libparity.so
else
cp -v ../../target/$CARGO_TARGET/release/parity ./parity
cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm
cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore
cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey
cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
fi fi
echo "_____ Calculating checksums _____" echo "_____ Calculating checksums _____"
@@ -64,4 +50,3 @@ do
./parity tools hash $binary > $binary.sha3 ./parity tools hash $binary > $binary.sha3
fi fi
done done

View File

@@ -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

View File

@@ -7,6 +7,7 @@ clone_repos() {
echo "__________Clone repos__________" echo "__________Clone repos__________"
git clone https://github.com/parity-js/jsonrpc.git jsonrpc git clone https://github.com/parity-js/jsonrpc.git jsonrpc
git clone https://github.com/paritytech/wiki.git wiki git clone https://github.com/paritytech/wiki.git wiki
git clone https://github.com/paritytech/parity-config-generator
} }
build_docs() { build_docs() {
@@ -15,18 +16,25 @@ build_docs() {
npm run build:markdown npm run build:markdown
} }
build_config() {
echo "_______Build config docs______"
yarn install
AUTOGENSCRIPT=1 yarn generate-docs
}
update_wiki_docs() { update_wiki_docs() {
echo "__________Update WIKI docs__________" echo "__________Update WIKI docs__________"
for file in $(ls jsonrpc/docs); do for file in $(ls jsonrpc/docs); do
module_name=${file:0:-3} module_name=${file:0:-3}
mv jsonrpc/docs/$file wiki/JSONRPC-$module_name-module.md mv jsonrpc/docs/$file wiki/JSONRPC-$module_name-module.md
done done
mv parity-config-generator/docs/config.md wiki/Configuring-Parity-Ethereum.md
} }
setup_git() { setup_git() {
echo "__________Set github__________" echo "__________Set github__________"
git config user.email "devops@parity.com" git config --global user.email "devops@parity.com"
git config user.name "Devops Parity" git config --global user.name "Devops Parity"
} }
set_remote_wiki() { set_remote_wiki() {
@@ -38,13 +46,13 @@ commit_files() {
git checkout -b rpcdoc-update-${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}} git checkout -b rpcdoc-update-${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}
git add . git add .
git commit -m "Update docs to ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" git commit -m "Update docs to ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}"
git tag -a "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" -m "Update RPC docs to ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" git tag -a -f "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" -m "Update RPC and config docs to ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}"
} }
upload_files() { upload_files() {
echo "__________Upload files__________" echo "__________Upload files__________"
git push origin HEAD git push -q origin HEAD
git push --tags git push -q -f --tags
} }
RPC_TRAITS_DIR="rpc/src/v1/traits" RPC_TRAITS_DIR="rpc/src/v1/traits"
@@ -56,6 +64,9 @@ cp $RPC_TRAITS_DIR/*.rs "jsonrpc/.parity/$RPC_TRAITS_DIR"
cd jsonrpc cd jsonrpc
build_docs build_docs
cd .. cd ..
cd parity-config-generator
build_config
cd ..
update_wiki_docs update_wiki_docs
cd wiki cd wiki
set_remote_wiki set_remote_wiki

View File

@@ -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}}/

52
scripts/gitlab/publish-snap.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/bash
set -e # fail on any error
set -u # treat unset variables as error
# some necromancy:
# gsub(/"/, "", $2) deletes "qoutes"
# gsub(/ /, "", $2) deletes whitespaces
TRACK=`awk -F '=' '/^track/ {gsub(/"/, "", $2); gsub(/ /, "", $2); print $2}' ./util/version/Cargo.toml`
echo Track is: $TRACK
case ${TRACK} in
nightly) export GRADE="devel" CHANNEL="edge";;
beta) export GRADE="stable" CHANNEL="beta";;
stable) export GRADE="stable" CHANNEL="stable";;
*) echo "No release" && exit 0;;
esac
SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap"
echo "__________Create snap package__________"
echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME
echo $VERSION:$GRADE:$BUILD_ARCH
# cat scripts/snap/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml
# 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
snapcraft --target-arch=$BUILD_ARCH
ls *.snap
echo "__________Calculating checksums__________"
rhash --sha256 $SNAP_PACKAGE -o $SNAP_PACKAGE".sha256"
cat $SNAP_PACKAGE".sha256"
echo "__________Releasing snap package__________"
echo "Release channel :" $CHANNEL " Branch/tag: " $CI_COMMIT_REF_NAME
echo $SNAPCRAFT_LOGIN_PARITY_BASE64 | base64 --decode > snapcraft.login
snapcraft login --with snapcraft.login
snapcraft push --release $CHANNEL $SNAP_PACKAGE
snapcraft status parity
snapcraft logout

View File

@@ -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

BIN
scripts/snap/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Parity Ethereum
Comment=The fastest and most advanced Ethereum client.
Exec=parity
Icon=/usr/share/pixmaps/icon.png
Terminal=true

View File

@@ -0,0 +1,53 @@
name: parity
version: $VERSION
architectures: [$BUILD_ARCH]
grade: $GRADE
confinement: strict
summary: Fast, light, robust Ethereum implementation
description: |
Parity's goal is to be the fastest, lightest, and most secure Ethereum
client. We are developing Parity using the sophisticated and cutting-edge
Rust programming language. Parity is licensed under the GPLv3, and can be
used for all your Ethereum needs.
apps:
parity:
command: parity
plugs: [home, network, network-bind, mount-observe, x11, unity7, desktop, desktop-legacy, wayland]
desktop: ./usr/share/applications/parity.desktop
parity-evm:
command: parity-evm
plugs: [home, network, network-bind]
ethkey:
command: ethkey
plugs: [home]
ethstore:
command: ethstore
plugs: [home]
whisper:
command: whisper
plugs: [home, network-bind]
icon: ./scripts/snap/icon.png
parts:
desktop-icon:
source: ./scripts/snap
plugin: nil
override-build: |
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/share/applications
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/share/pixmaps
cp -v ./parity.desktop $SNAPCRAFT_PART_INSTALL/usr/share/applications/
cp -v ./icon.png $SNAPCRAFT_PART_INSTALL/usr/share/pixmaps/
parity:
source: ./artifacts/$CARGO_TARGET
plugin: nil
override-build: |
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/bin
cp -v parity $SNAPCRAFT_PART_INSTALL/usr/bin/parity
cp -v parity-evm $SNAPCRAFT_PART_INSTALL/usr/bin/parity-evm
cp -v ethkey $SNAPCRAFT_PART_INSTALL/usr/bin/ethkey
cp -v ethstore $SNAPCRAFT_PART_INSTALL/usr/bin/ethstore
cp -v whisper $SNAPCRAFT_PART_INSTALL/usr/bin/whisper
stage-packages: [libc6, libudev1, libstdc++6, cmake, libdb5.3]

View File

@@ -16,12 +16,10 @@
use std::sync::Arc; use std::sync::Arc;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::time::Duration;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use ethcore::client::{BlockId, ChainNotify, ChainRoute, CallContract}; use ethcore::client::{BlockId, ChainNotify, NewBlocks, CallContract};
use ethereum_types::{H256, Address}; use ethereum_types::Address;
use ethabi::FunctionOutputDecoder; use ethabi::FunctionOutputDecoder;
use bytes::Bytes;
use trusted_client::TrustedClient; use trusted_client::TrustedClient;
use types::{Error, ServerKeyId, ContractAddress}; use types::{Error, ServerKeyId, ContractAddress};
@@ -77,8 +75,9 @@ impl AclStorage for OnChainAclStorage {
} }
impl ChainNotify for OnChainAclStorage { impl ChainNotify for OnChainAclStorage {
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) { fn new_blocks(&self, new_blocks: NewBlocks) {
if !route.enacted().is_empty() || !route.retracted().is_empty() { if new_blocks.has_more_blocks_to_import { return }
if !new_blocks.route.enacted().is_empty() || !new_blocks.route.retracted().is_empty() {
self.contract.lock().update_contract_address() self.contract.lock().update_contract_address()
} }
} }

View File

@@ -17,10 +17,9 @@
use std::sync::Arc; use std::sync::Arc;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, HashSet};
use std::time::Duration;
use parking_lot::Mutex; use parking_lot::Mutex;
use ethabi::FunctionOutputDecoder; use ethabi::FunctionOutputDecoder;
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, ChainRoute, CallContract}; use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify, NewBlocks, CallContract};
use ethereum_types::{H256, Address}; use ethereum_types::{H256, Address};
use ethkey::public_to_address; use ethkey::public_to_address;
use bytes::Bytes; use bytes::Bytes;
@@ -151,8 +150,9 @@ impl KeyServerSet for OnChainKeyServerSet {
} }
impl ChainNotify for OnChainKeyServerSet { impl ChainNotify for OnChainKeyServerSet {
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) { fn new_blocks(&self, new_blocks: NewBlocks) {
let (enacted, retracted) = route.into_enacted_retracted(); if new_blocks.has_more_blocks_to_import { return }
let (enacted, retracted) = new_blocks.route.into_enacted_retracted();
if !enacted.is_empty() || !retracted.is_empty() { if !enacted.is_empty() || !retracted.is_empty() {
self.contract.lock().update(enacted, retracted) self.contract.lock().update(enacted, retracted)

View File

@@ -17,10 +17,9 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
use std::thread; use std::thread;
use parking_lot::Mutex; use parking_lot::Mutex;
use ethcore::client::{ChainNotify, ChainRoute}; use ethcore::client::{ChainNotify, NewBlocks};
use ethkey::{Public, public_to_address}; use ethkey::{Public, public_to_address};
use bytes::Bytes; use bytes::Bytes;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
@@ -435,9 +434,10 @@ impl Drop for ServiceContractListener {
} }
impl ChainNotify for ServiceContractListener { impl ChainNotify for ServiceContractListener {
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) { fn new_blocks(&self, new_blocks: NewBlocks) {
let enacted_len = route.enacted().len(); if new_blocks.has_more_blocks_to_import { return }
if enacted_len == 0 && route.retracted().is_empty() { let enacted_len = new_blocks.route.enacted().len();
if enacted_len == 0 && new_blocks.route.retracted().is_empty() {
return; return;
} }

33
test.sh
View File

@@ -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
@@ -35,9 +14,9 @@ validate () {
if [ "$VALIDATE" -eq "1" ] if [ "$VALIDATE" -eq "1" ]
then then
echo "________Validate build________" echo "________Validate build________"
time cargo check $@ --no-default-features time cargo check $@ --locked --no-default-features
time cargo check $@ --manifest-path util/io/Cargo.toml --no-default-features time cargo check $@ --locked --manifest-path util/io/Cargo.toml --no-default-features
time cargo check $@ --manifest-path util/io/Cargo.toml --features "mio" time cargo check $@ --locked --manifest-path util/io/Cargo.toml --features "mio"
# Validate chainspecs # Validate chainspecs
echo "________Validate chainspecs________" echo "________Validate chainspecs________"
@@ -57,7 +36,6 @@ cpp_test () {
cd build && \ cd build && \
cmake .. && \ cmake .. && \
make -j $THREADS && \ make -j $THREADS && \
./parity-example && \
cd .. && \ cd .. && \
rm -rf build && \ rm -rf build && \
cd ../.. cd ../..
@@ -71,7 +49,7 @@ cpp_test () {
cargo_test () { cargo_test () {
echo "________Running Parity Full Test Suite________" echo "________Running Parity Full Test Suite________"
git submodule update --init --recursive git submodule update --init --recursive
time cargo test $OPTIONS --features "$FEATURES" --all $@ -- --test-threads $THREADS time cargo test $OPTIONS --features "$FEATURES" --locked --all $@ -- --test-threads $THREADS
} }
@@ -98,4 +76,3 @@ then
else else
cargo_test $@ cargo_test $@
fi fi

View File

@@ -25,9 +25,8 @@ use parking_lot::{Mutex, MutexGuard};
use rand::{self, Rng}; use rand::{self, Rng};
use target_info::Target; use target_info::Target;
use bytes::Bytes;
use ethcore::BlockNumber; use ethcore::BlockNumber;
use ethcore::client::{BlockId, BlockChainClient, ChainNotify, ChainRoute}; use ethcore::client::{BlockId, BlockChainClient, ChainNotify, NewBlocks};
use ethcore::filter::Filter; use ethcore::filter::Filter;
use ethereum_types::H256; use ethereum_types::H256;
use hash_fetch::{self as fetch, HashFetch}; use hash_fetch::{self as fetch, HashFetch};
@@ -669,7 +668,8 @@ impl<O: OperationsClient, F: HashFetch, T: TimeProvider, R: GenRange> Updater<O,
} }
impl ChainNotify for Updater { impl ChainNotify for Updater {
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, _route: ChainRoute, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: Duration) { fn new_blocks(&self, new_blocks: NewBlocks) {
if new_blocks.has_more_blocks_to_import { return }
match (self.client.upgrade(), self.sync.as_ref().and_then(Weak::upgrade)) { match (self.client.upgrade(), self.sync.as_ref().and_then(Weak::upgrade)) {
(Some(ref c), Some(ref s)) if !s.status().is_syncing(c.queue_info()) => self.poll(), (Some(ref c), Some(ref s)) if !s.status().is_syncing(c.queue_info()) => self.poll(),
_ => {}, _ => {},

View File

@@ -35,6 +35,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]
tempdir = "0.3" tempdir = "0.3"

View File

@@ -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};
@@ -53,12 +54,17 @@ const REQUEST_BACKOFF: [Duration; 4] = [
Duration::from_secs(64) Duration::from_secs(64)
]; ];
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,
pub endpoint: NodeEndpoint, pub endpoint: NodeEndpoint,
} }
#[derive(Debug)]
pub struct BucketEntry { pub struct BucketEntry {
pub address: NodeEntry, pub address: NodeEntry,
pub id_hash: H256, pub id_hash: H256,
@@ -89,6 +95,32 @@ struct FindNodeRequest {
answered: bool, answered: bool,
} }
#[derive(Clone, Copy)]
enum PingReason {
Default,
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 {
// Time when the request was sent // Time when the request was sent
sent_at: Instant, sent_at: Instant,
@@ -99,8 +131,10 @@ struct PingRequest {
// The hash Parity used to respond with (until rev 01f825b0e1f1c4c420197b51fc801cbe89284b29) // The hash Parity used to respond with (until rev 01f825b0e1f1c4c420197b51fc801cbe89284b29)
#[deprecated()] #[deprecated()]
deprecated_echo_hash: H256, deprecated_echo_hash: H256,
reason: PingReason
} }
#[derive(Debug)]
pub struct NodeBucket { pub struct NodeBucket {
nodes: VecDeque<BucketEntry>, //sorted by last active nodes: VecDeque<BucketEntry>, //sorted by last active
} }
@@ -134,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>,
@@ -160,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(),
@@ -178,7 +219,7 @@ impl<'a> Discovery<'a> {
if self.node_buckets[dist].nodes.iter().any(|n| n.id_hash == id_hash) { if self.node_buckets[dist].nodes.iter().any(|n| n.id_hash == id_hash) {
return; return;
} }
self.try_ping(e); self.try_ping(e, PingReason::Default);
} }
} }
@@ -189,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 bucket = &mut self.node_buckets[dist];
bucket.nodes.iter_mut().find(|n| n.address.id == e.id)
.map_or(Err(BucketError::NotInTheBucket{node_entry: e.clone(), bucket_distance: dist}.into()), |entry| {
entry.address = e;
entry.last_seen = Instant::now();
entry.backoff_until = Instant::now();
entry.fail_count = 0;
Ok(())
})
}
let mut added_map = HashMap::new(); fn update_node(&mut self, e: NodeEntry) -> Option<TableUpdates> {
let ping = { trace!(target: "discovery", "Inserting {:?}", &e);
let bucket = &mut self.node_buckets[dist];
let updated = if let Some(node) = bucket.nodes.iter_mut().find(|n| n.address.id == e.id) {
node.address = e.clone();
node.last_seen = Instant::now();
node.backoff_until = Instant::now();
node.fail_count = 0;
true
} else { false };
if !updated { match self.update_bucket_record(e) {
added_map.insert(e.id, e.clone()); Ok(()) => None,
bucket.nodes.push_front(BucketEntry::new(e)); 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); if let Some(node) = node_to_ping {
} self.try_ping(node, PingReason::Default);
Some(TableUpdates { added: added_map, removed: HashSet::new() }) };
TableUpdates{added, removed: HashSet::new()}
})
} }
/// Starts the discovery process at round 0 /// Starts the discovery process at round 0
@@ -244,7 +297,7 @@ impl<'a> Discovery<'a> {
fn update_new_nodes(&mut self) { fn update_new_nodes(&mut self) {
while self.in_flight_pings.len() < MAX_NODES_PING { while self.in_flight_pings.len() < MAX_NODES_PING {
match self.adding_nodes.pop() { match self.adding_nodes.pop() {
Some(next) => self.try_ping(next), Some(next) => self.try_ping(next, PingReason::Default),
None => break, None => break,
} }
} }
@@ -298,7 +351,7 @@ impl<'a> Discovery<'a> {
None // a and b are equal, so log distance is -inf None // a and b are equal, so log distance is -inf
} }
fn try_ping(&mut self, node: NodeEntry) { fn try_ping(&mut self, node: NodeEntry, reason: PingReason) {
if !self.is_allowed(&node) { if !self.is_allowed(&node) {
trace!(target: "discovery", "Node {:?} not allowed", node); trace!(target: "discovery", "Node {:?} not allowed", node);
return; return;
@@ -313,7 +366,7 @@ impl<'a> Discovery<'a> {
} }
if self.in_flight_pings.len() < MAX_NODES_PING { if self.in_flight_pings.len() < MAX_NODES_PING {
self.ping(&node) self.ping(&node, reason)
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
warn!(target: "discovery", "Error sending Ping packet: {:?}", e); warn!(target: "discovery", "Error sending Ping packet: {:?}", e);
}); });
@@ -322,7 +375,7 @@ impl<'a> Discovery<'a> {
} }
} }
fn ping(&mut self, node: &NodeEntry) -> Result<(), Error> { fn ping(&mut self, node: &NodeEntry, reason: PingReason) -> Result<(), Error> {
let mut rlp = RlpStream::new_list(4); let mut rlp = RlpStream::new_list(4);
rlp.append(&PROTOCOL_VERSION); rlp.append(&PROTOCOL_VERSION);
self.public_endpoint.to_rlp_list(&mut rlp); self.public_endpoint.to_rlp_list(&mut rlp);
@@ -336,6 +389,7 @@ impl<'a> Discovery<'a> {
node: node.clone(), node: node.clone(),
echo_hash: hash, echo_hash: hash,
deprecated_echo_hash: old_parity_hash, deprecated_echo_hash: old_parity_hash,
reason: reason
}); });
trace!(target: "discovery", "Sent Ping to {:?} ; node_id={:#x}", &node.endpoint, node.id); trace!(target: "discovery", "Sent Ping to {:?} ; node_id={:#x}", &node.endpoint, node.id);
@@ -515,7 +569,7 @@ impl<'a> Discovery<'a> {
if request.deprecated_echo_hash == echo_hash { if request.deprecated_echo_hash == echo_hash {
trace!(target: "discovery", "Got Pong from an old parity-ethereum version."); trace!(target: "discovery", "Got Pong from an old parity-ethereum version.");
} }
Some(request.node.clone()) Some((request.node.clone(), request.reason.clone()))
} }
}; };
@@ -529,29 +583,98 @@ impl<'a> Discovery<'a> {
}, },
}; };
if let Some(node) = expected_node { if let Some((node, ping_reason)) = expected_node {
Ok(self.update_node(node)) if let PingReason::FromDiscoveryRequest(target, validity) = ping_reason {
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))
}
} 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)
} }
} }
fn on_find_node(&mut self, rlp: &Rlp, _node: &NodeId, from: &SocketAddr) -> Result<Option<TableUpdates>, Error> { fn on_find_node(&mut self, rlp: &Rlp, node_id: &NodeId, from: &SocketAddr) -> Result<Option<TableUpdates>, Error> {
trace!(target: "discovery", "Got FindNode from {:?}", &from); trace!(target: "discovery", "Got FindNode from {:?}", &from);
let target: NodeId = rlp.val_at(0)?; let target: NodeId = rlp.val_at(0)?;
let timestamp: u64 = rlp.val_at(1)?; let timestamp: u64 = rlp.val_at(1)?;
self.check_timestamp(timestamp)?; self.check_timestamp(timestamp)?;
let node = NodeEntry {
id: node_id.clone(),
endpoint: NodeEndpoint {
address: *from,
udp_port: from.port()
}
};
match self.check_validity(&node) {
NodeValidity::Ourselves => (), // It makes no sense to respond to the discovery request from ourselves
NodeValidity::ValidNode(_) => self.respond_with_discovery(target, &node)?,
// Make sure the request source is actually there and responds to pings before actually responding
invalidity_reason => self.try_ping(node, PingReason::FromDiscoveryRequest(target, invalidity_reason))
}
Ok(None)
}
fn check_validity(&mut self, node: &NodeEntry) -> NodeValidity {
let id_hash = keccak(node.id);
let dist = match Discovery::distance(&self.id_hash, &id_hash) {
Some(dist) => dist,
None => {
debug!(target: "discovery", "Got an incoming discovery request from self: {:?}", node);
return NodeValidity::Ourselves;
}
};
let bucket = &self.node_buckets[dist];
if let Some(known_node) = bucket.nodes.iter().find(|n| n.address.id == node.id) {
debug!(target: "discovery", "Found a known node in a bucket when processing discovery: {:?}/{:?}", known_node, node);
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 {
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
}
})
}
}
fn respond_with_discovery(&mut self, target: NodeId, node: &NodeEntry) -> Result<(), Error> {
let nearest = self.nearest_node_entries(&target); let nearest = self.nearest_node_entries(&target);
if nearest.is_empty() { if nearest.is_empty() {
return Ok(None); return Ok(());
} }
let mut packets = Discovery::prepare_neighbours_packets(&nearest); let mut packets = Discovery::prepare_neighbours_packets(&nearest);
for p in packets.drain(..) { for p in packets.drain(..) {
self.send_packet(PACKET_NEIGHBOURS, from, &p)?; self.send_packet(PACKET_NEIGHBOURS, &node.endpoint.address, &p)?;
} }
trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &from); trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &node.endpoint);
Ok(None) Ok(())
} }
fn prepare_neighbours_packets(nearest: &[NodeEntry]) -> Vec<Bytes> { fn prepare_neighbours_packets(nearest: &[NodeEntry]) -> Vec<Bytes> {
@@ -827,7 +950,7 @@ mod tests {
} }
// After 4 discovery rounds, the first one should have learned about the rest. // After 4 discovery rounds, the first one should have learned about the rest.
for _round in 0 .. 4 { for _round in 0 .. 5 {
discovery_handlers[0].round(); discovery_handlers[0].round();
let mut continue_loop = true; let mut continue_loop = true;
@@ -835,9 +958,9 @@ mod tests {
continue_loop = false; continue_loop = false;
// Process all queued messages. // Process all queued messages.
for i in 0 .. 5 { for i in 0 .. 20 {
let src = discovery_handlers[i].public_endpoint.address.clone(); let src = discovery_handlers[i%5].public_endpoint.address.clone();
while let Some(datagram) = discovery_handlers[i].dequeue_send() { while let Some(datagram) = discovery_handlers[i%5].dequeue_send() {
let dest = discovery_handlers.iter_mut() let dest = discovery_handlers.iter_mut()
.find(|disc| datagram.address == disc.public_endpoint.address) .find(|disc| datagram.address == disc.public_endpoint.address)
.unwrap(); .unwrap();
@@ -929,14 +1052,14 @@ mod tests {
let mut discovery = Discovery { request_backoff: &request_backoff, ..discovery }; let mut discovery = Discovery { request_backoff: &request_backoff, ..discovery };
for _ in 0..2 { for _ in 0..2 {
discovery.ping(&node_entries[101]).unwrap(); discovery.ping(&node_entries[101], PingReason::Default).unwrap();
let num_nodes = total_bucket_nodes(&discovery.node_buckets); let num_nodes = total_bucket_nodes(&discovery.node_buckets);
discovery.check_expired(Instant::now() + PING_TIMEOUT); discovery.check_expired(Instant::now() + PING_TIMEOUT);
let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets); let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets);
assert_eq!(removed, 0); assert_eq!(removed, 0);
} }
discovery.ping(&node_entries[101]).unwrap(); discovery.ping(&node_entries[101], PingReason::Default).unwrap();
let num_nodes = total_bucket_nodes(&discovery.node_buckets); let num_nodes = total_bucket_nodes(&discovery.node_buckets);
discovery.check_expired(Instant::now() + PING_TIMEOUT); discovery.check_expired(Instant::now() + PING_TIMEOUT);
let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets); let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets);
@@ -1123,7 +1246,7 @@ mod tests {
let mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default()); let mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default());
let mut discovery2 = Discovery::new(&key2, ep2.clone(), IpFilter::default()); let mut discovery2 = Discovery::new(&key2, ep2.clone(), IpFilter::default());
discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }).unwrap(); discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }, PingReason::Default).unwrap();
let ping_data = discovery1.dequeue_send().unwrap(); let ping_data = discovery1.dequeue_send().unwrap();
assert!(!discovery1.any_sends_queued()); assert!(!discovery1.any_sends_queued());
let data = &ping_data.payload[(32 + 65)..]; let data = &ping_data.payload[(32 + 65)..];

View File

@@ -40,7 +40,7 @@ pub trait SocketAddrExt {
fn is_documentation_s(&self) -> bool { false } fn is_documentation_s(&self) -> bool { false }
fn is_global_multicast(&self) -> bool { false } fn is_global_multicast(&self) -> bool { false }
fn is_other_multicast(&self) -> bool { false } fn is_other_multicast(&self) -> bool { false }
fn is_reserved(&self) -> bool; fn is_reserved(&self) -> bool;
fn is_usable_public(&self) -> bool; fn is_usable_public(&self) -> bool;
fn is_usable_private(&self) -> bool; fn is_usable_private(&self) -> bool;
@@ -50,38 +50,38 @@ pub trait SocketAddrExt {
impl SocketAddrExt for Ipv4Addr { impl SocketAddrExt for Ipv4Addr {
fn is_global_s(&self) -> bool { fn is_global_s(&self) -> bool {
!self.is_private() && !self.is_private() &&
!self.is_loopback() && !self.is_loopback() &&
!self.is_link_local() && !self.is_link_local() &&
!self.is_broadcast() && !self.is_broadcast() &&
!self.is_documentation() !self.is_documentation()
} }
// Used for communications between a service provider and its subscribers when using a carrier-grade NAT // Used for communications between a service provider and its subscribers when using a carrier-grade NAT
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
fn is_shared_space(&self) -> bool { fn is_shared_space(&self) -> bool {
*self >= Ipv4Addr::new(100, 64, 0, 0) && *self >= Ipv4Addr::new(100, 64, 0, 0) &&
*self <= Ipv4Addr::new(100, 127, 255, 255) *self <= Ipv4Addr::new(100, 127, 255, 255)
} }
// Used for the IANA IPv4 Special Purpose Address Registry // Used for the IANA IPv4 Special Purpose Address Registry
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
fn is_special_purpose(&self) -> bool { fn is_special_purpose(&self) -> bool {
*self >= Ipv4Addr::new(192, 0, 0, 0) && *self >= Ipv4Addr::new(192, 0, 0, 0) &&
*self <= Ipv4Addr::new(192, 0, 0, 255) *self <= Ipv4Addr::new(192, 0, 0, 255)
} }
// Used for testing of inter-network communications between two separate subnets // Used for testing of inter-network communications between two separate subnets
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
fn is_benchmarking(&self) -> bool { fn is_benchmarking(&self) -> bool {
*self >= Ipv4Addr::new(198, 18, 0, 0) && *self >= Ipv4Addr::new(198, 18, 0, 0) &&
*self <= Ipv4Addr::new(198, 19, 255, 255) *self <= Ipv4Addr::new(198, 19, 255, 255)
} }
// Reserved for future use // Reserved for future use
// see: https://en.wikipedia.org/wiki/Reserved_IP_addresses // see: https://en.wikipedia.org/wiki/Reserved_IP_addresses
fn is_future_use(&self) -> bool { fn is_future_use(&self) -> bool {
*self >= Ipv4Addr::new(240, 0, 0, 0) && *self >= Ipv4Addr::new(240, 0, 0, 0) &&
*self <= Ipv4Addr::new(255, 255, 255, 254) *self <= Ipv4Addr::new(255, 255, 255, 254)
} }
@@ -102,7 +102,7 @@ impl SocketAddrExt for Ipv4Addr {
!self.is_reserved() && !self.is_reserved() &&
!self.is_private() !self.is_private()
} }
fn is_usable_private(&self) -> bool { fn is_usable_private(&self) -> bool {
self.is_private() self.is_private()
} }
@@ -118,7 +118,7 @@ impl SocketAddrExt for Ipv4Addr {
impl SocketAddrExt for Ipv6Addr { impl SocketAddrExt for Ipv6Addr {
fn is_global_s(&self) -> bool { fn is_global_s(&self) -> bool {
self.is_global_multicast() || self.is_global_multicast() ||
(!self.is_loopback() && (!self.is_loopback() &&
!self.is_unique_local_s() && !self.is_unique_local_s() &&
!self.is_unicast_link_local_s() && !self.is_unicast_link_local_s() &&
!self.is_documentation_s() && !self.is_documentation_s() &&
@@ -134,7 +134,7 @@ impl SocketAddrExt for Ipv6Addr {
fn is_unicast_link_local_s(&self) -> bool { fn is_unicast_link_local_s(&self) -> bool {
(self.segments()[0] & 0xffc0) == 0xfe80 (self.segments()[0] & 0xffc0) == 0xfe80
} }
// reserved for documentation (2001:db8::/32). // reserved for documentation (2001:db8::/32).
fn is_documentation_s(&self) -> bool { fn is_documentation_s(&self) -> bool {
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
@@ -160,7 +160,7 @@ impl SocketAddrExt for Ipv6Addr {
!self.is_reserved() && !self.is_reserved() &&
!self.is_unique_local_s() !self.is_unique_local_s()
} }
fn is_usable_private(&self) -> bool { fn is_usable_private(&self) -> bool {
self.is_unique_local_s() self.is_unique_local_s()
} }
@@ -194,7 +194,7 @@ impl SocketAddrExt for IpAddr {
IpAddr::V6(ref ip) => ip.is_usable_public(), IpAddr::V6(ref ip) => ip.is_usable_public(),
} }
} }
fn is_usable_private(&self) -> bool { fn is_usable_private(&self) -> bool {
match *self { match *self {
IpAddr::V4(ref ip) => ip.is_usable_private(), IpAddr::V4(ref ip) => ip.is_usable_private(),
@@ -308,7 +308,15 @@ pub fn select_public_address(port: u16) -> SocketAddr {
pub fn map_external_address(local: &NodeEndpoint) -> Option<NodeEndpoint> { pub fn map_external_address(local: &NodeEndpoint) -> Option<NodeEndpoint> {
if let SocketAddr::V4(ref local_addr) = local.address { if let SocketAddr::V4(ref local_addr) = local.address {
match search_gateway_from_timeout(*local_addr.ip(), Duration::new(5, 0)) { let local_ip = *local_addr.ip();
let search_gateway_child = ::std::thread::spawn(move || {
search_gateway_from_timeout(local_ip, Duration::new(5, 0))
});
let gateway_result = match search_gateway_child.join() {
Err(_) => return None,
Ok(gateway_result) => gateway_result,
};
match gateway_result {
Err(ref err) => debug!("Gateway search error: {}", err), Err(ref err) => debug!("Gateway search error: {}", err),
Ok(gateway) => { Ok(gateway) => {
match gateway.get_external_ip() { match gateway.get_external_ip() {
@@ -425,32 +433,32 @@ fn ipv4_future_use() {
fn ipv4_usable_public() { fn ipv4_usable_public() {
assert!(!Ipv4Addr::new(0,0,0,0).is_usable_public()); // unspecified assert!(!Ipv4Addr::new(0,0,0,0).is_usable_public()); // unspecified
assert!(Ipv4Addr::new(0,0,0,1).is_usable_public()); assert!(Ipv4Addr::new(0,0,0,1).is_usable_public());
assert!(Ipv4Addr::new(9,255,255,255).is_usable_public()); assert!(Ipv4Addr::new(9,255,255,255).is_usable_public());
assert!(!Ipv4Addr::new(10,0,0,0).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(10,0,0,0).is_usable_public()); // private intra-network
assert!(!Ipv4Addr::new(10,255,255,255).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(10,255,255,255).is_usable_public()); // private intra-network
assert!(Ipv4Addr::new(11,0,0,0).is_usable_public()); assert!(Ipv4Addr::new(11,0,0,0).is_usable_public());
assert!(Ipv4Addr::new(100, 63, 255, 255).is_usable_public()); assert!(Ipv4Addr::new(100, 63, 255, 255).is_usable_public());
assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space assert!(!Ipv4Addr::new(100, 64, 0, 0).is_usable_public()); // shared space
assert!(!Ipv4Addr::new(100, 127, 255, 255).is_usable_public()); // shared space assert!(!Ipv4Addr::new(100, 127, 255, 255).is_usable_public()); // shared space
assert!(Ipv4Addr::new(100, 128, 0, 0).is_usable_public()); assert!(Ipv4Addr::new(100, 128, 0, 0).is_usable_public());
assert!(Ipv4Addr::new(126,255,255,255).is_usable_public()); assert!(Ipv4Addr::new(126,255,255,255).is_usable_public());
assert!(!Ipv4Addr::new(127,0,0,0).is_usable_public()); // loopback assert!(!Ipv4Addr::new(127,0,0,0).is_usable_public()); // loopback
assert!(!Ipv4Addr::new(127,255,255,255).is_usable_public()); // loopback assert!(!Ipv4Addr::new(127,255,255,255).is_usable_public()); // loopback
assert!(Ipv4Addr::new(128,0,0,0).is_usable_public()); assert!(Ipv4Addr::new(128,0,0,0).is_usable_public());
assert!(Ipv4Addr::new(169,253,255,255).is_usable_public()); assert!(Ipv4Addr::new(169,253,255,255).is_usable_public());
assert!(!Ipv4Addr::new(169,254,0,0).is_usable_public()); // link-local assert!(!Ipv4Addr::new(169,254,0,0).is_usable_public()); // link-local
assert!(!Ipv4Addr::new(169,254,255,255).is_usable_public()); // link-local assert!(!Ipv4Addr::new(169,254,255,255).is_usable_public()); // link-local
assert!(Ipv4Addr::new(169,255,0,0).is_usable_public()); assert!(Ipv4Addr::new(169,255,0,0).is_usable_public());
assert!(Ipv4Addr::new(172,15,255,255).is_usable_public()); assert!(Ipv4Addr::new(172,15,255,255).is_usable_public());
assert!(!Ipv4Addr::new(172,16,0,0).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(172,16,0,0).is_usable_public()); // private intra-network
assert!(!Ipv4Addr::new(172,31,255,255).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(172,31,255,255).is_usable_public()); // private intra-network
assert!(Ipv4Addr::new(172,32,255,255).is_usable_public()); assert!(Ipv4Addr::new(172,32,255,255).is_usable_public());
assert!(Ipv4Addr::new(191,255,255,255).is_usable_public()); assert!(Ipv4Addr::new(191,255,255,255).is_usable_public());
assert!(!Ipv4Addr::new(192,0,0,0).is_usable_public()); // special purpose assert!(!Ipv4Addr::new(192,0,0,0).is_usable_public()); // special purpose
assert!(!Ipv4Addr::new(192,0,0,255).is_usable_public()); // special purpose assert!(!Ipv4Addr::new(192,0,0,255).is_usable_public()); // special purpose
@@ -458,19 +466,19 @@ fn ipv4_usable_public() {
assert!(Ipv4Addr::new(192,0,1,255).is_usable_public()); assert!(Ipv4Addr::new(192,0,1,255).is_usable_public());
assert!(!Ipv4Addr::new(192,0,2,0).is_usable_public()); // documentation assert!(!Ipv4Addr::new(192,0,2,0).is_usable_public()); // documentation
assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation assert!(!Ipv4Addr::new(192,0,2,255).is_usable_public()); // documentation
assert!(Ipv4Addr::new(192,0,3,0).is_usable_public()); assert!(Ipv4Addr::new(192,0,3,0).is_usable_public());
assert!(Ipv4Addr::new(192,167,255,255).is_usable_public()); assert!(Ipv4Addr::new(192,167,255,255).is_usable_public());
assert!(!Ipv4Addr::new(192,168,0,0).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(192,168,0,0).is_usable_public()); // private intra-network
assert!(!Ipv4Addr::new(192,168,255,255).is_usable_public()); // private intra-network assert!(!Ipv4Addr::new(192,168,255,255).is_usable_public()); // private intra-network
assert!(Ipv4Addr::new(192,169,0,0).is_usable_public()); assert!(Ipv4Addr::new(192,169,0,0).is_usable_public());
assert!(Ipv4Addr::new(198,17,255,255).is_usable_public()); assert!(Ipv4Addr::new(198,17,255,255).is_usable_public());
assert!(!Ipv4Addr::new(198,18,0,0).is_usable_public()); // benchmarking assert!(!Ipv4Addr::new(198,18,0,0).is_usable_public()); // benchmarking
assert!(!Ipv4Addr::new(198,19,255,255).is_usable_public()); // benchmarking assert!(!Ipv4Addr::new(198,19,255,255).is_usable_public()); // benchmarking
assert!(Ipv4Addr::new(198,20,0,0).is_usable_public()); assert!(Ipv4Addr::new(198,20,0,0).is_usable_public());
assert!(Ipv4Addr::new(198,51,99,255).is_usable_public()); assert!(Ipv4Addr::new(198,51,99,255).is_usable_public());
assert!(!Ipv4Addr::new(198,51,100,0).is_usable_public()); // documentation assert!(!Ipv4Addr::new(198,51,100,0).is_usable_public()); // documentation
assert!(!Ipv4Addr::new(198,51,100,255).is_usable_public()); // documentation assert!(!Ipv4Addr::new(198,51,100,255).is_usable_public()); // documentation
@@ -485,7 +493,7 @@ fn ipv4_usable_public() {
assert!(!Ipv4Addr::new(224,0,0,0).is_usable_public()); // multicast assert!(!Ipv4Addr::new(224,0,0,0).is_usable_public()); // multicast
assert!(!Ipv4Addr::new(239, 255, 255, 255).is_usable_public()); // multicast assert!(!Ipv4Addr::new(239, 255, 255, 255).is_usable_public()); // multicast
assert!(!Ipv4Addr::new(240, 0, 0, 0).is_usable_public()); // future use assert!(!Ipv4Addr::new(240, 0, 0, 0).is_usable_public()); // future use
assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use assert!(!Ipv4Addr::new(255, 255, 255, 254).is_usable_public()); // future use
assert!(!Ipv4Addr::new(255, 255, 255, 255).is_usable_public()); // limited broadcast assert!(!Ipv4Addr::new(255, 255, 255, 255).is_usable_public()); // limited broadcast
} }
@@ -495,12 +503,12 @@ fn ipv4_usable_private() {
assert!(Ipv4Addr::new(10,0,0,0).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(10,0,0,0).is_usable_private()); // private intra-network
assert!(Ipv4Addr::new(10,255,255,255).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(10,255,255,255).is_usable_private()); // private intra-network
assert!(!Ipv4Addr::new(11,0,0,0).is_usable_private()); assert!(!Ipv4Addr::new(11,0,0,0).is_usable_private());
assert!(!Ipv4Addr::new(172,15,255,255).is_usable_private()); assert!(!Ipv4Addr::new(172,15,255,255).is_usable_private());
assert!(Ipv4Addr::new(172,16,0,0).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(172,16,0,0).is_usable_private()); // private intra-network
assert!(Ipv4Addr::new(172,31,255,255).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(172,31,255,255).is_usable_private()); // private intra-network
assert!(!Ipv4Addr::new(172,32,255,255).is_usable_private()); assert!(!Ipv4Addr::new(172,32,255,255).is_usable_private());
assert!(!Ipv4Addr::new(192,167,255,255).is_usable_private()); assert!(!Ipv4Addr::new(192,167,255,255).is_usable_private());
assert!(Ipv4Addr::new(192,168,0,0).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(192,168,0,0).is_usable_private()); // private intra-network
assert!(Ipv4Addr::new(192,168,255,255).is_usable_private()); // private intra-network assert!(Ipv4Addr::new(192,168,255,255).is_usable_private()); // private intra-network

View File

@@ -85,6 +85,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;

View File

@@ -3,22 +3,22 @@
[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.2.4" version = "2.2.10"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[package.metadata] [package.metadata]
# This versions track. Should be changed to `stable` or `beta` when on respective branches. # This versions track. Should be changed to `stable` or `beta` when on respective branches.
# Used by auto-updater and for Parity version string. # Used by auto-updater and for Parity version string.
track = "beta" track = "stable"
# Network specific settings, used ONLY by auto-updater. # Network specific settings, used ONLY by auto-updater.
# Latest supported fork blocks. # Latest supported fork blocks.
# Indicates a critical release in this track (i.e. consensus issue). # Indicates a critical release in this track (i.e. consensus issue).
[package.metadata.networks] [package.metadata.networks]
foundation = { forkBlock = 4370000, critical = false } foundation = { forkBlock = 7280000, critical = false }
ropsten = { forkBlock = 4230000, critical = false } ropsten = { forkBlock = 4939394, critical = false }
kovan = { forkBlock = 6600000, critical = false } kovan = { forkBlock = 10255201, critical = false }
[dependencies] [dependencies]
parity-bytes = "0.1" parity-bytes = "0.1"