Compare commits

..

13 Commits

Author SHA1 Message Date
Hernando Castano
ebd0fd0117 More Backports for Stable 2.3.5 (#10430)
* revert some changes, could be buggy (#10399)

* ci: clean up gitlab-ci.yml leftovers from previous merge (#10429)

* 10000 > 5000 (#10422)

addresses #10418

* fix underflow in pip, closes #10419 (#10423)

* fix panic when logging directory does not exist, closes #10420 (#10424)

* Update hardcoded headers for Foundation, Ropsten, Kovan and Classic (#10417)

* update foundation to #7262209

* update kovan to #10434561

* update ropsten to #5027841

* update classic to #7555073

* Update Ropsten headers to #5101569
2019-02-27 16:33:20 +01:00
Hernando Castano
0d63c932af Backports for Stable 2.3.5 (#10414)
* no-git for publish jobs, empty artifacts dir (#10393)

* no-git for publish jobs, empty artifacts dir

* fix syntax

* prettiness

* fix prettiness

* should get rid of git in publishing

* snap: reenable i386, arm64, armhf architecture publishing (#10386)

* snap: reenable i386, arm64, armhf architecture publishing

* gitlab: fix indent

* gitlab: fix yml syntax

* Linker for crosscomile

* fix target to linker

* new docker image

* fix lint, add build to this PR

* calc SHA3 using rhash

* add new images for i386, armhf

* show snap target & artifacts

* set CARGO_TARGET for publish snap

* move detect Version to publish snap

* rm libc6 dep from snap-template up pub-snap script

* clean up cargo config before add linker

* move linker config to docker images

* tx pool: always accept local transactions (#10375)

* tx pool: always accept local transactions

* tx pool: `choose` local txs with same sender and nonce

* Fix to_pod storage trie value decoding (#10368)
2019-02-25 15:24:44 +01:00
5chdn
0b78a1b5a0 version: mark 2.3.5 as stable 2019-02-21 11:24:11 +01:00
5chdn
0e95db11d4 beta: snap: release untagged versions from branches to the candidate (#10357) (#10373)
* snap: release untagged versions from branches to the candidate snap channel (#10357)

* snap: add the removable-media plug (#10377)

This interface allows the snap to access the directories in /media. This is needed when the storage is in a separate disk, not part of home.

* exchanged old(azure) bootnodes with new(ovh) ones (#10309)

* exchanged old(azure) bootnodes with new(ovh) ones

* Fix indent
2019-02-20 10:52:43 +01:00
Afri Schoedon
7f3a72bde1 Beta Backports (#10354)
* version: bump beta to 2.3.4

* snap: prefix version and populate candidate channel (#10343)

* snap: populate candidate releases with beta snaps to avoid stale channel

* snap: prefix version with v*

* no volumes are needed, just run -v volume:/path/in/the/container (#10345)
2019-02-14 14:14:42 +01:00
Afri Schoedon
3b9b1a8f14 Backports for Beta 2.3.3 (#10333)
* version: bump beta to 2.3.3

* import rpc transactions sequentially (#10051)

* import rpc transactions sequentially

* use impl trait in argument position, renamed ProspectiveDispatcher to WithPostSign

* grouped imports

* integrates PostSign with ProspectiveSigner

* fix spaces, removed unnecessary type cast and duplicate polling

* clean up code style

* Apply suggestions from code review

* Fix Windows build (#10284)

* Don't run the CPP example on CI (#10285)

* Don't run the CPP example on CI

* Add comment

* CI optimizations (#10297)

* CI optimizations

* fix stripping

* new dockerfile

* no need n submodule upd

* review

* moved dockerfile

* it becomes large

* onchain update depends on s3

* fix dependency

* fix cache status

* fix cache status

* new cache status

* fix publish job (#10317)

* fix publish job

* dashes and colonels

* Add Statetest support for Constantinople Fix (#10323)

* Update Ethereum tests repo to v6.0.0-beta.3 tag

* Add spec for St.Peter's / ConstantinopleFix statetests

* Properly handle check_epoch_end_signal errors (#10015)

* Make check_epoch_end_signal to only use immutable data

* Move check_epoch_end_signals out of commit_block

* Make check_epoch_end_signals possible to fail

* Actually return the error from check_epoch_end_signals

* Remove a clone

* Fix import error

* cargo: fix compilation

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

* fix(add helper timestamp overflows)

* fix(simplify code)

* fix(make helper private)

* Remove CallContract and RegistryInfo re-exports from `ethcore/client` (#10205)

* Remove re-export of `CallContract` and `RegistryInfo` from `ethcore/client`

* Remove CallContract and RegistryInfo re-exports again

This was missed while fixing merge conflicts

* fix(docker): fix not receives SIGINT (#10059)

* fix(docker): fix not receives SIGINT

* fix: update with reviews

* update with review

* update

* update

* snap: official image / test (#10168)

* official image / test

* fix / test

* bit more necromancy

* fix paths

* add source bin/df /test

* add source bin/df /test2

* something w paths /test

* something w paths /test

* add source-type /test

* show paths /test

* copy plugin /test

* plugin -> nil

* install rhash

* no questions while installing rhash

* publish snap only for release

* Don't add discovery initiators to the node table (#10305)

* Don't add discovery initiators to the node table

* Use enums for tracking state of the nodes in discovery

* Dont try to ping ourselves

* Fix minor nits

* Update timeouts when observing an outdated node

* Extracted update_bucket_record from update_node

* Fixed typo

* Fix two final nits from @todr

* Extract CallContract and RegistryInfo traits into their own crate (#10178)

* Create call-contract crate

* Add license

* First attempt at using extracted CallContract trait

* Remove unneeded `extern crate` calls

* Move RegistryInfo trait into call-contract crate

* Move service-transaction-checker from ethcore to ethcore-miner

* Update Cargo.lock file

* Re-export call_contract

* Merge CallContract and RegistryInfo imports

* Remove commented code

* Add documentation to call_contract crate

* Add TODO for removal of re-exports

* Update call-contract crate description

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

* Rename call-contract crate to ethcore-call-contract

* Remove CallContract and RegistryInfo re-exports from `ethcore/client` (#10205)

* Remove re-export of `CallContract` and `RegistryInfo` from `ethcore/client`

* Remove CallContract and RegistryInfo re-exports again

This was missed while fixing merge conflicts

* fixed: types::transaction::SignedTransaction; (#10229)

* fix daemonize dependency

* fix build

* change docker image based on debian instead of ubuntu due to the chan… (#10336)

* change docker image based on debian instead of ubuntu due to the changes of the build container

* role back docker build image and docker deploy image to ubuntu:xenial based (#10338)

* perform stripping during build (#10208)

* perform stripping during build (#10208)

* perform stripping during build

* var RUSTFLAGS
2019-02-13 11:00:41 +01:00
Kirill Pimenov
a6c4b17303 Additional error for invalid gas (#10327) (#10328)
* Tag sensible place (ECHECH)

* Additional overflows checks.
2019-02-12 10:52:55 +01:00
Pierre Krieger
678138f097 Backport #10285 to beta (#10286)
* Don't run the CPP example on CI

* Add comment
2019-02-03 14:02:40 +01:00
Kirill Pimenov
b4e4038fb5 Additional tests for uint deserialization. (#10280) 2019-02-03 12:50:38 +01:00
Afri Schoedon
7a8e5976bc version: bump beta to 2.3.2 (#10283) 2019-02-03 12:44:26 +01:00
Afri Schoedon
938c8d8bcd Macos heapsize force jemalloc (#10234) (#10259)
* 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.
2019-01-30 12:02:02 +01:00
Afri Schoedon
3aefa2b960 Beta Backports 2.3.1 (#10225)
* version: bump beta to 2.3.1

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

* Change igd to github:maufl/rust-igd

* Run `igd::search_gateway_from_timeout` from own thread

* 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

* Run all `igd` methods in its own thread (#10195)

* 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:33:45 +01:00
Afri Schoedon
10657d96c4 backports for 2.3.0 beta (#10164)
* version: mark 2.3 track beta

* version: mark update critical on all networks

* Ping nodes from discovery (#10167)

* 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 23:05:56 +01:00
698 changed files with 30175 additions and 37695 deletions

View File

@@ -1,27 +1,3 @@
# NOTE: if you make changes here, remember to also update:
# scripts/test-linux.sh
# scripts/build-linux.sh
# scripts/build-windows.sh
# Using 'cfg` is broken, see https://github.com/rust-lang/cargo/issues/6858
#[target.'cfg(target_arch = "x86_64")']
#rustflags = ["-Ctarget-feature=+aes,+sse2,+ssse3"]
# …so instead we list all target triples (Tier 1 64-bit platforms)
[target.x86_64-unknown-linux-gnu]
# Enables the aes-ni instructions for RustCrypto dependency.
rustflags = ["-Ctarget-feature=+aes,+sse2,+ssse3"]
[target.x86_64-pc-windows-gnu]
# Enables the aes-ni instructions for RustCrypto dependency.
rustflags = ["-Ctarget-feature=+aes,+sse2,+ssse3"]
[target.x86_64-pc-windows-msvc]
# Enables the aes-ni instructions for RustCrypto dependency.
# Link the C runtime statically ; https://github.com/paritytech/parity-ethereum/issues/6643
rustflags = ["-Ctarget-feature=+aes,+sse2,+ssse3", "-Ctarget-feature=+crt-static"]
[target.x86_64-apple-darwin]
# Enables the aes-ni instructions for RustCrypto dependency.
rustflags = ["-Ctarget-feature=+aes,+sse2,+ssse3"]
rustflags = ["-Ctarget-feature=+crt-static"]

View File

@@ -24,42 +24,7 @@ Also, try to include **steps to reproduce** the issue and expand on the **actual
If you would like to contribute to Parity Ethereum, please **fork it**, fix bugs or implement features, and [propose a pull request](https://github.com/paritytech/parity-ethereum/compare).
### Labels & Milestones
We use [labels](https://github.com/paritytech/parity-ethereum/labels) to manage PRs and issues and communicate the state of a PR. Please familiarize yourself with them. Furthermore we are organizing issues in [milestones](https://github.com/paritytech/parity-ethereum/milestones). Best way to get started is to a pick a ticket from the current milestone tagged [`easy`](https://github.com/paritytech/parity-ethereum/labels/Q2-easy%20%F0%9F%92%83) and get going, or [`mentor`](https://github.com/paritytech/parity-ethereum/labels/Q1-mentor%20%F0%9F%95%BA) and get in contact with the mentor offering their support on that larger task.
### Rules
There are a few basic ground-rules for contributors (including the maintainer(s) of the project):
* **No pushing directly to the master branch**.
* **All modifications** must be made in a **pull-request** to solicit feedback from other contributors.
* Pull-requests cannot be merged before CI runs green and two reviewers have given their approval.
* Contributors should adhere to the [Parity Ethereum Style Guide](https://wiki.parity.io/Parity-Ethereum-Style-Guide).
### Recommendations
* **Non-master branch names** *should* be prefixed with a short name moniker, followed by the associated Github Issue ID (if any), and a brief description of the task using the format `<GITHUB_USERNAME>-<ISSUE_ID>-<BRIEF_DESCRIPTION>` (e.g. `gavin-123-readme`). The name moniker helps people to inquiry about their unfinished work, and the GitHub Issue ID helps your future self and other developers (particularly those who are onboarding) find out about and understand the original scope of the task, and where it fits into Parity Ethereum [Projects](https://github.com/paritytech/parity-ethereum/projects).
* **Remove stale branches periodically**
### Preparing Pull Requests
* If your PR does not alter any logic (e.g. comments, dependencies, docs), then it may be tagged [`insubstantial`](https://github.com/paritytech/parity-ethereum/pulls?q=is%3Aopen+is%3Apr+label%3A%22A2-insubstantial+%F0%9F%91%B6%22).
* Once a PR is ready for review please add the [`pleasereview`](https://github.com/paritytech/parity-ethereum/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+label%3A%22A0-pleasereview+%F0%9F%A4%93%22+) label.
### Reviewing Pull Requests*:
* At least two reviewers are required to review PRs (even for PRs tagged [`insubstantial`](https://github.com/paritytech/parity-ethereum/pulls?q=is%3Aopen+is%3Apr+label%3A%22A2-insubstantial+%F0%9F%91%B6%22)).
When doing a review, make sure to look for any:
* Buggy behavior.
* Undue maintenance burden.
* Breaking with house coding style.
* Pessimization (i.e. reduction of speed as measured in the projects benchmarks).
* Breaking changes should be carefuly reviewed and tagged as such so they end up in the [changelog](../CHANGELOG.md).
* Uselessness (i.e. it does not strictly add a feature or fix a known issue).
Please, refer to the [Coding Guide](https://wiki.parity.io/Coding-guide) in our wiki for more details about hacking on Parity.
## License.

View File

@@ -1,14 +1,10 @@
_Before filing a new issue, please **provide the following information**._
_If you think that your issue is an exploitable security vulnerability, please mail your bugreport to security@parity.io instead; your submission might be eligible for our Bug Bounty._
_You can find mode info on the reporting process in [SECURITY.md](https://github.com/paritytech/parity-ethereum/blob/master/SECURITY.md)_
- **Parity Ethereum version**: 0.0.0
- **Operating system**: Windows / MacOS / Linux
- **Installation**: homebrew / one-line installer / built from source
- **Fully synchronized**: no / yes
- **Network**: ethereum / ropsten / goerli / ...
- **Network**: ethereum / ropsten / kovan / ...
- **Restarted**: no / yes
_Your issue description goes here below. Try to include **actual** vs. **expected behavior** and **steps to reproduce** the issue._

View File

@@ -1,21 +0,0 @@
Thank you for your Pull Request!
Before you submitting, please check that:
- [ ] You added a brief description of the PR, e.g.:
- What does it do?
- What important points reviewers should know?
- Is there something left for follow-up PRs?
- [ ] You labeled the PR with appropriate labels if you have permissions to do so.
- [ ] You mentioned a related issue if this PR related to it, e.g. `Fixes #228` or `Related #1337`.
- [ ] You asked any particular reviewers to review. If you aren't sure, start with GH suggestions.
- [ ] Your PR adheres [the style guide](https://wiki.parity.io/Coding-guide)
- In particular, mind the maximal line length.
- There is no commented code checked in unless necessary.
- Any panickers have a proof or removed.
- [ ] You updated any rustdocs which may have changed
After you've read this notice feel free to remove it.
Thank you!
✄ -----------------------------------------------------------------------------

View File

@@ -4,15 +4,19 @@ stages:
- publish
- optional
image: parity/parity-ci-linux:latest
image: parity/rust-parity-ethereum-build:xenial
variables:
GIT_STRATEGY: fetch
GIT_SUBMODULE_STRATEGY: recursive
CI_SERVER_NAME: "GitLab CI"
CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_JOB_NAME}"
SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache"
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
CARGO_TARGET: x86_64-unknown-linux-gnu
.no_git: &no_git
variables:
GIT_STRATEGY: none
GIT_SUBMODULE_STRATEGY: none
.releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries")
only: &releaseable_branches
@@ -21,6 +25,7 @@ variables:
- tags
- schedules
.collect_artifacts: &collect_artifacts
artifacts:
name: "${CI_JOB_NAME}_${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}"
@@ -28,291 +33,143 @@ variables:
expire_in: 1 mos
paths:
- artifacts/
- tools/
.docker-cache-status: &docker-cache-status
test-linux:
stage: test
variables:
CARGO_HOME: "/ci-cache/parity-ethereum/cargo/${CI_JOB_NAME}"
dependencies: []
before_script:
- rustup show
- cargo --version
- SCCACHE_ERROR_LOG=/builds/parity/parity-ethereum/sccache_debug.log
RUST_LOG=sccache=debug
sccache --start-server
RUN_TESTS: all
script:
- scripts/gitlab/test-all.sh
- sccache -s
after_script:
# sccache debug info
- if test -e sccache_debug.log;
then
echo "_____All crate-types:_____";
grep 'parse_arguments.*--crate-type' sccache_debug.log | sed -re 's/.*"--crate-type", "([^"]+)".*/\1/' | sort | uniq -c;
echo "_____Non-cacheable reasons:_____";
grep CannotCache sccache_debug.log | sed -re 's/.*CannotCache\((.+)\).*/\1/' | sort | uniq -c;
else
echo "_____No logs from sccache_____";
exit 0;
fi
tags:
- linux-docker
.build-on-linux: &build-on-linux
stage: build
<<: *docker-cache-status
<<: *collect_artifacts
script:
- scripts/gitlab/build-linux.sh
- sccache -s
after_script:
- mkdir -p tools
- cp -r scripts/docker/hub/* ./tools
- cp scripts/gitlab/publish-snap.sh ./tools
- cp scripts/gitlab/publish-onchain.sh ./tools
- cp scripts/gitlab/safe-curl.sh ./tools
- echo v"$(sed -r -n '1,/^version/s/^version\s*=\s*"([^"]+)".*$/\1/p' Cargo.toml)" |
tee ./tools/VERSION
- echo "$(sed -r -n '1,/^track/s/^track\s*=\s*"([^"]+)".*$/\1/p' ./util/version/Cargo.toml)" |
tee ./tools/TRACK
cargo-check 0 3:
test-audit:
stage: test
<<: *docker-cache-status
script:
- time cargo check --target $CARGO_TARGET --locked --no-default-features --verbose --color=always
- sccache -s
cargo-check 1 3:
stage: test
<<: *docker-cache-status
script:
- time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --no-default-features --verbose --color=always
- sccache -s
cargo-check 2 3:
stage: test
<<: *docker-cache-status
script:
- time cargo check --target $CARGO_TARGET --locked --manifest-path util/io/Cargo.toml --features "mio" --verbose --color=always
- sccache -s
cargo-audit:
stage: test
<<: *docker-cache-status
script:
- set -e
- set -u
- cargo audit
allow_failure: true # failed cargo audit shouldn't prevent a PR from being merged
tags:
- linux-docker
validate-chainspecs:
stage: test
<<: *docker-cache-status
script:
- ./scripts/gitlab/validate-chainspecs.sh
- sccache -s
test-cpp:
stage: build
<<: *docker-cache-status
script:
- ./scripts/gitlab/test-cpp.sh
- sccache -s
test-linux:
stage: build
<<: *docker-cache-status
script:
- ./scripts/gitlab/test-linux.sh stable
- sccache -s
test-linux-beta:
build-linux: &build-linux
stage: build
only: *releaseable_branches
<<: *docker-cache-status
script:
- ./scripts/gitlab/test-linux.sh beta
- scripts/gitlab/build-unix.sh
- sccache -s
test-linux-nightly:
stage: build
only: *releaseable_branches
<<: *docker-cache-status
script:
- ./scripts/gitlab/test-linux.sh nightly
- sccache -s
allow_failure: true
build-android:
<<: *build-on-linux
image: parity/parity-ci-android:stretch
variables:
CARGO_TARGET: armv7-linux-androideabi
build-linux:
<<: *build-on-linux
only: *releaseable_branches
<<: *collect_artifacts
tags:
- linux-docker
build-linux-i386:
<<: *build-on-linux
only: *releaseable_branches
image: parity/parity-ci-i386:latest
<<: *build-linux
image: parity/rust-parity-ethereum-build:i386
variables:
CARGO_TARGET: i686-unknown-linux-gnu
build-linux-arm64:
<<: *build-on-linux
only: *releaseable_branches
image: parity/parity-ci-arm64:latest
<<: *build-linux
image: parity/rust-parity-ethereum-build:arm64
variables:
CARGO_TARGET: aarch64-unknown-linux-gnu
build-linux-armhf:
<<: *build-on-linux
only: *releaseable_branches
image: parity/parity-ci-armhf:latest
<<: *build-linux
image: parity/rust-parity-ethereum-build:armhf
variables:
CARGO_TARGET: armv7-unknown-linux-gnueabihf
build-darwin:
stage: build
<<: *collect_artifacts
only: *releaseable_branches
variables:
CARGO_TARGET: x86_64-apple-darwin
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
CC: gcc
CXX: g++
script:
- scripts/gitlab/build-linux.sh
- scripts/gitlab/build-unix.sh
tags:
- rust-osx
<<: *collect_artifacts
build-windows:
stage: build
<<: *collect_artifacts
only: *releaseable_branches
variables:
CARGO_TARGET: x86_64-pc-windows-msvc
CARGO_HOME: "C:/ci-cache/parity-ethereum/cargo/$CI_JOB_NAME"
GIT_SUBMODULE_STRATEGY: none
script:
- sh scripts/gitlab/build-windows.sh
tags:
- rust-windows
- rust-windows
<<: *collect_artifacts
publish-docker:
stage: publish
only: *releaseable_branches
except:
- nightly
when: manual
cache: {}
dependencies:
- build-linux
environment:
name: parity-build
cache: {}
image: docker:stable
services:
- docker:dind
variables:
GIT_STRATEGY: none
DOCKER_HOST: tcp://localhost:2375
DOCKER_DRIVER: overlay2
GIT_STRATEGY: none
# DOCKERFILE: tools/Dockerfile
# CONTAINER_IMAGE: parity/parity
script:
- ./tools/publish-docker.sh
tags:
- kubernetes-parity-build
- shell
script:
- scripts/gitlab/publish-docker.sh parity
publish-snap-nightly: &publish-snap
publish-snap: &publish-snap
stage: publish
only:
- nightly
only: *releaseable_branches
image: snapcore/snapcraft
variables:
GIT_STRATEGY: none
BUILD_ARCH: amd64
cache: {}
cache: {}
dependencies:
- build-linux
tags:
- linux-docker
script:
- ./tools/publish-snap.sh
- scripts/gitlab/publish-snap.sh
<<: *collect_artifacts
publish-snap-manually:
<<: *publish-snap
only: *releaseable_branches
when: manual
publish-snap-i386-nightly: &publish-snap-i386
publish-snap-i386:
<<: *publish-snap
variables:
BUILD_ARCH: i386
CARGO_TARGET: i686-unknown-linux-gnu
dependencies:
- build-linux-i386
publish-snap-i386-manually:
<<: *publish-snap-i386
only: *releaseable_branches
when: manual
publish-snap-arm64-nightly: &publish-snap-arm64
publish-snap-arm64:
<<: *publish-snap
variables:
BUILD_ARCH: arm64
CARGO_TARGET: aarch64-unknown-linux-gnu
dependencies:
- build-linux-arm64
publish-snap-arm64-manually:
<<: *publish-snap-arm64
only: *releaseable_branches
when: manual
publish-snap-armhf-nightly: &publish-snap-armhf
publish-snap-armhf:
<<: *publish-snap
variables:
BUILD_ARCH: armhf
CARGO_TARGET: armv7-unknown-linux-gnueabihf
dependencies:
- build-linux-armhf
publish-snap-armhf-manually:
<<: *publish-snap-armhf
only: *releaseable_branches
when: manual
publish-onchain-nightly: &publish-onchain
publish-onchain:
stage: publish
only:
- nightly
only: *releaseable_branches
cache: {}
variables:
GIT_STRATEGY: none
dependencies:
- build-linux
- build-darwin
- build-windows
script:
- ./tools/publish-onchain.sh
- scripts/gitlab/publish-onchain.sh
tags:
- linux-docker
publish-onchain-manually:
<<: *publish-onchain
only: *releaseable_branches
when: manual
publish-release-awss3-nightly: &publish-release-awss3
publish-awss3-release:
image: parity/awscli:latest
stage: publish
only:
- nightly
variables:
GIT_STRATEGY: none
only: *releaseable_branches
<<: *no_git
cache: {}
dependencies:
- build-linux
@@ -321,52 +178,40 @@ publish-release-awss3-nightly: &publish-release-awss3
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
(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}}/
- echo "__________Read from S3____________"
- aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}} --recursive --human-readable --summarize
after_script:
- aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/
--recursive --human-readable --summarize
tags:
- linux-docker
publish-release-awss3-manually:
<<: *publish-release-awss3
only: *releaseable_branches
when: manual
publish-docs:
stage: publish
image: parity/parity-ci-docs:latest
stage: publish
only:
- tags
except:
- nightly
when: manual
cache: {}
dependencies: []
cache: {}
script:
- scripts/gitlab/publish-docs.sh
tags:
- linux-docker
allow_failure: true
publish-av-whitelist:
stage: publish
build-android:
stage: optional
image: parity/rust-android:gitlab-ci
variables:
GIT_STRATEGY: none
only: *releaseable_branches
except:
- nightly
when: manual
cache: {}
dependencies:
- build-windows
CARGO_TARGET: armv7-linux-androideabi
script:
- scripts/gitlab/publish-av-whitelists.sh
- scripts/gitlab/build-unix.sh
tags:
- linux-docker
allow_failure: true
<<: *collect_artifacts

View File

@@ -1,218 +1,276 @@
## Parity-Ethereum [v2.6.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.3)
## Parity-Ethereum [v2.2.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.5) (2018-12-14)
Parity-Ethereum 2.2.5-beta is an important release that introduces Constantinople fork at block 7080000 on Mainnet.
This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you.
If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release`strict_empty_steps_transition` **is enabled by default at block 0** for any chain with `empty_steps`.
If your network uses `empty_steps` you **must**:
- plan a hard fork and change `strict_empty_steps_transition` to the desire fork block
- update the clients of the whole network to 2.2.5-beta / 2.1.10-stable.
If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it.
Parity Ethereum v2.6.4-stable is a patch release that adds the block numbers for activating the Istanbul hardfork on test networks: Ropsten, Görli, Rinkeby and Kovan.
The full list of included changes:
- Backports for beta 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047))
- Bump beta to 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047))
- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939))
- Prevent sending empty step message twice
- Prevent sending empty step and then block in the same step
- Don't accept double empty steps
- Do basic validation of self-sealed blocks
- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041))
- Enables strict verification of empty steps - there can be no duplicates and empty steps should be ordered inside the seal.
- Note that authorities won't produce invalid seals after [#9939](https://github.com/paritytech/parity-ethereum/pull/9939), this PR just adds verification to the seal to prevent forging incorrect blocks and potentially causing consensus issues.
- This features is enabled by default so any AuRa + EmptySteps chain should set strict_empty_steps_transition fork block number in their spec and upgrade to v2.2.5-beta or v2.1.10-stable.
- ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/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](https://github.com/paritytech/parity-ethereum/pull/10024))
- Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019))
A full list of included changes:
## Parity-Ethereum [v2.2.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.2) (2018-11-29)
* ethcore/res: activate Istanbul on Ropsten, Görli, Rinkeby, Kovan (#11068)
* cleanup json crate (#11027)
* [json-spec] make blake2 pricing spec more readable (#11034)
* Update JSON tests to d4f86ecf4aa7c (#11054)
Parity-Ethereum 2.2.2-beta is an exciting release. Among others, it improves sync performance, peering stability, block propagation, and transaction propagation times. Also, a warp-sync no longer removes existing blocks from the database, but rather reuses locally available information to decrease sync times and reduces required bandwidth.
## Parity-Ethereum [v2.6.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.3)
Before upgrading to 2.2.2, please also verify the validity of your chain specs. Parity Ethereum now denies unknown fields in the specification. To do this, use the chainspec tool:
Parity Ethereum v2.6.3-stable is a patch release that improves security, stability and performance.
```
cargo build --release -p chainspec
./target/release/chainspec /path/to/spec.json
```
* The most noteworthy improvement in this release is incorporating all the EIPs required for the Istanbul hard fork.
* This release also fixes certain security and performance issues, one of which was suspected to be consensus-threatening but turned out to be benign. Thanks to Martin Holst Swende and Felix Lange from the Ethereum Foundation for bringing the suspicious issue to our attention.
Last but not least, JSONRPC APIs which are not yet accepted as an EIP in the `eth`, `personal`, or `web3` namespace, are now considere experimental as their final specification might change in future. These APIs have to be manually enabled by explicitly running `--jsonrpc-experimental`.
The full list of included changes:
* add more tx tests (#11038)
* Fix parallel transactions race-condition (#10995)
* Add blake2_f precompile (#11017)
* [trace] introduce trace failed to Ext (#11019)
* Edit publish-onchain.sh to use https (#11016)
* Fix deadlock in network-devp2p (#11013)
* EIP 1108: Reduce alt_bn128 precompile gas costs (#11008)
* xDai chain support and nodes list update (#10989)
* EIP 2028: transaction gas lowered from 68 to 16 (#10987)
* EIP-1344 Add CHAINID op-code (#10983)
* manual publish jobs for releases, no changes for nightlies (#10977)
* [blooms-db] Fix benchmarks (#10974)
* Verify transaction against its block during import (#10954)
* Better error message for rpc gas price errors (#10931)
* Fix fork choice (#10837)
* Fix compilation on recent nightlies (#10991)
* Don't build rpc with ethcore test-helpers (#11048)
* EIP 1884 Re-pricing of trie-size dependent operations (#10992)
* Implement EIP-1283 reenable transition, EIP-1706 and EIP-2200 (#10191)
- Backports For beta 2.2.2 ([#9976](https://github.com/paritytech/parity-ethereum/pull/9976))
- Version: bump beta to 2.2.2
- Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928))
- Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643))
- Rename db_restore => client
- First step: make it compile!
- Second step: working implementation!
- Refactoring
- Fix tests
- Migrate ancient blocks interacting backward
- Early return in block migration if snapshot is aborted
- Remove RwLock getter (PR Grumble I)
- Remove dependency on `Client`: only used Traits
- Add test for recovering aborted snapshot recovery
- Add test for migrating old blocks
- Release RwLock earlier
- Revert Cargo.lock
- Update _update ancient block_ logic: set local in `commit`
- Update typo in ethcore/src/snapshot/service.rs
- Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925))
- Pip Table Cost relative to average peers instead of max peers
- Add tracing in PIP new_cost_table
- Update stat peer_count
- Use number of leeching peers for Light serve costs
- Fix test::light_params_load_share_depends_on_max_peers (wrong type)
- Remove (now) useless test
- Remove `load_share` from LightParams.Config
- Add LEECHER_COUNT_FACTOR
- Pr Grumble: u64 to u32 for f64 casting
- Prevent u32 overflow for avg_peer_count
- Add tests for LightSync::Statistics
- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939))
- Don't send empty step twice or empty step then block.
- Perform basic validation of locally sealed blocks.
- Don't include empty step twice.
- Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946))
- Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952))
- Update informant:
- Decimal in Mgas/s
- Print every 5s (not randomly between 5s and 10s)
- Fix dead-lock in `blockchain.rs`
- Update locks ordering
- Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932))
- Add `is_idle` to LightSync to check importing status
- Use SyncStateWrapper to make sure is_idle gets updates
- Update is_major_import to use verified queue size as well
- Add comment for `is_idle`
- Add Debug to `SyncStateWrapper`
- `fn get` -> `fn into_inner`
- Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970))
- Ci: rearrange pipeline by logic
- Ci: rename docs script
- Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971))
- Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972))
- Add deny_unknown_fields to chainspec
- Add tests and fix existing one
- Remove serde_ignored dependency for chainspec
- Fix rpc test eth chain spec
- Fix starting_nonce_test spec
- Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954))
- Refactor sync to add priority tasks.
- Send priority tasks notifications.
- Propagate blocks, optimize transactions.
- Implement transaction propagation. Use sync_channel.
- Tone down info.
- Prevent deadlock by not waiting forever for sync lock.
- Fix lock order.
- Don't use sync_channel to prevent deadlocks.
- Fix tests.
- Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967))
- Don't sync all peers after each response
- Update formating
- Fix tests: add `continue_sync` to `Sync_step`
- Update ethcore/sync/src/chain/mod.rs
- Fix rpc middlewares
- Fix Cargo.lock
- Json: resolve merge in spec
- Rpc: fix starting_nonce_test
- Ci: allow nightl job to fail
## Parity-Ethereum [v2.6.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.2)
## Parity-Ethereum [v2.2.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.1) (2018-11-15)
Parity Ethereum v2.6.2-stable is a bugfix release that fixes a potential DoS attack in the trace_call RPC method. This is a critical upgrade for anyone running Parity nodes with RPC exposed to the public internet (and highly recommended for anyone else). For details see this blog post.
Parity-Ethereum 2.2.1-beta is the first v2.2 release, and might introduce features that break previous work flows, among others:
## Parity-Ethereum [v2.6.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.1)
Parity-Ethereum 2.6.1-beta is a patch release that improves stability.
This release includes:
* Allow specifying hostnames for node URLs
* Fix a bug where archive nodes were losing peers
* Add support for Energy Web Foundations new chains 'Volta' and 'EWC', and remove their deprecated 'Tobalaba' chain.
- Prevent zero network ID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763)) and drop support for Olympic testnet ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801)): The Olympic test net is dead for years and never used a chain ID but network ID zero. Parity Ethereum is now preventing the network ID to be zero, thus Olympic support is dropped. Make sure to chose positive non-zero network IDs in future.
- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239)): adds a CLI argument `--snapshot-threads` which specifies the number of threads. This helps improving the performance of full nodes that wish to provide warp-snapshots for the network. The gain in performance comes with a slight drawback in increased snapshot size.
- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439)): Parity Ethereum imports blocks in rounds. If at the end of any round, the queue is not empty, we consider it to be _importing_ and won't notify pubsub. On large re-orgs (10+ blocks), this is possible. The default `max_round_blocks_to_import` is increased to 12 and configurable via the `--max-round-blocks-to-import` CLI flag. With unstable network conditions, it is advised to increase the number. This shouldn't have any noticeable performance impact unless the number is set to really large.
- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564)): the default values for gas floor target are `8_000_000` and gas cap `10_000_000`, similar to Geth 1.8.15+.
- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725)): we now produce portable binaries, but it may incur some performance degradation. For ultimate performance it's now better to compile Parity Ethereum from source with `PORTABLE=OFF` environment variable.
- RPC: `parity_allTransactionHashes` ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745)): Get all pending transactions from the queue with the high performant `parity_allTransactionHashes` RPC method.
- Support `eth_chainId` RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783)): implements EIP-695 to get the chainID via RPC.
- AuRa: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692)): The AuRa engine was updated to emit ancestry actions to finalize blocks. The full client stores block finality in the database, the engine builds finality from an ancestry of `ExtendedHeader`; `is_epoch_end` was updated to take a vec of recently finalized headers; `is_epoch_end_light` was added which maintains the previous interface and is used by the light client since the client itself doesn't track finality.
The full list of included changes:
* Add support for Energy Web Foundation's new chains (#10957)
* Kaspersky AV whitelisting (#10919)
* Avast whitelist script (#10900)
* Docker images renaming (#10863)
* Remove excessive warning (#10831)
* Allow --nat extip:your.host.here.org (#10830)
* When updating the client or when called from RPC, sleep should mean sleep (#10814)
* added new ropsten-bootnode and removed old one (#10794)
* ethkey no longer uses byteorder (#10786)
* docs: Update Readme with TOC, Contributor Guideline. Update Cargo package descriptions (#10652)
## Parity-Ethereum [v2.6.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.0)
Parity-Ethereum 2.6.0-beta is a minor release that stabilizes the 2.6 branch by
marking it as a beta release.
This release includes:
* Major refactoring of the codebase
* Many bugfixes
* Significant improvements to logging, error and warning message clarity.
* SecretStore: remove support of old database formats (#10757)
* This is a potentially breaking change if you have not upgraded for
quite some time.
As of today, Parity-Ethereum 2.4 reaches end of life, and everyone is
encouraged to upgrade.
The full list of included changes:
* update jsonrpc to 12.0 ([#10841](https://github.com/paritytech/parity-ethereum/pull/10841))
* Move more code into state-account ([#10840](https://github.com/paritytech/parity-ethereum/pull/10840))
* Extract AccountDB to account-db ([#10839](https://github.com/paritytech/parity-ethereum/pull/10839))
* Extricate PodAccount and state Account to own crates ([#10838](https://github.com/paritytech/parity-ethereum/pull/10838))
* Fix fork choice ([#10837](https://github.com/paritytech/parity-ethereum/pull/10837))
* tests: Relates to #10655: Test instructions for Readme ([#10835](https://github.com/paritytech/parity-ethereum/pull/10835))
* idiomatic changes to PodState ([#10834](https://github.com/paritytech/parity-ethereum/pull/10834))
* Break circular dependency between Client and Engine (part 1) ([#10833](https://github.com/paritytech/parity-ethereum/pull/10833))
* Remove excessive warning ([#10831](https://github.com/paritytech/parity-ethereum/pull/10831))
* Allow --nat extip:your.host.here.org ([#10830](https://github.com/paritytech/parity-ethereum/pull/10830))
* ethcore does not use byteorder ([#10829](https://github.com/paritytech/parity-ethereum/pull/10829))
* Fix typo in README.md ([#10828](https://github.com/paritytech/parity-ethereum/pull/10828))
* Update wordlist to v1.3 ([#10823](https://github.com/paritytech/parity-ethereum/pull/10823))
* bump `smallvec 0.6.10` to fix vulnerability ([#10822](https://github.com/paritytech/parity-ethereum/pull/10822))
* removed additional_params method ([#10818](https://github.com/paritytech/parity-ethereum/pull/10818))
* Improve logging when remote peer is unknown ([#10817](https://github.com/paritytech/parity-ethereum/pull/10817))
* replace memzero with zeroize crate ([#10816](https://github.com/paritytech/parity-ethereum/pull/10816))
* When updating the client or when called from RPC, sleep should mean sleep ([#10814](https://github.com/paritytech/parity-ethereum/pull/10814))
* Don't reimplement the logic from the Default impl ([#10813](https://github.com/paritytech/parity-ethereum/pull/10813))
* refactor: whisper: Add type aliases and update rustdocs in message.rs ([#10812](https://github.com/paritytech/parity-ethereum/pull/10812))
* test: whisper/cli `add invalid pool size test depending on processor` ([#10811](https://github.com/paritytech/parity-ethereum/pull/10811))
* Add Constantinople EIPs to the dev (instant_seal) config ([#10809](https://github.com/paritytech/parity-ethereum/pull/10809))
* fix spurious test failure ([#10808](https://github.com/paritytech/parity-ethereum/pull/10808))
* revert temp changes to .gitlab-ci.yml ([#10807](https://github.com/paritytech/parity-ethereum/pull/10807))
* removed redundant fmt::Display implementations ([#10806](https://github.com/paritytech/parity-ethereum/pull/10806))
* removed EthEngine alias ([#10805](https://github.com/paritytech/parity-ethereum/pull/10805))
* ethcore-bloom-journal updated to 2018 ([#10804](https://github.com/paritytech/parity-ethereum/pull/10804))
* Fix a few typos and unused warnings. ([#10803](https://github.com/paritytech/parity-ethereum/pull/10803))
* updated price-info to edition 2018 ([#10801](https://github.com/paritytech/parity-ethereum/pull/10801))
* updated parity-local-store to edition 2018 ([#10800](https://github.com/paritytech/parity-ethereum/pull/10800))
* updated project to ansi_term 0.11 ([#10799](https://github.com/paritytech/parity-ethereum/pull/10799))
* ethcore-light uses bincode 1.1 ([#10798](https://github.com/paritytech/parity-ethereum/pull/10798))
* ethcore-network-devp2p uses igd 0.9 ([#10797](https://github.com/paritytech/parity-ethereum/pull/10797))
* Better logging when backfilling ancient blocks fail ([#10796](https://github.com/paritytech/parity-ethereum/pull/10796))
* added new ropsten-bootnode and removed old one ([#10794](https://github.com/paritytech/parity-ethereum/pull/10794))
* Removed machine abstraction from ethcore ([#10791](https://github.com/paritytech/parity-ethereum/pull/10791))
* Removed redundant ethcore-service error type ([#10788](https://github.com/paritytech/parity-ethereum/pull/10788))
* Cleanup unused vm dependencies ([#10787](https://github.com/paritytech/parity-ethereum/pull/10787))
* ethkey no longer uses byteorder ([#10786](https://github.com/paritytech/parity-ethereum/pull/10786))
* Updated blooms-db to rust 2018 and removed redundant deps ([#10785](https://github.com/paritytech/parity-ethereum/pull/10785))
* Treat empty account the same as non-exist accounts in EIP-1052 ([#10775](https://github.com/paritytech/parity-ethereum/pull/10775))
* Do not drop the peer with None difficulty ([#10772](https://github.com/paritytech/parity-ethereum/pull/10772))
* EIP-1702: Generalized Account Versioning Scheme ([#10771](https://github.com/paritytech/parity-ethereum/pull/10771))
* Move Engine::register_client to be before other I/O handler registration ([#10767](https://github.com/paritytech/parity-ethereum/pull/10767))
* ethcore/res: activate atlantis classic hf on block 8772000 ([#10766](https://github.com/paritytech/parity-ethereum/pull/10766))
* Updated Bn128PairingImpl to use optimized batch pairing ([#10765](https://github.com/paritytech/parity-ethereum/pull/10765))
* Remove unused code ([#10762](https://github.com/paritytech/parity-ethereum/pull/10762))
* Initialize private tx logger only if private tx functionality is enabled ([#10758](https://github.com/paritytech/parity-ethereum/pull/10758))
* SecretStore: remove support of old database formats ([#10757](https://github.com/paritytech/parity-ethereum/pull/10757))
* Enable aesni ([#10756](https://github.com/paritytech/parity-ethereum/pull/10756))
* updater: fix static id hashes initialization ([#10755](https://github.com/paritytech/parity-ethereum/pull/10755))
* Use fewer threads for snapshotting ([#10752](https://github.com/paritytech/parity-ethereum/pull/10752))
* Die error_chain, die ([#10747](https://github.com/paritytech/parity-ethereum/pull/10747))
* Fix deprectation warnings on nightly ([#10746](https://github.com/paritytech/parity-ethereum/pull/10746))
* Improve logging and cleanup in miner around block sealing ([#10745](https://github.com/paritytech/parity-ethereum/pull/10745))
* Add a way to signal shutdown to snapshotting threads ([#10744](https://github.com/paritytech/parity-ethereum/pull/10744))
* fix docker tags for publishing ([#10741](https://github.com/paritytech/parity-ethereum/pull/10741))
* refactor: Fix indentation in ethjson ([#10740](https://github.com/paritytech/parity-ethereum/pull/10740))
* Log validator set changes in EpochManager ([#10734](https://github.com/paritytech/parity-ethereum/pull/10734))
* Print warnings when using dangerous settings for ValidatorSet ([#10733](https://github.com/paritytech/parity-ethereum/pull/10733))
* ethcore: enable ECIP-1054 for classic ([#10731](https://github.com/paritytech/parity-ethereum/pull/10731))
* Stop breaking out of loop if a non-canonical hash is found ([#10729](https://github.com/paritytech/parity-ethereum/pull/10729))
* Removed secret_store folder ([#10722](https://github.com/paritytech/parity-ethereum/pull/10722))
* Revert "enable lto for release builds (#10717)" ([#10721](https://github.com/paritytech/parity-ethereum/pull/10721))
* fix: aura don't add `SystemTime::now()` ([#10720](https://github.com/paritytech/parity-ethereum/pull/10720))
* Use RUSTFLAGS to set the optimization level ([#10719](https://github.com/paritytech/parity-ethereum/pull/10719))
* enable lto for release builds ([#10717](https://github.com/paritytech/parity-ethereum/pull/10717))
* [devp2p] Update to 2018 edition ([#10716](https://github.com/paritytech/parity-ethereum/pull/10716))
* [devp2p] Don't use `rust-crypto` ([#10714](https://github.com/paritytech/parity-ethereum/pull/10714))
* [devp2p] Fix warnings and re-org imports ([#10710](https://github.com/paritytech/parity-ethereum/pull/10710))
* DevP2p: Get node IP address and udp port from Socket, if not included in PING packet ([#10705](https://github.com/paritytech/parity-ethereum/pull/10705))
* introduce MissingParent Error, fixes #10699 ([#10700](https://github.com/paritytech/parity-ethereum/pull/10700))
* Refactor Clique stepping ([#10691](https://github.com/paritytech/parity-ethereum/pull/10691))
* add_sync_notifier in EthPubSubClient holds on to a Client for too long ([#10689](https://github.com/paritytech/parity-ethereum/pull/10689))
* Fix compiler warning (that will become an error) ([#10683](https://github.com/paritytech/parity-ethereum/pull/10683))
* Don't panic if extra_data is longer than VANITY_LENGTH ([#10682](https://github.com/paritytech/parity-ethereum/pull/10682))
* Remove annoying compiler warnings ([#10679](https://github.com/paritytech/parity-ethereum/pull/10679))
* Remove support for hardware wallets ([#10678](https://github.com/paritytech/parity-ethereum/pull/10678))
* [CI] allow cargo audit to fail ([#10676](https://github.com/paritytech/parity-ethereum/pull/10676))
* new image ([#10673](https://github.com/paritytech/parity-ethereum/pull/10673))
* Upgrade ethereum types ([#10670](https://github.com/paritytech/parity-ethereum/pull/10670))
* Reset blockchain properly ([#10669](https://github.com/paritytech/parity-ethereum/pull/10669))
* fix: Move PR template into .github/ folder ([#10663](https://github.com/paritytech/parity-ethereum/pull/10663))
* docs: evmbin - Update Rust docs ([#10658](https://github.com/paritytech/parity-ethereum/pull/10658))
* refactor: Related #9459 - evmbin: replace untyped json! macro with fully typed serde serialization using Rust structs ([#10657](https://github.com/paritytech/parity-ethereum/pull/10657))
* docs: Add PR template ([#10654](https://github.com/paritytech/parity-ethereum/pull/10654))
* docs: Add ProgPoW Rust docs to ethash module ([#10653](https://github.com/paritytech/parity-ethereum/pull/10653))
* docs: Update Readme with TOC, Contributor Guideline. Update Cargo package descriptions ([#10652](https://github.com/paritytech/parity-ethereum/pull/10652))
* Upgrade to parity-crypto 0.4 ([#10650](https://github.com/paritytech/parity-ethereum/pull/10650))
* fix(compilation warnings) ([#10649](https://github.com/paritytech/parity-ethereum/pull/10649))
* [whisper] Move needed aes_gcm crypto in-crate ([#10647](https://github.com/paritytech/parity-ethereum/pull/10647))
* Update publishing ([#10644](https://github.com/paritytech/parity-ethereum/pull/10644))
* ci: publish docs debug ([#10638](https://github.com/paritytech/parity-ethereum/pull/10638))
* Fix publish docs ([#10635](https://github.com/paritytech/parity-ethereum/pull/10635))
* Fix rinkeby petersburg fork ([#10632](https://github.com/paritytech/parity-ethereum/pull/10632))
* Update kovan.json to switch Kovan validator set to POA Consensus Contracts ([#10628](https://github.com/paritytech/parity-ethereum/pull/10628))
* [ethcore] remove error_chain ([#10616](https://github.com/paritytech/parity-ethereum/pull/10616))
* Remove unused import ([#10615](https://github.com/paritytech/parity-ethereum/pull/10615))
* Adds parity_getRawBlockByNumber, parity_submitRawBlock ([#10609](https://github.com/paritytech/parity-ethereum/pull/10609))
* adds rpc error message for --no-ancient-blocks ([#10608](https://github.com/paritytech/parity-ethereum/pull/10608))
* Constantinople HF on POA Core ([#10606](https://github.com/paritytech/parity-ethereum/pull/10606))
* Clique: zero-fill extradata when the supplied value is less than 32 bytes in length ([#10605](https://github.com/paritytech/parity-ethereum/pull/10605))
* evm: add some mulmod benches ([#10600](https://github.com/paritytech/parity-ethereum/pull/10600))
* sccache logs to stdout ([#10596](https://github.com/paritytech/parity-ethereum/pull/10596))
* update bootnodes ([#10595](https://github.com/paritytech/parity-ethereum/pull/10595))
* Merge `Notifier` and `TransactionsPoolNotifier` ([#10591](https://github.com/paritytech/parity-ethereum/pull/10591))
* fix(whisper): change expiry `unix_time + ttl + work` ([#10587](https://github.com/paritytech/parity-ethereum/pull/10587))
* fix(evmbin): make benches compile again ([#10586](https://github.com/paritytech/parity-ethereum/pull/10586))
* fix issue with compilation when 'slow-blocks' feature enabled ([#10585](https://github.com/paritytech/parity-ethereum/pull/10585))
* Allow CORS requests in Secret Store API ([#10584](https://github.com/paritytech/parity-ethereum/pull/10584))
* CI improvements ([#10579](https://github.com/paritytech/parity-ethereum/pull/10579))
* ethcore: improve timestamp handling ([#10574](https://github.com/paritytech/parity-ethereum/pull/10574))
* Update Issue Template to direct security issue to email ([#10562](https://github.com/paritytech/parity-ethereum/pull/10562))
* version: bump master to 2.6 ([#10560](https://github.com/paritytech/parity-ethereum/pull/10560))
* fix(light cull): poll light cull instead of timer ([#10559](https://github.com/paritytech/parity-ethereum/pull/10559))
* Watch transactions pool ([#10558](https://github.com/paritytech/parity-ethereum/pull/10558))
* Add SealingState; don't prepare block when not ready. ([#10529](https://github.com/paritytech/parity-ethereum/pull/10529))
* Explicitly enable or disable Stratum in config file (Issue 9785) ([#10521](https://github.com/paritytech/parity-ethereum/pull/10521))
* Add filtering capability to `parity_pendingTransactions` (issue 8269) ([#10506](https://github.com/paritytech/parity-ethereum/pull/10506))
* Remove calls to heapsize ([#10432](https://github.com/paritytech/parity-ethereum/pull/10432))
* RPC: Implements eth_subscribe("syncing") ([#10311](https://github.com/paritytech/parity-ethereum/pull/10311))
* SecretStore: non-blocking wait of session completion ([#10303](https://github.com/paritytech/parity-ethereum/pull/10303))
* Node table limiting and cache for node filter ([#10288](https://github.com/paritytech/parity-ethereum/pull/10288))
* SecretStore: expose restore_key_public in HTTP API ([#10241](https://github.com/paritytech/parity-ethereum/pull/10241))
* Trivial journal for private transactions ([#10056](https://github.com/paritytech/parity-ethereum/pull/10056))
- Backport to parity 2.2.1 beta ([#9905](https://github.com/paritytech/parity-ethereum/pull/9905))
- Bump version to 2.2.1
- Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885))
- Fix Parity not closing on Ctrl-C ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886))
- Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873))
- Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854))
- Add hardcoded headers for light client ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907))
- Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743))
- Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876))
- Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906))
- Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824))
- Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631))
- Eip-191 implementation ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701))
- Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918))
- Fix performance issue importing Kovan blocks ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914))
- Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855))
- Backports to parity beta 2.2.0 ([#9820](https://github.com/paritytech/parity-ethereum/pull/9820))
- Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788))
- Implement NoProof for json tests and update tests reference ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814))
- Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841))
- Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828))
- Rpc: parity_allTransactionHashes ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745))
- Revert "prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763))" ([#9815](https://github.com/paritytech/parity-ethereum/pull/9815))
- Allow zero chain id in EIP155 signing process ([#9792](https://github.com/paritytech/parity-ethereum/pull/9792))
- Add readiness check for docker container ([#9804](https://github.com/paritytech/parity-ethereum/pull/9804))
- Insert dev account before unlocking ([#9813](https://github.com/paritytech/parity-ethereum/pull/9813))
- Removed "rustup" & added new runner tag ([#9731](https://github.com/paritytech/parity-ethereum/pull/9731))
- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439))
- Aura: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692))
- Sync: retry different peer after empty subchain heads response ([#9753](https://github.com/paritytech/parity-ethereum/pull/9753))
- Fix(light-rpc/parity) : Remove unused client ([#9802](https://github.com/paritytech/parity-ethereum/pull/9802))
- Drops support for olympic testnet, closes [#9800](https://github.com/paritytech/parity-ethereum/issues/9800) ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801))
- Replace `tokio_core` with `tokio` (`ring` -> 0.13) ([#9657](https://github.com/paritytech/parity-ethereum/pull/9657))
- Support eth_chainId RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783))
- Ethcore: bump ropsten forkblock checkpoint ([#9775](https://github.com/paritytech/parity-ethereum/pull/9775))
- Docs: changelogs for 2.0.8 and 2.1.3 ([#9758](https://github.com/paritytech/parity-ethereum/pull/9758))
- Prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763))
- Skip seal fields count check when --no-seal-check is used ([#9757](https://github.com/paritytech/parity-ethereum/pull/9757))
- Aura: fix panic on extra_info with unsealed block ([#9755](https://github.com/paritytech/parity-ethereum/pull/9755))
- Docs: update changelogs ([#9742](https://github.com/paritytech/parity-ethereum/pull/9742))
- Removed extra assert in generation_session_is_removed_when_succeeded ([#9738](https://github.com/paritytech/parity-ethereum/pull/9738))
- Make checkpoint_storage_at use plain loop instead of recursion ([#9734](https://github.com/paritytech/parity-ethereum/pull/9734))
- Use signed 256-bit integer for sstore gas refund substate ([#9746](https://github.com/paritytech/parity-ethereum/pull/9746))
- Heads ref not present for branches beta and stable ([#9741](https://github.com/paritytech/parity-ethereum/pull/9741))
- Add Callisto support ([#9534](https://github.com/paritytech/parity-ethereum/pull/9534))
- Add --force to cargo audit install script ([#9735](https://github.com/paritytech/parity-ethereum/pull/9735))
- Remove unused expired value from Handshake ([#9732](https://github.com/paritytech/parity-ethereum/pull/9732))
- Add hardcoded headers ([#9730](https://github.com/paritytech/parity-ethereum/pull/9730))
- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725))
- Gitlab ci: releasable_branches: change variables condition to schedule ([#9729](https://github.com/paritytech/parity-ethereum/pull/9729))
- Update a few parity-common dependencies ([#9663](https://github.com/paritytech/parity-ethereum/pull/9663))
- Hf in POA Core (2018-10-22) ([#9724](https://github.com/paritytech/parity-ethereum/pull/9724))
- Schedule nightly builds ([#9717](https://github.com/paritytech/parity-ethereum/pull/9717))
- Fix ancient blocks sync ([#9531](https://github.com/paritytech/parity-ethereum/pull/9531))
- Ci: Skip docs job for nightly ([#9693](https://github.com/paritytech/parity-ethereum/pull/9693))
- Fix (light/provider) : Make `read_only executions` read-only ([#9591](https://github.com/paritytech/parity-ethereum/pull/9591))
- Ethcore: fix detection of major import ([#9552](https://github.com/paritytech/parity-ethereum/pull/9552))
- Return 0 on error ([#9705](https://github.com/paritytech/parity-ethereum/pull/9705))
- Ethcore: delay ropsten hardfork ([#9704](https://github.com/paritytech/parity-ethereum/pull/9704))
- Make instantSeal engine backwards compatible, closes [#9696](https://github.com/paritytech/parity-ethereum/issues/9696) ([#9700](https://github.com/paritytech/parity-ethereum/pull/9700))
- Implement CREATE2 gas changes and fix some potential overflowing ([#9694](https://github.com/paritytech/parity-ethereum/pull/9694))
- Don't hash the init_code of CREATE. ([#9688](https://github.com/paritytech/parity-ethereum/pull/9688))
- Ethcore: minor optimization of modexp by using LR exponentiation ([#9697](https://github.com/paritytech/parity-ethereum/pull/9697))
- Removed redundant clone before each block import ([#9683](https://github.com/paritytech/parity-ethereum/pull/9683))
- Add Foundation Bootnodes ([#9666](https://github.com/paritytech/parity-ethereum/pull/9666))
- Docker: run as parity user ([#9689](https://github.com/paritytech/parity-ethereum/pull/9689))
- Ethcore: mcip3 block reward contract ([#9605](https://github.com/paritytech/parity-ethereum/pull/9605))
- Verify block syncing responses against requests ([#9670](https://github.com/paritytech/parity-ethereum/pull/9670))
- Add a new RPC `parity_submitWorkDetail` similar `eth_submitWork` but return block hash ([#9404](https://github.com/paritytech/parity-ethereum/pull/9404))
- Resumable EVM and heap-allocated callstack ([#9360](https://github.com/paritytech/parity-ethereum/pull/9360))
- Update parity-wordlist library ([#9682](https://github.com/paritytech/parity-ethereum/pull/9682))
- Ci: Remove unnecessary pipes ([#9681](https://github.com/paritytech/parity-ethereum/pull/9681))
- Test.sh: use cargo --target for platforms other than linux, win or mac ([#9650](https://github.com/paritytech/parity-ethereum/pull/9650))
- Ci: fix push script ([#9679](https://github.com/paritytech/parity-ethereum/pull/9679))
- Hardfork the testnets ([#9562](https://github.com/paritytech/parity-ethereum/pull/9562))
- Calculate sha3 instead of sha256 for push-release. ([#9673](https://github.com/paritytech/parity-ethereum/pull/9673))
- Ethcore-io retries failed work steal ([#9651](https://github.com/paritytech/parity-ethereum/pull/9651))
- Fix(light_fetch): avoid race with BlockNumber::Latest ([#9665](https://github.com/paritytech/parity-ethereum/pull/9665))
- Test fix for windows cache name... ([#9658](https://github.com/paritytech/parity-ethereum/pull/9658))
- Refactor(fetch) : light use only one `DNS` thread ([#9647](https://github.com/paritytech/parity-ethereum/pull/9647))
- Ethereum libfuzzer integration small change ([#9547](https://github.com/paritytech/parity-ethereum/pull/9547))
- Cli: remove reference to --no-ui in --unlock flag help ([#9616](https://github.com/paritytech/parity-ethereum/pull/9616))
- Remove master from releasable branches ([#9655](https://github.com/paritytech/parity-ethereum/pull/9655))
- Ethcore/VerificationQueue don't spawn up extra `worker-threads` when explictly specified not to ([#9620](https://github.com/paritytech/parity-ethereum/pull/9620))
- Rpc: parity_getBlockReceipts ([#9527](https://github.com/paritytech/parity-ethereum/pull/9527))
- Remove unused dependencies ([#9589](https://github.com/paritytech/parity-ethereum/pull/9589))
- Ignore key_server_cluster randomly failing tests ([#9639](https://github.com/paritytech/parity-ethereum/pull/9639))
- Ethcore: handle vm exception when estimating gas ([#9615](https://github.com/paritytech/parity-ethereum/pull/9615))
- Fix bad-block reporting no reason ([#9638](https://github.com/paritytech/parity-ethereum/pull/9638))
- Use static call and apparent value transfer for block reward contract code ([#9603](https://github.com/paritytech/parity-ethereum/pull/9603))
- Hf in POA Sokol (2018-09-19) ([#9607](https://github.com/paritytech/parity-ethereum/pull/9607))
- Bump smallvec to 0.6 in ethcore-light, ethstore and whisper ([#9588](https://github.com/paritytech/parity-ethereum/pull/9588))
- Add constantinople conf to EvmTestClient. ([#9570](https://github.com/paritytech/parity-ethereum/pull/9570))
- Fix(network): don't disconnect reserved peers ([#9608](https://github.com/paritytech/parity-ethereum/pull/9608))
- Fix failing node-table tests on mac os, closes [#9632](https://github.com/paritytech/parity-ethereum/issues/9632) ([#9633](https://github.com/paritytech/parity-ethereum/pull/9633))
- Update ropsten.json ([#9602](https://github.com/paritytech/parity-ethereum/pull/9602))
- Simplify ethcore errors by removing BlockImportError ([#9593](https://github.com/paritytech/parity-ethereum/pull/9593))
- Fix windows compilation, replaces [#9561](https://github.com/paritytech/parity-ethereum/issues/9561) ([#9621](https://github.com/paritytech/parity-ethereum/pull/9621))
- Master: rpc-docs set github token ([#9610](https://github.com/paritytech/parity-ethereum/pull/9610))
- Docs: add changelogs for 1.11.10, 1.11.11, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.1.0, and 2.1.1 ([#9554](https://github.com/paritytech/parity-ethereum/pull/9554))
- Docs(rpc): annotate tag with the provided message ([#9601](https://github.com/paritytech/parity-ethereum/pull/9601))
- Ci: fix regex roll_eyes ([#9597](https://github.com/paritytech/parity-ethereum/pull/9597))
- Remove snapcraft clean ([#9585](https://github.com/paritytech/parity-ethereum/pull/9585))
- Add snapcraft package image (master) ([#9584](https://github.com/paritytech/parity-ethereum/pull/9584))
- Docs(rpc): push the branch along with tags ([#9578](https://github.com/paritytech/parity-ethereum/pull/9578))
- Fix typo for jsonrpc-threads flag ([#9574](https://github.com/paritytech/parity-ethereum/pull/9574))
- Fix informant compile ([#9571](https://github.com/paritytech/parity-ethereum/pull/9571))
- Added ropsten bootnodes ([#9569](https://github.com/paritytech/parity-ethereum/pull/9569))
- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564))
- While working on the platform tests make them non-breaking ([#9563](https://github.com/paritytech/parity-ethereum/pull/9563))
- Improve P2P discovery ([#9526](https://github.com/paritytech/parity-ethereum/pull/9526))
- Move dockerfile for android build container to scripts repo ([#9560](https://github.com/paritytech/parity-ethereum/pull/9560))
- Simultaneous platform tests WIP ([#9557](https://github.com/paritytech/parity-ethereum/pull/9557))
- Update ethabi-derive, serde, serde_json, serde_derive, syn && quote ([#9553](https://github.com/paritytech/parity-ethereum/pull/9553))
- Ci: fix rpc docs generation 2 ([#9550](https://github.com/paritytech/parity-ethereum/pull/9550))
- Ci: always run build pipelines for win, mac, linux, and android ([#9537](https://github.com/paritytech/parity-ethereum/pull/9537))
- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239))
- New ethabi ([#9511](https://github.com/paritytech/parity-ethereum/pull/9511))
- Remove initial token for WS. ([#9545](https://github.com/paritytech/parity-ethereum/pull/9545))
- Net_version caches network_id to avoid redundant aquire of sync readlock ([#9544](https://github.com/paritytech/parity-ethereum/pull/9544))
- Correct before_script for nightly build versions ([#9543](https://github.com/paritytech/parity-ethereum/pull/9543))
- Deps: bump kvdb-rocksdb to 0.1.4 ([#9539](https://github.com/paritytech/parity-ethereum/pull/9539))
- State: test when contract creation fails, old storage values should re-appear ([#9532](https://github.com/paritytech/parity-ethereum/pull/9532))
- Allow dropping light client RPC query with no results ([#9318](https://github.com/paritytech/parity-ethereum/pull/9318))
- Bump master to 2.2.0 ([#9517](https://github.com/paritytech/parity-ethereum/pull/9517))
- Enable all Constantinople hard fork changes in constantinople_test.json ([#9505](https://github.com/paritytech/parity-ethereum/pull/9505))
- [Light] Validate `account balance` before importing transactions ([#9417](https://github.com/paritytech/parity-ethereum/pull/9417))
- In create memory calculation is the same for create2 because the additional parameter was popped before. ([#9522](https://github.com/paritytech/parity-ethereum/pull/9522))
- Update patricia trie to 0.2.2 ([#9525](https://github.com/paritytech/parity-ethereum/pull/9525))
- Replace hardcoded JSON with serde json! macro ([#9489](https://github.com/paritytech/parity-ethereum/pull/9489))
- Fix typo in version string ([#9516](https://github.com/paritytech/parity-ethereum/pull/9516))
## Previous releases
- [CHANGELOG-2.5](docs/CHANGELOG-2.5.md) (_stable_)
- [CHANGELOG-2.4](docs/CHANGELOG-2.4.md) (EOL: 2019-07-08)
- [CHANGELOG-2.3](docs/CHANGELOG-2.3.md) (EOL: 2019-04-09)
- [CHANGELOG-2.2](docs/CHANGELOG-2.2.md) (EOL: 2019-02-25)
- [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (EOL: 2019-01-16)
- [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (_stable_)
- [CHANGELOG-2.0](docs/CHANGELOG-2.0.md) (EOL: 2018-11-15)
- [CHANGELOG-1.11](docs/CHANGELOG-1.11.md) (EOL: 2018-09-19)
- [CHANGELOG-1.10](docs/CHANGELOG-1.10.md) (EOL: 2018-07-18)

2751
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
description = "Parity Ethereum client"
name = "parity-ethereum"
# NOTE Make sure to update util/version/Cargo.toml as well
version = "2.6.4"
version = "2.3.5"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
@@ -18,7 +18,7 @@ num_cpus = "1.2"
number_prefix = "0.2"
rpassword = "1.0"
semver = "0.9"
ansi_term = "0.11"
ansi_term = "0.10"
parking_lot = "0.7"
regex = "1.0"
atty = "0.2.8"
@@ -29,11 +29,10 @@ serde_derive = "1.0"
futures = "0.1"
fdlimit = "0.1"
ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" }
jsonrpc-core = "12.0.0"
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" }
ethcore = { path = "ethcore", features = ["parity"] }
parity-bytes = "0.1"
common-types = { path = "ethcore/types" }
ethcore = { path = "ethcore", features = ["parity"] }
ethcore-accounts = { path = "accounts", optional = true }
ethcore-blockchain = { path = "ethcore/blockchain" }
ethcore-call-contract = { path = "ethcore/call-contract"}
ethcore-db = { path = "ethcore/db" }
@@ -45,13 +44,12 @@ ethcore-network = { path = "util/network" }
ethcore-private-tx = { path = "ethcore/private-tx" }
ethcore-service = { path = "ethcore/service" }
ethcore-sync = { path = "ethcore/sync" }
ethereum-types = "0.6.0"
ethkey = { path = "accounts/ethkey" }
ethstore = { path = "accounts/ethstore" }
ethereum-types = "0.4"
node-filter = { path = "ethcore/node-filter" }
rlp = "0.4.0"
ethkey = { path = "accounts/ethkey" }
rlp = { version = "0.3.0", features = ["ethereum"] }
cli-signer= { path = "cli-signer" }
parity-daemonize = "0.3"
parity-hash-fetch = { path = "updater/hash-fetch" }
parity-ipfs-api = { path = "ipfs" }
parity-local-store = { path = "miner/local-store" }
@@ -63,7 +61,7 @@ parity-whisper = { path = "whisper" }
parity-path = "0.1"
dir = { path = "util/dir" }
panic_hook = { path = "util/panic-hook" }
keccak-hash = "0.2.0"
keccak-hash = "0.1"
migration-rocksdb = { path = "util/migration-rocksdb" }
kvdb = "0.1"
kvdb-rocksdb = "0.1.3"
@@ -73,8 +71,6 @@ ethcore-secretstore = { path = "secret-store", optional = true }
registrar = { path = "util/registrar" }
parity-util-mem = { version = "0.1", features = ["jemalloc-global"] }
[build-dependencies]
rustc_version = "0.2"
@@ -84,19 +80,21 @@ ipnetwork = "0.12.6"
tempdir = "0.3"
fake-fetch = { path = "util/fake-fetch" }
[target.'cfg(not(windows))'.dependencies]
daemonize = "0.3"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] }
[features]
default = ["accounts"]
accounts = ["ethcore-accounts", "parity-rpc/accounts"]
miner-debug = ["ethcore/miner-debug"]
json-tests = ["ethcore/json-tests"]
ci-skip-issue = ["ethcore/ci-skip-issue"]
test-heavy = ["ethcore/test-heavy"]
evm-debug = ["ethcore/evm-debug"]
evm-debug-tests = ["ethcore/evm-debug-tests"]
slow-blocks = ["ethcore/slow-blocks"]
secretstore = ["ethcore-secretstore", "ethcore-secretstore/accounts"]
secretstore = ["ethcore-secretstore"]
final = ["parity-version/final"]
deadlock_detection = ["parking_lot/deadlock_detection"]
# to create a memory profile (requires nightly rust), use e.g.
@@ -118,9 +116,10 @@ path = "parity/lib.rs"
path = "parity/main.rs"
name = "parity"
[profile.dev]
[profile.release]
debug = false
lto = true
[workspace]
# This should only list projects that are not
@@ -137,6 +136,8 @@ members = [
"util/triehash-ethereum",
"util/keccak-hasher",
"util/patricia-trie-ethereum",
"util/fastmap",
"util/time-utils",
"util/fastmap"
]
[patch.crates-io]
heapsize = { git = "https://github.com/cheme/heapsize.git", branch = "ec-macfix" }

276
README.md
View File

@@ -7,25 +7,6 @@
<p align="center"><a href="https://gitlab.parity.io/parity/parity-ethereum/commits/master" target="_blank"><img src="https://gitlab.parity.io/parity/parity-ethereum/badges/master/build.svg" /></a>
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"><img src="https://img.shields.io/badge/license-GPL%20v3-green.svg" /></a></p>
## Table of Contents
1. [Description](#chapter-001)
2. [Technical Overview](#chapter-002)
3. [Building](#chapter-003)<br>
3.1 [Building Dependencies](#chapter-0031)<br>
3.2 [Building from Source Code](#chapter-0032)<br>
3.3 [Simple One-Line Installer for Mac and Linux](#chapter-0033)<br>
3.4 [Starting Parity Ethereum](#chapter-0034)
4. [Testing](#chapter-004)
5. [Documentation](#chapter-005)
6. [Toolchain](#chapter-006)
7. [Community](#chapter-007)
8. [Contributing](#chapter-008)
9. [License](#chapter-009)
## 1. Description <a id="chapter-001"></a>
**Built for mission-critical use**: Miners, service providers, and exchanges need fast synchronisation and maximum uptime. Parity Ethereum provides the core infrastructure essential for speedy and reliable services.
- Clean, modular codebase for easy customisation
@@ -34,7 +15,7 @@
- Synchronise in hours, not days with Warp Sync
- Modular for light integration into your service or product
## 2. Technical Overview <a id="chapter-002"></a>
## Technical Overview
Parity Ethereum's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity Ethereum using the sophisticated and cutting-edge **Rust programming language**. Parity Ethereum is licensed under the GPLv3 and can be used for all your Ethereum needs.
@@ -44,9 +25,7 @@ If you run into problems while using Parity Ethereum, check out the [wiki for do
Parity Ethereum's current beta-release is 2.1. You can download it at [the releases page](https://github.com/paritytech/parity-ethereum/releases) or follow the instructions below to build from source. Please, mind the [CHANGELOG.md](CHANGELOG.md) for a list of all changes between different versions.
## 3. Building <a id="chapter-003"></a>
### 3.1 Build Dependencies <a id="chapter-0031"></a>
## Build Dependencies
Parity Ethereum requires **latest stable Rust version** to build.
@@ -57,7 +36,7 @@ We recommend installing Rust through [rustup](https://www.rustup.rs/). If you do
$ curl https://sh.rustup.rs -sSf | sh
```
Parity Ethereum also requires `gcc`, `g++`, `pkg-config`, `file`, `make`, and `cmake` packages to be installed.
Parity Ethereum also requires `gcc`, `g++`, `libudev-dev`, `pkg-config`, `file`, `make`, and `cmake` packages to be installed.
- OSX:
```bash
@@ -66,7 +45,7 @@ We recommend installing Rust through [rustup](https://www.rustup.rs/). If you do
`clang` is required. It comes with Xcode command line tools or can be installed with homebrew.
- Windows:
- Windows
Make sure you have Visual Studio 2015 with C++ support installed. Next, download and run the `rustup` installer from
https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe, start "VS2015 x64 Native Tools Command Prompt", and use the following command to install and set up the `msvc` toolchain:
```bash
@@ -79,7 +58,7 @@ Once you have `rustup` installed, then you need to install:
Make sure that these binaries are in your `PATH`. After that, you should be able to build Parity Ethereum from source.
### 3.2 Build from Source Code <a id="chapter-0032"></a>
## Build from Source Code
```bash
# download Parity Ethereum code
@@ -116,7 +95,7 @@ or
$ git checkout beta
```
### 3.3 Simple One-Line Installer for Mac and Linux <a id="chapter-0033"></a>
## Simple One-Line Installer for Mac and Linux
```bash
bash <(curl https://get.parity.io -L)
@@ -128,9 +107,9 @@ The one-line installer always defaults to the latest beta release. To install a
bash <(curl https://get.parity.io -L) -r stable
```
### 3.4 Starting Parity Ethereum <a id="chapter-0034"></a>
## Start Parity Ethereum
#### Manually
### Manually
To start Parity Ethereum manually, just run
@@ -140,234 +119,25 @@ $ ./target/release/parity
so Parity Ethereum begins syncing the Ethereum blockchain.
#### Using `systemd` service file
### Using `systemd` service file
To start Parity Ethereum as a regular user using `systemd` init:
1. Copy `./scripts/parity.service` to your
`systemd` user directory (usually `~/.config/systemd/user`).
2. Copy release to bin folder, write `sudo install ./target/release/parity /usr/bin/parity`
3. To configure Parity Ethereum, write a `/etc/parity/config.toml` config file, see [Configuring Parity Ethereum](https://paritytech.github.io/wiki/Configuring-Parity) for details.
2. To configure Parity Ethereum, write a `/etc/parity/config.toml` config file, see [Configuring Parity Ethereum](https://paritytech.github.io/wiki/Configuring-Parity) for details.
## 4. Testing <a id="chapter-004"></a>
You can run tests with the following commands:
* **All** packages
```
cargo test --all
```
* Specific package
```
cargo test --package <spec>
```
Replace `<spec>` with one of the packages from the [package list](#package-list) (e.g. `cargo test --package evmbin`).
You can show your logs in the test output by passing `--nocapture` (i.e. `cargo test --package evmbin -- --nocapture`)
## 5. Documentation <a id="chapter-005"></a>
Official website: https://parity.io
Be sure to [check out our wiki](https://wiki.parity.io) for more information.
### Viewing documentation for Parity Ethereum packages
You can generate documentation for Parity Ethereum Rust packages that automatically opens in your web browser using [rustdoc with Cargo](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html#using-rustdoc-with-cargo) (of the The Rustdoc Book), by running the the following commands:
* **All** packages
```
cargo doc --document-private-items --open
```
* Specific package
```
cargo doc --package <spec> -- --document-private-items --open
```
Use`--document-private-items` to also view private documentation and `--no-deps` to exclude building documentation for dependencies.
Replacing `<spec>` with one of the following from the details section below (i.e. `cargo doc --package parity-ethereum --open`):
<a id="package-list"></a>
**Package List**
<details><p>
* Parity Ethereum (EthCore) Client Application
```bash
parity-ethereum
```
* Parity Ethereum Account Management, Key Management Tool, and Keys Generator
```bash
ethcore-accounts, ethkey-cli, ethstore, ethstore-cli
```
* Parity Chain Specification
```bash
chainspec
```
* Parity CLI Signer Tool & RPC Client
```bash
cli-signer parity-rpc-client
```
* Parity Ethereum Ethash & ProgPoW Implementations
```bash
ethash
```
* Parity (EthCore) Library
```bash
ethcore
```
* Parity Ethereum Blockchain Database, Test Generator, Configuration,
Caching, Importing Blocks, and Block Information
```bash
ethcore-blockchain
```
* Parity Ethereum (EthCore) Contract Calls and Blockchain Service & Registry Information
```bash
ethcore-call-contract
```
* Parity Ethereum (EthCore) Database Access & Utilities, Database Cache Manager
```bash
ethcore-db
```
* Parity Ethereum Virtual Machine (EVM) Rust Implementation
```bash
evm
```
* Parity Ethereum (EthCore) Light Client Implementation
```bash
ethcore-light
```
* Parity Smart Contract based Node Filter, Manage Permissions of Network Connections
```bash
node-filter
```
* Parity Private Transactions
```bash
ethcore-private-tx
```
* Parity Ethereum (EthCore) Client & Network Service Creation & Registration with the I/O Subsystem
```bash
ethcore-service
```
* Parity Ethereum (EthCore) Blockchain Synchronization
```bash
ethcore-sync
```
* Parity Ethereum Common Types
```bash
common-types
```
* Parity Ethereum Virtual Machines (VM) Support Library
```bash
vm
```
* Parity Ethereum WASM Interpreter
```bash
wasm
```
* Parity Ethereum WASM Test Runner
```bash
pwasm-run-test
```
* Parity EVM Implementation
```bash
evmbin
```
* Parity Ethereum IPFS-compatible API
```bash
parity-ipfs-api
```
* Parity Ethereum JSON Deserialization
```bash
ethjson
```
* Parity Ethereum State Machine Generalization for Consensus Engines
```bash
parity-machine
```
* Parity Ethereum (EthCore) Miner Interface
```bash
ethcore-miner parity-local-store price-info ethcore-stratum using_queue
```
* Parity Ethereum (EthCore) Logger Implementation
```bash
ethcore-logger
```
* C bindings library for the Parity Ethereum client
```bash
parity-clib
```
* Parity Ethereum JSON-RPC Servers
```bash
parity-rpc
```
* Parity Ethereum (EthCore) Secret Store
```bash
ethcore-secretstore
```
* Parity Updater Service
```bash
parity-updater parity-hash-fetch
```
* Parity Core Libraries (Parity Util)
```bash
ethcore-bloom-journal blooms-db dir eip-712 fake-fetch fastmap fetch ethcore-io
journaldb keccak-hasher len-caching-lock macros memory-cache memzero
migration-rocksdb ethcore-network ethcore-network-devp2p panic_hook
patricia-trie-ethereum registrar rlp_compress rlp_derive parity-runtime stats
time-utils triehash-ethereum unexpected parity-version
```
* Parity Whisper Protocol Implementation
```bash
parity-whisper whisper-cli
```
</p></details>
### Contributing to documentation for Parity Ethereum packages
[Document source code](https://doc.rust-lang.org/1.9.0/book/documentation.html) for Parity Ethereum packages by annotating the source code with documentation comments.
Example (generic documentation comment):
```markdown
/// Summary
///
/// Description
///
/// # Panics
///
/// # Errors
///
/// # Safety
///
/// # Examples
///
/// Summary of Example 1
///
/// ```rust
/// // insert example 1 code here for use with documentation as tests
/// ```
///
```
## 6. Toolchain <a id="chapter-006"></a>
## Parity Ethereum toolchain
In addition to the Parity Ethereum client, there are additional tools in this repository available:
- [evmbin](./evmbin) - Parity Ethereum EVM Implementation.
- [ethstore](./accounts/ethstore) - Parity Ethereum Key Management.
- [ethkey](./accounts/ethkey) - Parity Ethereum Keys Generator.
- [whisper](./whisper) - Parity Ethereum Whisper-v2 PoC Implementation.
- [evmbin](https://github.com/paritytech/parity-ethereum/blob/master/evmbin/) - EVM implementation for Parity Ethereum.
- [ethabi](https://github.com/paritytech/ethabi) - Parity Ethereum function calls encoding.
- [ethstore](https://github.com/paritytech/parity-ethereum/blob/master/accounts/ethstore) - Parity Ethereum key management.
- [ethkey](https://github.com/paritytech/parity-ethereum/blob/master/accounts/ethkey) - Parity Ethereum keys generator.
- [whisper](https://github.com/paritytech/parity-ethereum/blob/master/whisper/) - Implementation of Whisper-v2 PoC.
The following tool is available in a separate repository:
- [ethabi](https://github.com/paritytech/ethabi) - Parity Ethereum Encoding of Function Calls. [Docs here](https://crates.io/crates/ethabi)
## 7. Community <a id="chapter-007"></a>
### Join the chat!
## Join the chat!
Questions? Get in touch with us on Gitter:
[![Gitter: Parity](https://img.shields.io/badge/gitter-parity-4AB495.svg)](https://gitter.im/paritytech/parity)
@@ -378,14 +148,8 @@ Questions? Get in touch with us on Gitter:
Alternatively, join our community on Matrix:
[![Riot: +Parity](https://img.shields.io/badge/riot-%2Bparity%3Amatrix.parity.io-orange.svg)](https://riot.im/app/#/group/+parity:matrix.parity.io)
## 8. Contributing <a id="chapter-008"></a>
## Documentation
An introduction has been provided in the ["So You Want to be a Core Developer" presentation slides by Hernando Castano](http://tiny.cc/contrib-to-parity-eth). Additional guidelines are provided in [CONTRIBUTING](./.github/CONTRIBUTING.md).
Official website: https://parity.io
### Contributor Code of Conduct
[CODE_OF_CONDUCT](./.github/CODE_OF_CONDUCT.md)
## 9. License <a id="chapter-009"></a>
[LICENSE](./LICENSE)
Be sure to [check out our wiki](https://wiki.parity.io) for more information.

View File

@@ -1,21 +0,0 @@
[package]
description = "Parity Ethereum Account Management"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "ethcore-accounts"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
ethkey = { path = "ethkey" }
ethstore = { path = "ethstore" }
log = "0.4"
parking_lot = "0.7"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
[dev-dependencies]
ethereum-types = "0.6.0"
tempdir = "0.3"

View File

@@ -1,21 +1,21 @@
[package]
description = "Parity Ethereum Keys Generator"
name = "ethkey"
version = "0.3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
byteorder = "1.0"
edit-distance = "2.0"
parity-crypto = "0.4.0"
parity-crypto = "0.2"
eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
ethereum-types = "0.6.0"
ethereum-types = "0.4"
lazy_static = "1.0"
log = "0.4"
parity-wordlist = "1.3"
memzero = { path = "../../util/memzero" }
parity-wordlist = "1.2"
quick-error = "1.2.2"
rand = "0.6"
rand = "0.4"
rustc-hex = "1.0"
serde = "1.0"
serde_derive = "1.0"
tiny-keccak = "1.4"
zeroize = "0.9.1"

View File

@@ -5,8 +5,8 @@ Parity Ethereum keys generator.
### Usage
```
Parity Ethereum Keys Generator.
Copyright 2015-2019 Parity Technologies (UK) Ltd.
Parity Ethereum keys generator.
Copyright 2015-2018 Parity Technologies (UK) Ltd.
Usage:
ethkey info <secret-or-phrase> [options]

View File

@@ -1,5 +1,4 @@
[package]
description = "Parity Ethereum Keys Generator CLI"
name = "ethkey-cli"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]

View File

@@ -35,7 +35,7 @@ use rustc_hex::{FromHex, FromHexError};
const USAGE: &'static str = r#"
Parity Ethereum keys generator.
Copyright 2015-2019 Parity Technologies (UK) Ltd.
Copyright 2015-2018 Parity Technologies (UK) Ltd.
Usage:
ethkey info <secret-or-phrase> [options]

View File

@@ -47,7 +47,7 @@ impl Generator for BrainPrefix {
for _ in 0..self.iterations {
let phrase = wordlist::random_phrase(self.no_of_words);
let keypair = Brain::new(phrase.clone()).generate().unwrap();
if keypair.address().as_ref().starts_with(&self.prefix) {
if keypair.address().starts_with(&self.prefix) {
self.last_phrase = phrase;
return Ok(keypair)
}
@@ -65,6 +65,6 @@ mod tests {
fn prefix_generator() {
let prefix = vec![0x00u8];
let keypair = BrainPrefix::new(prefix.clone(), usize::max_value(), 12).generate().unwrap();
assert!(keypair.address().as_bytes().starts_with(&prefix));
assert!(keypair.address().starts_with(&prefix));
}
}

View File

@@ -57,7 +57,7 @@ pub mod ecdh {
};
let publ = key::PublicKey::from_slice(context, &pdata)?;
let sec = key::SecretKey::from_slice(context, secret.as_bytes())?;
let sec = key::SecretKey::from_slice(context, &secret)?;
let shared = ecdh::SharedSecret::new_raw(context, &publ, &sec);
Secret::from_unsafe_slice(&shared[0..32])
@@ -89,12 +89,12 @@ pub mod ecies {
msg[0] = 0x04u8;
{
let msgd = &mut msg[1..];
msgd[0..64].copy_from_slice(r.public().as_bytes());
msgd[0..64].copy_from_slice(r.public());
let iv = H128::random();
msgd[64..80].copy_from_slice(iv.as_bytes());
msgd[64..80].copy_from_slice(&iv);
{
let cipher = &mut msgd[(64 + 16)..(64 + 16 + plain.len())];
aes::encrypt_128_ctr(ekey, iv.as_bytes(), plain, cipher)?;
aes::encrypt_128_ctr(ekey, &iv, plain, cipher)?;
}
let mut hmac = hmac::Signer::with(&mkey);
{
@@ -156,7 +156,7 @@ pub mod ecies {
let mut hasher = digest::Hasher::sha256();
let ctrs = [(ctr >> 24) as u8, (ctr >> 16) as u8, (ctr >> 8) as u8, ctr as u8];
hasher.update(&ctrs);
hasher.update(secret.as_bytes());
hasher.update(secret);
hasher.update(s1);
let d = hasher.finish();
&mut dest[written..(written + 32)].copy_from_slice(&d);

View File

@@ -35,8 +35,9 @@ impl Label for u32 {
fn len() -> usize { 4 }
fn store(&self, target: &mut [u8]) {
let bytes = self.to_be_bytes();
target[0..4].copy_from_slice(&bytes);
use byteorder::{BigEndian, ByteOrder};
BigEndian::write_u32(&mut target[0..4], *self);
}
}
@@ -63,7 +64,7 @@ impl Label for H256 {
fn len() -> usize { 32 }
fn store(&self, target: &mut [u8]) {
(&mut target[0..32]).copy_from_slice(self.as_bytes());
self.copy_to(&mut target[0..32]);
}
}
@@ -179,7 +180,7 @@ impl ExtendedKeyPair {
pub fn with_seed(seed: &[u8]) -> Result<ExtendedKeyPair, DerivationError> {
let (master_key, chain_code) = derivation::seed_pair(seed);
Ok(ExtendedKeyPair::with_secret(
Secret::from_unsafe_slice(master_key.as_bytes()).map_err(|_| DerivationError::InvalidSeed)?,
Secret::from_unsafe_slice(&*master_key).map_err(|_| DerivationError::InvalidSeed)?,
chain_code,
))
}
@@ -207,13 +208,12 @@ impl ExtendedKeyPair {
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
mod derivation {
use parity_crypto::hmac;
use ethereum_types::{BigEndianHash, U256, U512, H512, H256};
use ethereum_types::{U256, U512, H512, H256};
use secp256k1::key::{SecretKey, PublicKey};
use SECP256K1;
use keccak;
use math::curve_order;
use super::{Label, Derivation};
use std::convert::TryInto;
#[derive(Debug)]
pub enum Error {
@@ -237,18 +237,18 @@ mod derivation {
}
fn hmac_pair(data: &[u8], private_key: H256, chain_code: H256) -> (H256, H256) {
let private: U256 = private_key.into_uint();
let private: U256 = private_key.into();
// produces 512-bit derived hmac (I)
let skey = hmac::SigKey::sha512(chain_code.as_bytes());
let skey = hmac::SigKey::sha512(&*chain_code);
let i_512 = hmac::sign(&skey, &data[..]);
// left most 256 bits are later added to original private key
let hmac_key: U256 = H256::from_slice(&i_512[0..32]).into_uint();
let hmac_key: U256 = H256::from_slice(&i_512[0..32]).into();
// right most 256 bits are new chain code for later derivations
let next_chain_code = H256::from_slice(&i_512[32..64]);
let next_chain_code = H256::from(&i_512[32..64]);
let child_key = BigEndianHash::from_uint(&private_add(hmac_key, private));
let child_key = private_add(hmac_key, private).into();
(child_key, next_chain_code)
}
@@ -257,7 +257,7 @@ mod derivation {
fn private_soft<T>(private_key: H256, chain_code: H256, index: T) -> (H256, H256) where T: Label {
let mut data = vec![0u8; 33 + T::len()];
let sec_private = SecretKey::from_slice(&SECP256K1, private_key.as_bytes())
let sec_private = SecretKey::from_slice(&SECP256K1, &*private_key)
.expect("Caller should provide valid private key");
let sec_public = PublicKey::from_secret_key(&SECP256K1, &sec_private)
.expect("Caller should provide valid private key");
@@ -276,7 +276,7 @@ mod derivation {
// corresponding public keys of the original and derived private keys
fn private_hard<T>(private_key: H256, chain_code: H256, index: T) -> (H256, H256) where T: Label {
let mut data: Vec<u8> = vec![0u8; 33 + T::len()];
let private: U256 = private_key.into_uint();
let private: U256 = private_key.into();
// 0x00 (padding) -- private_key -- index
// 0 -- 1..33 -- 33..end
@@ -293,8 +293,9 @@ mod derivation {
// todo: surely can be optimized
fn modulo(u1: U512, u2: U256) -> U256 {
let m = u1 % U512::from(u2);
m.try_into().expect("U512 modulo U256 should fit into U256; qed")
let dv = u1 / U512::from(u2);
let md = u1 - (dv * U512::from(u2));
md.into()
}
pub fn public<T>(public_key: H512, chain_code: H256, derivation: Derivation<T>) -> Result<(H512, H256), Error> where T: Label {
@@ -305,7 +306,7 @@ mod derivation {
let mut public_sec_raw = [0u8; 65];
public_sec_raw[0] = 4;
public_sec_raw[1..65].copy_from_slice(public_key.as_bytes());
public_sec_raw[1..65].copy_from_slice(&*public_key);
let public_sec = PublicKey::from_slice(&SECP256K1, &public_sec_raw).map_err(|_| Error::InvalidPoint)?;
let public_serialized = public_sec.serialize_vec(&SECP256K1, true);
@@ -316,15 +317,15 @@ mod derivation {
index.store(&mut data[33..(33 + T::len())]);
// HMAC512SHA produces [derived private(256); new chain code(256)]
let skey = hmac::SigKey::sha512(chain_code.as_bytes());
let skey = hmac::SigKey::sha512(&*chain_code);
let i_512 = hmac::sign(&skey, &data[..]);
let new_private = H256::from_slice(&i_512[0..32]);
let new_chain_code = H256::from_slice(&i_512[32..64]);
let new_private = H256::from(&i_512[0..32]);
let new_chain_code = H256::from(&i_512[32..64]);
// Generated private key can (extremely rarely) be out of secp256k1 key field
if curve_order() <= new_private.into_uint() { return Err(Error::MissingIndex); }
let new_private_sec = SecretKey::from_slice(&SECP256K1, new_private.as_bytes())
if curve_order() <= new_private.clone().into() { return Err(Error::MissingIndex); }
let new_private_sec = SecretKey::from_slice(&SECP256K1, &*new_private)
.expect("Private key belongs to the field [0..CURVE_ORDER) (checked above); So initializing can never fail; qed");
let mut new_public = PublicKey::from_secret_key(&SECP256K1, &new_private_sec)
.expect("Valid private key produces valid public key");
@@ -336,7 +337,7 @@ mod derivation {
let serialized = new_public.serialize_vec(&SECP256K1, false);
Ok((
H512::from_slice(&serialized[1..65]),
H512::from(&serialized[1..65]),
new_chain_code,
))
}
@@ -347,18 +348,18 @@ mod derivation {
pub fn chain_code(secret: H256) -> H256 {
// 10,000 rounds of sha3
let mut running_sha3 = sha3(secret.as_bytes());
for _ in 0..99999 { running_sha3 = sha3(running_sha3.as_bytes()); }
let mut running_sha3 = sha3(&*secret);
for _ in 0..99999 { running_sha3 = sha3(&*running_sha3); }
running_sha3
}
pub fn point(secret: H256) -> Result<H512, Error> {
let sec = SecretKey::from_slice(&SECP256K1, secret.as_bytes())
let sec = SecretKey::from_slice(&SECP256K1, &*secret)
.map_err(|_| Error::InvalidPoint)?;
let public_sec = PublicKey::from_secret_key(&SECP256K1, &sec)
.map_err(|_| Error::InvalidPoint)?;
let serialized = public_sec.serialize_vec(&SECP256K1, false);
Ok(H512::from_slice(&serialized[1..65]))
Ok(H512::from(&serialized[1..65]))
}
pub fn seed_pair(seed: &[u8]) -> (H256, H256) {
@@ -377,13 +378,12 @@ mod tests {
use super::{ExtendedSecret, ExtendedPublic, ExtendedKeyPair};
use secret::Secret;
use std::str::FromStr;
use ethereum_types::{H128, H256, H512};
use ethereum_types::{H128, H256};
use super::{derivation, Derivation};
fn master_chain_basic() -> (H256, H256) {
let seed = H128::from_str("000102030405060708090a0b0c0d0e0f")
.expect("Seed should be valid H128")
.as_bytes()
.to_vec();
derivation::seed_pair(&*seed)
@@ -399,39 +399,27 @@ mod tests {
#[test]
fn smoky() {
let secret = Secret::from_str("a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65").unwrap();
let extended_secret = ExtendedSecret::with_code(secret.clone(), H256::zero());
let extended_secret = ExtendedSecret::with_code(secret.clone(), 0u64.into());
// hardened
assert_eq!(&**extended_secret.as_raw(), &*secret);
assert_eq!(
**extended_secret.derive(2147483648.into()).as_raw(),
H256::from_str("0927453daed47839608e414a3738dfad10aed17c459bbd9ab53f89b026c834b6").unwrap(),
);
assert_eq!(
**extended_secret.derive(2147483649.into()).as_raw(),
H256::from_str("44238b6a29c6dcbe9b401364141ba11e2198c289a5fed243a1c11af35c19dc0f").unwrap(),
);
assert_eq!(&**extended_secret.derive(2147483648.into()).as_raw(), &"0927453daed47839608e414a3738dfad10aed17c459bbd9ab53f89b026c834b6".into());
assert_eq!(&**extended_secret.derive(2147483649.into()).as_raw(), &"44238b6a29c6dcbe9b401364141ba11e2198c289a5fed243a1c11af35c19dc0f".into());
// normal
assert_eq!(**extended_secret.derive(0.into()).as_raw(), H256::from_str("bf6a74e3f7b36fc4c96a1e12f31abc817f9f5904f5a8fc27713163d1f0b713f6").unwrap());
assert_eq!(**extended_secret.derive(1.into()).as_raw(), H256::from_str("bd4fca9eb1f9c201e9448c1eecd66e302d68d4d313ce895b8c134f512205c1bc").unwrap());
assert_eq!(**extended_secret.derive(2.into()).as_raw(), H256::from_str("86932b542d6cab4d9c65490c7ef502d89ecc0e2a5f4852157649e3251e2a3268").unwrap());
assert_eq!(&**extended_secret.derive(0.into()).as_raw(), &"bf6a74e3f7b36fc4c96a1e12f31abc817f9f5904f5a8fc27713163d1f0b713f6".into());
assert_eq!(&**extended_secret.derive(1.into()).as_raw(), &"bd4fca9eb1f9c201e9448c1eecd66e302d68d4d313ce895b8c134f512205c1bc".into());
assert_eq!(&**extended_secret.derive(2.into()).as_raw(), &"86932b542d6cab4d9c65490c7ef502d89ecc0e2a5f4852157649e3251e2a3268".into());
let extended_public = ExtendedPublic::from_secret(&extended_secret).expect("Extended public should be created");
let derived_public = extended_public.derive(0.into()).expect("First derivation of public should succeed");
assert_eq!(
*derived_public.public(),
H512::from_str("f7b3244c96688f92372bfd4def26dc4151529747bab9f188a4ad34e141d47bd66522ff048bc6f19a0a4429b04318b1a8796c000265b4fa200dae5f6dda92dd94").unwrap(),
);
assert_eq!(&*derived_public.public(), &"f7b3244c96688f92372bfd4def26dc4151529747bab9f188a4ad34e141d47bd66522ff048bc6f19a0a4429b04318b1a8796c000265b4fa200dae5f6dda92dd94".into());
let keypair = ExtendedKeyPair::with_secret(
Secret::from_str("a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65").unwrap(),
H256::from_low_u64_be(64),
);
assert_eq!(
**keypair.derive(2147483648u32.into()).expect("Derivation of keypair should succeed").secret().as_raw(),
H256::from_str("edef54414c03196557cf73774bc97a645c9a1df2164ed34f0c2a78d1375a930c").unwrap(),
064.into(),
);
assert_eq!(&**keypair.derive(2147483648u32.into()).expect("Derivation of keypair should succeed").secret().as_raw(), &"edef54414c03196557cf73774bc97a645c9a1df2164ed34f0c2a78d1375a930c".into());
}
#[test]
@@ -439,7 +427,7 @@ mod tests {
let secret = Secret::from_str("a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65").unwrap();
let derivation_secret = H256::from_str("51eaf04f9dbbc1417dc97e789edd0c37ecda88bac490434e367ea81b71b7b015").unwrap();
let extended_secret = ExtendedSecret::with_code(secret.clone(), H256::zero());
let extended_secret = ExtendedSecret::with_code(secret.clone(), 0u64.into());
let extended_public = ExtendedPublic::from_secret(&extended_secret).expect("Extended public should be created");
let derived_secret0 = extended_secret.derive(Derivation::Soft(derivation_secret));
@@ -454,18 +442,15 @@ mod tests {
fn h256_hard() {
let secret = Secret::from_str("a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65").unwrap();
let derivation_secret = H256::from_str("51eaf04f9dbbc1417dc97e789edd0c37ecda88bac490434e367ea81b71b7b015").unwrap();
let extended_secret = ExtendedSecret::with_code(secret.clone(), H256::from_low_u64_be(1));
let extended_secret = ExtendedSecret::with_code(secret.clone(), 1u64.into());
assert_eq!(
**extended_secret.derive(Derivation::Hard(derivation_secret)).as_raw(),
H256::from_str("2bc2d696fb744d77ff813b4a1ef0ad64e1e5188b622c54ba917acc5ebc7c5486").unwrap(),
);
assert_eq!(&**extended_secret.derive(Derivation::Hard(derivation_secret)).as_raw(), &"2bc2d696fb744d77ff813b4a1ef0ad64e1e5188b622c54ba917acc5ebc7c5486".into());
}
#[test]
fn match_() {
let secret = Secret::from_str("a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65").unwrap();
let extended_secret = ExtendedSecret::with_code(secret.clone(), H256::from_low_u64_be(1));
let extended_secret = ExtendedSecret::with_code(secret.clone(), 1.into());
let extended_public = ExtendedPublic::from_secret(&extended_secret).expect("Extended public should be created");
let derived_secret0 = extended_secret.derive(0.into());
@@ -480,7 +465,6 @@ mod tests {
fn test_seeds() {
let seed = H128::from_str("000102030405060708090a0b0c0d0e0f")
.expect("Seed should be valid H128")
.as_bytes()
.to_vec();
// private key from bitcoin test vector

View File

@@ -16,13 +16,14 @@
use std::fmt;
use secp256k1::key;
use rustc_hex::ToHex;
use keccak::Keccak256;
use super::{Secret, Public, Address, SECP256K1, Error};
use parity_crypto::Keccak256 as _;
pub fn public_to_address(public: &Public) -> Address {
let hash = public.keccak256();
let mut result = Address::zero();
result.as_bytes_mut().copy_from_slice(&hash[12..]);
let mut result = Address::default();
result.copy_from_slice(&hash[12..]);
result
}
@@ -35,9 +36,9 @@ pub struct KeyPair {
impl fmt::Display for KeyPair {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
writeln!(f, "secret: {:x}", self.secret)?;
writeln!(f, "public: {:x}", self.public)?;
write!(f, "address: {:x}", self.address())
writeln!(f, "secret: {}", self.secret.to_hex())?;
writeln!(f, "public: {}", self.public.to_hex())?;
write!(f, "address: {}", self.address().to_hex())
}
}
@@ -50,7 +51,7 @@ impl KeyPair {
let serialized = pub_key.serialize_vec(context, false);
let mut public = Public::default();
public.as_bytes_mut().copy_from_slice(&serialized[1..65]);
public.copy_from_slice(&serialized[1..65]);
let keypair = KeyPair {
secret: secret,
@@ -69,7 +70,7 @@ impl KeyPair {
let serialized = publ.serialize_vec(context, false);
let secret = Secret::from(sec);
let mut public = Public::default();
public.as_bytes_mut().copy_from_slice(&serialized[1..65]);
public.copy_from_slice(&serialized[1..65]);
KeyPair {
secret: secret,

View File

@@ -16,9 +16,11 @@
// #![warn(missing_docs)]
extern crate byteorder;
extern crate edit_distance;
extern crate parity_crypto;
extern crate ethereum_types;
extern crate memzero;
extern crate parity_wordlist;
#[macro_use]
extern crate quick_error;
@@ -27,7 +29,6 @@ extern crate rustc_hex;
extern crate secp256k1;
extern crate serde;
extern crate tiny_keccak;
extern crate zeroize;
#[macro_use]
extern crate lazy_static;

View File

@@ -17,7 +17,7 @@
use super::{SECP256K1, Public, Secret, Error};
use secp256k1::key;
use secp256k1::constants::{GENERATOR_X, GENERATOR_Y, CURVE_ORDER};
use ethereum_types::{BigEndianHash as _, U256, H256};
use ethereum_types::{U256, H256};
/// Whether the public key is valid.
pub fn public_is_valid(public: &Public) -> bool {
@@ -78,7 +78,7 @@ pub fn generation_point() -> Public {
/// Return secp256k1 elliptic curve order
pub fn curve_order() -> U256 {
H256::from_slice(&CURVE_ORDER).into_uint()
H256::from_slice(&CURVE_ORDER).into()
}
fn to_secp256k1_public(public: &Public) -> Result<key::PublicKey, Error> {
@@ -93,7 +93,7 @@ fn to_secp256k1_public(public: &Public) -> Result<key::PublicKey, Error> {
fn set_public(public: &mut Public, key_public: &key::PublicKey) {
let key_public_serialized = key_public.serialize_vec(&SECP256K1, false);
public.as_bytes_mut().copy_from_slice(&key_public_serialized[1..65]);
public.copy_from_slice(&key_public_serialized[1..65]);
}
#[cfg(test)]

View File

@@ -37,7 +37,7 @@ impl Generator for Prefix {
fn generate(&mut self) -> Result<KeyPair, Error> {
for _ in 0..self.iterations {
let keypair = Random.generate()?;
if keypair.address().as_ref().starts_with(&self.prefix) {
if keypair.address().starts_with(&self.prefix) {
return Ok(keypair)
}
}
@@ -54,6 +54,6 @@ mod tests {
fn prefix_generator() {
let prefix = vec![0xffu8];
let keypair = Prefix::new(prefix.clone(), usize::max_value()).generate().unwrap();
assert!(keypair.address().as_bytes().starts_with(&prefix));
assert!(keypair.address().starts_with(&prefix));
}
}

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use rand::rngs::OsRng;
use rand::os::OsRng;
use super::{Generator, KeyPair, SECP256K1};
/// Randomly generates new keypair, instantiating the RNG each time.

View File

@@ -21,23 +21,17 @@ use rustc_hex::ToHex;
use secp256k1::constants::{SECRET_KEY_SIZE as SECP256K1_SECRET_KEY_SIZE};
use secp256k1::key;
use ethereum_types::H256;
use zeroize::Zeroize;
use memzero::Memzero;
use {Error, SECP256K1};
#[derive(Clone, PartialEq, Eq)]
pub struct Secret {
inner: H256,
}
impl Drop for Secret {
fn drop(&mut self) {
self.inner.0.zeroize()
}
inner: Memzero<H256>,
}
impl ToHex for Secret {
fn to_hex(&self) -> String {
format!("{:x}", self.inner)
format!("{:x}", *self.inner)
}
}
@@ -65,14 +59,14 @@ impl Secret {
if key.len() != 32 {
return None
}
let mut h = H256::zero();
h.as_bytes_mut().copy_from_slice(&key[0..32]);
Some(Secret { inner: h })
let mut h = H256::default();
h.copy_from_slice(&key[0..32]);
Some(Secret { inner: Memzero::from(h) })
}
/// Creates zero key, which is invalid for crypto operations, but valid for math operation.
pub fn zero() -> Self {
Secret { inner: H256::zero() }
Secret { inner: Memzero::from(H256::default()) }
}
/// Imports and validates the key.
@@ -220,7 +214,7 @@ impl FromStr for Secret {
impl From<[u8; 32]> for Secret {
fn from(k: [u8; 32]) -> Self {
Secret { inner: H256(k) }
Secret { inner: Memzero::from(H256(k)) }
}
}

View File

@@ -68,44 +68,24 @@ impl Signature {
/// Create a signature object from the sig.
pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Self {
let mut sig = [0u8; 65];
sig[0..32].copy_from_slice(r.as_ref());
sig[32..64].copy_from_slice(s.as_ref());
sig[0..32].copy_from_slice(&r);
sig[32..64].copy_from_slice(&s);
sig[64] = v;
Signature(sig)
}
/// Check if this is a "low" signature.
pub fn is_low_s(&self) -> bool {
// "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0"
const MASK: H256 = H256([
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x5D, 0x57, 0x6E, 0x73, 0x57, 0xA4, 0x50, 0x1D,
0xDF, 0xE9, 0x2F, 0x46, 0x68, 0x1B, 0x20, 0xA0,
]);
H256::from_slice(self.s()) <= MASK
H256::from_slice(self.s()) <= "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0".into()
}
/// Check if each component of the signature is in range.
pub fn is_valid(&self) -> bool {
// "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"
const MASK: H256 = H256([
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
]);
const ONE: H256 = H256([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
]);
let r = H256::from_slice(self.r());
let s = H256::from_slice(self.s());
self.v() <= 1 &&
r < MASK && r >= ONE &&
s < MASK && s >= ONE
H256::from_slice(self.r()) < "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141".into() &&
H256::from_slice(self.r()) >= 1.into() &&
H256::from_slice(self.s()) < "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141".into() &&
H256::from_slice(self.s()) >= 1.into()
}
}
@@ -210,7 +190,7 @@ impl DerefMut for Signature {
pub fn sign(secret: &Secret, message: &Message) -> Result<Signature, Error> {
let context = &SECP256K1;
let sec = SecretKey::from_slice(context, secret.as_ref())?;
let sec = SecretKey::from_slice(context, &secret)?;
let s = context.sign_recoverable(&SecpMessage::from_slice(&message[..])?, &sec)?;
let (rec_id, data) = s.serialize_compact(context);
let mut data_arr = [0; 65];
@@ -228,7 +208,7 @@ pub fn verify_public(public: &Public, signature: &Signature, message: &Message)
let pdata: [u8; 65] = {
let mut temp = [4u8; 65];
temp[1..65].copy_from_slice(public.as_bytes());
temp[1..65].copy_from_slice(&**public);
temp
};
@@ -253,7 +233,7 @@ pub fn recover(signature: &Signature, message: &Message) -> Result<Public, Error
let serialized = pubkey.serialize_vec(context, false);
let mut public = Public::default();
public.as_bytes_mut().copy_from_slice(&serialized[1..65]);
public.copy_from_slice(&serialized[1..65]);
Ok(public)
}

View File

@@ -1,5 +1,4 @@
[package]
description = "Parity Ethereum Key Management"
name = "ethstore"
version = "0.2.1"
authors = ["Parity Technologies <admin@parity.io>"]
@@ -7,7 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
log = "0.4"
libc = "0.2"
rand = "0.6"
rand = "0.4"
ethkey = { path = "../ethkey" }
serde = "1.0"
serde_json = "1.0"
@@ -17,8 +16,8 @@ tiny-keccak = "1.4"
time = "0.1.34"
itertools = "0.5"
parking_lot = "0.7"
parity-crypto = "0.4.0"
ethereum-types = "0.6.0"
parity-crypto = "0.2"
ethereum-types = "0.4"
dir = { path = "../../util/dir" }
smallvec = "0.6"
parity-wordlist = "1.0"

View File

@@ -6,7 +6,7 @@ Parity Ethereum key management.
```
Parity Ethereum key management tool.
Copyright 2015-2019 Parity Technologies (UK) Ltd.
Copyright 2015-2018 Parity Technologies (UK) Ltd.
Usage:
ethstore insert <secret> <password> [--dir DIR] [--vault VAULT] [--vault-pwd VAULTPWD]

View File

@@ -1,5 +1,4 @@
[package]
description = "Parity Ethereum Key Management CLI"
name = "ethstore-cli"
version = "0.1.1"
authors = ["Parity Technologies <admin@parity.io>"]
@@ -22,4 +21,4 @@ path = "src/main.rs"
doc = false
[dev-dependencies]
tempdir = "0.3"
tempdir = "0.3.5"

View File

@@ -41,7 +41,7 @@ mod crack;
pub const USAGE: &'static str = r#"
Parity Ethereum key management tool.
Copyright 2015-2019 Parity Technologies (UK) Ltd.
Copyright 2015-2018 Parity Technologies (UK) Ltd.
Usage:
ethstore insert <secret> <password> [--dir DIR] [--vault VAULT] [--vault-pwd VAULTPWD]

View File

@@ -74,7 +74,7 @@ impl From<Crypto> for String {
impl Crypto {
/// Encrypt account secret
pub fn with_secret(secret: &Secret, password: &Password, iterations: u32) -> Result<Self, crypto::Error> {
Crypto::with_plain(secret.as_ref(), password, iterations)
Crypto::with_plain(&*secret, password, iterations)
}
/// Encrypt custom plain data

View File

@@ -61,6 +61,7 @@ pub fn find_unique_filename_using_random_suffix(parent_path: &Path, original_fil
/// Create a new file and restrict permissions to owner only. It errors if the file already exists.
#[cfg(unix)]
pub fn create_new_file_with_permissions_to_owner(file_path: &Path) -> io::Result<fs::File> {
use libc;
use std::os::unix::fs::OpenOptionsExt;
fs::OpenOptions::new()
@@ -82,6 +83,7 @@ pub fn create_new_file_with_permissions_to_owner(file_path: &Path) -> io::Result
/// Create a new file and restrict permissions to owner only. It replaces the existing file if it already exists.
#[cfg(unix)]
pub fn replace_file_with_permissions_to_owner(file_path: &Path) -> io::Result<fs::File> {
use libc;
use std::os::unix::fs::PermissionsExt;
let file = fs::File::create(file_path)?;

View File

@@ -68,7 +68,7 @@ impl KeyDirectory for MemoryDirectory {
fn unique_repr(&self) -> Result<u64, Error> {
let mut val = 0u64;
let accounts = self.accounts.read();
for acc in accounts.keys() { val = val ^ acc.to_low_u64_be() }
for acc in accounts.keys() { val = val ^ acc.low_u64() }
Ok(val)
}
}

View File

@@ -1084,7 +1084,7 @@ mod tests {
SecretVaultRef::Root,
&address,
&"test".into(),
Derivation::HardHash(H256::zero()),
Derivation::HardHash(H256::from(0)),
).unwrap();
// there should be 2 accounts in the store

View File

@@ -41,7 +41,7 @@ impl str::FromStr for Crypto {
impl From<Crypto> for String {
fn from(c: Crypto) -> Self {
serde_json::to_string(&c).expect("Serialization cannot fail, because all crypto keys are strings")
serde_json::to_string(&c).expect("serialization cannot fail, cause all crypto keys are strings")
}
}

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use rand::{Rng, RngCore, rngs::OsRng, distributions::Alphanumeric};
use rand::{Rng, OsRng};
pub trait Random {
fn random() -> Self where Self: Sized;
@@ -41,5 +41,5 @@ impl Random for [u8; 32] {
/// Generate a random string of given length.
pub fn random_string(length: usize) -> String {
let mut rng = OsRng::new().expect("Not able to operate without random source.");
rng.sample_iter(&Alphanumeric).take(length).collect()
rng.gen_ascii_chars().take(length).collect()
}

View File

@@ -16,7 +16,6 @@
extern crate rand;
extern crate ethstore;
extern crate ethereum_types;
mod util;
@@ -24,8 +23,6 @@ use ethstore::{EthStore, SimpleSecretStore, SecretVaultRef, StoreAccountRef};
use ethstore::ethkey::{Random, Generator, Secret, KeyPair, verify_address};
use ethstore::accounts_dir::RootDiskDirectory;
use util::TransientDir;
use ethereum_types::Address;
use std::str::FromStr;
#[test]
fn secret_store_create() {
@@ -117,9 +114,9 @@ fn secret_store_laod_geth_files() {
let dir = RootDiskDirectory::at(test_path());
let store = EthStore::open(Box::new(dir)).unwrap();
assert_eq!(store.accounts().unwrap(), vec![
StoreAccountRef::root(Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap()),
StoreAccountRef::root(Address::from_str("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf").unwrap()),
StoreAccountRef::root(Address::from_str("63121b431a52f8043c16fcf0d1df9cb7b5f66649").unwrap()),
StoreAccountRef::root("3f49624084b67849c7b4e805c5988c21a430f9d9".into()),
StoreAccountRef::root("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf".into()),
StoreAccountRef::root("63121b431a52f8043c16fcf0d1df9cb7b5f66649".into()),
]);
}
@@ -128,8 +125,8 @@ fn secret_store_load_pat_files() {
let dir = RootDiskDirectory::at(pat_path());
let store = EthStore::open(Box::new(dir)).unwrap();
assert_eq!(store.accounts().unwrap(), vec![
StoreAccountRef::root(Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap()),
StoreAccountRef::root(Address::from_str("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf").unwrap()),
StoreAccountRef::root("3f49624084b67849c7b4e805c5988c21a430f9d9".into()),
StoreAccountRef::root("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf".into()),
]);
}
@@ -143,8 +140,8 @@ fn test_decrypting_files_with_short_ciphertext() {
let store = EthStore::open(Box::new(dir)).unwrap();
let accounts = store.accounts().unwrap();
assert_eq!(accounts, vec![
StoreAccountRef::root(Address::from_str("31e9d1e6d844bd3a536800ef8d8be6a9975db509").unwrap()),
StoreAccountRef::root(Address::from_str("d1e64e5480bfaf733ba7d48712decb8227797a4e").unwrap()),
StoreAccountRef::root("31e9d1e6d844bd3a536800ef8d8be6a9975db509".into()),
StoreAccountRef::root("d1e64e5480bfaf733ba7d48712decb8227797a4e".into()),
]);
let message = Default::default();

View File

@@ -16,7 +16,7 @@
use std::path::PathBuf;
use std::{env, fs};
use rand::{RngCore, rngs::OsRng};
use rand::{Rng, OsRng};
use ethstore::accounts_dir::{KeyDirectory, RootDiskDirectory};
use ethstore::{Error, SafeAccount};

View File

@@ -0,0 +1,10 @@
[package]
description = "Fake hardware-wallet, for OS' that don't support libusb"
name = "fake-hardware-wallet"
version = "0.0.1"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ethereum-types = "0.4"
ethkey = { path = "../../accounts/ethkey" }

View File

@@ -0,0 +1,101 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Dummy module for platforms that does not provide support for hardware wallets (libusb)
extern crate ethereum_types;
extern crate ethkey;
use std::fmt;
use ethereum_types::U256;
use ethkey::{Address, Signature};
pub struct WalletInfo {
pub address: Address,
pub name: String,
pub manufacturer: String,
}
#[derive(Debug)]
/// `ErrorType` for devices with no `hardware wallet`
pub enum Error {
NoWallet,
KeyNotFound,
}
pub struct TransactionInfo {
/// Nonce
pub nonce: U256,
/// Gas price
pub gas_price: U256,
/// Gas limit
pub gas_limit: U256,
/// Receiver
pub to: Option<Address>,
/// Value
pub value: U256,
/// Data
pub data: Vec<u8>,
/// Chain ID
pub chain_id: Option<u64>,
}
pub enum KeyPath {
/// Ethereum.
Ethereum,
/// Ethereum classic.
EthereumClassic,
}
/// `HardwareWalletManager` for devices with no `hardware wallet`
pub struct HardwareWalletManager;
impl HardwareWalletManager {
pub fn new() -> Result<Self, Error> {
Err(Error::NoWallet)
}
pub fn set_key_path(&self, _key_path: KeyPath) {}
pub fn wallet_info(&self, _: &Address) -> Option<WalletInfo> {
None
}
pub fn list_wallets(&self) -> Vec<WalletInfo> {
Vec::with_capacity(0)
}
pub fn list_locked_wallets(&self) -> Result<Vec<String>, Error> {
Err(Error::NoWallet)
}
pub fn pin_matrix_ack(&self, _: &str, _: &str) -> Result<bool, Error> {
Err(Error::NoWallet)
}
pub fn sign_transaction(&self, _address: &Address, _transaction: &TransactionInfo, _rlp_transaction: &[u8]) -> Result<Signature, Error> {
Err(Error::NoWallet) }
pub fn sign_message(&self, _address: &Address, _msg: &[u8]) -> Result<Signature, Error> {
Err(Error::NoWallet)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "No hardware wallet!!")
}
}

21
accounts/hw/Cargo.toml Normal file
View File

@@ -0,0 +1,21 @@
[package]
description = "Hardware wallet support."
homepage = "http://parity.io"
license = "GPL-3.0"
name = "hardware-wallet"
version = "1.12.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
log = "0.4"
parking_lot = "0.7"
protobuf = "1.4"
hidapi = { git = "https://github.com/paritytech/hidapi-rs" }
libusb = { git = "https://github.com/paritytech/libusb-rs" }
trezor-sys = { git = "https://github.com/paritytech/trezor-sys" }
ethkey = { path = "../ethkey" }
ethereum-types = "0.4"
semver = "0.9"
[dev-dependencies]
rustc-hex = "1.0"

534
accounts/hw/src/ledger.rs Normal file

File diff suppressed because one or more lines are too long

402
accounts/hw/src/lib.rs Normal file
View File

@@ -0,0 +1,402 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Hardware wallet management.
#![warn(missing_docs)]
#![warn(warnings)]
extern crate ethereum_types;
extern crate ethkey;
extern crate hidapi;
extern crate libusb;
extern crate parking_lot;
extern crate protobuf;
extern crate semver;
extern crate trezor_sys;
#[macro_use] extern crate log;
#[cfg(test)] extern crate rustc_hex;
mod ledger;
mod trezor;
use std::sync::{Arc, atomic, atomic::AtomicBool, Weak};
use std::{fmt, time::Duration};
use std::thread;
use ethereum_types::U256;
use ethkey::{Address, Signature};
use parking_lot::Mutex;
const HID_GLOBAL_USAGE_PAGE: u16 = 0xFF00;
const HID_USB_DEVICE_CLASS: u8 = 0;
const MAX_POLLING_DURATION: Duration = Duration::from_millis(500);
const USB_EVENT_POLLING_INTERVAL: Duration = Duration::from_millis(500);
/// `HardwareWallet` device
#[derive(Debug)]
pub struct Device {
path: String,
info: WalletInfo,
}
/// `Wallet` trait
pub trait Wallet<'a> {
/// Error
type Error;
/// Transaction data format
type Transaction;
/// Sign transaction data with wallet managing `address`.
fn sign_transaction(&self, address: &Address, transaction: Self::Transaction) -> Result<Signature, Self::Error>;
/// Set key derivation path for a chain.
fn set_key_path(&self, key_path: KeyPath);
/// Re-populate device list
/// Note, this assumes all devices are iterated over and updated
fn update_devices(&self, device_direction: DeviceDirection) -> Result<usize, Self::Error>;
/// Read device info
fn read_device(&self, usb: &hidapi::HidApi, dev_info: &hidapi::HidDeviceInfo) -> Result<Device, Self::Error>;
/// List connected and acknowledged wallets
fn list_devices(&self) -> Vec<WalletInfo>;
/// List locked wallets
/// This may be moved if it is the wrong assumption, for example this is not supported by Ledger
/// Then this method return a empty vector
fn list_locked_devices(&self) -> Vec<String>;
/// Get wallet info.
fn get_wallet(&self, address: &Address) -> Option<WalletInfo>;
/// Generate ethereum address for a Wallet
fn get_address(&self, device: &hidapi::HidDevice) -> Result<Option<Address>, Self::Error>;
/// Open a device using `device path`
/// Note, f - is a closure that borrows HidResult<HidDevice>
/// HidDevice is in turn a type alias for a `c_void function pointer`
/// For further information see:
/// * <https://github.com/paritytech/hidapi-rs>
/// * <https://github.com/rust-lang/libc>
fn open_path<R, F>(&self, f: F) -> Result<R, Self::Error>
where F: Fn() -> Result<R, &'static str>;
}
/// Hardware wallet error.
#[derive(Debug)]
pub enum Error {
/// Ledger device error.
LedgerDevice(ledger::Error),
/// Trezor device error
TrezorDevice(trezor::Error),
/// USB error.
Usb(libusb::Error),
/// HID error
Hid(String),
/// Hardware wallet not found for specified key.
KeyNotFound,
}
/// This is the transaction info we need to supply to Trezor message. It's more
/// or less a duplicate of `ethcore::transaction::Transaction`, but we can't
/// import ethcore here as that would be a circular dependency.
pub struct TransactionInfo {
/// Nonce
pub nonce: U256,
/// Gas price
pub gas_price: U256,
/// Gas limit
pub gas_limit: U256,
/// Receiver
pub to: Option<Address>,
/// Value
pub value: U256,
/// Data
pub data: Vec<u8>,
/// Chain ID
pub chain_id: Option<u64>,
}
/// Hardware wallet information.
#[derive(Debug, Clone)]
pub struct WalletInfo {
/// Wallet device name.
pub name: String,
/// Wallet device manufacturer.
pub manufacturer: String,
/// Wallet device serial number.
pub serial: String,
/// Ethereum address.
pub address: Address,
}
/// Key derivation paths used on hardware wallets.
#[derive(Debug, Clone, Copy)]
pub enum KeyPath {
/// Ethereum.
Ethereum,
/// Ethereum classic.
EthereumClassic,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Error::KeyNotFound => write!(f, "Key not found for given address."),
Error::LedgerDevice(ref e) => write!(f, "{}", e),
Error::TrezorDevice(ref e) => write!(f, "{}", e),
Error::Usb(ref e) => write!(f, "{}", e),
Error::Hid(ref e) => write!(f, "{}", e),
}
}
}
impl From<ledger::Error> for Error {
fn from(err: ledger::Error) -> Self {
match err {
ledger::Error::KeyNotFound => Error::KeyNotFound,
_ => Error::LedgerDevice(err),
}
}
}
impl From<trezor::Error> for Error {
fn from(err: trezor::Error) -> Self {
match err {
trezor::Error::KeyNotFound => Error::KeyNotFound,
_ => Error::TrezorDevice(err),
}
}
}
impl From<libusb::Error> for Error {
fn from(err: libusb::Error) -> Self {
Error::Usb(err)
}
}
/// Specifies the direction of the `HardwareWallet` i.e, whether it arrived or left
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum DeviceDirection {
/// Device arrived
Arrived,
/// Device left
Left,
}
impl fmt::Display for DeviceDirection {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DeviceDirection::Arrived => write!(f, "arrived"),
DeviceDirection::Left => write!(f, "left"),
}
}
}
/// Hardware wallet management interface.
pub struct HardwareWalletManager {
exiting: Arc<AtomicBool>,
ledger: Arc<ledger::Manager>,
trezor: Arc<trezor::Manager>,
}
impl HardwareWalletManager {
/// Hardware wallet constructor
pub fn new() -> Result<Self, Error> {
let exiting = Arc::new(AtomicBool::new(false));
let hidapi = Arc::new(Mutex::new(hidapi::HidApi::new().map_err(|e| Error::Hid(e.to_string().clone()))?));
let ledger = ledger::Manager::new(hidapi.clone());
let trezor = trezor::Manager::new(hidapi.clone());
let usb_context = Arc::new(libusb::Context::new()?);
let l = ledger.clone();
let t = trezor.clone();
let exit = exiting.clone();
// Subscribe to all vendor IDs (VIDs) and product IDs (PIDs)
// This means that the `HardwareWalletManager` is responsible to validate the detected device
usb_context.register_callback(
None, None, Some(HID_USB_DEVICE_CLASS),
Box::new(EventHandler::new(
Arc::downgrade(&ledger),
Arc::downgrade(&trezor)
))
)?;
// Hardware event subscriber thread
thread::Builder::new()
.name("hw_wallet_manager".to_string())
.spawn(move || {
if let Err(e) = l.update_devices(DeviceDirection::Arrived) {
debug!(target: "hw", "Ledger couldn't connect at startup, error: {}", e);
}
if let Err(e) = t.update_devices(DeviceDirection::Arrived) {
debug!(target: "hw", "Trezor couldn't connect at startup, error: {}", e);
}
while !exit.load(atomic::Ordering::Acquire) {
if let Err(e) = usb_context.handle_events(Some(USB_EVENT_POLLING_INTERVAL)) {
debug!(target: "hw", "HardwareWalletManager event handler error: {}", e);
}
}
})
.ok();
Ok(Self {
exiting,
trezor,
ledger,
})
}
/// Select key derivation path for a chain.
/// Currently, only one hard-coded keypath is supported
/// It is managed by `ethcore/account_provider`
pub fn set_key_path(&self, key_path: KeyPath) {
self.ledger.set_key_path(key_path);
self.trezor.set_key_path(key_path);
}
/// List connected wallets. This only returns wallets that are ready to be used.
pub fn list_wallets(&self) -> Vec<WalletInfo> {
let mut wallets = Vec::new();
wallets.extend(self.ledger.list_devices());
wallets.extend(self.trezor.list_devices());
wallets
}
/// Return a list of paths to locked hardware wallets
/// This is only applicable to Trezor because Ledger only appears as
/// a device when it is unlocked
pub fn list_locked_wallets(&self) -> Result<Vec<String>, Error> {
Ok(self.trezor.list_locked_devices())
}
/// Get connected wallet info.
pub fn wallet_info(&self, address: &Address) -> Option<WalletInfo> {
if let Some(info) = self.ledger.get_wallet(address) {
Some(info)
} else {
self.trezor.get_wallet(address)
}
}
/// Sign a message with the wallet (only supported by Ledger)
pub fn sign_message(&self, address: &Address, msg: &[u8]) -> Result<Signature, Error> {
if self.ledger.get_wallet(address).is_some() {
Ok(self.ledger.sign_message(address, msg)?)
} else if self.trezor.get_wallet(address).is_some() {
Err(Error::TrezorDevice(trezor::Error::NoSigningMessage))
} else {
Err(Error::KeyNotFound)
}
}
/// Sign transaction data with wallet managing `address`.
pub fn sign_transaction(&self, address: &Address, t_info: &TransactionInfo, encoded_transaction: &[u8]) -> Result<Signature, Error> {
if self.ledger.get_wallet(address).is_some() {
Ok(self.ledger.sign_transaction(address, encoded_transaction)?)
} else if self.trezor.get_wallet(address).is_some() {
Ok(self.trezor.sign_transaction(address, t_info)?)
} else {
Err(Error::KeyNotFound)
}
}
/// Send a pin to a device at a certain path to unlock it
/// This is only applicable to Trezor because Ledger only appears as
/// a device when it is unlocked
pub fn pin_matrix_ack(&self, path: &str, pin: &str) -> Result<bool, Error> {
self.trezor.pin_matrix_ack(path, pin).map_err(Error::TrezorDevice)
}
}
impl Drop for HardwareWalletManager {
fn drop(&mut self) {
// Indicate to the USB Hotplug handler that it
// shall terminate but don't wait for it to terminate.
// If it doesn't terminate for some reason USB Hotplug events will be handled
// even if the HardwareWalletManger has been dropped
self.exiting.store(true, atomic::Ordering::Release);
}
}
/// Hardware wallet event handler
///
/// Note, that this runs to completion and race-conditions can't occur but it can
/// stop other events for being processed with an infinite loop or similar
struct EventHandler {
ledger: Weak<ledger::Manager>,
trezor: Weak<trezor::Manager>,
}
impl EventHandler {
/// Trezor event handler constructor
pub fn new(ledger: Weak<ledger::Manager>, trezor: Weak<trezor::Manager>) -> Self {
Self { ledger, trezor }
}
fn extract_device_info(device: &libusb::Device) -> Result<(u16, u16), Error> {
let desc = device.device_descriptor()?;
Ok((desc.vendor_id(), desc.product_id()))
}
}
impl libusb::Hotplug for EventHandler {
fn device_arrived(&mut self, device: libusb::Device) {
// Upgrade reference to an Arc
if let (Some(ledger), Some(trezor)) = (self.ledger.upgrade(), self.trezor.upgrade()) {
// Version ID and Product ID are available
if let Ok((vid, pid)) = Self::extract_device_info(&device) {
if trezor::is_valid_trezor(vid, pid) {
if !trezor::try_connect_polling(&trezor, &MAX_POLLING_DURATION, DeviceDirection::Arrived) {
trace!(target: "hw", "Trezor device was detected but connection failed");
}
} else if ledger::is_valid_ledger(vid, pid) {
if !ledger::try_connect_polling(&ledger, &MAX_POLLING_DURATION, DeviceDirection::Arrived) {
trace!(target: "hw", "Ledger device was detected but connection failed");
}
}
}
}
}
fn device_left(&mut self, device: libusb::Device) {
// Upgrade reference to an Arc
if let (Some(ledger), Some(trezor)) = (self.ledger.upgrade(), self.trezor.upgrade()) {
// Version ID and Product ID are available
if let Ok((vid, pid)) = Self::extract_device_info(&device) {
if trezor::is_valid_trezor(vid, pid) {
if !trezor::try_connect_polling(&trezor, &MAX_POLLING_DURATION, DeviceDirection::Left) {
trace!(target: "hw", "Trezor device was detected but disconnection failed");
}
} else if ledger::is_valid_ledger(vid, pid) {
if !ledger::try_connect_polling(&ledger, &MAX_POLLING_DURATION, DeviceDirection::Left) {
trace!(target: "hw", "Ledger device was detected but disconnection failed");
}
}
}
}
}
}
/// Helper to determine if a device is a valid HID
pub fn is_valid_hid_device(usage_page: u16, interface_number: i32) -> bool {
usage_page == HID_GLOBAL_USAGE_PAGE || interface_number == HID_USB_DEVICE_CLASS as i32
}

463
accounts/hw/src/trezor.rs Normal file
View File

@@ -0,0 +1,463 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Trezor hardware wallet module. Supports Trezor v1.
//! See <http://doc.satoshilabs.com/trezor-tech/api-protobuf.html>
//! and <https://github.com/trezor/trezor-common/blob/master/protob/protocol.md>
//! for protocol details.
use std::cmp::{min, max};
use std::sync::Arc;
use std::time::{Duration, Instant};
use std::fmt;
use ethereum_types::{U256, H256, Address};
use ethkey::Signature;
use hidapi;
use libusb;
use parking_lot::{Mutex, RwLock};
use protobuf::{self, Message, ProtobufEnum};
use super::{DeviceDirection, WalletInfo, TransactionInfo, KeyPath, Wallet, Device, is_valid_hid_device};
use trezor_sys::messages::{EthereumAddress, PinMatrixAck, MessageType, EthereumTxRequest, EthereumSignTx, EthereumGetAddress, EthereumTxAck, ButtonAck};
/// Trezor v1 vendor ID
const TREZOR_VID: u16 = 0x534c;
/// Trezor product IDs
const TREZOR_PIDS: [u16; 1] = [0x0001];
const ETH_DERIVATION_PATH: [u32; 5] = [0x8000_002C, 0x8000_003C, 0x8000_0000, 0, 0]; // m/44'/60'/0'/0/0
const ETC_DERIVATION_PATH: [u32; 5] = [0x8000_002C, 0x8000_003D, 0x8000_0000, 0, 0]; // m/44'/61'/0'/0/0
/// Hardware wallet error.
#[derive(Debug)]
pub enum Error {
/// Ethereum wallet protocol error.
Protocol(&'static str),
/// Hidapi error.
Usb(hidapi::HidError),
/// Libusb error
LibUsb(libusb::Error),
/// Device with request key is not available.
KeyNotFound,
/// Signing has been cancelled by user.
UserCancel,
/// The Message Type given in the trezor RPC call is not something we recognize
BadMessageType,
/// Trying to read from a closed device at the given path
LockedDevice(String),
/// Signing messages are not supported by Trezor
NoSigningMessage,
/// No device arrived
NoDeviceArrived,
/// No device left
NoDeviceLeft,
/// Invalid PID or VID
InvalidDevice,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Error::Protocol(ref s) => write!(f, "Trezor protocol error: {}", s),
Error::Usb(ref e) => write!(f, "USB communication error: {}", e),
Error::LibUsb(ref e) => write!(f, "LibUSB communication error: {}", e),
Error::KeyNotFound => write!(f, "Key not found"),
Error::UserCancel => write!(f, "Operation has been cancelled"),
Error::BadMessageType => write!(f, "Bad Message Type in RPC call"),
Error::LockedDevice(ref s) => write!(f, "Device is locked, needs PIN to perform operations: {}", s),
Error::NoSigningMessage=> write!(f, "Signing messages are not supported by Trezor"),
Error::NoDeviceArrived => write!(f, "No device arrived"),
Error::NoDeviceLeft => write!(f, "No device left"),
Error::InvalidDevice => write!(f, "Device with non-supported product ID or vendor ID was detected"),
}
}
}
impl From<hidapi::HidError> for Error {
fn from(err: hidapi::HidError) -> Self {
Error::Usb(err)
}
}
impl From<libusb::Error> for Error {
fn from(err: libusb::Error) -> Self {
Error::LibUsb(err)
}
}
impl From<protobuf::ProtobufError> for Error {
fn from(_: protobuf::ProtobufError) -> Self {
Error::Protocol(&"Could not read response from Trezor Device")
}
}
/// Trezor device manager
pub struct Manager {
usb: Arc<Mutex<hidapi::HidApi>>,
devices: RwLock<Vec<Device>>,
locked_devices: RwLock<Vec<String>>,
key_path: RwLock<KeyPath>,
}
/// HID Version used for the Trezor device
enum HidVersion {
V1,
V2,
}
impl Manager {
/// Create a new instance.
pub fn new(usb: Arc<Mutex<hidapi::HidApi>>) -> Arc<Self> {
Arc::new(Self {
usb,
devices: RwLock::new(Vec::new()),
locked_devices: RwLock::new(Vec::new()),
key_path: RwLock::new(KeyPath::Ethereum),
})
}
pub fn pin_matrix_ack(&self, device_path: &str, pin: &str) -> Result<bool, Error> {
let unlocked = {
let usb = self.usb.lock();
let device = self.open_path(|| usb.open_path(&device_path))?;
let t = MessageType::MessageType_PinMatrixAck;
let mut m = PinMatrixAck::new();
m.set_pin(pin.to_string());
self.send_device_message(&device, t, &m)?;
let (resp_type, _) = self.read_device_response(&device)?;
match resp_type {
// Getting an Address back means it's unlocked, this is undocumented behavior
MessageType::MessageType_EthereumAddress => Ok(true),
// Getting anything else means we didn't unlock it
_ => Ok(false),
}
};
self.update_devices(DeviceDirection::Arrived)?;
unlocked
}
fn u256_to_be_vec(&self, val: &U256) -> Vec<u8> {
let mut buf = [0_u8; 32];
val.to_big_endian(&mut buf);
buf.iter().skip_while(|x| **x == 0).cloned().collect()
}
fn signing_loop(&self, handle: &hidapi::HidDevice, chain_id: &Option<u64>, data: &[u8]) -> Result<Signature, Error> {
let (resp_type, bytes) = self.read_device_response(&handle)?;
match resp_type {
MessageType::MessageType_Cancel => Err(Error::UserCancel),
MessageType::MessageType_ButtonRequest => {
self.send_device_message(handle, MessageType::MessageType_ButtonAck, &ButtonAck::new())?;
// Signing loop goes back to the top and reading blocks
// for up to 5 minutes waiting for response from the device
// if the user doesn't click any button within 5 minutes you
// get a signing error and the device sort of locks up on the signing screen
self.signing_loop(handle, chain_id, data)
}
MessageType::MessageType_EthereumTxRequest => {
let resp: EthereumTxRequest = protobuf::core::parse_from_bytes(&bytes)?;
if resp.has_data_length() {
let mut msg = EthereumTxAck::new();
let len = resp.get_data_length() as usize;
msg.set_data_chunk(data[..len].to_vec());
self.send_device_message(handle, MessageType::MessageType_EthereumTxAck, &msg)?;
self.signing_loop(handle, chain_id, &data[len..])
} else {
let v = resp.get_signature_v();
let r = H256::from_slice(resp.get_signature_r());
let s = H256::from_slice(resp.get_signature_s());
if let Some(c_id) = *chain_id {
// If there is a chain_id supplied, Trezor will return a v
// part of the signature that is already adjusted for EIP-155,
// so v' = v + 2 * chain_id + 35, but code further down the
// pipeline will already do this transformation, so remove it here
let adjustment = 35 + 2 * c_id as u32;
Ok(Signature::from_rsv(&r, &s, (max(v, adjustment) - adjustment) as u8))
} else {
// If there isn't a chain_id, v will be returned as v + 27
let adjusted_v = if v < 27 { v } else { v - 27 };
Ok(Signature::from_rsv(&r, &s, adjusted_v as u8))
}
}
}
MessageType::MessageType_Failure => Err(Error::Protocol("Last message sent to Trezor failed")),
_ => Err(Error::Protocol("Unexpected response from Trezor device.")),
}
}
fn send_device_message(&self, device: &hidapi::HidDevice, msg_type: MessageType, msg: &Message) -> Result<usize, Error> {
let msg_id = msg_type as u16;
let mut message = msg.write_to_bytes()?;
let msg_size = message.len();
let mut data = Vec::new();
let hid_version = self.probe_hid_version(device)?;
// Magic constants
data.push(b'#');
data.push(b'#');
// Convert msg_id to BE and split into bytes
data.push(((msg_id >> 8) & 0xFF) as u8);
data.push((msg_id & 0xFF) as u8);
// Convert msg_size to BE and split into bytes
data.push(((msg_size >> 24) & 0xFF) as u8);
data.push(((msg_size >> 16) & 0xFF) as u8);
data.push(((msg_size >> 8) & 0xFF) as u8);
data.push((msg_size & 0xFF) as u8);
data.append(&mut message);
while data.len() % 63 > 0 {
data.push(0);
}
let mut total_written = 0;
for chunk in data.chunks(63) {
let mut padded_chunk = match hid_version {
HidVersion::V1 => vec![b'?'],
HidVersion::V2 => vec![0, b'?'],
};
padded_chunk.extend_from_slice(&chunk);
total_written += device.write(&padded_chunk)?;
}
Ok(total_written)
}
fn probe_hid_version(&self, device: &hidapi::HidDevice) -> Result<HidVersion, Error> {
let mut buf2 = [0xFF_u8; 65];
buf2[0] = 0;
buf2[1] = 63;
let mut buf1 = [0xFF_u8; 64];
buf1[0] = 63;
if device.write(&buf2)? == 65 {
Ok(HidVersion::V2)
} else if device.write(&buf1)? == 64 {
Ok(HidVersion::V1)
} else {
Err(Error::Usb("Unable to determine HID Version"))
}
}
fn read_device_response(&self, device: &hidapi::HidDevice) -> Result<(MessageType, Vec<u8>), Error> {
let protocol_err = Error::Protocol(&"Unexpected wire response from Trezor Device");
let mut buf = vec![0; 64];
let first_chunk = device.read_timeout(&mut buf, 300_000)?;
if first_chunk < 9 || buf[0] != b'?' || buf[1] != b'#' || buf[2] != b'#' {
return Err(protocol_err);
}
let msg_type = MessageType::from_i32(((buf[3] as i32 & 0xFF) << 8) + (buf[4] as i32 & 0xFF)).ok_or(protocol_err)?;
let msg_size = ((buf[5] as u32 & 0xFF) << 24) + ((buf[6] as u32 & 0xFF) << 16) + ((buf[7] as u32 & 0xFF) << 8) + (buf[8] as u32 & 0xFF);
let mut data = Vec::new();
data.extend_from_slice(&buf[9..]);
while data.len() < (msg_size as usize) {
device.read_timeout(&mut buf, 10_000)?;
data.extend_from_slice(&buf[1..]);
}
Ok((msg_type, data[..msg_size as usize].to_vec()))
}
}
impl<'a> Wallet<'a> for Manager {
type Error = Error;
type Transaction = &'a TransactionInfo;
fn sign_transaction(&self, address: &Address, t_info: Self::Transaction) ->
Result<Signature, Error> {
let usb = self.usb.lock();
let devices = self.devices.read();
let device = devices.iter().find(|d| &d.info.address == address).ok_or(Error::KeyNotFound)?;
let handle = self.open_path(|| usb.open_path(&device.path))?;
let msg_type = MessageType::MessageType_EthereumSignTx;
let mut message = EthereumSignTx::new();
match *self.key_path.read() {
KeyPath::Ethereum => message.set_address_n(ETH_DERIVATION_PATH.to_vec()),
KeyPath::EthereumClassic => message.set_address_n(ETC_DERIVATION_PATH.to_vec()),
}
message.set_nonce(self.u256_to_be_vec(&t_info.nonce));
message.set_gas_limit(self.u256_to_be_vec(&t_info.gas_limit));
message.set_gas_price(self.u256_to_be_vec(&t_info.gas_price));
message.set_value(self.u256_to_be_vec(&t_info.value));
if let Some(addr) = t_info.to {
message.set_to(addr.to_vec())
}
let first_chunk_length = min(t_info.data.len(), 1024);
let chunk = &t_info.data[0..first_chunk_length];
message.set_data_initial_chunk(chunk.to_vec());
message.set_data_length(t_info.data.len() as u32);
if let Some(c_id) = t_info.chain_id {
message.set_chain_id(c_id as u32);
}
self.send_device_message(&handle, msg_type, &message)?;
self.signing_loop(&handle, &t_info.chain_id, &t_info.data[first_chunk_length..])
}
fn set_key_path(&self, key_path: KeyPath) {
*self.key_path.write() = key_path;
}
fn update_devices(&self, device_direction: DeviceDirection) -> Result<usize, Error> {
let mut usb = self.usb.lock();
usb.refresh_devices();
let devices = usb.devices();
let num_prev_devices = self.devices.read().len();
let detected_devices = devices.iter()
.filter(|&d| is_valid_trezor(d.vendor_id, d.product_id) &&
is_valid_hid_device(d.usage_page, d.interface_number)
)
.fold(Vec::new(), |mut v, d| {
match self.read_device(&usb, &d) {
Ok(info) => {
trace!(target: "hw", "Found device: {:?}", info);
v.push(info);
}
Err(e) => trace!(target: "hw", "Error reading device info: {}", e),
};
v
});
let num_curr_devices = detected_devices.len();
*self.devices.write() = detected_devices;
match device_direction {
DeviceDirection::Arrived => {
if num_curr_devices > num_prev_devices {
Ok(num_curr_devices - num_prev_devices)
} else {
Err(Error::NoDeviceArrived)
}
}
DeviceDirection::Left => {
if num_prev_devices > num_curr_devices {
Ok(num_prev_devices - num_curr_devices)
} else {
Err(Error::NoDeviceLeft)
}
}
}
}
fn read_device(&self, usb: &hidapi::HidApi, dev_info: &hidapi::HidDeviceInfo) -> Result<Device, Error> {
let handle = self.open_path(|| usb.open_path(&dev_info.path))?;
let manufacturer = dev_info.manufacturer_string.clone().unwrap_or_else(|| "Unknown".to_owned());
let name = dev_info.product_string.clone().unwrap_or_else(|| "Unknown".to_owned());
let serial = dev_info.serial_number.clone().unwrap_or_else(|| "Unknown".to_owned());
match self.get_address(&handle) {
Ok(Some(addr)) => {
Ok(Device {
path: dev_info.path.clone(),
info: WalletInfo {
name,
manufacturer,
serial,
address: addr,
},
})
}
Ok(None) => Err(Error::LockedDevice(dev_info.path.clone())),
Err(e) => Err(e),
}
}
fn list_devices(&self) -> Vec<WalletInfo> {
self.devices.read().iter().map(|d| d.info.clone()).collect()
}
fn list_locked_devices(&self) -> Vec<String> {
(*self.locked_devices.read()).clone()
}
fn get_wallet(&self, address: &Address) -> Option<WalletInfo> {
self.devices.read().iter().find(|d| &d.info.address == address).map(|d| d.info.clone())
}
fn get_address(&self, device: &hidapi::HidDevice) -> Result<Option<Address>, Error> {
let typ = MessageType::MessageType_EthereumGetAddress;
let mut message = EthereumGetAddress::new();
match *self.key_path.read() {
KeyPath::Ethereum => message.set_address_n(ETH_DERIVATION_PATH.to_vec()),
KeyPath::EthereumClassic => message.set_address_n(ETC_DERIVATION_PATH.to_vec()),
}
message.set_show_display(false);
self.send_device_message(&device, typ, &message)?;
let (resp_type, bytes) = self.read_device_response(&device)?;
match resp_type {
MessageType::MessageType_EthereumAddress => {
let response: EthereumAddress = protobuf::core::parse_from_bytes(&bytes)?;
Ok(Some(From::from(response.get_address())))
}
_ => Ok(None),
}
}
fn open_path<R, F>(&self, f: F) -> Result<R, Error>
where F: Fn() -> Result<R, &'static str>
{
f().map_err(Into::into)
}
}
/// Poll the device in maximum `max_polling_duration` if it doesn't succeed
pub fn try_connect_polling(trezor: &Manager, duration: &Duration, dir: DeviceDirection) -> bool {
let start_time = Instant::now();
while start_time.elapsed() <= *duration {
if let Ok(num_devices) = trezor.update_devices(dir) {
trace!(target: "hw", "{} Trezor devices {}", num_devices, dir);
return true
}
}
false
}
/// Check if the detected device is a Trezor device by checking both the product ID and the vendor ID
pub fn is_valid_trezor(vid: u16, pid: u16) -> bool {
vid == TREZOR_VID && TREZOR_PIDS.contains(&pid)
}
#[test]
#[ignore]
/// This test can't be run without an actual trezor device connected
/// (and unlocked) attached to the machine that's running the test
fn test_signature() {
use ethereum_types::Address;
use MAX_POLLING_DURATION;
use super::HardwareWalletManager;
let manager = HardwareWalletManager::new().unwrap();
assert_eq!(try_connect_polling(&manager.trezor, &MAX_POLLING_DURATION, DeviceDirection::Arrived), true);
let addr: Address = manager.list_wallets()
.iter()
.filter(|d| d.name == "TREZOR".to_string() && d.manufacturer == "SatoshiLabs".to_string())
.nth(0)
.map(|d| d.address)
.unwrap();
let t_info = TransactionInfo {
nonce: U256::from(1),
gas_price: U256::from(100),
gas_limit: U256::from(21_000),
to: Some(Address::from(1337)),
chain_id: Some(1),
value: U256::from(1_000_000),
data: (&[1u8; 3000]).to_vec(),
};
let signature = manager.trezor.sign_transaction(&addr, &t_info);
assert!(signature.is_ok());
}

View File

@@ -1,73 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Account Metadata
use std::{
collections::HashMap,
time::Instant,
};
use ethkey::{Address, Password};
use serde_derive::{Serialize, Deserialize};
use serde_json;
/// Type of unlock.
#[derive(Clone, PartialEq)]
pub enum Unlock {
/// If account is unlocked temporarily, it should be locked after first usage.
OneTime,
/// Account unlocked permanently can always sign message.
/// Use with caution.
Perm,
/// Account unlocked with a timeout
Timed(Instant),
}
/// Data associated with account.
#[derive(Clone)]
pub struct AccountData {
pub unlock: Unlock,
pub password: Password,
}
/// Collected account metadata
#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct AccountMeta {
/// The name of the account.
pub name: String,
/// The rest of the metadata of the account.
pub meta: String,
/// The 128-bit Uuid of the account, if it has one (brain-wallets don't).
pub uuid: Option<String>,
}
impl AccountMeta {
/// Read a hash map of Address -> AccountMeta
pub fn read<R>(reader: R) -> Result<HashMap<Address, Self>, serde_json::Error> where
R: ::std::io::Read,
{
serde_json::from_reader(reader)
}
/// Write a hash map of Address -> AccountMeta
pub fn write<W>(m: &HashMap<Address, Self>, writer: &mut W) -> Result<(), serde_json::Error> where
W: ::std::io::Write,
{
serde_json::to_writer(writer, m)
}
}

View File

@@ -1,46 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::fmt;
use ethstore::{Error as SSError};
/// Signing error
#[derive(Debug)]
pub enum SignError {
/// Account is not unlocked
NotUnlocked,
/// Account does not exist.
NotFound,
/// Low-level error from store
SStore(SSError),
}
impl fmt::Display for SignError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
SignError::NotUnlocked => write!(f, "Account is locked"),
SignError::NotFound => write!(f, "Account does not exist"),
SignError::SStore(ref e) => write!(f, "{}", e),
}
}
}
impl From<SSError> for SignError {
fn from(e: SSError) -> Self {
SignError::SStore(e)
}
}

View File

@@ -1,5 +1,4 @@
[package]
description = "Parity Ethereum Chain Specification"
name = "chainspec"
version = "0.1.0"
authors = ["Marek Kotewicz <marek@parity.io>"]

View File

@@ -1,13 +1,12 @@
[package]
description = "Parity Ethereum CLI Signer Tool"
authors = ["Parity <admin@parity.io>"]
description = "Parity Cli Tool"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "cli-signer"
version = "1.4.0"
authors = ["Parity <admin@parity.io>"]
[dependencies]
ethereum-types = "0.6.0"
futures = "0.1"
rpassword = "1.0"
parity-rpc = { path = "../rpc" }

View File

@@ -1,13 +1,12 @@
[package]
description = "Parity Ethereum RPC Client"
authors = ["Parity <admin@parity.io>"]
description = "Parity Rpc Client"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "parity-rpc-client"
version = "1.4.0"
authors = ["Parity <admin@parity.io>"]
[dependencies]
ethereum-types = "0.6.0"
futures = "0.1"
log = "0.4"
serde = "1.0"
@@ -15,7 +14,7 @@ serde_json = "1.0"
url = "1.2.0"
matches = "0.1"
parking_lot = "0.7"
jsonrpc-core = "12.0.0"
jsonrpc-ws-server = "12.0.0"
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" }
jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" }
parity-rpc = { path = "../../rpc" }
keccak-hash = "0.2.0"
keccak-hash = "0.1"

View File

@@ -17,7 +17,6 @@
pub mod client;
pub mod signer_client;
extern crate ethereum_types;
extern crate futures;
extern crate jsonrpc_core;
extern crate jsonrpc_ws_server as ws;

View File

@@ -15,8 +15,7 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use client::{Rpc, RpcError};
use ethereum_types::U256;
use rpc::signer::{ConfirmationRequest, TransactionModification, TransactionCondition};
use rpc::signer::{ConfirmationRequest, TransactionModification, U256, TransactionCondition};
use serde;
use serde_json::{Value as JsonValue, to_value};
use std::path::PathBuf;

View File

@@ -14,15 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
extern crate ethereum_types;
extern crate futures;
extern crate rpassword;
extern crate parity_rpc as rpc;
extern crate parity_rpc_client as client;
use ethereum_types::U256;
use rpc::signer::ConfirmationRequest;
use rpc::signer::{U256, ConfirmationRequest};
use client::signer_client::SignerRpc;
use std::io::{Write, BufRead, BufReader, stdout, stdin};
use std::path::PathBuf;

View File

@@ -1,4 +1,4 @@
Note: Parity Ethereum 2.0 reached End-of-Life on 2018-11-15 (EOL).
Note: Parity 2.0 reached End-of-Life on 2018-11-15 (EOL).
## Parity-Ethereum [v2.0.9](https://github.com/paritytech/parity-ethereum/releases/tag/v2.0.9) (2018-10-29)

View File

@@ -1,31 +1,13 @@
Note: Parity Ethereum 2.1 reached End-of-Life on 2019-01-16 (EOL).
## Parity-Ethereum [v2.1.11](https://github.com/paritytech/parity-ethereum/releases/tag/v2.1.11) (2019-01-09)
Parity-Ethereum 2.1.11-stable is a bugfix release that improves performance and stability.
The full list of included changes:
- Stable backports v2.1.11 ([#10112](https://github.com/paritytech/parity-ethereum/pull/10112))
- Version: bump stable to v2.1.11
- HF in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077))
- Add --locked when running cargo ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107))
- Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123))
- Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128))
- Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134))
- Version: mark upgrade critical on kovan
## Parity-Ethereum [v2.1.10](https://github.com/paritytech/parity-ethereum/releases/tag/v2.1.10) (2018-12-14)
Parity-Ethereum 2.1.10-stable is an important release that introduces Constantinople fork at block 7080000 on Mainnet.
This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you.
Parity-Ethereum 2.1.10-stable is an important release that introduces Constantinople fork at block 7080000 on Mainnet.
This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you.
If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release`strict_empty_steps_transition` **is enabled by default at block 0** for any chain with `empty_steps`.
If your network uses `empty_steps` you **must**:
- plan a hard fork and change `strict_empty_steps_transition` to the desire fork block
- update the clients of the whole network to 2.2.5-beta / 2.1.10-stable.
If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it.
The full list of included changes:
The full list of included changes:
- Backports for stable 2.1.10 ([#10046](https://github.com/paritytech/parity-ethereum/pull/10046))
- Bump stable to 2.1.10 ([#10046](https://github.com/paritytech/parity-ethereum/pull/10046))

View File

@@ -1,392 +0,0 @@
Note: Parity Ethereum 2.2 reached End-of-Life on 2019-02-25 (EOL).
## Parity-Ethereum [v2.2.11](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.11) (2019-02-21)
Parity-Ethereum 2.2.11-stable is a maintenance release that fixes snap and docker installations.
The full list of included changes:
- Stable: snap: release untagged versions from branches to the candidate ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) ([#10372](https://github.com/paritytech/parity-ethereum/pull/10372))
- Snap: release untagged versions from branches to the candidate snap channel ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357))
- Snap: add the removable-media plug ([#10377](https://github.com/paritytech/parity-ethereum/pull/10377))
- Exchanged old(azure) bootnodes with new(ovh) ones ([#10309](https://github.com/paritytech/parity-ethereum/pull/10309))
- Stable Backports ([#10353](https://github.com/paritytech/parity-ethereum/pull/10353))
- Version: bump stable to 2.2.11
- Snap: prefix version and populate candidate channel ([#10343](https://github.com/paritytech/parity-ethereum/pull/10343))
- Snap: populate candidate releases with beta snaps to avoid stale channel
- Snap: prefix version with v*
- No volumes are needed, just run -v volume:/path/in/the/container ([#10345](https://github.com/paritytech/parity-ethereum/pull/10345))
## Parity-Ethereum [v2.2.10](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.10) (2019-02-13)
Parity-Ethereum 2.2.10-stable is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints.
- https://www.parity.io/new-parity-ethereum-update-fixes-several-rpc-vulnerabilities/
The full list of included changes:
- Additional error for invalid gas ([#10327](https://github.com/paritytech/parity-ethereum/pull/10327)) ([#10329](https://github.com/paritytech/parity-ethereum/pull/10329))
- Backports for Stable 2.2.10 ([#10332](https://github.com/paritytech/parity-ethereum/pull/10332))
- fix(docker-aarch64) : cross-compile config ([#9798](https://github.com/paritytech/parity-ethereum/pull/9798))
- import rpc transactions sequentially ([#10051](https://github.com/paritytech/parity-ethereum/pull/10051))
- fix(docker): fix not receives SIGINT ([#10059](https://github.com/paritytech/parity-ethereum/pull/10059))
- snap: official image / test ([#10168](https://github.com/paritytech/parity-ethereum/pull/10168))
- perform stripping during build ([#10208](https://github.com/paritytech/parity-ethereum/pull/10208))
- Additional tests for uint/hash/bytes deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279))
- Don't run the CPP example on CI ([#10285](https://github.com/paritytech/parity-ethereum/pull/10285))
- CI optimizations ([#10297](https://github.com/paritytech/parity-ethereum/pull/10297))
- fix publish job ([#10317](https://github.com/paritytech/parity-ethereum/pull/10317))
- Add Statetest support for Constantinople Fix ([#10323](https://github.com/paritytech/parity-ethereum/pull/10323))
- Add helper for Timestamp overflows ([#10330](https://github.com/paritytech/parity-ethereum/pull/10330))
- Don't add discovery initiators to the node table ([#10305](https://github.com/paritytech/parity-ethereum/pull/10305))
- change docker image based on debian instead of ubuntu due to the chan ([#10336](https://github.com/paritytech/parity-ethereum/pull/10336))
- role back docker build image and docker deploy image to ubuntu:xenial based ([#10338](https://github.com/paritytech/parity-ethereum/pull/10338))
## Parity-Ethereum [v2.2.9](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.9) (2019-02-03)
Parity-Ethereum 2.2.9-stable is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints.
- https://www.parity.io/security-alert-parity-ethereum-03-02/
The full list of included changes:
- Additional tests for uint deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) ([#10281](https://github.com/paritytech/parity-ethereum/pull/10281))
- Version: bump stable to 2.2.9 ([#10282](https://github.com/paritytech/parity-ethereum/pull/10282))
## Parity-Ethereum [v2.2.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.8) (2019-02-01)
Parity-Ethereum 2.2.8-stable is a consensus-relevant release that enables _St. Petersfork_ on:
- Ethereum Block `7280000` (along with Constantinople)
- Kovan Block `10255201`
- Ropsten Block `4939394`
- POA Sokol Block `7026400`
In addition to this, Constantinople is cancelled for the POA Core network. Upgrading is mandatory for clients on any of these chains.
The full list of included changes:
- Backports for stable 2.2.8 ([#10224](https://github.com/paritytech/parity-ethereum/pull/10224))
- Update for Android cross-compilation. ([#10180](https://github.com/paritytech/parity-ethereum/pull/10180))
- Cancel Constantinople HF on POA Core ([#10198](https://github.com/paritytech/parity-ethereum/pull/10198))
- Add EIP-1283 disable transition ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214))
- Enable St-Peters-Fork ("Constantinople Fix") ([#10223](https://github.com/paritytech/parity-ethereum/pull/10223))
- Stable: Macos heapsize force jemalloc ([#10234](https://github.com/paritytech/parity-ethereum/pull/10234)) ([#10258](https://github.com/paritytech/parity-ethereum/pull/10258))
## Parity-Ethereum [v2.2.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.7) (2019-01-15)
Parity-Ethereum 2.2.7-stable is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks.
- **Consensus** - Ethereum Network: Pull Constantinople protocol upgrade on Ethereum ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189))
- Read more: [Security Alert: Ethereum Constantinople Postponement](https://blog.ethereum.org/2019/01/15/security-alert-ethereum-constantinople-postponement/)
- **Networking** - All networks: Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167))
- **Wasm** - Kovan Network: Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134))
_Note:_ This release marks Parity 2.2 as _stable_. All versions of Parity 2.1 now reached _end of life_.
The full list of included changes:
- Backports for stable 2.2.7 ([#10163](https://github.com/paritytech/parity-ethereum/pull/10163))
- Version: bump stable to 2.2.7
- Version: mark 2.2 track stable
- Version: mark update critical on all networks
- Handle the case for contract creation on an empty but exist account with storage items ([#10065](https://github.com/paritytech/parity-ethereum/pull/10065))
- Fix _cannot recursively call into `Core`_ issue ([#10144](https://github.com/paritytech/parity-ethereum/pull/10144))
- Snap: fix path in script ([#10157](https://github.com/paritytech/parity-ethereum/pull/10157))
- Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167))
- Version: bump fork blocks for kovan and foundation, mark releases non critical
- Pull constantinople on ethereum network ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189))
## Parity-Ethereum [v2.2.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.6) (2019-01-10)
Parity-Ethereum 2.2.6-beta is a bugfix release that improves performance and stability.
The full list of included changes:
- Beta backports v2.2.6 ([#10113](https://github.com/paritytech/parity-ethereum/pull/10113))
- Version: bump beta to v2.2.6
- Fill transaction hash on ethGetLog of light client. ([#9938](https://github.com/paritytech/parity-ethereum/pull/9938))
- Fix pubsub new_blocks notifications to include all blocks ([#9987](https://github.com/paritytech/parity-ethereum/pull/9987))
- Finality: dont require chain head to be in the chain ([#10054](https://github.com/paritytech/parity-ethereum/pull/10054))
- Handle the case for contract creation on an empty but exist account with storage items ([#10065](https://github.com/paritytech/parity-ethereum/pull/10065))
- Autogen docs for the "Configuring Parity Ethereum" wiki page. ([#10067](https://github.com/paritytech/parity-ethereum/pull/10067))
- HF in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077))
- Add --locked when running cargo ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107))
- Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123))
- Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128))
- Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134))
- Make sure parent block is not in importing queue when importing ancient blocks ([#10138](https://github.com/paritytech/parity-ethereum/pull/10138))
- CI: re-enable snap publishing ([#10142](https://github.com/paritytech/parity-ethereum/pull/10142))
- HF in POA Core (2019-01-18) - Constantinople ([#10155](https://github.com/paritytech/parity-ethereum/pull/10155))
- Version: mark upgrade critical on kovan
## Parity-Ethereum [v2.2.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.5) (2018-12-14)
Parity-Ethereum 2.2.5-beta is an important release that introduces Constantinople fork at block 7080000 on Mainnet.
This release also contains a fix for chains using AuRa + EmptySteps. Read carefully if this applies to you.
If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release`strict_empty_steps_transition` **is enabled by default at block 0** for any chain with `empty_steps`.
If your network uses `empty_steps` you **must**:
- plan a hard fork and change `strict_empty_steps_transition` to the desire fork block
- update the clients of the whole network to 2.2.5-beta / 2.1.10-stable.
If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it.
The full list of included changes:
- Backports for beta 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047))
- Bump beta to 2.2.5 ([#10047](https://github.com/paritytech/parity-ethereum/pull/10047))
- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939))
- Prevent sending empty step message twice
- Prevent sending empty step and then block in the same step
- Don't accept double empty steps
- Do basic validation of self-sealed blocks
- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041))
- Enables strict verification of empty steps - there can be no duplicates and empty steps should be ordered inside the seal.
- Note that authorities won't produce invalid seals after [#9939](https://github.com/paritytech/parity-ethereum/pull/9939), this PR just adds verification to the seal to prevent forging incorrect blocks and potentially causing consensus issues.
- This features is enabled by default so any AuRa + EmptySteps chain should set strict_empty_steps_transition fork block number in their spec and upgrade to v2.2.5-beta or v2.1.10-stable.
- ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/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](https://github.com/paritytech/parity-ethereum/pull/10024))
- Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019))
## Parity-Ethereum [v2.2.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.2) (2018-11-29)
Parity-Ethereum 2.2.2-beta is an exciting release. Among others, it improves sync performance, peering stability, block propagation, and transaction propagation times. Also, a warp-sync no longer removes existing blocks from the database, but rather reuses locally available information to decrease sync times and reduces required bandwidth.
Before upgrading to 2.2.2, please also verify the validity of your chain specs. Parity Ethereum now denies unknown fields in the specification. To do this, use the chainspec tool:
```
cargo build --release -p chainspec
./target/release/chainspec /path/to/spec.json
```
Last but not least, JSONRPC APIs which are not yet accepted as an EIP in the `eth`, `personal`, or `web3` namespace, are now considere experimental as their final specification might change in future. These APIs have to be manually enabled by explicitly running `--jsonrpc-experimental`.
The full list of included changes:
- Backports For beta 2.2.2 ([#9976](https://github.com/paritytech/parity-ethereum/pull/9976))
- Version: bump beta to 2.2.2
- Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928))
- Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643))
- Rename db_restore => client
- First step: make it compile!
- Second step: working implementation!
- Refactoring
- Fix tests
- Migrate ancient blocks interacting backward
- Early return in block migration if snapshot is aborted
- Remove RwLock getter (PR Grumble I)
- Remove dependency on `Client`: only used Traits
- Add test for recovering aborted snapshot recovery
- Add test for migrating old blocks
- Release RwLock earlier
- Revert Cargo.lock
- Update _update ancient block_ logic: set local in `commit`
- Update typo in ethcore/src/snapshot/service.rs
- Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925))
- Pip Table Cost relative to average peers instead of max peers
- Add tracing in PIP new_cost_table
- Update stat peer_count
- Use number of leeching peers for Light serve costs
- Fix test::light_params_load_share_depends_on_max_peers (wrong type)
- Remove (now) useless test
- Remove `load_share` from LightParams.Config
- Add LEECHER_COUNT_FACTOR
- Pr Grumble: u64 to u32 for f64 casting
- Prevent u32 overflow for avg_peer_count
- Add tests for LightSync::Statistics
- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939))
- Don't send empty step twice or empty step then block.
- Perform basic validation of locally sealed blocks.
- Don't include empty step twice.
- Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946))
- Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952))
- Update informant:
- Decimal in Mgas/s
- Print every 5s (not randomly between 5s and 10s)
- Fix dead-lock in `blockchain.rs`
- Update locks ordering
- Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932))
- Add `is_idle` to LightSync to check importing status
- Use SyncStateWrapper to make sure is_idle gets updates
- Update is_major_import to use verified queue size as well
- Add comment for `is_idle`
- Add Debug to `SyncStateWrapper`
- `fn get` -> `fn into_inner`
- Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970))
- Ci: rearrange pipeline by logic
- Ci: rename docs script
- Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971))
- Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972))
- Add deny_unknown_fields to chainspec
- Add tests and fix existing one
- Remove serde_ignored dependency for chainspec
- Fix rpc test eth chain spec
- Fix starting_nonce_test spec
- Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954))
- Refactor sync to add priority tasks.
- Send priority tasks notifications.
- Propagate blocks, optimize transactions.
- Implement transaction propagation. Use sync_channel.
- Tone down info.
- Prevent deadlock by not waiting forever for sync lock.
- Fix lock order.
- Don't use sync_channel to prevent deadlocks.
- Fix tests.
- Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967))
- Don't sync all peers after each response
- Update formating
- Fix tests: add `continue_sync` to `Sync_step`
- Update ethcore/sync/src/chain/mod.rs
- Fix rpc middlewares
- Fix Cargo.lock
- Json: resolve merge in spec
- Rpc: fix starting_nonce_test
- Ci: allow nightl job to fail
## Parity-Ethereum [v2.2.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.1) (2018-11-15)
Parity-Ethereum 2.2.1-beta is the first v2.2 release, and might introduce features that break previous work flows, among others:
- Prevent zero network ID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763)) and drop support for Olympic testnet ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801)): The Olympic test net is dead for years and never used a chain ID but network ID zero. Parity Ethereum is now preventing the network ID to be zero, thus Olympic support is dropped. Make sure to chose positive non-zero network IDs in future.
- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239)): adds a CLI argument `--snapshot-threads` which specifies the number of threads. This helps improving the performance of full nodes that wish to provide warp-snapshots for the network. The gain in performance comes with a slight drawback in increased snapshot size.
- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439)): Parity Ethereum imports blocks in rounds. If at the end of any round, the queue is not empty, we consider it to be _importing_ and won't notify pubsub. On large re-orgs (10+ blocks), this is possible. The default `max_round_blocks_to_import` is increased to 12 and configurable via the `--max-round-blocks-to-import` CLI flag. With unstable network conditions, it is advised to increase the number. This shouldn't have any noticeable performance impact unless the number is set to really large.
- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564)): the default values for gas floor target are `8_000_000` and gas cap `10_000_000`, similar to Geth 1.8.15+.
- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725)): we now produce portable binaries, but it may incur some performance degradation. For ultimate performance it's now better to compile Parity Ethereum from source with `PORTABLE=OFF` environment variable.
- RPC: `parity_allTransactionHashes` ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745)): Get all pending transactions from the queue with the high performant `parity_allTransactionHashes` RPC method.
- Support `eth_chainId` RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783)): implements EIP-695 to get the chainID via RPC.
- AuRa: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692)): The AuRa engine was updated to emit ancestry actions to finalize blocks. The full client stores block finality in the database, the engine builds finality from an ancestry of `ExtendedHeader`; `is_epoch_end` was updated to take a vec of recently finalized headers; `is_epoch_end_light` was added which maintains the previous interface and is used by the light client since the client itself doesn't track finality.
The full list of included changes:
- Backport to parity 2.2.1 beta ([#9905](https://github.com/paritytech/parity-ethereum/pull/9905))
- Bump version to 2.2.1
- Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885))
- Fix Parity not closing on Ctrl-C ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886))
- Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873))
- Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854))
- Add hardcoded headers for light client ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907))
- Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743))
- Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876))
- Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906))
- Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824))
- Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631))
- Eip-191 implementation ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701))
- Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918))
- Fix performance issue importing Kovan blocks ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914))
- Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855))
- Backports to parity beta 2.2.0 ([#9820](https://github.com/paritytech/parity-ethereum/pull/9820))
- Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788))
- Implement NoProof for json tests and update tests reference ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814))
- Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841))
- Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828))
- Rpc: parity_allTransactionHashes ([#9745](https://github.com/paritytech/parity-ethereum/pull/9745))
- Revert "prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763))" ([#9815](https://github.com/paritytech/parity-ethereum/pull/9815))
- Allow zero chain id in EIP155 signing process ([#9792](https://github.com/paritytech/parity-ethereum/pull/9792))
- Add readiness check for docker container ([#9804](https://github.com/paritytech/parity-ethereum/pull/9804))
- Insert dev account before unlocking ([#9813](https://github.com/paritytech/parity-ethereum/pull/9813))
- Removed "rustup" & added new runner tag ([#9731](https://github.com/paritytech/parity-ethereum/pull/9731))
- Expose config max-round-blocks-to-import ([#9439](https://github.com/paritytech/parity-ethereum/pull/9439))
- Aura: finalize blocks ([#9692](https://github.com/paritytech/parity-ethereum/pull/9692))
- Sync: retry different peer after empty subchain heads response ([#9753](https://github.com/paritytech/parity-ethereum/pull/9753))
- Fix(light-rpc/parity) : Remove unused client ([#9802](https://github.com/paritytech/parity-ethereum/pull/9802))
- Drops support for olympic testnet, closes [#9800](https://github.com/paritytech/parity-ethereum/issues/9800) ([#9801](https://github.com/paritytech/parity-ethereum/pull/9801))
- Replace `tokio_core` with `tokio` (`ring` -> 0.13) ([#9657](https://github.com/paritytech/parity-ethereum/pull/9657))
- Support eth_chainId RPC method ([#9783](https://github.com/paritytech/parity-ethereum/pull/9783))
- Ethcore: bump ropsten forkblock checkpoint ([#9775](https://github.com/paritytech/parity-ethereum/pull/9775))
- Docs: changelogs for 2.0.8 and 2.1.3 ([#9758](https://github.com/paritytech/parity-ethereum/pull/9758))
- Prevent zero networkID ([#9763](https://github.com/paritytech/parity-ethereum/pull/9763))
- Skip seal fields count check when --no-seal-check is used ([#9757](https://github.com/paritytech/parity-ethereum/pull/9757))
- Aura: fix panic on extra_info with unsealed block ([#9755](https://github.com/paritytech/parity-ethereum/pull/9755))
- Docs: update changelogs ([#9742](https://github.com/paritytech/parity-ethereum/pull/9742))
- Removed extra assert in generation_session_is_removed_when_succeeded ([#9738](https://github.com/paritytech/parity-ethereum/pull/9738))
- Make checkpoint_storage_at use plain loop instead of recursion ([#9734](https://github.com/paritytech/parity-ethereum/pull/9734))
- Use signed 256-bit integer for sstore gas refund substate ([#9746](https://github.com/paritytech/parity-ethereum/pull/9746))
- Heads ref not present for branches beta and stable ([#9741](https://github.com/paritytech/parity-ethereum/pull/9741))
- Add Callisto support ([#9534](https://github.com/paritytech/parity-ethereum/pull/9534))
- Add --force to cargo audit install script ([#9735](https://github.com/paritytech/parity-ethereum/pull/9735))
- Remove unused expired value from Handshake ([#9732](https://github.com/paritytech/parity-ethereum/pull/9732))
- Add hardcoded headers ([#9730](https://github.com/paritytech/parity-ethereum/pull/9730))
- Produce portable binaries ([#9725](https://github.com/paritytech/parity-ethereum/pull/9725))
- Gitlab ci: releasable_branches: change variables condition to schedule ([#9729](https://github.com/paritytech/parity-ethereum/pull/9729))
- Update a few parity-common dependencies ([#9663](https://github.com/paritytech/parity-ethereum/pull/9663))
- Hf in POA Core (2018-10-22) ([#9724](https://github.com/paritytech/parity-ethereum/pull/9724))
- Schedule nightly builds ([#9717](https://github.com/paritytech/parity-ethereum/pull/9717))
- Fix ancient blocks sync ([#9531](https://github.com/paritytech/parity-ethereum/pull/9531))
- Ci: Skip docs job for nightly ([#9693](https://github.com/paritytech/parity-ethereum/pull/9693))
- Fix (light/provider) : Make `read_only executions` read-only ([#9591](https://github.com/paritytech/parity-ethereum/pull/9591))
- Ethcore: fix detection of major import ([#9552](https://github.com/paritytech/parity-ethereum/pull/9552))
- Return 0 on error ([#9705](https://github.com/paritytech/parity-ethereum/pull/9705))
- Ethcore: delay ropsten hardfork ([#9704](https://github.com/paritytech/parity-ethereum/pull/9704))
- Make instantSeal engine backwards compatible, closes [#9696](https://github.com/paritytech/parity-ethereum/issues/9696) ([#9700](https://github.com/paritytech/parity-ethereum/pull/9700))
- Implement CREATE2 gas changes and fix some potential overflowing ([#9694](https://github.com/paritytech/parity-ethereum/pull/9694))
- Don't hash the init_code of CREATE. ([#9688](https://github.com/paritytech/parity-ethereum/pull/9688))
- Ethcore: minor optimization of modexp by using LR exponentiation ([#9697](https://github.com/paritytech/parity-ethereum/pull/9697))
- Removed redundant clone before each block import ([#9683](https://github.com/paritytech/parity-ethereum/pull/9683))
- Add Foundation Bootnodes ([#9666](https://github.com/paritytech/parity-ethereum/pull/9666))
- Docker: run as parity user ([#9689](https://github.com/paritytech/parity-ethereum/pull/9689))
- Ethcore: mcip3 block reward contract ([#9605](https://github.com/paritytech/parity-ethereum/pull/9605))
- Verify block syncing responses against requests ([#9670](https://github.com/paritytech/parity-ethereum/pull/9670))
- Add a new RPC `parity_submitWorkDetail` similar `eth_submitWork` but return block hash ([#9404](https://github.com/paritytech/parity-ethereum/pull/9404))
- Resumable EVM and heap-allocated callstack ([#9360](https://github.com/paritytech/parity-ethereum/pull/9360))
- Update parity-wordlist library ([#9682](https://github.com/paritytech/parity-ethereum/pull/9682))
- Ci: Remove unnecessary pipes ([#9681](https://github.com/paritytech/parity-ethereum/pull/9681))
- Test.sh: use cargo --target for platforms other than linux, win or mac ([#9650](https://github.com/paritytech/parity-ethereum/pull/9650))
- Ci: fix push script ([#9679](https://github.com/paritytech/parity-ethereum/pull/9679))
- Hardfork the testnets ([#9562](https://github.com/paritytech/parity-ethereum/pull/9562))
- Calculate sha3 instead of sha256 for push-release. ([#9673](https://github.com/paritytech/parity-ethereum/pull/9673))
- Ethcore-io retries failed work steal ([#9651](https://github.com/paritytech/parity-ethereum/pull/9651))
- Fix(light_fetch): avoid race with BlockNumber::Latest ([#9665](https://github.com/paritytech/parity-ethereum/pull/9665))
- Test fix for windows cache name... ([#9658](https://github.com/paritytech/parity-ethereum/pull/9658))
- Refactor(fetch) : light use only one `DNS` thread ([#9647](https://github.com/paritytech/parity-ethereum/pull/9647))
- Ethereum libfuzzer integration small change ([#9547](https://github.com/paritytech/parity-ethereum/pull/9547))
- Cli: remove reference to --no-ui in --unlock flag help ([#9616](https://github.com/paritytech/parity-ethereum/pull/9616))
- Remove master from releasable branches ([#9655](https://github.com/paritytech/parity-ethereum/pull/9655))
- Ethcore/VerificationQueue don't spawn up extra `worker-threads` when explictly specified not to ([#9620](https://github.com/paritytech/parity-ethereum/pull/9620))
- Rpc: parity_getBlockReceipts ([#9527](https://github.com/paritytech/parity-ethereum/pull/9527))
- Remove unused dependencies ([#9589](https://github.com/paritytech/parity-ethereum/pull/9589))
- Ignore key_server_cluster randomly failing tests ([#9639](https://github.com/paritytech/parity-ethereum/pull/9639))
- Ethcore: handle vm exception when estimating gas ([#9615](https://github.com/paritytech/parity-ethereum/pull/9615))
- Fix bad-block reporting no reason ([#9638](https://github.com/paritytech/parity-ethereum/pull/9638))
- Use static call and apparent value transfer for block reward contract code ([#9603](https://github.com/paritytech/parity-ethereum/pull/9603))
- Hf in POA Sokol (2018-09-19) ([#9607](https://github.com/paritytech/parity-ethereum/pull/9607))
- Bump smallvec to 0.6 in ethcore-light, ethstore and whisper ([#9588](https://github.com/paritytech/parity-ethereum/pull/9588))
- Add constantinople conf to EvmTestClient. ([#9570](https://github.com/paritytech/parity-ethereum/pull/9570))
- Fix(network): don't disconnect reserved peers ([#9608](https://github.com/paritytech/parity-ethereum/pull/9608))
- Fix failing node-table tests on mac os, closes [#9632](https://github.com/paritytech/parity-ethereum/issues/9632) ([#9633](https://github.com/paritytech/parity-ethereum/pull/9633))
- Update ropsten.json ([#9602](https://github.com/paritytech/parity-ethereum/pull/9602))
- Simplify ethcore errors by removing BlockImportError ([#9593](https://github.com/paritytech/parity-ethereum/pull/9593))
- Fix windows compilation, replaces [#9561](https://github.com/paritytech/parity-ethereum/issues/9561) ([#9621](https://github.com/paritytech/parity-ethereum/pull/9621))
- Master: rpc-docs set github token ([#9610](https://github.com/paritytech/parity-ethereum/pull/9610))
- Docs: add changelogs for 1.11.10, 1.11.11, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.1.0, and 2.1.1 ([#9554](https://github.com/paritytech/parity-ethereum/pull/9554))
- Docs(rpc): annotate tag with the provided message ([#9601](https://github.com/paritytech/parity-ethereum/pull/9601))
- Ci: fix regex roll_eyes ([#9597](https://github.com/paritytech/parity-ethereum/pull/9597))
- Remove snapcraft clean ([#9585](https://github.com/paritytech/parity-ethereum/pull/9585))
- Add snapcraft package image (master) ([#9584](https://github.com/paritytech/parity-ethereum/pull/9584))
- Docs(rpc): push the branch along with tags ([#9578](https://github.com/paritytech/parity-ethereum/pull/9578))
- Fix typo for jsonrpc-threads flag ([#9574](https://github.com/paritytech/parity-ethereum/pull/9574))
- Fix informant compile ([#9571](https://github.com/paritytech/parity-ethereum/pull/9571))
- Added ropsten bootnodes ([#9569](https://github.com/paritytech/parity-ethereum/pull/9569))
- Increase Gas-floor-target and Gas Cap ([#9564](https://github.com/paritytech/parity-ethereum/pull/9564))
- While working on the platform tests make them non-breaking ([#9563](https://github.com/paritytech/parity-ethereum/pull/9563))
- Improve P2P discovery ([#9526](https://github.com/paritytech/parity-ethereum/pull/9526))
- Move dockerfile for android build container to scripts repo ([#9560](https://github.com/paritytech/parity-ethereum/pull/9560))
- Simultaneous platform tests WIP ([#9557](https://github.com/paritytech/parity-ethereum/pull/9557))
- Update ethabi-derive, serde, serde_json, serde_derive, syn && quote ([#9553](https://github.com/paritytech/parity-ethereum/pull/9553))
- Ci: fix rpc docs generation 2 ([#9550](https://github.com/paritytech/parity-ethereum/pull/9550))
- Ci: always run build pipelines for win, mac, linux, and android ([#9537](https://github.com/paritytech/parity-ethereum/pull/9537))
- Multithreaded snapshot creation ([#9239](https://github.com/paritytech/parity-ethereum/pull/9239))
- New ethabi ([#9511](https://github.com/paritytech/parity-ethereum/pull/9511))
- Remove initial token for WS. ([#9545](https://github.com/paritytech/parity-ethereum/pull/9545))
- Net_version caches network_id to avoid redundant aquire of sync readlock ([#9544](https://github.com/paritytech/parity-ethereum/pull/9544))
- Correct before_script for nightly build versions ([#9543](https://github.com/paritytech/parity-ethereum/pull/9543))
- Deps: bump kvdb-rocksdb to 0.1.4 ([#9539](https://github.com/paritytech/parity-ethereum/pull/9539))
- State: test when contract creation fails, old storage values should re-appear ([#9532](https://github.com/paritytech/parity-ethereum/pull/9532))
- Allow dropping light client RPC query with no results ([#9318](https://github.com/paritytech/parity-ethereum/pull/9318))
- Bump master to 2.2.0 ([#9517](https://github.com/paritytech/parity-ethereum/pull/9517))
- Enable all Constantinople hard fork changes in constantinople_test.json ([#9505](https://github.com/paritytech/parity-ethereum/pull/9505))
- [Light] Validate `account balance` before importing transactions ([#9417](https://github.com/paritytech/parity-ethereum/pull/9417))
- In create memory calculation is the same for create2 because the additional parameter was popped before. ([#9522](https://github.com/paritytech/parity-ethereum/pull/9522))
- Update patricia trie to 0.2.2 ([#9525](https://github.com/paritytech/parity-ethereum/pull/9525))
- Replace hardcoded JSON with serde json! macro ([#9489](https://github.com/paritytech/parity-ethereum/pull/9489))
- Fix typo in version string ([#9516](https://github.com/paritytech/parity-ethereum/pull/9516))

View File

@@ -1,288 +0,0 @@
## Parity-Ethereum [v2.3.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.8) (2019-03-22)
Parity-Ethereum 2.3.8-stable is a bugfix release that improves performance and stability. This patch release contains a critical bug fix where serving light clients previously led to client crashes. Upgrading is highly recommended.
The full list of included changes:
- 2.3.8 stable backports ([#10507](https://github.com/paritytech/parity-ethereum/pull/10507))
- Version: bump stable
- Add additional request tests ([#10503](https://github.com/paritytech/parity-ethereum/pull/10503))
## Parity-Ethereum [v2.3.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.7) (2019-03-20)
Parity-Ethereum 2.3.7-stable is a bugfix release that improves performance and stability.
The full list of included changes:
- 2.3.7 stable backports ([#10487](https://github.com/paritytech/parity-ethereum/pull/10487))
- Version: bump stable
- Сaching through docker volume ([#10477](https://github.com/paritytech/parity-ethereum/pull/10477))
- fix win&mac build ([#10486](https://github.com/paritytech/parity-ethereum/pull/10486))
- fix(extract `timestamp_checked_add` as lib) ([#10383](https://github.com/paritytech/parity-ethereum/pull/10383))
## Parity-Ethereum [v2.3.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.6) (2019-03-19)
Parity-Ethereum 2.3.6-stable is a bugfix release that improves performance and stability.
The full list of included changes:
- 2.3.6 stable backports ([#10470](https://github.com/paritytech/parity-ethereum/pull/10470))
- Version: bump stable
- CI publish to aws ([#10446](https://github.com/paritytech/parity-ethereum/pull/10446))
- Ensure static validator set changes are recognized ([#10467](https://github.com/paritytech/parity-ethereum/pull/10467))
- CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))
- Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))" ([#10456](https://github.com/paritytech/parity-ethereum/pull/10456))
- Tests parallelized ([#10452](https://github.com/paritytech/parity-ethereum/pull/10452))
## Parity-Ethereum [v2.3.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.5) (2019-02-25)
Parity-Ethereum 2.3.5-stable is a bugfix release that improves performance and stability.
Note, all 2.2 releases and older are now unsupported and upgrading is recommended.
The full list of included changes:
- More Backports for Stable 2.3.5 ([#10430](https://github.com/paritytech/parity-ethereum/pull/10430))
- Revert some changes, could be buggy ([#10399](https://github.com/paritytech/parity-ethereum/pull/10399))
- Ci: clean up gitlab-ci.yml leftovers from previous merge ([#10429](https://github.com/paritytech/parity-ethereum/pull/10429))
- 10000 > 5000 ([#10422](https://github.com/paritytech/parity-ethereum/pull/10422))
- Fix underflow in pip, closes [#10419](https://github.com/paritytech/parity-ethereum/pull/10419) ([#10423](https://github.com/paritytech/parity-ethereum/pull/10423))
- Fix panic when logging directory does not exist, closes [#10420](https://github.com/paritytech/parity-ethereum/pull/10420) ([#10424](https://github.com/paritytech/parity-ethereum/pull/10424))
- Update hardcoded headers for Foundation, Ropsten, Kovan and Classic ([#10417](https://github.com/paritytech/parity-ethereum/pull/10417))
- Backports for Stable 2.3.5 ([#10414](https://github.com/paritytech/parity-ethereum/pull/10414))
- No-git for publish jobs, empty artifacts dir ([#10393](https://github.com/paritytech/parity-ethereum/pull/10393))
- Snap: reenable i386, arm64, armhf architecture publishing ([#10386](https://github.com/paritytech/parity-ethereum/pull/10386))
- Tx pool: always accept local transactions ([#10375](https://github.com/paritytech/parity-ethereum/pull/10375))
- Fix to_pod storage trie value decoding ([#10368)](https://github.com/paritytech/parity-ethereum/pull/10368))
- Version: mark 2.3.5 as stable
## Parity-Ethereum [v2.3.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.4) (2019-02-21)
Parity-Ethereum 2.3.4-beta is a maintenance release that fixes snap and docker installations.
The full list of included changes:
- Beta: snap: release untagged versions from branches to the candidate ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357)) ([#10373](https://github.com/paritytech/parity-ethereum/pull/10373))
- Snap: release untagged versions from branches to the candidate snap channel ([#10357](https://github.com/paritytech/parity-ethereum/pull/10357))
- Snap: add the removable-media plug ([#10377](https://github.com/paritytech/parity-ethereum/pull/10377))
- Exchanged old(azure) bootnodes with new(ovh) ones ([#10309](https://github.com/paritytech/parity-ethereum/pull/10309))
- Beta Backports ([#10354](https://github.com/paritytech/parity-ethereum/pull/10354))
- Version: bump beta to 2.3.4
- Snap: prefix version and populate candidate channel ([#10343](https://github.com/paritytech/parity-ethereum/pull/10343))
- Snap: populate candidate releases with beta snaps to avoid stale channel
- Snap: prefix version with v*
- No volumes are needed, just run -v volume:/path/in/the/container ([#10345](https://github.com/paritytech/parity-ethereum/pull/10345))
## Parity-Ethereum [v2.3.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.3) (2019-02-13)
Parity-Ethereum 2.3.3-beta is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints.
- https://www.parity.io/new-parity-ethereum-update-fixes-several-rpc-vulnerabilities/
The full list of included changes:
- Additional error for invalid gas ([#10327](https://github.com/paritytech/parity-ethereum/pull/10327)) ([#10328](https://github.com/paritytech/parity-ethereum/pull/10328))
- Backports for Beta 2.3.3 ([#10333](https://github.com/paritytech/parity-ethereum/pull/10333))
- Properly handle check_epoch_end_signal errors ([#10015](https://github.com/paritytech/parity-ethereum/pull/10015))
- import rpc transactions sequentially ([#10051](https://github.com/paritytech/parity-ethereum/pull/10051))
- fix(docker): fix not receives SIGINT ([#10059](https://github.com/paritytech/parity-ethereum/pull/10059))
- snap: official image / test ([#10168](https://github.com/paritytech/parity-ethereum/pull/10168))
- Extract CallContract and RegistryInfo traits into their own crate ([#10178](https://github.com/paritytech/parity-ethereum/pull/10178))
- perform stripping during build ([#10208](https://github.com/paritytech/parity-ethereum/pull/10208))
- Remove CallContract and RegistryInfo re-exports from `ethcore/client` ([#10205](https://github.com/paritytech/parity-ethereum/pull/10205))
- fixed: types::transaction::SignedTransaction; ([#10229](https://github.com/paritytech/parity-ethereum/pull/10229))
- Additional tests for uint/hash/bytes deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279))
- Fix Windows build ([#10284](https://github.com/paritytech/parity-ethereum/pull/10284))
- Don't run the CPP example on CI ([#10285](https://github.com/paritytech/parity-ethereum/pull/10285))
- CI optimizations ([#10297](https://github.com/paritytech/parity-ethereum/pull/10297))
- fix publish job ([#10317](https://github.com/paritytech/parity-ethereum/pull/10317))
- Add Statetest support for Constantinople Fix ([#10323](https://github.com/paritytech/parity-ethereum/pull/10323))
- Add helper for Timestamp overflows ([#10330](https://github.com/paritytech/parity-ethereum/pull/10330))
- Don't add discovery initiators to the node table ([#10305](https://github.com/paritytech/parity-ethereum/pull/10305))
- change docker image based on debian instead of ubuntu due to the chan ([#10336](https://github.com/paritytech/parity-ethereum/pull/10336))
- role back docker build image and docker deploy image to ubuntu:xenial based ([#10338](https://github.com/paritytech/parity-ethereum/pull/10338))
## Parity-Ethereum [v2.3.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.2) (2019-02-03)
Parity-Ethereum 2.3.2-stable is a security-relevant release. A bug in the JSONRPC-deserialization module can cause crashes of all versions of Parity Ethereum nodes if an attacker is able to submit a specially-crafted RPC to certain publicly available endpoints.
- https://www.parity.io/security-alert-parity-ethereum-03-02/
The full list of included changes:
- Version: bump beta to 2.3.2 ([#10283](https://github.com/paritytech/parity-ethereum/pull/10283))
- Additional tests for uint deserialization. ([#10279](https://github.com/paritytech/parity-ethereum/pull/10279)) ([#10280](https://github.com/paritytech/parity-ethereum/pull/10280))
- Backport [#10285](https://github.com/paritytech/parity-ethereum/pull/10285) to beta ([#10286](https://github.com/paritytech/parity-ethereum/pull/10286))
## Parity-Ethereum [v2.3.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.1) (2019-02-01)
Parity-Ethereum 2.3.1-beta is a consensus-relevant release that enables _St. Petersfork_ on:
- Ethereum Block `7280000` (along with Constantinople)
- Kovan Block `10255201`
- Ropsten Block `4939394`
- POA Sokol Block `7026400`
In addition to this, Constantinople is cancelled for the POA Core network. Upgrading is mandatory for clients on any of these chains.
The full list of included changes:
- Backports for beta 2.3.1 ([#10225](https://github.com/paritytech/parity-ethereum/pull/10225))
- Fix _cannot recursively call into `Core`_ issue ([#10144](https://github.com/paritytech/parity-ethereum/pull/10144))
- Update for Android cross-compilation. ([#10180](https://github.com/paritytech/parity-ethereum/pull/10180))
- Fix _cannot recursively call into `Core`_ - Part 2 ([#10195](https://github.com/paritytech/parity-ethereum/pull/10195))
- Cancel Constantinople HF on POA Core ([#10198](https://github.com/paritytech/parity-ethereum/pull/10198))
- Add EIP-1283 disable transition ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214))
- Enable St-Peters-Fork ("Constantinople Fix") ([#10223](https://github.com/paritytech/parity-ethereum/pull/10223))
- Beta: Macos heapsize force jemalloc ([#10234](https://github.com/paritytech/parity-ethereum/pull/10234)) ([#10259](https://github.com/paritytech/parity-ethereum/pull/10259))
## Parity-Ethereum [v2.3.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.0) (2019-01-16)
Parity-Ethereum 2.3.0-beta is a consensus-relevant security release that reverts Constantinople on the Ethereum network. Upgrading is mandatory for Ethereum, and strongly recommended for other networks.
- **Consensus** - Ethereum Network: Pull Constantinople protocol upgrade on Ethereum ([#10189](https://github.com/paritytech/parity-ethereum/pull/10189))
- Read more: [Security Alert: Ethereum Constantinople Postponement](https://blog.ethereum.org/2019/01/15/security-alert-ethereum-constantinople-postponement/)
- **Networking** - All networks: Ping nodes from discovery ([#10167](https://github.com/paritytech/parity-ethereum/pull/10167))
- **Wasm** - Kovan Network: Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134))
Other notable changes:
- Existing blocks in the database are now kept when restoring a Snapshot. ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643))
- Block and transaction propagation is improved significantly. ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954))
- The ERC-191 Signed Data Standard is now supported by `personal_sign191`. ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701))
- Add support for ERC-191/712 `eth_signTypedData` as a standard for machine-verifiable and human-readable typed data signing with Ethereum keys. ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631))
- Add support for ERC-1186 `eth_getProof` ([#9001](https://github.com/paritytech/parity-ethereum/pull/9001))
- Add experimental RPCs flag to enable ERC-191, ERC-712, and ERC-1186 APIs via `--jsonrpc-experimental` ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928))
- Make `CALLCODE` to trace value to be the code address. ([#9881](https://github.com/paritytech/parity-ethereum/pull/9881))
Configuration changes:
- The EIP-98 transition is now disabled by default. If you previously had no `eip98transition` specified in your chain specification, you would enable this now manually on block `0x0`. ([#9955](https://github.com/paritytech/parity-ethereum/pull/9955))
- Also, unknown fields in chain specs are now rejected. ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972))
- The Tendermint engine was removed from Parity Ethereum and is no longer available and maintained. ([#9980](https://github.com/paritytech/parity-ethereum/pull/9980))
- Ropsten testnet data and keys moved from `test/` to `ropsten/` subdir. To reuse your old keys and data either copy or symlink them to the new location. ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123))
- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041))
- If you have a chain with`empty_steps` already running, some blocks most likely contain non-strict entries (unordered or duplicated empty steps). In this release `strict_empty_steps_transition` is enabled by default at block `0x0` for any chain with `empty_steps`.
- If your network uses `empty_steps` you **must** (A) plan a hard fork and change `strict_empty_steps_transition` to the desired fork block and (B) update the clients of the whole network to 2.2.7-stable / 2.3.0-beta. If for some reason you don't want to do this please set`strict_empty_steps_transition` to `0xfffffffff` to disable it.
_Note:_ This release marks Parity 2.3 as _beta_. All versions of Parity 2.2 are now considered _stable_.
The full list of included changes:
- Backports for 2.3.0 beta ([#10164](https://github.com/paritytech/parity-ethereum/pull/10164))
- Snap: fix path in script ([#10157](https://github.com/paritytech/parity-ethereum/pull/10157))
- Make sure parent block is not in importing queue when importing ancient blocks ([#10138](https://github.com/paritytech/parity-ethereum/pull/10138))
- Ci: re-enable snap publishing ([#10142](https://github.com/paritytech/parity-ethereum/pull/10142))
- Hf in POA Core (2019-01-18) - Constantinople ([#10155](https://github.com/paritytech/parity-ethereum/pull/10155))
- Update EWF's tobalaba chainspec ([#10152](https://github.com/paritytech/parity-ethereum/pull/10152))
- Replace ethcore-logger with env-logger. ([#10102](https://github.com/paritytech/parity-ethereum/pull/10102))
- Finality: dont require chain head to be in the chain ([#10054](https://github.com/paritytech/parity-ethereum/pull/10054))
- Remove caching for node connections ([#10143](https://github.com/paritytech/parity-ethereum/pull/10143))
- Blooms file iterator empty on out of range position. ([#10145](https://github.com/paritytech/parity-ethereum/pull/10145))
- Autogen docs for the "Configuring Parity Ethereum" wiki page. ([#10067](https://github.com/paritytech/parity-ethereum/pull/10067))
- Misc: bump license header to 2019 ([#10135](https://github.com/paritytech/parity-ethereum/pull/10135))
- Hide most of the logs from cpp example. ([#10139](https://github.com/paritytech/parity-ethereum/pull/10139))
- Don't try to send oversized packets ([#10042](https://github.com/paritytech/parity-ethereum/pull/10042))
- Private tx enabled flag added into STATUS packet ([#9999](https://github.com/paritytech/parity-ethereum/pull/9999))
- Update pwasm-utils to 0.6.1 ([#10134](https://github.com/paritytech/parity-ethereum/pull/10134))
- Extract blockchain from ethcore ([#10114](https://github.com/paritytech/parity-ethereum/pull/10114))
- Ethcore: update hardcoded headers ([#10123](https://github.com/paritytech/parity-ethereum/pull/10123))
- Identity fix ([#10128](https://github.com/paritytech/parity-ethereum/pull/10128))
- Use LenCachingMutex to optimize verification. ([#10117](https://github.com/paritytech/parity-ethereum/pull/10117))
- Pyethereum keystore support ([#9710](https://github.com/paritytech/parity-ethereum/pull/9710))
- Bump rocksdb-sys to 0.5.5 ([#10124](https://github.com/paritytech/parity-ethereum/pull/10124))
- Parity-clib: `async C bindings to RPC requests` + `subscribe/unsubscribe to websocket events` ([#9920](https://github.com/paritytech/parity-ethereum/pull/9920))
- Refactor (hardware wallet) : reduce the number of threads ([#9644](https://github.com/paritytech/parity-ethereum/pull/9644))
- Hf in POA Sokol (2019-01-04) ([#10077](https://github.com/paritytech/parity-ethereum/pull/10077))
- Fix broken links ([#10119](https://github.com/paritytech/parity-ethereum/pull/10119))
- Follow-up to [#10105](https://github.com/paritytech/parity-ethereum/issues/10105) ([#10107](https://github.com/paritytech/parity-ethereum/pull/10107))
- Move EIP-712 crate back to parity-ethereum ([#10106](https://github.com/paritytech/parity-ethereum/pull/10106))
- Move a bunch of stuff around ([#10101](https://github.com/paritytech/parity-ethereum/pull/10101))
- Revert "Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081))" ([#10105](https://github.com/paritytech/parity-ethereum/pull/10105))
- Fix left over small grumbles on whitespaces ([#10084](https://github.com/paritytech/parity-ethereum/pull/10084))
- Add --frozen when running cargo ([#10081](https://github.com/paritytech/parity-ethereum/pull/10081))
- Fix pubsub new_blocks notifications to include all blocks ([#9987](https://github.com/paritytech/parity-ethereum/pull/9987))
- Update some dependencies for compilation with pc-windows-gnu ([#10082](https://github.com/paritytech/parity-ethereum/pull/10082))
- Fill transaction hash on ethGetLog of light client. ([#9938](https://github.com/paritytech/parity-ethereum/pull/9938))
- Update changelog update for 2.2.5-beta and 2.1.10-stable ([#10064](https://github.com/paritytech/parity-ethereum/pull/10064))
- Implement len caching for parking_lot RwLock ([#10032](https://github.com/paritytech/parity-ethereum/pull/10032))
- Update parking_lot to 0.7 ([#10050](https://github.com/paritytech/parity-ethereum/pull/10050))
- Bump crossbeam. ([#10048](https://github.com/paritytech/parity-ethereum/pull/10048))
- Ethcore: enable constantinople on ethereum ([#10031](https://github.com/paritytech/parity-ethereum/pull/10031))
- Strict empty steps validation ([#10041](https://github.com/paritytech/parity-ethereum/pull/10041))
- Center the Subtitle, use some CAPS ([#10034](https://github.com/paritytech/parity-ethereum/pull/10034))
- Change test miner max memory to malloc reports. ([#10024](https://github.com/paritytech/parity-ethereum/pull/10024))
- Sort the storage for private state ([#10018](https://github.com/paritytech/parity-ethereum/pull/10018))
- Fix: test corpus_inaccessible panic ([#10019](https://github.com/paritytech/parity-ethereum/pull/10019))
- Ci: move future releases to ethereum subdir on s3 ([#10017](https://github.com/paritytech/parity-ethereum/pull/10017))
- Light(on_demand): decrease default time window to 10 secs ([#10016](https://github.com/paritytech/parity-ethereum/pull/10016))
- Light client : failsafe crate (circuit breaker) ([#9790](https://github.com/paritytech/parity-ethereum/pull/9790))
- Lencachingmutex ([#9988](https://github.com/paritytech/parity-ethereum/pull/9988))
- Version and notification for private contract wrapper added ([#9761](https://github.com/paritytech/parity-ethereum/pull/9761))
- Handle failing case for update account cache in require ([#9989](https://github.com/paritytech/parity-ethereum/pull/9989))
- Add tokio runtime to ethcore io worker ([#9979](https://github.com/paritytech/parity-ethereum/pull/9979))
- Move daemonize before creating account provider ([#10003](https://github.com/paritytech/parity-ethereum/pull/10003))
- Docs: update changelogs ([#9990](https://github.com/paritytech/parity-ethereum/pull/9990))
- Fix daemonize ([#10000](https://github.com/paritytech/parity-ethereum/pull/10000))
- Fix Bloom migration ([#9992](https://github.com/paritytech/parity-ethereum/pull/9992))
- Remove tendermint engine support ([#9980](https://github.com/paritytech/parity-ethereum/pull/9980))
- Calculate gas for deployment transaction ([#9840](https://github.com/paritytech/parity-ethereum/pull/9840))
- Fix unstable peers and slowness in sync ([#9967](https://github.com/paritytech/parity-ethereum/pull/9967))
- Adds parity_verifySignature RPC method ([#9507](https://github.com/paritytech/parity-ethereum/pull/9507))
- Improve block and transaction propagation ([#9954](https://github.com/paritytech/parity-ethereum/pull/9954))
- Deny unknown fields for chainspec ([#9972](https://github.com/paritytech/parity-ethereum/pull/9972))
- Fix docker build ([#9971](https://github.com/paritytech/parity-ethereum/pull/9971))
- Ci: rearrange pipeline by logic ([#9970](https://github.com/paritytech/parity-ethereum/pull/9970))
- Add changelogs for 2.0.9, 2.1.4, 2.1.6, and 2.2.1 ([#9963](https://github.com/paritytech/parity-ethereum/pull/9963))
- Add Error message when sync is still in progress. ([#9475](https://github.com/paritytech/parity-ethereum/pull/9475))
- Make CALLCODE to trace value to be the code address ([#9881](https://github.com/paritytech/parity-ethereum/pull/9881))
- Fix light client informant while syncing ([#9932](https://github.com/paritytech/parity-ethereum/pull/9932))
- Add a optional json dump state to evm-bin ([#9706](https://github.com/paritytech/parity-ethereum/pull/9706))
- Disable EIP-98 transition by default ([#9955](https://github.com/paritytech/parity-ethereum/pull/9955))
- Remove secret_store runtimes. ([#9888](https://github.com/paritytech/parity-ethereum/pull/9888))
- Fix a deadlock ([#9952](https://github.com/paritytech/parity-ethereum/pull/9952))
- Chore(eip712): remove unused `failure-derive` ([#9958](https://github.com/paritytech/parity-ethereum/pull/9958))
- Do not use the home directory as the working dir in docker ([#9834](https://github.com/paritytech/parity-ethereum/pull/9834))
- Prevent silent errors in daemon mode, closes [#9367](https://github.com/paritytech/parity-ethereum/issues/9367) ([#9946](https://github.com/paritytech/parity-ethereum/pull/9946))
- Fix empty steps ([#9939](https://github.com/paritytech/parity-ethereum/pull/9939))
- Adjust requests costs for light client ([#9925](https://github.com/paritytech/parity-ethereum/pull/9925))
- Eip-1186: add `eth_getProof` RPC-Method ([#9001](https://github.com/paritytech/parity-ethereum/pull/9001))
- Missing blocks in filter_changes RPC ([#9947](https://github.com/paritytech/parity-ethereum/pull/9947))
- Allow rust-nightly builds fail in nightly builds ([#9944](https://github.com/paritytech/parity-ethereum/pull/9944))
- Update eth-secp256k1 to include fix for BSDs ([#9935](https://github.com/paritytech/parity-ethereum/pull/9935))
- Unbreak build on rust -stable ([#9934](https://github.com/paritytech/parity-ethereum/pull/9934))
- Keep existing blocks when restoring a Snapshot ([#8643](https://github.com/paritytech/parity-ethereum/pull/8643))
- Add experimental RPCs flag ([#9928](https://github.com/paritytech/parity-ethereum/pull/9928))
- Clarify poll lifetime ([#9922](https://github.com/paritytech/parity-ethereum/pull/9922))
- Docs(require rust 1.30) ([#9923](https://github.com/paritytech/parity-ethereum/pull/9923))
- Use block header for building finality ([#9914](https://github.com/paritytech/parity-ethereum/pull/9914))
- Simplify cargo audit ([#9918](https://github.com/paritytech/parity-ethereum/pull/9918))
- Light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure ([#9824](https://github.com/paritytech/parity-ethereum/pull/9824))
- Eip 191 ([#9701](https://github.com/paritytech/parity-ethereum/pull/9701))
- Fix(logger): `reqwest` no longer a dependency ([#9908](https://github.com/paritytech/parity-ethereum/pull/9908))
- Remove rust-toolchain file ([#9906](https://github.com/paritytech/parity-ethereum/pull/9906))
- Foundation: 6692865, ropsten: 4417537, kovan: 9363457 ([#9907](https://github.com/paritytech/parity-ethereum/pull/9907))
- Ethcore: use Machine::verify_transaction on parent block ([#9900](https://github.com/paritytech/parity-ethereum/pull/9900))
- Chore(rpc-tests): remove unused rand ([#9896](https://github.com/paritytech/parity-ethereum/pull/9896))
- Fix: Intermittent failing CI due to addr in use ([#9885](https://github.com/paritytech/parity-ethereum/pull/9885))
- Chore(bump docopt): 0.8 -> 1.0 ([#9889](https://github.com/paritytech/parity-ethereum/pull/9889))
- Use expect ([#9883](https://github.com/paritytech/parity-ethereum/pull/9883))
- Use Weak reference in PubSubClient ([#9886](https://github.com/paritytech/parity-ethereum/pull/9886))
- Ci: nuke the gitlab caches ([#9855](https://github.com/paritytech/parity-ethereum/pull/9855))
- Remove unused code ([#9884](https://github.com/paritytech/parity-ethereum/pull/9884))
- Fix json tracer overflow ([#9873](https://github.com/paritytech/parity-ethereum/pull/9873))
- Allow to seal work on latest block ([#9876](https://github.com/paritytech/parity-ethereum/pull/9876))
- Fix docker script ([#9854](https://github.com/paritytech/parity-ethereum/pull/9854))
- Health endpoint ([#9847](https://github.com/paritytech/parity-ethereum/pull/9847))
- Gitlab-ci: make android release build succeed ([#9743](https://github.com/paritytech/parity-ethereum/pull/9743))
- Clean up existing benchmarks ([#9839](https://github.com/paritytech/parity-ethereum/pull/9839))
- Update Callisto block reward code to support HF1 ([#9811](https://github.com/paritytech/parity-ethereum/pull/9811))
- Option to disable keep alive for JSON-RPC http transport ([#9848](https://github.com/paritytech/parity-ethereum/pull/9848))
- Classic.json Bootnode Update ([#9828](https://github.com/paritytech/parity-ethereum/pull/9828))
- Support MIX. ([#9767](https://github.com/paritytech/parity-ethereum/pull/9767))
- Ci: remove failing tests for android, windows, and macos ([#9788](https://github.com/paritytech/parity-ethereum/pull/9788))
- Implement NoProof for json tests and update tests reference (replaces [#9744](https://github.com/paritytech/parity-ethereum/issues/9744)) ([#9814](https://github.com/paritytech/parity-ethereum/pull/9814))
- Chore(bump regex) ([#9842](https://github.com/paritytech/parity-ethereum/pull/9842))
- Ignore global cache for patched accounts ([#9752](https://github.com/paritytech/parity-ethereum/pull/9752))
- Move state root verification before gas used ([#9841](https://github.com/paritytech/parity-ethereum/pull/9841))
- Fix(docker-aarch64) : cross-compile config ([#9798](https://github.com/paritytech/parity-ethereum/pull/9798))
- Version: bump nightly to 2.3.0 ([#9819](https://github.com/paritytech/parity-ethereum/pull/9819))
- Tests modification for windows CI ([#9671](https://github.com/paritytech/parity-ethereum/pull/9671))
- Eip-712 implementation ([#9631](https://github.com/paritytech/parity-ethereum/pull/9631))
- Fix typo ([#9826](https://github.com/paritytech/parity-ethereum/pull/9826))
- Clean up serde rename and use rename_all = camelCase when possible ([#9823](https://github.com/paritytech/parity-ethereum/pull/9823))

View File

@@ -1,128 +0,0 @@
## Parity-Ethereum [v2.4.9](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.9)
Parity Ethereum v2.4.9-stable is a security update which addresses servo/rust-smallvec#148
The full list of included changes:
* cargo update -p smallvec ([#10822](https://github.com/paritytech/parity-ethereum/pull/10822))
## Parity-Ethereum [v2.4.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.8)
Parity-Ethereum 2.4.8-stable is a bugfix release that improves performance and stability.
* Blockchain: fix reset chain
* State tests: treat empty accounts the same as non-existant accounts (EIP 1052)
* Aura: fix Timestamp Overflow
* Networking: support discovery-only peers (geth bootnodes)
* Snapshotting: fix unclean shutdown while snappshotting is under way
The full list of included changes:
* ethcore/res: activate atlantis classic hf on block 8772000 ([#10766](https://github.com/paritytech/parity-ethereum/pull/10766))
* fix docker tags for publishing ([#10741](https://github.com/paritytech/parity-ethereum/pull/10741))
* Reset blockchain properly ([#10669](https://github.com/paritytech/parity-ethereum/pull/10669))
* adds rpc error message for --no-ancient-blocks ([#10608](https://github.com/paritytech/parity-ethereum/pull/10608))
* Treat empty account the same as non-exist accounts in EIP-1052 ([#10775](https://github.com/paritytech/parity-ethereum/pull/10775))
* fix: aura don't add `SystemTime::now()` ([#10720](https://github.com/paritytech/parity-ethereum/pull/10720))
* DevP2p: Get node IP address and udp port from Socket, if not included in PING packet ([#10705](https://github.com/paritytech/parity-ethereum/pull/10705))
* Revert "fix: aura don't add `SystemTime::now()` ([#10720](https://github.com/paritytech/parity-ethereum/pull/10720))"
* Add a way to signal shutdown to snapshotting threads ([#10744](https://github.com/paritytech/parity-ethereum/pull/10744))
## Parity-Ethereum [v2.4.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.7)
Parity-Ethereum 2.4.7-stable is a bugfix release that improves performance and stability.
Among others, it enables the _Atlantis_ hardfork on **Morden** and **Kotti** Classic networks.
The full list of included changes:
* [CI] allow cargo audit to fail ([#10676](https://github.com/paritytech/parity-ethereum/pull/10676))
* new image ([#10673](https://github.com/paritytech/parity-ethereum/pull/10673))
* Update publishing ([#10644](https://github.com/paritytech/parity-ethereum/pull/10644))
* enable lto for release builds ([#10717](https://github.com/paritytech/parity-ethereum/pull/10717))
* Use RUSTFLAGS to set the optimization level ([#10719](https://github.com/paritytech/parity-ethereum/pull/10719))
* ethcore: enable ECIP-1054 for classic ([#10731](https://github.com/paritytech/parity-ethereum/pull/10731))
## Parity-Ethereum [v2.4.6](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.6)
Parity-Ethereum 2.4.6-stable is a bugfix release that improves performance and stability.
Among others, it enables the Petersburg hardfork on **Rinkeby** and **POA-Core** Network, as well as the **Kovan** Network community hardfork.
The full list of included changes:
* ci: publish docs debug ([#10638](https://github.com/paritytech/parity-ethereum/pull/10638))
## Parity-Ethereum [v2.4.5](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.5)
Parity-Ethereum 2.4.5-stable is a bugfix release that improves performance and stability. This release improves memory optimizations around timestamp handling and stabilizes the 2.4 release branch.
As of today, Parity-Ethereum 2.3 reaches end of life and everyone is encouraged to upgrade.
## Parity-Ethereum [v2.4.4](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.4)
Parity-Ethereum 2.4.4-beta is a bugfix release that improves performance and stability. This patch release removes the dead chain configs for Easthub and Ethereum Social.
The full list of included changes:
* fix(rpc-types): replace uint and hash with `ethereum_types v0.4` ([#10217](https://github.com/paritytech/parity-ethereum/pull/10217))
* chore(bump ethereum-types) ([#10396](https://github.com/paritytech/parity-ethereum/pull/10396))
* fix(light eth_gasPrice): ask network if not in cache ([#10535](https://github.com/paritytech/parity-ethereum/pull/10535))
* fix(light account response): update `tx_queue` ([#10545](https://github.com/paritytech/parity-ethereum/pull/10545))
* fix(bump dependencies) ([#10540](https://github.com/paritytech/parity-ethereum/pull/10540))
* tx-pool: check transaction readiness before replacing ([#10526](https://github.com/paritytech/parity-ethereum/pull/10526))
* fix #10390 ([#10391](https://github.com/paritytech/parity-ethereum/pull/10391))
* private-tx: replace error_chain ([#10510](https://github.com/paritytech/parity-ethereum/pull/10510))
## Parity-Ethereum [v2.4.3](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.3)
Parity-Ethereum 2.4.3-beta is a bugfix release that improves performance and stability. This patch release contains a critical bug fix where serving light clients previously led to client crashes. Upgrading is highly recommended.
The full list of included changes:
* Add additional request tests ([#10503](https://github.com/paritytech/parity-ethereum/pull/10503))
## Parity-Ethereum [v2.4.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.2)
Parity-Ethereum 2.4.2-beta is a bugfix release that improves performance and stability.
The full list of included changes:
* Сaching through docker volume ([#10477](https://github.com/paritytech/parity-ethereum/pull/10477))
* fix win&mac build ([#10486](https://github.com/paritytech/parity-ethereum/pull/10486))
* fix(extract `timestamp_checked_add` as lib) ([#10383](https://github.com/paritytech/parity-ethereum/pull/10383))
## Parity-Ethereum [v2.4.1](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.1)
Parity-Ethereum 2.4.1-beta is a bugfix release that improves performance and stability.
The full list of included changes:
* Implement parity_versionInfo & parity_setChain on LC; fix parity_setChain ([#10312](https://github.com/paritytech/parity-ethereum/pull/10312))
* CI publish to aws ([#10446](https://github.com/paritytech/parity-ethereum/pull/10446))
* CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))
* Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))" (#10456)
* Revert "CI aws git checkout ([#10451](https://github.com/paritytech/parity-ethereum/pull/10451))"
* Tests parallelized ([#10452](https://github.com/paritytech/parity-ethereum/pull/10452))
* Ensure static validator set changes are recognized ([#10467](https://github.com/paritytech/parity-ethereum/pull/10467))
## Parity-Ethereum [v2.4.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.4.0)
Parity-Ethereum 2.4.0-beta is our trifortnightly minor version release coming with a lot of new features as well as bugfixes and performance improvements.
Notable changes:
- Account management is now deprecated ([#10213](https://github.com/paritytech/parity-ethereum/pull/10213))
- Local accounts can now be specified via CLI ([#9960](https://github.com/paritytech/parity-ethereum/pull/9960))
- Chains can now be reset to a particular block via CLI ([#9782](https://github.com/paritytech/parity-ethereum/pull/9782))
- Ethash now additionally implements ProgPoW ([#9762](https://github.com/paritytech/parity-ethereum/pull/9762))
- The `eip1283DisableTransition` flag was added to revert EIP-1283 ([#10214](https://github.com/paritytech/parity-ethereum/pull/10214))
The full list of included changes:
* revert some changes, could be buggy ([#10399](https://github.com/paritytech/parity-ethereum/pull/10399))
* 10000 > 5000 ([#10422](https://github.com/paritytech/parity-ethereum/pull/10422))
* fix panic when logging directory does not exist, closes #10420 ([#10424](https://github.com/paritytech/parity-ethereum/pull/10424))
* fix underflow in pip, closes #10419 ([#10423](https://github.com/paritytech/parity-ethereum/pull/10423))
* ci: clean up gitlab-ci.yml leftovers from previous merge ([#10429](https://github.com/paritytech/parity-ethereum/pull/10429))
* Update hardcoded headers for Foundation, Ropsten, Kovan and Classic ([#10417](https://github.com/paritytech/parity-ethereum/pull/10417))

View File

@@ -1,5 +1,4 @@
[package]
description = "Parity Ethereum Ethash & ProgPoW Implementations"
name = "ethash"
version = "1.12.0"
authors = ["Parity Technologies <admin@parity.io>"]
@@ -7,27 +6,17 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
crunchy = "0.1.0"
either = "1.0.0"
ethereum-types = "0.6.0"
keccak-hash = "0.2.0"
ethereum-types = "0.4"
keccak-hash = "0.1"
log = "0.4"
memmap = "0.6"
parking_lot = "0.7"
primal = "0.2.3"
[dev-dependencies]
criterion = "0.2"
rustc-hex = "1.0"
serde_json = "1.0"
tempdir = "0.3"
[features]
default = []
bench = []
criterion = "0.2"
[[bench]]
name = "basic"
harness = false
[[bench]]
name = "progpow"
harness = false

View File

@@ -40,28 +40,28 @@ criterion_main!(basic);
fn bench_light_compute_memmap(b: &mut Criterion) {
use std::env;
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let light = builder.light(&env::temp_dir(), 486382);
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value())));
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE)));
}
fn bench_light_compute_memory(b: &mut Criterion) {
use std::env;
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let light = builder.light(&env::temp_dir(), 486382);
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value())));
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE)));
}
fn bench_light_new_round_trip_memmap(b: &mut Criterion) {
use std::env;
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let light = builder.light(&env::temp_dir(), 486382);
light.compute(&HASH, NONCE, u64::max_value());
light.compute(&HASH, NONCE);
}));
}
@@ -69,9 +69,9 @@ fn bench_light_new_round_trip_memory(b: &mut Criterion) {
use std::env;
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let light = builder.light(&env::temp_dir(), 486382);
light.compute(&HASH, NONCE, u64::max_value());
light.compute(&HASH, NONCE);
}));
}
@@ -81,15 +81,15 @@ fn bench_light_from_file_round_trip_memory(b: &mut Criterion) {
let dir = env::temp_dir();
let height = 486382;
{
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let mut dummy = builder.light(&dir, height);
dummy.to_file().unwrap();
}
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let light = builder.light_from_file(&dir, 486382).unwrap();
light.compute(&HASH, NONCE, u64::max_value());
light.compute(&HASH, NONCE);
}));
}
@@ -100,14 +100,14 @@ fn bench_light_from_file_round_trip_memmap(b: &mut Criterion) {
let height = 486382;
{
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let mut dummy = builder.light(&dir, height);
dummy.to_file().unwrap();
}
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let light = builder.light_from_file(&dir, 486382).unwrap();
light.compute(&HASH, NONCE, u64::max_value());
light.compute(&HASH, NONCE);
}));
}

View File

@@ -1,86 +0,0 @@
#[macro_use]
extern crate criterion;
extern crate ethash;
extern crate rustc_hex;
extern crate tempdir;
use criterion::Criterion;
use ethash::progpow;
use tempdir::TempDir;
use rustc_hex::FromHex;
use ethash::{NodeCacheBuilder, OptimizeFor};
use ethash::compute::light_compute;
fn bench_hashimoto_light(c: &mut Criterion) {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let light = builder.light(&tempdir.path(), 1);
let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap();
let mut hash = [0; 32];
hash.copy_from_slice(&h);
c.bench_function("hashimoto_light", move |b| {
b.iter(|| light_compute(&light, &hash, 0))
});
}
fn bench_progpow_light(c: &mut Criterion) {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let cache = builder.new_cache(tempdir.into_path(), 0);
let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap();
let mut hash = [0; 32];
hash.copy_from_slice(&h);
c.bench_function("progpow_light", move |b| {
b.iter(|| {
let c_dag = progpow::generate_cdag(cache.as_ref());
progpow::progpow(
hash,
0,
0,
cache.as_ref(),
&c_dag,
);
})
});
}
fn bench_progpow_optimal_light(c: &mut Criterion) {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let cache = builder.new_cache(tempdir.into_path(), 0);
let c_dag = progpow::generate_cdag(cache.as_ref());
let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap();
let mut hash = [0; 32];
hash.copy_from_slice(&h);
c.bench_function("progpow_optimal_light", move |b| {
b.iter(|| {
progpow::progpow(
hash,
0,
0,
cache.as_ref(),
&c_dag,
);
})
});
}
fn bench_keccak_f800_long(c: &mut Criterion) {
c.bench_function("keccak_f800_long(0, 0, 0)", |b| {
b.iter(|| progpow::keccak_f800_long([0; 32], 0, [0; 8]))
});
}
criterion_group!(benches,
bench_hashimoto_light,
bench_progpow_light,
bench_progpow_optimal_light,
bench_keccak_f800_long,
);
criterion_main!(benches);

View File

@@ -1,86 +0,0 @@
[
[
0,
"0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000",
"faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3",
"63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b"
],
[
49,
"63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b",
"0000000006ff2c47",
"c789c1180f890ec555ff42042913465481e8e6bc512cb981e1c1108dc3f2227d",
"9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922"
],
[
50,
"9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922",
"00000000076e482e",
"c7340542c2a06b3a7dc7222635f7cd402abf8b528ae971ddac6bbe2b0c7cb518",
"de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d"
],
[
99,
"de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d",
"000000003917afab",
"f5e60b2c5bfddd136167a30cbc3c8dbdbd15a512257dee7964e0bc6daa9f8ba7",
"ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce"
],
[
29950,
"ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce",
"005d409dbc23a62a",
"07393d15805eb08ee6fc6cb3ad4ad1010533bd0ff92d6006850246829f18fd6e",
"e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5"
],
[
29999,
"e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5",
"005db5fa4c2a3d03",
"7551bddf977491da2f6cfc1679299544b23483e8f8ee0931c4c16a796558a0b8",
"d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454"
],
[
30000,
"d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454",
"005db8607994ff30",
"f1c2c7c32266af9635462e6ce1c98ebe4e7e3ecab7a38aaabfbf2e731e0fbff4",
"8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64"
],
[
30049,
"8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64",
"005e2e215a8ca2e7",
"57fe6a9fbf920b4e91deeb66cb0efa971e08229d1a160330e08da54af0689add",
"c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047"
],
[
30050,
"c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047",
"005e30899481055e",
"ba30c61cc5a2c74a5ecaf505965140a08f24a296d687e78720f0b48baf712f2d",
"ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71"
],
[
30099,
"ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71",
"005ea6aef136f88b",
"cfd5e46048cd133d40f261fe8704e51d3f497fc14203ac6a9ef6a0841780b1cd",
"49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6"
],
[
59950,
"49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6",
"02ebe0503bd7b1da",
"21511fbaa31fb9f5fc4998a754e97b3083a866f4de86fa7500a633346f56d773",
"f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf"
],
[
59999,
"f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf",
"02edb6275bd221e3",
"653eda37d337e39d311d22be9bbd3458d3abee4e643bee4a7280a6d08106ef98",
"341562d10d4afb706ec2c8d5537cb0c810de02b4ebb0a0eea5ae335af6fb2e88"
]
]

View File

@@ -69,7 +69,6 @@ pub struct NodeCacheBuilder {
// TODO: Remove this locking and just use an `Rc`?
seedhash: Arc<Mutex<SeedHashCompute>>,
optimize_for: OptimizeFor,
progpow_transition: u64,
}
// TODO: Abstract the "optimize for" logic
@@ -83,18 +82,17 @@ pub struct NodeCache {
impl NodeCacheBuilder {
pub fn light(&self, cache_dir: &Path, block_number: u64) -> Light {
Light::new_with_builder(self, cache_dir, block_number, self.progpow_transition)
Light::new_with_builder(self, cache_dir, block_number)
}
pub fn light_from_file(&self, cache_dir: &Path, block_number: u64) -> io::Result<Light> {
Light::from_file_with_builder(self, cache_dir, block_number, self.progpow_transition)
Light::from_file_with_builder(self, cache_dir, block_number)
}
pub fn new<T: Into<Option<OptimizeFor>>>(optimize_for: T, progpow_transition: u64) -> Self {
pub fn new<T: Into<Option<OptimizeFor>>>(optimize_for: T) -> Self {
NodeCacheBuilder {
seedhash: Arc::new(Mutex::new(SeedHashCompute::default())),
optimize_for: optimize_for.into().unwrap_or_default(),
progpow_transition
}
}

View File

@@ -21,7 +21,6 @@
use keccak::{keccak_512, keccak_256, H256};
use cache::{NodeCache, NodeCacheBuilder};
use progpow::{CDag, generate_cdag, progpow, keccak_f800_short, keccak_f800_long};
use seed_compute::SeedHashCompute;
use shared::*;
use std::io;
@@ -31,7 +30,7 @@ use std::path::Path;
const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4;
const MIX_NODES: usize = MIX_WORDS / NODE_WORDS;
pub const FNV_PRIME: u32 = 0x01000193;
const FNV_PRIME: u32 = 0x01000193;
/// Computation result
pub struct ProofOfWork {
@@ -41,15 +40,9 @@ pub struct ProofOfWork {
pub mix_hash: H256,
}
enum Algorithm {
Hashimoto,
Progpow(Box<CDag>),
}
pub struct Light {
block_number: u64,
cache: NodeCache,
algorithm: Algorithm,
}
/// Light cache structure
@@ -58,55 +51,32 @@ impl Light {
builder: &NodeCacheBuilder,
cache_dir: &Path,
block_number: u64,
progpow_transition: u64,
) -> Self {
let cache = builder.new_cache(cache_dir.to_path_buf(), block_number);
let algorithm = if block_number >= progpow_transition {
Algorithm::Progpow(Box::new(generate_cdag(cache.as_ref())))
} else {
Algorithm::Hashimoto
};
Light { block_number, cache, algorithm }
Light {
block_number: block_number,
cache: cache,
}
}
/// Calculate the light boundary data
/// `header_hash` - The header hash to pack into the mix
/// `nonce` - The nonce to pack into the mix
pub fn compute(&self, header_hash: &H256, nonce: u64, block_number: u64) -> ProofOfWork {
match self.algorithm {
Algorithm::Progpow(ref c_dag) => {
let (value, mix_hash) = progpow(
*header_hash,
nonce,
block_number,
self.cache.as_ref(),
c_dag,
);
ProofOfWork { value, mix_hash }
},
Algorithm::Hashimoto => light_compute(self, header_hash, nonce),
}
pub fn compute(&self, header_hash: &H256, nonce: u64) -> ProofOfWork {
light_compute(self, header_hash, nonce)
}
pub fn from_file_with_builder(
builder: &NodeCacheBuilder,
cache_dir: &Path,
block_number: u64,
progpow_transition: u64,
) -> io::Result<Self> {
let cache = builder.from_file(cache_dir.to_path_buf(), block_number)?;
let algorithm = if block_number >= progpow_transition {
Algorithm::Progpow(Box::new(generate_cdag(cache.as_ref())))
} else {
Algorithm::Hashimoto
};
Ok(Light { block_number, cache, algorithm })
Ok(Light {
block_number: block_number,
cache: cache,
})
}
pub fn to_file(&mut self) -> io::Result<&Path> {
@@ -129,32 +99,27 @@ fn fnv_hash(x: u32, y: u32) -> u32 {
/// `nonce` The block's nonce
/// `mix_hash` The mix digest hash
/// Boundary recovered from mix hash
pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256, progpow: bool) -> H256 {
pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256) -> H256 {
unsafe {
if progpow {
let seed = keccak_f800_short(*header_hash, nonce, [0u32; 8]);
keccak_f800_long(*header_hash, seed, mem::transmute(*mix_hash))
} else {
// This is safe - the `keccak_512` call below reads the first 40 bytes (which we explicitly set
// with two `copy_nonoverlapping` calls) but writes the first 64, and then we explicitly write
// the next 32 bytes before we read the whole thing with `keccak_256`.
//
// This cannot be elided by the compiler as it doesn't know the implementation of
// `keccak_512`.
let mut buf: [u8; 64 + 32] = mem::uninitialized();
// This is safe - the `keccak_512` call below reads the first 40 bytes (which we explicitly set
// with two `copy_nonoverlapping` calls) but writes the first 64, and then we explicitly write
// the next 32 bytes before we read the whole thing with `keccak_256`.
//
// This cannot be elided by the compiler as it doesn't know the implementation of
// `keccak_512`.
let mut buf: [u8; 64 + 32] = mem::uninitialized();
ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32);
ptr::copy_nonoverlapping(&nonce as *const u64 as *const u8, buf[32..].as_mut_ptr(), 8);
ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32);
ptr::copy_nonoverlapping(&nonce as *const u64 as *const u8, buf[32..].as_mut_ptr(), 8);
keccak_512::unchecked(buf.as_mut_ptr(), 64, buf.as_ptr(), 40);
ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32);
keccak_512::unchecked(buf.as_mut_ptr(), 64, buf.as_ptr(), 40);
ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32);
// This is initialized in `keccak_256`
let mut hash: [u8; 32] = mem::uninitialized();
keccak_256::unchecked(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len());
// This is initialized in `keccak_256`
let mut hash: [u8; 32] = mem::uninitialized();
keccak_256::unchecked(hash.as_mut_ptr(), hash.len(), buf.as_ptr(), buf.len());
hash
}
hash
}
}
@@ -307,7 +272,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
// We overwrite the second half since `keccak_256` has an internal buffer and so allows
// overlapping arrays as input.
let write_ptr: *mut u8 = &mut buf.compress_bytes as *mut [u8; 32] as *mut u8;
unsafe {
unsafe {
keccak_256::unchecked(
write_ptr,
buf.compress_bytes.len(),
@@ -322,7 +287,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
}
// TODO: Use the `simd` crate
pub fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node {
fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node {
let num_parent_nodes = cache.len();
let mut ret = cache[node_index as usize % num_parent_nodes].clone();
ret.as_words_mut()[0] ^= node_index;
@@ -396,13 +361,13 @@ mod test {
0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a,
0xe9, 0x7e, 0x53, 0x84,
];
assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash, false)[..], boundary_good[..]);
assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash)[..], boundary_good[..]);
let boundary_bad = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2,
0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a,
0xe9, 0x7e, 0x53, 0x84,
];
assert!(quick_get_difficulty(&hash, nonce, &mix_hash, false)[..] != boundary_bad[..]);
assert!(quick_get_difficulty(&hash, nonce, &mix_hash)[..] != boundary_bad[..]);
}
#[test]
@@ -426,7 +391,7 @@ mod test {
let tempdir = TempDir::new("").unwrap();
// difficulty = 0x085657254bd9u64;
let light = NodeCacheBuilder::new(None, u64::max_value()).light(tempdir.path(), 486382);
let light = NodeCacheBuilder::new(None).light(tempdir.path(), 486382);
let result = light_compute(&light, &hash, nonce);
assert_eq!(result.mix_hash[..], mix_hash[..]);
assert_eq!(result.value[..], boundary[..]);
@@ -435,7 +400,7 @@ mod test {
#[test]
fn test_drop_old_data() {
let tempdir = TempDir::new("").unwrap();
let builder = NodeCacheBuilder::new(None, u64::max_value());
let builder = NodeCacheBuilder::new(None);
let first = builder.light(tempdir.path(), 0).to_file().unwrap().to_owned();
let second = builder.light(tempdir.path(), ETHASH_EPOCH_LENGTH).to_file().unwrap().to_owned();

View File

@@ -25,41 +25,26 @@ extern crate crunchy;
#[macro_use]
extern crate log;
#[cfg(test)]
extern crate rustc_hex;
#[cfg(test)]
extern crate serde_json;
#[cfg(test)]
extern crate tempdir;
#[cfg(feature = "bench")]
pub mod compute;
#[cfg(not(feature = "bench"))]
mod compute;
mod seed_compute;
mod cache;
mod keccak;
mod shared;
#[cfg(feature = "bench")]
pub mod progpow;
#[cfg(not(feature = "bench"))]
mod progpow;
pub use cache::{NodeCacheBuilder, OptimizeFor};
pub use compute::{ProofOfWork, quick_get_difficulty, slow_hash_block_number};
use compute::Light;
use ethereum_types::{BigEndianHash, U256, U512};
use ethereum_types::{U256, U512};
use keccak::H256;
use parking_lot::Mutex;
pub use seed_compute::SeedHashCompute;
pub use shared::ETHASH_EPOCH_LENGTH;
use std::mem;
use std::path::{Path, PathBuf};
use std::convert::TryFrom;
use std::sync::Arc;
struct LightCache {
@@ -74,16 +59,14 @@ pub struct EthashManager {
nodecache_builder: NodeCacheBuilder,
cache: Mutex<LightCache>,
cache_dir: PathBuf,
progpow_transition: u64,
}
impl EthashManager {
/// Create a new new instance of ethash manager
pub fn new<T: Into<Option<OptimizeFor>>>(cache_dir: &Path, optimize_for: T, progpow_transition: u64) -> EthashManager {
pub fn new<T: Into<Option<OptimizeFor>>>(cache_dir: &Path, optimize_for: T) -> EthashManager {
EthashManager {
cache_dir: cache_dir.to_path_buf(),
nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default(), progpow_transition),
progpow_transition: progpow_transition,
nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default()),
cache: Mutex::new(LightCache {
recent_epoch: None,
recent: None,
@@ -102,33 +85,27 @@ impl EthashManager {
let epoch = block_number / ETHASH_EPOCH_LENGTH;
let light = {
let mut lights = self.cache.lock();
let light = if block_number == self.progpow_transition {
// we need to regenerate the cache to trigger algorithm change to progpow inside `Light`
None
} else {
match lights.recent_epoch.clone() {
Some(ref e) if *e == epoch => lights.recent.clone(),
_ => match lights.prev_epoch.clone() {
Some(e) if e == epoch => {
// don't swap if recent is newer.
if lights.recent_epoch > lights.prev_epoch {
None
} else {
// swap
let t = lights.prev_epoch;
lights.prev_epoch = lights.recent_epoch;
lights.recent_epoch = t;
let t = lights.prev.clone();
lights.prev = lights.recent.clone();
lights.recent = t;
lights.recent.clone()
}
let light = match lights.recent_epoch.clone() {
Some(ref e) if *e == epoch => lights.recent.clone(),
_ => match lights.prev_epoch.clone() {
Some(e) if e == epoch => {
// don't swap if recent is newer.
if lights.recent_epoch > lights.prev_epoch {
None
} else {
// swap
let t = lights.prev_epoch;
lights.prev_epoch = lights.recent_epoch;
lights.recent_epoch = t;
let t = lights.prev.clone();
lights.prev = lights.recent.clone();
lights.recent = t;
lights.recent.clone()
}
_ => None,
},
}
}
_ => None,
},
};
match light {
None => {
let light = match self.nodecache_builder.light_from_file(
@@ -155,18 +132,18 @@ impl EthashManager {
Some(light) => light,
}
};
light.compute(header_hash, nonce, block_number)
light.compute(header_hash, nonce)
}
}
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
pub fn boundary_to_difficulty(boundary: &ethereum_types::H256) -> U256 {
difficulty_to_boundary_aux(&boundary.into_uint())
difficulty_to_boundary_aux(&**boundary)
}
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
pub fn difficulty_to_boundary(difficulty: &U256) -> ethereum_types::H256 {
BigEndianHash::from_uint(&difficulty_to_boundary_aux(difficulty))
difficulty_to_boundary_aux(difficulty).into()
}
fn difficulty_to_boundary_aux<T: Into<U512>>(difficulty: T) -> ethereum_types::U256 {
@@ -177,8 +154,8 @@ fn difficulty_to_boundary_aux<T: Into<U512>>(difficulty: T) -> ethereum_types::U
if difficulty == U512::one() {
U256::max_value()
} else {
const PROOF: &str = "difficulty > 1, so result never overflows 256 bits; qed";
U256::try_from((U512::one() << 256) / difficulty).expect(PROOF)
// difficulty > 1, so result should never overflow 256 bits
U256::from((U512::one() << 256) / difficulty)
}
}
@@ -187,7 +164,7 @@ fn test_lru() {
use tempdir::TempDir;
let tempdir = TempDir::new("").unwrap();
let ethash = EthashManager::new(tempdir.path(), None, u64::max_value());
let ethash = EthashManager::new(tempdir.path(), None);
let hash = [0u8; 32];
ethash.compute_light(1, &hash, 1);
ethash.compute_light(50000, &hash, 1);
@@ -203,10 +180,10 @@ fn test_lru() {
#[test]
fn test_difficulty_to_boundary() {
use ethereum_types::{H256, BigEndianHash};
use ethereum_types::H256;
use std::str::FromStr;
assert_eq!(difficulty_to_boundary(&U256::from(1)), BigEndianHash::from_uint(&U256::max_value()));
assert_eq!(difficulty_to_boundary(&U256::from(1)), H256::from(U256::max_value()));
assert_eq!(difficulty_to_boundary(&U256::from(2)), H256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(difficulty_to_boundary(&U256::from(4)), H256::from_str("4000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap());
@@ -220,18 +197,9 @@ fn test_difficulty_to_boundary_regression() {
// https://github.com/paritytech/parity-ethereum/issues/8397
for difficulty in 1..9 {
assert_eq!(U256::from(difficulty), boundary_to_difficulty(&difficulty_to_boundary(&difficulty.into())));
assert_eq!(
H256::from_low_u64_be(difficulty),
difficulty_to_boundary(&boundary_to_difficulty(&H256::from_low_u64_be(difficulty))),
);
assert_eq!(
U256::from(difficulty),
boundary_to_difficulty(&BigEndianHash::from_uint(&boundary_to_difficulty(&H256::from_low_u64_be(difficulty)))),
);
assert_eq!(
H256::from_low_u64_be(difficulty),
difficulty_to_boundary(&difficulty_to_boundary(&difficulty.into()).into_uint()),
);
assert_eq!(H256::from(difficulty), difficulty_to_boundary(&boundary_to_difficulty(&difficulty.into())));
assert_eq!(U256::from(difficulty), boundary_to_difficulty(&boundary_to_difficulty(&difficulty.into()).into()));
assert_eq!(H256::from(difficulty), difficulty_to_boundary(&difficulty_to_boundary(&difficulty.into()).into()));
}
}
@@ -244,5 +212,5 @@ fn test_difficulty_to_boundary_panics_on_zero() {
#[test]
#[should_panic]
fn test_boundary_to_difficulty_panics_on_zero() {
boundary_to_difficulty(&ethereum_types::H256::zero());
boundary_to_difficulty(&ethereum_types::H256::from(0));
}

View File

@@ -1,611 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! ProgPoW (Programmatic Proof-of-Work) is the Ethereum network's proposed new Application-Specific Integrated
//! Circuit (ASIC) resistant Proof-of-Work mining algorithm.
//!
//! ProgPoW's aim is to reduce the efficiencies of specialized mining devices known as ASIC chips
//! (and accelerated GPU-based setups), and to maximize the performance of General Purpose Hardware (GPUs) to enable
//! more users to compete for new cryptocurrency awarded by the protocol.
//!
//! ASIC chips are those that are tailored to efficiently mining cryptocurrency based on a specific hashing algorithm.
//!
//! GPU mining setups are less specialised are struggle to compete for mining rewards.
//!
//! It would be a change from Ethereum's current PoW mining algorithm known as Ethash.
//!
//! ProgPoW audits have been proposed to analyse the efficiency of a ProgPoW ASICs over
//! GPUs and analysis of the economic impact on the Ethereum protocol.
use compute::{FNV_PRIME, calculate_dag_item};
use keccak::H256;
use shared::{ETHASH_ACCESSES, ETHASH_MIX_BYTES, Node, get_data_size};
const PROGPOW_CACHE_BYTES: usize = 16 * 1024;
const PROGPOW_CACHE_WORDS: usize = PROGPOW_CACHE_BYTES / 4;
const PROGPOW_CNT_CACHE: usize = 12;
const PROGPOW_CNT_MATH: usize = 20;
const PROGPOW_CNT_DAG: usize = ETHASH_ACCESSES;
const PROGPOW_DAG_LOADS: usize = 4;
const PROGPOW_MIX_BYTES: usize = 2 * ETHASH_MIX_BYTES;
const PROGPOW_PERIOD_LENGTH: usize = 50; // blocks per progpow epoch (N)
const PROGPOW_LANES: usize = 16;
const PROGPOW_REGS: usize = 32;
const FNV_HASH: u32 = 0x811c9dc5;
const KECCAKF_RNDC: [u32; 24] = [
0x00000001, 0x00008082, 0x0000808a, 0x80008000, 0x0000808b, 0x80000001,
0x80008081, 0x00008009, 0x0000008a, 0x00000088, 0x80008009, 0x8000000a,
0x8000808b, 0x0000008b, 0x00008089, 0x00008003, 0x00008002, 0x00000080,
0x0000800a, 0x8000000a, 0x80008081, 0x00008080, 0x80000001, 0x80008008
];
const KECCAKF_ROTC: [u32; 24] = [
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
];
const KECCAKF_PILN: [usize; 24] = [
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
];
fn keccak_f800_round(st: &mut [u32; 25], r: usize) {
// Theta
let mut bc = [0u32; 5];
for i in 0..bc.len() {
bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
}
for i in 0..bc.len() {
let t = bc[(i + 4) % 5] ^ bc[(i + 1) % 5].rotate_left(1);
for j in (0..st.len()).step_by(5) {
st[j + i] ^= t;
}
}
// Rho Pi
let mut t = st[1];
debug_assert_eq!(KECCAKF_ROTC.len(), 24);
for i in 0..24 {
let j = KECCAKF_PILN[i];
bc[0] = st[j];
st[j] = t.rotate_left(KECCAKF_ROTC[i]);
t = bc[0];
}
// Chi
for j in (0..st.len()).step_by(5) {
for i in 0..bc.len() {
bc[i] = st[j + i];
}
for i in 0..bc.len() {
st[j + i] ^= (!bc[(i + 1) % 5]) & bc[(i + 2) % 5];
}
}
// Iota
debug_assert!(r < KECCAKF_RNDC.len());
st[0] ^= KECCAKF_RNDC[r];
}
fn keccak_f800(header_hash: H256, nonce: u64, result: [u32; 8], st: &mut [u32; 25]) {
for i in 0..8 {
st[i] = (header_hash[4 * i] as u32) +
((header_hash[4 * i + 1] as u32) << 8) +
((header_hash[4 * i + 2] as u32) << 16) +
((header_hash[4 * i + 3] as u32) << 24);
}
st[8] = nonce as u32;
st[9] = (nonce >> 32) as u32;
for i in 0..8 {
st[10 + i] = result[i];
}
for r in 0..22 {
keccak_f800_round(st, r);
}
}
pub fn keccak_f800_short(header_hash: H256, nonce: u64, result: [u32; 8]) -> u64 {
let mut st = [0u32; 25];
keccak_f800(header_hash, nonce, result, &mut st);
(st[0].swap_bytes() as u64) << 32 | st[1].swap_bytes() as u64
}
pub fn keccak_f800_long(header_hash: H256, nonce: u64, result: [u32; 8]) -> H256 {
let mut st = [0u32; 25];
keccak_f800(header_hash, nonce, result, &mut st);
// NOTE: transmute from `[u32; 8]` to `[u8; 32]`
unsafe {
std::mem::transmute(
[st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7]]
)
}
}
#[inline]
fn fnv1a_hash(h: u32, d: u32) -> u32 {
(h ^ d).wrapping_mul(FNV_PRIME)
}
#[derive(Clone)]
struct Kiss99 {
z: u32,
w: u32,
jsr: u32,
jcong: u32,
}
impl Kiss99 {
fn new(z: u32, w: u32, jsr: u32, jcong: u32) -> Kiss99 {
Kiss99 { z, w, jsr, jcong }
}
#[inline]
fn next_u32(&mut self) -> u32 {
self.z = 36969u32.wrapping_mul(self.z & 65535).wrapping_add(self.z >> 16);
self.w = 18000u32.wrapping_mul(self.w & 65535).wrapping_add(self.w >> 16);
let mwc = (self.z << 16).wrapping_add(self.w);
self.jsr ^= self.jsr << 17;
self.jsr ^= self.jsr >> 13;
self.jsr ^= self.jsr << 5;
self.jcong = 69069u32.wrapping_mul(self.jcong).wrapping_add(1234567);
(mwc ^ self.jcong).wrapping_add(self.jsr)
}
}
fn fill_mix(seed: u64, lane_id: u32) -> [u32; PROGPOW_REGS] {
// Use FNV to expand the per-warp seed to per-lane
// Use KISS to expand the per-lane seed to fill mix
let z = fnv1a_hash(FNV_HASH, seed as u32);
let w = fnv1a_hash(z, (seed >> 32) as u32);
let jsr = fnv1a_hash(w, lane_id);
let jcong = fnv1a_hash(jsr, lane_id);
let mut rnd = Kiss99::new(z, w, jsr, jcong);
let mut mix = [0; PROGPOW_REGS];
debug_assert_eq!(PROGPOW_REGS, 32);
for i in 0..32 {
mix[i] = rnd.next_u32();
}
mix
}
// Merge new data from b into the value in a. Assuming A has high entropy only
// do ops that retain entropy even if B is low entropy (IE don't do A&B)
fn merge(a: u32, b: u32, r: u32) -> u32 {
match r % 4 {
0 => a.wrapping_mul(33).wrapping_add(b),
1 => (a ^ b).wrapping_mul(33),
2 => a.rotate_left(((r >> 16) % 31) + 1) ^ b,
_ => a.rotate_right(((r >> 16) % 31) + 1) ^ b,
}
}
fn math(a: u32, b: u32, r: u32) -> u32 {
match r % 11 {
0 => a.wrapping_add(b),
1 => a.wrapping_mul(b),
2 => ((a as u64).wrapping_mul(b as u64) >> 32) as u32,
3 => a.min(b),
4 => a.rotate_left(b),
5 => a.rotate_right(b),
6 => a & b,
7 => a | b,
8 => a ^ b,
9 => a.leading_zeros() + b.leading_zeros(),
_ => a.count_ones() + b.count_ones(),
}
}
fn progpow_init(seed: u64) -> (Kiss99, [u32; PROGPOW_REGS], [u32; PROGPOW_REGS]) {
let z = fnv1a_hash(FNV_HASH, seed as u32);
let w = fnv1a_hash(z, (seed >> 32) as u32);
let jsr = fnv1a_hash(w, seed as u32);
let jcong = fnv1a_hash(jsr, (seed >> 32) as u32);
let mut rnd = Kiss99::new(z, w, jsr, jcong);
// Create a random sequence of mix destinations for merge() and mix sources
// for cache reads guarantees every destination merged once and guarantees
// no duplicate cache reads, which could be optimized away. Uses
// Fisher-Yates shuffle.
let mut mix_seq_dst = [0u32; PROGPOW_REGS];
let mut mix_seq_cache = [0u32; PROGPOW_REGS];
for i in 0..mix_seq_dst.len() {
mix_seq_dst[i] = i as u32;
mix_seq_cache[i] = i as u32;
}
for i in (1..mix_seq_dst.len()).rev() {
let j = rnd.next_u32() as usize % (i + 1);
mix_seq_dst.swap(i, j);
let j = rnd.next_u32() as usize % (i + 1);
mix_seq_cache.swap(i, j);
}
(rnd, mix_seq_dst, mix_seq_cache)
}
pub type CDag = [u32; PROGPOW_CACHE_WORDS];
fn progpow_loop(
seed: u64,
loop_: usize,
mix: &mut [[u32; PROGPOW_REGS]; PROGPOW_LANES],
cache: &[Node],
c_dag: &CDag,
data_size: usize,
) {
// All lanes share a base address for the global load. Global offset uses
// mix[0] to guarantee it depends on the load result.
let g_offset = mix[loop_ % PROGPOW_LANES][0] as usize %
(64 * data_size / (PROGPOW_LANES * PROGPOW_DAG_LOADS));
// 256 bytes of dag data
let mut dag_item = [0u32; 64];
// Fetch DAG nodes (64 bytes each)
for l in 0..PROGPOW_DAG_LOADS {
let index = g_offset * PROGPOW_LANES * PROGPOW_DAG_LOADS + l * 16;
let node = calculate_dag_item(index as u32 / 16, cache);
dag_item[l * 16..(l + 1) * 16].clone_from_slice(node.as_words());
}
let (rnd, mix_seq_dst, mix_seq_cache) = progpow_init(seed);
// Lanes can execute in parallel and will be convergent
for l in 0..mix.len() {
let mut rnd = rnd.clone();
// Initialize the seed and mix destination sequence
let mut mix_seq_dst_cnt = 0;
let mut mix_seq_cache_cnt = 0;
let mut mix_dst = || {
let res = mix_seq_dst[mix_seq_dst_cnt % PROGPOW_REGS] as usize;
mix_seq_dst_cnt += 1;
res
};
let mut mix_cache = || {
let res = mix_seq_cache[mix_seq_cache_cnt % PROGPOW_REGS] as usize;
mix_seq_cache_cnt += 1;
res
};
for i in 0..PROGPOW_CNT_CACHE.max(PROGPOW_CNT_MATH) {
if i < PROGPOW_CNT_CACHE {
// Cached memory access, lanes access random 32-bit locations
// within the first portion of the DAG
let offset = mix[l][mix_cache()] as usize % PROGPOW_CACHE_WORDS;
let data = c_dag[offset];
let dst = mix_dst();
mix[l][dst] = merge(mix[l][dst], data, rnd.next_u32());
}
if i < PROGPOW_CNT_MATH {
// Random math
// Generate 2 unique sources
let src_rnd = rnd.next_u32() % (PROGPOW_REGS * (PROGPOW_REGS - 1)) as u32;
let src1 = src_rnd % PROGPOW_REGS as u32; // 0 <= src1 < PROGPOW_REGS
let mut src2 = src_rnd / PROGPOW_REGS as u32; // 0 <= src2 < PROGPOW_REGS - 1
if src2 >= src1 {
src2 += 1; // src2 is now any reg other than src1
}
let data = math(mix[l][src1 as usize], mix[l][src2 as usize], rnd.next_u32());
let dst = mix_dst();
mix[l][dst] = merge(mix[l][dst], data, rnd.next_u32());
}
}
// Global load to sequential locations
let mut data_g = [0u32; PROGPOW_DAG_LOADS];
let index = ((l ^ loop_) % PROGPOW_LANES) * PROGPOW_DAG_LOADS;
for i in 0..PROGPOW_DAG_LOADS {
data_g[i] = dag_item[index + i];
}
// Consume the global load data at the very end of the loop to allow
// full latency hiding. Always merge into `mix[0]` to feed the offset
// calculation.
mix[l][0] = merge(mix[l][0], data_g[0], rnd.next_u32());
for i in 1..PROGPOW_DAG_LOADS {
let dst = mix_dst();
mix[l][dst] = merge(mix[l][dst], data_g[i], rnd.next_u32());
}
}
}
pub fn progpow(
header_hash: H256,
nonce: u64,
block_number: u64,
cache: &[Node],
c_dag: &CDag,
) -> (H256, H256) {
let mut mix = [[0u32; PROGPOW_REGS]; PROGPOW_LANES];
let mut lane_results = [0u32; PROGPOW_LANES];
let mut result = [0u32; 8];
let data_size = get_data_size(block_number) / PROGPOW_MIX_BYTES;
// NOTE: This assert is required to aid the optimizer elide the non-zero
// remainder check in `progpow_loop`.
assert!(data_size > 0);
// Initialize mix for all lanes
let seed = keccak_f800_short(header_hash, nonce, result);
for l in 0..mix.len() {
mix[l] = fill_mix(seed, l as u32);
}
// Execute the randomly generated inner loop
let period = block_number / PROGPOW_PERIOD_LENGTH as u64;
for i in 0..PROGPOW_CNT_DAG {
progpow_loop(
period,
i,
&mut mix,
cache,
c_dag,
data_size,
);
}
// Reduce mix data to a single per-lane result
for l in 0..lane_results.len() {
lane_results[l] = FNV_HASH;
for i in 0..PROGPOW_REGS {
lane_results[l] = fnv1a_hash(lane_results[l], mix[l][i]);
}
}
// Reduce all lanes to a single 128-bit result
result = [FNV_HASH; 8];
for l in 0..PROGPOW_LANES {
result[l % 8] = fnv1a_hash(result[l % 8], lane_results[l]);
}
let digest = keccak_f800_long(header_hash, seed, result);
// NOTE: transmute from `[u32; 8]` to `[u8; 32]`
let result = unsafe { ::std::mem::transmute(result) };
(digest, result)
}
pub fn generate_cdag(cache: &[Node]) -> CDag {
let mut c_dag = [0u32; PROGPOW_CACHE_WORDS];
for i in 0..PROGPOW_CACHE_WORDS / 16 {
let node = calculate_dag_item(i as u32, cache);
for j in 0..16 {
c_dag[i * 16 + j] = node.as_words()[j];
}
}
c_dag
}
#[cfg(test)]
mod test {
use tempdir::TempDir;
use cache::{NodeCacheBuilder, OptimizeFor};
use keccak::H256;
use rustc_hex::FromHex;
use serde_json::{self, Value};
use std::collections::VecDeque;
use super::*;
fn h256(hex: &str) -> H256 {
let bytes = FromHex::from_hex(hex).unwrap();
let mut res = [0; 32];
res.copy_from_slice(&bytes);
res
}
#[test]
fn test_cdag() {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let cache = builder.new_cache(tempdir.into_path(), 0);
let c_dag = generate_cdag(cache.as_ref());
let expected = vec![
690150178u32, 1181503948, 2248155602, 2118233073, 2193871115,
1791778428, 1067701239, 724807309, 530799275, 3480325829, 3899029234,
1998124059, 2541974622, 1100859971, 1297211151, 3268320000, 2217813733,
2690422980, 3172863319, 2651064309
];
assert_eq!(
c_dag.iter().take(20).cloned().collect::<Vec<_>>(),
expected,
);
}
#[test]
fn test_random_merge() {
let tests = [
(1000000u32, 101u32, 33000101u32),
(2000000, 102, 66003366),
(3000000, 103, 6000103),
(4000000, 104, 2000104),
(1000000, 0, 33000000),
(2000000, 0, 66000000),
(3000000, 0, 6000000),
(4000000, 0, 2000000),
];
for (i, &(a, b, expected)) in tests.iter().enumerate() {
assert_eq!(
merge(a, b, i as u32),
expected,
);
}
}
#[test]
fn test_random_math() {
let tests = [
(20u32, 22u32, 42u32),
(70000, 80000, 1305032704),
(70000, 80000, 1),
(1, 2, 1),
(3, 10000, 196608),
(3, 0, 3),
(3, 6, 2),
(3, 6, 7),
(3, 6, 5),
(0, 0xffffffff, 32),
(3 << 13, 1 << 5, 3),
(22, 20, 42),
(80000, 70000, 1305032704),
(80000, 70000, 1),
(2, 1, 1),
(10000, 3, 80000),
(0, 3, 0),
(6, 3, 2),
(6, 3, 7),
(6, 3, 5),
(0, 0xffffffff, 32),
(3 << 13, 1 << 5, 3),
];
for (i, &(a, b, expected)) in tests.iter().enumerate() {
assert_eq!(
math(a, b, i as u32),
expected,
);
}
}
#[test]
fn test_keccak_256() {
let expected = "5dd431e5fbc604f499bfa0232f45f8f142d0ff5178f539e5a7800bf0643697af";
assert_eq!(
keccak_f800_long([0; 32], 0, [0; 8]),
h256(expected),
);
}
#[test]
fn test_keccak_64() {
let expected: u64 = 0x5dd431e5fbc604f4;
assert_eq!(
keccak_f800_short([0; 32], 0, [0; 8]),
expected,
);
}
#[test]
fn test_progpow_hash() {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let cache = builder.new_cache(tempdir.into_path(), 0);
let c_dag = generate_cdag(cache.as_ref());
let header_hash = [0; 32];
let (digest, result) = progpow(
header_hash,
0,
0,
cache.as_ref(),
&c_dag,
);
let expected_digest = FromHex::from_hex("63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b").unwrap();
let expected_result = FromHex::from_hex("faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3").unwrap();
assert_eq!(
digest.to_vec(),
expected_digest,
);
assert_eq!(
result.to_vec(),
expected_result,
);
}
#[test]
fn test_progpow_testvectors() {
struct ProgpowTest {
block_number: u64,
header_hash: H256,
nonce: u64,
mix_hash: H256,
final_hash: H256,
}
let tests: Vec<VecDeque<Value>> =
serde_json::from_slice(include_bytes!("../res/progpow_testvectors.json")).unwrap();
let tests: Vec<ProgpowTest> = tests.into_iter().map(|mut test: VecDeque<Value>| {
assert!(test.len() == 5);
let block_number: u64 = serde_json::from_value(test.pop_front().unwrap()).unwrap();
let header_hash: String = serde_json::from_value(test.pop_front().unwrap()).unwrap();
let nonce: String = serde_json::from_value(test.pop_front().unwrap()).unwrap();
let mix_hash: String = serde_json::from_value(test.pop_front().unwrap()).unwrap();
let final_hash: String = serde_json::from_value(test.pop_front().unwrap()).unwrap();
ProgpowTest {
block_number,
header_hash: h256(&header_hash),
nonce: u64::from_str_radix(&nonce, 16).unwrap(),
mix_hash: h256(&mix_hash),
final_hash: h256(&final_hash),
}
}).collect();
for test in tests {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let cache = builder.new_cache(tempdir.path().to_owned(), test.block_number);
let c_dag = generate_cdag(cache.as_ref());
let (digest, result) = progpow(
test.header_hash,
test.nonce,
test.block_number,
cache.as_ref(),
&c_dag,
);
assert_eq!(digest, test.final_hash);
assert_eq!(result, test.mix_hash);
}
}
}

View File

@@ -1,5 +1,5 @@
[package]
description = "Parity Ethereum (EthCore) Library"
description = "Ethcore library"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "ethcore"
@@ -7,86 +7,85 @@ version = "1.12.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
account-db = { path = "account-db" }
ansi_term = "0.11"
ansi_term = "0.10"
blooms-db = { path = "../util/blooms-db", optional = true }
bn = { git = "https://github.com/paritytech/bn", default-features = false }
byteorder = "1.0"
common-types = { path = "types" }
crossbeam-utils = "0.6"
derive_more = "0.14.0"
crossbeam = "0.4"
env_logger = { version = "0.5", optional = true }
ethabi = "8.0"
ethabi-contract = "8.0"
ethabi-derive = "8.0"
error-chain = { version = "0.12", default-features = false }
ethabi = "6.0"
ethabi-contract = "6.0"
ethabi-derive = "6.0"
ethash = { path = "../ethash" }
ethcore-blockchain = { path = "./blockchain" }
ethcore-bloom-journal = { path = "../util/bloom" }
ethcore-builtin = { path = "./builtin" }
ethcore-call-contract = { path = "./call-contract" }
ethcore-db = { path = "./db" }
ethcore-io = { path = "../util/io" }
ethcore-miner = { path = "../miner" }
ethcore-stratum = { path = "../miner/stratum", optional = true }
ethereum-types = "0.6.0"
ethereum-types = "0.4"
ethjson = { path = "../json" }
ethkey = { path = "../accounts/ethkey" }
ethstore = { path = "../accounts/ethstore" }
evm = { path = "evm" }
futures = "0.1"
hash-db = "0.12.4"
parity-util-mem = "0.1"
hashdb = "0.3.0"
heapsize = "0.4"
itertools = "0.5"
journaldb = { path = "../util/journaldb" }
keccak-hash = "0.2.0"
keccak-hash = "0.1"
keccak-hasher = { path = "../util/keccak-hasher" }
kvdb = "0.1"
kvdb-memorydb = "0.1"
kvdb-rocksdb = { version = "0.1.3", optional = true }
lazy_static = "1.2.0"
lazy_static = "1.0"
len-caching-lock = { path = "../util/len-caching-lock" }
log = "0.4"
lru-cache = "0.1"
macros = { path = "../util/macros" }
memory-cache = { path = "../util/memory-cache" }
memory-db = "0.12.4"
memorydb = "0.3.0"
num = { version = "0.1", default-features = false, features = ["bigint"] }
num_cpus = "1.2"
parity-bytes = "0.1"
parity-crypto = "0.2"
parity-machine = { path = "../machine" }
parity-snappy = "0.1"
parking_lot = "0.7"
pod-account = { path = "pod-account" }
trie-db = "0.12.4"
patricia-trie = "0.3.0"
patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" }
rand = "0.6"
rayon = "1.1"
rlp = "0.4.0"
rand = "0.4"
rayon = "1.0"
rlp = { version = "0.3.0", features = ["ethereum"] }
rlp_derive = { path = "../util/rlp-derive" }
rustc-hex = "1.0"
serde = "1.0"
serde_derive = "1.0"
state-account = { path = "state-account" }
stats = { path = "../util/stats" }
tempdir = { version = "0.3", optional = true }
time-utils = { path = "../util/time-utils" }
tempdir = {version="0.3", optional = true}
trace-time = "0.1"
triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" }
unexpected = { path = "../util/unexpected" }
using_queue = { path = "../miner/using-queue" }
vm = { path = "vm" }
wasm = { path = "wasm" }
rand_xorshift = "0.1.1"
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))'.dependencies]
hardware-wallet = { path = "../accounts/hw" }
[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android")))'.dependencies]
fake-hardware-wallet = { path = "../accounts/fake-hardware-wallet" }
[dev-dependencies]
blooms-db = { path = "../util/blooms-db" }
criterion = "0.2"
env_logger = "0.5"
ethcore-accounts = { path = "../accounts" }
ethjson = { path = "../json", features = ["test-helpers"] }
ethkey = { path = "../accounts/ethkey" }
fetch = { path = "../util/fetch" }
kvdb-rocksdb = "0.1.3"
parity-runtime = { path = "../util/runtime" }
rlp_compress = { path = "../util/rlp-compress" }
serde_json = "1.0"
tempdir = "0.3"
trie-standardmap = "0.12.4"
trie-standardmap = "0.1"
[features]
parity = ["work-notify", "price-info", "stratum"]
@@ -111,6 +110,8 @@ evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
slow-blocks = []
# Run JSON consensus tests.
json-tests = ["env_logger", "test-helpers", "to-pod-full"]
# Skip JSON consensus tests with pending issues.
ci-skip-issue = []
# Run memory/cpu heavy tests.
test-heavy = []
# Compile test helpers

View File

@@ -1,14 +0,0 @@
[package]
description = "DB backend wrapper for Account trie"
name = "account-db"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
ethereum-types = "0.6"
hash-db = "0.12.4"
keccak-hash = "0.2.0"
keccak-hasher = { path = "../../util/keccak-hasher" }
kvdb = "0.1"
rlp = "0.4"

View File

@@ -28,13 +28,13 @@ extern crate rustc_hex;
use criterion::{Criterion, Bencher};
use bytes::BytesRef;
use ethcore::builtin::Builtin;
use ethcore::machine::Machine;
use ethereum_types::H160;
use ethcore::machine::EthereumMachine;
use ethereum_types::U256;
use ethcore::ethereum::new_byzantium_test_machine;
use rustc_hex::FromHex;
lazy_static! {
static ref BYZANTIUM_MACHINE: Machine = new_byzantium_test_machine();
static ref BYZANTIUM_MACHINE: EthereumMachine = new_byzantium_test_machine();
}
struct BuiltinBenchmark<'a> {
@@ -46,9 +46,8 @@ struct BuiltinBenchmark<'a> {
impl<'a> BuiltinBenchmark<'a> {
fn new(builtin_address: &'static str, input: &str, expected: &str) -> BuiltinBenchmark<'a> {
let builtins = BYZANTIUM_MACHINE.builtins();
use std::str::FromStr;
let addr = H160::from_str(builtin_address).unwrap();
let builtin = builtins.get(&addr).unwrap().clone();
let builtin = builtins.get(&builtin_address.into()).unwrap().clone();
let input = FromHex::from_hex(input).unwrap();
let expected = FromHex::from_hex(expected).unwrap();
@@ -57,6 +56,10 @@ impl<'a> BuiltinBenchmark<'a> {
}
}
fn gas_cost(&self) -> U256 {
self.builtin.cost(&self.input)
}
fn run(&self, b: &mut Bencher) {
let mut output = vec![0; self.expected.len()];

View File

@@ -1,5 +1,5 @@
[package]
description = "Parity Ethereum Blockchain Database, Test Generator, Configuration, Caching, Importing Blocks, and Block Information"
description = "Ethcore blockchain database"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "ethcore-blockchain"
@@ -8,28 +8,26 @@ authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
ansi_term = "0.11"
ansi_term = "0.10"
blooms-db = { path = "../../util/blooms-db" }
common-types = { path = "../types" }
ethcore-db = { path = "../db" }
ethereum-types = "0.6.0"
keccak-hash = "0.2.0"
parity-util-mem = "0.1"
ethereum-types = "0.4"
heapsize = "0.4"
itertools = "0.5"
kvdb = "0.1"
log = "0.4"
parity-bytes = "0.1"
parking_lot = "0.7"
rand = "0.6"
rayon = "1.0"
rlp = "0.4.0"
rlp = { version = "0.3.0", features = ["ethereum"] }
rlp_compress = { path = "../../util/rlp-compress" }
rlp_derive = { path = "../../util/rlp-derive" }
triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" }
[dev-dependencies]
env_logger = "0.5"
ethkey = { path = "../../accounts/ethkey" }
keccak-hash = "0.1"
rustc-hex = "1.0"
tempdir = "0.3"
kvdb-memorydb = "0.1"

View File

@@ -24,8 +24,7 @@ use common_types::header::Header;
/// For GHOST fork-choice rule it would typically describe the block with highest
/// combined difficulty (usually the block with the highest block number).
///
/// Sometimes referred as 'latest block'.
#[derive(Debug)]
/// Sometimes refered as 'latest block'.
pub struct BestBlock {
/// Best block decoded header.
pub header: Header,
@@ -36,7 +35,7 @@ pub struct BestBlock {
}
/// Best ancient block info. If the blockchain has a gap this keeps track of where it starts.
#[derive(Debug, Default)]
#[derive(Default)]
pub struct BestAncientBlock {
/// Best block hash.
pub hash: H256,

View File

@@ -39,10 +39,10 @@ use ethcore_db::cache_manager::CacheManager;
use ethcore_db::keys::{BlockReceipts, BlockDetails, TransactionAddress, EPOCH_KEY_PREFIX, EpochTransitions};
use ethcore_db::{self as db, Writable, Readable, CacheUpdatePolicy};
use ethereum_types::{H256, Bloom, BloomRef, U256};
use util_mem::{MallocSizeOf, allocators::new_malloc_size_ops};
use heapsize::HeapSizeOf;
use itertools::Itertools;
use kvdb::{DBTransaction, KeyValueDB};
use log::{trace, debug, warn, info};
use log::{trace, warn, info};
use parity_bytes::Bytes;
use parking_lot::{Mutex, RwLock};
use rayon::prelude::*;
@@ -57,7 +57,7 @@ use crate::{CacheSize, ImportRoute, Config};
/// Database backing `BlockChain`.
pub trait BlockChainDB: Send + Sync {
/// Generic key value store.
fn key_value(&self) -> &Arc<dyn KeyValueDB>;
fn key_value(&self) -> &Arc<KeyValueDB>;
/// Header blooms database.
fn blooms(&self) -> &blooms_db::Database;
@@ -85,7 +85,7 @@ pub trait BlockChainDB: Send + Sync {
/// predefined config.
pub trait BlockChainDBHandler: Send + Sync {
/// Open the predefined key-value database.
fn open(&self, path: &Path) -> io::Result<Arc<dyn BlockChainDB>>;
fn open(&self, path: &Path) -> io::Result<Arc<BlockChainDB>>;
}
/// Interface for querying blocks by hash and by number.
@@ -228,7 +228,7 @@ pub struct BlockChain {
transaction_addresses: RwLock<HashMap<H256, TransactionAddress>>,
block_receipts: RwLock<HashMap<H256, BlockReceipts>>,
db: Arc<dyn BlockChainDB>,
db: Arc<BlockChainDB>,
cache_man: Mutex<CacheManager<CacheId>>,
@@ -284,7 +284,7 @@ impl BlockProvider for BlockChain {
}
// Read from DB and populate cache
let b = self.db.key_value().get(db::COL_HEADERS, hash.as_bytes())
let b = self.db.key_value().get(db::COL_HEADERS, hash)
.expect("Low level database error when fetching block header data. Some issue with disk?")?;
let header = encoded::Header::new(decompress(&b, blocks_swapper()).into_vec());
@@ -314,7 +314,7 @@ impl BlockProvider for BlockChain {
}
// Read from DB and populate cache
let b = self.db.key_value().get(db::COL_BODIES, hash.as_bytes())
let b = self.db.key_value().get(db::COL_BODIES, hash)
.expect("Low level database error when fetching block body data. Some issue with disk?")?;
let body = encoded::Body::new(decompress(&b, blocks_swapper()).into_vec());
@@ -469,7 +469,7 @@ impl<'a> Iterator for AncestryWithMetadataIter<'a> {
})
},
_ => {
self.current = H256::zero();
self.current = H256::default();
None
},
}
@@ -481,7 +481,7 @@ impl<'a> Iterator for AncestryWithMetadataIter<'a> {
/// Returns epoch transitions.
pub struct EpochTransitionIter<'a> {
chain: &'a BlockChain,
prefix_iter: Box<dyn Iterator<Item=(Box<[u8]>, Box<[u8]>)> + 'a>,
prefix_iter: Box<Iterator<Item=(Box<[u8]>, Box<[u8]>)> + 'a>,
}
impl<'a> Iterator for EpochTransitionIter<'a> {
@@ -521,7 +521,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> {
impl BlockChain {
/// Create new instance of blockchain from given Genesis.
pub fn new(config: Config, genesis: &[u8], db: Arc<dyn BlockChainDB>) -> BlockChain {
pub fn new(config: Config, genesis: &[u8], db: Arc<BlockChainDB>) -> BlockChain {
// 400 is the average size of the key
let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400);
@@ -572,13 +572,13 @@ impl BlockChain {
};
let mut batch = DBTransaction::new();
batch.put(db::COL_HEADERS, hash.as_bytes(), block.header_rlp().as_raw());
batch.put(db::COL_BODIES, hash.as_bytes(), &Self::block_to_body(genesis));
batch.put(db::COL_HEADERS, &hash, block.header_rlp().as_raw());
batch.put(db::COL_BODIES, &hash, &Self::block_to_body(genesis));
batch.write(db::COL_EXTRA, &hash, &details);
batch.write(db::COL_EXTRA, &header.number(), &hash);
batch.put(db::COL_EXTRA, b"best", hash.as_bytes());
batch.put(db::COL_EXTRA, b"best", &hash);
bc.db.key_value().write(batch).expect("Low level database error when fetching 'best' block. Some issue with disk?");
hash
}
@@ -639,7 +639,7 @@ impl BlockChain {
if hash != bc.genesis_hash() {
trace!("First block calculated: {:?}", hash);
let mut batch = db.key_value().transaction();
batch.put(db::COL_EXTRA, b"first", hash.as_bytes());
batch.put(db::COL_EXTRA, b"first", &hash);
db.key_value().write(batch).expect("Low level database error when writing 'first' block. Some issue with disk?");
bc.first_block = Some(hash);
}
@@ -652,7 +652,10 @@ impl BlockChain {
// and write them
if let (Some(hash), Some(number)) = (best_ancient, best_ancient_number) {
let mut best_ancient_block = bc.best_ancient_block.write();
*best_ancient_block = Some(BestAncientBlock { hash, number });
*best_ancient_block = Some(BestAncientBlock {
hash: hash,
number: number,
});
}
}
@@ -710,10 +713,6 @@ impl BlockChain {
///
/// If the tree route verges into pruned or unknown blocks,
/// `None` is returned.
///
/// `is_from_route_finalized` returns whether the `from` part of the
/// route contains a finalized block. This only holds if the two parts (from
/// and to) are on different branches, ie. on 2 different forks.
pub fn tree_route(&self, from: H256, to: H256) -> Option<TreeRoute> {
let mut from_branch = vec![];
let mut is_from_route_finalized = false;
@@ -727,9 +726,9 @@ impl BlockChain {
// reset from && to to the same level
while from_details.number > to_details.number {
from_branch.push(current_from);
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
current_from = from_details.parent.clone();
from_details = self.block_details(&from_details.parent)?;
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
}
while to_details.number > from_details.number {
@@ -743,9 +742,9 @@ impl BlockChain {
// move to shared parent
while current_from != current_to {
from_branch.push(current_from);
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
current_from = from_details.parent.clone();
from_details = self.block_details(&from_details.parent)?;
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
to_branch.push(current_to);
current_to = to_details.parent.clone();
@@ -759,8 +758,8 @@ impl BlockChain {
Some(TreeRoute {
blocks: from_branch,
ancestor: current_from,
index,
is_from_route_finalized,
index: index,
is_from_route_finalized: is_from_route_finalized,
})
}
@@ -789,8 +788,8 @@ impl BlockChain {
let compressed_body = compress(&Self::block_to_body(block.raw()), blocks_swapper());
// store block in db
batch.put(db::COL_HEADERS, hash.as_bytes(), &compressed_header);
batch.put(db::COL_BODIES, hash.as_bytes(), &compressed_body);
batch.put(db::COL_HEADERS, &hash, &compressed_header);
batch.put(db::COL_BODIES, &hash, &compressed_body);
let maybe_parent = self.block_details(&block_parent_hash);
@@ -855,14 +854,6 @@ impl BlockChain {
}
}
/// clears all caches for testing purposes
pub fn clear_cache(&self) {
self.block_bodies.write().clear();
self.block_details.write().clear();
self.block_hashes.write().clear();
self.block_headers.write().clear();
}
/// Update the best ancient block to the given hash, after checking that
/// it's directly linked to the currently known best ancient block
pub fn update_best_ancient_block(&self, hash: &H256) {
@@ -933,7 +924,7 @@ impl BlockChain {
*pending_best_ancient_block = Some(None);
} else if block_number > ancient_number {
trace!(target: "blockchain", "Updating the best ancient block to {}.", block_number);
batch.put(db::COL_EXTRA, b"ancient", block_hash.as_bytes());
batch.put(db::COL_EXTRA, b"ancient", &block_hash);
*pending_best_ancient_block = Some(Some(BestAncientBlock {
hash: *block_hash,
number: block_number,
@@ -964,7 +955,6 @@ impl BlockChain {
/// Iterate over all epoch transitions.
/// This will only return transitions within the canonical chain.
pub fn epoch_transitions(&self) -> EpochTransitionIter {
debug!(target: "blockchain", "Iterating over all epoch transitions");
let iter = self.db.key_value().iter_from_prefix(db::COL_EXTRA, &EPOCH_KEY_PREFIX[..]);
EpochTransitionIter {
chain: self,
@@ -990,9 +980,7 @@ impl BlockChain {
pub fn epoch_transition_for(&self, parent_hash: H256) -> Option<EpochTransition> {
// slow path: loop back block by block
for hash in self.ancestry_iter(parent_hash)? {
trace!(target: "blockchain", "Got parent hash {} from ancestry_iter", hash);
let details = self.block_details(&hash)?;
trace!(target: "blockchain", "Block #{}: Got block details for parent hash {}", details.number, hash);
// look for transition in database.
if let Some(transition) = self.epoch_transition(details.number, hash) {
@@ -1004,22 +992,11 @@ impl BlockChain {
//
// if `block_hash` is canonical it will only return transitions up to
// the parent.
match self.block_hash(details.number) {
Some(h) if h == hash => {
return self.epoch_transitions()
.map(|(_, t)| t)
.take_while(|t| t.block_number <= details.number)
.last()
},
Some(h) => {
warn!(target: "blockchain", "Block #{}: Found non-canonical block hash {} (expected {})", details.number, h, hash);
trace!(target: "blockchain", "Block #{} Mismatched hashes. Ancestor {} != Own {}", details.number, hash, h);
trace!(target: "blockchain", " Ancestor {}: #{:#?}", hash, details);
trace!(target: "blockchain", " Own {}: #{:#?}", h, self.block_details(&h));
},
None => trace!(target: "blockchain", "Block #{}: hash {} not found in cache or DB", details.number, hash),
if self.block_hash(details.number)? == hash {
return self.epoch_transitions()
.map(|(_, t)| t)
.take_while(|t| t.block_number <= details.number)
.last()
}
}
@@ -1087,8 +1064,8 @@ impl BlockChain {
let compressed_body = compress(&Self::block_to_body(block.raw()), blocks_swapper());
// store block in db
batch.put(db::COL_HEADERS, hash.as_bytes(), &compressed_header);
batch.put(db::COL_BODIES, hash.as_bytes(), &compressed_body);
batch.put(db::COL_HEADERS, &hash, &compressed_header);
batch.put(db::COL_BODIES, &hash, &compressed_body);
let info = self.block_info(&block.header_view(), route, &extras);
@@ -1187,7 +1164,7 @@ impl BlockChain {
{
let mut best_block = self.pending_best_block.write();
if is_best && update.info.location != BlockLocation::Branch {
batch.put(db::COL_EXTRA, b"best", update.info.hash.as_bytes());
batch.put(db::COL_EXTRA, b"best", &update.info.hash);
*best_block = Some(BestBlock {
total_difficulty: update.info.total_difficulty,
header: update.block.decode_header(),
@@ -1274,7 +1251,7 @@ impl BlockChain {
current: if self.is_known(&first) {
first
} else {
H256::zero() // zero hash
H256::default() // zero hash
},
chain: self
}
@@ -1490,12 +1467,11 @@ impl BlockChain {
/// Get current cache size.
pub fn cache_size(&self) -> CacheSize {
let mut ops = new_malloc_size_ops();
CacheSize {
blocks: self.block_headers.size_of(&mut ops) + self.block_bodies.size_of(&mut ops),
block_details: self.block_details.size_of(&mut ops),
transaction_addresses: self.transaction_addresses.size_of(&mut ops),
block_receipts: self.block_receipts.size_of(&mut ops),
blocks: self.block_headers.read().heap_size_of_children() + self.block_bodies.read().heap_size_of_children(),
block_details: self.block_details.read().heap_size_of_children(),
transaction_addresses: self.transaction_addresses.read().heap_size_of_children(),
block_receipts: self.block_receipts.read().heap_size_of_children(),
}
}
@@ -1530,13 +1506,12 @@ impl BlockChain {
transaction_addresses.shrink_to_fit();
block_receipts.shrink_to_fit();
let mut ops = new_malloc_size_ops();
block_headers.size_of(&mut ops) +
block_bodies.size_of(&mut ops) +
block_details.size_of(&mut ops) +
block_hashes.size_of(&mut ops) +
transaction_addresses.size_of(&mut ops) +
block_receipts.size_of(&mut ops)
block_headers.heap_size_of_children() +
block_bodies.heap_size_of_children() +
block_details.heap_size_of_children() +
block_hashes.heap_size_of_children() +
transaction_addresses.heap_size_of_children() +
block_receipts.heap_size_of_children()
});
}
@@ -1588,18 +1563,17 @@ mod tests {
use keccak_hash::keccak;
use rustc_hex::FromHex;
use tempdir::TempDir;
use std::str::FromStr;
struct TestBlockChainDB {
_blooms_dir: TempDir,
_trace_blooms_dir: TempDir,
blooms: blooms_db::Database,
trace_blooms: blooms_db::Database,
key_value: Arc<dyn KeyValueDB>,
key_value: Arc<KeyValueDB>,
}
impl BlockChainDB for TestBlockChainDB {
fn key_value(&self) -> &Arc<dyn KeyValueDB> {
fn key_value(&self) -> &Arc<KeyValueDB> {
&self.key_value
}
@@ -1613,7 +1587,7 @@ mod tests {
}
/// Creates new test instance of `BlockChainDB`
pub fn new_db() -> Arc<dyn BlockChainDB> {
pub fn new_db() -> Arc<BlockChainDB> {
let blooms_dir = TempDir::new("").unwrap();
let trace_blooms_dir = TempDir::new("").unwrap();
@@ -1628,15 +1602,15 @@ mod tests {
Arc::new(db)
}
fn new_chain(genesis: encoded::Block, db: Arc<dyn BlockChainDB>) -> BlockChain {
fn new_chain(genesis: encoded::Block, db: Arc<BlockChainDB>) -> BlockChain {
BlockChain::new(Config::default(), genesis.raw(), db)
}
fn insert_block(db: &Arc<dyn BlockChainDB>, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>) -> ImportRoute {
fn insert_block(db: &Arc<BlockChainDB>, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>) -> ImportRoute {
insert_block_commit(db, bc, block, receipts, true)
}
fn insert_block_commit(db: &Arc<dyn BlockChainDB>, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>, commit: bool) -> ImportRoute {
fn insert_block_commit(db: &Arc<BlockChainDB>, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>, commit: bool) -> ImportRoute {
let mut batch = db.key_value().transaction();
let res = insert_block_batch(&mut batch, bc, block, receipts);
db.key_value().write(batch).unwrap();
@@ -1647,6 +1621,8 @@ mod tests {
}
fn insert_block_batch(batch: &mut DBTransaction, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>) -> ImportRoute {
use crate::ExtrasInsert;
let fork_choice = {
let header = block.header_view();
let parent_hash = header.parent_hash();
@@ -2073,7 +2049,7 @@ mod tests {
fn find_transaction_by_hash() {
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0af81e09f8c46ca322193edfda764fa7e88e81923f802f1d325ec0b0308ac2cd0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083023e38808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0".from_hex().unwrap();
let b1 = "f904a8f901faa0ce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a65c2364cd0f1542d761823dc0109c6b072f14c20459598c5455c274601438f4a070616ebd7ad2ed6fb7860cf7e9df00163842351c38a87cac2c1cb193895035a2a05c5b4fc43c2d45787f54e1ae7d27afdb4ad16dfc567c5692070d5c4556e0b1d7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000183023ec683021536845685109780a029f07836e4e59229b3a065913afc27702642c683bba689910b2b2fd45db310d3888957e6d004a31802f902a7f85f800a8255f094aaaf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0575da4e21b66fa764be5f74da9389e67693d066fb0d1312e19e17e501da00ecda06baf5a5327595f6619dfc2fcb3f2e6fb410b5810af3cb52d0e7508038e91a188f85f010a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba04fa966bf34b93abc1bcd665554b7f316b50f928477b50be0f3285ead29d18c5ba017bba0eeec1625ab433746955e125d46d80b7fdc97386c51266f842d8e02192ef85f020a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca004377418ae981cc32b1312b4a427a1d69a821b28db8584f5f2bd8c6d42458adaa053a1dba1af177fac92f3b6af0a9fa46a22adf56e686c93794b6a012bf254abf5f85f030a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca04fe13febd28a05f4fcb2f451d7ddc2dda56486d9f8c79a62b0ba4da775122615a0651b2382dd402df9ebc27f8cb4b2e0f3cea68dda2dca0ee9603608f0b6f51668f85f040a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba078e6a0ba086a08f8450e208a399bb2f2d2a0d984acd2517c7c7df66ccfab567da013254002cd45a97fac049ae00afbc43ed0d9961d0c56a3b2382c80ce41c198ddf85f050a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba0a7174d8f43ea71c8e3ca9477691add8d80ac8e0ed89d8d8b572041eef81f4a54a0534ea2e28ec4da3b5b944b18c51ec84a5cf35f5b3343c5fb86521fd2d388f506f85f060a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba034bd04065833536a10c77ee2a43a5371bc6d34837088b861dd9d4b7f44074b59a078807715786a13876d3455716a6b9cb2186b7a4887a5c31160fc877454958616c0".from_hex().unwrap();
let b1_hash = H256::from_str("f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3").unwrap();
let b1_hash: H256 = "f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3".into();
let db = new_db();
let bc = new_chain(encoded::Block::new(genesis), db.clone());
@@ -2146,7 +2122,7 @@ mod tests {
let db = new_db();
let bc = new_chain(genesis.last().encoded(), db.clone());
insert_block(&db, &bc, b1.last().encoded(), vec![Receipt {
outcome: TransactionOutcome::StateRoot(H256::zero()),
outcome: TransactionOutcome::StateRoot(H256::default()),
gas_used: 10_000.into(),
log_bloom: Default::default(),
logs: vec![
@@ -2155,7 +2131,7 @@ mod tests {
],
},
Receipt {
outcome: TransactionOutcome::StateRoot(H256::zero()),
outcome: TransactionOutcome::StateRoot(H256::default()),
gas_used: 10_000.into(),
log_bloom: Default::default(),
logs: vec![
@@ -2164,7 +2140,7 @@ mod tests {
}]);
insert_block(&db, &bc, b2.last().encoded(), vec![
Receipt {
outcome: TransactionOutcome::StateRoot(H256::zero()),
outcome: TransactionOutcome::StateRoot(H256::default()),
gas_used: 10_000.into(),
log_bloom: Default::default(),
logs: vec![
@@ -2174,7 +2150,7 @@ mod tests {
]);
insert_block(&db, &bc, b3.last().encoded(), vec![
Receipt {
outcome: TransactionOutcome::StateRoot(H256::zero()),
outcome: TransactionOutcome::StateRoot(H256::default()),
gas_used: 10_000.into(),
log_bloom: Default::default(),
logs: vec![
@@ -2253,11 +2229,11 @@ mod tests {
#[test]
fn test_bloom_filter_simple() {
let bloom_b1 = Bloom::from_str("00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000").unwrap();
let bloom_b1: Bloom = "00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000".into();
let bloom_b2 = Bloom::from_str("00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
let bloom_b2: Bloom = "00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
let bloom_ba = Bloom::from_str("00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
let bloom_ba: Bloom = "00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
let genesis = BlockBuilder::genesis();
let b1 = genesis.add_block_with(|| BlockOptions {
@@ -2321,11 +2297,11 @@ mod tests {
#[test]
fn test_insert_unordered() {
let bloom_b1 = Bloom::from_str("00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000").unwrap();
let bloom_b1: Bloom = "00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000".into();
let bloom_b2 = Bloom::from_str("00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
let bloom_b2: Bloom = "00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
let bloom_b3 = Bloom::from_str("00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
let bloom_b3: Bloom = "00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
let genesis = BlockBuilder::genesis();
let b1 = genesis.add_block_with_bloom(bloom_b1);
@@ -2507,74 +2483,4 @@ mod tests {
assert_eq!(bc.epoch_transition_for(fork_hash).unwrap().block_number, 0);
}
}
#[test]
fn tree_rout_with_finalization() {
let genesis = BlockBuilder::genesis();
let a = genesis.add_block();
// First branch
let a1 = a.add_block_with_random_transactions();
let a2 = a1.add_block_with_random_transactions();
let a3 = a2.add_block_with_random_transactions();
// Second branch
let b1 = a.add_block_with_random_transactions();
let b2 = b1.add_block_with_random_transactions();
let a_hash = a.last().hash();
let a1_hash = a1.last().hash();
let a2_hash = a2.last().hash();
let a3_hash = a3.last().hash();
let b2_hash = b2.last().hash();
let bootstrap_chain = |blocks: Vec<&BlockBuilder>| {
let db = new_db();
let bc = new_chain(genesis.last().encoded(), db.clone());
let mut batch = db.key_value().transaction();
for block in blocks {
insert_block_batch(&mut batch, &bc, block.last().encoded(), vec![]);
bc.commit();
}
db.key_value().write(batch).unwrap();
(db, bc)
};
let mark_finalized = |block_hash: H256, db: &Arc<dyn BlockChainDB>, bc: &BlockChain| {
let mut batch = db.key_value().transaction();
bc.mark_finalized(&mut batch, block_hash).unwrap();
bc.commit();
db.key_value().write(batch).unwrap();
};
// Case 1: fork, with finalized common ancestor
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]);
assert_eq!(bc.best_block_hash(), a3_hash);
assert_eq!(bc.block_hash(2).unwrap(), a1_hash);
mark_finalized(a_hash, &db, &bc);
assert!(!bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized);
}
// Case 2: fork with a finalized block on a branch
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]);
assert_eq!(bc.best_block_hash(), a3_hash);
assert_eq!(bc.block_hash(2).unwrap(), a1_hash);
mark_finalized(a2_hash, &db, &bc);
assert!(bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized);
}
// Case 3: no-fork, with a finalized block
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2]);
assert_eq!(bc.best_block_hash(), a2_hash);
mark_finalized(a1_hash, &db, &bc);
assert!(!bc.tree_route(a1_hash, a2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(a2_hash, a1_hash).unwrap().is_from_route_finalized);
}
}
}

View File

@@ -21,13 +21,11 @@ use ethereum_types::{U256, H256, Bloom};
use common_types::encoded;
use common_types::header::Header;
use common_types::transaction::{SignedTransaction, Transaction, Action};
use common_types::transaction::SignedTransaction;
use common_types::view;
use common_types::views::BlockView;
use keccak_hash::keccak;
use rlp::encode;
use rlp_derive::RlpEncodable;
use triehash_ethereum::ordered_trie_root;
/// Helper structure, used for encoding blocks.
#[derive(Default, Clone, RlpEncodable)]
@@ -138,29 +136,6 @@ impl BlockBuilder {
})
}
/// Add a block with randomly generated transactions.
#[inline]
pub fn add_block_with_random_transactions(&self) -> Self {
// Maximum of ~50 transactions
let count = rand::random::<u8>() as usize / 5;
let transactions = std::iter::repeat_with(|| {
let data_len = rand::random::<u8>();
let data = std::iter::repeat_with(|| rand::random::<u8>())
.take(data_len as usize)
.collect::<Vec<_>>();
Transaction {
nonce: 0.into(),
gas_price: 0.into(),
gas: 100_000.into(),
action: Action::Create,
value: 100.into(),
data,
}.sign(&keccak("").into(), None)
}).take(count);
self.add_block_with_transactions(transactions)
}
/// Add a block with given transactions.
#[inline]
pub fn add_block_with_transactions<T>(&self, transactions: T) -> Self
@@ -191,15 +166,11 @@ impl BlockBuilder {
let mut block = Block::default();
let metadata = get_metadata();
let block_number = parent_number + 1;
let transactions = metadata.transactions;
let transactions_root = ordered_trie_root(transactions.iter().map(rlp::encode));
block.header.set_parent_hash(parent_hash);
block.header.set_number(block_number);
block.header.set_log_bloom(metadata.bloom);
block.header.set_difficulty(metadata.difficulty);
block.header.set_transactions_root(transactions_root);
block.transactions = transactions;
block.transactions = metadata.transactions;
parent_hash = block.hash();
parent_number = block_number;

View File

@@ -68,7 +68,7 @@ impl From<BlockInfo> for ImportRoute {
#[cfg(test)]
mod tests {
use ethereum_types::{U256, BigEndianHash};
use ethereum_types::{H256, U256};
use crate::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
use super::ImportRoute;
@@ -84,7 +84,7 @@ mod tests {
#[test]
fn import_route_branch() {
let info = BlockInfo {
hash: BigEndianHash::from_uint(&U256::from(1)),
hash: H256::from(U256::from(1)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::Branch,
@@ -93,14 +93,14 @@ mod tests {
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![],
enacted: vec![],
omitted: vec![BigEndianHash::from_uint(&U256::from(1))],
omitted: vec![H256::from(U256::from(1))],
});
}
#[test]
fn import_route_canon_chain() {
let info = BlockInfo {
hash: BigEndianHash::from_uint(&U256::from(1)),
hash: H256::from(U256::from(1)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::CanonChain,
@@ -108,7 +108,7 @@ mod tests {
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![],
enacted: vec![BigEndianHash::from_uint(&U256::from(1))],
enacted: vec![H256::from(U256::from(1))],
omitted: vec![],
});
}
@@ -116,19 +116,19 @@ mod tests {
#[test]
fn import_route_branch_becoming_canon_chain() {
let info = BlockInfo {
hash: BigEndianHash::from_uint(&U256::from(2)),
hash: H256::from(U256::from(2)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
ancestor: BigEndianHash::from_uint(&U256::from(0)),
enacted: vec![BigEndianHash::from_uint(&U256::from(1))],
retracted: vec![BigEndianHash::from_uint(&U256::from(3)), BigEndianHash::from_uint(&U256::from(4))],
ancestor: H256::from(U256::from(0)),
enacted: vec![H256::from(U256::from(1))],
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
})
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![BigEndianHash::from_uint(&U256::from(3)), BigEndianHash::from_uint(&U256::from(4))],
enacted: vec![BigEndianHash::from_uint(&U256::from(1)), BigEndianHash::from_uint(&U256::from(2))],
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
enacted: vec![H256::from(U256::from(1)), H256::from(U256::from(2))],
omitted: vec![],
});
}

View File

@@ -18,9 +18,6 @@
#![warn(missing_docs)]
extern crate parity_util_mem as util_mem;
extern crate parity_util_mem as malloc_size_of;
mod best_block;
mod block_info;
mod blockchain;
@@ -36,5 +33,5 @@ pub use self::cache::CacheSize;
pub use self::config::Config;
pub use self::import_route::ImportRoute;
pub use self::update::ExtrasInsert;
pub use ethcore_db::keys::{BlockReceipts, BlockDetails, TransactionAddress, BlockNumberKey};
pub use ethcore_db::keys::{BlockReceipts, BlockDetails, TransactionAddress};
pub use common_types::tree_route::TreeRoute;

View File

@@ -1,22 +0,0 @@
[package]
description = "ethereum vm builtin"
name = "ethcore-builtin"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
bn = { git = "https://github.com/paritytech/bn", default-features = false }
ethereum-types = "0.6.0"
ethjson = { path = "../../json" }
ethkey = { path = "../../accounts/ethkey" }
keccak-hash = "0.2.0"
log = "0.4"
num = { version = "0.1", default-features = false, features = ["bigint"] }
parity-bytes = "0.1"
eip-152 = { path = "../../util/EIP-152" }
parity-crypto = "0.4.0"
byteorder = "1.3.2"
[dev-dependencies]
hex-literal = "0.2.1"

View File

@@ -1,5 +1,4 @@
[package]
description = "Parity Ethereum (EthCore) Contract Calls and Blockchain Service & Registry Information"
name = "ethcore-call-contract"
version = "0.1.0"
license = "GPL-3.0"
@@ -8,5 +7,5 @@ edition = "2018"
[dependencies]
types = { path = "../types", package = "common-types" }
ethereum-types = "0.6.0"
ethereum-types = "0.4"
bytes = { version = "0.1", package = "parity-bytes" }

View File

@@ -9,9 +9,9 @@ edition = "2018"
[dependencies]
common-types = { path = "../types" }
ethereum-types = "0.6.0"
ethereum-types = "0.4"
heapsize = "0.4"
kvdb = "0.1"
parity-util-mem = "0.1"
parking_lot = "0.7"
rlp = "0.4.0"
rlp = { version = "0.3.0", features = ["ethereum"] }
rlp_derive = { path = "../../util/rlp-derive" }

View File

@@ -16,7 +16,7 @@
//! Database utilities and definitions.
use std::convert::AsRef;
use std::ops::Deref;
use std::hash::Hash;
use std::collections::HashMap;
use parking_lot::RwLock;
@@ -82,7 +82,7 @@ impl<K, V> Cache<K, V> for HashMap<K, V> where K: Hash + Eq {
/// Should be used to get database key associated with given value.
pub trait Key<T> {
/// The db key associated with this value.
type Target: AsRef<[u8]>;
type Target: Deref<Target = [u8]>;
/// Returns db key.
fn key(&self) -> Self::Target;
@@ -91,16 +91,16 @@ pub trait Key<T> {
/// Should be used to write value into database.
pub trait Writable {
/// Writes the value into the database.
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: AsRef<[u8]>;
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: Deref<Target = [u8]>;
/// Deletes key from the databse.
fn delete<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>) where T: rlp::Encodable, R: AsRef<[u8]>;
fn delete<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>) where T: rlp::Encodable, R: Deref<Target = [u8]>;
/// Writes the value into the database and updates the cache.
fn write_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: rlp::Encodable,
R: AsRef<[u8]> {
R: Deref<Target = [u8]> {
self.write(col, &key, &value);
match policy {
CacheUpdatePolicy::Overwrite => {
@@ -116,7 +116,7 @@ pub trait Writable {
fn extend_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: rlp::Encodable,
R: AsRef<[u8]> {
R: Deref<Target = [u8]> {
match policy {
CacheUpdatePolicy::Overwrite => {
for (key, value) in values {
@@ -137,7 +137,7 @@ pub trait Writable {
fn extend_with_option_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, Option<T>>, values: HashMap<K, Option<T>>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: rlp::Encodable,
R: AsRef<[u8]> {
R: Deref<Target = [u8]> {
match policy {
CacheUpdatePolicy::Overwrite => {
for (key, value) in values {
@@ -167,7 +167,7 @@ pub trait Readable {
/// Returns value for given key.
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where
T: rlp::Decodable,
R: AsRef<[u8]>;
R: Deref<Target = [u8]>;
/// Returns value for given key either in cache or in database.
fn read_with_cache<K, T, C>(&self, col: Option<u32>, cache: &RwLock<C>, key: &K) -> Option<T> where
@@ -189,12 +189,12 @@ pub trait Readable {
}
/// Returns true if given value exists.
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: AsRef<[u8]>;
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target= [u8]>;
/// Returns true if given value exists either in cache or in database.
fn exists_with_cache<K, T, R, C>(&self, col: Option<u32>, cache: &RwLock<C>, key: &K) -> bool where
K: Eq + Hash + Key<T, Target = R>,
R: AsRef<[u8]>,
R: Deref<Target = [u8]>,
C: Cache<K, T> {
{
let read = cache.read();
@@ -208,31 +208,31 @@ pub trait Readable {
}
impl Writable for DBTransaction {
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: AsRef<[u8]> {
self.put(col, key.key().as_ref(), &rlp::encode(value));
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: Deref<Target = [u8]> {
self.put(col, &key.key(), &rlp::encode(value));
}
fn delete<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>) where T: rlp::Encodable, R: AsRef<[u8]> {
self.delete(col, key.key().as_ref());
fn delete<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>) where T: rlp::Encodable, R: Deref<Target = [u8]> {
self.delete(col, &key.key());
}
}
impl<KVDB: KeyValueDB + ?Sized> Readable for KVDB {
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T>
where T: rlp::Decodable, R: AsRef<[u8]> {
self.get(col, key.key().as_ref())
.expect(&format!("db get failed, key: {:?}", key.key().as_ref()))
where T: rlp::Decodable, R: Deref<Target = [u8]> {
self.get(col, &key.key())
.expect(&format!("db get failed, key: {:?}", &key.key() as &[u8]))
.map(|v| rlp::decode(&v).expect("decode db value failed") )
}
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: AsRef<[u8]> {
let result = self.get(col, key.key().as_ref());
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {
let result = self.get(col, &key.key());
match result {
Ok(v) => v.is_some(),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", key.key().as_ref(), err);
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}

View File

@@ -17,13 +17,13 @@
//! Blockchain DB extras.
use std::io::Write;
use std::convert::AsRef;
use std::ops;
use common_types::BlockNumber;
use common_types::engines::epoch::Transition as EpochTransition;
use common_types::receipt::Receipt;
use ethereum_types::{H256, H264, U256};
use parity_util_mem::MallocSizeOf;
use heapsize::HeapSizeOf;
use kvdb::PREFIX_LEN as DB_PREFIX_LEN;
use rlp;
use rlp_derive::{RlpEncodableWrapper, RlpDecodableWrapper, RlpEncodable, RlpDecodable};
@@ -49,17 +49,19 @@ pub enum ExtrasIndex {
fn with_index(hash: &H256, i: ExtrasIndex) -> H264 {
let mut result = H264::default();
result.as_bytes_mut()[0] = i as u8;
result.as_bytes_mut()[1..].clone_from_slice(hash.as_bytes());
result[0] = i as u8;
(*result)[1..].clone_from_slice(hash);
result
}
/// Wrapper for block number used as a DB key.
pub struct BlockNumberKey([u8; 5]);
impl AsRef<[u8]> for BlockNumberKey {
fn as_ref(&self) -> &[u8] {
&self.0[..]
impl ops::Deref for BlockNumberKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
@@ -121,8 +123,10 @@ pub const EPOCH_KEY_PREFIX: &'static [u8; DB_PREFIX_LEN] = &[
/// Epoch transitions key
pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]);
impl AsRef<[u8]> for EpochTransitionsKey {
fn as_ref(&self) -> &[u8] { &self.0[..] }
impl ops::Deref for EpochTransitionsKey {
type Target = [u8];
fn deref(&self) -> &[u8] { &self.0[..] }
}
impl Key<EpochTransitions> for u64 {
@@ -140,7 +144,7 @@ impl Key<EpochTransitions> for u64 {
}
/// Familial details concerning a block
#[derive(Debug, Clone, MallocSizeOf)]
#[derive(Debug, Clone)]
pub struct BlockDetails {
/// Block number
pub number: BlockNumber,
@@ -195,8 +199,14 @@ impl rlp::Decodable for BlockDetails {
}
}
impl HeapSizeOf for BlockDetails {
fn heap_size_of_children(&self) -> usize {
self.children.heap_size_of_children()
}
}
/// Represents address of certain transaction within block
#[derive(Debug, PartialEq, Clone, RlpEncodable, RlpDecodable, MallocSizeOf)]
#[derive(Debug, PartialEq, Clone, RlpEncodable, RlpDecodable)]
pub struct TransactionAddress {
/// Block hash
pub block_hash: H256,
@@ -204,8 +214,12 @@ pub struct TransactionAddress {
pub index: usize
}
impl HeapSizeOf for TransactionAddress {
fn heap_size_of_children(&self) -> usize { 0 }
}
/// Contains all block receipts.
#[derive(Debug, Clone, RlpEncodableWrapper, RlpDecodableWrapper, MallocSizeOf)]
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct BlockReceipts {
/// Block receipts
pub receipts: Vec<Receipt>,
@@ -214,7 +228,15 @@ pub struct BlockReceipts {
impl BlockReceipts {
/// Create new block receipts wrapper.
pub fn new(receipts: Vec<Receipt>) -> Self {
BlockReceipts { receipts }
BlockReceipts {
receipts: receipts
}
}
}
impl HeapSizeOf for BlockReceipts {
fn heap_size_of_children(&self) -> usize {
self.receipts.heap_size_of_children()
}
}

View File

@@ -18,9 +18,6 @@
#![warn(missing_docs)]
extern crate parity_util_mem as mem;
extern crate parity_util_mem as malloc_size_of;
mod db;
pub mod keys;

View File

@@ -1,5 +1,4 @@
[package]
description = "Parity Ethereum Virtual Machine (EVM) Rust Implementation"
name = "evm"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
@@ -7,19 +6,18 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
bit-set = "0.4"
parity-bytes = "0.1"
ethereum-types = "0.6.0"
parity-util-mem = "0.1"
ethereum-types = "0.4"
heapsize = "0.4"
lazy_static = "1.0"
log = "0.4"
vm = { path = "../vm" }
keccak-hash = "0.2.0"
keccak-hash = "0.1"
parking_lot = "0.7"
memory-cache = { path = "../../util/memory-cache" }
[dev-dependencies]
rustc-hex = "1.0"
criterion = "0.2"
hex-literal = "0.2.0"
[features]
evm-debug = []

View File

@@ -21,7 +21,7 @@ extern crate criterion;
extern crate bit_set;
extern crate ethereum_types;
extern crate parking_lot;
extern crate parity_util_mem as mem;
extern crate heapsize;
extern crate vm;
extern crate evm;
extern crate keccak_hash as hash;
@@ -45,9 +45,7 @@ criterion_group!(
mem_gas_calculation_same_usize,
mem_gas_calculation_same_u256,
mem_gas_calculation_increasing_usize,
mem_gas_calculation_increasing_u256,
blockhash_mulmod_small,
blockhash_mulmod_large,
mem_gas_calculation_increasing_u256
);
criterion_main!(basic);
@@ -152,54 +150,6 @@ fn mem_gas_calculation_increasing(gas: U256, b: &mut Bencher) {
});
}
fn blockhash_mulmod_small(b: &mut Criterion) {
b.bench_function("blockhash_mulmod_small", |b| {
let factory = Factory::default();
let mut ext = FakeExt::new();
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
b.iter(|| {
let code = black_box(
"6080604052348015600f57600080fd5b5060005a90505b60c881111560de5760017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80095060017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8009505a90506016565b506035806100ed6000396000f3fe6080604052600080fdfea165627a7a72305820bde4a0ac6d0fac28fc879244baf8a6a0eda514bc95fb7ecbcaaebf2556e2687c0029".from_hex().unwrap()
);
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(4_000u64);
params.code = Some(Arc::new(code.clone()));
let vm = factory.create(params, ext.schedule(), 0);
result(vm.exec(&mut ext).ok().unwrap())
});
});
}
fn blockhash_mulmod_large(b: &mut Criterion) {
b.bench_function("blockhash_mulmod_large", |b| {
let factory = Factory::default();
let mut ext = FakeExt::new();
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
b.iter(|| {
let code = black_box(
"608060405234801561001057600080fd5b5060005a90505b60c8811115610177577efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009507efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff17efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08009505a9050610017565b506035806101866000396000f3fe6080604052600080fdfea165627a7a72305820dcaec306f67bb96f3044fff25c9af2ec66f01d0954d0656964f046f42f2780670029".from_hex().unwrap()
);
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(4_000u64);
params.code = Some(Arc::new(code.clone()));
let vm = factory.create(params, ext.schedule(), 0);
result(vm.exec(&mut ext).ok().unwrap())
});
});
}
fn result(r: Result<evm::GasLeft>) -> U256 {
match r {
Ok(GasLeft::Known(gas_left)) => gas_left,

View File

@@ -44,18 +44,12 @@ pub trait Finalize {
impl Finalize for Result<GasLeft> {
fn finalize<E: Ext>(self, ext: E) -> Result<FinalizationResult> {
match self {
Ok(GasLeft::Known(gas_left)) => {
Ok(FinalizationResult {
gas_left,
apply_state: true,
return_data: ReturnData::empty()
})
},
Ok(GasLeft::NeedsReturn { gas_left, data, apply_state }) => {
ext.ret(&gas_left, &data, apply_state).map(|gas_left|
FinalizationResult { gas_left, apply_state, return_data: data }
)
},
Ok(GasLeft::Known(gas_left)) => Ok(FinalizationResult { gas_left: gas_left, apply_state: true, return_data: ReturnData::empty() }),
Ok(GasLeft::NeedsReturn { gas_left, data, apply_state }) => ext.ret(&gas_left, &data, apply_state).map(|gas_left| FinalizationResult {
gas_left: gas_left,
apply_state: apply_state,
return_data: data,
}),
Err(err) => Err(err),
}
}

View File

@@ -47,7 +47,7 @@ impl Factory {
/// for caching jump destinations.
pub fn new(evm: VMType, cache_size: usize) -> Self {
Factory {
evm,
evm: evm,
evm_cache: Arc::new(SharedCache::new(cache_size)),
}
}

View File

@@ -149,10 +149,6 @@ enum_with_from_u8! {
DIFFICULTY = 0x44,
#[doc = "get the block's gas limit"]
GASLIMIT = 0x45,
#[doc = "get chain ID"]
CHAINID = 0x46,
#[doc = "get balance of own account"]
SELFBALANCE = 0x47,
#[doc = "remove item from stack"]
POP = 0x50,
@@ -446,7 +442,12 @@ pub struct InstructionInfo {
impl InstructionInfo {
/// Create new instruction info.
pub fn new(name: &'static str, args: usize, ret: usize, tier: GasPriceTier) -> Self {
InstructionInfo { name, args, ret, tier }
InstructionInfo {
name: name,
args: args,
ret: ret,
tier: tier
}
}
}
@@ -503,8 +504,6 @@ lazy_static! {
arr[NUMBER as usize] = Some(InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base));
arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base));
arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base));
arr[CHAINID as usize] = Some(InstructionInfo::new("CHAINID", 0, 1, GasPriceTier::Base));
arr[SELFBALANCE as usize] = Some(InstructionInfo::new("SELFBALANCE", 0, 1, GasPriceTier::Low));
arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base));
arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow));
arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow));

View File

@@ -15,7 +15,7 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::cmp;
use ethereum_types::{BigEndianHash, U256};
use ethereum_types::{U256, H256};
use super::u256_to_address;
use {evm, vm};
@@ -121,16 +121,12 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
Request::Gas(Gas::from(1))
},
instructions::SSTORE => {
if schedule.eip1706 && self.current_gas <= Gas::from(schedule.call_stipend) {
return Err(vm::Error::OutOfGas);
}
let address = BigEndianHash::from_uint(stack.peek(0));
let address = H256::from(stack.peek(0));
let newval = stack.peek(1);
let val = ext.storage_at(&address)?.into_uint();
let val = U256::from(&*ext.storage_at(&address)?);
let gas = if schedule.eip1283 {
let orig = ext.initial_storage_at(&address)?.into_uint();
let orig = U256::from(&*ext.initial_storage_at(&address)?);
calculate_eip1283_sstore_gas(schedule, &orig, &val, &newval)
} else {
if val.is_zero() && !newval.is_zero() {

View File

@@ -26,11 +26,9 @@ mod shared_cache;
use std::marker::PhantomData;
use std::{cmp, mem};
use std::sync::Arc;
use std::convert::TryFrom;
use hash::keccak;
use bytes::Bytes;
use ethereum_types::{U256, U512, H256, Address, BigEndianHash};
use ethereum_types::{U256, U512, H256, Address};
use vm::{
self, ActionParams, ParamsType, ActionValue, CallType, MessageCallResult,
@@ -109,6 +107,8 @@ enum InstructionResult<Gas> {
Trap(TrapKind),
}
enum Never {}
/// ActionParams without code, so that it can be feed into CodeReader.
#[derive(Debug)]
struct InterpreterParams {
@@ -166,6 +166,12 @@ pub enum InterpreterResult {
Trap(TrapKind),
}
impl From<vm::Error> for InterpreterResult {
fn from(error: vm::Error) -> InterpreterResult {
InterpreterResult::Done(Err(error))
}
}
/// Intepreter EVM implementation
pub struct Interpreter<Cost: CostType> {
mem: Vec<u8>,
@@ -276,8 +282,6 @@ impl<Cost: CostType> Interpreter<Cost> {
cache, params, reader, informant,
valid_jump_destinations, gasometer, stack,
done: false,
// Overridden in `step_inner` based on
// the result of `ext.trace_next_instruction`.
do_trace: true,
mem: Vec::new(),
return_data: ReturnData::empty(),
@@ -298,26 +302,21 @@ impl<Cost: CostType> Interpreter<Cost> {
let result = if self.gasometer.is_none() {
InterpreterResult::Done(Err(vm::Error::OutOfGas))
} else if self.reader.len() == 0 {
let current_gas = self.gasometer
.as_ref()
.expect("Gasometer None case is checked above; qed")
.current_gas
.as_u256();
InterpreterResult::Done(Ok(GasLeft::Known(current_gas)))
InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_ref().expect("Gasometer None case is checked above; qed").current_gas.as_u256())))
} else {
self.step_inner(ext)
self.step_inner(ext).err().expect("step_inner never returns Ok(()); qed")
};
if let &InterpreterResult::Done(_) = &result {
self.done = true;
self.informant.done();
}
result
return result;
}
/// Inner helper function for step.
#[inline(always)]
fn step_inner(&mut self, ext: &mut dyn vm::Ext) -> InterpreterResult {
fn step_inner(&mut self, ext: &mut vm::Ext) -> Result<Never, InterpreterResult> {
let result = match self.resume_result.take() {
Some(result) => result,
None => {
@@ -332,31 +331,22 @@ impl<Cost: CostType> Interpreter<Cost> {
let instruction = match instruction {
Some(i) => i,
None => return InterpreterResult::Done(Err(vm::Error::BadInstruction {
None => return Err(InterpreterResult::Done(Err(vm::Error::BadInstruction {
instruction: opcode
})),
}))),
};
let info = instruction.info();
self.last_stack_ret_len = info.ret;
if let Err(e) = self.verify_instruction(ext, instruction, info) {
return InterpreterResult::Done(Err(e));
};
self.verify_instruction(ext, instruction, info)?;
// Calculate gas cost
let requirements = match self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size()) {
Ok(t) => t,
Err(e) => return InterpreterResult::Done(Err(e)),
};
let requirements = self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size())?;
if self.do_trace {
ext.trace_prepare_execute(self.reader.position - 1, opcode, requirements.gas_cost.as_u256(), Self::mem_written(instruction, &self.stack), Self::store_written(instruction, &self.stack));
}
if let Err(e) = self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost) {
if self.do_trace {
ext.trace_failed();
}
return InterpreterResult::Done(Err(e));
}
self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost)?;
self.mem.expand(requirements.memory_required_size);
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_mem_gas = requirements.memory_total_gas;
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas - requirements.gas_cost;
@@ -365,24 +355,18 @@ impl<Cost: CostType> Interpreter<Cost> {
// Execute instruction
let current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas;
let result = match self.exec_instruction(
let result = self.exec_instruction(
current_gas, ext, instruction, requirements.provide_gas
) {
Err(x) => {
if self.do_trace {
ext.trace_failed();
}
return InterpreterResult::Done(Err(x));
},
Ok(x) => x,
};
)?;
evm_debug!({ self.informant.after_instruction(instruction) });
result
},
};
if let InstructionResult::Trap(trap) = result {
return InterpreterResult::Trap(trap);
return Err(InterpreterResult::Trap(trap));
}
if let InstructionResult::UnusedGas(ref gas) = result {
@@ -404,31 +388,28 @@ impl<Cost: CostType> Interpreter<Cost> {
self.valid_jump_destinations = Some(self.cache.jump_destinations(&self.params.code_hash, &self.reader.code));
}
let jump_destinations = self.valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed");
let pos = match self.verify_jump(position, jump_destinations) {
Ok(x) => x,
Err(e) => return InterpreterResult::Done(Err(e))
};
let pos = self.verify_jump(position, jump_destinations)?;
self.reader.position = pos;
},
InstructionResult::StopExecutionNeedsReturn {gas, init_off, init_size, apply} => {
let mem = mem::replace(&mut self.mem, Vec::new());
return InterpreterResult::Done(Ok(GasLeft::NeedsReturn {
return Err(InterpreterResult::Done(Ok(GasLeft::NeedsReturn {
gas_left: gas.as_u256(),
data: mem.into_return_data(init_off, init_size),
apply_state: apply
}));
})));
},
InstructionResult::StopExecution => {
return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())));
return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))));
},
_ => {},
}
if self.reader.position >= self.reader.len() {
return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())));
return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))));
}
InterpreterResult::Continue
Err(InterpreterResult::Continue)
}
fn verify_instruction(&self, ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo) -> vm::Result<()> {
@@ -440,9 +421,7 @@ impl<Cost: CostType> Interpreter<Cost> {
((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) ||
(instruction == instructions::REVERT && !schedule.have_revert) ||
((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) ||
(instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash) ||
(instruction == instructions::CHAINID && !schedule.have_chain_id) ||
(instruction == instructions::SELFBALANCE && !schedule.have_selfbalance)
(instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash)
{
return Err(vm::Error::BadInstruction {
instruction: instruction as u8
@@ -529,7 +508,7 @@ impl<Cost: CostType> Interpreter<Cost> {
let init_size = self.stack.pop_back();
let address_scheme = match instruction {
instructions::CREATE => CreateContractAddress::FromSenderAndNonce,
instructions::CREATE2 => CreateContractAddress::FromSenderSaltAndCodeHash(BigEndianHash::from_uint(&self.stack.pop_back())),
instructions::CREATE2 => CreateContractAddress::FromSenderSaltAndCodeHash(self.stack.pop_back().into()),
_ => unreachable!("instruction can only be CREATE/CREATE2 checked above; qed"),
};
@@ -686,7 +665,7 @@ impl<Cost: CostType> Interpreter<Cost> {
let size = self.stack.pop_back();
let topics = self.stack.pop_n(no_of_topics)
.iter()
.map(BigEndianHash::from_uint)
.map(H256::from)
.collect();
ext.log(topics, self.mem.read_slice(offset, size))?;
},
@@ -723,21 +702,21 @@ impl<Cost: CostType> Interpreter<Cost> {
let offset = self.stack.pop_back();
let size = self.stack.pop_back();
let k = keccak(self.mem.read_slice(offset, size));
self.stack.push(k.into_uint());
self.stack.push(U256::from(&*k));
},
instructions::SLOAD => {
let key = BigEndianHash::from_uint(&self.stack.pop_back());
let word = ext.storage_at(&key)?.into_uint();
let key = H256::from(&self.stack.pop_back());
let word = U256::from(&*ext.storage_at(&key)?);
self.stack.push(word);
},
instructions::SSTORE => {
let address = BigEndianHash::from_uint(&self.stack.pop_back());
let address = H256::from(&self.stack.pop_back());
let val = self.stack.pop_back();
let current_val = ext.storage_at(&address)?.into_uint();
let current_val = U256::from(&*ext.storage_at(&address)?);
// Increase refund for clear
if ext.schedule().eip1283 {
let original_val = ext.initial_storage_at(&address)?.into_uint();
let original_val = U256::from(&*ext.initial_storage_at(&address)?);
gasometer::handle_eip1283_sstore_clears_refund(ext, &original_val, &current_val, &val);
} else {
if !current_val.is_zero() && val.is_zero() {
@@ -745,7 +724,7 @@ impl<Cost: CostType> Interpreter<Cost> {
ext.add_sstore_refund(sstore_clears_schedule);
}
}
ext.set_storage(address, BigEndianHash::from_uint(&val))?;
ext.set_storage(address, H256::from(&val))?;
},
instructions::PC => {
self.stack.push(U256::from(self.reader.position - 1));
@@ -806,7 +785,7 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::EXTCODEHASH => {
let address = u256_to_address(&self.stack.pop_back());
let hash = ext.extcodehash(&address)?.unwrap_or_else(H256::zero);
self.stack.push(hash.into_uint());
self.stack.push(U256::from(hash));
},
instructions::CALLDATACOPY => {
Self::copy_data_to_memory(&mut self.mem, &mut self.stack, &self.params.data.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8]));
@@ -840,7 +819,7 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::BLOCKHASH => {
let block_number = self.stack.pop_back();
let block_hash = ext.blockhash(&block_number);
self.stack.push(block_hash.into_uint());
self.stack.push(U256::from(&*block_hash));
},
instructions::COINBASE => {
self.stack.push(address_to_u256(ext.env_info().author.clone()));
@@ -857,12 +836,6 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::GASLIMIT => {
self.stack.push(ext.env_info().gas_limit.clone());
},
instructions::CHAINID => {
self.stack.push(ext.chain_id().into())
},
instructions::SELFBALANCE => {
self.stack.push(ext.balance(&self.params.address)?);
}
// Stack instructions
@@ -1036,12 +1009,11 @@ impl<Cost: CostType> Interpreter<Cost> {
let c = self.stack.pop_back();
self.stack.push(if !c.is_zero() {
let a_512 = U512::from(a);
let b_512 = U512::from(b);
let c_512 = U512::from(c);
let res = a_512 + b_512;
let x = res % c_512;
U256::try_from(x).expect("U512 % U256 fits U256; qed")
// upcast to 512
let a5 = U512::from(a);
let res = a5.overflowing_add(U512::from(b)).0;
let x = res % U512::from(c);
U256::from(x)
} else {
U256::zero()
});
@@ -1052,12 +1024,10 @@ impl<Cost: CostType> Interpreter<Cost> {
let c = self.stack.pop_back();
self.stack.push(if !c.is_zero() {
let a_512 = U512::from(a);
let b_512 = U512::from(b);
let c_512 = U512::from(c);
let res = a_512 * b_512;
let x = res % c_512;
U256::try_from(x).expect("U512 % U256 fits U256; qed")
let a5 = U512::from(a);
let res = a5.overflowing_mul(U512::from(b)).0;
let x = res % U512::from(c);
U256::from(x)
} else {
U256::zero()
});
@@ -1197,13 +1167,12 @@ fn set_sign(value: U256, sign: bool) -> U256 {
#[inline]
fn u256_to_address(value: &U256) -> Address {
let addr: H256 = BigEndianHash::from_uint(value);
Address::from(addr)
Address::from(H256::from(value))
}
#[inline]
fn address_to_u256(value: Address) -> U256 {
H256::from(value).into_uint()
U256::from(&*H256::from(value))
}
#[cfg(test)]
@@ -1214,7 +1183,6 @@ mod tests {
use factory::Factory;
use vm::{self, Exec, ActionParams, ActionValue};
use vm::tests::{FakeExt, test_finalize};
use ethereum_types::Address;
fn interpreter(params: ActionParams, ext: &vm::Ext) -> Box<Exec> {
Factory::new(VMType::Interpreter, 1).create(params, ext.schedule(), ext.depth())
@@ -1225,13 +1193,13 @@ mod tests {
let code = "7feeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000620f120660406000601773945304eb96065b2a98b57a48a06ae28d285a71b56101f4f1600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = Address::from_low_u64_be(5);
params.address = 5.into();
params.gas = 300_000.into();
params.gas_price = 1.into();
params.value = ActionValue::Transfer(100_000.into());
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.balances.insert(Address::from_low_u64_be(5), 1_000_000_000.into());
ext.balances.insert(5.into(), 1_000_000_000.into());
ext.tracing = true;
let gas_left = {
@@ -1248,12 +1216,12 @@ mod tests {
let code = "6001600160000360003e00".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = Address::from_low_u64_be(5);
params.address = 5.into();
params.gas = 300_000.into();
params.gas_price = 1.into();
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_byzantium();
ext.balances.insert(Address::from_low_u64_be(5), 1_000_000_000.into());
ext.balances.insert(5.into(), 1_000_000_000.into());
ext.tracing = true;
let err = {

View File

@@ -16,7 +16,7 @@
use std::sync::Arc;
use hash::KECCAK_EMPTY;
use parity_util_mem::{MallocSizeOf, MallocSizeOfOps};
use heapsize::HeapSizeOf;
use ethereum_types::H256;
use parking_lot::Mutex;
use memory_cache::MemoryLruCache;
@@ -25,12 +25,11 @@ use super::super::instructions::{self, Instruction};
const DEFAULT_CACHE_SIZE: usize = 4 * 1024 * 1024;
/// Stub for a sharing `BitSet` data in cache (reference counted)
/// and implementing MallocSizeOf on it.
// stub for a HeapSizeOf implementation.
struct Bits(Arc<BitSet>);
impl MallocSizeOf for Bits {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
impl HeapSizeOf for Bits {
fn heap_size_of_children(&self) -> usize {
// dealing in bits here
self.0.capacity() * 8
}

View File

@@ -19,7 +19,7 @@
extern crate bit_set;
extern crate ethereum_types;
extern crate parking_lot;
extern crate parity_util_mem;
extern crate heapsize;
extern crate vm;
extern crate keccak_hash as hash;
extern crate memory_cache;
@@ -33,8 +33,6 @@ extern crate log;
#[cfg(test)]
extern crate rustc_hex;
#[cfg(test)]
extern crate hex_literal;
pub mod evm;
pub mod interpreter;

View File

@@ -25,7 +25,6 @@ use vm::{self, ActionParams, ActionValue, Ext};
use vm::tests::{FakeExt, FakeCall, FakeCallType, test_finalize};
use factory::Factory;
use vmtype::VMType;
use hex_literal::hex;
evm_test!{test_add: test_add_int}
fn test_add(factory: super::Factory) {
@@ -109,32 +108,6 @@ fn test_origin(factory: super::Factory) {
assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681");
}
evm_test!{test_selfbalance: test_selfbalance_int}
fn test_selfbalance(factory: super::Factory) {
let own_addr = Address::from_str("1337000000000000000000000000000000000000").unwrap();
// 47 SELFBALANCE
// 60 ff PUSH ff
// 55 SSTORE
let code = hex!("47 60 ff 55").to_vec();
let mut params = ActionParams::default();
params.address = own_addr.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_istanbul();
ext.balances = {
let mut x = HashMap::new();
x.insert(own_addr, U256::from(1_025)); // 0x401
x
};
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_992)); // TODO[dvdplm]: do the sums here, SELFBALANCE-5 + PUSH1-3 + ONEBYTE-4 + SSTORE-?? = 100_000 - 79_992
assert_store(&ext, 0xff, "0000000000000000000000000000000000000000000000000000000000000401");
}
evm_test!{test_sender: test_sender_int}
fn test_sender(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
@@ -157,27 +130,6 @@ fn test_sender(factory: super::Factory) {
assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681");
}
evm_test!{test_chain_id: test_chain_id_int}
fn test_chain_id(factory: super::Factory) {
// 46 CHAINID
// 60 00 PUSH 0
// 55 SSTORE
let code = hex!("46 60 00 55").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_istanbul().with_chain_id(9);
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000009");
}
evm_test!{test_extcodecopy: test_extcodecopy_int}
fn test_extcodecopy(factory: super::Factory) {
// 33 - sender
@@ -287,7 +239,7 @@ fn test_blockhash(factory: super::Factory) {
};
assert_eq!(gas_left, U256::from(79_974));
assert_eq!(ext.store.get(&H256::zero()).unwrap(), &blockhash);
assert_eq!(ext.store.get(&H256::new()).unwrap(), &blockhash);
}
evm_test!{test_calldataload: test_calldataload_int}
@@ -310,6 +262,7 @@ fn test_calldataload(factory: super::Factory) {
assert_eq!(gas_left, U256::from(79_991));
assert_store(&ext, 0, "23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23");
}
evm_test!{test_author: test_author_int}
@@ -773,8 +726,8 @@ evm_test!{test_calls: test_calls_int}
fn test_calls(factory: super::Factory) {
let code = "600054602d57600160005560006000600060006050610998610100f160006000600060006050610998610100f25b".from_hex().unwrap();
let address = Address::from_low_u64_be(0x155);
let code_address = Address::from_low_u64_be(0x998);
let address = Address::from(0x155);
let code_address = Address::from(0x998);
let mut params = ActionParams::default();
params.gas = U256::from(150_000);
params.code = Some(Arc::new(code));
@@ -819,7 +772,7 @@ evm_test!{test_create_in_staticcall: test_create_in_staticcall_int}
fn test_create_in_staticcall(factory: super::Factory) {
let code = "600060006064f000".from_hex().unwrap();
let address = Address::from_low_u64_be(0x155);
let address = Address::from(0x155);
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
@@ -1113,5 +1066,5 @@ fn assert_set_contains<T : Debug + Eq + PartialEq + Hash>(set: &HashSet<T>, val:
}
fn assert_store(ext: &FakeExt, pos: u64, val: &str) {
assert_eq!(ext.store.get(&H256::from_low_u64_be(pos)).unwrap(), &H256::from_str(val).unwrap());
assert_eq!(ext.store.get(&H256::from(pos)).unwrap(), &H256::from_str(val).unwrap());
}

View File

@@ -1,5 +1,5 @@
[package]
description = "Parity Ethereum (EthCore) Light Client Implementation (Block Import IO Service, Blockchain Data Fetching, Light Client Header Chain Storage, Parity Light Protocol (PLP) Provider, Light Transaction Queue, CHT Definitions, Light Client Data Cache), Parity Light Protocol (PLP) Implementation, P2P Network I/O and Event Context Generalization, Peer Error Handling & Punishment, Request Load Timer & Distribution Manager, Pending Request Set Storage, Request Credit Management, Light Client Request Types, Request Chain Builder Utility, On-demand Chain Request Service over LES (for RPCs), ResponseGuard Implementation)"
description = "Parity Light Client Implementation"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "ethcore-light"
@@ -10,40 +10,37 @@ authors = ["Parity Technologies <admin@parity.io>"]
log = "0.4"
parity-bytes = "0.1"
common-types = { path = "../types" }
derive_more = "0.14.0"
ethcore = { path = ".."}
ethcore-db = { path = "../db" }
ethcore-blockchain = { path = "../blockchain" }
ethereum-types = "0.6.0"
memory-db = "0.12.4"
trie-db = "0.12.4"
ethereum-types = "0.4"
memorydb = "0.3.0"
patricia-trie = "0.3.0"
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
ethcore-network = { path = "../../util/network" }
ethcore-miner = { path = "../../miner" }
ethcore-io = { path = "../../util/io" }
hash-db = "0.12.4"
parity-util-mem = "0.1"
hashdb = "0.3.0"
heapsize = "0.4"
vm = { path = "../vm" }
fastmap = { path = "../../util/fastmap" }
failsafe = { version = "0.3.0", default-features = false, features = ["parking_lot_mutex"] }
rlp = "0.4.0"
rlp = { version = "0.3.0", features = ["ethereum"] }
rlp_derive = { path = "../../util/rlp-derive" }
smallvec = "0.6"
futures = "0.1"
rand = "0.6"
rand = "0.4"
itertools = "0.5"
bincode = "1.1"
bincode = "0.8.0"
serde = "1.0"
serde_derive = "1.0"
parking_lot = "0.7"
stats = { path = "../../util/stats" }
keccak-hash = "0.2.0"
keccak-hash = "0.1"
keccak-hasher = { path = "../../util/keccak-hasher" }
triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" }
kvdb = "0.1"
memory-cache = { path = "../../util/memory-cache" }
error-chain = { version = "0.12", default-features = false }
journaldb = { path = "../../util/journaldb" }
[dev-dependencies]
ethcore = { path = "..", features = ["test-helpers"] }

View File

@@ -21,12 +21,12 @@
//! vector of all gas prices from a recent range of blocks.
use std::time::{Instant, Duration};
use parity_util_mem::{MallocSizeOf, MallocSizeOfOps, MallocSizeOfExt};
use common_types::encoded;
use common_types::BlockNumber;
use common_types::receipt::Receipt;
use ethereum_types::{H256, U256};
use heapsize::HeapSizeOf;
use memory_cache::MemoryLruCache;
use stats::Corpus;
@@ -157,20 +157,18 @@ impl Cache {
/// Get the memory used.
pub fn mem_used(&self) -> usize {
self.malloc_size_of()
self.heap_size_of_children()
}
}
// This is fast method: it is possible to have a more exhaustive implementation
impl MallocSizeOf for Cache {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
impl HeapSizeOf for Cache {
fn heap_size_of_children(&self) -> usize {
self.headers.current_size()
+ self.canon_hashes.current_size()
+ self.bodies.current_size()
+ self.receipts.current_size()
+ self.chain_score.current_size()
// `self.corpus` is skipped
// TODO: + corpus
}
}

View File

@@ -25,11 +25,10 @@
use common_types::ids::BlockId;
use ethereum_types::{H256, U256};
use hash_db::HashDB;
use hashdb::HashDB;
use keccak_hasher::KeccakHasher;
use kvdb::DBValue;
use memory_db::MemoryDB;
use journaldb::new_memory_db;
use memorydb::MemoryDB;
use bytes::Bytes;
use trie::{TrieMut, Trie, Recorder};
use ethtrie::{self, TrieDB, TrieDBMut};
@@ -74,8 +73,7 @@ impl<DB: HashDB<KeccakHasher, DBValue>> CHT<DB> {
if block_to_cht_number(num) != Some(self.number) { return Ok(None) }
let mut recorder = Recorder::with_depth(from_level);
let db: &HashDB<_,_> = &self.db;
let t = TrieDB::new(&db, &self.root)?;
let t = TrieDB::new(&self.db, &self.root)?;
t.get_with(&key!(num), &mut recorder)?;
Ok(Some(recorder.drain().into_iter().map(|x| x.data).collect()))
@@ -95,17 +93,16 @@ pub struct BlockInfo {
/// Build an in-memory CHT from a closure which provides necessary information
/// about blocks. If the fetcher ever fails to provide the info, the CHT
/// will not be generated.
pub fn build<F>(cht_num: u64, mut fetcher: F)
-> Option<CHT<MemoryDB<KeccakHasher, memory_db::HashKey<KeccakHasher>, DBValue>>>
pub fn build<F>(cht_num: u64, mut fetcher: F) -> Option<CHT<MemoryDB<KeccakHasher, DBValue>>>
where F: FnMut(BlockId) -> Option<BlockInfo>
{
let mut db = new_memory_db();
let mut db = MemoryDB::<KeccakHasher, DBValue>::new();
// start from the last block by number and work backwards.
let last_num = start_number(cht_num + 1) - 1;
let mut id = BlockId::Number(last_num);
let mut root = H256::zero();
let mut root = H256::default();
{
let mut t = TrieDBMut::new(&mut db, &mut root);
@@ -153,9 +150,9 @@ pub fn compute_root<I>(cht_num: u64, iterable: I) -> Option<H256>
/// verify the given trie branch and extract the canonical hash and total difficulty.
// TODO: better support for partially-checked queries.
pub fn check_proof(proof: &[Bytes], num: u64, root: H256) -> Option<(H256, U256)> {
let mut db = new_memory_db();
let mut db = MemoryDB::<KeccakHasher, DBValue>::new();
for node in proof { db.insert(hash_db::EMPTY_PREFIX, &node[..]); }
for node in proof { db.insert(&node[..]); }
let res = match TrieDB::new(&db, &root) {
Err(_) => return None,
Ok(trie) => trie.get_with(&key!(num), |val: &[u8]| {

View File

@@ -21,7 +21,8 @@ use std::sync::Arc;
use common_types::encoded;
use common_types::header::Header;
use common_types::receipt::Receipt;
use ethcore::engines::{Engine, StateDependentProof};
use ethcore::engines::{EthEngine, StateDependentProof};
use ethcore::machine::EthereumMachine;
use ethereum_types::H256;
use futures::future::IntoFuture;
@@ -47,8 +48,8 @@ pub trait ChainDataFetcher: Send + Sync + 'static {
fn epoch_transition(
&self,
_hash: H256,
_engine: Arc<Engine>,
_checker: Arc<StateDependentProof>
_engine: Arc<EthEngine>,
_checker: Arc<StateDependentProof<EthereumMachine>>
) -> Self::Transition;
}
@@ -76,8 +77,8 @@ impl ChainDataFetcher for Unavailable {
fn epoch_transition(
&self,
_hash: H256,
_engine: Arc<Engine>,
_checker: Arc<StateDependentProof>
_engine: Arc<EthEngine>,
_checker: Arc<StateDependentProof<EthereumMachine>>
) -> Self::Transition {
Err("fetching epoch transition proofs unavailable")
}

View File

@@ -35,10 +35,10 @@ use common_types::encoded;
use common_types::header::Header;
use common_types::ids::BlockId;
use ethcore::engines::epoch::{Transition as EpochTransition, PendingTransition as PendingEpochTransition};
use ethcore::error::{Error, EthcoreResult, BlockError};
use ethcore::error::{Error, EthcoreResult, ErrorKind as EthcoreErrorKind, BlockError};
use ethcore::spec::{Spec, SpecHardcodedSync};
use ethereum_types::{H256, H264, U256};
use parity_util_mem::{MallocSizeOf, MallocSizeOfOps};
use heapsize::HeapSizeOf;
use kvdb::{DBTransaction, KeyValueDB};
use parking_lot::{Mutex, RwLock};
use fastmap::H256FastMap;
@@ -95,8 +95,8 @@ struct Entry {
canonical_hash: H256,
}
impl MallocSizeOf for Entry {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
impl HeapSizeOf for Entry {
fn heap_size_of_children(&self) -> usize {
if self.candidates.spilled() {
self.candidates.capacity() * ::std::mem::size_of::<Candidate>()
} else {
@@ -154,11 +154,8 @@ fn pending_transition_key(block_hash: H256) -> H264 {
let mut key = H264::default();
{
let bytes = key.as_bytes_mut();
bytes[0] = LEADING;
bytes[1..].copy_from_slice(block_hash.as_bytes());
}
key[0] = LEADING;
key.0[1..].copy_from_slice(&block_hash.0[..]);
key
}
@@ -168,11 +165,8 @@ fn transition_key(block_hash: H256) -> H264 {
let mut key = H264::default();
{
let bytes = key.as_bytes_mut();
bytes[0] = LEADING;
bytes[1..].copy_from_slice(block_hash.as_bytes());
}
key[0] = LEADING;
key.0[1..].copy_from_slice(&block_hash.0[..]);
key
}
@@ -202,21 +196,14 @@ pub enum HardcodedSync {
Deny,
}
#[derive(MallocSizeOf)]
/// Header chain. See module docs for more details.
pub struct HeaderChain {
#[ignore_malloc_size_of = "ignored for performance reason"]
genesis_header: encoded::Header, // special-case the genesis.
candidates: RwLock<BTreeMap<u64, Entry>>,
#[ignore_malloc_size_of = "ignored for performance reason"]
best_block: RwLock<BlockDescriptor>,
#[ignore_malloc_size_of = "ignored for performance reason"]
live_epoch_proofs: RwLock<H256FastMap<EpochTransition>>,
#[ignore_malloc_size_of = "ignored for performance reason"]
db: Arc<KeyValueDB>,
#[ignore_malloc_size_of = "ignored for performance reason"]
col: Option<u32>,
#[ignore_malloc_size_of = "ignored for performance reason"]
cache: Arc<Mutex<Cache>>,
}
@@ -250,7 +237,7 @@ impl HeaderChain {
for c in &entry.candidates {
let key = transition_key(c.hash);
if let Some(proof) = db.get(col, key.as_bytes())? {
if let Some(proof) = db.get(col, &*key)? {
live_epoch_proofs.insert(c.hash, EpochTransition {
block_hash: c.hash,
block_number: cur_number,
@@ -267,7 +254,7 @@ impl HeaderChain {
let best_block = {
let era = match candidates.get(&curr.best_num) {
Some(era) => era,
None => return Err("Database corrupt: highest block referenced but no data.".into()),
None => bail!("Database corrupt: highest block referenced but no data."),
};
let best = &era.candidates[0];
@@ -416,7 +403,7 @@ impl HeaderChain {
.and_then(|entry| entry.candidates.iter().find(|c| c.hash == parent_hash))
.map(|c| c.total_difficulty)
.ok_or_else(|| BlockError::UnknownParent(parent_hash))
.map_err(Error::Block)?
.map_err(EthcoreErrorKind::Block)?
};
parent_td + *header.difficulty()
@@ -444,7 +431,7 @@ impl HeaderChain {
}
if let Some(transition) = transition {
transaction.put(self.col, transition_key(hash).as_bytes(), &transition.proof);
transaction.put(self.col, &*transition_key(hash), &transition.proof);
self.live_epoch_proofs.write().insert(hash, transition);
}
@@ -521,10 +508,10 @@ impl HeaderChain {
for ancient in &era_entry.candidates {
let maybe_transition = live_epoch_proofs.remove(&ancient.hash);
if let Some(epoch_transition) = maybe_transition {
transaction.delete(self.col, transition_key(ancient.hash).as_bytes());
transaction.delete(self.col, &*transition_key(ancient.hash));
if ancient.hash == era_entry.canonical_hash {
last_canonical_transition = match self.db.get(self.col, ancient.hash.as_bytes()) {
last_canonical_transition = match self.db.get(self.col, &ancient.hash) {
Err(e) => {
warn!(target: "chain", "Error reading from DB: {}\n
", e);
@@ -539,7 +526,7 @@ impl HeaderChain {
}
}
transaction.delete(self.col, ancient.hash.as_bytes());
transaction.delete(self.col, &ancient.hash);
}
let canon = &era_entry.candidates[0];
@@ -589,7 +576,7 @@ impl HeaderChain {
} else {
let msg = format!("header of block #{} not found in DB ; database in an \
inconsistent state", h_num);
return Err(msg.into());
bail!(msg);
};
let decoded = header.decode().expect("decoding db value failed");
@@ -660,7 +647,7 @@ impl HeaderChain {
match cache.block_header(&hash) {
Some(header) => Some(header),
None => {
match self.db.get(self.col, hash.as_bytes()) {
match self.db.get(self.col, &hash) {
Ok(db_value) => {
db_value.map(|x| x.into_vec()).map(encoded::Header::new)
.and_then(|header| {
@@ -785,7 +772,7 @@ impl HeaderChain {
/// Get block status.
pub fn status(&self, hash: &H256) -> BlockStatus {
if self.db.get(self.col, hash.as_bytes()).ok().map_or(false, |x| x.is_some()) {
if self.db.get(self.col, hash).ok().map_or(false, |x| x.is_some()) {
BlockStatus::InChain
} else {
BlockStatus::Unknown
@@ -795,13 +782,13 @@ impl HeaderChain {
/// Insert a pending transition.
pub fn insert_pending_transition(&self, batch: &mut DBTransaction, hash: H256, t: &PendingEpochTransition) {
let key = pending_transition_key(hash);
batch.put(self.col, key.as_bytes(), &*::rlp::encode(t));
batch.put(self.col, &*key, &*::rlp::encode(t));
}
/// Get pending transition for a specific block hash.
pub fn pending_transition(&self, hash: H256) -> Option<PendingEpochTransition> {
let key = pending_transition_key(hash);
match self.db.get(self.col, key.as_bytes()) {
match self.db.get(self.col, &*key) {
Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")),
Err(e) => {
warn!(target: "chain", "Error reading from database: {}", e);
@@ -845,6 +832,12 @@ impl HeaderChain {
}
}
impl HeapSizeOf for HeaderChain {
fn heap_size_of_children(&self) -> usize {
self.candidates.read().heap_size_of_children()
}
}
/// Iterator over a block's ancestry.
pub struct AncestryIter<'a> {
next: Option<encoded::Header>,

View File

@@ -19,7 +19,8 @@
use std::sync::{Weak, Arc};
use ethcore::client::{ClientReport, EnvInfo, ClientIoMessage};
use ethcore::engines::{epoch, Engine, EpochChange, EpochTransition, Proof};
use ethcore::engines::{epoch, EthEngine, EpochChange, EpochTransition, Proof};
use ethcore::machine::EthereumMachine;
use ethcore::error::{Error, EthcoreResult};
use ethcore::verification::queue::{self, HeaderQueue};
use ethcore::spec::{Spec, SpecHardcodedSync};
@@ -33,7 +34,6 @@ use common_types::blockchain_info::BlockChainInfo;
use common_types::encoded;
use common_types::header::Header;
use common_types::ids::BlockId;
use common_types::verification_queue_info::VerificationQueueInfo as BlockQueueInfo;
use kvdb::KeyValueDB;
@@ -91,9 +91,6 @@ pub trait LightChainClient: Send + Sync {
/// Attempt to get a block hash by block id.
fn block_hash(&self, id: BlockId) -> Option<H256>;
/// Get block queue information.
fn queue_info(&self) -> BlockQueueInfo;
/// Attempt to get block header by block id.
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
@@ -114,20 +111,20 @@ pub trait LightChainClient: Send + Sync {
fn env_info(&self, id: BlockId) -> Option<EnvInfo>;
/// Get a handle to the consensus engine.
fn engine(&self) -> &Arc<Engine>;
fn engine(&self) -> &Arc<EthEngine>;
/// Query whether a block is known.
fn is_known(&self, hash: &H256) -> bool;
/// Set the chain via a spec name.
fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()>;
/// Clear the queue.
fn clear_queue(&self);
/// Flush the queue.
fn flush_queue(&self);
/// Get queue info.
fn queue_info(&self) -> queue::QueueInfo;
/// Get the `i`th CHT root.
fn cht_root(&self, i: usize) -> Option<H256>;
@@ -159,7 +156,7 @@ impl<T: LightChainClient> AsLightClient for T {
/// Light client implementation.
pub struct Client<T> {
queue: HeaderQueue,
engine: Arc<Engine>,
engine: Arc<EthEngine>,
chain: HeaderChain,
report: RwLock<ClientReport>,
import_lock: Mutex<()>,
@@ -167,8 +164,6 @@ pub struct Client<T> {
listeners: RwLock<Vec<Weak<LightChainNotify>>>,
fetcher: T,
verify_full: bool,
/// A closure to call when we want to restart the client
exit_handler: Mutex<Option<Box<Fn(String) + 'static + Send>>>,
}
impl<T: ChainDataFetcher> Client<T> {
@@ -195,7 +190,6 @@ impl<T: ChainDataFetcher> Client<T> {
listeners: RwLock::new(vec![]),
fetcher,
verify_full: config.verify_full,
exit_handler: Mutex::new(None),
})
}
@@ -361,21 +355,13 @@ impl<T: ChainDataFetcher> Client<T> {
/// Get blockchain mem usage in bytes.
pub fn chain_mem_used(&self) -> usize {
use parity_util_mem::MallocSizeOfExt;
use heapsize::HeapSizeOf;
self.chain.malloc_size_of()
}
/// Set a closure to call when the client wants to be restarted.
///
/// The parameter passed to the callback is the name of the new chain spec to use after
/// the restart.
pub fn set_exit_handler<F>(&self, f: F) where F: Fn(String) + 'static + Send {
*self.exit_handler.lock() = Some(Box::new(f));
self.chain.heap_size_of_children()
}
/// Get a handle to the verification engine.
pub fn engine(&self) -> &Arc<Engine> {
pub fn engine(&self) -> &Arc<EthEngine> {
&self.engine
}
@@ -467,7 +453,7 @@ impl<T: ChainDataFetcher> Client<T> {
true
}
fn check_epoch_signal(&self, verified_header: &Header) -> Result<Option<Proof>, T::Error> {
fn check_epoch_signal(&self, verified_header: &Header) -> Result<Option<Proof<EthereumMachine>>, T::Error> {
use ethcore::machine::{AuxiliaryRequest, AuxiliaryData};
let mut block: Option<Vec<u8>> = None;
@@ -513,7 +499,7 @@ impl<T: ChainDataFetcher> Client<T> {
}
// attempts to fetch the epoch proof from the network until successful.
fn write_pending_proof(&self, header: &Header, proof: Proof) -> Result<(), T::Error> {
fn write_pending_proof(&self, header: &Header, proof: Proof<EthereumMachine>) -> Result<(), T::Error> {
let proof = match proof {
Proof::Known(known) => known,
Proof::WithState(state_dependent) => {
@@ -534,7 +520,6 @@ impl<T: ChainDataFetcher> Client<T> {
}
}
impl<T: ChainDataFetcher> LightChainClient for Client<T> {
fn add_listener(&self, listener: Weak<LightChainNotify>) {
Client::add_listener(self, listener)
@@ -542,10 +527,6 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
fn chain_info(&self) -> BlockChainInfo { Client::chain_info(self) }
fn queue_info(&self) -> queue::QueueInfo {
self.queue.queue_info()
}
fn queue_header(&self, header: Header) -> EthcoreResult<H256> {
self.import_header(header)
}
@@ -578,21 +559,10 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
Client::env_info(self, id)
}
fn engine(&self) -> &Arc<Engine> {
fn engine(&self) -> &Arc<EthEngine> {
Client::engine(self)
}
fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()> {
trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name);
if let Some(ref h) = *self.exit_handler.lock() {
(*h)(new_spec_name);
Ok(())
} else {
warn!("Not hypervised; cannot change chain.");
Err(())
}
}
fn is_known(&self, hash: &H256) -> bool {
self.status(hash) == BlockStatus::InChain
}
@@ -605,6 +575,10 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
Client::flush_queue(self);
}
fn queue_info(&self) -> queue::QueueInfo {
self.queue.queue_info()
}
fn cht_root(&self, i: usize) -> Option<H256> {
Client::cht_root(self, i)
}

View File

@@ -75,8 +75,9 @@ impl<T: ChainDataFetcher> Service<T> {
io_service.channel(),
cache,
)?);
spec.engine.register_client(Arc::downgrade(&client) as _);
io_service.register_handler(Arc::new(ImportBlocks(client.clone()))).map_err(Error::Io)?;
spec.engine.register_client(Arc::downgrade(&client) as _);
Ok(Service {
client,

View File

@@ -61,18 +61,15 @@ extern crate ethcore_io as io;
extern crate ethcore_network as network;
extern crate parity_bytes as bytes;
extern crate ethereum_types;
extern crate ethcore_miner as miner;
extern crate ethcore;
extern crate hash_db;
extern crate parity_util_mem;
extern crate parity_util_mem as mem;
extern crate parity_util_mem as malloc_size_of;
extern crate hashdb;
extern crate heapsize;
extern crate failsafe;
extern crate futures;
extern crate itertools;
extern crate keccak_hasher;
extern crate memory_db;
extern crate trie_db as trie;
extern crate memorydb;
extern crate patricia_trie as trie;
extern crate patricia_trie_ethereum as ethtrie;
extern crate fastmap;
extern crate rand;
@@ -88,10 +85,10 @@ extern crate keccak_hash as hash;
extern crate triehash_ethereum as triehash;
extern crate kvdb;
extern crate memory_cache;
extern crate derive_more;
#[macro_use]
extern crate error_chain;
#[cfg(test)]
extern crate kvdb_memorydb;
#[cfg(test)]
extern crate tempdir;
extern crate journaldb;

View File

@@ -199,15 +199,15 @@ pub struct FileStore(pub PathBuf);
impl SampleStore for FileStore {
fn load(&self) -> HashMap<Kind, VecDeque<u64>> {
File::open(&self.0)
.map_err(|e| Box::new(bincode::ErrorKind::Io(e)))
.and_then(|mut file| bincode::deserialize_from(&mut file))
.map_err(|e| Box::new(bincode::ErrorKind::IoError(e)))
.and_then(|mut file| bincode::deserialize_from(&mut file, bincode::Infinite))
.unwrap_or_else(|_| HashMap::new())
}
fn store(&self, samples: &HashMap<Kind, VecDeque<u64>>) {
let res = File::create(&self.0)
.map_err(|e| Box::new(bincode::ErrorKind::Io(e)))
.and_then(|mut file| bincode::serialize_into(&mut file, samples));
.map_err(|e| Box::new(bincode::ErrorKind::IoError(e)))
.and_then(|mut file| bincode::serialize_into(&mut file, samples, bincode::Infinite));
if let Err(e) = res {
warn!(target: "pip", "Error writing light request timing samples to file: {}", e);

View File

@@ -382,7 +382,7 @@ mod tests {
protocol_version: 1,
network_id: 1,
head_td: U256::default(),
head_hash: H256::zero(),
head_hash: H256::default(),
head_num: 10,
genesis_hash: H256::zero(),
last_head: None,
@@ -417,7 +417,7 @@ mod tests {
protocol_version: 1,
network_id: 1,
head_td: U256::default(),
head_hash: H256::zero(),
head_hash: H256::default(),
head_num: 10,
genesis_hash: H256::zero(),
last_head: None,
@@ -452,7 +452,7 @@ mod tests {
protocol_version: 1,
network_id: 1,
head_td: U256::default(),
head_hash: H256::zero(),
head_hash: H256::default(),
head_num: 10,
genesis_hash: H256::zero(),
last_head: None,
@@ -550,7 +550,7 @@ mod tests {
protocol_version: 1,
network_id: 1,
head_td: U256::default(),
head_hash: H256::zero(),
head_hash: H256::default(),
head_num: 10,
genesis_hash: H256::zero(),
last_head: None,

View File

@@ -22,7 +22,7 @@ use common_types::encoded;
use common_types::ids::BlockId;
use common_types::transaction::{Action, PendingTransaction};
use ethcore::client::{EachBlockWith, TestBlockChainClient};
use ethereum_types::{H256, U256, Address, BigEndianHash};
use ethereum_types::{H256, U256, Address};
use net::context::IoContext;
use net::load_timer::MOVING_SAMPLE_SIZE;
use net::status::{Capabilities, Status};
@@ -158,7 +158,7 @@ impl Provider for TestProvider {
fn contract_code(&self, req: request::CompleteCodeRequest) -> Option<request::CodeResponse> {
Some(CodeResponse {
code: req.block_hash.as_bytes().iter().chain(req.code_hash.as_bytes().iter()).cloned().collect(),
code: req.block_hash.iter().chain(req.code_hash.iter()).cloned().collect(),
})
}
@@ -261,7 +261,7 @@ fn genesis_mismatch() {
let (provider, proto) = setup(capabilities);
let mut status = status(provider.client.chain_info());
status.genesis_hash = H256::zero();
status.genesis_hash = H256::default();
let packet_body = write_handshake(&status, &capabilities, &proto);
@@ -472,16 +472,16 @@ fn get_state_proofs() {
}
let req_id = 112;
let key1: H256 = BigEndianHash::from_uint(&U256::from(11223344));
let key2: H256 = BigEndianHash::from_uint(&U256::from(99988887));
let key1: H256 = U256::from(11223344).into();
let key2: H256 = U256::from(99988887).into();
let mut builder = Builder::default();
builder.push(Request::Account(IncompleteAccountRequest {
block_hash: H256::zero().into(),
block_hash: H256::default().into(),
address_hash: key1.into(),
})).unwrap();
builder.push(Request::Storage(IncompleteStorageRequest {
block_hash: H256::zero().into(),
block_hash: H256::default().into(),
address_hash: key1.into(),
key_hash: key2.into(),
})).unwrap();
@@ -492,11 +492,11 @@ fn get_state_proofs() {
let response = {
let responses = vec![
Response::Account(provider.account_proof(CompleteAccountRequest {
block_hash: H256::zero(),
block_hash: H256::default(),
address_hash: key1,
}).unwrap()),
Response::Storage(provider.storage_proof(CompleteStorageRequest {
block_hash: H256::zero(),
block_hash: H256::default(),
address_hash: key1,
key_hash: key2,
}).unwrap()),
@@ -529,8 +529,8 @@ fn get_contract_code() {
}
let req_id = 112;
let key1: H256 = BigEndianHash::from_uint(&U256::from(11223344));
let key2: H256 = BigEndianHash::from_uint(&U256::from(99988887));
let key1: H256 = U256::from(11223344).into();
let key2: H256 = U256::from(99988887).into();
let request = Request::Code(IncompleteCodeRequest {
block_hash: key1.into(),
@@ -541,7 +541,7 @@ fn get_contract_code() {
let request_body = make_packet(req_id, &requests);
let response = {
let response = vec![Response::Code(CodeResponse {
code: key1.as_bytes().iter().chain(key2.as_bytes().iter()).cloned().collect(),
code: key1.iter().chain(key2.iter()).cloned().collect(),
})];
let new_creds = *flow_params.limit() - flow_params.compute_cost_multi(requests.requests()).unwrap();
@@ -616,9 +616,9 @@ fn proof_of_execution() {
let req_id = 112;
let mut request = Request::Execution(request::IncompleteExecutionRequest {
block_hash: H256::zero().into(),
from: Address::zero(),
action: Action::Call(Address::zero()),
block_hash: H256::default().into(),
from: Address::default(),
action: Action::Call(Address::default()),
gas: 100.into(),
gas_price: 0.into(),
value: 0.into(),
@@ -755,7 +755,7 @@ fn get_transaction_index() {
}
let req_id = 112;
let key1: H256 = BigEndianHash::from_uint(&U256::from(11223344));
let key1: H256 = U256::from(11223344).into();
let request = Request::TransactionIndex(IncompleteTransactionIndexRequest {
hash: key1.into(),

View File

@@ -24,6 +24,7 @@ use std::marker::PhantomData;
use std::sync::Arc;
use std::time::Duration;
use ethcore::executed::{Executed, ExecutionError};
use futures::{Poll, Future, Async};
use futures::sync::oneshot::{self, Receiver};
use network::PeerId;
@@ -40,10 +41,10 @@ use cache::Cache;
use request::{self as basic_request, Request as NetworkRequest};
use self::request::CheckedRequest;
pub use ethcore::executed::ExecutionResult;
pub use self::request::{Request, Response, HeaderRef, Error as ValidityError};
pub use self::request_guard::{RequestGuard, Error as RequestError};
pub use self::response_guard::{ResponseGuard, Error as ResponseGuardError, Inner as ResponseGuardInner};
pub use types::request::ResponseError;
#[cfg(test)]
@@ -53,6 +54,9 @@ pub mod request;
mod request_guard;
mod response_guard;
/// The result of execution
pub type ExecutionResult = Result<Executed, ExecutionError>;
/// The initial backoff interval for OnDemand queries
pub const DEFAULT_REQUEST_MIN_BACKOFF_DURATION: Duration = Duration::from_secs(10);
/// The maximum request interval for OnDemand queries
@@ -68,49 +72,28 @@ pub const DEFAULT_NUM_CONSECUTIVE_FAILED_REQUESTS: usize = 1;
pub mod error {
use futures::sync::oneshot::Canceled;
/// OnDemand Error
#[derive(Debug, derive_more::Display, derive_more::From)]
pub enum Error {
/// Canceled oneshot channel
ChannelCanceled(Canceled),
/// Timeout bad response
BadResponse(String),
/// OnDemand requests limit exceeded
#[display(fmt = "OnDemand request maximum backoff iterations exceeded")]
RequestLimit,
}
error_chain! {
impl std::error::Error for Error {
fn source(&self) -> Option<&(std::error::Error + 'static)> {
match self {
Error::ChannelCanceled(err) => Some(err),
_ => None,
foreign_links {
ChannelCanceled(Canceled) #[doc = "Canceled oneshot channel"];
}
errors {
#[doc = "Timeout bad response"]
BadResponse(err: String) {
description("Max response evaluation time exceeded")
display("{}", err)
}
#[doc = "OnDemand requests limit exceeded"]
RequestLimit {
description("OnDemand request maximum backoff iterations exceeded")
display("OnDemand request maximum backoff iterations exceeded")
}
}
}
/// OnDemand Result
pub type Result<T> = std::result::Result<T, Error>;
}
/// Public interface for performing network requests `OnDemand`
pub trait OnDemandRequester: Send + Sync {
/// Submit a strongly-typed batch of requests.
///
/// Fails if back-reference are not coherent.
fn request<T>(&self, ctx: &BasicContext, requests: T) -> Result<OnResponses<T>, basic_request::NoSuchOutput>
where
T: request::RequestAdapter;
/// Submit a vector of requests to be processed together.
///
/// Fails if back-references are not coherent.
/// The returned vector of responses will correspond to the requests exactly.
fn request_raw(&self, ctx: &BasicContext, requests: Vec<Request>)
-> Result<Receiver<PendingResponse>, basic_request::NoSuchOutput>;
}
// relevant peer info.
#[derive(Debug, Clone, PartialEq, Eq)]
struct Peer {
@@ -271,7 +254,7 @@ impl Pending {
response_err
);
let err = self::error::Error::BadResponse(err);
let err = self::error::ErrorKind::BadResponse(err);
if self.sender.send(Err(err.into())).is_err() {
debug!(target: "on_demand", "Dropped oneshot channel receiver on no response");
}
@@ -279,7 +262,7 @@ impl Pending {
// returning a peer discovery timeout during query attempts
fn request_limit_reached(self) {
let err = self::error::Error::RequestLimit;
let err = self::error::ErrorKind::RequestLimit;
if self.sender.send(Err(err.into())).is_err() {
debug!(target: "on_demand", "Dropped oneshot channel receiver on time out");
}
@@ -372,74 +355,6 @@ pub struct OnDemand {
request_number_of_consecutive_errors: usize
}
impl OnDemandRequester for OnDemand {
fn request_raw(&self, ctx: &BasicContext, requests: Vec<Request>)
-> Result<Receiver<PendingResponse>, basic_request::NoSuchOutput>
{
let (sender, receiver) = oneshot::channel();
if requests.is_empty() {
assert!(sender.send(Ok(Vec::new())).is_ok(), "receiver still in scope; qed");
return Ok(receiver);
}
let mut builder = basic_request::Builder::default();
let responses = Vec::with_capacity(requests.len());
let mut header_producers = HashMap::new();
for (i, request) in requests.into_iter().enumerate() {
let request = CheckedRequest::from(request);
// ensure that all requests needing headers will get them.
if let Some((idx, field)) = request.needs_header() {
// a request chain with a header back-reference is valid only if it both
// points to a request that returns a header and has the same back-reference
// for the block hash.
match header_producers.get(&idx) {
Some(ref f) if &field == *f => {}
_ => return Err(basic_request::NoSuchOutput),
}
}
if let CheckedRequest::HeaderByHash(ref req, _) = request {
header_producers.insert(i, req.0);
}
builder.push(request)?;
}
let requests = builder.build();
let net_requests = requests.clone().map_requests(|req| req.into_net_request());
let capabilities = guess_capabilities(requests.requests());
self.submit_pending(ctx, Pending {
requests,
net_requests,
required_capabilities: capabilities,
responses,
sender,
request_guard: RequestGuard::new(
self.request_number_of_consecutive_errors as u32,
self.request_backoff_rounds_max,
self.request_backoff_start,
self.request_backoff_max,
),
response_guard: ResponseGuard::new(self.response_time_window),
});
Ok(receiver)
}
fn request<T>(&self, ctx: &BasicContext, requests: T) -> Result<OnResponses<T>, basic_request::NoSuchOutput>
where T: request::RequestAdapter
{
self.request_raw(ctx, requests.make_requests()).map(|recv| OnResponses {
receiver: recv,
_marker: PhantomData,
})
}
}
impl OnDemand {
/// Create a new `OnDemand` service with the given cache.
@@ -500,6 +415,77 @@ impl OnDemand {
me
}
/// Submit a vector of requests to be processed together.
///
/// Fails if back-references are not coherent.
/// The returned vector of responses will correspond to the requests exactly.
pub fn request_raw(&self, ctx: &BasicContext, requests: Vec<Request>)
-> Result<Receiver<PendingResponse>, basic_request::NoSuchOutput>
{
let (sender, receiver) = oneshot::channel();
if requests.is_empty() {
assert!(sender.send(Ok(Vec::new())).is_ok(), "receiver still in scope; qed");
return Ok(receiver);
}
let mut builder = basic_request::Builder::default();
let responses = Vec::with_capacity(requests.len());
let mut header_producers = HashMap::new();
for (i, request) in requests.into_iter().enumerate() {
let request = CheckedRequest::from(request);
// ensure that all requests needing headers will get them.
if let Some((idx, field)) = request.needs_header() {
// a request chain with a header back-reference is valid only if it both
// points to a request that returns a header and has the same back-reference
// for the block hash.
match header_producers.get(&idx) {
Some(ref f) if &field == *f => {}
_ => return Err(basic_request::NoSuchOutput),
}
}
if let CheckedRequest::HeaderByHash(ref req, _) = request {
header_producers.insert(i, req.0);
}
builder.push(request)?;
}
let requests = builder.build();
let net_requests = requests.clone().map_requests(|req| req.into_net_request());
let capabilities = guess_capabilities(requests.requests());
self.submit_pending(ctx, Pending {
requests,
net_requests,
required_capabilities: capabilities,
responses,
sender,
request_guard: RequestGuard::new(
self.request_number_of_consecutive_errors as u32,
self.request_backoff_rounds_max,
self.request_backoff_start,
self.request_backoff_max,
),
response_guard: ResponseGuard::new(self.response_time_window),
});
Ok(receiver)
}
/// Submit a strongly-typed batch of requests.
///
/// Fails if back-reference are not coherent.
pub fn request<T>(&self, ctx: &BasicContext, requests: T) -> Result<OnResponses<T>, basic_request::NoSuchOutput>
where T: request::RequestAdapter
{
self.request_raw(ctx, requests.make_requests()).map(|recv| OnResponses {
receiver: recv,
_marker: PhantomData,
})
}
// maybe dispatch pending requests.
// sometimes

Some files were not shown because too many files have changed in this diff Show More