Compare commits

...

100 Commits

Author SHA1 Message Date
Talha Cross
d6c55469c9 backports for stable 2.4.7 (#10736)
* version: bump stable to 2.4.7

* [CI] allow cargo audit to fail (#10676)

* [CI] allow cargo audit to fail

* [.gitlab-ci.yml] add a comment about cargo audit

* [Cargo.lock] cargo update -p protobuf

* new image (#10673)

* Update publishing (#10644)

* docker images are now built on k8s: test run

* copy check_sync.sh in build-linux job

* copy scripts/docker/hub/* in build-linux job

* removed cache var

* cleanup, no more nightly dockers

* cleanup in dockerfile

* some new tags

* removed sccsche debug log, cleanup

* no_gits, new artifacts dir, changed scripts. Test run.

* define version once

* one source for TRACK

* stop kovan onchain updates

* moved changes for two images to a new branch

* rename Dockerfile

* no need in libudev-dev

* enable lto for release builds (#10717)

* Use RUSTFLAGS to set the optimization level (#10719)

* Use RUSTFLAGS to set the optimization level

Cargo has a [quirk]() in how configuration settings are propagated when `cargo test` runs: local code respect the settings in `[profile.test]` but all dependencies use the `[profile.dev]` settings. Here we force `opt-level=3` for all dependencies.

* Remove unused profile settings

* Maybe like this?

* Turn off incremental compilation

* Remove colors; try again with overflow-checks on

* Use quiet CI machine

* Turn overflow checking back on

* Be explicit about what options we use

* Remove "quiet machine" override

* ethcore: enable ECIP-1054 for classic (#10731)

* config: enable atlantis on ethereum classic

* config: enable atlantis on morden classic

* config: enable atlantis on morden classic

* config: enable atlantis on kotti classic

* ethcore: move kotti fork block to 0xAEF49

* ethcore: move morden fork block to 0x4829BA

* ethcore: move classic fork block to 0x81B320

* remove trailing comma

* remove trailing comma

* fix chainspec

* ethcore: move classic fork block to 0x7fffffffffffffff
2019-06-11 20:50:37 +02:00
Talha Cross
94164e1ca5 stable ci: backport missing diff from master (#10662)
* ci: publish docs debug (#10638)

* ci: backport missing diff from master
2019-05-14 15:03:08 +02:00
Talha Cross
9bb75d8dda ci: publish docs debug (#10638) (#10659) 2019-05-14 14:04:28 +02:00
Talha Cross
e78a9872c0 stable 2.4.6 (#10642)
* version: bump stable to 2.4.6

* fix(whisper expiry): current time + work + ttl (#10587)

* update bootnodes (#10595)

* config: update goerli bootnodes

* config: update kotti bootnodes

* Constantinople HF on POA Core (#10606)

* Constantinople HF on POA Core

Plan Constantinople/St.Petersfork HF on POA Core network at block 8582254.
Original PR in POA repository: https://github.com/poanetwork/poa-chain-spec/pull/110

* Remove extra empty line

* evm: add some mulmod benches (#10600)

* evm: add blockhash_mulmod bench

* evm: use num-bigint for mod ops

* Update kovan.json to switch validator set to POA Consensus Contracts (#10628)

* Fix publish docs (#10635)

* Fix publish docs

* this never should be forced, either way compiling previous versions will produce outdated docs

* fix array, var was moved to the group project global variables list
2019-05-10 13:48:40 +02:00
Talha Cross
76d4064a4c Reject crazy timestamps instead of truncating. (#10575) 2019-04-08 13:27:32 +02:00
Talha Cross
a03cf2ed43 separate docker image to build docs (#10543) (#10561) 2019-04-05 13:30:58 +02:00
soc1c
b6a764deb2 version: stabilize 2.4 2019-04-02 09:36:25 +02:00
Niklas Adolfsson
8f6911af20 2.4.4 more beta backports (#10554)
* fix(rpc-types): replace uint and hash with `ethereum_types v0.4` (#10217)

* fix(rpc-types): remove uint and hash wrappers

* fix(tests)

* fix(cleanup)

* grumbles(rpc-api): revert `verify_signature`

* revert change of `U64` -> `u64`

* fix(cleanup after bad merge)

* chore(bump ethereum-types)

* fix(bad merge)

* feat(tests ethereum-types): add tests

* chore(update `ethereum-types` to 0.4.2)

* feat(tests for h256)

* chore(rpc): remove `ethbloom` import

Use re-export from `ethereum-types` instead

* fix(bad merge): remove `DefaultAccount` type

* doc(add TODO with issue link)

* chore(bump ethereum-types) (#10396)

Fixes a de-serialization bug in `ethereum-tyes`

* fix(light eth_gasPrice): ask network if not in cache (#10535)

* fix(light eth_gasPrice): ask N/W if not in cache

* fix(bad rebase)

* fix(light account response): update `tx_queue` (#10545)

* fix(bump dependencies) (#10540)

* cargo update -p log:0.4.5

* cargo update -p regex:1.0.5

* cargo update -p parking_lot

* cargo update -p serde_derive

* cargo update -p serde_json

* cargo update -p serde

* cargo update -p lazy_static

* cargo update -p num_cpus

* cargo update -p toml

# Conflicts:
#	Cargo.lock

* tx-pool: check transaction readiness before replacing (#10526)

* Update to vanilla tx pool error

* Prevent a non ready tx replacing a ready tx

* Make tests compile

* Test ready tx not replaced by future tx

* Transaction indirection

* Use StateReadiness to calculate Ready in `should_replace`

* Test existing txs from same sender are used to compute Readiness

* private-tx: Wire up ShouldReplace

* Revert "Use StateReadiness to calculate Ready in `should_replace`"

This reverts commit af9e69c8

* Make replace generic so it works with private-tx

* Rename Replace and add missing docs

* ShouldReplace no longer mutable

* tx-pool: update to transaction-pool 2.0 from crates.io

* tx-pool: generic error type alias

* Exit early for first unmatching nonce

* Fix private-tx test, use existing write lock

* Use read lock for pool scoring

* fix #10390 (#10391)

* private-tx: replace error_chain (#10510)

* Update to vanilla tx pool error

* private-tx: remove error-chain, implement Error, derive Display

* private-tx: replace ErrorKind and bail!

* private-tx: add missing From impls and other compiler errors

* private-tx: use original tx-pool error

* Don't be silly cargo
2019-04-01 17:04:50 +02:00
Talha Cross
d30610621f 2.4.4 beta backports (#10533)
* version: bump beta

* fix Sha3/keccak256 hash calculation for binaries (#10509)

https://github.com/paritytech/parity-ethereum/issues/10495

* verbose flag for cpp tests (#10524)

* Initial support sccache for windows build (#10520)

* Initial support sccache for win build

* show sccache stats

* cache paths for shared runners

* sccache status is in the script.

* removed windows test for now

* ethcore: remove eth social and easthub chain configs (#10531)

* Fix max_gas (#10537)

Fix max_gas

* build android with cache, win fixes (#10546)

* build android with cache!

* windows fixes

* windows fixes 2

* windows fixes 3

* windows fixes 4

* windows should have sccache variables in env variables

* Update light client harcoded headers (#10547)

* kovan #10643457

* ropsten #5296129

* foundation #7460865

* classic #7747585

* indentation

* morden #3973121
2019-04-01 10:51:06 +02:00
Sočik
33860c3f32 2.4.3 beta backports (#10508)
* version: bump beta

* Add additional request tests (#10503)
2019-03-22 10:23:45 +01:00
Sočik
e1c1ecf0a5 2.4.2 beta backports (#10488)
* version: bump beta

* Сaching through docker volume (#10477)

* _old codebase_ before docker update

* before docker update, testing runnr

* docker update, testing the caching

* distributed job cargo homes

* distributed job cargo homes 2

* distributed job cargo homes 3

* dockerfile with gitlab checkout, audit uses template

* dockerfile gets repo in volume

* change builds_dir

* trying docker cache for repo

* repo cached automatically

* after script is not concatenated

* check sccache non-cacheable reasons nature

* watch cache

* log sccache

* log sccache 2

* debug log sccache

* fix debug log sccache

* fix debug log sccache 2

* debug log cache 3

* debug log cache 3

* trace log all sccache

* test wo cargo cache

* test w removed cargo cache

* report non-cacheable reasons, cargo cache is back and empty

* report non-cacheable reasons, cargo cache is back and empty 2

* report non-cacheable reasons, cargo cache is back and empty 3

* wrap into after_script

* restore CI tags

`qa` -> `linux-docker`

* return to main runners, this will fail until config on runners And Dockerfile won't be updated

* typo fix CI lint

* return to docker tag

* fix win&mac build (#10486)

add CARGO_HOME:                      "${CI_PROJECT_DIR}/.cargo"

* fix(extract `timestamp_checked_add` as lib) (#10383)

* fix(extract `timestamp_checked_add` as lib)

* fix(whisper types): remove unused `EmptyTopics`

* fix(time-lib): feature-flag to use time-lib or std

This commit adds conditional compilation checks that falls back to `our time-lib` when
`time_checked_add` is not available in the standard library

Note, `time_checked_add` covers both `checked_add` and `checked_sub`

* fix(grumble): use cfg_attr to define rustc feature
2019-03-20 09:17:30 +01:00
Sočik
72c8b79035 2.4.1 beta backports (#10471)
* version: bump beta

* Implement parity_versionInfo & parity_setChain on LC; fix parity_setChain (#10312)

* Light client: implement parity_versionInfo RPC

* Light client: implement set_exit_handler & parity_setChain RPC

* parity_setChain RPC: return an error if failed (instead of `true`)

* Implement eth_subscribe('syncing') RPC for full node & light node

* Fix indentation

* Revert commit: Implement eth_subscribe('syncing')

* Revert change to Cr callback function

* CI publish to aws (#10446)

* move publish aws from gitlab.yml to gitlab scripts

* gitlab.yml cleaning
move publish AWS to gitlab scripts
remove dependencies from android build

* CI aws git checkout (#10451)

* Updating the CI system with the publication of releases and binary files on github

Signed-off-by: Denis S. Soldatov aka General-Beck <general.beck@gmail.com>

* move publish aws from gitlab.yml to gitlab scripts

Signed-off-by: Denis S. Soldatov aka General-Beck <general.beck@gmail.com>

* gitlab.yml cleaning
move publish AWS to gitlab scripts
remove dependencies from android build

Signed-off-by: Denis S. Soldatov aka General-Beck <general.beck@gmail.com>

* Revert "Updating the CI system with the publication of releases and binary files on github"

This reverts commit da87e06f2e4751dbca08a898b52926aef5ad0aba.

* remove no-git for aws

* microfix

* no need in no_git then

* Revert "CI aws git checkout (#10451)" (#10456)

* Revert "CI aws git checkout (#10451)"

This reverts commit 3e1d73126c.

* Update .gitlab-ci.yml

revert aws script with small fixes

* Delete publish-aws.sh

* Tests parallelized (#10452)

* tests splitted, phase 1

* typo

* fix wrong launch commands

* typos

* rearrangements

* use `nproc` function for threads

* use nproc for threads

* let theads be auto, build-andriod no more in regular run

* split val chain and cargo check

* renamed some files

* wrong phase

* check rust files before test jobs

* lint error

* rust files modivied var

* test except changes

* add rust_changes except

* lint error

* fixes

* .gitlab-ci.yml can't be excluded

* pipeline shouldn't start

* pipeline must go

* pipeline must go 2

* pipeline must go 3

* pipeline must go 4

* pipeline must go 5

* pipeline must go 6

* pipeline must go 7

* pipeline must not go 1

* pipeline must go 8

* avoid skippng tests yet, reintroducing them after the caching

* test theory

* parallelized cargo check with combusting helicopters

* less uploads

* alias for cargo checks

* nice template

* Ensure static validator set changes are recognized (#10467)
2019-03-19 09:10:36 +01:00
Hernando Castano
c7d8ee1dd7 More Backports for Beta 2.4.0 (#10431)
* revert some changes, could be buggy (#10399)

* 10000 > 5000 (#10422)

addresses #10418

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

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

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

* 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:29 +01:00
Hernando Castano
ce9f4c65d3 Backports for Beta 2.4.0 (#10416)
* 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

* Fix to_pod storage trie value decoding (#10368)

* 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
2019-02-25 15:24:51 +01:00
5chdn
ab0ad1925b version: mark 2.4.0 beta 2019-02-21 11:25:29 +01:00
cheme
6bb106a784 Update to latest mem-db, hash-db and trie-db. (#10314)
* Switch to 'trie' crates, there is an unpublished deps to staging
parity-common triehash still.

* Use crates.io dependency.

* indentation

* Update util/journaldb/src/traits.rs

indentation

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

* Update ethcore/src/snapshot/tests/state.rs

Co-Authored-By: cheme <emericchevalier.pro@gmail.com>
2019-02-20 21:09:34 +03:00
Andrew Jones
4e0ec4e66b tx pool: always accept local transactions (#10375)
* tx pool: always accept local transactions

* tx pool: `choose` local txs with same sender and nonce
2019-02-20 16:49:39 +00:00
Niklas Adolfsson
b58a3ed0ad fix(trace_main! macro): don't re-export (#10384) 2019-02-20 10:52:28 +01:00
felix
b803f57db6 exchanged old(azure) bootnodes with new(ovh) ones (#10309)
* exchanged old(azure) bootnodes with new(ovh) ones

* Fix indent
2019-02-20 10:06:26 +01:00
André Silva
b457f46c81 ethash: implement Progpow (#9762)
* ethash: initial implementation of progpow

* progpow: use wrapping arithmetic

* progpow: cleanup comments

* progpow: fix keccak_f800

* progpow: reorder definitions

* progpow: general fixing

* progpow: add basic tests from geth

* progpow: generate c_dag and add test

* progpow: fix progpow_init and progpow_loop

* progpow: fix and add new test

* progpow: tabify

* progpow: add shared testvectors from geth and aleth

* progpow: add benchmarks

* progpow: don't read bytes from dag

* ethash: use criterion for progpow benchmarks

* progpow: dont borrow hash on fnv1a_hash

* progpow: don't borrow operand on progpow merge

* progpow: hardcode dag lookup function

we only support light verification anyway

* progpow: read double words directly from the dag

* progpow: inline some small functions

* progpow: remove some bounds checking from the main loop

* progpow: remove unreachable match cases

* progpow: remove bounds check in keccak_f800_round

* progpow: fix ptr::swap

* progpow: force loop unroll in keccak_f800_round

* progpow: remove unnecessary branching in progpow_loop

* progpow: force loop unroll in fill_mix

* progpow: silence unused warning

* progpow: dont run last keccak_f800_round out of the loop

rustc generates the same assembly, it unrolls the loop

* progpow: fix output of keccak_f800_short

* ethcore: support progpow in ethash engine

* ethash: fix typo

* ethcore, ethash: fix tests

* json: fix ethash spec tests

* ethash: update quick_get_difficulty for progpow

* ethash: drop light cache on progpow transition block

* ethash: fix quick_get_difficulty tests

* progpow: update to spec v0.9.0

* progpow: update to spec v0.9.1

* progpow: update to spec v0.9.2

* ethash: rename progpow benchmarks

* fix Cargo.lock bad merge

* ethash: only export modules for benchmarks

* ethash: progpow: remove unsafe unchecked indexing

* ethash: create enum for pow algorithm

* ethash: box the progpow cdag

* ethash: skip slow progpow test vectors on ci

* ethash: don't skip progpow test vectors

they don't take too long when running in release mode which is the case
for CI.

* ethash: progpow: update copyright date

Co-Authored-By: andresilva <andre.beat@gmail.com>

* ethcore: remove verification of ci-skip-tests on non-test builds
2019-02-20 10:05:11 +01:00
Leo Arias
b4520c5886 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.
2019-02-20 09:49:54 +01:00
Psilon
ca67dc251f Add message to IO errors (#10324) 2019-02-18 20:39:38 +03:00
Niklas Adolfsson
aea289e79e chore(bump parity-daemonize): require rust >= 1.31 (#10359) 2019-02-18 13:38:46 +01:00
Svyatoslav Nikolsky
ef0eda0c39 SecretStore: use in-memory transport in cluster tests (#9850)
* fixing SS tests

* removed some redundant clones

* fixed grumbles

* replaced hash.clone() with *hash + fixed comment

* lost files
2019-02-18 13:38:19 +01:00
Hernando Castano
af7dc3676b Add fields to memzero's Cargo.toml (#10362)
* Add fields to Cargo.toml before publishing to crates.io

* Change license from MIT to GPL-3.0

* Add docs page
2019-02-15 12:32:33 +01:00
Afri Schoedon
fa570f297e snap: release untagged versions from branches to the candidate snap channel (#10357) 2019-02-14 17:24:52 +01:00
Niklas Adolfsson
9cce6a47d4 fix(compilation warns): no-default-features (#10346) 2019-02-14 17:54:44 +03:00
TriplEight
bff0bedfa9 no volumes are needed, just run -v volume:/path/in/the/container (#10345) 2019-02-14 12:45:56 +01:00
Dan Acristinii
d6c80c1672 Fixed misstype (#10351)
* Fixed misstype

BadTransactonType => BadTransactionType

* fixed other insances of transacton
2019-02-14 12:25:44 +01:00
Afri Schoedon
512343003d snap: prefix version and populate candidate channel (#10343)
* snap: populate candidate releases with beta snaps to avoid stale channel

* snap: prefix version with v*
2019-02-13 15:50:02 +01:00
elferdo
3adb640d2b Bundle protocol and packet_id together in chain sync (#10315)
Define a new `enum` where devp2p subprotocol packet ids (currently eth and par) are defined. Additionally provide functionality to query id value and protocol of a given id object.
2019-02-13 09:20:33 +01:00
gabriel klawitter
ea589a17a4 role back docker build image and docker deploy image to ubuntu:xenial based (#10338) 2019-02-12 20:52:30 +01:00
gabriel klawitter
a3883ca5d9 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
2019-02-12 19:00:52 +01:00
Kirill Pimenov
5be0163cde 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
2019-02-12 16:57:53 +01:00
Shude Li
55454b2f2d fix(docker): fix not receives SIGINT (#10059)
* fix(docker): fix not receives SIGINT

* fix: update with reviews

* update with review

* update

* update
2019-02-12 16:57:07 +01:00
TriplEight
a4dc85543b 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
2019-02-12 15:37:54 +01:00
Niklas Adolfsson
d8394bded7 fix(add helper for timestamp overflows) (#10330)
* fix(add helper timestamp overflows)

* fix(simplify code)

* fix(make helper private)
2019-02-12 14:16:23 +00:00
cheme
d89b8d904f Additional error for invalid gas (#10327)
* Tag sensible place (ECHECH)

* Additional overflows checks.
2019-02-11 22:20:51 +00:00
Hernando Castano
8e866ee551 Revive parity_setMinGasPrice RPC call (#10294)
* Add function to update minimum gas price

* Update TestMinerService to handle min_gas_price changes

* Place minimum gas price test behind feature flag

* Update check for fixed gas pricer to be more explicit

* Use errors::unsupported instead of errors::request_rejected

* Add test that fails to set minimum gas price

* Fix test that should fail when setting new gas price

* Put dev dependencies behind feature flag

* Fix deadlock in set_minimal_gas_price()

* Update RPC tests with mocked error response

* Remove unnecessary cfg flag

* Remove duplicate crate imports
2019-02-11 18:08:12 +01:00
Hernando Castano
6dfc1bd474 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
2019-02-11 17:13:36 +01:00
Niklas Adolfsson
c84e5745fa fix(parity-clib): grumbles that were not addressed in #9920 (#10154)
* fix(remove needless unsafe blocks)

* style(nits)

* fix(parity-clib): eliminate repetitive event loops

* revert(java bindings): safe rust -> unsafe rust

These functions can still end up with `UB` thus should be unsafe

* fix(grumbles): make Callback trait `pub (crate)`
2019-02-11 15:27:46 +01:00
Niklas Adolfsson
751d15e4be fix(light-rpc): Make light_sync generic (#10238)
* fix(light-rpc): Make `light_sync` generic

The motivation behind this change is to easily mock `light-sync` to make it possible to enable `rpc-integration` tests
for the light-client.

Currently the `rpc's` requires the concrete type `sync::LightSync` which makes it very hard to do so

* fix(bad merge)
2019-02-11 10:33:16 +00:00
TriplEight
8b6c5be6a9 fix publish job (#10317)
* fix publish job

* dashes and colonels
2019-02-08 18:22:08 +01:00
Axel Chalon
3502b36232 Secure WS-RPC: grant access to all apis (#10246) 2019-02-08 14:11:55 +01:00
elferdo
046b8bbc8a Make specification of protocol in SyncRequester::send_request explicit (#10295)
* Make the specification of the protocol to which a packet_id belongs to
  explicit when calling "SyncRequester::send_packet".

* Remove "SyncIO::send" and leave only "SyncIO::send_protocol"

* Adapt tests to new code.

* Strengthen tests to check if packet_id and protocol match when sending
a devp2p packet.
2019-02-08 13:01:29 +01:00
Alexander Arlt
6fa4b2dec5 fix: parity-clib/examples/cpp/CMakeLists.txt (#10313)
* use of ${CMAKE_SHARED_LIBRARY_PREFIX} &
${CMAKE_SHARED_LIBRARY_SUFFIX} to support other operating systems.
2019-02-08 12:01:29 +03:00
TriplEight
83bcb819da 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
2019-02-07 18:49:50 +01:00
elferdo
b7e8621846 Increase number of requested block bodies in chain sync (#10247)
* Increase the number of block bodies requested during Sync.

* Increase the number of block bodies requested during Sync.

* Check if our peer is an older parity client with the bug
  of not handling large requests properly

* Add a ClientVersion struct and a ClientCapabilites trait

* Make ClientVersion its own module

* Refactor and extend use of ClientVersion

* Replace strings with ClientVersion in PeerInfo

* Group further functionality in ClientCapabilities

* Move parity client version data from tuple to its own struct.

* Implement accessor methods for ParityClientData and remove them
from ClientVersion.

* Minor fixes

* Make functions specific to parity return types specific to parity.

* Test for shorter ID strings

* Fix formatting and remove unneeded dependencies.

* Roll back Cargo.lock

* Commit last Cargo.lock

* Convert from string to ClientVersion

* * When checking if peer accepts service transactions just check
  if it's parity, remove version check.

* Remove dependency on semver in ethcore-sync

* Remove unnecessary String instantiation

* Rename peer_info to peer_version

* Update RPC test helpers

* Simplify From<String>

* Parse static version string only once

* Update RPC tests to new ClientVersion struct

* Document public members

* More robust parsing of ID string

* Minor changes.

* Update version in which large block bodies requests appear.

* Update ethcore/sync/src/block_sync.rs

Co-Authored-By: elferdo <elferdo@gmail.com>

* Update util/network/src/client_version.rs

Co-Authored-By: elferdo <elferdo@gmail.com>

* Update util/network/src/client_version.rs

Co-Authored-By: elferdo <elferdo@gmail.com>

* Update tests.

* Minor fixes.
2019-02-07 15:27:09 +01:00
Tomasz Drwięga
d5c19f8719 Deprecate account management (#10213)
* Extract accounts from ethcore.

* Fix ethcore.

* Get rid of AccountProvider in test_helpers

* Fix rest of the code.

* Re-use EngineSigner, fix tests.

* Simplify EngineSigner to always have an Address.

* Fix RPC tests.

* Add deprecation notice to RPCs.

* Feature to disable accounts.

* extract accounts in RPC

* Run with accounts in tests.

* Fix RPC compilation and tests.

* Fix compilation of the binary.

* Fix compilation of the binary.

* Fix compilation with accounts enabled.

* Fix tests.

* Update submodule.

* Remove android.

* Use derive for Default

* Don't build secretstore by default.

* Add link to issue.

* Refresh Cargo.lock.

* Fix miner tests.

* Update rpc/Cargo.toml

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

* Fix private tests.
2019-02-07 14:34:24 +01:00
Wei Tang
8fa56add47 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
2019-02-07 14:34:07 +01:00
Niklas Adolfsson
e45ee6cd72 fix(osx and windows builds): bump parity-daemonize (#10291) 2019-02-07 12:53:12 +01:00
Julien Bouteloup
e344286c32 Add missing step for Using systemd service file (#10175)
* Add missing step for  Using `systemd` service file

Copy Parity release from target folder to bin, write `cp -R ./target/release/parity /usr/bin/` to match `ExecStart=/usr/bin/parity --config /etc/parity/config.toml` from `https://github.com/paritytech/parity-ethereum/blob/master/scripts/parity.service`

* Copy release to bin folder using sudo install

`sudo install ./target/release/parity /usr/bin/parity`
2019-02-07 12:50:15 +01:00
Anton Gavrilov
45d7c60608 Call private contract methods from another private contract (read-only) (#10086)
* Patch available private contracts during private transaction

* Key acl ABI added

* Work with secret store keys moved to the separate struct

* Private tx test refactored

* Revert "Private tx test refactored"

This reverts commit 476c132d692c7a886bc7b7cd7fe47b3d7692bd63.

* Test for calling private contract from another one added

* Test fixed

* Redundant tab removed

* ACL contract processing fixed, test added

* Merge with head

* Expect replaced with closure
2019-02-07 12:39:04 +01:00
Andronik Ordian
a3e39c9858 update ring to 0.14 (#10262)
* cargo upgrade hyper-rustls --all

* cargo upgrade parity-crypto --all

* update Cargo.lock

* propagate NonZeroU32

* use NonZeroU32::new_unchecked for crypto::KEY_ITERATIONS

* update Cargo.lock

* replace unsafe code with lazy_static
2019-02-06 17:53:34 +01:00
Niklas Adolfsson
8ab6d89810 fix(secret-store): deprecation warning (#10301)
use of deprecated item 'core::str::<impl str>::trim_left_matches': superseded by `trim_start_matches`
2019-02-06 16:54:35 +03:00
Andrew Jones
1b3b9b2887 Update to jsonrpc-derive 10.0.2, fixes aliases bug (#10300) 2019-02-05 14:47:25 +00:00
Andrew Jones
89ae0f0ea0 Convert to jsonrpc-derive, use jsonrpc-* from crates.io (#10298)
* Use jsonrpc crates on local path

* Convert all RPC traits to use jsonrpc-derive

* Use local jsonrpc at top level

* Upgrade remaining jsonrpc dependencies

* Checkout Cargo.lock to master HEAD

* Use jsonrpc-* 10.0.1 from crates.io

* Attribute after docs
2019-02-05 14:31:19 +01:00
Pierre Krieger
06cae8a535 Fix Windows build (#10284) 2019-02-03 13:32:06 +01:00
Pierre Krieger
12ac992ffb Don't run the CPP example on CI (#10285)
* Don't run the CPP example on CI

* Add comment
2019-02-03 13:23:07 +01:00
Tomasz Drwięga
3b23c2e86d Additional tests for uint deserialization. (#10279) 2019-02-03 12:26:25 +01:00
Seun LanLege
0f9b2218da prevent silent errors in daemon mode (#10007)
* prevent silent errors in daemon mode

* change author in Cargo.toml, add preamble to pipe.rs

* set the uid and gid on daemon process, fix permission errors when writing to pid file

* call setup_logger before daemonize to prevent crashing when attempting to create logfile

* map_err for calls to splice and ioctl, fix spaces in Cargo.toml

* split out daemonize to own repo

* removed util/daemonize

* renamed dep to parity-daemonize

* fix(parity-clib): enable `logger`

* bump parity-daemonize

* remove obsolete comment

Co-Authored-By: seunlanlege <seunlanlege@gmail.com>

* fix(grumbles): docs and log in ParityParams

* Add FIXME comment regarding @tomaka grumbles
* Unify logger with the C-API in ParityParams (less type-safety with more from_raw() conversions)
* Add better documentation in the `parity.h`

* Apply suggestions from code review

Co-Authored-By: seunlanlege <seunlanlege@gmail.com>

* docs(parity lib): add link to logging issue

* fix(parity-clib): JNI enable `logger`

* fix(parity-clib): update `Java example`

* Update example to the API changes
* Remove needless printouts which can be controlled via logger instead
2019-02-01 19:31:02 +01:00
Tomasz Drwięga
12c42bce9b Fix join-set test to be deterministic. (#10263) 2019-01-30 12:57:38 +00:00
Gabriel Majoulet
eb3d33ed6f Update CHANGELOG-2.2.md (#10254) 2019-01-29 10:13:21 +01:00
cheme
a139c6d216 Macos heapsize force jemalloc (#10234)
* Switch to non prefixed malloc_size_of on macos

* Fix

* Testing darwin build

* Fix import

* conflict

* switch heapsize deps commit

* switch heapsize commit

* Rename branch

* Restore gitlab ci to origin

* test for mac

* mac tests?

* Switch of macos CI tests.
2019-01-29 09:26:22 +01:00
Andrew Plaza
50f5ccc4f2 Allow specifying local accounts via CLI (#9960)
* Allow specifying local accounts via CLI

 * Add `tx-queue-locals` CLI option
 * ethcore: modify miner to check options vec before importing transaction
 * modify tests (ethcore/parity)
Resolves #9634

* fix formatting

* fixes: Make prefer HashSet over Vec<>, add test, comment formatting

* Update ethcore/src/miner/miner.rs

Co-Authored-By: insipx <aplaza@liquidthink.net>

* Fix comments and add helper for set->vec conversion

* remove blank line from use statement

* fix helper test

* formatting

* fix test to pass on nightly

* revert test fix for nightly
2019-01-28 11:26:11 +01:00
Vladyslav Lupashevskyi
94db961975 Take in account zero gas price certification when doing transact_contract (#10232)
* Tx permission contract improvement

* Take in account zero gas price certification when doing transact_contract

* DRY in ServiceTransactionChecker

* Fix typos and regroup mod

* Fix imports

* Simplify code in struct instantiation

Co-Authored-By: VladLupashevskyi <vlad@lupashevskyi.com>
2019-01-28 10:58:34 +01:00
Yucong Sun
38f3747cde Update CHANGELOG.md (#10249)
change 2018 to 2019
2019-01-28 10:54:07 +01:00
folex
4fec2f2fc2 Fix typo: CHANGELOG-2.1 -> CHANGELOG-2.2 (#10233) 2019-01-23 11:09:40 +01:00
Sho Sawada
c96d8a742b Update copyright year to 2019. (#10181)
* Update copyright year to 2019.

Have a great year.

* add `(UK)`

* 2018-2019
2019-01-23 09:26:36 +00:00
Elder Ryan
c2de31e586 fixed: types::transaction::SignedTransaction; (#10229) 2019-01-22 22:03:31 +03:00
Niklas Adolfsson
4b11d79829 fix(ManageNetwork): replace Range with RangeInclusive (#10209)
* fix(ManageNetwork): replace Range -> RangeIncls

Fixes `TODO: Range should be changed to RangeInclusive once stable (https://github.com/rust-lang/rust/pull/50758)`

* fix(tests)

* fix(grumbles): off-by-one error in debug_asserts

* RangeInclusive::end() is inclusive which means that if start and end is equal the `debug_assert(range.end() >
range.start()` will fail which is shouldn't
2019-01-22 09:51:40 +01:00
Seun LanLege
c35abe4196 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
2019-01-22 09:33:56 +01:00
Afri Schoedon
a9a278a6e1 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-21 22:55:44 +01:00
Wei Tang
fb07ffa676 Add EIP-1283 disable transition (#10214) 2019-01-21 12:22:29 +01:00
Michael Müller
940a88fa4e Echo CORS request headers by default (#10221)
* Echo CORS request headers by default

More details in https://github.com/paritytech/parity-ethereum/issues/6616.

* fixup: Single line
2019-01-21 10:30:24 +00:00
Bryant Eisenbach
708e495c28 Happy New Year! (#10211)
* Happy New Year!

* Happy New Year!

* Update README.md
2019-01-18 14:00:13 +01:00
Denis S. Soldatov aka General-Beck
460681ead9 perform stripping during build (#10208)
* perform stripping during build

* var RUSTFLAGS
2019-01-18 12:03:18 +01:00
Hernando Castano
2a7ed457dc 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
2019-01-17 16:43:08 +01:00
Hernando Castano
35bbf11ba5 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
2019-01-16 19:52:21 +01:00
Afri Schoedon
4f1e1e8870 Update the changelogs for 2.1.11, 2.2.6, 2.2.7, and 2.3.0 (#10197)
* docs: move 2.2 changelog to docs/

* docs: mark parity 2.1 end of life

* docs: add changelog for 2.1.11

* docs: add changelog for 2.2.6

* docs: add changelog for 2.2.7

* docs: add changelog for 2.3.0

* docs: add release notes for 2.3.0
2019-01-16 18:32:53 +01:00
Victor Baranov
cf505139f1 Cancel Constantinople HF on POA Core (#10198) 2019-01-16 18:31:59 +01:00
Seun LanLege
cdba22a2cb Adds cli interface to allow reseting chain to a particular block (#9782)
* added BlockChainReset trait, client impl, and cli interface

* show block hashes to be deleted and new best block, update best block in db, better cli interface

* delete BlockNumber from COL_EXTRA

* add TODO comment

* add BlockReciepts to imports

* refactor block_headers_from_best_block, better cli documentation

* exit gracefully if reset arg isn't supplied

* fix cli usage macro

* removed stray int literals

* use Vec::with_capacity

Co-Authored-By: seunlanlege <seunlanlege@gmail.com>

* cast n to usize

* correct imports

* make db reset arg required
2019-01-16 16:37:26 +01:00
Nicolas Gotchac
1df6361753 Run all igd methods in its own thread (#10195) 2019-01-16 16:35:28 +01:00
Afri Schoedon
a6c6c7c070 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 21:50:41 +01:00
TriplEight
ed6f2877d7 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
2019-01-15 17:27:43 +01:00
Afri Schoedon
53c408f549 version: bump fork blocks for kovan and foundation (#10186) 2019-01-15 15:48:50 +01:00
Wei Tang
64704c456f 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>
2019-01-15 10:21:44 +01:00
joshua-mir
0edf8e3f1b Align personal_unlockAccount behaviour when permanent unlock is disabled (#10060)
* align with docs

> If permanent unlocking is disabled (the default) then the duration argument will be ignored, and the account will be unlocked for a single signing.

Current behaviour throws an error that is no longer relevant.

* fix test

* Change back to throwing error

* Fix test again

* formatting

* oops

* whitespace fixes
2019-01-15 09:36:55 +01:00
Nicolas Gotchac
53a04e1686 Drop runtime after others (especially ws_server) (#10179) 2019-01-15 09:14:15 +01:00
Afri Schoedon
d356c6640d version: bump nightly to 2.4 (#10165)
* version: bump nightly to 2.4

* revert rand downgrade
2019-01-14 17:29:17 +01:00
Wei Tang
e8e087fc37 Skip locking in statedb for non-canon blocks (#10141) 2019-01-15 01:33:10 +11:00
shoffmeister
181738a736 Remove reference to ui-interface command-line option (#10170) 2019-01-12 13:12:03 +01:00
Tomasz Drwięga
1ac1224cd3 Fix #9822: trace_filter does not return failed contract creation (#10140)
currently trace_filter can't return failed contract creation transaction
but trace_block can query the failed contract creation transaction.it
because the logic of parity-ethereum/ethcore/src/trace/types/filter.rs
Line 109 in 9982eba
```
 _ => false
```

this patch correct the logic:
```
 _ => self.to_address.matches_all()
```

Signed-off-by: Deshi Xiao <xiaods@gmail.com>
2019-01-11 18:08:58 +01:00
Nicolas Gotchac
3687df8da2 Fix _cannot recursively call into Core_ issue (#10144)
* Change igd to github:maufl/rust-igd

* Run `igd::search_gateway_from_timeout` from own thread
2019-01-11 17:59:05 +01:00
Niklas Adolfsson
67eee6aeb7 fix(whisper): correct PoW calculation (#10166)
* Fix off-by-one error on `leading_zeros` which was used to index in the hash to get leading zeros when not aligned on byte boundary (i.e, all the bits in a byte was not zero such as 0001 1111)
* Fix overflow by shifting with bigger value than 63
2019-01-11 17:48:58 +01:00
Tomasz Drwięga
83ba9df85b Bump JSON-RPC (#10151)
* Bump JSON-RPC

* Fix test casing.
2019-01-11 16:55:03 +01:00
Kirill Pimenov
83f706186f Ping nodes from discovery (#10167) 2019-01-10 20:43:16 +01:00
Niklas Adolfsson
eea5f6f232 fix(android): remove dependency to libusb (#10161) 2019-01-10 13:13:15 +01:00
Niklas Adolfsson
38af7f35fc refactor(trim_right_matches -> trim_end_matches) (#10159) 2019-01-10 13:12:14 +01:00
Pierre Krieger
eea3de00c1 Merge Machine and WithRewards (#10071) 2019-01-10 13:11:39 +01:00
396 changed files with 21972 additions and 21464 deletions

View File

@@ -4,13 +4,20 @@ stages:
- publish
- optional
image: parity/rust:gitlab-ci
image: parity/parity-ci-linux:latest
variables:
GIT_STRATEGY: fetch
GIT_SUBMODULE_STRATEGY: recursive
CI_SERVER_NAME: "GitLab CI"
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_JOB_NAME}"
SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache"
CARGO_TARGET: x86_64-unknown-linux-gnu
.no_git: &no_git # disable git strategy
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
- stable
@@ -18,153 +25,301 @@ variables:
- tags
- schedules
.collect_artifacts: &collect_artifacts
artifacts:
name: "${CI_JOB_NAME}_${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}"
when: on_success
expire_in: 1 mos
paths:
- artifacts/
- artifacts/
- tools/
.determine_version: &determine_version
- VERSION="$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' Cargo.toml)"
- DATE_STR="$(date +%Y%m%d)"
- ID_SHORT="$(echo ${CI_COMMIT_SHA} | cut -c 1-7)"
- test "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" = "nightly" && VERSION="${VERSION}-${ID_SHORT}-${DATE_STR}"
- export VERSION
- echo "Version = ${VERSION}"
.docker-cache-status: &docker-cache-status
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
- 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:
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:
- cargo audit
allow_failure: true # failed cargo audit shouldn't prevent a PR from being merged
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: test
variables:
RUN_TESTS: all
stage: build
<<: *docker-cache-status
script:
- scripts/gitlab/test-all.sh stable
tags:
- rust-stable
- ./scripts/gitlab/test-linux.sh stable
- sccache -s
test-audit:
stage: test
script:
- scripts/gitlab/cargo-audit.sh
tags:
- rust-stable
build-linux:
test-linux-beta:
stage: build
only: *releaseable_branches
<<: *docker-cache-status
script:
- scripts/gitlab/build-unix.sh
<<: *collect_artifacts
tags:
- rust-stable
- ./scripts/gitlab/test-linux.sh beta
- 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/rust-parity-ethereum-android-build:stretch
variables:
CARGO_TARGET: armv7-linux-androideabi
build-linux:
<<: *build-on-linux
only: *releaseable_branches
build-linux-i386:
<<: *build-on-linux
only: *releaseable_branches
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/rust-parity-ethereum-build:arm64
variables:
CARGO_TARGET: aarch64-unknown-linux-gnu
build-linux-armhf:
<<: *build-on-linux
only: *releaseable_branches
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-unix.sh
- scripts/gitlab/build-linux.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
<<: *collect_artifacts
- rust-windows
publish-docker:
stage: publish
<<: *no_git
only: *releaseable_branches
cache: {}
except:
variables:
- $SCHEDULE_TAG == "nightly"
dependencies:
- build-linux
tags:
- shell
script:
- scripts/gitlab/publish-docker.sh parity
publish-snap:
stage: publish
only: *releaseable_branches
image: parity/snapcraft:gitlab-ci
environment:
name: parity-build
cache: {}
image: docker:stable
services:
- docker:dind
variables:
BUILD_ARCH: amd64
cache: {}
before_script: *determine_version
DOCKER_HOST: tcp://localhost:2375
DOCKER_DRIVER: overlay2
GIT_STRATEGY: none
# DOCKERFILE: tools/Dockerfile
# CONTAINER_IMAGE: parity/parity
script:
# we stopped pushing nightlies to dockerhub, will push to own registry prb.
- ./tools/publish-docker.sh
tags:
- kubernetes-parity-build
publish-snap: &publish-snap
stage: publish
<<: *no_git
only: *releaseable_branches
image: snapcore/snapcraft
variables:
BUILD_ARCH: amd64
cache: {}
dependencies:
- build-linux
tags:
- rust-stable
- linux-docker
script:
- scripts/gitlab/publish-snap.sh
allow_failure: true
<<: *collect_artifacts
- ./tools/publish-snap.sh
publish-awss3:
publish-snap-i386:
<<: *publish-snap
variables:
BUILD_ARCH: i386
CARGO_TARGET: i686-unknown-linux-gnu
dependencies:
- build-linux-i386
publish-snap-arm64:
<<: *publish-snap
variables:
BUILD_ARCH: arm64
CARGO_TARGET: aarch64-unknown-linux-gnu
dependencies:
- build-linux-arm64
publish-snap-armhf:
<<: *publish-snap
variables:
BUILD_ARCH: armhf
CARGO_TARGET: armv7-unknown-linux-gnueabihf
dependencies:
- build-linux-armhf
publish-onchain:
stage: publish
<<: *no_git
only: *releaseable_branches
cache: {}
cache: {}
dependencies:
- build-linux
- build-darwin
- build-windows
before_script: *determine_version
script:
- scripts/gitlab/publish-awss3.sh
- ./tools/publish-onchain.sh
tags:
- shell
- linux-docker
publish-awss3-release:
image: parity/awscli:latest
stage: publish
only: *releaseable_branches
<<: *no_git
cache: {}
dependencies:
- build-linux
- build-darwin
- build-windows
script:
- echo "__________Push binaries to AWS S3____________"
- case "${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}" in
(beta|stable|nightly)
export BUCKET=releases.parity.io/ethereum;
;;
(*)
export BUCKET=builds-parity;
;;
esac
- aws s3 sync ./artifacts s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/
- echo "__________Read from S3____________"
- aws s3 ls s3://${BUCKET}/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}} --recursive --human-readable --summarize
tags:
- linux-docker
publish-docs:
stage: publish
image: parity/rust-parity-ethereum-docs:xenial
only:
- tags
except:
- nightly
cache: {}
cache: {}
dependencies: []
script:
- scripts/gitlab/publish-docs.sh
tags:
- linux-docker
build-android:
stage: optional
image: parity/rust-android:gitlab-ci
variables:
CARGO_TARGET: armv7-linux-androideabi
script:
- scripts/gitlab/build-unix.sh
tags:
- rust-arm
allow_failure: true
test-beta:
stage: optional
variables:
RUN_TESTS: cargo
script:
- scripts/gitlab/test-all.sh beta
tags:
- rust-beta
allow_failure: true
test-nightly:
stage: optional
variables:
RUN_TESTS: all
script:
- scripts/gitlab/test-all.sh nightly
tags:
- rust-nightly
allow_failure: true

View File

@@ -1,276 +1,163 @@
## 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.3.0](https://github.com/paritytech/parity-ethereum/releases/tag/v2.3.0) (2019-01-16)
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 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.
## Parity-Ethereum [v2.2.2](https://github.com/paritytech/parity-ethereum/releases/tag/v2.2.2) (2018-11-29)
- **Consensus** - Ethereum Network: Pull Constantinople protocol upgrade on Ethereum (#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)
- **Wasm** - Kovan Network: Update pwasm-utils to 0.6.1 (#10134)
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.
Other notable changes:
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:
- Existing blocks in the database are now kept when restoring a Snapshot. (#8643)
- Block and transaction propagation is improved significantly. (#9954)
- The ERC-191 Signed Data Standard is now supported by `personal_sign191`. (#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)
- Add support for ERC-1186 `eth_getProof` (#9001)
- Add experimental RPCs flag to enable ERC-191, ERC-712, and ERC-1186 APIs via `--jsonrpc-experimental` (#9928)
- Make `CALLCODE` to trace value to be the code address. (#9881)
```
cargo build --release -p chainspec
./target/release/chainspec /path/to/spec.json
```
Configuration changes:
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 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)
- Also, unknown fields in chain specs are now rejected. (#9972)
- The Tendermint engine was removed from Parity Ethereum and is no longer available and maintained. (#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)
- Strict empty steps validation (#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 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))
- 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))
## Previous releases
- [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (_stable_)
- [CHANGELOG-2.2](docs/CHANGELOG-2.2.md) (_stable_)
- [CHANGELOG-2.1](docs/CHANGELOG-2.1.md) (EOL: 2019-01-16)
- [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)

1306
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.3.0"
version = "2.4.7"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
@@ -29,11 +29,13 @@ serde_derive = "1.0"
futures = "0.1"
fdlimit = "0.1"
ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" }
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-2.2" }
ethcore = { path = "ethcore", features = ["parity"] }
jsonrpc-core = "10.0.1"
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" }
ethcore-io = { path = "util/io" }
ethcore-light = { path = "ethcore/light" }
@@ -43,12 +45,13 @@ ethcore-network = { path = "util/network" }
ethcore-private-tx = { path = "ethcore/private-tx" }
ethcore-service = { path = "ethcore/service" }
ethcore-sync = { path = "ethcore/sync" }
ethstore = { path = "accounts/ethstore" }
ethereum-types = "0.4"
node-filter = { path = "ethcore/node-filter" }
ethkey = { path = "accounts/ethkey" }
ethstore = { path = "accounts/ethstore" }
node-filter = { path = "ethcore/node-filter" }
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" }
@@ -78,22 +81,22 @@ pretty_assertions = "0.1"
ipnetwork = "0.12.6"
tempdir = "0.3"
fake-fetch = { path = "util/fake-fetch" }
lazy_static = "1.2.0"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] }
[target.'cfg(not(windows))'.dependencies]
daemonize = "0.3"
[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"]
ci-skip-tests = ["ethcore/ci-skip-tests"]
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"]
secretstore = ["ethcore-secretstore", "ethcore-secretstore/accounts"]
final = ["parity-version/final"]
deadlock_detection = ["parking_lot/deadlock_detection"]
# to create a memory profile (requires nightly rust), use e.g.
@@ -115,10 +118,13 @@ path = "parity/lib.rs"
path = "parity/main.rs"
name = "parity"
[profile.dev]
[profile.test]
lto = false
opt-level = 3 # makes tests slower to compile, but faster to run
[profile.release]
debug = false
lto = true
[workspace]
# This should only list projects that are not
@@ -132,4 +138,12 @@ members = [
"evmbin",
"parity-clib",
"whisper/cli",
"util/triehash-ethereum",
"util/keccak-hasher",
"util/patricia-trie-ethereum",
"util/fastmap",
"util/time-utils"
]
[patch.crates-io]
heapsize = { git = "https://github.com/cheme/heapsize.git", branch = "ec-macfix" }

View File

@@ -125,7 +125,8 @@ 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. 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. 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.
## Parity Ethereum toolchain

28
accounts/Cargo.toml Normal file
View File

@@ -0,0 +1,28 @@
[package]
description = "Account management for Parity Ethereum"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "ethcore-accounts"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
common-types = { path = "../ethcore/types" }
ethkey = { path = "ethkey" }
ethstore = { path = "ethstore" }
log = "0.4"
parking_lot = "0.7"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies]
hardware-wallet = { path = "hw" }
[target.'cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))'.dependencies]
fake-hardware-wallet = { path = "fake-hardware-wallet" }
[dev-dependencies]
ethereum-types = "0.4"
tempdir = "0.3"

View File

@@ -6,7 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
byteorder = "1.0"
edit-distance = "2.0"
parity-crypto = "0.2"
parity-crypto = "0.3.0"
eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
ethereum-types = "0.4"
lazy_static = "1.0"

View File

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

View File

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

View File

@@ -16,12 +16,13 @@ tiny-keccak = "1.4"
time = "0.1.34"
itertools = "0.5"
parking_lot = "0.7"
parity-crypto = "0.2"
parity-crypto = "0.3.0"
ethereum-types = "0.4"
dir = { path = "../../util/dir" }
smallvec = "0.6"
parity-wordlist = "1.0"
tempdir = "0.3"
lazy_static = "1.2.0"
[dev-dependencies]
matches = "0.1"

View File

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

View File

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

View File

@@ -15,6 +15,7 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::str;
use std::num::NonZeroU32;
use ethkey::{Password, Secret};
use {json, Error, crypto};
use crypto::Keccak256;
@@ -73,12 +74,12 @@ impl From<Crypto> for String {
impl Crypto {
/// Encrypt account secret
pub fn with_secret(secret: &Secret, password: &Password, iterations: u32) -> Result<Self, crypto::Error> {
pub fn with_secret(secret: &Secret, password: &Password, iterations: NonZeroU32) -> Result<Self, crypto::Error> {
Crypto::with_plain(&*secret, password, iterations)
}
/// Encrypt custom plain data
pub fn with_plain(plain: &[u8], password: &Password, iterations: u32) -> Result<Self, crypto::Error> {
pub fn with_plain(plain: &[u8], password: &Password, iterations: NonZeroU32) -> Result<Self, crypto::Error> {
let salt: [u8; 32] = Random::random();
let iv: [u8; 16] = Random::random();
@@ -159,13 +160,17 @@ impl Crypto {
#[cfg(test)]
mod tests {
use ethkey::{Generator, Random};
use super::{Crypto, Error};
use super::{Crypto, Error, NonZeroU32};
lazy_static! {
static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(10240).expect("10240 > 0; qed");
}
#[test]
fn crypto_with_secret_create() {
let keypair = Random.generate().unwrap();
let passwd = "this is sparta".into();
let crypto = Crypto::with_secret(keypair.secret(), &passwd, 10240).unwrap();
let crypto = Crypto::with_secret(keypair.secret(), &passwd, *ITERATIONS).unwrap();
let secret = crypto.secret(&passwd).unwrap();
assert_eq!(keypair.secret(), &secret);
}
@@ -173,7 +178,7 @@ mod tests {
#[test]
fn crypto_with_secret_invalid_password() {
let keypair = Random.generate().unwrap();
let crypto = Crypto::with_secret(keypair.secret(), &"this is sparta".into(), 10240).unwrap();
let crypto = Crypto::with_secret(keypair.secret(), &"this is sparta".into(), *ITERATIONS).unwrap();
assert_matches!(crypto.secret(&"this is sparta!".into()), Err(Error::InvalidPassword))
}
@@ -181,7 +186,7 @@ mod tests {
fn crypto_with_null_plain_data() {
let original_data = b"";
let passwd = "this is sparta".into();
let crypto = Crypto::with_plain(&original_data[..], &passwd, 10240).unwrap();
let crypto = Crypto::with_plain(&original_data[..], &passwd, *ITERATIONS).unwrap();
let decrypted_data = crypto.decrypt(&passwd).unwrap();
assert_eq!(original_data[..], *decrypted_data);
}
@@ -190,7 +195,7 @@ mod tests {
fn crypto_with_tiny_plain_data() {
let original_data = b"{}";
let passwd = "this is sparta".into();
let crypto = Crypto::with_plain(&original_data[..], &passwd, 10240).unwrap();
let crypto = Crypto::with_plain(&original_data[..], &passwd, *ITERATIONS).unwrap();
let decrypted_data = crypto.decrypt(&passwd).unwrap();
assert_eq!(original_data[..], *decrypted_data);
}
@@ -199,7 +204,7 @@ mod tests {
fn crypto_with_huge_plain_data() {
let original_data: Vec<_> = (1..65536).map(|i| (i % 256) as u8).collect();
let passwd = "this is sparta".into();
let crypto = Crypto::with_plain(&original_data, &passwd, 10240).unwrap();
let crypto = Crypto::with_plain(&original_data, &passwd, *ITERATIONS).unwrap();
let decrypted_data = crypto.decrypt(&passwd).unwrap();
assert_eq!(&original_data, &decrypted_data);
}

View File

@@ -15,6 +15,7 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use json;
use std::num::NonZeroU32;
#[derive(Debug, PartialEq, Clone)]
pub enum Prf {
@@ -23,7 +24,7 @@ pub enum Prf {
#[derive(Debug, PartialEq, Clone)]
pub struct Pbkdf2 {
pub c: u32,
pub c: NonZeroU32,
pub dklen: u32,
pub prf: Prf,
pub salt: Vec<u8>,

View File

@@ -20,6 +20,7 @@ use {json, Error};
use account::Version;
use crypto;
use super::crypto::Crypto;
use std::num::NonZeroU32;
/// Account representation.
#[derive(Debug, PartialEq, Clone)]
@@ -59,7 +60,7 @@ impl SafeAccount {
keypair: &KeyPair,
id: [u8; 16],
password: &Password,
iterations: u32,
iterations: NonZeroU32,
name: String,
meta: String
) -> Result<Self, crypto::Error> {
@@ -135,7 +136,7 @@ impl SafeAccount {
}
/// Create a new `VaultKeyFile` from the given `self`
pub fn into_vault_file(self, iterations: u32, password: &Password) -> Result<json::VaultKeyFile, Error> {
pub fn into_vault_file(self, iterations: NonZeroU32, password: &Password) -> Result<json::VaultKeyFile, Error> {
let meta_plain = json::VaultKeyMeta {
address: self.address.into(),
name: Some(self.name),
@@ -177,7 +178,7 @@ impl SafeAccount {
}
/// Change account's password.
pub fn change_password(&self, old_password: &Password, new_password: &Password, iterations: u32) -> Result<Self, Error> {
pub fn change_password(&self, old_password: &Password, new_password: &Password, iterations: NonZeroU32) -> Result<Self, Error> {
let secret = self.crypto.secret(old_password)?;
let result = SafeAccount {
id: self.id.clone(),
@@ -200,14 +201,19 @@ impl SafeAccount {
#[cfg(test)]
mod tests {
use ethkey::{Generator, Random, verify_public, Message};
use super::SafeAccount;
use super::{SafeAccount, NonZeroU32};
lazy_static! {
static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(10240).expect("10240 > 0; qed");
}
#[test]
fn sign_and_verify_public() {
let keypair = Random.generate().unwrap();
let password = "hello world".into();
let message = Message::default();
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 10240, "Test".to_owned(), "{}".to_owned());
let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned());
let signature = account.unwrap().sign(&password, &message).unwrap();
assert!(verify_public(keypair.public(), &signature, &message).unwrap());
}
@@ -217,10 +223,9 @@ mod tests {
let keypair = Random.generate().unwrap();
let first_password = "hello world".into();
let sec_password = "this is sparta".into();
let i = 10240;
let message = Message::default();
let account = SafeAccount::create(&keypair, [0u8; 16], &first_password, i, "Test".to_owned(), "{}".to_owned()).unwrap();
let new_account = account.change_password(&first_password, &sec_password, i).unwrap();
let account = SafeAccount::create(&keypair, [0u8; 16], &first_password, *ITERATIONS, "Test".to_owned(), "{}".to_owned()).unwrap();
let new_account = account.change_password(&first_password, &sec_password, *ITERATIONS).unwrap();
assert!(account.sign(&first_password, &message).is_ok());
assert!(account.sign(&sec_password, &message).is_err());
assert!(new_account.sign(&first_password, &message).is_err());

View File

@@ -356,11 +356,16 @@ mod test {
extern crate tempdir;
use std::{env, fs};
use std::num::NonZeroU32;
use super::{KeyDirectory, RootDiskDirectory, VaultKey};
use account::SafeAccount;
use ethkey::{Random, Generator};
use self::tempdir::TempDir;
lazy_static! {
static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(1024).expect("1024 > 0; qed");
}
#[test]
fn should_create_new_account() {
// given
@@ -371,7 +376,7 @@ mod test {
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
// when
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned());
let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned());
let res = directory.insert(account.unwrap());
// then
@@ -392,7 +397,7 @@ mod test {
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
// when
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned()).unwrap();
let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned()).unwrap();
let filename = "test".to_string();
let dedup = true;
@@ -428,7 +433,7 @@ mod test {
// and when
let before_root_items_count = fs::read_dir(&dir).unwrap().count();
let vault = directory.as_vault_provider().unwrap().create(vault_name, VaultKey::new(&password, 1024));
let vault = directory.as_vault_provider().unwrap().create(vault_name, VaultKey::new(&password, *ITERATIONS));
// then
assert!(vault.is_ok());
@@ -436,7 +441,7 @@ mod test {
assert!(after_root_items_count > before_root_items_count);
// and when
let vault = directory.as_vault_provider().unwrap().open(vault_name, VaultKey::new(&password, 1024));
let vault = directory.as_vault_provider().unwrap().open(vault_name, VaultKey::new(&password, *ITERATIONS));
// then
assert!(vault.is_ok());
@@ -453,8 +458,9 @@ mod test {
let temp_path = TempDir::new("").unwrap();
let directory = RootDiskDirectory::create(&temp_path).unwrap();
let vault_provider = directory.as_vault_provider().unwrap();
vault_provider.create("vault1", VaultKey::new(&"password1".into(), 1)).unwrap();
vault_provider.create("vault2", VaultKey::new(&"password2".into(), 1)).unwrap();
let iter = NonZeroU32::new(1).expect("1 > 0; qed");
vault_provider.create("vault1", VaultKey::new(&"password1".into(), iter)).unwrap();
vault_provider.create("vault2", VaultKey::new(&"password2".into(), iter)).unwrap();
// then
let vaults = vault_provider.list_vaults().unwrap();
@@ -476,7 +482,7 @@ mod test {
let keypair = Random.generate().unwrap();
let password = "test pass".into();
let account = SafeAccount::create(&keypair, [0u8; 16], &password, 1024, "Test".to_owned(), "{}".to_owned());
let account = SafeAccount::create(&keypair, [0u8; 16], &password, *ITERATIONS, "Test".to_owned(), "{}".to_owned());
directory.insert(account.unwrap()).expect("Account should be inserted ok");
let new_hash = directory.files_hash().expect("New files hash should be calculated ok");

View File

@@ -17,6 +17,7 @@
//! Accounts Directory
use ethkey::Password;
use std::num::NonZeroU32;
use std::path::{PathBuf};
use {SafeAccount, Error};
@@ -41,7 +42,7 @@ pub struct VaultKey {
/// Vault password
pub password: Password,
/// Number of iterations to produce a derived key from password
pub iterations: u32,
pub iterations: NonZeroU32,
}
/// Keys directory
@@ -96,7 +97,7 @@ pub use self::vault::VaultDiskDirectory;
impl VaultKey {
/// Create new vault key
pub fn new(password: &Password, iterations: u32) -> Self {
pub fn new(password: &Password, iterations: NonZeroU32) -> Self {
VaultKey {
password: password.clone(),
iterations: iterations,

View File

@@ -282,11 +282,17 @@ mod test {
use std::fs;
use std::io::Write;
use std::num::NonZeroU32;
use std::path::PathBuf;
use super::VaultKey;
use super::{VAULT_FILE_NAME, check_vault_name, make_vault_dir_path, create_vault_file, read_vault_file, VaultDiskDirectory};
use self::tempdir::TempDir;
lazy_static! {
static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(1024).expect("1024 > 0; qed");
}
#[test]
fn check_vault_name_succeeds() {
assert!(check_vault_name("vault"));
@@ -325,7 +331,7 @@ mod test {
fn create_vault_file_succeeds() {
// given
let temp_path = TempDir::new("").unwrap();
let key = VaultKey::new(&"password".into(), 1024);
let key = VaultKey::new(&"password".into(), *ITERATIONS);
let mut vault_dir: PathBuf = temp_path.path().into();
vault_dir.push("vault");
fs::create_dir_all(&vault_dir).unwrap();
@@ -344,7 +350,7 @@ mod test {
fn read_vault_file_succeeds() {
// given
let temp_path = TempDir::new("").unwrap();
let key = VaultKey::new(&"password".into(), 1024);
let key = VaultKey::new(&"password".into(), *ITERATIONS);
let vault_file_contents = r#"{"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"758696c8dc6378ab9b25bb42790da2f5"},"ciphertext":"54eb50683717d41caaeb12ea969f2c159daada5907383f26f327606a37dc7168","kdf":"pbkdf2","kdfparams":{"c":1024,"dklen":32,"prf":"hmac-sha256","salt":"3c320fa566a1a7963ac8df68a19548d27c8f40bf92ef87c84594dcd5bbc402b6"},"mac":"9e5c2314c2a0781962db85611417c614bd6756666b6b1e93840f5b6ed895f003"}}"#;
let dir: PathBuf = temp_path.path().into();
let mut vault_file_path: PathBuf = dir.clone();
@@ -365,7 +371,7 @@ mod test {
fn read_vault_file_fails() {
// given
let temp_path = TempDir::new("").unwrap();
let key = VaultKey::new(&"password1".into(), 1024);
let key = VaultKey::new(&"password1".into(), *ITERATIONS);
let dir: PathBuf = temp_path.path().into();
let mut vault_file_path: PathBuf = dir.clone();
vault_file_path.push(VAULT_FILE_NAME);
@@ -394,7 +400,7 @@ mod test {
fn vault_directory_can_be_created() {
// given
let temp_path = TempDir::new("").unwrap();
let key = VaultKey::new(&"password".into(), 1024);
let key = VaultKey::new(&"password".into(), *ITERATIONS);
let dir: PathBuf = temp_path.path().into();
// when
@@ -414,7 +420,7 @@ mod test {
fn vault_directory_cannot_be_created_if_already_exists() {
// given
let temp_path = TempDir::new("").unwrap();
let key = VaultKey::new(&"password".into(), 1024);
let key = VaultKey::new(&"password".into(), *ITERATIONS);
let dir: PathBuf = temp_path.path().into();
let mut vault_dir = dir.clone();
vault_dir.push("vault");
@@ -431,7 +437,7 @@ mod test {
fn vault_directory_cannot_be_opened_if_not_exists() {
// given
let temp_path = TempDir::new("").unwrap();
let key = VaultKey::new(&"password".into(), 1024);
let key = VaultKey::new(&"password".into(), *ITERATIONS);
let dir: PathBuf = temp_path.path().into();
// when

View File

@@ -15,12 +15,12 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::collections::{BTreeMap, HashMap};
use std::num::NonZeroU32;
use std::mem;
use std::path::PathBuf;
use parking_lot::{Mutex, RwLock};
use std::time::{Instant, Duration};
use crypto::KEY_ITERATIONS;
use random::Random;
use ethkey::{self, Signature, Password, Address, Message, Secret, Public, KeyPair, ExtendedKeyPair};
use accounts_dir::{KeyDirectory, VaultKeyDirectory, VaultKey, SetKeyError};
@@ -29,6 +29,12 @@ use presale::PresaleWallet;
use json::{self, Uuid, OpaqueKeyFile};
use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret};
lazy_static! {
static ref KEY_ITERATIONS: NonZeroU32 =
NonZeroU32::new(crypto::KEY_ITERATIONS as u32).expect("KEY_ITERATIONS > 0; qed");
}
/// Accounts store.
pub struct EthStore {
store: EthMultiStore,
@@ -37,11 +43,11 @@ pub struct EthStore {
impl EthStore {
/// Open a new accounts store with given key directory backend.
pub fn open(directory: Box<KeyDirectory>) -> Result<Self, Error> {
Self::open_with_iterations(directory, KEY_ITERATIONS as u32)
Self::open_with_iterations(directory, *KEY_ITERATIONS)
}
/// Open a new account store with given key directory backend and custom number of iterations.
pub fn open_with_iterations(directory: Box<KeyDirectory>, iterations: u32) -> Result<Self, Error> {
pub fn open_with_iterations(directory: Box<KeyDirectory>, iterations: NonZeroU32) -> Result<Self, Error> {
Ok(EthStore {
store: EthMultiStore::open_with_iterations(directory, iterations)?,
})
@@ -257,7 +263,7 @@ impl SecretStore for EthStore {
/// Similar to `EthStore` but may store many accounts (with different passwords) for the same `Address`
pub struct EthMultiStore {
dir: Box<KeyDirectory>,
iterations: u32,
iterations: NonZeroU32,
// order lock: cache, then vaults
cache: RwLock<BTreeMap<StoreAccountRef, Vec<SafeAccount>>>,
vaults: Mutex<HashMap<String, Box<VaultKeyDirectory>>>,
@@ -273,11 +279,11 @@ struct Timestamp {
impl EthMultiStore {
/// Open new multi-accounts store with given key directory backend.
pub fn open(directory: Box<KeyDirectory>) -> Result<Self, Error> {
Self::open_with_iterations(directory, KEY_ITERATIONS as u32)
Self::open_with_iterations(directory, *KEY_ITERATIONS)
}
/// Open new multi-accounts store with given key directory backend and custom number of iterations for new keys.
pub fn open_with_iterations(directory: Box<KeyDirectory>, iterations: u32) -> Result<Self, Error> {
pub fn open_with_iterations(directory: Box<KeyDirectory>, iterations: NonZeroU32) -> Result<Self, Error> {
let store = EthMultiStore {
dir: directory,
vaults: Mutex::new(HashMap::new()),

View File

@@ -15,6 +15,7 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::fmt;
use std::num::NonZeroU32;
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::{Visitor, Error as SerdeError};
use super::{Error, Bytes};
@@ -108,7 +109,7 @@ impl<'a> Visitor<'a> for PrfVisitor {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Pbkdf2 {
pub c: u32,
pub c: NonZeroU32,
pub dklen: u32,
pub prf: Prf,
pub salt: Bytes,

View File

@@ -41,6 +41,11 @@ impl VaultFile {
mod test {
use serde_json;
use json::{VaultFile, Crypto, Cipher, Aes128Ctr, Kdf, Pbkdf2, Prf};
use std::num::NonZeroU32;
lazy_static! {
static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(1024).expect("1024 > 0; qed");
}
#[test]
fn to_and_from_json() {
@@ -51,7 +56,7 @@ mod test {
}),
ciphertext: "4d6938a1f49b7782".into(),
kdf: Kdf::Pbkdf2(Pbkdf2 {
c: 1024,
c: *ITERATIONS,
dklen: 32,
prf: Prf::HmacSha256,
salt: "b6a9338a7ccd39288a86dba73bfecd9101b4f3db9c9830e7c76afdbd4f6872e5".into(),
@@ -76,7 +81,7 @@ mod test {
}),
ciphertext: "4d6938a1f49b7782".into(),
kdf: Kdf::Pbkdf2(Pbkdf2 {
c: 1024,
c: *ITERATIONS,
dklen: 32,
prf: Prf::HmacSha256,
salt: "b6a9338a7ccd39288a86dba73bfecd9101b4f3db9c9830e7c76afdbd4f6872e5".into(),

View File

@@ -106,6 +106,11 @@ mod test {
use serde_json;
use json::{VaultKeyFile, Version, Crypto, Cipher, Aes128Ctr, Kdf, Pbkdf2, Prf,
insert_vault_name_to_json_meta, remove_vault_name_from_json_meta};
use std::num::NonZeroU32;
lazy_static! {
static ref ITERATIONS: NonZeroU32 = NonZeroU32::new(10240).expect("10240 > 0; qed");
}
#[test]
fn to_and_from_json() {
@@ -118,7 +123,7 @@ mod test {
}),
ciphertext: "4befe0a66d9a4b6fec8e39eb5c90ac5dafdeaab005fff1af665fd1f9af925c91".into(),
kdf: Kdf::Pbkdf2(Pbkdf2 {
c: 10240,
c: *ITERATIONS,
dklen: 32,
prf: Prf::HmacSha256,
salt: "f17731e84ecac390546692dbd4ccf6a3a2720dc9652984978381e61c28a471b2".into(),
@@ -131,7 +136,7 @@ mod test {
}),
ciphertext: "fef0d113d7576c1702daf380ad6f4c5408389e57991cae2a174facd74bd549338e1014850bddbab7eb486ff5f5c9c5532800c6a6d4db2be2212cd5cd3769244ab230e1f369e8382a9e6d7c0a".into(),
kdf: Kdf::Pbkdf2(Pbkdf2 {
c: 10240,
c: *ITERATIONS,
dklen: 32,
prf: Prf::HmacSha256,
salt: "aca82865174a82249a198814b263f43a631f272cbf7ed329d0f0839d259c652a".into(),

View File

@@ -36,6 +36,8 @@ extern crate ethereum_types;
extern crate ethkey as _ethkey;
extern crate parity_wordlist;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[macro_use]

View File

@@ -15,6 +15,7 @@
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
use std::fs;
use std::num::NonZeroU32;
use std::path::Path;
use json;
use ethkey::{Address, Secret, KeyPair, Password};
@@ -58,7 +59,8 @@ impl PresaleWallet {
let mut derived_key = [0u8; 32];
let salt = pbkdf2::Salt(password.as_bytes());
let sec = pbkdf2::Secret(password.as_bytes());
pbkdf2::sha256(2000, salt, sec, &mut derived_key);
let iter = NonZeroU32::new(2000).expect("2000 > 0; qed");
pbkdf2::sha256(iter, salt, sec, &mut derived_key);
let mut key = vec![0; self.ciphertext.len()];
let len = crypto::aes::decrypt_128_cbc(&derived_key[0..16], &self.iv, &self.ciphertext, &mut key)

View File

@@ -0,0 +1,73 @@
// 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)
}
}

56
accounts/src/error.rs Normal file
View File

@@ -0,0 +1,56 @@
// 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};
use hardware_wallet::{Error as HardwareError};
/// Signing error
#[derive(Debug)]
pub enum SignError {
/// Account is not unlocked
NotUnlocked,
/// Account does not exist.
NotFound,
/// Low-level hardware device error.
Hardware(HardwareError),
/// 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::Hardware(ref e) => write!(f, "{}", e),
SignError::SStore(ref e) => write!(f, "{}", e),
}
}
}
impl From<HardwareError> for SignError {
fn from(e: HardwareError) -> Self {
SignError::Hardware(e)
}
}
impl From<SSError> for SignError {
fn from(e: SSError) -> Self {
SignError::SStore(e)
}
}

View File

@@ -14,94 +14,55 @@
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)]
//! Account management.
mod account_data;
mod error;
mod stores;
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
extern crate fake_hardware_wallet as hardware_wallet;
use self::account_data::{Unlock, AccountData};
use self::stores::AddressBook;
use std::collections::HashMap;
use std::fmt;
use std::time::{Instant, Duration};
use common_types::transaction::{Action, Transaction};
use ethkey::{Address, Message, Public, Secret, Password, Random, Generator};
use ethstore::accounts_dir::MemoryDirectory;
use ethstore::ethkey::{Address, Message, Public, Secret, Password, Random, Generator};
use ethjson::misc::AccountMeta;
use ethstore::{
SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore,
SimpleSecretStore, SecretStore, EthStore, EthMultiStore,
random_string, SecretVaultRef, StoreAccountRef, OpaqueSecret,
};
use log::{warn, debug};
use parking_lot::RwLock;
use types::transaction::{Action, Transaction};
pub use ethstore::ethkey::Signature;
pub use ethstore::{Derivation, IndexDerivation, KeyFile};
pub use ethkey::Signature;
pub use ethstore::{Derivation, IndexDerivation, KeyFile, Error};
pub use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo};
/// Type of unlock.
#[derive(Clone, PartialEq)]
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)]
struct AccountData {
unlock: Unlock,
password: Password,
}
/// Signing error
#[derive(Debug)]
pub enum SignError {
/// Account is not unlocked
NotUnlocked,
/// Account does not exist.
NotFound,
/// Low-level hardware device error.
Hardware(HardwareError),
/// 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::Hardware(ref e) => write!(f, "{}", e),
SignError::SStore(ref e) => write!(f, "{}", e),
}
}
}
impl From<HardwareError> for SignError {
fn from(e: HardwareError) -> Self {
SignError::Hardware(e)
}
}
impl From<SSError> for SignError {
fn from(e: SSError) -> Self {
SignError::SStore(e)
}
}
/// `AccountProvider` errors.
pub type Error = SSError;
fn transient_sstore() -> EthMultiStore {
EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")
}
pub use self::account_data::AccountMeta;
pub use self::error::SignError;
type AccountToken = Password;
/// Account management settings.
#[derive(Debug, Default)]
pub struct AccountProviderSettings {
/// Enable hardware wallet support.
pub enable_hardware_wallets: bool,
/// Use the classic chain key on the hardware wallet.
pub hardware_wallet_classic_key: bool,
/// Store raw account secret when unlocking the account permanently.
pub unlock_keep_secret: bool,
/// Disallowed accounts.
pub blacklisted_accounts: Vec<Address>,
}
/// Account management.
/// Responsible for unlocking accounts.
pub struct AccountProvider {
@@ -124,27 +85,8 @@ pub struct AccountProvider {
blacklisted_accounts: Vec<Address>,
}
/// Account management settings.
pub struct AccountProviderSettings {
/// Enable hardware wallet support.
pub enable_hardware_wallets: bool,
/// Use the classic chain key on the hardware wallet.
pub hardware_wallet_classic_key: bool,
/// Store raw account secret when unlocking the account permanently.
pub unlock_keep_secret: bool,
/// Disallowed accounts.
pub blacklisted_accounts: Vec<Address>,
}
impl Default for AccountProviderSettings {
fn default() -> Self {
AccountProviderSettings {
enable_hardware_wallets: false,
hardware_wallet_classic_key: false,
unlock_keep_secret: false,
blacklisted_accounts: vec![],
}
}
fn transient_sstore() -> EthMultiStore {
EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")
}
impl AccountProvider {
@@ -221,7 +163,7 @@ impl AccountProvider {
let account = self.sstore.insert_account(SecretVaultRef::Root, secret, password)?;
if self.blacklisted_accounts.contains(&account.address) {
self.sstore.remove_account(&account, password)?;
return Err(SSError::InvalidAccount.into());
return Err(Error::InvalidAccount.into());
}
Ok(account.address)
}
@@ -251,7 +193,7 @@ impl AccountProvider {
let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password, gen_id)?;
if self.blacklisted_accounts.contains(&account.address) {
self.sstore.remove_account(&account, password)?;
return Err(SSError::InvalidAccount.into());
return Err(Error::InvalidAccount.into());
}
Ok(Address::from(account.address).into())
}
@@ -284,7 +226,7 @@ impl AccountProvider {
return Ok(accounts.into_iter().map(|a| a.address).collect());
}
}
Err(SSError::Custom("No hardware wallet accounts were found".into()))
Err(Error::Custom("No hardware wallet accounts were found".into()))
}
/// Get a list of paths to locked hardware wallets
@@ -669,7 +611,7 @@ impl AccountProvider {
mod tests {
use super::{AccountProvider, Unlock};
use std::time::{Duration, Instant};
use ethstore::ethkey::{Generator, Random, Address};
use ethkey::{Generator, Random, Address};
use ethstore::{StoreAccountRef, Derivation};
use ethereum_types::H256;

View File

@@ -20,8 +20,10 @@ use std::{fs, fmt, hash, ops};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use ethstore::ethkey::Address;
use ethjson::misc::AccountMeta;
use ethkey::Address;
use log::{trace, warn};
use crate::AccountMeta;
/// Disk-backed map from Address to String. Uses JSON.
pub struct AddressBook {
@@ -153,8 +155,8 @@ impl<K: hash::Hash + Eq, V> DiskMap<K, V> {
mod tests {
use super::AddressBook;
use std::collections::HashMap;
use ethjson::misc::AccountMeta;
use tempdir::TempDir;
use crate::account_data::AccountMeta;
#[test]
fn should_save_and_reload_address_book() {
@@ -163,7 +165,9 @@ mod tests {
b.set_name(1.into(), "One".to_owned());
b.set_meta(1.into(), "{1:1}".to_owned());
let b = AddressBook::new(tempdir.path());
assert_eq!(b.get(), hash_map![1.into() => AccountMeta{name: "One".to_owned(), meta: "{1:1}".to_owned(), uuid: None}]);
assert_eq!(b.get(), vec![
(1, AccountMeta {name: "One".to_owned(), meta: "{1:1}".to_owned(), uuid: None})
].into_iter().map(|(a, b)| (a.into(), b)).collect::<HashMap<_, _>>());
}
#[test]
@@ -177,9 +181,9 @@ mod tests {
b.remove(2.into());
let b = AddressBook::new(tempdir.path());
assert_eq!(b.get(), hash_map![
1.into() => AccountMeta{name: "One".to_owned(), meta: "{}".to_owned(), uuid: None},
3.into() => AccountMeta{name: "Three".to_owned(), meta: "{}".to_owned(), uuid: None}
]);
assert_eq!(b.get(), vec![
(1, AccountMeta{name: "One".to_owned(), meta: "{}".to_owned(), uuid: None}),
(3, AccountMeta{name: "Three".to_owned(), meta: "{}".to_owned(), uuid: None}),
].into_iter().map(|(a, b)| (a.into(), b)).collect::<HashMap<_, _>>());
}
}

View File

@@ -7,6 +7,7 @@ name = "cli-signer"
version = "1.4.0"
[dependencies]
ethereum-types = "0.4"
futures = "0.1"
rpassword = "1.0"
parity-rpc = { path = "../rpc" }

View File

@@ -7,6 +7,7 @@ name = "parity-rpc-client"
version = "1.4.0"
[dependencies]
ethereum-types = "0.4"
futures = "0.1"
log = "0.4"
serde = "1.0"
@@ -14,7 +15,7 @@ serde_json = "1.0"
url = "1.2.0"
matches = "0.1"
parking_lot = "0.7"
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" }
jsonrpc-core = "10.0.1"
jsonrpc-ws-server = "10.0.1"
parity-rpc = { path = "../../rpc" }
keccak-hash = "0.1"

View File

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

View File

@@ -14,13 +14,15 @@
// 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 rpc::signer::{U256, ConfirmationRequest};
use ethereum_types::U256;
use rpc::signer::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 2.0 reached End-of-Life on 2018-11-15 (EOL).
Note: Parity Ethereum 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,13 +1,31 @@
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))

317
docs/CHANGELOG-2.2.md Normal file
View File

@@ -0,0 +1,317 @@
## 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

@@ -14,9 +14,19 @@ parking_lot = "0.7"
primal = "0.2.3"
[dev-dependencies]
tempdir = "0.3"
criterion = "0.2"
rustc-hex = "1.0"
serde_json = "1.0"
tempdir = "0.3"
[features]
default = []
bench = []
[[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);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE)));
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value())));
}
fn bench_light_compute_memory(b: &mut Criterion) {
use std::env;
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE)));
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value())));
}
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);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}
@@ -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);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}
@@ -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);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
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);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let light = builder.light_from_file(&dir, 486382).unwrap();
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}
@@ -100,14 +100,14 @@ fn bench_light_from_file_round_trip_memmap(b: &mut Criterion) {
let height = 486382;
{
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
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);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let light = builder.light_from_file(&dir, 486382).unwrap();
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}

86
ethash/benches/progpow.rs Normal file
View File

@@ -0,0 +1,86 @@
#[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

@@ -0,0 +1,86 @@
[
[
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,6 +69,7 @@ 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
@@ -82,17 +83,18 @@ 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)
Light::new_with_builder(self, cache_dir, block_number, self.progpow_transition)
}
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)
Light::from_file_with_builder(self, cache_dir, block_number, self.progpow_transition)
}
pub fn new<T: Into<Option<OptimizeFor>>>(optimize_for: T) -> Self {
pub fn new<T: Into<Option<OptimizeFor>>>(optimize_for: T, progpow_transition: u64) -> Self {
NodeCacheBuilder {
seedhash: Arc::new(Mutex::new(SeedHashCompute::default())),
optimize_for: optimize_for.into().unwrap_or_default(),
progpow_transition
}
}

View File

@@ -21,6 +21,7 @@
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;
@@ -30,7 +31,7 @@ use std::path::Path;
const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4;
const MIX_NODES: usize = MIX_WORDS / NODE_WORDS;
const FNV_PRIME: u32 = 0x01000193;
pub const FNV_PRIME: u32 = 0x01000193;
/// Computation result
pub struct ProofOfWork {
@@ -40,9 +41,15 @@ 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
@@ -51,32 +58,55 @@ 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);
Light {
block_number: block_number,
cache: cache,
}
let algorithm = if block_number >= progpow_transition {
Algorithm::Progpow(Box::new(generate_cdag(cache.as_ref())))
} else {
Algorithm::Hashimoto
};
Light { block_number, cache, algorithm }
}
/// 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) -> ProofOfWork {
light_compute(self, header_hash, nonce)
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 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)?;
Ok(Light {
block_number: block_number,
cache: cache,
})
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 })
}
pub fn to_file(&mut self) -> io::Result<&Path> {
@@ -99,27 +129,32 @@ 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) -> H256 {
pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256, progpow: bool) -> H256 {
unsafe {
// 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();
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();
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
}
}
}
@@ -272,7 +307,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(),
@@ -287,7 +322,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
}
// TODO: Use the `simd` crate
fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node {
pub 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;
@@ -361,13 +396,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)[..], boundary_good[..]);
assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash, false)[..], 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)[..] != boundary_bad[..]);
assert!(quick_get_difficulty(&hash, nonce, &mix_hash, false)[..] != boundary_bad[..]);
}
#[test]
@@ -391,7 +426,7 @@ mod test {
let tempdir = TempDir::new("").unwrap();
// difficulty = 0x085657254bd9u64;
let light = NodeCacheBuilder::new(None).light(tempdir.path(), 486382);
let light = NodeCacheBuilder::new(None, u64::max_value()).light(tempdir.path(), 486382);
let result = light_compute(&light, &hash, nonce);
assert_eq!(result.mix_hash[..], mix_hash[..]);
assert_eq!(result.value[..], boundary[..]);
@@ -400,7 +435,7 @@ mod test {
#[test]
fn test_drop_old_data() {
let tempdir = TempDir::new("").unwrap();
let builder = NodeCacheBuilder::new(None);
let builder = NodeCacheBuilder::new(None, u64::max_value());
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,15 +25,30 @@ 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;
@@ -59,14 +74,16 @@ 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) -> EthashManager {
pub fn new<T: Into<Option<OptimizeFor>>>(cache_dir: &Path, optimize_for: T, progpow_transition: u64) -> EthashManager {
EthashManager {
cache_dir: cache_dir.to_path_buf(),
nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default()),
nodecache_builder: NodeCacheBuilder::new(optimize_for.into().unwrap_or_default(), progpow_transition),
progpow_transition: progpow_transition,
cache: Mutex::new(LightCache {
recent_epoch: None,
recent: None,
@@ -85,27 +102,33 @@ impl EthashManager {
let epoch = block_number / ETHASH_EPOCH_LENGTH;
let light = {
let mut lights = self.cache.lock();
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()
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()
}
}
}
_ => None,
},
_ => None,
},
}
};
match light {
None => {
let light = match self.nodecache_builder.light_from_file(
@@ -132,7 +155,7 @@ impl EthashManager {
Some(light) => light,
}
};
light.compute(header_hash, nonce)
light.compute(header_hash, nonce, block_number)
}
}
@@ -164,7 +187,7 @@ fn test_lru() {
use tempdir::TempDir;
let tempdir = TempDir::new("").unwrap();
let ethash = EthashManager::new(tempdir.path(), None);
let ethash = EthashManager::new(tempdir.path(), None, u64::max_value());
let hash = [0u8; 32];
ethash.compute_light(1, &hash, 1);
ethash.compute_light(50000, &hash, 1);

595
ethash/src/progpow.rs Normal file
View File

@@ -0,0 +1,595 @@
// 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/>.
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

@@ -21,6 +21,7 @@ ethabi-derive = "6.0"
ethash = { path = "../ethash" }
ethcore-blockchain = { path = "./blockchain" }
ethcore-bloom-journal = { path = "../util/bloom" }
ethcore-call-contract = { path = "./call-contract" }
ethcore-db = { path = "./db" }
ethcore-io = { path = "../util/io" }
ethcore-miner = { path = "../miner" }
@@ -28,9 +29,8 @@ ethcore-stratum = { path = "../miner/stratum", optional = true }
ethereum-types = "0.4"
ethjson = { path = "../json" }
ethkey = { path = "../accounts/ethkey" }
ethstore = { path = "../accounts/ethstore" }
evm = { path = "evm" }
hashdb = "0.3.0"
hash-db = "0.11.0"
heapsize = "0.4"
itertools = "0.5"
journaldb = { path = "../util/journaldb" }
@@ -45,15 +45,15 @@ log = "0.4"
lru-cache = "0.1"
macros = { path = "../util/macros" }
memory-cache = { path = "../util/memory-cache" }
memorydb = "0.3.0"
memory-db = "0.11.0"
num = { version = "0.1", default-features = false, features = ["bigint"] }
num_cpus = "1.2"
parity-bytes = "0.1"
parity-crypto = "0.2"
parity-crypto = "0.3.0"
parity-machine = { path = "../machine" }
parity-snappy = "0.1"
parking_lot = "0.7"
patricia-trie = "0.3.0"
trie-db = "0.11.0"
patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" }
rand = "0.4"
rayon = "1.0"
@@ -64,6 +64,7 @@ serde = "1.0"
serde_derive = "1.0"
stats = { path = "../util/stats" }
tempdir = {version="0.3", optional = true}
time-utils = { path = "../util/time-utils" }
trace-time = "0.1"
triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" }
unexpected = { path = "../util/unexpected" }
@@ -71,17 +72,14 @@ using_queue = { path = "../miner/using-queue" }
vm = { path = "vm" }
wasm = { path = "wasm" }
[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" }
fetch = { path = "../util/fetch" }
kvdb-rocksdb = "0.1.3"
parity-runtime = { path = "../util/runtime" }
rlp_compress = { path = "../util/rlp-compress" }
tempdir = "0.3"
trie-standardmap = "0.1"
@@ -110,7 +108,7 @@ 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 = []
ci-skip-tests = []
# Run memory/cpu heavy tests.
test-heavy = []
# Compile test helpers

View File

@@ -668,6 +668,21 @@ impl BlockChain {
self.db.key_value().read_with_cache(db::COL_EXTRA, &self.block_details, parent).map_or(false, |d| d.children.contains(hash))
}
/// fetches the list of blocks from best block to n, and n's parent hash
/// where n > 0
pub fn block_headers_from_best_block(&self, n: u32) -> Option<(Vec<encoded::Header>, H256)> {
let mut blocks = Vec::with_capacity(n as usize);
let mut hash = self.best_block_hash();
for _ in 0..n {
let current_hash = self.block_header_data(&hash)?;
hash = current_hash.parent_hash();
blocks.push(current_hash);
}
Some((blocks, hash))
}
/// Returns a tree route between `from` and `to`, which is a tuple of:
///
/// - a vector of hashes of all blocks, ordered from `from` to `to`.

View File

@@ -33,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};
pub use ethcore_db::keys::{BlockReceipts, BlockDetails, TransactionAddress, BlockNumberKey};
pub use common_types::tree_route::TreeRoute;

View File

@@ -0,0 +1,11 @@
[package]
name = "ethcore-call-contract"
version = "0.1.0"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
types = { path = "../types", package = "common-types" }
ethereum-types = "0.4"
bytes = { version = "0.1", package = "parity-bytes" }

View File

@@ -0,0 +1,33 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Provides CallContract and RegistryInfo traits
use bytes::Bytes;
use ethereum_types::Address;
use types::ids::BlockId;
/// Provides `call_contract` method
pub trait CallContract {
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String>;
}
/// Provides information on a blockchain service and it's registry
pub trait RegistryInfo {
/// Get the address of a particular blockchain service, if available.
fn registry_address(&self, name: String, block: BlockId) -> Option<Address>;
}

View File

@@ -14,14 +14,14 @@
// 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 std::sync::Arc;
use ethcore::account_provider::AccountProvider;
use jsonrpc_core::Error;
use v1::helpers::errors;
#![warn(missing_docs)]
pub fn unwrap_provider(provider: &Option<Arc<AccountProvider>>) -> Result<Arc<AccountProvider>, Error> {
match *provider {
Some(ref arc) => Ok(arc.clone()),
None => Err(errors::public_unsupported(None)),
}
}
//! Call Contract module
//!
//! This crate exposes traits required to call contracts at particular block.
//! All utilities that depend on on-chain data should use those traits to access it.
pub mod call_contract;
// Re-export
pub use self::call_contract::*;

View File

@@ -14,6 +14,7 @@ vm = { path = "../vm" }
keccak-hash = "0.1"
parking_lot = "0.7"
memory-cache = { path = "../../util/memory-cache" }
num-bigint = "0.2"
[dev-dependencies]
rustc-hex = "1.0"

View File

@@ -45,7 +45,9 @@ criterion_group!(
mem_gas_calculation_same_usize,
mem_gas_calculation_same_u256,
mem_gas_calculation_increasing_usize,
mem_gas_calculation_increasing_u256
mem_gas_calculation_increasing_u256,
blockhash_mulmod_small,
blockhash_mulmod_large,
);
criterion_main!(basic);
@@ -150,6 +152,54 @@ 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

@@ -28,7 +28,8 @@ use std::{cmp, mem};
use std::sync::Arc;
use hash::keccak;
use bytes::Bytes;
use ethereum_types::{U256, U512, H256, Address};
use ethereum_types::{U256, H256, Address};
use num_bigint::BigUint;
use vm::{
self, ActionParams, ParamsType, ActionValue, CallType, MessageCallResult,
@@ -61,6 +62,17 @@ const TWO_POW_96: U256 = U256([0, 0x100000000, 0, 0]); //0x1 00000000 00000000 0
const TWO_POW_224: U256 = U256([0, 0, 0, 0x100000000]); //0x1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
const TWO_POW_248: U256 = U256([0, 0, 0, 0x100000000000000]); //0x1 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000000
fn to_biguint(x: U256) -> BigUint {
let mut bytes = [0u8; 32];
x.to_little_endian(&mut bytes);
BigUint::from_bytes_le(&bytes)
}
fn from_biguint(x: BigUint) -> U256 {
let bytes = x.to_bytes_le();
U256::from_little_endian(&bytes)
}
/// Abstraction over raw vector of Bytes. Easier state management of PC.
struct CodeReader {
position: ProgramCounter,
@@ -571,10 +583,10 @@ impl<Cost: CostType> Interpreter<Cost> {
let out_size = self.stack.pop_back();
// Add stipend (only CALL|CALLCODE when value > 0)
let call_gas = call_gas + value.map_or_else(|| Cost::from(0), |val| match val.is_zero() {
let call_gas = call_gas.overflow_add(value.map_or_else(|| Cost::from(0), |val| match val.is_zero() {
false => Cost::from(ext.schedule().call_stipend),
true => Cost::from(0),
});
})).0;
// Get sender & receive addresses, check if we have balance
let (sender_address, receive_address, has_balance, call_type) = match instruction {
@@ -1009,11 +1021,12 @@ impl<Cost: CostType> Interpreter<Cost> {
let c = self.stack.pop_back();
self.stack.push(if !c.is_zero() {
// 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)
let a_num = to_biguint(a);
let b_num = to_biguint(b);
let c_num = to_biguint(c);
let res = a_num + b_num;
let x = res % c_num;
from_biguint(x)
} else {
U256::zero()
});
@@ -1024,10 +1037,12 @@ impl<Cost: CostType> Interpreter<Cost> {
let c = self.stack.pop_back();
self.stack.push(if !c.is_zero() {
let a5 = U512::from(a);
let res = a5.overflowing_mul(U512::from(b)).0;
let x = res % U512::from(c);
U256::from(x)
let a_num = to_biguint(a);
let b_num = to_biguint(b);
let c_num = to_biguint(c);
let res = a_num * b_num;
let x = res % c_num;
from_biguint(x)
} else {
U256::zero()
});

View File

@@ -24,6 +24,7 @@ extern crate vm;
extern crate keccak_hash as hash;
extern crate memory_cache;
extern crate parity_bytes as bytes;
extern crate num_bigint;
#[macro_use]
extern crate lazy_static;

View File

@@ -14,12 +14,12 @@ ethcore = { path = ".."}
ethcore-db = { path = "../db" }
ethcore-blockchain = { path = "../blockchain" }
ethereum-types = "0.4"
memorydb = "0.3.0"
patricia-trie = "0.3.0"
memory-db = "0.11.0"
trie-db = "0.11.0"
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
ethcore-network = { path = "../../util/network" }
ethcore-io = { path = "../../util/io" }
hashdb = "0.3.0"
hash-db = "0.11.0"
heapsize = "0.4"
vm = { path = "../vm" }
fastmap = { path = "../../util/fastmap" }
@@ -41,6 +41,7 @@ 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

@@ -25,10 +25,11 @@
use common_types::ids::BlockId;
use ethereum_types::{H256, U256};
use hashdb::HashDB;
use hash_db::HashDB;
use keccak_hasher::KeccakHasher;
use kvdb::DBValue;
use memorydb::MemoryDB;
use memory_db::MemoryDB;
use journaldb::new_memory_db;
use bytes::Bytes;
use trie::{TrieMut, Trie, Recorder};
use ethtrie::{self, TrieDB, TrieDBMut};
@@ -73,7 +74,8 @@ 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 t = TrieDB::new(&self.db, &self.root)?;
let db: &HashDB<_,_> = &self.db;
let t = TrieDB::new(&db, &self.root)?;
t.get_with(&key!(num), &mut recorder)?;
Ok(Some(recorder.drain().into_iter().map(|x| x.data).collect()))
@@ -96,7 +98,7 @@ pub struct BlockInfo {
pub fn build<F>(cht_num: u64, mut fetcher: F) -> Option<CHT<MemoryDB<KeccakHasher, DBValue>>>
where F: FnMut(BlockId) -> Option<BlockInfo>
{
let mut db = MemoryDB::<KeccakHasher, DBValue>::new();
let mut db = new_memory_db();
// start from the last block by number and work backwards.
let last_num = start_number(cht_num + 1) - 1;
@@ -150,7 +152,7 @@ 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 = MemoryDB::<KeccakHasher, DBValue>::new();
let mut db = new_memory_db();
for node in proof { db.insert(&node[..]); }
let res = match TrieDB::new(&db, &root) {

View File

@@ -116,6 +116,9 @@ pub trait LightChainClient: Send + Sync {
/// 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);
@@ -164,6 +167,8 @@ 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> {
@@ -190,6 +195,7 @@ impl<T: ChainDataFetcher> Client<T> {
listeners: RwLock::new(vec![]),
fetcher,
verify_full: config.verify_full,
exit_handler: Mutex::new(None),
})
}
@@ -360,6 +366,14 @@ impl<T: ChainDataFetcher> Client<T> {
self.chain.heap_size_of_children()
}
/// 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));
}
/// Get a handle to the verification engine.
pub fn engine(&self) -> &Arc<EthEngine> {
&self.engine
@@ -563,6 +577,17 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
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
}

View File

@@ -62,14 +62,14 @@ extern crate ethcore_network as network;
extern crate parity_bytes as bytes;
extern crate ethereum_types;
extern crate ethcore;
extern crate hashdb;
extern crate hash_db;
extern crate heapsize;
extern crate failsafe;
extern crate futures;
extern crate itertools;
extern crate keccak_hasher;
extern crate memorydb;
extern crate patricia_trie as trie;
extern crate memory_db;
extern crate trie_db as trie;
extern crate patricia_trie_ethereum as ethtrie;
extern crate fastmap;
extern crate rand;
@@ -92,3 +92,4 @@ extern crate error_chain;
extern crate kvdb_memorydb;
#[cfg(test)]
extern crate tempdir;
extern crate journaldb;

View File

@@ -533,6 +533,9 @@ impl LightProtocol {
// the timer approach will skip 1 (possibly 2) in rare occasions.
if peer_info.sent_head == announcement.head_hash ||
peer_info.status.head_num >= announcement.head_num ||
// fix for underflow reported in
// https://github.com/paritytech/parity-ethereum/issues/10419
now < peer_info.last_update ||
now - peer_info.last_update < UPDATE_INTERVAL {
continue
}

View File

@@ -30,9 +30,8 @@ use ethcore::state::{self, ProvedExecution};
use ethereum_types::{H256, U256, Address};
use ethtrie::{TrieError, TrieDB};
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak};
use hashdb::HashDB;
use hash_db::HashDB;
use kvdb::DBValue;
use memorydb::MemoryDB;
use parking_lot::Mutex;
use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field};
use rlp::{RlpStream, Rlp};
@@ -981,7 +980,7 @@ impl Account {
let header = self.header.as_ref()?;
let state_root = header.state_root();
let mut db = MemoryDB::new();
let mut db = journaldb::new_memory_db();
for node in proof { db.insert(&node[..]); }
match TrieDB::new(&db, &state_root).and_then(|t| t.get(&keccak(&self.address)))? {
@@ -1101,7 +1100,6 @@ mod tests {
use super::*;
use std::time::Duration;
use ethereum_types::{H256, Address};
use memorydb::MemoryDB;
use parking_lot::Mutex;
use trie::{Trie, TrieMut};
use ethtrie::{SecTrieDB, SecTrieDBMut};
@@ -1281,7 +1279,7 @@ mod tests {
use rlp::RlpStream;
let mut root = H256::default();
let mut db = MemoryDB::new();
let mut db = journaldb::new_memory_db();
let mut header = Header::new();
header.set_number(123_456);
header.set_extra_data(b"test_header".to_vec());

View File

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

View File

@@ -255,4 +255,78 @@ mod tests {
hash: Field::BackReference(0, 0),
})).unwrap();
}
#[test]
fn batch_tx_index_backreference() {
let mut builder = Builder::default();
builder.push(Request::HeaderProof(IncompleteHeaderProofRequest {
num: 100.into(), // header proof puts hash at output 0.
})).unwrap();
builder.push(Request::TransactionIndex(IncompleteTransactionIndexRequest {
hash: Field::BackReference(0, 0),
})).unwrap();
let mut batch = builder.build();
batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Hash(42.into())));
assert!(batch.next_complete().is_some());
batch.answered += 1;
assert!(batch.next_complete().is_some());
}
#[test]
#[should_panic]
fn batch_tx_index_backreference_wrong_output() {
let mut builder = Builder::default();
builder.push(Request::HeaderProof(IncompleteHeaderProofRequest {
num: 100.into(), // header proof puts hash at output 0.
})).unwrap();
builder.push(Request::TransactionIndex(IncompleteTransactionIndexRequest {
hash: Field::BackReference(0, 0),
})).unwrap();
let mut batch = builder.build();
batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Number(42)));
batch.next_complete();
batch.answered += 1;
batch.next_complete();
}
#[test]
fn batch_receipts_backreference() {
let mut builder = Builder::default();
builder.push(Request::HeaderProof(IncompleteHeaderProofRequest {
num: 100.into(), // header proof puts hash at output 0.
})).unwrap();
builder.push(Request::Receipts(IncompleteReceiptsRequest {
hash: Field::BackReference(0, 0),
})).unwrap();
let mut batch = builder.build();
batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Hash(42.into())));
assert!(batch.next_complete().is_some());
batch.answered += 1;
assert!(batch.next_complete().is_some());
}
#[test]
#[should_panic]
fn batch_receipts_backreference_wrong_output() {
let mut builder = Builder::default();
builder.push(Request::HeaderProof(IncompleteHeaderProofRequest {
num: 100.into(), // header proof puts hash at output 0.
})).unwrap();
builder.push(Request::Receipts(IncompleteReceiptsRequest {
hash: Field::BackReference(0, 0),
})).unwrap();
let mut batch = builder.build();
batch.requests[1].fill(|_req_idx, _out_idx| Ok(Output::Number(42)));
batch.next_complete();
batch.answered += 1;
batch.next_complete();
}
}

View File

@@ -907,7 +907,7 @@ pub mod transaction_index {
fn fill<F>(&mut self, oracle: F) where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> {
if let Field::BackReference(req, idx) = self.hash {
self.hash = match oracle(req, idx) {
Ok(Output::Number(hash)) => Field::Scalar(hash.into()),
Ok(Output::Hash(hash)) => Field::Scalar(hash.into()),
_ => Field::BackReference(req, idx),
}
}
@@ -982,7 +982,7 @@ pub mod block_receipts {
fn fill<F>(&mut self, oracle: F) where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> {
if let Field::BackReference(req, idx) = self.hash {
self.hash = match oracle(req, idx) {
Ok(Output::Number(hash)) => Field::Scalar(hash.into()),
Ok(Output::Hash(hash)) => Field::Scalar(hash.into()),
_ => Field::BackReference(req, idx),
}
}

View File

@@ -7,11 +7,12 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
common-types = { path = "../types" }
error-chain = { version = "0.12", default-features = false }
derive_more = "0.14.0"
ethabi = "6.0"
ethabi-contract = "6.0"
ethabi-derive = "6.0"
ethcore = { path = ".." }
ethcore-call-contract = { path = "../call-contract" }
ethcore-io = { path = "../../util/io" }
ethcore-miner = { path = "../../miner" }
ethereum-types = "0.4"
@@ -23,9 +24,9 @@ heapsize = "0.4"
keccak-hash = "0.1.2"
log = "0.4"
parity-bytes = "0.1"
parity-crypto = "0.2"
parity-crypto = "0.3.0"
parking_lot = "0.7"
patricia-trie = "0.3.0"
trie-db = "0.11.0"
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
rand = "0.3"
rlp = { version = "0.3.0", features = ["ethereum"] }
@@ -35,7 +36,7 @@ serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
tiny-keccak = "1.4"
transaction-pool = "1.13.2"
transaction-pool = "2.0"
url = "1"
[dev-dependencies]

View File

@@ -0,0 +1,43 @@
[
{
"constant": true,
"inputs": [
{
"name":"user",
"type":"address"
}
],
"name": "availableKeys",
"outputs": [
{
"name": "",
"type": "bytes32[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant":true,
"inputs": [
{
"name":"user",
"type":"address"
},
{
"name":"document",
"type":"bytes32"
}
],
"name":"checkPermissions",
"outputs": [
{
"name":"",
"type":"bool"
}
],
"payable":false,
"type":"function"
}
]

View File

@@ -18,22 +18,23 @@
use std::io::Read;
use std::str::FromStr;
use std::sync::Arc;
use std::iter::repeat;
use std::time::{Instant, Duration};
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use parking_lot::Mutex;
use ethcore::account_provider::AccountProvider;
use ethereum_types::{H128, H256, Address};
use ethjson;
use ethkey::{Signature, Password, Public};
use ethkey::{Signature, Public};
use crypto;
use futures::Future;
use fetch::{Fetch, Client as FetchClient, Method, BodyReader, Request};
use bytes::{Bytes, ToPretty};
use error::{Error, ErrorKind};
use error::Error;
use url::Url;
use super::find_account_password;
use super::Signer;
use super::key_server_keys::address_to_key;
/// Initialization vector length.
const INIT_VEC_LEN: usize = 16;
@@ -47,7 +48,6 @@ pub trait Encryptor: Send + Sync + 'static {
fn encrypt(
&self,
contract_address: &Address,
accounts: &AccountProvider,
initialisation_vector: &H128,
plain_data: &[u8],
) -> Result<Bytes, Error>;
@@ -56,7 +56,6 @@ pub trait Encryptor: Send + Sync + 'static {
fn decrypt(
&self,
contract_address: &Address,
accounts: &AccountProvider,
cypher: &[u8],
) -> Result<Bytes, Error>;
}
@@ -70,8 +69,6 @@ pub struct EncryptorConfig {
pub threshold: u32,
/// Account used for signing requests to key server
pub key_server_account: Option<Address>,
/// Passwords used to unlock accounts
pub passwords: Vec<Password>,
}
struct EncryptionSession {
@@ -84,14 +81,20 @@ pub struct SecretStoreEncryptor {
config: EncryptorConfig,
client: FetchClient,
sessions: Mutex<HashMap<Address, EncryptionSession>>,
signer: Arc<Signer>,
}
impl SecretStoreEncryptor {
/// Create new encryptor
pub fn new(config: EncryptorConfig, client: FetchClient) -> Result<Self, Error> {
pub fn new(
config: EncryptorConfig,
client: FetchClient,
signer: Arc<Signer>,
) -> Result<Self, Error> {
Ok(SecretStoreEncryptor {
config,
client,
signer,
sessions: Mutex::default(),
})
}
@@ -102,18 +105,17 @@ impl SecretStoreEncryptor {
url_suffix: &str,
use_post: bool,
contract_address: &Address,
accounts: &AccountProvider,
) -> Result<Bytes, Error> {
// check if the key was already cached
if let Some(key) = self.obtained_key(contract_address) {
return Ok(key);
}
let contract_address_signature = self.sign_contract_address(contract_address, accounts)?;
let requester = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?;
let contract_address_signature = self.sign_contract_address(contract_address)?;
let requester = self.config.key_server_account.ok_or_else(|| Error::KeyServerAccountNotSet)?;
// key id in SS is H256 && we have H160 here => expand with assitional zeros
let contract_address_extended: H256 = contract_address.into();
let base_url = self.config.base_url.clone().ok_or_else(|| ErrorKind::KeyServerNotSet)?;
let base_url = self.config.base_url.clone().ok_or_else(|| Error::KeyServerNotSet)?;
// prepare request url
let url = format!("{}/{}/{}{}",
@@ -130,16 +132,16 @@ impl SecretStoreEncryptor {
Method::GET
};
let url = Url::from_str(&url).map_err(|e| ErrorKind::Encrypt(e.to_string()))?;
let url = Url::from_str(&url).map_err(|e| Error::Encrypt(e.to_string()))?;
let response = self.client.fetch(Request::new(url, method), Default::default()).wait()
.map_err(|e| ErrorKind::Encrypt(e.to_string()))?;
.map_err(|e| Error::Encrypt(e.to_string()))?;
if response.is_not_found() {
bail!(ErrorKind::EncryptionKeyNotFound(*contract_address));
return Err(Error::EncryptionKeyNotFound(*contract_address));
}
if !response.is_success() {
bail!(ErrorKind::Encrypt(response.status().canonical_reason().unwrap_or("unknown").into()));
return Err(Error::Encrypt(response.status().canonical_reason().unwrap_or("unknown").into()));
}
// read HTTP response
@@ -147,11 +149,10 @@ impl SecretStoreEncryptor {
BodyReader::new(response).read_to_string(&mut result)?;
// response is JSON string (which is, in turn, hex-encoded, encrypted Public)
let encrypted_bytes: ethjson::bytes::Bytes = result.trim_matches('\"').parse().map_err(|e| ErrorKind::Encrypt(e))?;
let password = find_account_password(&self.config.passwords, &*accounts, &requester);
let encrypted_bytes: ethjson::bytes::Bytes = result.trim_matches('\"').parse().map_err(|e| Error::Encrypt(e))?;
// decrypt Public
let decrypted_bytes = accounts.decrypt(requester, password, &crypto::DEFAULT_MAC, &encrypted_bytes)?;
let decrypted_bytes = self.signer.decrypt(requester, &crypto::DEFAULT_MAC, &encrypted_bytes)?;
let decrypted_key = Public::from_slice(&decrypted_bytes);
// and now take x coordinate of Public as a key
@@ -187,12 +188,9 @@ impl SecretStoreEncryptor {
}
}
fn sign_contract_address(&self, contract_address: &Address, accounts: &AccountProvider) -> Result<Signature, Error> {
// key id in SS is H256 && we have H160 here => expand with assitional zeros
let contract_address_extended: H256 = contract_address.into();
let key_server_account = self.config.key_server_account.ok_or_else(|| ErrorKind::KeyServerAccountNotSet)?;
let password = find_account_password(&self.config.passwords, accounts, &key_server_account);
Ok(accounts.sign(key_server_account, password, H256::from_slice(&contract_address_extended))?)
fn sign_contract_address(&self, contract_address: &Address) -> Result<Signature, Error> {
let key_server_account = self.config.key_server_account.ok_or_else(|| Error::KeyServerAccountNotSet)?;
Ok(self.signer.sign(key_server_account, address_to_key(contract_address))?)
}
}
@@ -200,16 +198,15 @@ impl Encryptor for SecretStoreEncryptor {
fn encrypt(
&self,
contract_address: &Address,
accounts: &AccountProvider,
initialisation_vector: &H128,
plain_data: &[u8],
) -> Result<Bytes, Error> {
// retrieve the key, try to generate it if it doesn't exist yet
let key = match self.retrieve_key("", false, contract_address, &*accounts) {
let key = match self.retrieve_key("", false, contract_address) {
Ok(key) => Ok(key),
Err(Error(ErrorKind::EncryptionKeyNotFound(_), _)) => {
Err(Error::EncryptionKeyNotFound(_)) => {
trace!(target: "privatetx", "Key for account wasnt found in sstore. Creating. Address: {:?}", contract_address);
self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address, &*accounts)
self.retrieve_key(&format!("/{}", self.config.threshold), true, contract_address)
}
Err(err) => Err(err),
}?;
@@ -218,7 +215,7 @@ impl Encryptor for SecretStoreEncryptor {
let mut cypher = Vec::with_capacity(plain_data.len() + initialisation_vector.len());
cypher.extend(repeat(0).take(plain_data.len()));
crypto::aes::encrypt_128_ctr(&key, initialisation_vector, plain_data, &mut cypher)
.map_err(|e| ErrorKind::Encrypt(e.to_string()))?;
.map_err(|e| Error::Encrypt(e.to_string()))?;
cypher.extend_from_slice(&initialisation_vector);
Ok(cypher)
@@ -228,24 +225,23 @@ impl Encryptor for SecretStoreEncryptor {
fn decrypt(
&self,
contract_address: &Address,
accounts: &AccountProvider,
cypher: &[u8],
) -> Result<Bytes, Error> {
// initialization vector takes INIT_VEC_LEN bytes
let cypher_len = cypher.len();
if cypher_len < INIT_VEC_LEN {
bail!(ErrorKind::Decrypt("Invalid cypher".into()));
return Err(Error::Decrypt("Invalid cypher".into()));
}
// retrieve existing key
let key = self.retrieve_key("", false, contract_address, accounts)?;
let key = self.retrieve_key("", false, contract_address)?;
// use symmetric decryption to decrypt document
let (cypher, iv) = cypher.split_at(cypher_len - INIT_VEC_LEN);
let mut plain_data = Vec::with_capacity(cypher_len - INIT_VEC_LEN);
plain_data.extend(repeat(0).take(cypher_len - INIT_VEC_LEN));
crypto::aes::decrypt_128_ctr(&key, &iv, cypher, &mut plain_data)
.map_err(|e| ErrorKind::Decrypt(e.to_string()))?;
.map_err(|e| Error::Decrypt(e.to_string()))?;
Ok(plain_data)
}
}
@@ -258,7 +254,6 @@ impl Encryptor for NoopEncryptor {
fn encrypt(
&self,
_contract_address: &Address,
_accounts: &AccountProvider,
_initialisation_vector: &H128,
data: &[u8],
) -> Result<Bytes, Error> {
@@ -268,7 +263,6 @@ impl Encryptor for NoopEncryptor {
fn decrypt(
&self,
_contract_address: &Address,
_accounts: &AccountProvider,
data: &[u8],
) -> Result<Bytes, Error> {
Ok(data.to_vec())

View File

@@ -14,191 +14,182 @@
// 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 std::error;
use derive_more::Display;
use ethereum_types::Address;
use rlp::DecoderError;
use ethtrie::TrieError;
use ethcore::account_provider::SignError;
use ethcore::error::{Error as EthcoreError, ExecutionError};
use types::transaction::Error as TransactionError;
use ethkey::Error as KeyError;
use txpool::Error as TxPoolError;
use ethkey::crypto::Error as CryptoError;
use txpool::VerifiedTransaction;
use private_transactions::VerifiedPrivateTransaction;
error_chain! {
foreign_links {
Io(::std::io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."];
Decoder(DecoderError) #[doc = "RLP decoding error."];
Trie(TrieError) #[doc = "Error concerning TrieDBs."];
Txpool(TxPoolError) #[doc = "Tx pool error."];
}
type TxPoolError = txpool::Error<<VerifiedPrivateTransaction as VerifiedTransaction>::Hash>;
errors {
#[doc = "Encryption error."]
Encrypt(err: String) {
description("Encryption error"),
display("Encryption error. ({})", err),
}
#[derive(Debug, Display)]
pub enum Error {
/// Error concerning the Rust standard library's IO subsystem.
#[display(fmt = "Io Error: {}", _0)]
Io(::std::io::Error),
/// RLP decoding error.
#[display(fmt = "Decoder Error: {}", _0)]
Decoder(DecoderError),
/// Error concerning TrieDBs.
#[display(fmt = "Trie Error: {}", _0)]
Trie(TrieError),
/// Transaction pool error.
#[display(fmt = "Transaction Pool Error: {}", _0)]
TxPool(TxPoolError),
/// Crypto error.
#[display(fmt = "Crypto Error {}", _0)]
Crypto(CryptoError),
/// Encryption error.
#[display(fmt = "Encryption error. ({})", _0)]
Encrypt(String),
/// Decryption error.
#[display(fmt = "Decryption error. ({})", _0)]
Decrypt(String),
/// Address not authorized.
#[display(fmt = "Private transaction execution is not authorised for {}", _0)]
NotAuthorised(Address),
/// Transaction creates more than one contract.
#[display(fmt = "Private transaction created too many contracts")]
TooManyContracts,
/// Contract call error.
#[display(fmt = "Contract call error. ({})", _0)]
Call(String),
/// State is not available.
#[display(fmt = "State is not available")]
StatePruned,
/// State is incorrect.
#[display(fmt = "State is incorrect")]
StateIncorrect,
/// Wrong private transaction type.
#[display(fmt = "Wrong private transaction type")]
BadTransactionType,
/// Contract does not exist or was not created.
#[display(fmt = "Contract does not exist or was not created")]
ContractDoesNotExist,
/// Reference to the client is corrupted.
#[display(fmt = "Reference to the client is corrupted")]
ClientIsMalformed,
/// Queue of private transactions for verification is full.
#[display(fmt = "Queue of private transactions for verification is full")]
QueueIsFull,
/// The transaction already exists in queue of private transactions.
#[display(fmt = "The transaction already exists in queue of private transactions.")]
PrivateTransactionAlreadyImported,
/// The information about private transaction is not found in the store.
#[display(fmt = "The information about private transaction is not found in the store.")]
PrivateTransactionNotFound,
/// Account for signing public transactions not set.
#[display(fmt = "Account for signing public transactions not set.")]
SignerAccountNotSet,
/// Account for validating private transactions not set.
#[display(fmt = "Account for validating private transactions not set.")]
ValidatorAccountNotSet,
/// Account for signing requests to key server not set.
#[display(fmt = "Account for signing requests to key server not set.")]
KeyServerAccountNotSet,
/// Encryption key is not found on key server.
#[display(fmt = "Encryption key is not found on key server for {}", _0)]
EncryptionKeyNotFound(Address),
/// Key server URL is not set.
#[display(fmt = "Key server URL is not set.")]
KeyServerNotSet,
/// VM execution error.
#[display(fmt = "VM execution error {}", _0)]
Execution(ExecutionError),
/// General signing error.
#[display(fmt = "General signing error {}", _0)]
Key(KeyError),
/// Error of transactions processing.
#[display(fmt = "Error of transactions processing {}", _0)]
Transaction(TransactionError),
/// General ethcore error.
#[display(fmt = "General ethcore error {}", _0)]
Ethcore(EthcoreError),
/// A convenient variant for String.
#[display(fmt = "{}", _0)]
Msg(String),
}
#[doc = "Decryption error."]
Decrypt(err: String) {
description("Decryption error"),
display("Decryption error. ({})", err),
}
#[doc = "Address not authorized."]
NotAuthorised(address: Address) {
description("Address not authorized"),
display("Private transaction execution is not authorised for {}", address),
}
#[doc = "Transaction creates more than one contract."]
TooManyContracts {
description("Transaction creates more than one contract."),
display("Private transaction created too many contracts"),
}
#[doc = "Contract call error."]
Call(err: String) {
description("Contract call error."),
display("Contract call error. ({})", err),
}
#[doc = "State is not available."]
StatePruned {
description("State is not available."),
display("State is not available"),
}
#[doc = "State is incorrect."]
StateIncorrect {
description("State is incorrect."),
display("State is incorrect"),
}
#[doc = "Wrong private transaction type."]
BadTransactonType {
description("Wrong private transaction type."),
display("Wrong private transaction type"),
}
#[doc = "Contract does not exist or was not created."]
ContractDoesNotExist {
description("Contract does not exist or was not created."),
display("Contract does not exist or was not created"),
}
#[doc = "Reference to the client is corrupted."]
ClientIsMalformed {
description("Reference to the client is corrupted."),
display("Reference to the client is corrupted"),
}
#[doc = "Queue of private transactions for verification is full."]
QueueIsFull {
description("Queue of private transactions for verification is full."),
display("Queue of private transactions for verification is full"),
}
#[doc = "The transaction already exists in queue of private transactions."]
PrivateTransactionAlreadyImported {
description("The transaction already exists in queue of private transactions."),
display("The transaction already exists in queue of private transactions."),
}
#[doc = "The information about private transaction is not found in the store."]
PrivateTransactionNotFound {
description("The information about private transaction is not found in the store."),
display("The information about private transaction is not found in the store."),
}
#[doc = "Account for signing public transactions not set."]
SignerAccountNotSet {
description("Account for signing public transactions not set."),
display("Account for signing public transactions not set."),
}
#[doc = "Account for validating private transactions not set."]
ValidatorAccountNotSet {
description("Account for validating private transactions not set."),
display("Account for validating private transactions not set."),
}
#[doc = "Account for signing requests to key server not set."]
KeyServerAccountNotSet {
description("Account for signing requests to key server not set."),
display("Account for signing requests to key server not set."),
}
#[doc = "Encryption key is not found on key server."]
EncryptionKeyNotFound(address: Address) {
description("Encryption key is not found on key server"),
display("Encryption key is not found on key server for {}", address),
}
#[doc = "Key server URL is not set."]
KeyServerNotSet {
description("Key server URL is not set."),
display("Key server URL is not set."),
}
#[doc = "VM execution error."]
Execution(err: ExecutionError) {
description("VM execution error."),
display("VM execution error {}", err),
}
#[doc = "General signing error."]
Key(err: KeyError) {
description("General signing error."),
display("General signing error {}", err),
}
#[doc = "Account provider signing error."]
Sign(err: SignError) {
description("Account provider signing error."),
display("Account provider signing error {}", err),
}
#[doc = "Error of transactions processing."]
Transaction(err: TransactionError) {
description("Error of transactions processing."),
display("Error of transactions processing {}", err),
}
#[doc = "General ethcore error."]
Ethcore(err: EthcoreError) {
description("General ethcore error."),
display("General ethcore error {}", err),
impl error::Error for Error {
fn source(&self) -> Option<&(error::Error + 'static)> {
match self {
Error::Io(e) => Some(e),
Error::Decoder(e) => Some(e),
Error::Trie(e) => Some(e),
Error::TxPool(e) => Some(e),
Error::Crypto(e) => Some(e),
Error::Execution(e) => Some(e),
Error::Key(e) => Some(e),
Error::Transaction(e) => Some(e),
Error::Ethcore(e) => Some(e),
_ => None,
}
}
}
impl From<SignError> for Error {
fn from(err: SignError) -> Self {
ErrorKind::Sign(err).into()
impl From<String> for Error {
fn from(s: String) -> Self {
Error::Msg(s)
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Error::Io(err).into()
}
}
impl From<KeyError> for Error {
fn from(err: KeyError) -> Self {
ErrorKind::Key(err).into()
Error::Key(err).into()
}
}
impl From<CryptoError> for Error {
fn from(err: CryptoError) -> Self {
Error::Crypto(err).into()
}
}
impl From<DecoderError> for Error {
fn from(err: DecoderError) -> Self {
Error::Decoder(err).into()
}
}
impl From<ExecutionError> for Error {
fn from(err: ExecutionError) -> Self {
ErrorKind::Execution(err).into()
Error::Execution(err).into()
}
}
impl From<TransactionError> for Error {
fn from(err: TransactionError) -> Self {
ErrorKind::Transaction(err).into()
Error::Transaction(err).into()
}
}
impl From<TrieError> for Error {
fn from(err: TrieError) -> Self {
Error::Trie(err).into()
}
}
impl From<TxPoolError> for Error {
fn from(err: TxPoolError) -> Self {
Error::TxPool(err).into()
}
}
impl From<EthcoreError> for Error {
fn from(err: EthcoreError) -> Self {
ErrorKind::Ethcore(err).into()
Error::Ethcore(err).into()
}
}

View File

@@ -0,0 +1,173 @@
// 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/>.
//! Wrapper around key server responsible for access keys processing.
use std::sync::Arc;
use parking_lot::RwLock;
use ethereum_types::{H256, Address};
use call_contract::{CallContract, RegistryInfo};
use ethcore::client::BlockId;
use ethabi::FunctionOutputDecoder;
const ACL_CHECKER_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_acl_checker";
use_contract!(keys_acl_contract, "res/keys_acl.json");
/// Returns the address (of the contract), that corresponds to the key
pub fn key_to_address(key: &H256) -> Address {
Address::from_slice(&key.to_vec()[..10])
}
/// Returns the key from the key server associated with the contract
pub fn address_to_key(contract_address: &Address) -> H256 {
// Current solution uses contract address extended with 0 as id
let contract_address_extended: H256 = contract_address.into();
H256::from_slice(&contract_address_extended)
}
/// Trait for keys server keys provider.
pub trait KeyProvider: Send + Sync + 'static {
/// Account, that is used for communication with key server
fn key_server_account(&self) -> Option<Address>;
/// List of keys available for the account
fn available_keys(&self, block: BlockId, account: &Address) -> Option<Vec<Address>>;
/// Update permissioning contract
fn update_acl_contract(&self);
}
/// Secret Store keys provider
pub struct SecretStoreKeys<C> where C: CallContract + RegistryInfo + Send + Sync + 'static {
client: Arc<C>,
key_server_account: Option<Address>,
keys_acl_contract: RwLock<Option<Address>>,
}
impl<C> SecretStoreKeys<C> where C: CallContract + RegistryInfo + Send + Sync + 'static {
/// Create provider
pub fn new(client: Arc<C>, key_server_account: Option<Address>) -> Self {
SecretStoreKeys {
client,
key_server_account,
keys_acl_contract: RwLock::new(None),
}
}
}
impl<C> KeyProvider for SecretStoreKeys<C> where C: CallContract + RegistryInfo + Send + Sync + 'static {
fn key_server_account(&self) -> Option<Address> {
self.key_server_account
}
fn available_keys(&self, block: BlockId, account: &Address) -> Option<Vec<Address>> {
match *self.keys_acl_contract.read() {
Some(acl_contract_address) => {
let (data, decoder) = keys_acl_contract::functions::available_keys::call(*account);
if let Ok(value) = self.client.call_contract(block, acl_contract_address, data) {
decoder.decode(&value).ok().map(|key_values| {
key_values.iter().map(key_to_address).collect()
})
} else {
None
}
}
None => None,
}
}
fn update_acl_contract(&self) {
let contract_address = self.client.registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.into(), BlockId::Latest);
if *self.keys_acl_contract.read() != contract_address {
trace!(target: "privatetx", "Configuring for ACL checker contract from address {:?}",
contract_address);
*self.keys_acl_contract.write() = contract_address;
}
}
}
/// Dummy keys provider.
pub struct StoringKeyProvider {
available_keys: RwLock<Option<Vec<Address>>>,
key_server_account: Option<Address>,
}
impl StoringKeyProvider {
/// Store available keys
pub fn set_available_keys(&self, keys: &Vec<Address>) {
*self.available_keys.write() = Some(keys.clone())
}
}
impl Default for StoringKeyProvider {
fn default() -> Self {
StoringKeyProvider {
available_keys: RwLock::new(None),
key_server_account: Some(Address::default()),
}
}
}
impl KeyProvider for StoringKeyProvider {
fn key_server_account(&self) -> Option<Address> {
self.key_server_account
}
fn available_keys(&self, _block: BlockId, _account: &Address) -> Option<Vec<Address>> {
self.available_keys.read().clone()
}
fn update_acl_contract(&self) {}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use ethkey::{Secret, KeyPair};
use bytes::Bytes;
use super::*;
struct DummyRegistryClient {
registry_address: Option<Address>,
}
impl DummyRegistryClient {
pub fn new(registry_address: Option<Address>) -> Self {
DummyRegistryClient {
registry_address
}
}
}
impl RegistryInfo for DummyRegistryClient {
fn registry_address(&self, _name: String, _block: BlockId) -> Option<Address> { self.registry_address }
}
impl CallContract for DummyRegistryClient {
fn call_contract(&self, _id: BlockId, _address: Address, _data: Bytes) -> Result<Bytes, String> { Ok(vec![]) }
}
#[test]
fn should_update_acl_contract() {
let key = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000011")).unwrap();
let client = DummyRegistryClient::new(Some(key.address()));
let keys_data = SecretStoreKeys::new(Arc::new(client), None);
keys_data.update_acl_contract();
assert_eq!(keys_data.keys_acl_contract.read().unwrap(), key.address());
}
}

View File

@@ -21,6 +21,7 @@
#![recursion_limit="256"]
mod encryptor;
mod key_server_keys;
mod private_transactions;
mod messages;
mod error;
@@ -28,6 +29,7 @@ mod error;
extern crate common_types as types;
extern crate ethabi;
extern crate ethcore;
extern crate ethcore_call_contract as call_contract;
extern crate ethcore_io as io;
extern crate ethcore_miner;
extern crate ethereum_types;
@@ -40,7 +42,7 @@ extern crate keccak_hash as hash;
extern crate parity_bytes as bytes;
extern crate parity_crypto as crypto;
extern crate parking_lot;
extern crate patricia_trie as trie;
extern crate trie_db as trie;
extern crate patricia_trie_ethereum as ethtrie;
extern crate rlp;
extern crate rustc_hex;
@@ -52,8 +54,7 @@ extern crate log;
extern crate ethabi_derive;
#[macro_use]
extern crate ethabi_contract;
#[macro_use]
extern crate error_chain;
extern crate derive_more;
#[macro_use]
extern crate rlp_derive;
@@ -63,9 +64,10 @@ extern crate rand;
extern crate env_logger;
pub use encryptor::{Encryptor, SecretStoreEncryptor, EncryptorConfig, NoopEncryptor};
pub use key_server_keys::{KeyProvider, SecretStoreKeys, StoringKeyProvider};
pub use private_transactions::{VerifiedPrivateTransaction, VerificationStore, PrivateTransactionSigningDesc, SigningStore};
pub use messages::{PrivateTransaction, SignedPrivateTransaction};
pub use error::{Error, ErrorKind};
pub use error::Error;
use std::sync::{Arc, Weak};
use std::collections::{HashMap, HashSet, BTreeMap};
@@ -82,13 +84,13 @@ use types::transaction::{SignedTransaction, Transaction, Action, UnverifiedTrans
use ethcore::{contract_address as ethcore_contract_address};
use ethcore::client::{
Client, ChainNotify, NewBlocks, ChainMessageType, ClientIoMessage, BlockId,
CallContract, Call, BlockInfo
Call, BlockInfo
};
use ethcore::account_provider::AccountProvider;
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
use ethcore::{state, state_db};
use ethcore::trace::{Tracer, VMTracer};
use call_contract::CallContract;
use rustc_hex::FromHex;
use ethkey::Password;
use ethabi::FunctionOutputDecoder;
// Source avaiable at https://github.com/parity-contracts/private-tx/blob/master/contracts/PrivateContract.sol
@@ -115,8 +117,6 @@ pub struct ProviderConfig {
pub validator_accounts: Vec<Address>,
/// Account used for signing public transactions created from private transactions
pub signer_account: Option<Address>,
/// Passwords used to unlock accounts
pub passwords: Vec<Password>,
}
#[derive(Debug)]
@@ -124,50 +124,85 @@ pub struct ProviderConfig {
pub struct Receipt {
/// Private transaction hash.
pub hash: H256,
/// Created contract address if any.
pub contract_address: Option<Address>,
/// Contract address.
pub contract_address: Address,
/// Execution status.
pub status_code: u8,
}
/// Payload signing and decrypting capabilities.
pub trait Signer: Send + Sync {
/// Decrypt payload using private key of given address.
fn decrypt(&self, account: Address, shared_mac: &[u8], payload: &[u8]) -> Result<Vec<u8>, Error>;
/// Sign given hash using provided account.
fn sign(&self, account: Address, hash: ethkey::Message) -> Result<Signature, Error>;
}
/// Signer implementation that errors on any request.
pub struct DummySigner;
impl Signer for DummySigner {
fn decrypt(&self, _account: Address, _shared_mac: &[u8], _payload: &[u8]) -> Result<Vec<u8>, Error> {
Err("Decrypting is not supported.".to_owned())?
}
fn sign(&self, _account: Address, _hash: ethkey::Message) -> Result<Signature, Error> {
Err("Signing is not supported.".to_owned())?
}
}
/// Signer implementation using multiple keypairs
pub struct KeyPairSigner(pub Vec<ethkey::KeyPair>);
impl Signer for KeyPairSigner {
fn decrypt(&self, account: Address, shared_mac: &[u8], payload: &[u8]) -> Result<Vec<u8>, Error> {
let kp = self.0.iter().find(|k| k.address() == account).ok_or(ethkey::Error::InvalidAddress)?;
Ok(ethkey::crypto::ecies::decrypt(kp.secret(), shared_mac, payload)?)
}
fn sign(&self, account: Address, hash: ethkey::Message) -> Result<Signature, Error> {
let kp = self.0.iter().find(|k| k.address() == account).ok_or(ethkey::Error::InvalidAddress)?;
Ok(ethkey::sign(kp.secret(), &hash)?)
}
}
/// Manager of private transactions
pub struct Provider {
encryptor: Box<Encryptor>,
validator_accounts: HashSet<Address>,
signer_account: Option<Address>,
passwords: Vec<Password>,
notify: RwLock<Vec<Weak<ChainNotify>>>,
transactions_for_signing: RwLock<SigningStore>,
transactions_for_verification: VerificationStore,
client: Arc<Client>,
miner: Arc<Miner>,
accounts: Arc<AccountProvider>,
accounts: Arc<Signer>,
channel: IoChannel<ClientIoMessage>,
keys_provider: Arc<KeyProvider>,
}
#[derive(Debug)]
pub struct PrivateExecutionResult<T, V> where T: Tracer, V: VMTracer {
code: Option<Bytes>,
state: Bytes,
contract_address: Option<Address>,
contract_address: Address,
result: Executed<T::Output, V::Output>,
}
impl Provider where {
impl Provider {
/// Create a new provider.
pub fn new(
client: Arc<Client>,
miner: Arc<Miner>,
accounts: Arc<AccountProvider>,
accounts: Arc<Signer>,
encryptor: Box<Encryptor>,
config: ProviderConfig,
channel: IoChannel<ClientIoMessage>,
keys_provider: Arc<KeyProvider>,
) -> Self {
keys_provider.update_acl_contract();
Provider {
encryptor,
validator_accounts: config.validator_accounts.into_iter().collect(),
signer_account: config.signer_account,
passwords: config.passwords,
notify: RwLock::default(),
transactions_for_signing: RwLock::default(),
transactions_for_verification: VerificationStore::default(),
@@ -175,6 +210,7 @@ impl Provider where {
miner,
accounts,
channel,
keys_provider,
}
}
@@ -201,10 +237,10 @@ impl Provider where {
trace!(target: "privatetx", "Creating private transaction from regular transaction: {:?}", signed_transaction);
if self.signer_account.is_none() {
warn!(target: "privatetx", "Signing account not set");
bail!(ErrorKind::SignerAccountNotSet);
return Err(Error::SignerAccountNotSet);
}
let tx_hash = signed_transaction.hash();
let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| ErrorKind::BadTransactonType)?;
let contract = Self::contract_address_from_transaction(&signed_transaction).map_err(|_| Error::BadTransactionType)?;
let data = signed_transaction.rlp_bytes();
let encrypted_transaction = self.encrypt(&contract, &Self::iv_from_transaction(&signed_transaction), &data)?;
let private = PrivateTransaction::new(encrypted_transaction, contract);
@@ -225,7 +261,7 @@ impl Provider where {
self.broadcast_private_transaction(private.hash(), private.rlp_bytes());
Ok(Receipt {
hash: tx_hash,
contract_address: Some(contract),
contract_address: contract,
status_code: 0,
})
}
@@ -239,21 +275,20 @@ impl Provider where {
keccak(&state_buf.as_ref())
}
fn pool_client<'a>(&'a self, nonce_cache: &'a NonceCache) -> miner::pool_client::PoolClient<'a, Client> {
fn pool_client<'a>(&'a self, nonce_cache: &'a NonceCache, local_accounts: &'a HashSet<Address>) -> miner::pool_client::PoolClient<'a, Client> {
let engine = self.client.engine();
let refuse_service_transactions = true;
miner::pool_client::PoolClient::new(
&*self.client,
nonce_cache,
engine,
Some(&*self.accounts),
local_accounts,
refuse_service_transactions,
)
}
/// Retrieve and verify the first available private transaction for every sender
fn process_verification_queue(&self) -> Result<(), Error> {
let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE);
let process_transaction = |transaction: &VerifiedPrivateTransaction| -> Result<_, String> {
let private_hash = transaction.private_transaction.hash();
match transaction.validator_account {
@@ -273,20 +308,19 @@ impl Provider where {
// TODO #9825 [ToDr] Usage of BlockId::Latest
let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest);
if let Err(e) = contract_nonce {
bail!("Cannot retrieve contract nonce: {:?}", e);
return Err(format!("Cannot retrieve contract nonce: {:?}", e).into());
}
let contract_nonce = contract_nonce.expect("Error was checked before");
let private_state = self.execute_private_transaction(BlockId::Latest, &transaction.transaction);
if let Err(e) = private_state {
bail!("Cannot retrieve private state: {:?}", e);
return Err(format!("Cannot retrieve private state: {:?}", e).into());
}
let private_state = private_state.expect("Error was checked before");
let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce);
trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash);
let password = find_account_password(&self.passwords, &*self.accounts, &validator_account);
let signed_state = self.accounts.sign(validator_account, password, private_state_hash);
let signed_state = self.accounts.sign(validator_account, private_state_hash);
if let Err(e) = signed_state {
bail!("Cannot sign the state: {:?}", e);
return Err(format!("Cannot sign the state: {:?}", e).into());
}
let signed_state = signed_state.expect("Error was checked before");
let signed_private_transaction = SignedPrivateTransaction::new(private_hash, signed_state, None);
@@ -296,7 +330,9 @@ impl Provider where {
}
Ok(())
};
let ready_transactions = self.transactions_for_verification.drain(self.pool_client(&nonce_cache));
let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE);
let local_accounts = HashSet::new();
let ready_transactions = self.transactions_for_verification.drain(self.pool_client(&nonce_cache, &local_accounts));
for transaction in ready_transactions {
if let Err(e) = process_transaction(&transaction) {
warn!(target: "privatetx", "Error: {:?}", e);
@@ -325,26 +361,27 @@ impl Provider where {
signatures.push(signed_tx.signature());
let rsv: Vec<Signature> = signatures.into_iter().map(|sign| sign.into_electrum().into()).collect();
// Create public transaction
let signer_account = self.signer_account.ok_or_else(|| Error::SignerAccountNotSet)?;
let state = self.client.state_at(BlockId::Latest).ok_or(Error::StatePruned)?;
let nonce = state.nonce(&signer_account)?;
let public_tx = self.public_transaction(
desc.state.clone(),
&desc.original_transaction,
&rsv,
desc.original_transaction.nonce,
nonce,
desc.original_transaction.gas_price
)?;
trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx);
// Sign and add it to the queue
let chain_id = desc.original_transaction.chain_id();
let hash = public_tx.hash(chain_id);
let signer_account = self.signer_account.ok_or_else(|| ErrorKind::SignerAccountNotSet)?;
let password = find_account_password(&self.passwords, &*self.accounts, &signer_account);
let signature = self.accounts.sign(signer_account, password, hash)?;
let signature = self.accounts.sign(signer_account, hash)?;
let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?;
match self.miner.import_own_transaction(&*self.client, signed.into()) {
Ok(_) => trace!(target: "privatetx", "Public transaction added to queue"),
Err(err) => {
warn!(target: "privatetx", "Failed to add transaction to queue, error: {:?}", err);
bail!(err);
return Err(err.into());
}
}
// Notify about state changes
@@ -359,7 +396,7 @@ impl Provider where {
// Remove from store for signing
if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) {
warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err);
bail!(err);
return Err(err);
}
} else {
// Add signature to the store
@@ -367,7 +404,7 @@ impl Provider where {
Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"),
Err(err) => {
warn!(target: "privatetx", "Failed to add signature to signing store, error: {:?}", err);
bail!(err);
return Err(err);
}
}
}
@@ -379,7 +416,7 @@ impl Provider where {
Action::Call(contract) => Ok(contract),
_ => {
warn!(target: "privatetx", "Incorrect type of action for the transaction");
bail!(ErrorKind::BadTransactonType);
return Err(Error::BadTransactionType);
}
}
}
@@ -398,13 +435,13 @@ impl Provider where {
}
false => {
warn!(target: "privatetx", "Sender's state doesn't correspond to validator's");
bail!(ErrorKind::StateIncorrect);
return Err(Error::StateIncorrect);
}
}
}
Err(err) => {
warn!(target: "privatetx", "Sender's state doesn't correspond to validator's, error {:?}", err);
bail!(err);
return Err(err.into());
}
}
}
@@ -433,32 +470,32 @@ impl Provider where {
fn encrypt(&self, contract_address: &Address, initialisation_vector: &H128, data: &[u8]) -> Result<Bytes, Error> {
trace!(target: "privatetx", "Encrypt data using key(address): {:?}", contract_address);
Ok(self.encryptor.encrypt(contract_address, &*self.accounts, initialisation_vector, data)?)
Ok(self.encryptor.encrypt(contract_address, initialisation_vector, data)?)
}
fn decrypt(&self, contract_address: &Address, data: &[u8]) -> Result<Bytes, Error> {
trace!(target: "privatetx", "Decrypt data using key(address): {:?}", contract_address);
Ok(self.encryptor.decrypt(contract_address, &*self.accounts, data)?)
Ok(self.encryptor.decrypt(contract_address, data)?)
}
fn get_decrypted_state(&self, address: &Address, block: BlockId) -> Result<Bytes, Error> {
let (data, decoder) = private_contract::functions::state::call();
let value = self.client.call_contract(block, *address, data)?;
let state = decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?;
let state = decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?;
self.decrypt(address, &state)
}
fn get_decrypted_code(&self, address: &Address, block: BlockId) -> Result<Bytes, Error> {
let (data, decoder) = private_contract::functions::code::call();
let value = self.client.call_contract(block, *address, data)?;
let state = decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)))?;
let state = decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?;
self.decrypt(address, &state)
}
pub fn get_contract_nonce(&self, address: &Address, block: BlockId) -> Result<U256, Error> {
let (data, decoder) = private_contract::functions::nonce::call();
let value = self.client.call_contract(block, *address, data)?;
decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)).into())
decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into())
}
fn snapshot_to_storage(raw: Bytes) -> HashMap<H256, H256> {
@@ -482,53 +519,68 @@ impl Provider where {
raw
}
fn patch_account_state(&self, contract_address: &Address, block: BlockId, state: &mut state::State<state_db::StateDB>) -> Result<(), Error> {
let contract_code = Arc::new(self.get_decrypted_code(contract_address, block)?);
let contract_state = self.get_decrypted_state(contract_address, block)?;
trace!(target: "privatetx", "Patching contract at {:?}, code: {:?}, state: {:?}", contract_address, contract_code, contract_state);
state.patch_account(contract_address, contract_code, Self::snapshot_to_storage(contract_state))?;
Ok(())
}
pub fn execute_private<T, V>(&self, transaction: &SignedTransaction, options: TransactOptions<T, V>, block: BlockId) -> Result<PrivateExecutionResult<T, V>, Error>
where
T: Tracer,
V: VMTracer,
{
let mut env_info = self.client.env_info(block).ok_or(ErrorKind::StatePruned)?;
let mut env_info = self.client.env_info(block).ok_or(Error::StatePruned)?;
env_info.gas_limit = transaction.gas;
let mut state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?;
let mut state = self.client.state_at(block).ok_or(Error::StatePruned)?;
// TODO #9825 in case of BlockId::Latest these need to operate on the same state
let contract_address = match transaction.action {
Action::Call(ref contract_address) => {
let contract_code = Arc::new(self.get_decrypted_code(contract_address, block)?);
let contract_state = self.get_decrypted_state(contract_address, block)?;
trace!(target: "privatetx", "Patching contract at {:?}, code: {:?}, state: {:?}", contract_address, contract_code, contract_state);
state.patch_account(contract_address, contract_code, Self::snapshot_to_storage(contract_state))?;
// Patch current contract state
self.patch_account_state(contract_address, block, &mut state)?;
Some(*contract_address)
},
Action::Create => None,
};
let engine = self.client.engine();
let contract_address = contract_address.or({
let sender = transaction.sender();
let nonce = state.nonce(&sender)?;
let sender = transaction.sender();
let nonce = state.nonce(&sender)?;
let contract_address = contract_address.unwrap_or_else(|| {
let (new_address, _) = ethcore_contract_address(engine.create_address_scheme(env_info.number), &sender, &nonce, &transaction.data);
Some(new_address)
new_address
});
// Patch other available private contracts' states as well
// TODO: #10133 patch only required for the contract states
if let Some(key_server_account) = self.keys_provider.key_server_account() {
if let Some(available_contracts) = self.keys_provider.available_keys(block, &key_server_account) {
for private_contract in available_contracts {
if private_contract == contract_address {
continue;
}
self.patch_account_state(&private_contract, block, &mut state)?;
}
}
}
let machine = engine.machine();
let schedule = machine.schedule(env_info.number);
let result = Executive::new(&mut state, &env_info, &machine, &schedule).transact_virtual(transaction, options)?;
let (encrypted_code, encrypted_storage) = match contract_address {
None => bail!(ErrorKind::ContractDoesNotExist),
Some(address) => {
let (code, storage) = state.into_account(&address)?;
trace!(target: "privatetx", "Private contract executed. code: {:?}, state: {:?}, result: {:?}", code, storage, result.output);
let enc_code = match code {
Some(c) => Some(self.encrypt(&address, &Self::iv_from_address(&address), &c)?),
None => None,
};
(enc_code, self.encrypt(&address, &Self::iv_from_transaction(transaction), &Self::snapshot_from_storage(&storage))?)
},
let (encrypted_code, encrypted_storage) = {
let (code, storage) = state.into_account(&contract_address)?;
trace!(target: "privatetx", "Private contract executed. code: {:?}, state: {:?}, result: {:?}", code, storage, result.output);
let enc_code = match code {
Some(c) => Some(self.encrypt(&contract_address, &Self::iv_from_address(&contract_address), &c)?),
None => None,
};
(enc_code, self.encrypt(&contract_address, &Self::iv_from_transaction(transaction), &Self::snapshot_from_storage(&storage))?)
};
Ok(PrivateExecutionResult {
code: encrypted_code,
state: encrypted_storage,
contract_address,
contract_address: contract_address,
result,
})
}
@@ -553,24 +605,21 @@ impl Provider where {
/// Returns the key from the key server associated with the contract
pub fn contract_key_id(&self, contract_address: &Address) -> Result<H256, Error> {
// Current solution uses contract address extended with 0 as id
let contract_address_extended: H256 = contract_address.into();
Ok(H256::from_slice(&contract_address_extended))
Ok(key_server_keys::address_to_key(contract_address))
}
/// Create encrypted public contract deployment transaction.
pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Option<Address>), Error> {
pub fn public_creation_transaction(&self, block: BlockId, source: &SignedTransaction, validators: &[Address], gas_price: U256) -> Result<(Transaction, Address), Error> {
if let Action::Call(_) = source.action {
bail!(ErrorKind::BadTransactonType);
return Err(Error::BadTransactionType);
}
let sender = source.sender();
let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?;
let state = self.client.state_at(block).ok_or(Error::StatePruned)?;
let nonce = state.nonce(&sender)?;
let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?;
let header = self.client.block_header(block)
.ok_or(ErrorKind::StatePruned)
.and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?;
.ok_or(Error::StatePruned)
.and_then(|h| h.decode().map_err(|_| Error::StateIncorrect).into())?;
let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state);
let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone());
let mut tx = Transaction {
@@ -601,7 +650,7 @@ impl Provider where {
/// Create encrypted public contract deployment transaction. Returns updated encrypted state.
pub fn execute_private_transaction(&self, block: BlockId, source: &SignedTransaction) -> Result<Bytes, Error> {
if let Action::Create = source.action {
bail!(ErrorKind::BadTransactonType);
return Err(Error::BadTransactionType);
}
let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?;
Ok(result.state)
@@ -630,7 +679,7 @@ impl Provider where {
pub fn get_validators(&self, block: BlockId, address: &Address) -> Result<Vec<Address>, Error> {
let (data, decoder) = private_contract::functions::get_validators::call();
let value = self.client.call_contract(block, *address, data)?;
decoder.decode(&value).map_err(|e| ErrorKind::Call(format!("Contract call failed {:?}", e)).into())
decoder.decode(&value).map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into())
}
fn get_contract_version(&self, block: BlockId, address: &Address) -> usize {
@@ -681,12 +730,13 @@ impl Importer for Arc<Provider> {
let transaction_bytes = self.decrypt(&contract, &encrypted_data)?;
let original_tx: UnverifiedTransaction = Rlp::new(&transaction_bytes).as_val()?;
let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE);
let local_accounts = HashSet::new();
// Add to the queue for further verification
self.transactions_for_verification.add_transaction(
original_tx,
validation_account.map(|&account| account),
private_tx,
self.pool_client(&nonce_cache),
self.pool_client(&nonce_cache, &local_accounts),
)?;
let provider = Arc::downgrade(self);
let result = self.channel.send(ClientIoMessage::execute(move |_| {
@@ -721,16 +771,6 @@ impl Importer for Arc<Provider> {
}
}
/// Try to unlock account using stored password, return found password if any
fn find_account_password(passwords: &Vec<Password>, account_provider: &AccountProvider, account: &Address) -> Option<Password> {
for password in passwords {
if let Ok(true) = account_provider.test_password(account, password) {
return Some(password.clone());
}
}
None
}
impl ChainNotify for Provider {
fn new_blocks(&self, new_blocks: NewBlocks) {
if new_blocks.imported.is_empty() || new_blocks.has_more_blocks_to_import { return }
@@ -738,5 +778,6 @@ impl ChainNotify for Provider {
if let Err(err) = self.process_verification_queue() {
warn!(target: "privatetx", "Cannot prune private transactions queue. error: {:?}", err);
}
self.keys_provider.update_acl_contract();
}
}

View File

@@ -28,7 +28,7 @@ use parking_lot::RwLock;
use types::transaction::{UnverifiedTransaction, SignedTransaction};
use txpool;
use txpool::{VerifiedTransaction, Verifier};
use error::{Error, ErrorKind};
use error::Error;
type Pool = txpool::Pool<VerifiedPrivateTransaction, pool::scoring::NonceAndGasPrice>;
@@ -154,7 +154,7 @@ impl Default for VerificationStore {
impl VerificationStore {
/// Adds private transaction for verification into the store
pub fn add_transaction<C: pool::client::Client>(
pub fn add_transaction<C: pool::client::Client + pool::client::NonceClient + Clone>(
&self,
transaction: UnverifiedTransaction,
validator_account: Option<Address>,
@@ -164,7 +164,7 @@ impl VerificationStore {
let options = self.verification_options.clone();
// Use pool's verifying pipeline for original transaction's verification
let verifier = pool::verifier::Verifier::new(client, options, Default::default(), None);
let verifier = pool::verifier::Verifier::new(client.clone(), options, Default::default(), None);
let unverified = pool::verifier::Transaction::Unverified(transaction);
let verified_tx = verifier.verify_transaction(unverified)?;
let signed_tx: SignedTransaction = verified_tx.signed().clone();
@@ -177,8 +177,9 @@ impl VerificationStore {
transaction_hash: signed_hash,
transaction_sender: signed_sender,
};
let mut pool = self.verification_pool.write();
pool.import(verified)?;
let replace = pool::replace::ReplaceByScoreAndReadiness::new(
self.verification_pool.read().scoring().clone(), client);
self.verification_pool.write().import(verified, &replace)?;
Ok(())
}
@@ -228,7 +229,7 @@ impl SigningStore {
contract_nonce: U256,
) -> Result<(), Error> {
if self.transactions.len() > MAX_QUEUE_LEN {
bail!(ErrorKind::QueueIsFull);
return Err(Error::QueueIsFull);
}
self.transactions.insert(private_hash, PrivateTransactionSigningDesc {
@@ -254,7 +255,7 @@ impl SigningStore {
/// Adds received signature for the stored private transaction
pub fn add_signature(&mut self, private_hash: &H256, signature: Signature) -> Result<(), Error> {
let desc = self.transactions.get_mut(private_hash).ok_or_else(|| ErrorKind::PrivateTransactionNotFound)?;
let desc = self.transactions.get_mut(private_hash).ok_or_else(|| Error::PrivateTransactionNotFound)?;
if !desc.received_signatures.contains(&signature) {
desc.received_signatures.push(signature);
}

View File

@@ -29,12 +29,11 @@ extern crate rustc_hex;
extern crate log;
use std::sync::Arc;
use rustc_hex::FromHex;
use rustc_hex::{FromHex, ToHex};
use types::ids::BlockId;
use types::transaction::{Transaction, Action};
use ethcore::CreateContractAddress;
use ethcore::account_provider::AccountProvider;
use ethcore::client::BlockChainClient;
use ethcore::executive::{contract_address};
use ethcore::miner::Miner;
@@ -42,7 +41,7 @@ use ethcore::test_helpers::{generate_dummy_client, push_block_with_transactions}
use ethkey::{Secret, KeyPair, Signature};
use hash::keccak;
use ethcore_private_tx::{NoopEncryptor, Provider, ProviderConfig};
use ethcore_private_tx::{NoopEncryptor, Provider, ProviderConfig, StoringKeyProvider};
#[test]
fn private_contract() {
@@ -54,26 +53,25 @@ fn private_contract() {
let _key2 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000012")).unwrap();
let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000013")).unwrap();
let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000014")).unwrap();
let ap = Arc::new(AccountProvider::transient_provider());
ap.insert_account(key1.secret().clone(), &"".into()).unwrap();
ap.insert_account(key3.secret().clone(), &"".into()).unwrap();
ap.insert_account(key4.secret().clone(), &"".into()).unwrap();
let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![key1.clone(), key3.clone(), key4.clone()]));
let config = ProviderConfig{
validator_accounts: vec![key3.address(), key4.address()],
signer_account: None,
passwords: vec!["".into()],
};
let io = ethcore_io::IoChannel::disconnected();
let miner = Arc::new(Miner::new_for_tests(&::ethcore::spec::Spec::new_test(), None));
let private_keys = Arc::new(StoringKeyProvider::default());
let pm = Arc::new(Provider::new(
client.clone(),
miner,
ap.clone(),
signer.clone(),
Box::new(NoopEncryptor::default()),
config,
io,
private_keys,
));
let (address, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &0.into(), &[]);
@@ -155,3 +153,123 @@ fn private_contract() {
let result = pm.private_call(BlockId::Latest, &query_tx).unwrap();
assert_eq!(result.output, "2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap());
}
#[test]
fn call_other_private_contract() {
// This test verifies calls private contract methods from another one
// Two contract will be deployed
// The same contract A:
// contract Test1 {
// bytes32 public x;
// function setX(bytes32 _x) {
// x = _x;
// }
// }
// And the following contract B:
// contract Deployed {
// function setX(uint) {}
// function x() returns (uint) {}
//}
// contract Existing {
// Deployed dc;
// function Existing(address t) {
// dc = Deployed(t);
// }
// function getX() returns (uint) {
// return dc.x();
// }
// }
//ethcore_logger::init_log();
// Create client and provider
let client = generate_dummy_client(0);
let chain_id = client.signing_chain_id();
let key1 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000011")).unwrap();
let _key2 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000012")).unwrap();
let key3 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000013")).unwrap();
let key4 = KeyPair::from_secret(Secret::from("0000000000000000000000000000000000000000000000000000000000000014")).unwrap();
let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![key1.clone(), key3.clone(), key4.clone()]));
let config = ProviderConfig{
validator_accounts: vec![key3.address(), key4.address()],
signer_account: None,
};
let io = ethcore_io::IoChannel::disconnected();
let miner = Arc::new(Miner::new_for_tests(&::ethcore::spec::Spec::new_test(), None));
let private_keys = Arc::new(StoringKeyProvider::default());
let pm = Arc::new(Provider::new(
client.clone(),
miner,
signer.clone(),
Box::new(NoopEncryptor::default()),
config,
io,
private_keys.clone(),
));
// Deploy contract A
let (address_a, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &0.into(), &[]);
trace!("Creating private contract A");
let private_contract_a_test = "6060604052341561000f57600080fd5b60d88061001d6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c146046578063bc64b76d14607457600080fd5b3415605057600080fd5b60566098565b60405180826000191660001916815260200191505060405180910390f35b3415607e57600080fd5b6096600480803560001916906020019091905050609e565b005b60005481565b8060008160001916905550505600a165627a7a723058206acbdf4b15ca4c2d43e1b1879b830451a34f1e9d02ff1f2f394d8d857e79d2080029".from_hex().unwrap();
let mut private_create_tx1 = Transaction::default();
private_create_tx1.action = Action::Create;
private_create_tx1.data = private_contract_a_test;
private_create_tx1.gas = 200000.into();
private_create_tx1.nonce = 0.into();
let private_create_tx_signed = private_create_tx1.sign(&key1.secret(), None);
let validators = vec![key3.address(), key4.address()];
let (public_tx1, _) = pm.public_creation_transaction(BlockId::Latest, &private_create_tx_signed, &validators, 0.into()).unwrap();
let public_tx1 = public_tx1.sign(&key1.secret(), chain_id);
trace!("Transaction created. Pushing block");
push_block_with_transactions(&client, &[public_tx1]);
// Deploy contract B
let (address_b, _) = contract_address(CreateContractAddress::FromSenderAndNonce, &key1.address(), &1.into(), &[]);
trace!("Creating private contract B");
// Build constructor data
let mut deploy_data = "6060604052341561000f57600080fd5b6040516020806101c583398101604052808051906020019091905050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061014a8061007b6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635197c7aa14610046575b600080fd5b341561005157600080fd5b61005961006f565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630c55699c6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156100fe57600080fd5b6102c65a03f1151561010f57600080fd5b505050604051805190509050905600a165627a7a723058207f8994e02725b47d76ec73e5c54a338d27b306dd1c830276bff2d75fcd1a5c920029000000000000000000000000".to_string();
deploy_data.push_str(&address_a.to_vec().to_hex());
let private_contract_b_test = deploy_data.from_hex().unwrap();
let mut private_create_tx2 = Transaction::default();
private_create_tx2.action = Action::Create;
private_create_tx2.data = private_contract_b_test;
private_create_tx2.gas = 200000.into();
private_create_tx2.nonce = 1.into();
let private_create_tx_signed = private_create_tx2.sign(&key1.secret(), None);
let (public_tx2, _) = pm.public_creation_transaction(BlockId::Latest, &private_create_tx_signed, &validators, 0.into()).unwrap();
let public_tx2 = public_tx2.sign(&key1.secret(), chain_id);
trace!("Transaction created. Pushing block");
push_block_with_transactions(&client, &[public_tx2]);
// Let provider know, that it has access to both keys for A and B
private_keys.set_available_keys(&vec![address_a, address_b]);
// Call A.setx(42)
trace!("Modifying private state");
let mut private_tx = Transaction::default();
private_tx.action = Action::Call(address_a.clone());
private_tx.data = "bc64b76d2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap(); //setX(42)
private_tx.gas = 120000.into();
private_tx.nonce = 2.into();
let private_tx = private_tx.sign(&key1.secret(), None);
let private_contract_nonce = pm.get_contract_nonce(&address_b, BlockId::Latest).unwrap();
let private_state = pm.execute_private_transaction(BlockId::Latest, &private_tx).unwrap();
let nonced_state_hash = pm.calculate_state_hash(&private_state, private_contract_nonce);
let signatures: Vec<_> = [&key3, &key4].iter().map(|k|
Signature::from(::ethkey::sign(&k.secret(), &nonced_state_hash).unwrap().into_electrum())).collect();
let public_tx = pm.public_transaction(private_state, &private_tx, &signatures, 2.into(), 0.into()).unwrap();
let public_tx = public_tx.sign(&key1.secret(), chain_id);
push_block_with_transactions(&client, &[public_tx]);
// Call B.getX()
trace!("Querying private state");
let mut query_tx = Transaction::default();
query_tx.action = Action::Call(address_b.clone());
query_tx.data = "5197c7aa".from_hex().unwrap(); // getX
query_tx.gas = 50000.into();
query_tx.nonce = 3.into();
let query_tx = query_tx.sign(&key1.secret(), chain_id);
let result = pm.private_call(BlockId::Latest, &query_tx).unwrap();
assert_eq!(&result.output[..], &("2a00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()[..]));
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,87 +0,0 @@
{
"name": "Easthub",
"dataDir": "easthub",
"engine": {
"Ethash": {
"params": {
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x2B5E3AF16B1880000",
"homesteadTransition": "0x0",
"bombDefuseTransition": "0x0",
"ecip1017EraRounds": 5000000
}
}
},
"params": {
"gasLimitBoundDivisor": "0x0400",
"registrar": "0x0000000000000000000000000000000000000000",
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID": "0x7",
"chainID": "0x7",
"eip150Transition": "0x0",
"eip160Transition": "0x0",
"eip155Transition": "0x0",
"eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x0400000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x323031382045617374636f696e2050726f6a656374",
"gasLimit": "0x1388"
},
"nodes": [
"enode://ca57e40edb95a08a81b85a91e91099a0aaab777ad329ea7f3f772bc0fd511a276a5d84944725d181ff80f8c7dc1034814bff25b9723b03363d48617fed4b15f0@13.125.109.174:30303",
"enode://57254e23a7e5fe1e081ee5d1b236e37735a120660daeb4bf1fec6943a82c915c5b6fad23eeb1a43a27c23f236e084e8051aaa28f7d4139149f844747facb62bb@18.217.39.51:30303",
"enode://ef248f327c73c0318f4d51a62270b0612f3c4a4fd04b77d04854dc355980e137708d1e48811bc91387b0d7eb85cf447d8bbc095404f39bb7064e76751bda9cd4@52.221.160.236:30303",
"enode://bf6f0e37dd733cf04f2b079c753d2dea7cc7c59d8637eff9a8e63e17d08e2bfc91229fbb2dff08fe6ee12e51c1b6f8ed969d7042b89d77029e7ea02b05e17be3@18.197.47.177:30303"
],
"accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"20c1252a8cb33a7a9a257b2a4cfeed8daf87c847": {
"balance": "100000000000000000000000000"
},
"9dcd37c8e5aea3a0d37c5d0a2db683362d81febd": {
"balance": "100000000000000000000000000"
},
"9eff080302333f44a60bfd8c33bd63015c6d921b": {
"balance": "100000000000000000000000000"
},
"c1df2e5de98d5c41fec0642dc302971f5d3500bd": {
"balance": "100000000000000000000000000"
},
"2e0fb67cd1d029cbaea4b74c361efcc06b3105fd": {
"balance": "100000000000000000000000000"
},
"2b6425cc3cd90654f077889ef7262ac2f5846460": {
"balance": "100000000000000000000000000"
},
"28562041230c6d575e233e4ed1b35c514884d964": {
"balance": "100000000000000000000000000"
},
"16eb6896a5a83d39ac762d79d21f825f5f980d12": {
"balance": "100000000000000000000000000"
},
"f09e3f1de27dd03a1ac0a021b2d9e45bde1b360c": {
"balance": "100000000000000000000000000"
},
"2d87547819c6433f208ee3096161cdb2835a2333": {
"balance": "100000000000000000000000000"
}
}
}

View File

@@ -10,7 +10,7 @@
"blockReward": {
"0x0": "0x4563918244f40000",
"0x42ae50": "0x29a2241af62c0000",
"0x6c0840": "0x1bc16d674ec80000"
"0x6f1580": "0x1bc16d674ec80000"
},
"homesteadTransition": "0x118c30",
"daoHardforkTransition": "0x1d4c00",
@@ -136,7 +136,7 @@
"eip100bTransition": "0x42ae50",
"difficultyBombDelays": {
"0x42ae50": "0x2dc6c0",
"0x6c0840": "0x1e8480"
"0x6f1580": "0x1e8480"
}
}
}
@@ -161,10 +161,9 @@
"eip211Transition": "0x42ae50",
"eip214Transition": "0x42ae50",
"eip658Transition": "0x42ae50",
"eip145Transition": "0x6c0840",
"eip1014Transition": "0x6c0840",
"eip1052Transition": "0x6c0840",
"eip1283Transition": "0x6c0840"
"eip145Transition": "0x6f1580",
"eip1014Transition": "0x6f1580",
"eip1052Transition": "0x6f1580"
},
"genesis": {
"seal": {
@@ -182,8 +181,8 @@
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
},
"hardcodedSync": {
"header": "f9020aa016c0aa39e09bf4ec53d630cdea0be984445c6c76f769b1541ce6b11c281c2fbda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a0de05c24d96b1b9012d7a875feecf86924d7a8d98b00fd0b9b7768785088edb01a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000870892f443c80323836ab801837a121d80845c2bdd638c6e616e6f706f6f6c2e6f7267a08f47201b260e0e422100cebf3d61a6acdcc49f4a24e0b1e680e26f13bea9dc4e88bef16aef8812be32",
"totalDifficulty": "8531065961847479229671",
"header": "f90212a0113ba3b1153987fc483b01ccfe9ecadbdc36a7b264be75d6486cb6b694cc38a1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a0d91db5900e312a1ba8d39505406a95dc0ea20393b723c4bf488ade4e3c4ee4c3a05e63ab076852043b1c2fe010e2f14ab13dcc8e1c546ac497a24ce88c4abf3056a0b72e4a776f895459b6bf0937040990d868b1f45889aeaa26684e07472263fc31b90100b00200000063664554889124822ce2001022840543085d5810042382888542ca3816801780384384cd6851081cdc4d4b2b205a814b049198110a6869d60f4009a79c3854c9000581044889080000611c09142200106552000044027024004038092102814ed6c48040a8715851088a20108e80165f8c0c514019037a0000121304b2343416800b029000024404248238a06818414cb8690244879491855405026bc8250220520992c2380099d10024411c6048424083d1307822442d8444700405147883c4c041300aaa2408bb61084012983825a22830040a180106b5e27182088060b111515832902903a8f1d432a48004d0250437106a503491000048a91587067a897789f4d78371d801837a309c8379ffd7845c9d879e9150505945206e616e6f706f6f6c2e6f7267a0db22736cb3f06f9c86804902731fa6841eaaa1cd6326ea2a30e9c304d48bdd04880323b06837344cb8",
"totalDifficulty": "9633968582330911261986",
"CHTs": [
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
@@ -3599,7 +3598,235 @@
"0x43b9d76f1c2bbab800dadc6ccb88b966ccda198e30068364cb9c0b9a346f5f03",
"0x1c9ae4b3977a1d4969ef3d950d2c74548c8b44bcee652a65f7df128511b84e48",
"0xa06a1a6ba91e429f805640faf789214f42be0d8d574065b7daea7daa37b05865",
"0xf53ed26aeec7ba846e10a84814e7264197a0b2bf485c74d98e8315f0ddfd4b3d"
"0xf53ed26aeec7ba846e10a84814e7264197a0b2bf485c74d98e8315f0ddfd4b3d",
"0x57fa0c3eee29055cf5232125619ff171a60d2e8f0246af1ea8120969e03dc3f7",
"0xeca0088d30058eac4ecb7ce8dfa454e46e642154b7851db0faa430a01bf33744",
"0x3f43e499ddd06a059b192a9cb9881d15078157508c1ac30d687951454a22441f",
"0xd99f60df5d3b55202089a3a69147e43a021c5760485e0899116f56060ba56a92",
"0xe662a0a21e688b7452d0d5b6372bc8aeb00c589849f63da9c3fb4c280e6236b8",
"0xcc83d5becb2f1580e7771c576b97709778a8502096948677f1274e9b0ff444de",
"0x17cfc1a415766b30cfd1ecdb2bc8bca535928e1048803b9820e81d7058aa3b68",
"0x8e1410621e8b0edbfd9c98cd1dac02e6b5dc8336da445cdb00c16c457ca27750",
"0x3d8bc5d8acf9ff44f9099594290a91d47040eba0f766609f1dc034d6bb127f4d",
"0xbc32d05ddd709d4f7ba929353a618d70b8eecbe1d3b06010cdc7dbf053569e25",
"0x818d10c0a40a9675a1d87673d9dc55895b8ee337a0cdd99dda88d6c1d506a301",
"0x633d32a1adbc08ab373324175e0205412bd17ed1be4ee5882d20944c3439f77d",
"0x8107273c0ecc4179096f1492d21de076f84d0c4529ff6d563acaf85a8f5db5c9",
"0x5d8c25ebc9468667d043926dc4a6d28caaa6be696ba3e4d248ab7150b20fd771",
"0x5a8cdc39a49bff71df23eb7fb01811ce114edf6829f946a6155113b39480d023",
"0x72f7ce230da5fe9ad521901d2e1f7c88a20c98ea82fc09c240501ba327ff3518",
"0xc9c91729c335752f0e04f091dc181ce8659dfc13a77034b319c47554a5ff0bee",
"0x3773c7671613b65b8c6fbedc97c96ba6e3b8a6cf64acf6d1947f2881dfec93b1",
"0xb378b0953123036f313210f7e020441f41c81344b0437e5c947aa3d2e76cc357",
"0xcf3b0163249f3b6d1c9b756eddcabc9fb9d11e121dd96499c750350dd56cfa3d",
"0x8baa2ead915e991532ce72a856a001f7cc493a58016d3a0255cd416108357396",
"0xf748b8ba84812b2f5ac3b91b51402194fe08c1d15382d10895fcc8d4622b58f7",
"0x7ec5d0b6b989137882c20bebe11d2facc3e68e9a93a9b2c793d804d9e973304a",
"0x4512ed8b4f3586a79c971cba695d727684c6485ccadfff6a3db45ff93fb1e1dd",
"0xe6edc389d0ade0c7e558ffd357a7557af9f2d38b0b20c84a67936914acf088de",
"0xf2947281385a9b2077e6e8657a6bdfb9c93f82311bd739d8e9b96bf97454ade3",
"0xc768e9216d0dfa3da3fd3727ac4a673897567570653a8517219c079edd191496",
"0x9bcb33bab81663ac501a5a4d2f3d739668b42a6bd2cf7645c3571d58b37c60a6",
"0x540fda7f30ecbf8a61855b9619a139e502d8b9e1a3e72179f2399efb3aafab0e",
"0xde605b760659834d38aa120d97d5b0721eddcdfeaa69a716e44b35ef721c85c7",
"0x8979afdd57a677913bfd414f3c7cf88c3c7144f5168476e7c08518396cf8134c",
"0x6826b8b3aae4d8f97707e9751a4313738ad42861bac31090afb77a34f7214b7e",
"0xade12591565e41be9e81ac8a673324a680b0a9e6d980ede210c966b1b9252938",
"0xb2f3710b4e6c805bd20ad93fa0f254bd645b5c9b5fa299f1f8f9bb57d299e21d",
"0xdb80cf61e5a9d6b6237855eb518851f474d12db1fde3c534762e1f7d9367763f",
"0xc40c3599108f6057fb67f09e7aee418490af2a887d59f428af222519a7c03a12",
"0x0916f11f929196f5834bad46ea7eaf55716ec2d269aef9f486cac38fa7734831",
"0xd5362e4d43e3da51e12debe7966c2a06ae0fdd327cff666aeb7185b5d6cc71e2",
"0xaed4937eb0e5c9a5e6803cff864691f7ac63fa9f82d3c2e1ec9a2777d4d3f263",
"0x49f63292bb091a6d6e6515e5f822903da4a9e652847a7de5b0fba5ca69336ae2",
"0x7347591d5dc652262db2e95f65a570ae894f28a631dace959f6264027ae5f3c3",
"0x300ebb8f363f2921f5baa4ad46332bd7d10eb113679afa0851ede28a33ce62b7",
"0xff1b93baa7285220352ab656d513ee19c12da79c0c87d2035c148744164cf32f",
"0xd1793b3309372878fea3c14f2e4dae39588ddaa2396fe246b3c4cdb534a167dd",
"0xe2c7d728bb7899ab8b0ae0d07d585cd380a38f63fb9079532419fb5cbeacbe01",
"0xc972d3a0a76889c41d1130c52bf175526a5560d2fab7b28bba7c914a9b9621cc",
"0xebd731a2040b488d736e846efdb41ac5a6020e7c2b287249c105c71bf59b9504",
"0x8745a726f0e971fbe22c9b28234c3d93333c0f8d5c126ff9ee5000e26da7031b",
"0x3033928e0f79cc47d31814e409312127ef73a15a6aa915786e4410677942dc6b",
"0xeb77e57fc7de01107d1adfbf479a4c3a6ab5ddd008dab67069c5fb488551634e",
"0x6eae31a9b04e7d30e7781e33323f52e9f411fc7143b8feeefeb71cf6b4e86081",
"0x39ac81712892e1ca0cec0b63cb7d526edb0a276e6ff41369288f788d4eeff7a3",
"0x9de1c4046104a2bfe58e94215f59e1ce5898e3efcaa2ac6a7916817648e3b304",
"0x3d6fa25cdb3aa2cda4bf65a85927fa5b5c79d3ca427b6b128d34dd24aa08b5aa",
"0x8f5d95fb92d3eedb02da88535e4d0c9ed713fb2a6ded42ad8d2036306abd3b31",
"0x36abaa49a58fd335ecfe8b0ec61a68da28af30833018788fb710c3847dc3e258",
"0xe0224a4df20ed2e5cd78db19cd906d29bcf3aeb6f79135aeb62be16f766572ab",
"0x7584341a036595e957e7f7c09a5932c1e75e5a5a73ccd31fc2806b134a899082",
"0x1dd6909a77af37732b2e59d4341047ad85b610f470684433f2929673399c2fb0",
"0x5d9bf04171804ff9f2927a14176988349c0d0a86654d8a5897ada06ca4a18d02",
"0xa1714a70cbbaffc82a9018ec48acd7aaa70a5b6ed00800249fdd76326c5eb32a",
"0xb8fe04ca47841ffa34b5f17ce8922c86a9b98bb6d7d13c4b0fd27df931200422",
"0x308d034f42f0beba3aedda196573bff7b9c9852888d6f9e3362b4259d2c1cbe0",
"0x05be7b2c1b9f84273af920a4af58b183619b016aa20199fd6845eeacc479c744",
"0x613880fff823c896127092c2c4e0319e6cca955b650829ffa053c4b228429d61",
"0xca039f943e38b017fafd119e870ee80bcd19e7994b15449a03b7bf35c1a69add",
"0xfe29c86d46c9db3f2332f2109a81199c5f48730826755b56715a98eae6e6bef9",
"0x6e95261130af62956647ad47ebf45dba97a9dd684940d5b241a6b0cc36fc0b45",
"0x113eff6173e9551800e70882942c37723aa83d573f2349ac614e6d245411af19",
"0x07e9fbe087e6b8f4a2cf41373b1977823875a9d3be56b937b977503a20996437",
"0xae0792daa47529f8690d30dddb9e0ccbdcd3e4a3b3f0386f098b147c4cb3dd58",
"0x6ad953988a96ea288c407afc70581289c4dd6b8ffceda65f6d4a51e8cb7228a8",
"0x949d0b15d25fb79f31900f0e48ac3fef50b3d1b69f24f505fad87ca56ad883ca",
"0xf0e01643fc4c21dc3adb6dc1a0bc9f601af1bd4b5ed50ba156a280996d521db9",
"0xcf396c2e2018e5dc71ce2e8d8d2716565fd9ef6ae097b871b4349a487e0a6727",
"0x5f22e44bdf7a346985839c4a395f66e2fbed238f0463ab2b02d7dd23c4e25748",
"0x8808ab6e652afa85738443a808d140c103757cd1a356bbe2b409e95cced6fa7c",
"0x9ab3eb50f50a357020c69c9501cb2864febf0be1c04edd20cb1fce3fc075b7db",
"0xc360f24716b701218d2c486938e17d7b56a85b818b4e808f7c12c85778914f68",
"0x0e8388813ad36963923d68e9a223087e2e29282dec830d13e04ca444a6e1ed6f",
"0xf77bc7d25e80792e69d8900f5e77a9eb276bc13d391720c8b8a1c608deaca05e",
"0x0979a99fa0f1a046c1da8204f2912b3c09c6dc7d37e0b6dba11935e5af8b1fb5",
"0xf9327d2fb74c22853685a3d41d6f63984a354115af69c7873650c9f8bc2d31ba",
"0x9fa02b5ef88c4496cd054f6dd26f292e389976b38a22760cbb505f068754a60f",
"0x1dff7dbca8c5d169d2ad52a4434a01ef647f29707e59d4543053a8bc7afc664c",
"0x051dc8f86a07ed084afe4d14f0b39268fc5858c908056401586acd0c9bd628d4",
"0xe6776e7bffe6398d66564b7e5993ef70c7347287842319e585c7f844002d9555",
"0xc5bc5e2c1e26900fe2492019e11bc4ec5595e1c8eb68bc1ddde65aed94ab83b1",
"0x6f868ac5f8f7071b3742573d8f4a3aea1bff632f6c5c15988572ea1983e9e535",
"0x086a27e853ff55ef97cf876e0d703898eaa0769ee4efadffacbb8c03de35657e",
"0x00aa9b9ffb2837aec2fd6444802437a5dcd4654ddc2df584e1ca351832a9e163",
"0xd395a77dd37f2e397456a5385e1fe4e781458db37d3a6d8da3b1d5fb7c5558fe",
"0x7567bd55454dc888c6aca9481ac1fd6641a93b3d2f5d1bc81bab97dd78f490ad",
"0xb7e980a03060221442dc0f9487a6f0614f5b83ea23350d2de3ff0ae4e93d02a6",
"0x1b43c09f68af74141ab23bcc3402932257deece48af74503e6ca452ecd59d9a3",
"0xfde1e03da25883b8eb78e3ac92914feab4e7294eb78a94e801876d59aa559f8b",
"0x807aca1ff5c2132a7c2b5d67de9c536968755dcfc32e8873fdd296f807148d56",
"0x8f3160048010ee14d59c26c0c2767b78350023327534ca27b086feea4cde5910",
"0xb26f5f50bdef8212578eb07f7afb52785944811975e1671a405013a0fcfb88cf",
"0x4e14680b46a09bdf8b9046f62ec5a28b8edd5704c3cc91fefb83646a5dd3eee9",
"0x792f84baa0644328b9cf5af899a154faae97fbbae7a1e7874e6219085b271265",
"0xc4d26ab903ed6478fd9a0fa80382f7b4eecd25125b623c6dcbc4ebaf0d8b3fc1",
"0x906b46aba1de6a6e3692bea009597d0a8dc40b76a1c5a4476a9daeeed65c2b25",
"0x167fb1cbf8026a1af6c16ff3b18285dd9d934158a9b9ae75b90ba7895ca2b7c9",
"0xaa659098a8ed4e33e511872bc82cf758eb6c2b47e318899b4e4385bd32fae051",
"0x757c86586e3307882c6d966c2a88745e4bc1a9002337a5d137d83ef3d4496768",
"0xf342de6ecb6bb5579cfca4e7dd4dedd2c1a685287dcbd891fb918226eb82cacd",
"0xb025cb5c7c1d64a8138ddd439aa95cd9a4c1162d628dae1f09bbf8a225a49f22",
"0x6ab070192b7919718111a5b1d74862c48a5705d4e9c6b47a3a81564180c3526f",
"0xf9a23794eddea371183902ae36ae4b54387b4b8b170bf848dc24a5ea39649545",
"0xfb9dfb946dd83814681f93091ceb299d417d8ec8d28e2ddb7843d913b699a6a3",
"0x44ea56c8eabaaef19c9fde38ad0f92c074039d93960b51238c1b11ed2315163a",
"0x66f8ce000b102ea085a18cfb17e99f242e0458d0b0d9d39b6a8653008fdaa98b",
"0xd573e736c4609d90ade296503843c9a12ad8f3795eefb32635dce70f2fb17381",
"0xa783abcf83917308a63bee26ef64b010e15b62014ed560881adc3ce78f80c3b3",
"0xf8406110d71475627fa02fe434b3270c353eca0ea700bd196a9c42dd2e6c472d",
"0x5e3350f159e6370a741af5879bdcc8b08c44538dabd162fef2b745e9ff2828c6",
"0x915c517a16a1dc3095bfb9550f24afc3a60f442c9205a7ebddc7eed37fb267e7",
"0x9ec7f72f0e8d5509e3ec337b0c879f730c16c55e4259526c0816d6891feb1dc6",
"0xc294284cac5de499512f9b12707b5f66dbb3b635c1cc6d4419b17f40e272e339",
"0xfbda44ddfe4b7c31b915fa94a27aa01fcfb22a9fcf0b557f9788bbf48b3f7f32",
"0x4418fe011a16af7da4645f300143a6cb005650ea96ce23c6adb4a82f60f72beb",
"0xfd3a00e52f4cc05610976b0def190199543ff3e423f09f8bbe5cef8315f36d7a",
"0x5c9fee100da6ec53ab1cf96ca9f369401853753eeaea30bef75f6989faddc504",
"0x713e2e28396b62bc63ab0a3dcfeabe977bceece4057a687d157320358f2dd08b",
"0x62ba90cbd06efea1d7bb7128e37e33d94a21b246b7eb7159d2708b5552247a75",
"0xe13d2697cfeea63e973c7493b4c54917a639fcf13eb1b327e02acee353bf84bb",
"0x8ed199e2fd654bfc9dfd5e7ea7dc82bea9f4535eb480c95984a5a6bc1533bf8e",
"0x4e5475dae57c548460d4ddd15583223bf2a4a2046c2ee56ca670892794a37d90",
"0x80409971b3e59ec71deb1a158a92ab6fe8318cb9adebcf583586e23e42d370c4",
"0xeb35d7c78965874110f67b77307deae4bb29dc98c01fbac3737409ede61df7c6",
"0xd358b672db99b007ac54ef3ea7c77c0eb0b4e9cc1437ca4eb70d71aaaf84b6f2",
"0x0ca4c79c1709b947794ae73dd3b73b357273c4e5cfc83ec85c4c2b649e10740f",
"0x704635b2335b5ad2be0e586e60770dc1e0548794ee2c1670cbfbc2ed0c1f64ae",
"0x6a6f2425c865216b49e7e73026fd2e9cc02f131c0050ce849f274c37828909f0",
"0xce31e62ac098db0fef0823941009b826d4e5b8e11f2e01208ee6abccb160c0cc",
"0x5669c0e6ccaa8abff08e944fe8bdcf0001dce9c10ef8b90d7f821819e028dcb6",
"0x37b59281d4eec501ed45d68c2bfac450d336ee5a18ecb7d2d812763d2cfd4321",
"0xfb52f084a5ffd63001f47acdb2ea62e91714af63f896c151100350d83bd2c7e4",
"0x67bfc4a94fde6e81b54ebe52914c0d73a053bbac22d6d64862e987e53c78ed61",
"0x49c141a8ac1124f40d06c569f49363a8af092d0028b02d8f4c895af2f86d0f28",
"0x5c81c85021692d5dd1bdbd3a4543ec86d49e674380a0e5f59d4400902d7e753b",
"0x9b46d19b0cee63461453a487bbf855fb4a7d70933ce2b7445d1dce8dbbc11cf9",
"0x50fe5cb0ddf34ed2ee8341848bc00df89fda05fbf0ebb1b34d12afe9e5ae4d1a",
"0xd56b4c4880798175c2db50c5c5d6845b5c1e7b6b33172ba107f5de075ed09def",
"0xe0928a4092e5ab5b9a34a8748c3ddf86a6a9ab50e85777c4e1e8088ac7b44ae7",
"0xfcde6d53ff8286afecafa27d608e94c07a4d78813edeccb73a1076772d1f7e83",
"0x1bff0dc76b0d8877a9ea133a023a5dc0f88559f16f0adffbf7b4d58b6be487a1",
"0x5252a71f6c9784b538ecd810bded0520f349f5aa748657a9b4422474eee08388",
"0xc4cccd5ae51babfe8e9f76af2c64227b0fd63bc2f4336b7820a32846516d9835",
"0xd07bc360f06a492a13047247448ba37fc9a167bd81ee63607976be269d245e14",
"0x9499022a6b509dd05eae2a7c799c332382b810843065e82ec72891b771cc3a8a",
"0x0ba258fb2666908035e53ec37a96ee13719779de43f14a57223b704961ef667a",
"0x4dec79cac5e3b414aa835c69bb2c580ccc03eaed675b61070f37b606ff4715bd",
"0xac640ffa67870bd91b1ff36450256fb1e5f59e65f4ef844875185c38f7f986b5",
"0x0af93eccdfbb75dc353ff31949329b3c96ffa93f63e9ae4a515f6e177e201d35",
"0x5a2d5ba9defce6db1bff0bbbe4eee170fe3b9c0ecb4a1ec6e16f904b55c07beb",
"0xd92f1c26de95255b1e0926341c35b5bfd106820dbdcb381400516d247062f3fd",
"0x447ec0cf1a32e8201cb92d0ad13adc6e664a07612bf38ce9c598c799cd947fb1",
"0x28460192df35aec41fe3992efc94da904d69e4b65e518fd2c530b38c1ec88819",
"0x6b0557132b0efe568a96f77fad4f1e18cf05670c007488052f347cf3461ee98c",
"0xb82f3f400a0edc100ddd6e82c2ea587eb5d56ea0f8faa379f8fa259f31ea0838",
"0x370b650e0bd14d9e5d749f628fca91ff47184473b6cba948e9ad3492a68bed5e",
"0x794e423feca451babc044923a79ceab62ff3a9a7e8947dcadd0d91f78a11cff6",
"0x7fe410432bfc7048e6685eb6bf0b4ae9808864a2e09ed1d373dc211f40c59da7",
"0x9f53d260f145de7b48c04829abd97989bc11d748af7d119ebf56948ca438913a",
"0xad5ad5cd5ff452e16c07bba12f0b34bb1c3c8c33d54db45b515cf6761d6a1cc8",
"0xcc6e322ea2c52af09d720524c85629019eac5ca01dcec5da887ad4b32157b9e4",
"0x5d3ddb9fa275898453e8430b26270e2812709717898683f0a3291291b29d688a",
"0xeff621bef47694a862a320a661b691b491e4a5c44e1d2026c9756f84903a6375",
"0x110e7059d20e4531323dcf981ad6cb9d67d56815c54394ab1b0b7af4235aa218",
"0xe44d27931b9429204cd2e9cba838f0ed707d5668ab55ecf2c906b2748fa1f16d",
"0x9d7166683764cde8445c58697df637cd48e35b3ad00f6e6d4bbf12844ba217c5",
"0xf5f6625754100a91cd7283d47e72cca73c39e5fa2e0405d427430bccd49cc2bb",
"0xd6b27ee81a557ff5d8947225c19f3ba023af18415a413acdf438548b24902427",
"0xccc665895dbabf0d8775c5fddf167b41579b0e6bff8fe99c8da00622334c8861",
"0x1986e5fd526af0a0e74ab83cb82c18dbd5a73fe72b94c8ca10318f8f6bd2d98a",
"0xd3f245d6f37b0c47506fc4a2b12d85ff87eb35c2f45f82c3e5bebdc7362d8cd6",
"0x53b97494c77ef9a843ce61b2a58231bc145b492b710fc3dcf79c297187993bbf",
"0x00d4cd1f9460a8625ed0a539257e58a9ab8051ff239172f0a9437cb9f0d1a11f",
"0x1c3d92f1e67b04c24db2eb04184ca7ccd5533540aca4dcbe084a70648c347ee5",
"0x200e39cb704bcda42f547c0cae54c0dd4c0b1aaf17469d69deaa67d3ef0d95c5",
"0x5aa208366dc50c2e9f0075b0e8aad396851f54a42c9ec1114c2994da0c2fcace",
"0xbea70811c324fb1553c4fc492521ce062756da0a469d8f98cd6c0f7a3a7b5e3a",
"0x79aa191ef9975049a5f2b8b7e2921a3f78d045b99b7a569a93680c5ee2600a18",
"0x233fd477509141aed423948a0c5c5b8f0ab8cc3c4836c0f44c8cd6c0811b419c",
"0x1737e144530678804416cd7c3c8200f54f395bf7712c9ade8340988e1e123af5",
"0xbdad2ae32cbfc13446adfe9e4101f32fb52b1e336c165a1125c917d6c1a1fceb",
"0xc20dedeedd63be4c10d92d9d0e7b47e20d503f331cb31d47ec9e99b915305ba0",
"0x262281f50e2892d8cfca3b8f8a6645b5931fb4601755f02fb863d719cd690381",
"0xb0a717f11ff1e3f1a4bd775792c7e5a75af6e56967ab1615be6b4941ca9315e3",
"0xe8f45b1aee0fb0e87148b316ee0ce662ae3bb2abd05e9666429fcf30893641b1",
"0xe7a439e2577c4f892921f798efa19353d236146b849c20253b07f03194b36286",
"0xf4eda704d4864d8fccefecc246fb683dbdeee5468a53dd11d71d71477d170422",
"0x308d977f739b7a8cb4810242fb447a8f6cad45389a127f5822ca2df48fa9df86",
"0x3115d6d0f174e00bf3e5704f57e44b62f7e279894ce62f39568ffe4367fc5a44",
"0x6b6e6354b8d1e1ab0430fe2a5068b2b2263ff453676dbfdce5da60a6d625f20f",
"0x9b8a7b122572f459d946e67a1c78973040bcf67a64327f689d4016c53afcc4cf",
"0xa367c0bc2e6029afec518db94fa79288801f5ebf2cba50980fc9754a40784d19",
"0xc1a017142eac944b5fda4cd66a9b6b6dc64551c3ce958e8811797433b96ec5d8",
"0xc9e3999a3f162d42ae52644ce4f765b5ccc7fe2a4c91cc59048eeb8c8086718e",
"0x67c135523c9703aa1f1b653d9279804af4cd81cd3de99e10a853b42d78143914",
"0x9af2390bb01b245c65f76454f1c80102871131417cc8fbff4b1ada056d04dd47",
"0xf4cec7d4f4a76c769021ab0dab848d668fd36e910259e45094d88defabd13448",
"0xe2a224fd4510ac5f8a6782d2eed14ee164e6bb92d3f0a7e5e71497046fe9f30c",
"0x9884ca2b5533c36e03fecf28470fd3c45292dc623fb220c5eb0a580781fbe724",
"0x078b1365c5dc77fdea6bb010fab6c4dede06e27386d4d5f205bf7e7857b03865",
"0x8f930fa645409fc1d7fb28637360489a5e5eaa6554857441c3fd8990243d9972",
"0x2e21ac485ed90007e8b69cf247c28b25361729bcc7501a3296f9c06dd0742888",
"0x46c3ea9e86ad55d87b6f5d50fd9c145bcb6ca90a4d570c1f86b5532b0762d8c0",
"0x87edc87f5ac353d64b0f157ce3e3180ce73fdd1f0ae9db1406e49581f1780de7",
"0xc940108991c82f871c3eea33ec93951c9bc33cd0aba1c77262cb6fc6ea16f4eb",
"0xba2f1d37cebd9bcde635bee4c0f260af8fddb43a84508f244b562dd1f7bdbe92",
"0x738e8d02870cf37ba27db2eb621d5f7b32a225010de41e3983ed389ebaa0e364",
"0x84af8e6e7ceb53e068bdf16091bfe966458bb5d3e4a925360411a213aaf46a5c",
"0x548302ac8a0af1ef5bb91d469f66f8669cdb2a07c432e7504a806e00487adb63",
"0x35bc3a284170d090e6fe053d3bd2a8fc3aa299d113b69b90340ca4c7e019016d",
"0xfe7b61c4388f2615642f9ffb44279f31a98c0f0d2f3f37b5f77ba09a67c12737",
"0x864581a4e526055847c252f6169bc54b5a1615de8e1cb7e80c649315b04a9aab",
"0xb8b4c67301cf9d3e91ae59a0394c8085737358bde297c58688b48a9d33c04205",
"0xa1ee0d1c7d50d37f96505ed06b166722f47fdd784b71bb3d47539ae40be96262",
"0x63b2658609397ec6a9e9d9d0a5b318b79b1e39348606ca53e0f84f6466d3aad4",
"0x2211abc4f8bbd6784aa191805465b10520a6c505d6257063aa9b911d5781fb89",
"0xefed35d1327328deece22922f08d3c3931c80c1ea9a8bc719b8226f38823bb6d",
"0x64b862e2d5a6c24d569f3352b8524ebfecfd5a3205a3200ec78df72d79a66838",
"0x6da8edf169a9c78307258a723c1ac1d96db20a7131018efad16f0606683c0f07",
"0xbae1427beab8c3e71cea57e5f9cdd55bc278c6d6073ae2628f0d3efbf9894a42",
"0x389bbd1b3fa390e8d3339cf5b018ec64d9cfc02bbcb801acad0857fe377ed83b"
]
},
"nodes": [

View File

@@ -7,17 +7,31 @@
"stepDuration": "0x4",
"blockReward": "0x4563918244F40000",
"validators": {
"list": [
"0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED",
"0x00427feae2419c15b89d1c21af10d1b6650a4d3d",
"0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c",
"0x0020ee4Be0e2027d76603cB751eE069519bA81A1",
"0x0010f94b296a852aaac52ea6c5ac72e03afd032d",
"0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A",
"0x00E6d2b931F55a3f1701c7389d592a7778897879",
"0x00e4a10650e5a6D6001C38ff8E64F97016a1645c",
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
]
"multi": {
"0": {
"list": [
"0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED",
"0x00427feae2419c15b89d1c21af10d1b6650a4d3d",
"0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c",
"0x0020ee4Be0e2027d76603cB751eE069519bA81A1",
"0x0010f94b296a852aaac52ea6c5ac72e03afd032d",
"0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A",
"0x00E6d2b931F55a3f1701c7389d592a7778897879",
"0x00e4a10650e5a6D6001C38ff8E64F97016a1645c",
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
]
},
"10960440": {
"list": [
"0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED",
"0x0010f94b296a852aaac52ea6c5ac72e03afd032d",
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
]
},
"10960500": {
"safeContract": "0xaE71807C1B0a093cB1547b682DC78316D945c9B8"
}
}
},
"validateScoreTransition": "0x41a3c4",
"validateStepTransition": "0x16e360",
@@ -49,6 +63,7 @@
"eip1014Transition": "0x8c6180",
"eip1052Transition": "0x8c6180",
"eip1283Transition": "0x8c6180",
"eip1283DisableTransition": "0x9c7b61",
"kip4Transition": "0x8c6180",
"kip6Transition": "0x8c6180"
},
@@ -63,8 +78,8 @@
"gasLimit": "0x5B8D80"
},
"hardcodedSync": {
"header": "f90247a0017c9292a6abf6bb9aa48c30f8854dc0e9649bceaf19079b1aac50ebea4fa316a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794007733a1fe69cf3f2cf989f81c7b4cac1693387aa06b81f6633226562f466201f0d097877c903a650f7427aefa7433fb971f601287a0098141509099d91ed2c2e503d43db5b5412d51880994e8e03a86e1d7a9ca8e8ca0495f318f8bfdd4beb517d115ad5d5330aebafe70eb2b1cfb0ab029221a0f48c1b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe83975801837a120083035108845c2c49e49fde830202058f5061726974792d457468657265756d86312e33312e30826c6984170b1279b8413ee0655a59d1f7f8db39c22055c614346450e99965fef62efa43b21b20f0966e3e41eb65fcaf6f9ce3a34359dc064827e06f3a29d2c717f287234785d369e56f00",
"totalDifficulty": "3324635628632492920129912637269655024947201711",
"header": "f90247a0d0c0f490e8e5045fa96fd77ce45ed983900feaab964b2b0ba3a2d3a6b5e0f842a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400d6cc1ba9cf89bd2e58009741f4f7325badc0eda0c91e59c81193c4fead4f64ecaa349e97056409dfbb787772ea3c1e55e7582b2ea08be1332f5e7eac286c7e5e5ccf3760e47f4a919548c15e748ad4351bb8405f9aa054e0533aa3433f4d07afa226230c867fc1e2844b5f49b25aba8df17630d9f8c8b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe83a26801837a12008306f78d845c9da0b09fde830203088f5061726974792d457468657265756d86312e33332e30827769841727682cb841d6db93a25c84287603ee26e48db0dd301753840cc7283d411d3febd0485e02b2520086bebfb3aec1ab69403f45f0d59249bf0d458f33aa268dc4badefc73c8d300",
"totalDifficulty": "3571337622391237938633151520660827524104528124",
"CHTs": [
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
@@ -4908,7 +4923,361 @@
"0xe3d68466d0747ab6245e5d8620eaae080a0f3c2aa34a56defe8adaef56d5474a",
"0x8d0f53bb5f7610133f04a763263815e092e43b0016369866e959d22eca466d85",
"0x8c8f0fff76977593112a64826f15ec0e909d9a1f1589e121a37f73d881e6b696",
"0x9ab1411e7ef5b295ab1a9dfe4ee1cd1a740af5b7e4b0a0e9c4a5f37e803c7c94"
"0x9ab1411e7ef5b295ab1a9dfe4ee1cd1a740af5b7e4b0a0e9c4a5f37e803c7c94",
"0x7a842e2c606aba52515ed7f114116bc782810bdade34b582077c57844e6af18d",
"0x40b14c755b9cecf8264622d80dcb5864241c0f41e9665908ef3683e83d33e9f1",
"0xd0faf39bcb44f583ded1cffebc93a8acb49a10b3bb2b0c9ed794b8aa4bd9e30c",
"0xe1eb93e1abdc400b49eda22b5818fcf61c56309f10d5e3cf3794bcd7760c4c0c",
"0xededdd50db9028797406a8559fd824a3e024b2362bb24f708c4f8423c657b31a",
"0x20f6ed1b586555773ded5606e711a4b9bc47b84f45bdb97653de8eb4c9aa40b7",
"0x77ade166b067475ddc450b0d6991b5a8de93c3b60d76d2b6a3f15ace449ea6d7",
"0x766c057ee18d96d84ac85caff6e0ff4954d3add40ed9488987ec5f4865f06ea3",
"0xe5dc0692cb0da1b9778ac99fb26b01ee7da45da56996dc7e5191f28e60a83bba",
"0xb86ddaab167daf9b8d4827e12f19201cb7ba2fdc7767aa7054f478650360b5a0",
"0x570f60bd9224065c7ac611e89e9737354b3186440dd328efa7ee0078850fc296",
"0x0438822dca67b58f7c5ede70758f24ad164e1c0e3f6628274535101c13121201",
"0x709382d302a6e5b21823af6ed14f22dfa79d7632b8649c67cff749fd9cad1d54",
"0xd42c07bf201d8025e9202ce752e25207cae1804877149a756536348853478dfb",
"0x82944c59acd3d43c731cc820a38f4b9ea4fafb3c5a5cc474ca0612c2e50f88a1",
"0xe9c2665ac57f450a47b8f5407dbfa7575ef4fd3bc4c90a1e64e7e0f597c6c4f2",
"0x862decca6c5c15a52cfc88a629237dc1740d533dea40a0850d8d0cff47672c43",
"0xeb453cbb85db88ed6ab19e57fc0b90c045c3c0dd6aca67f3be579c6e75e6a1ab",
"0x8f32d04dacbfaf1bdcde08205fe539f24a5e453c686257d5e39217ecf17e2a01",
"0x81f1d7ed305f8981fd6ef9adc7374a3bab51b9f5d042c35e7cb16c7eadaf37ed",
"0x8301660b9f830042d66b7197ca95eda84e9220d74f48ccef41aabcd8bec18c57",
"0x07c00b7b9e698074ac994f5a96cfbfbc6f3e8ba34bdd727deb60aa3ab9f0f1ff",
"0x44c59c12a76078144f62fc9646f8a37ac38a0db2db3cb002712834c0bf2a1bbe",
"0xb3abeacf4280e9fa9357fcdd9b4e866938c37513e0f8a31b9f8c5733c48498f5",
"0x72dd15a76cc64e9091fca937497027b77517334012d71b47502ec28f4cf31433",
"0x0f86404545ab226dda8789da56d1d67edaf201062dc4f3268e0a4c3314ca6628",
"0xf2c60e7441c1cd8b448b9d93fcc7e5f5a107d3b502454fb2f6b8607c49e12a01",
"0xc272b28ebdd6cb2cc76cc255f68602e731579bc79ee8c9f6a3471474f14febcf",
"0xed87c1f9b73e4f757d822e5161c6299aee52be1465ca389f0ce008eab6f51c17",
"0xcec988f7b79b0b5b9f4b1e43466b56dcae86823e45997fe208e7f2cbe4604947",
"0x0583ed42e92bf0cc3a54a4b80edde80606aa9a16d6254fe89b809faa0c7c5f46",
"0xc61e76957a49acc14fe008c525de69838370fdb7c3063bc04dd98b031b12eb92",
"0x5495eb0d9ac61871a364a5bd697628f4e480b8eea4c454cb583b0b11e59373ce",
"0x3ee00540b8bc71257573acbf77c97969e0af184589df1decccc5490858b1399b",
"0x6c10a21b5e7a430ed342bf38a88522919f217fb7a087576d7040f71b7d6a8e0f",
"0xc0410a1981bbae319921e5af78c1e80e4539e1ba9140adb9139ff40816255910",
"0x300f10eb6ba9d4ebd662710a91bfccde83a561b0dad7e14256a7b62e8b720662",
"0x9f5de17b88d3bbc6efbab33a7b2d8f2c120643b3844f8e37d19e10f1526195f8",
"0x2918baee5948882cfbbb57f6ba18a0434d2a0c3928eaea3d1b12de0054c00b5f",
"0xf5cb3b2a6d29bf9a0988877cbe22a01726883159a787a324bf1e685b92ab8018",
"0x08a9570f38daac2ca30d32e582f9f8f3a80e82020668b5020b29bf0456779b9a",
"0xf807d91faee554d99a4a728b219d285834f231129a6225a5a4340bd74693b133",
"0x7798ef990ab47b908f703dccfcc0d5507dcb7afaa9e5b98841825f7d2ac6b655",
"0xe5d3b714c47a7f5b8bc95dacec03facff800774c72f4379051a1c574b919bfee",
"0x5c5f6fdd4dc6d353865ee1edd5893b634f7239b327840b4973509027c8622f74",
"0xf713adae992084b0593ac33894fea127fd73a6439533cc94d07b89c50b071fc0",
"0x548d8bfbc57c4773fa2918dd13efd1f55a68d4a86b526f4560abcf48665ed637",
"0xf47bdfe91932a9b4e968e64ad23690b7c3421137b44030000ffdd78ac798b3bf",
"0x4ec25256a43c957c1cef4be253a69fc771889ad563ae677fe3e5ea6936cd760e",
"0x9b8a28041d701c32f976fada9ce9a73fcf5dad79587c9e02b5abd7a299d74292",
"0xc7c6285cea2145104924ab507bbd5aef09403f61e90ad04e0fa8a67e2abb140e",
"0x2e839dc3048ebe96490dacdf688b017f388288954704c9a99cdf25f9203fddce",
"0x37e37dbf1f4cb8b825cd5b68ea18a80a0bcbed46cbdb54c5ebb136ba4e88ff95",
"0xcdebce72ebb15b5fe081d0f3290cd8412c56e93269541af2461598fa2a05cd1e",
"0x37716cf58953f21168a83613bfb13db775fc96175384aee35f76e82095d19716",
"0x7f7ed8d8526f0586f08dcfba6a279689d0f7aebfb0b11e627c7cd0a31ea99256",
"0x1066be85b9d156b32227a7b74cd23b330f3c80e62f8b671b1dd03d2fbaf038b5",
"0x53b3ba2bf9f02a52c7caf9ef6b46df80d9fa1ab12437774b2f2d073e886dfd5b",
"0xad963410b3f77f2399b7ab925c7ef5cff512534c2e12e7e3e9573152f197f28d",
"0xa3b75316cb456a516d1e26ad8df52a0a2894f26ff3a2938f9e09cbd9354981d7",
"0x522ee88e34308bbdff564080e665cde9b3b4ae4a61afe558e5609996c1b2f855",
"0xd7d377a1ea94fdab72ce796d3e62cffa96b2b2226bbc9fcea51817414fc367a0",
"0x2ad4691181f4947c25d521a9d593e25c5e67c0b6150b3d9e27515c7808223633",
"0xf76442cc901ec7207c33840e6a029e3655d279394261b8e2fc350547f2fd4cd0",
"0x39688b8d86b6cacfea5d71e7311b01e2009a939c6531eb8af8e88b1d1b7a04a9",
"0xcc35ca75b97530d9c19199827d373210bc9624fa0ef572f7c3aaf2672918da58",
"0x85a6af5bf38ef40d2be7a529f3f370f56f380406fb8c5165f5bdff75a182b2ec",
"0x54296a0ca61a8a80d4ce9333c985983f953975f6bd7eb6beec593c149a3359cf",
"0xaa1f116c6fad9512afa8329eb499f197c5716a53ee283f06c417f45d9ce2fcf8",
"0xb9799045a8f20c5885649ec1a632eacd44a72b794dc7492469f8c1abff3edb24",
"0xd86348fcec2db2efc3deafcc18ca121de0176b1e89698a3c5244f377792784e7",
"0x7267a4a5e59e848f1c3c9e4c6f43e7aa128b73261adb296a89a7abccdfd16cd9",
"0x817a39c73cf85997721cb067b4e00812ab7fcde3e4506e37e6514c8c4e87846f",
"0xb8e7a1c1aa51637ee68590a2d5be7a8124fae067cb3b0ab3898f5c45fb275010",
"0x43f77794f4bb485488cf082b416885292a7b254057e7a75e331f4641c1ea2839",
"0x9bf3050d09ec32ddf7c40fb96ae136085587c3a4ef6cd413f73dd42615327218",
"0x069923933c215e6c60c8285f0afb83de8d4d9911a2c6417178f5f149388af874",
"0x01e1fb2dcd7bdf5e30e5569a677f39e9356d70ad5e7c30cbc8c73eec66bba5dc",
"0x39fcb505c1365111a0837993dfdf527a716a441628f248aeda785b32e04eeac4",
"0x7837393e026631af009ee2f61e1a39037f97f77f98690ce92fcdd934b80d3ddc",
"0x7695c9c3257358c759fd8c9018b2834ff56c42abecebaae806a281c03b887aa6",
"0x0446616edf3b74a68fbe0c22029b61d16b67c300022211e013572b90815b6050",
"0x274d5faf73eac9078b9d9c870bf07103aa749b0273871fa8e166932e3c0c1556",
"0x34fa06554a8bf6a2305d7ad293d1617f5295c046cd6de60689af2af9d44decc5",
"0xb641c3b6baa2370b85fb8bbb8c054fd9e7d44425a095778e859915f5b3931006",
"0xd4db8f0bebfa97e5ba93fe7aa444eb74782a98f03735720482b5080a4d3d980d",
"0x4261a0741221a7bcfa4d8bd1d6e8a62fe47ded969cc2b1446a7a76da9a23e844",
"0x6664826f16716dd01d707896f892a24b29aa9b78b2a162bfd01aade882314815",
"0xd9cacec24e60731fffc19e6fe8bf0241499ca78c51f38f841f6c1d91cb4f686d",
"0x57755fffef02b43c1be01eed12caee89bf5cb4ffa8b823aaed947083cde2d0ee",
"0x5d9bfb52ffa30989655e77512a3f40db66c790311c9cfb10d161b62b7542e334",
"0x302296acbdbd6737cdb060223f289ddd71516c8c42cc5128bdd545de6df02bb6",
"0xee1c6c48a63232e8dba59646f8d50dd6eded16ab310f39548300249efeaf7b45",
"0x60d151e272c9e6874c9c9bd90e8b241c0ec1e978b5b1db2d6632542f9b02488c",
"0x71c8d8c3da03c317eb14b12b5d403581432b3f0cea447da99dde8b60c9dc9cb7",
"0x9fd4de13da3b68bc5682debfae937d4ba4fb67f87cbc30677941ca53f5029945",
"0x2fb70f11714902235b3ca78b281c8ec80aab89f77e3fc59136bfbba44a2c46e2",
"0x30109aa2d8e89ef3669e4abb89870c77c5acf5a34bf273fd56b925d1a4fca03c",
"0x8d5c57cfcf34f5cd277a7d51c5a2fd1405b26231646db44043e735b8aae78478",
"0xaf961653148c2e6007d011e20d008c25a2c842f5dea15e2fefa76b3f324424ba",
"0xb4cc2c774796dd0c44923ecb3904e8f0c64839d32b7afd0c7f87eb0ba5e52949",
"0xf4c16b1aeaf622d35b4f897c5b9c96358af2fde5ede56d377132a6e57549565e",
"0x15c2a9f6eddc424c3ff3f91ebe6ac55d98442923267c80f59023d18b9d29cd9c",
"0x65abebec89e4a4d6e674a29f3e5ee304050da861a3a3c91ebe79a3a8aa159db5",
"0x46030219478d3c508cdbfe4cf76ce3924942cfbeb9ec6ac9e83dd5414cc8714a",
"0x4712aadd9407b29cdd5d3f0747374fea712eb3202fd2c13795268d498dd0843e",
"0xdc5ed31d4a9c4fce3f91f75102feef6da9a190638bf1f090df64175b531b1cc1",
"0x077992451f048591ea0bb7b46818c602b6fb1d535ddfab2dfbdaa6731745fb66",
"0x889307e6b877b390b86024c2f48afa3df0c9b375512e38ef778dde91dc950f55",
"0xc6127728eccce59452504b58e10c29ab854712f248d6c90b43360c2786f38647",
"0x76516eefb0f149ab9fbf2dace9fbdd4d435e583b3bb19820f45801abbb8309c8",
"0xa3771e4be252fc17bac8dd8cb9cce1168e531061b59be4fc9115838af2d3217e",
"0x1a0218061cd1c34a080b3a70cbb0c9f66420816a21a2f18f67e5fca6ce62b3f7",
"0x42751bae5dfa6d27b92cb15bf0c490d8184b97fb647563bbb4a7612f31369473",
"0x03bf5030aed483c4d07ba6a5be51ff968ce869decc37fe264b98661bccc55668",
"0xaf604a8c41a8a2fb37e317b2a565afa4e25c289a17b3e7030106849094d517ed",
"0xdbf8ed6fc0f94eddd863c883c17c974dd91f679194d4cc74316092327eb6bb42",
"0x27624ca6ec82b25f6bcaae3b0159c79803228ef5a5e4443498e39e7ca8280195",
"0x19338a8eb7d6884c8e6614b408ff2e5d44ed84e208673910f10fed7f1bf95c37",
"0xb612ba1448b74093a5be0f2ba8d330ca56647eaa2c84c3a1e3d2ef765f430126",
"0x523a7f824cb76717e0985ea2cabb23de5751c67ea03d6b569c30552d8bc9caf2",
"0xdc4f2e1b704ed39f818c36b26df95184c39927246f52a74772be1eebbddc78a7",
"0x4b5e3bc7c2e4f098b829f59ed096527216ea84bf9041d2a3c53c00cb7b5e7a56",
"0x3cec3a6e9f95bb0e2a63194ac6353ac6fe9a12fad00e8f603703454638e8d819",
"0x29b860f98a7239c9fe3994b68019ae8fd4d4009c07a088d23cd70ae6033fc727",
"0xa8d1900bc2c3156c6bc8a41378c0d2c646f0328d4f8b8963f52ac0dd506731ed",
"0xd9f8c709f2a6cbcda62ceae4c5244554af106e7f7fa0837d8887e23887d32e31",
"0xea7c17fa8dbc43b3680741957d5a020cf0df2d491aebd6955bf6027a63f75dd9",
"0xf764705990e0a12e1a97ea2cfe3d5fc0c28a601d1bb6c1bca0d24e61175d7403",
"0xbd5d6454bb6824df5a458fbd1a29476e76c645564c42064eb6cad79237e17a99",
"0x39e99ee5f716670380fcba0312b8b9d902dc3fe4e49e19bceaa4b2f3c2041366",
"0xbdb6860183ab7aa4362223c519791e7a0b63379b87ef4c30739e57515aae764e",
"0xbf6e060baab8b162bdf78e1996e30cdf4d6dd60b5daef909a5e7fada00090928",
"0x1ddc651ab0d26eda2c160911e4be92c8ef843ef510ee28f1d0b8356760c595f3",
"0xdfc38ad4e3225dcdd2dcadf32b024f754236601cb60c7aaec61a692a9f367acf",
"0x326cd0b07c68ed36049ef9ce9af1db0593a26193d9988d21d8ab05f7ffd91adf",
"0xfd76ef987cf758c89c04a221c10e50794132d3866bbf4e739e288a9b3014a9e8",
"0x590f03df3ea2123eac0957d2a84a4a0e0184be0eb75851643c0b876f364942cc",
"0x0fc92d4be9d7f7d5c49f3552d89203090fb7f4a4d34ac1a9925036c84d5d0d97",
"0xd90702e78e72b71a3f7db3510c25d0b26d098da80003cfa4abe3c525e3212d2b",
"0xec682fda87e3e66fc89855bd1ec01a80b515d6dda5f4b2d207cc5b2ac840532d",
"0xa75c0c5ae9cc31a14badd2f0cd66b9c081aa541e4f862ef0ee5aa8a692baa89c",
"0x9c237fd14d83ea449bc37922861be5fe81531264bb802d6a07c149b6883c826f",
"0xab2240195acb14c2cb5f3e6bdd352c4c36765ba6d2d3042bf15b3942b50471d7",
"0xe56052f2729f3d7d08b7958c0630b9c3ca2c6fcd9fd5655314bd1d5ca94e7852",
"0xd774822e8bd746a6b253e9c71f80fa6d6f9ad95bdffad3310eecb98785c549d6",
"0x4e478c8d5034a0e51e1e760fe258afc0c1f56cfa145f89bf34156426ea837b0e",
"0xf84cba0083c61307c45e7caa3844053ca78e2a1ce181edf17041130f314f4d00",
"0x24db4dc31929f9c0521a63d1b6ffd14939130c7d25df7a0827513a6ff0b28159",
"0x969f5efaeff2db44bcebbe23b9ff916a15087a313e814dd9f8140388fa62a48d",
"0xbdf6deadf158fbbe80670ae75744a419b999b747cc0804ec2a81b9082b5a4ccb",
"0xd25da9760de21e6483493f5f781cf526527aa0bc17ee9c9abefebda4e8bc5b71",
"0x83d5382a1a2132d7fa2bd48e06e59243f6ec71ee50626b65a84a7e5d3543f8f7",
"0xa5720e9755e2d04563583af4a2581a8a1761e82eb769dc7695b1f9654e36f753",
"0x97ceee5cb98a9e917223523650405aaa2e71cb12e568319baae1ee75df592fd8",
"0x1e1e8d3d81ae5be21cb8445833d9b8928b6c9a6b9217532b15ce0ba6cefa64e4",
"0x1c3ca12af63f1121e93b5fb602ab8c8ab1773d07bab5a60e78cb8e70e190bd4d",
"0xb343c9f8dbe3e65462838749865a748d4a5eeebe5b6622b56325e2e6680626ef",
"0x04eda02f974da35a3f4308d6b6be16b602d9317256209bf674f3282b2bda878a",
"0x0f85c864e5ac359d9a0ff54a4e0b44a31109c57d7c2171185138dee5638c627f",
"0x476f9f649f2365455d4756f541e8b8f8e34b32f8c67196a06fff2f71abddf5e5",
"0x185b523fa66564ed0e4cafadabe1c04a399b51114f5fb743136fcb2a0a53e477",
"0xc87106d70447c962f367b567b37281e4d840fc16d7b97dd349ecd073d0419cc6",
"0xc0e624f73d54230b99169c8919c965319ab2a93a31923bd22b50350bf0d25798",
"0xd78f2ea276fce38b53569cc64a6ce7ccec2fdf4f1a295106a1f2c54330a0db40",
"0x4a1c2807ccd57ecd989a2b0d4ed2d3ec609449e15c5652cff515ba5506cfb745",
"0x453e4ded943f491b41f0522188e88b28667172202b8a015f113171c29de193b2",
"0x9ea9a96b93c19a00f2238e15bb3c74409eca441e6d0ecb47b574fa8fe7390c67",
"0x9833f04cfbab3190d2d831116f1f0e1871018d862cc2389511bc266756963540",
"0x48ccbadc3d160d322bfc61d44962628b088da09d045c43d028b1b9fb979462bf",
"0x33d90a0c09d27087c15b01228250cac34fd4307d45593e7239096bb77822f6cc",
"0x545e2a8e511ef59a5fd7f183b0bed449d59788e4e377350b56bdb387e82ad4f8",
"0xe7e31fa668cee51a20ad4f2bbd459016639bcd47421836cc1bb3e0e2a4705998",
"0xaf6e1ffeaea0bcb61d5d90fb6d6146bf4f6102f49c3e5f653e1bcd6b043ab3ab",
"0x98bee111ed4d2cbd72725011d5a565b1873c86b8f3e17f16389ee009dfe3c6e3",
"0x2107b120a64b8fe21702af4bd26e8d981fec6d0051c83046bfa5dd05354ad05a",
"0xc982a8ce403f43557d0a812b8be06827d88e2410f6e7920971972fb205bc8a4c",
"0x5d58c764a39ccd3edc5e1b37f3ec73ddcfafde249e066c6185712c0d566b2e33",
"0x9afff9b16248767858ce0520877d7f414764eae8ad77d9810d615540c119e476",
"0x6154b7412dc1fabb80fd7ee43a3b91651e07b62d15afba8c004611d8ce2a88a9",
"0xfa859b6679bd6a2b283ad4ba43b8b3d96b19292d017e933cb307100e0e2a9c36",
"0xf32a85527d705fa439494f314800609a6c5f6657b205b0127b64cd595aa2c31c",
"0x02d1fe3725fad05e13189d6d9e078af8c825bccb5775dd1a6c90be3b57081d02",
"0xb003929860e22e0a4bebf5be75be8ac86a511e3f9e9b421aa9a99fe0fa4d9144",
"0x583341c3a9526d29c43bf22619df050676fc5e56974a8588a91bfef7409818f4",
"0xb94ebbab275786dbeff9189ca740bf324f916c76b800da87e6e507d546128ca9",
"0x5f26114f75c4f839fd6776b3a67b1a74fe6afe5fee1d3053fc5b09b38a2f31f5",
"0x053d6e94968bde9f906aa52065c0626810d138908f1645f2e563d3aca9660276",
"0x458fdb60ca1d0b7ffd846744ee6fc7219ce6700b4e5cd97603c4885563a0d14b",
"0xdc09316757c1ed63b9d984647db8fb69fc9e8e6153424a6e99016f868dea613c",
"0x409e2e26caddccbabf10754bf500262fca5aeaf6ebc937062e1d59b087873a70",
"0x288ee1a1e4b4437ac97c7130d4260bb0298ed2038b57c801fcf2389762a8dbe9",
"0xb82f496c7c8c8d2847ea7434e15c61883f4510e3151f56636394d88e902e19de",
"0x5fe701b2ac79e258c7201cadcf7892cd37e76bf9f7f9b9b46d39ba0fd359076c",
"0x32a841cf4e27eb60b5a6825665cc257fd1db222d501b42b5c6a814cdcddc1038",
"0x5b76c42acd108597e0f0ea8c92acb039a047dccc7f294205d1e404981bcffe0c",
"0x7084da3532f91d33a42701d9c580905f4cbc4137f33db33a579aec2ce5db1c53",
"0x11e58ad87c481e2d1b1583bed5b6e71ffbc1114bed29b7ac14a75d852a4741b2",
"0xdbbe146f3e58fa32d465a175205d757f18929cea4870bccbaa2698c58cd32f6c",
"0xf1dacbb951e0663d5db612046e090c04f18bbe31271d3d786f20deffd44b4205",
"0xa11dd2266cbe0af5b7f1f7955c28fc43a88abb8d82ac18e835723c85e8fd2d22",
"0x716ed679abca531ed520deed7b6d955e1c07c5ea483cb57a2322ed8c7a5a31e1",
"0xca4e5b466b978777d7a60a8bd841271da8643bdf0085379677131bf4b3604f33",
"0xe3ab5b13f5cb1bd8dc38c5182a7f16c02abdcae7a310d6c0233b96070d9d30f7",
"0x5f29236e49036d429f283d25a2e4cd6ee8f01b314201a34713b50871ac1ab628",
"0xf1e41d548090c62f207208b575e0bb7b4eb08c30abe40525effbcbb8b5511482",
"0x088fcad31ede2ffe1cb9e67becae368ba3be97a02d4837be59bef650f4b90e4c",
"0x4f4cadc003d445a2014dd5f819a2b67e67620a21af8302469f9ec264cee75e2a",
"0x23b331796e1c5c95a701a1f791ca392da953a7a9d5d2a834d0cc941ef6567250",
"0xb147414487aa60ae8ef7aef8577ce50b4a750b0ab77175aaa39fe78ca5d2e12c",
"0xa2250e2b126ef24cb732c79cf87afc5186b88402b70e0c9b7d3139205c7dfd09",
"0x5c40cffeb999c74452e77145e22c3c1d1080deadf4f49e40cd5184c683f628d8",
"0xe2f8ad15a61579535dc9afc59d9ad16308b80e409fed46af55b7938856485c33",
"0xec81eb466fd503be4a807bad9b2d0b6ccc24d1dce3f82f69adc99dc81d69a3b5",
"0xb87d20dbc44c1a473048e96a2957a4b9fb2ea606cf7b3de9d44937d18695f0d9",
"0xbf0dd81b0e07b07b22deb6b97d5cbd1d03a2726a1e7bf9f795c8104d1ff1c458",
"0x6aeed28f1590a1c96f1085a1867a4957673cbb8e4251e5876a43182e7b40e4ec",
"0x24df74cf385560d990f59f8c59d3545662f71b42736bbd1c1361b5a1c45d2b47",
"0x881647b453a1e3ff0b6e64a3667db62add41599f003f9032418576323a5ce1f2",
"0x9fb9c9bdcfcf35e02f0029f74b86d131be7cb49f409055cc075008e9ae33bff5",
"0x5f17c4c7b4d1b0cfd3929eadb46bf1060b8394f6bd5c0095623f73de5f8acf03",
"0x63c4b4aa80474a3cf70243f3a2d891266760f6f54693f4f189c0aa9b3d6302ec",
"0x97921aed12f6d78f6052050f7401caca6bd07cd643fd7a30f681a72a45b64a0c",
"0x82e6c73da95617192ccbc9374bbdec4c4323f8f63a27197cdb52a0d73b88e16d",
"0x3e24fcbe6a8d8ba769994150cc7a17dbb38d2248af14bc8328f729f4e01fe173",
"0x8390ef908e1dd84308347bdecd7f7e1f176551e291c6b8851c1f90d0ee4d87a3",
"0x016143668addb39c55a8c5397cf097567faeec1787643a89f8feaf817ea10d5b",
"0xde78935eace5f67e88d141d650c35b2b0c5144b12833a3c4bb64441aca1afc23",
"0x129345fd67f04b97d9e76fc9758c80b0616a68710f51decc61f85fed9250396a",
"0xcf6625191fe20056831cfa3839cd3f8fe60d17e6e4248dc46ecd35401986770a",
"0xda56c24559455221d6e465dc3385bb8fe8b547f96952e07647e46e10127873fb",
"0x85045ce82b529f7055bb8496f4084283edc86b6b79f0f1fa060ed9050419c542",
"0x4b94dbf2a96a4749a04d47fe563644b7f396f4c81753d8ec3a70e5065df0a3b9",
"0x4b025b46575b54136db392c9075b5973a421fb521ab37d8760a04f90b4f8526b",
"0xcfdf125601a1939cca129c4d38dc89a6157cf0a51400bfd8cbc1ea9a3ac5e859",
"0xbb9b417a9d9c975a1707778fa83950a2a6f6c7c20620e623e913509cc256c26c",
"0xc2dc9b5d9413508462391fbac33d1d4ac2fc4b3167d152d0888c5ef9b18a9bf8",
"0x918d35dede6db7175e5a11d9c26ed38fe8198da231d3955b1eee020ad32fa3d3",
"0x12515f32629d7e71e2f1ef0de1a08ab2ed2cf9cb2ffea11aeab06e7dab64eec8",
"0x3484f89e98c0436f603319b8c5d5e324f3e2cb6995be3334641e14a21e998b21",
"0xb045c079ca13a4a6760bae38dccad8b35503437c4643b1180f99b2bef15b9eff",
"0xf81cb06b474d642ef15ae0382f3d792071862d4a00a967ed352fcf5fc55529b0",
"0x2edc394894bdc21c9827c789cd1f1226459e5489f7a87dd941efdcee56d0be78",
"0x7a1993168a29b0869fbb337144031dd0bc47520ab9498c9065b71fc90a100294",
"0x1963f11d488f5db4ea7f6e99b0bfe5006702e911930a7a95fab8a45ea1c4c955",
"0x7e12d33b54970a2fba8539d57c02b8318fab2f22ceb8b0ef69b6cc9ccfbd0658",
"0x32655b99bb59604c91af6270b15834688de512ca3088544785c0f0304d1faa20",
"0xec8984da3bc415604c9facb5cec0238f162b3da22fc4d20bcfed387c647728fe",
"0x7ba1756f8fa6637d8cb6cc588a679f6366827bc2044865744837c63e8a5aadcc",
"0xfc1a94a88f1e52bb78a0862eea4b996444f0264a3b301c1a31e59744d0216de8",
"0x79472bc4de84a0c430f15bcf8569486cddd2de985409ceb8e48abec8aa3e3fe7",
"0x02bc578dcc715304c651a43d8dcb4a761d2073a93cca2c39da3ee513f0c6d415",
"0xcf6175cfa60c20178241c18111d64f8837ec008751c5c333bee96c616d3cb6d1",
"0xd8281202c7b6da2a2541cd7f8d4270066f6546bec601e83647896ebdf0f2eb66",
"0xc4975ca8b2b71f61d2ba2825833df91096bd733301d54a3c7b6eca016ac14153",
"0xd01d6f14e93c8ba17a602378bce1c9bdb51373675109d6233c497b6c638a03a0",
"0x805057e19b7dd857ec014b4e6333bb60f48c02d29b128fe37a69f952df8ef16b",
"0x69c55bdbaf74bfa3d53ed32b79dd35ac2c24dd723a1c0bfd70871cefa4dbb8a8",
"0x523efe8059e6e8e2abd85d77d22123f97cbbd9864b4a3ac1fe0c0e4b8a7131eb",
"0xe5a4f129016bcfbd71913d1eff01cec924f9d130b8762c921d43fe5bbbbdbbd0",
"0x07f68773d16907348ac6e7c5be293ee1163ef41b91a2a8abb17a004c4796fb42",
"0x90742f88c71f9e689b6d2ca0236c48bba0e8ddeace5fa4d53a5af082055cfd73",
"0xaf7af6e9f695c4ca9e9a3c0229d94cbf02fcafbc4ed978a6b662862182308a72",
"0x0208eac99df5025cab13d9767a2ba3e42ba1eccb72cfa01d87e834d15eea3751",
"0xee9ff9384cef76b51a9d5b8eb12fd7e00ee7f8142f81bd68393e7fcf0eaef90a",
"0x4770986e657683d901d73df444836f11f169f94ac55ec81e4e19f2212052788c",
"0x9f9c16d009da6e8ee20d9d5f3bd7f1a77b853dfd19beef68d980fca6bce2b707",
"0x468efd7c8dad29cfff0e278fd950f89e2d5a57d6824c6c1a7a7659bd7e7c0ffe",
"0xd0391bd0a2c1fb2260d89bd5e519d4ef26b4945a7ad0c1b695687fe1b24698dd",
"0xdef9ee668e09f8769b2c706a8de426e06f0bd9c264e67bf0c0bb177b851cef23",
"0x10c5b79048e611c6e65f92dd54754753e595cd8f8f0f1005d7a647fa59deeb78",
"0x4ce6d5812d2565237a9b018ed6ec386cf3e9fe1f2f429605288f2ef744c5a940",
"0xbbacf6662d816d5eb14fc1271c1a3404de94e12c175545bc8273c231c280b789",
"0xb216fd154d3726f16907ae571728d92ae2199872f180e4cd6be3b53a8dd43ae0",
"0x2b76e6685604c69f29399451c66ce053ae033ab011eb52c97c112df968e37232",
"0xf93b8076ce0dc6742196d2c9af501fad39f570cd927e8fe3b8dac4127a20a6a4",
"0x35027cc654f998af75b8379fac0a9d51703f058b518880e25e658151619f1611",
"0x3e7f59319228d40e5e07c06b696ad6478237ed0c8a71cff418ac259c6b5579e4",
"0x7295e21fccabab1545c1e64a57f0401e62689057ab4fef26f70c8d02b63867ab",
"0xb06bcf07fe1345c41ba16df213d699e2e185ef2fd3b5e19b194459d0b7baffc1",
"0x1b13d005a29e35fff33373e2d8abc81805a85e7970b48dca8fd605069c8a0d85",
"0x90a5a61ce554bb73253d7f62c78b1764f03fb0fd8f65b6aae4f9e529acb1d991",
"0x1b1eccf7565339748947358caf473ba0cea743da2ed4790763d3ac8c402f261c",
"0xef9b05ae7ce93febce342336e40922e0884891da43aac06f3e9bbfc0aec688f9",
"0x11e1075b50de92e960d0d65e9b37b3cec81095f5afc2afccc6a9a8a325264049",
"0x128e6dba4205701f673dda9e980dc0c02f3c0c8cbc570f9a240257a261f81b39",
"0x6fd9d3eaffaeebd52ce93ac8fcd0f69b146e2c0b05218850de1c9218db8ecd8f",
"0xc47e3487ad63b7db773f413cd5302818061f168409c27ff2daba4579c0a4263f",
"0x0a55695d4a132063735f7319d3a90a2e0b83fd6ec6b6f9994068f928f68afe12",
"0x39403d84aa319edbb18e0313a61ae075ba9c5dae40b9850eccbfc3e09e6b27a7",
"0x79ba98eede4cd0b7031472baacab20df85c704a26e4cfaa6e01e3d4a9d26ca39",
"0x219240759d36a317f269e4301256164cb3709628e0ba07e90a6bedd664cea059",
"0xec793562f8498937f270c6ae5490ab8f2ad21a20510699dc4d7d4d0139efeb3b",
"0x0a3e9c209903b906013c8876cb4292e6ccc8b76dbf4af2ca25d8260f9f8e7c22",
"0x0eb347bb16d897b4909dcaf31a0009e198cd197f722075c112fe29bc9f017f20",
"0xac1e6a97c51f5051dc8f3a1fa33c1071e29aff3d7040972dbb5481ba215010b3",
"0x7e1be83ac51c7e68110c6984da43885af18bc9fe988a57ada7b2379d0a122563",
"0xdb01b1cb4084a43c9a57bf8a65a58245edee5bbbdcf0573a3626e9290b4a2e6a",
"0x6c97523c89da4c9325fe17d2e879bbd6b4693f3e6d807564de83ccf801e66737",
"0x7511c0b30bd4dfa6f9a4f38793ee11e2a616de5d9d2212024c0875052ef2559e",
"0x6faa338fd78b41f2ecb623d578520b373e0c74caafce95938161dbd95edb0e24",
"0x0622bf3e00fae0e244d138f73d16035cd05aa9e0c4c16d20b36adad77951c2d4",
"0x72e1ed876e0bcdbdd200dbd55a9d7e8248a4c7ca75588681b61f6f76eb980060",
"0x981a052ee33c36c52fc33598c2563ff3698e1efd130090658cb457bb814ecff8",
"0x2b732d67211042b340c1bc49682518bb00dfcaebd0cfe861b5d38df9c127ed64",
"0xfcba6702d24950030403f872be646d058039d735cf297fcedb5daa255d47ce72",
"0xba3bdc1bd47ab43c2d39ee67a512f306e987b577166d7037705a1fda772bbeec",
"0xa39705f9efc0c0b9051742b705dab9fed7a08b3a00ff15583e15de95a9933356",
"0x551658242a3237fda7b61eae6dc40f368ffbbe3e7f292bf1b3d291d1f21a631d",
"0x631783a116fb5af727d2617276bf310e9f018e1f072d9f3d5432773ec29a193a",
"0x7d2bee7cbf5aa7a5247f047b1147f55380e035a5ff1ce958037d96a539fada37",
"0xfbe38f5210d9fc7c3474be4ff932d1ca393a565426f5d1443537e962beabbbca",
"0xfc9b71f941a0a9dafd6356c4a42c369f22144b43f32f5d50fe3d4c1cf3ee3cda",
"0xa4eb11bb0a0e210af085dc446766f4bb0d19dfec04e9d5d0d2c0ee390597906d",
"0x42e8e9e3d4d6de275146369fa7c010a10979793276a4406bbfd77a543809e762",
"0xb2fef38ac3b58b498cdad7d195bdb3604ca0cfc0ca3c7282163636d3022def43",
"0x923269e9a526ddaa446a2e7acaea5189726ff77e664c20a341f6ad2f6b810d5f",
"0x02e876ba6df7c9ddd7a9ad9bbc15f5918b096e299260fc85a8c7ebaa71d7dde5",
"0x660442f393884c6c4b879168ab3c80c57318c6c62a67ba8df3788edf9ad7303f",
"0x37f7ab248fded056ae5ecde87bf51c1f4baea786fc7c9f5b6760ad13c90659ac",
"0x36fda244e2896e45d3a8a9ed67d7c09a2974c75944a7233f571928a497b55f8c",
"0x4914478536196c3c813fe151cdf37097c6dc9e8d5c0cf9b370fe7567905fc4be",
"0xcedb88613a1d6fbc24909963911efbc5ff56ba09377350b5e824123b50d1a910",
"0x236fe31e63e426111507b2f972547255bd12c6f5df9079953a8b8346179bba57",
"0x2f08e1b0ad4024814428237b4f0e7ca5a83257d25a1cb97f42db14307113916f",
"0x41e45a3a2239551e8cb9598fb855f3d8922386c2e004426e294d111a94856b92",
"0xd5d385b54446abfa8c78950aacae52edede3a7a65d9c7515043431a4498e4f85",
"0xf2d2eb5169760d81d16067b9453979783a2feea91dfa253baa3183f2419478b0",
"0xa5aac8d064c4f4cdfdd2c7f7326c1e0260aeb44be48b391616eb01fc6d30c95e",
"0xb2a298085b0a082fc1781aad1abd263e9cc2c5eeeaa70acd88e8bdfbc0be7d15",
"0xe2d19c438ddb9b96e77a9bc70566f49021bb6444569eea3cd039ecab4d61f73a",
"0xa8549fc117d3faba2ca53efb94bbb37e9cb82bed8273e408da5ed47f5df7aab4",
"0x161c898240dd6e0a0a1f1f5948c652a796bb6586995783a35e7ed6c3c02fb82b",
"0x57214b17853934f1a548a7e9942849a04b9220f5b783a9d2be7395108bdc12e7",
"0x7902ef6c69f5d0a3de1e45d8b46aebcf35aa87cc5f4644186f1c34614a429175",
"0xc290a119f495ff04f406c28461e2de50abf92743b7fdd680048e491044fc59b7",
"0x09bf0fa4aa8b65dcc8f937e46287eb2585c85c587b425f8a0af69d02948f35d9",
"0xff20130699483dee0caacca392c2ad58738f61ea2443869616a3bf006e0cd1ad",
"0x937c629f7307f7411a4b1cc5b92f6a1f1f42f716463f15c449c681d16525996f",
"0x7cd028f48f117d8da3d537f0bb0fb0c832d3111d16fc116bd06454ddd513a095",
"0x4bf15bb783cf917375b5494e00ce003d8da01c65fcbac40d44e62a6172f2cca8",
"0xaff5ceacf024e9146631c772e4e87f223a241e789c88ae083da716c9aa47b860",
"0x68c1db9a727678d2018ec98d0bbc369faec2fb1283b479abd5d6f2b1b04036aa",
"0xe70962a032b4cb81910cea9911eef50ede2eeaa6f487f1e9f8fbf88f133249b1",
"0x1bc2bd4440a1412fbf582d167e0d08629ad2bfe0bc0dfaeb5eb7730a4baf007c",
"0x2d4cbafea30b01e466b41f6911deae979f4f5c82dcbdd76f711f7bf9300c23f4",
"0x252e39a51862ebaf28d9b38f9fb842c70b5bf0669ca008b4c83c542e5236a1af",
"0xba04c89c7ec2867d778f8632e7f51e11f06e56004520444ca922eabdab623473",
"0x74b8dc3bf589a6d9051fbed9af3021e8fb775eab0f457cfd5d38b2ec8f88a24c",
"0x8c0a98cd1665f50b702b44e10dfbfaa70f08b65ede72e39306b1d31b75c07afb",
"0xa38c3526f5f6bce7e64a195cf8659160bc7318b8862ba206535626c338485c64",
"0x4ad34e3c6be8cac9be3fba22eb7e99d951baf5827df5ef921f2b01d63862e116",
"0x596670c729beb030c8756bf2ec6c884f9b4edc433a94f5dc5d4d337dbb712d76",
"0x39611d27f11938df810165987ee7edbe87cfb7e4068216cbb45848b4029f8419"
]
},
"accounts": {
@@ -5012,10 +5381,11 @@
}
},
"nodes": [
"enode://f6e37b943bad3a78cb8589b1798d30d210ffd39cfcd2c8f2de4f098467fd49c667980100d919da7ca46cd50505d30989abda87f0b9339377de13d6592c22caf8@34.198.49.72:30303",
"enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303",
"enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303",
"enode://8fa162563a8e5a05eef3e1cd5abc5828c71344f7277bb788a395cce4a0e30baf2b34b92fe0b2dbbba2313ee40236bae2aab3c9811941b9f5a7e8e90aaa27ecba@52.165.239.18:30303",
"enode://7e2e7f00784f516939f94e22bdc6cf96153603ca2b5df1c7cc0f90a38e7a2f218ffb1c05b156835e8b49086d11fdd1b3e2965be16baa55204167aa9bf536a4d9@52.243.47.56:30303",
"enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303"
"enode://38e6e7fd416293ed120d567a2675fe078c0205ab0671abf16982ce969823bd1f3443d590c18b321dfae7dcbe1f6ba98ef8702f255c3c9822a188abb82c53adca@51.77.66.187:30303",
"enode://6f289111f7c77c68651b0f4803c3a47bcec801f9c618bb41231a1a24a6dbb9c76f2fdb63ba7a21357c41ebb7f6922c17397c1b5c8f71f7d3ef7965505d4945de@144.217.72.209:30303",
"enode://b6340eb94c3db1362ee517801389fe21cce6354275376b1006f8ce84f8a5cfa2b836268b3727be9db7cd3e581f356f39da39418c4ec1d63d959abc235d99cd86@145.239.7.213:30303"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -35,10 +35,9 @@
"eip211Transition": "0x0",
"eip214Transition": "0x0",
"eip658Transition": "0x0",
"eip145Transition": 6843780,
"eip1014Transition": 6843780,
"eip1052Transition": 6843780,
"eip1283Transition": 6843780
"eip145Transition": 8582254,
"eip1014Transition": 8582254,
"eip1052Transition": 8582254
},
"genesis": {
"seal": {

View File

@@ -41,7 +41,8 @@
"eip145Transition": 6464300,
"eip1014Transition": 6464300,
"eip1052Transition": 6464300,
"eip1283Transition": 6464300
"eip1283Transition": 6464300,
"eip1283DisableTransition": 7026400
},
"genesis": {
"seal": {

View File

@@ -44,7 +44,8 @@
"eip145Transition": "0x408b70",
"eip1014Transition": "0x408b70",
"eip1052Transition": "0x408b70",
"eip1283Transition": "0x408b70"
"eip1283Transition": "0x408b70",
"eip1283DisableTransition": "0x4b5e82"
},
"genesis": {
"seal": {
@@ -61,8 +62,8 @@
"gasLimit": "0x1000000"
},
"hardcodedSync": {
"header": "f90218a00379bed5cf7fb318965ec9b496aadc573fb78d1570ad2c43703c72e6c6ed997aa0b86c16b5c12556b0ea79b4d52ec77e3a3362ef43eeea51b594afc53c4b0ac115942450ec589db090d88e8de36c1790ca309841181da06183029c4e9e730abd17f5ea5427b626ed83796cab9bb4f28444cb7ab159f8f2a00ef00ef22f20f7d802cbede6ed8ff42d62671a7c07af9496e14710d7e63bbb9ea0a0e273f9d56a2ad827fb338fc0a109c28c0eee076d01454b76d42c99f8c54168b90100000c0002000000000000000000000400000000000000000000002000080000000008800010000000000000000000000002100000000000000000000020000000000000000000420000000008002000000000000000000000800001100000200004000000000000000000000008000000000000000000000000020010000000000000010000000010000040000000000000000020000000000000000028000018000000000000000000002000008000000800000000004000000000000000000000000002000009000000000810000000000040000000000000200100000000040000000000000000000200200000000000000000000000000000000000200000844af3d7d883486001837a120083146f76845c2c29239ad983010814846765746888676f312e31312e348664617277696ea071764589dfd7ecd322aee118da27aa747da4f5d14c1a5951f9b3a297d47a031888ba12cdb8daaeae57",
"totalDifficulty": "17277173430188370",
"header": "f9021aa0a8da98b6ef1e12b6c49e85b0e965f1ed1688f5e3605f06bb3c6ce4f857aa0bc6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794635b4764d1939dfacd3a8014726159abc277becca0d03c319fe68a91e22fb3b945a8dfc73b817976e29cf57e6c8425e6a02e9bf034a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000849fe1546f8350d001837a121d80845c9d55f29fde8302020b8f5061726974792d457468657265756d86312e33322e30826c69a04bf72e97bcf64717bfd655e2bca9ed1a5253cce5373268729161b1786ca4710488db3c50627f9321c4",
"totalDifficulty": "18787961645682286",
"CHTs": [
"0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a",
"0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc",
@@ -2379,7 +2380,277 @@
"0x12cf00d3b11cbfaf2038ca1e9de63e4dff65a3352da5824043978ba8fe7e08cf",
"0xd64011bda551b01b0b33e1065b0069fd1fe103e2e68c50fc5bdf1f99b4ab5e0f",
"0x3e3bef8f3d76d1f410327cfd8f4453e0fb9ed392da173e26ffaaed662411f7af",
"0x435816db536c536e0470a3fbfa32fcd6adab877831ffa66417e19bfaa2c9c62b"
"0x435816db536c536e0470a3fbfa32fcd6adab877831ffa66417e19bfaa2c9c62b",
"0x19d27119d0c702eb7735d70b30c26567d6ae4c5d204870a036f2273f027a80a9",
"0xd48c41e8365e9872d953b89e2b3dd0fa762b3360958ec9928124f54c79df5f19",
"0x7da805659d8b9e3f6b14aab3a5bd8d25e9d2d960076b4baf6c394a02fc763d12",
"0x5491cc6940517e3a790bf6e32437537e0241c9fcb3302a3bf94133ceb65b8862",
"0x0568a4d9b4e91fd1046fda2cb8a718ba57ba1526610013f465be7777e94356c1",
"0x0831b1ce49717503b49502ffe6b854ab2eb2c4db30f5ea5033c011f5e5e3d309",
"0xabd50d7ea56144421474763563ecdb591ec1df8645ccba4e28990d8b9b8ed16e",
"0xfe4ceb9425449bde581ef04b46c1fc7bdbd8f422c43d64b2d1bbbe3ff4dd7a26",
"0x489137c52ef8c71e620220d8e9e842c2a5befa812b70b0a709ab4603a729047d",
"0x8fa480e08230c6b9d964bca0bc5d5a246e4eac6c8d45c75a4cfac8c4601f455d",
"0xe5cde020c71c0ad3e7f9a789247e5518bc1b824b4c6297e12d09a42e265e4bef",
"0xd4c0b9e39b70ef4f229884817c317f20f53386969f8c1e2ddc69cfa57b1014f9",
"0x75b91e206eb0a2fa7752da4d6421fc294a4cd7d6d06dbdeb7b7df50e157ae99e",
"0xa650044c8fb1c0d98b1e671d576f389b0b7be37e946b7623ff6203ca72c574aa",
"0xe6dd07898de5688be966dbc612764a9956ef1105a7a02695ea269b6e40ccb077",
"0xd1c7d40ae3558d4b42cbf6bce332e718ed8f9b7026b81195beea713ea9fe81da",
"0xdfd6c816adcdd1a588db0bbb4c09050527a107bcc47d76be91c7e309a54dec92",
"0xa67e60d39fad4b6389908ced2c0b6fc4d0b1ae78379de0452963589cde410618",
"0x88a629bbfd9f5ec014580d47210562cc0ba162fc2e7f609dcc34babef9d2f89a",
"0x685dcd734516a666b7e9018a420cc1ed6f1cd13d13f54dc782d3d2529bafd375",
"0x00adf1bec319f440e54009e1ffc45d58f38a120644a111239aef09d1f91c20ed",
"0x0ec349f19c0374334a6f9463b349e97c6a6696984c7779cf29bf048a6317224e",
"0x0f190a67c3804e6aa618106b554578687d0f3983c8350709362fb7e4728adace",
"0x7af75c91424ed2a01f0b796ea4772780395cf77d4051c91552fcb962a384a04c",
"0xa43e2914fa364effea580b8d8ae6d7c5480acf7b9330b226438c12fb5e478ea2",
"0x38deda38720cb7918d43b4b7296fa0168d77ffefee1217bbe198b382fefade22",
"0x40e97169e2871117267eedd1095f76d97719f6e9dec56b3423a9258bb09815d7",
"0x3368d112a868cabf7d21ea1c5c851fe0a37551c03d72cfd6b235e3a904eb5889",
"0xaa25f4d9f97ca1cdbda79c61f1ab84883a037eed60d9ec2301cdd5c404c9805b",
"0x21132089753a085a0a982388817137c591a9a34d2cd9e6651c57c76a8b80b716",
"0xdf0c2df6ca5680424ac369b411ce78031614632c5fe44e2d8af1ddac30cd729a",
"0x4f55598eecadc5136e90d15fcb9f87e1eec65ce18121127b49cd159c69c94098",
"0x8a6b7276e3def38187b0cf9156aec251bab76637505f97583dc4d426ec86be50",
"0xe8a516509c5bcb7e81372ce88f7d51982e092ea93f895e5dc666ddaea58edd54",
"0x3edb18c971bd2f867ab6dbb3d63228aa94ed0d0eb9f603af71ebfb201095b836",
"0x0e7de89c28113289c1f84ed91c289328b9cac13495b289ce11cd1c5942be1188",
"0x2610da85e8fb400db625442fecb8cbe20435e8736fedf3bbf715501697ae6be0",
"0x5668c3a61683c91b17467e48b2f27c7e377010eaee64c69d53ecb1ab89dee1e1",
"0x58bb1cf79609e7223f1883dcc6d80538e278e514b1e11c6c2871db55dcdd9914",
"0xfd8faec518007958057845c7b9f204c8dd473db5dc19ad5f2460802b1fae2693",
"0x304b287a3513bf02a35fa61a8cb6aeb214d453d9d53213f458c207d2e15a537e",
"0x7b8f9c4775a775637d9e3274068df7c5330096a52750d604e6f3818c4a7f0b15",
"0xaac892295bff6dc1d99e51a4114857a5fffbc3c8b2b24bd057156c91a5e3bf7a",
"0x34266cdb180c5227ebae64b8ddbecec44a6144214b9412d723924a92fb4a93c4",
"0x1ed56966b89b57904056fcec5d2a23ca5a5d809a7f5c889c5123e3994d660398",
"0xb44dde8ad3b29068b5d3b3551bef7082d8f09366ac622e57f6b494bd594c7a03",
"0xabebaf98aa2e70020b83e45d5ab56164dcc58a4493264cdd6dfff3e921b395aa",
"0xdf26e98e5499f58665912d987eaebe8234eec92c9cb4e788b274b9e9cc8b527d",
"0xdb1f809c70c5633bac0f1642ad929984ff56154b16e0d81b8fa6b10706336c3e",
"0xecc6cfaadef8dab02149f15d1f39932e53b3fcf25fdb1d0379ef9b933222c018",
"0x17351e250078e53f17a144aad0933172ddc648a8f2fc530f0d4468623328b43a",
"0xb832ca94746ea0be489afd60548e74d654278b8a08bffdda83f87e58459769c8",
"0xbe1d486c25ec6042a110acb68d2fb9daeafb830f1d739506213b5a0de51887b5",
"0x560e8231a58aa914a6b82977734a8ce364d970af688f014e8957933ca3026d66",
"0x76b6b1959f5e0579fef78f6549b171028811c2fd64265bafd701e0a2de9d64b4",
"0xba8ee49b308ea0c0475cd30b90252f4909063b86119e4d1cd53dcf6b4671b0bb",
"0x168bfb6c2fd68fd7194561d6b0f6f76e733dfa092d550de243a2a7c0e6b14fa0",
"0x8d5dbd6b82c31c1237d84256a837ff86e005033d83622531bb00de243da0e5f4",
"0xd12f68a021b6f806c9d75468486f2c4fbad295ec51c0f507c445fc535a0caa81",
"0xdbe40f0f8ee88a80512e2f9162776abf02218c6dfb61a36042ba973ab55aad3a",
"0x6cf853351f1371aacafc02da272b304b246176c2867377185b349c5f5880257f",
"0x3f37a65caa18187a3552e300aab18b27d4a2b2a25c049f29e5d8d7a2c57af78f",
"0xad59d1d4be0ce243a38e94ffee6b21fe073b28b0bee9b0249f560219e9bf604d",
"0xe28ca7ade73017341acecc09a647c6c0e638f6ebdf1566b534dd27d5e9ad67ce",
"0xe3577a39c6d3670d2fcee9f36bfb4e79bcbea5695013ae037a7a7b4c5302979a",
"0x56a8566c6bb04d61331e9950a97248e152742d6f0408a77258c102efde79a0bd",
"0xf199dbb8b24df16441c45f5db31af6597172dcff5bcb84306a3f8ee9e7ebdea1",
"0x85a9e253bae3c1c5064f320911e7f964c7315602e83374f5df7ba532cd2acefc",
"0x80ce75ad1b2de3054cc12adc1774ef8e37f3123387d06daeb545953b7a2bb044",
"0xb26d9c8ece65562068826bc872a6fd93e76634b8b7b598769d3df142ed5d17d2",
"0xa43a1662961c4bd1bfa93fdf911067aca94460c733f5a9e296f9e47740b6f8a2",
"0xf84716d76638301b784430585722e4c112375a69329ac03fb8e98882fbbd2fb3",
"0xbdb1551fc7d0e24f2096586ea482b83b8603db1642ba6aa12d8369214af5e4c4",
"0x8f8f8de670e0dc95346e2b14b82bf8a63d9a2a4eca385b1fafc19964cf98f710",
"0x6d3f91249ce7f7f852a4ffab23b7e949117df088f2e2aa3db0fb386755a16c92",
"0xeb9c005485707baed2b7ab034e68597bb8be65bd6f8283b690cd338bf7d1826b",
"0xcaa884959fbea1f5110d7cc4360c24b2ede43d32f8cba522d28946ffd2d900fa",
"0xa561dbe805f8ba3cb6d3d1524c4b3bcbc95ac330e6d71d33642412f8f0a1a2a3",
"0xf158b9329dbbb90083c88982656840cb134713ba122e7e39b287bca4b0605dd4",
"0xee3ce79371c0f0a1ac399a3a722a1c7515f6b02d2e03118e3fb6d521e245ab6e",
"0x1083d6dba68c10cb19935b627e5576b5bc4e7904c8ff59657ced1c8397468017",
"0xa893338e4a49166bd36f4361799c7cccaaee211b512e0c8821136cdb823e8ac8",
"0x1327e2948ee57993f1b721e9fedc8f7d2e91f041b3e01340375bcbbdead83bfc",
"0x6bc88c663e475911e9fbdfb9a33931c34bcfff5e533e82059d33cd69ee414d94",
"0x81d95020affda45f536e01b1a4b840eb72afe2e82633d81de11acdeada45d93b",
"0x91e59cb7e3729c776c4dd441c3377659b37fd881760b9e70c73d5288e99bfa0a",
"0xbf69325ef2072cd5e3d2e93b8e6e2abbaa03434212e1ba4d36459a0f064a64ba",
"0x11f4a2d21c3145af81ba0edb80a9c27cf1e2d53b1a43a42b58b49d4340ce4fa2",
"0x8c366dac642346ca05e2fc047999f9adcab3b8166482854b06c77c2439e0655d",
"0xdcae4952619f997d791aa6a973f1c8c1d3a0c21859b0c37bec64533a6f7c0630",
"0x5300c16e42bf43e34c9e59fc5748c3e05d38437943956eb80ae91cebb4e33d87",
"0x40ec29594f14d9d9a76b13342face2565914b050cc5e5eb96299c51ec92a529d",
"0xa7da6ccf5a72ad5b8cfb6d00aed5f9f7e2bd70670c57873735ce976249fdd5d9",
"0x177a1ca473ae2fb06ed39e180567da24fd14faffa062edbdcb0cffe4520045b9",
"0xea7c63d98ea30c23e0f4df53566214eda57c96f9449aab5a02c165ddb8e61bd7",
"0x6bf4bac02febf1f9459a433d08b373143f44c0beabd3f7bce4218259e8d91311",
"0x6883559d2ed97c78d0aea12c0d14f0dbc911db36a3bd9e3f8a7142e1083e118f",
"0x999416083ffc7371c9b95b6d1bea32da9c2b00827e1f0e1f615354dfe76dd5aa",
"0x82873c88efa3041aae1d36c2a787e592a7af56c3d86f321b1dc619b974c88ff6",
"0x6bfb4371b0a7b9eb9e3fb1f6987854d6e4210286b98bf8dfe6f71f12014ffe59",
"0x5502ec7d23c5559afca6ac2d6178c1f2c778e4dca22a6bc8b16619082cafdc00",
"0x97307b650b949382bc80b6ea446b629c0fbd37bb65a36ac1b33b1e4ac310c056",
"0xe33b1569d06b2b5d05065c11a0dc4f22d214a7a4e4003c1888f7469094330a8d",
"0x691870ffdeabba194cbc10492332d51702d75c40681662fcbd5489753bd5fcaf",
"0xd9676a94b8e3eeac02389ca8c0a6d730e2718c0cfc3a5bab3110aa170d64bbf5",
"0xf558d9d27beca0657bd8ca7e82d1788b1777dbe06b474b7598acdfd46e8030cf",
"0x381d766d66669a50d13a141535c441887cad897984d7b2bd52e9bf33c385669c",
"0xacbc99a6cf54ca6fcc9ad8f844f8bbd7639791b663956cda2ac59fed34027024",
"0x04e5b5dfedaa9369bed72fe0ce827e3c16e7a07a274661d76ec92347baa8deda",
"0x2a905b1aa12a30fb04f56b2d9a26a38ce10cc2e9dc910f213ec3c6b368b15bf0",
"0x0f40416a8bc6d699c404972d27c9b69093b387a78f22295cb0a6001cd437a4fa",
"0x05a52a1501ff0d2c044f0c1932e5eb217aa734cabd527d865796fdd120fd8856",
"0x36c70cc55f4b571882ecab711522e4bffd3ae8f6873d940a0e4626ade7797612",
"0x4a7af1b12b32d3bb38ec4aa0cda6535cd96043466a56f0641253c7b21abe9205",
"0xf637f992df45cd4b58d2db4d5c8360a65cf05a11f14dba70638e50b5bf70bff4",
"0x5b271fd0d5a0adaa16218fab9f75e0599d85c093233761a76c03ba060d5b7948",
"0x8e3554617c506afbd2eed41a4c8e2ecc1bf619b163843a983411c884e5b07320",
"0x96c35e763be9f9a95f76c81fbe1659d22715f5cdc0cb36c168c67a1062818914",
"0x1d1235e2789d0d283a3d4c06e391a1e38869c788255facbaca7e23c4e76e5ba4",
"0x25246df476679b7364020ebe600ff596b6eb17b23c68ab05885a02616bd2e5f5",
"0x0a516b13c9e864bcaabf531c43ed3ca725d4521c9d34ee08280fd13500cdcfb5",
"0x15b0defb12ba7d05f4c5b387efbcf5eb41e325ece9a0b83619a5b7e19283b677",
"0x5000d5c4cad2ef87de73eb2f10d6733a840d069200cb30d4221031381e8c8f36",
"0x15e98f25d14ef227fbca0b760e2d436e291d3668498f486611a6a3118f5a8556",
"0xdc0d786b90d673f30f84706d29643bf0c392464f30ea66052b153ec28ee4b7cb",
"0xe4da2a6b7a254b85df06dbe8f2bf24b4ca3ef6d5c3b0fc8c17e0ebd32d5d69ac",
"0xe2e6fe80f327eded1c263684cbc525e27839bc816b237588b902c66623c38eb7",
"0x1b8c963829103769fab68bdf45dfe4d6130abc9560590871665f23b190e959e6",
"0x5d2e7cb7a42acaadbc832fb8974756f9473b18263ea50aa281fbcfe217a15762",
"0xcf46e1381d84a33aa488d4674b3ac43a1b6afb102c7a425fcc1447769ef5e6f9",
"0x00532839fe3e0691e406d230c8d384b6bc562923048ea0d89f1be054252eee58",
"0xa68d5545328145a3dabe1b143a57a13057d14866c6b9c9da8b4781f4efed4945",
"0x5223699aa191c964875eb16507aacefde636e88c0f0093d92bc38be221fb3792",
"0xa9b807ba38a8434b3befcc91f6b93427dc81f365354f62d5ee69730e319ce5d9",
"0xfd0dd9977372d780c38981010a339dd6552e8f81fc7654362590e7c6b9fd1f6f",
"0xca3900d2a87a6e0b04d679bb87dc81bd1ac11e79e4f0355e314c7e41d76de4e3",
"0x78ee224a33ce3b2629f7640392846f17c228288b89d6c2d9db42726cf64225cb",
"0x48a4acdd0758838c9ce2b322bc77459c1cc0fdca3d588d60697c8a5aa3035273",
"0x6eb8aeeda5a4b26e73ac2bd7f838c974b5bc45de138d14ba58b51bfb6d51cf93",
"0xd6895877c885791db924b0ab1a1d666c06a10e6d210e02cf9c2f29726d3c565b",
"0xcffa80c70e6246e7b17173c071384a7b46dfdd5ab4b4b524c88871ca02c7e658",
"0xbf64411370653f8e08373438b03ccff7fc6ae1d70385cd26a7e73b57da07dd75",
"0xd9a39f3b774d208608c7d1d9d1fcdacf0c0ff6e8cb7915bca57e8056a8b914c9",
"0xd6a1f8fae6440d4ba8b2e392dbd07f6dd6290651a221b3749cd2dd6b0f39ba0c",
"0xa1ad925960651423f598ab111a0f2bcc5d3fc7f62fc72eb2753815277183a4ac",
"0xf3f6feaa55dcb3eb9c572404a0da1cf7dbb53983a98873b3f0398aad91773b69",
"0xdb902ac0d33bba7b0bcfbbe3b5533b970d07381fb00a973b4dd92c8f7af7bcb8",
"0x5f97ac6dd3f55bbf179eafc50c64042f2daccfcb3bae9c4305045b709cf19ae2",
"0x7061adfb4514170759ff4ddf3922b10f2c85c1a65c361936e504ec77df84b703",
"0x07ae6b39e66142978d35c4c2a517c55c23ec47ae341557e8cbe8a0d001df0f6f",
"0x0e6b9fc3fec4e75d812128fbbae0946dc48b511b198a5301833992e763423da3",
"0x7e1da14382f9908299fe46dedaf1878a6d01e9070554f1436514d320e0a4ebc8",
"0xdb6cdc7239c51386bb9eb371765cccb84e4e4de38acc5ad7e5503bd0f60a31a4",
"0xcd0069c9fb9ba8d136a2020580827799eac95f613f7b75bce8322fe67ecdc2e0",
"0x06932b0dc851ffb7ce68ed9083cecb5ba074716f188c5bb4df94de8e7e057046",
"0x3a2e83e02240263c4e416898f9d54bd0b579ddb0076537b58c47c3a17df15208",
"0x61b166d6dee81bdf6d101f23bf8ca40b74c2eb3f47561b4ef024d30f410f88a7",
"0x7a9e85a9000cb7308a5c57c7b1421b22f63e64f48630a79e449e7a207cf586a1",
"0xd573fcbaafb3882fdb1985c1b939961d35dd7bcbd5865be82276d0cea1afc7a8",
"0x697152abd7502169e0d801346a41c815d8bd8e75e55845d4a4b251def64a9583",
"0x77e5cfae8dc5913c4bbd4f4d84a797bf8919a0c21a4eab4f5dfb42fe8c5019d3",
"0x6e7af8bd163f679b81489d3ec3cc4948cc57ccb3e0c8cbc80e387783bb87641d",
"0x4bd5ece25cfda291179b8977a84369ab1590c9d4d5b45a24865ca010e5ffa676",
"0x6331f61c715be1fe8e0c90740cb89c0a7cee24524be2258ad49542959f845477",
"0x0af729bb18715399a1b07ffe2e0d562f71c27ee2bc01921c25327d421165bef7",
"0x98ee97e5bbeaa0715143a39f38ac56736f54fe5b971584b4061c58721c051a3f",
"0xd06e19176339b1fb5cf469b1f0ee4350a416d20aaa9c1be50bdd26687b2424bc",
"0x2385cde28be71e40f64ba5db5bd1a8e5f4b767a9a17c21a96fd2642ead428394",
"0x3d2ef2f0e4bae5c2ca6fb9fcfa1a9ffc435471a7a533b3b7df2b28402d335f58",
"0x2ecc6ed70661e692248c80735650c253dfe6b3c2213bfc259ebc70c898ee8e6e",
"0x8a68b3eb663796ca2189e49b9fe5902e36615d03d28ac34c01f63a135b930f0b",
"0x563d7efb4175fc12dab431175b5097186c2379a5aca1901e39d641d02865d426",
"0x1a55cf9842f9008e0730ae9fc6af9f288edba323803d0ae787fc0fdda99be8c9",
"0xccdf47cee7142cad27bbf224f0afd1a6e5178345cab510f2f8ee27115ab27ff7",
"0xc5b3582937ad993c5c234d059e6cd3b98f2fa4e3fe4ad591ecb6ae710b51fee9",
"0xd651ab199355d61c49e63259e6a20d17bf72b27891271e5175a24c23fb2dc29c",
"0x800e1e33b0cd48afc6f8f7c69b85902ad93e94bb290b35a862cbad67706a2f3d",
"0x57c7349a6b630cb52c3c1205165df428ed51e25cc167c08739f86bfa46c69e48",
"0xb393d362daff182dafcce65eda9038fc0c8908b3cb1ec1a1218570211c34e142",
"0xb2f49f7a836cd0db9e4743158ff80dd97d23de7a39a0438d19c79c355339c43c",
"0x3f46776ec25b5c67468c32c1b2ca02910a7f46b4b62b5dc5d0cc6b9d3381b958",
"0x754c4ea722e501668aa48d6151ff423263b8a4e2f33b9e44e189ee4e78462741",
"0x12e79ee2724763a8a7f9196bf4d0e855e0ae3f75f5a697d90a263bf562acc5a3",
"0x407b168fea70128a8090ca86274b0b8e7965f16d54ea2b3bbabb378485b22a02",
"0x0d1557ad0cb1466965e6ee86c5ce887eedf462dbec2e719c5f396f8ed95edf08",
"0x29c3a0db9f83698e6ae703174dbeec06f3d2055eb933799e4ae3bf73f4570dde",
"0x8ade20e56fcacb40f54259696bea1aa04d839b88c503d6775d7b4491e0f9e7fa",
"0x327ef0f173632c5049988b312b1f49e9948b02125f70e117ea127088191c32d5",
"0x2989c11c234b7fc5901e168d7adfa655ff6165098eb94d244b623ba43c6abbd6",
"0x10b56dc8f023de6a8f97696dfe2993b56156a9b35f671438fee5830f52b633b5",
"0x46cd37fffe94a01297f2dcef322ae72f58bbf9f58bc9f930cbf56e73f8d5ce13",
"0x2240214683eafc37396f3078446b43ae96bc576e45db650b953ff87a895ee7d7",
"0x0db4d500e5755cba5b962f6b83942e72fd1504cf52531916084852179669a08d",
"0xafc686a8325a30966db0f54b64a4e7235ea54e300d280a4d2a502651a53424b5",
"0x59d46f6fb8eadcf18e31c9fd0da6844d63a2dc19eeeaf9ad5b80113aca5bc42a",
"0x153ae496364bf7c34c8c967e044cef69e401f0e4aff27b04808e2c299dcf15a8",
"0xc85b8d3156729c7f8ff1989f320464144f4918140d608cf03e7dfd5b51ec2acf",
"0x78fd0613f6f5291d4131152225fbded5464841a119d854a7550a1f178a8cdfc7",
"0x763dc1a000b949a45f792515fed6af70047641fa3d7beeb50b141c27b4f8cd33",
"0x42567a1e6caadaa10a13feff343ae1e2a903564affacc48aebc14f257db58ee1",
"0x62c208337234d101cc95cb6be54c17631e26c956758493f5bb7978faf0ace984",
"0x7977aec997a3029025ef789d3492755c80c2d028046aae8c4b926f247e1981d9",
"0xf927505a0c29231ed187a884af15a82dbc48a1cb002f6d91496f6569c673682d",
"0xefd2c54f6d2483a3dd7b994d8afa5441cfffa956d7da6e81bbd1691e07ac7519",
"0x7bcf94d8927a39dd00558763cdd2edaf40d55728d720dccfa0f5e1e827079cc0",
"0x19c7e5115ec25b14bd85e3d368e15d2bbe60451ed9a02f03770a3e845521b77c",
"0x60e32d48de6979c70dcb3e3f068fc3632aba5844703d50851a34975338b3a837",
"0x6722f01dc1d6dd1f0678e5b527155beb0616e33887697a56ef4cc1bac642f394",
"0x59bf17368d69e0379f0f20ec1b1b856298b8d6b4c36354ee765c8a894e58ab9b",
"0xe2559e7b67a15a3ddfbf1ddc597a1309d1fd780fe26da28aace16ad31754883c",
"0xbf687ac704bf02a3877e72f738691bf5027c21f64c68a50235876a8d015ae682",
"0xde01838df621b7368adf4fda268c827dfaa6753a39d51956c0445a2244585ec1",
"0x4ba14d3860d1dee44904719e45a5bfe54dd1e4c9bdafd0a41279e432a021f2e6",
"0xa2380cb32538cc80e07fda5575ecd7b35e0c12932687bd8002da652ad8c16dc2",
"0x82d0f5c8421d6803e52e3d6a37eea0cd978686792a2f6d175d77e9c75fb4ad86",
"0x23701b29d07c64c998ee4bf8199d5ac0f3d9724af2544cc29665a1d92a6dadce",
"0x8bbd490220c823506e111c668f923d18addf5a23d9b5244103cc135c4335f23d",
"0x190506f2d9decb8f9423662f406e61c99606abdcb369e25a1a89c2bdc44c6158",
"0xb9504b090b276cbbf86349bc4dbb66b46a42ce6ae8d44d5cd7f39773fdf6112a",
"0x38fc273344dc7230790963dfb3dedfabe142c18886d6542d77ace8ed6d117c4f",
"0xc76929e9a3a984f6ab6395c4811f007eb6d73a86fe62f8a1c02e860769f2bcde",
"0xc4fc2465f71d06102d232858cfd9737e6e82311a45b1cb2ac203de80c881a2f4",
"0x34427ee5534de01e7f0510b87e6f45aac6210897472978aee3c051c39776c561",
"0xec4f3c6349dac1e7e43b0541b1132b3d0cc8bd422436f31832184d1aa6f9c822",
"0x024a848067a1156852c78495581392774b00f22e32021ca531afeab1aafb683e",
"0x9bdf793e30326a181d3d8fb3f27818475b755e3d1fea200d8c514cf17024979a",
"0x55a1d92354a31354b4b1d9366e98b27c0467b01a108d67dab7feeeda23f981d9",
"0x74614ac3de92173d07434dd80d83aad5c1d551127896298808ad7fba96051e06",
"0x7bdb77183ca1e7f50d292e50ef701ad3bfff3e6e28d36629c5325da03cb8d013",
"0x3a35dc3d12de1053d204410a577b9e5c36d32fbda761f797aee248c27f7dbb02",
"0x430aaeb1dc02bb792375d1702999cda7c384dde1c6f46ef26f1e26e5a55dfd87",
"0xe12805d1713ba730fec6aae824bdcd0a896c6d5e12b9bfa5b6e0a2c2be251c17",
"0x5a297bd3be2352e56136db83a76c7041ef825128152366b2d8f032abb1d6656f",
"0x111782d82f50ea25d684af38689cea53319f1a88557d82c57e46ee5e75f99c05",
"0xe12520cda10064d74fdefba22b5ff4c5eb95508f77fd7c8c3fe82fb89e165bf6",
"0x6af12e8f4db19aee3865c3d681073e7433d902832bc651b8fc3f5fd038c8bca6",
"0x82a4a2ce19ca3fd99007279d62dadba547b6818607800e963b3bc53c5541298a",
"0xbf3a444d1b15d01a29ea22d05e71021ee3581338ecc9e770ee23ab6549a19d55",
"0x745ff92172b5c83cdd69265b919028b350ef95a01c84810366d630162fd9b07f",
"0x6128cd2ff1be9e56396a676362a2049f3e670c70ad2a77be724c090fd4085f0b",
"0x8ffc6bf8165e52ecf30ec955d4be1bb093e6074c92a527382a8892ffa3d3e7f7",
"0xd65bc11ef24c0fa476640d9effdc57030a86f547b7aa79b209954a6abf4072c4",
"0xcd5b5e184a5c0d1c5bdd12f80736ed1a4530210b4ef5f35dacd3feba722a334a",
"0xa80657ecf79ef03fb919bf312e02d94ab528c1b5c3858332d9bf82f807b1c232",
"0xc67dfe4aca5001e97ba6f401f15b72be85ae45972ba98b965a6dd4954d5c2386",
"0x59201e892aeab9e40aef69945585b81b47a7444ed61ba6c6e23e006103ed7edd",
"0xf535c920c5316f12f0bfedc298fbad028dd84161927414b14243c4c5ddd4f4f1",
"0x66c6e42c8137c043eb49528c718b10e5dbad9164bd3ffcc6b55b4b0501dc507b",
"0xa60b9485cb54818e0b0bfe4faeca923915f85bbac0525d09d96f375d0b2b9f81",
"0x8f9377dddacb6ed605c8ed8ed2bc6e2323a4e5d0c9b29bccdfbd27f57a9ec315",
"0xc48a1940c424c2df4803ba8d5573066ce4bbf0e0fbdaa87abcb2d2f51b0a4602",
"0xc7bce918e9f897aeb1351d2c9cbc2fbc8fd674017cb25c49846b05d609f00ed9",
"0xcdaa86e0c026c91954c6305cb7ce6010560f691a2667baf0e95bc18cd3e067df",
"0xf131e0910a8088fc5b0b1d2e93e31632eec67fa88f75bc4f9c3c1b0a317e1d54",
"0xb4f8d72a85c4c2261c7b00f43b96d7d749d0e53359993f52517da36de4c9559b",
"0x73f84bb4774a81b39b3a10d18c7a2404d21f3efd26301dbb7c8136e96304281e",
"0x5559435a987f1444e4ec78b8530009e49c52431b37c7e9f80ce2e056d44e876a",
"0x070664d11ee10c4e0475a7ece219eb0e606e055ee0fa1266b669e593b5ba1d87",
"0xfdfafeba7b5551d1e2d6f179be5ddfdbd0350bd2e9dfea40e272fb608549e8c2",
"0x50a1356bab9b56d8ed46a3e8f55b8a16af42df6b15fcc68aa548216de484c7eb",
"0x681161a307552ff12175074601005bae0c6f7b38cfa6dcb87975a1df205e28d5",
"0x2b39456efc2e8863197c95a4d6eef5069612cc2aa6414f0991393ffa672a1a15",
"0x571b916a82371fafcb456524655758bd42b4f7b768e13807a1a995e642ec205c",
"0xb2821504201eea0e6040a131a709547fc9afb44ba7bfa6a188201735753ba3b7",
"0xb16a8af1bfdde1fae0e28f29c6db0b361840df4b55e73bddffbc1cc11bcc5584",
"0x1df38b594f536cee38acad293a818bf83fc67830fc71bc19790d7733a2caab60",
"0xebb3e8f76f3b6a95285154dc11d4bd94ac4c3a150383ed69f5373499b1983dc3",
"0xb0919ed300acac5f912f01611a428861db27ffb8129a80495f735f0ac608ab35",
"0x2ee321d9d805b78a97210df2977ab62b352705e308773b90e0f4e923adec377c",
"0xee00cb02e9b86978ae10b119924bbe6c38f730c1d1b621d32c9d697e11105871"
]
},
"nodes": [

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
{
"name": "St. Peter's (test)",
"engine": {
"Ethash": {
"params": {
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x1BC16D674EC80000",
"homesteadTransition": "0x0",
"eip100bTransition": "0x0",
"difficultyBombDelays": {
"0": 5000000
}
}
}
},
"params": {
"gasLimitBoundDivisor": "0x0400",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x1",
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0",
"eip150Transition": "0x0",
"eip160Transition": "0x0",
"eip161abcTransition": "0x0",
"eip161dTransition": "0x0",
"eip140Transition": "0x0",
"eip211Transition": "0x0",
"eip214Transition": "0x0",
"eip155Transition": "0x0",
"eip658Transition": "0x0",
"eip145Transition": "0x0",
"eip1014Transition": "0x0",
"eip1052Transition": "0x0",
"eip1283DisableTransition": "0x0"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x400000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
}
}

View File

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

View File

@@ -19,12 +19,9 @@ use io;
use ethcore_private_tx;
error_chain! {
links {
PrivateTransactions(ethcore_private_tx::Error, ethcore_private_tx::ErrorKind);
}
foreign_links {
Ethcore(ethcore::error::Error);
IoError(io::IoError);
PrivateTransactions(ethcore_private_tx::Error);
}
}

View File

@@ -32,9 +32,8 @@ use ethcore::miner::Miner;
use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams};
use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus};
use ethcore::spec::Spec;
use ethcore::account_provider::AccountProvider;
use ethcore_private_tx::{self, Importer};
use ethcore_private_tx::{self, Importer, Signer};
use Error;
pub struct PrivateTxService {
@@ -96,9 +95,10 @@ impl ClientService {
restoration_db_handler: Box<BlockChainDBHandler>,
_ipc_path: &Path,
miner: Arc<Miner>,
account_provider: Arc<AccountProvider>,
signer: Arc<Signer>,
encryptor: Box<ethcore_private_tx::Encryptor>,
private_tx_conf: ethcore_private_tx::ProviderConfig,
private_encryptor_conf: ethcore_private_tx::EncryptorConfig,
) -> Result<ClientService, Error>
{
let io_service = IoService::<ClientIoMessage>::start()?;
@@ -127,13 +127,18 @@ impl ClientService {
};
let snapshot = Arc::new(SnapshotService::new(snapshot_params)?);
let private_keys = Arc::new(ethcore_private_tx::SecretStoreKeys::new(
client.clone(),
private_encryptor_conf.key_server_account,
));
let provider = Arc::new(ethcore_private_tx::Provider::new(
client.clone(),
miner,
account_provider,
encryptor,
private_tx_conf,
io_service.channel(),
client.clone(),
miner,
signer,
encryptor,
private_tx_conf,
io_service.channel(),
private_keys,
));
let private_tx = Arc::new(PrivateTxService::new(provider));
@@ -276,7 +281,6 @@ mod tests {
use tempdir::TempDir;
use ethcore_db::NUM_COLUMNS;
use ethcore::account_provider::AccountProvider;
use ethcore::client::ClientConfig;
use ethcore::miner::Miner;
use ethcore::spec::Spec;
@@ -311,9 +315,10 @@ mod tests {
restoration_db_handler,
tempdir.path(),
Arc::new(Miner::new_for_tests(&spec, None)),
Arc::new(AccountProvider::transient_provider()),
Arc::new(ethcore_private_tx::DummySigner),
Box::new(ethcore_private_tx::NoopEncryptor),
Default::default(),
Default::default(),
);
assert!(service.is_ok());
drop(service.unwrap());

View File

@@ -17,11 +17,10 @@
//! DB backend wrapper for Account trie
use ethereum_types::H256;
use hash::{KECCAK_NULL_RLP, keccak};
use hashdb::{HashDB, AsHashDB};
use hash_db::{HashDB, AsHashDB};
use keccak_hasher::KeccakHasher;
use kvdb::DBValue;
use rlp::NULL_RLP;
use std::collections::HashMap;
#[cfg(test)]
use ethereum_types::Address;
@@ -99,15 +98,11 @@ impl<'db> AccountDB<'db> {
}
impl<'db> AsHashDB<KeccakHasher, DBValue> for AccountDB<'db> {
fn as_hashdb(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hashdb_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
}
impl<'db> HashDB<KeccakHasher, DBValue> for AccountDB<'db> {
fn keys(&self) -> HashMap<H256, i32> {
unimplemented!()
}
fn get(&self, key: &H256) -> Option<DBValue> {
if key == &KECCAK_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));
@@ -163,10 +158,6 @@ impl<'db> AccountDBMut<'db> {
}
impl<'db> HashDB<KeccakHasher, DBValue> for AccountDBMut<'db>{
fn keys(&self) -> HashMap<H256, i32> {
unimplemented!()
}
fn get(&self, key: &H256) -> Option<DBValue> {
if key == &KECCAK_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));
@@ -209,22 +200,18 @@ impl<'db> HashDB<KeccakHasher, DBValue> for AccountDBMut<'db>{
}
impl<'db> AsHashDB<KeccakHasher, DBValue> for AccountDBMut<'db> {
fn as_hashdb(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hashdb_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
}
struct Wrapping<'db>(&'db HashDB<KeccakHasher, DBValue>);
impl<'db> AsHashDB<KeccakHasher, DBValue> for Wrapping<'db> {
fn as_hashdb(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hashdb_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
}
impl<'db> HashDB<KeccakHasher, DBValue> for Wrapping<'db> {
fn keys(&self) -> HashMap<H256, i32> {
unimplemented!()
}
fn get(&self, key: &H256) -> Option<DBValue> {
if key == &KECCAK_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));
@@ -254,15 +241,11 @@ impl<'db> HashDB<KeccakHasher, DBValue> for Wrapping<'db> {
struct WrappingMut<'db>(&'db mut HashDB<KeccakHasher, DBValue>);
impl<'db> AsHashDB<KeccakHasher, DBValue> for WrappingMut<'db> {
fn as_hashdb(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hashdb_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db(&self) -> &HashDB<KeccakHasher, DBValue> { self }
fn as_hash_db_mut(&mut self) -> &mut HashDB<KeccakHasher, DBValue> { self }
}
impl<'db> HashDB<KeccakHasher, DBValue> for WrappingMut<'db>{
fn keys(&self) -> HashMap<H256, i32> {
unimplemented!()
}
fn get(&self, key: &H256) -> Option<DBValue> {
if key == &KECCAK_NULL_RLP {
return Some(DBValue::from_slice(&NULL_RLP));

View File

@@ -21,9 +21,11 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::sync::{Arc, Weak};
use std::time::{Instant, Duration};
use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert, BlockNumberKey};
use bytes::Bytes;
use call_contract::{CallContract, RegistryInfo};
use ethcore_miner::pool::VerifiedTransaction;
use ethcore_miner::service_transaction_checker::ServiceTransactionChecker;
use ethereum_types::{H256, Address, U256};
use evm::Schedule;
use hash::keccak;
@@ -46,11 +48,11 @@ use vm::{EnvInfo, LastHashes};
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
use client::ancient_import::AncientVerifier;
use client::{
Nonce, Balance, ChainInfo, BlockInfo, CallContract, TransactionInfo,
RegistryInfo, ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock,
Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo,
ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock,
BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call,
AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter,
ClientIoMessage,
ClientIoMessage, BlockChainReset
};
use client::{
BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient,
@@ -59,7 +61,8 @@ use client::{
IoClient, BadBlocks,
};
use client::bad_blocks;
use engines::{EthEngine, EpochTransition, ForkChoice};
use engines::{EthEngine, EpochTransition, ForkChoice, EngineError};
use engines::epoch::PendingTransition;
use error::{
ImportErrorKind, ExecutionError, CallError, BlockError,
QueueError, QueueErrorKind, Error as EthcoreError, EthcoreResult, ErrorKind as EthcoreErrorKind
@@ -77,12 +80,14 @@ use verification::queue::kind::BlockLike;
use verification::queue::kind::blocks::Unverified;
use verification::{PreverifiedBlock, Verifier, BlockQueue};
use verification;
use ansi_term::Colour;
// re-export
pub use types::blockchain_info::BlockChainInfo;
pub use types::block_status::BlockStatus;
pub use blockchain::CacheSize as BlockChainCacheSize;
pub use verification::QueueInfo as BlockQueueInfo;
use db::Writable;
use_contract!(registry, "res/contracts/registrar.json");
@@ -291,8 +296,8 @@ impl Importer {
continue;
}
match self.check_and_lock_block(block, client) {
Ok(closed_block) => {
match self.check_and_lock_block(&bytes, block, client) {
Ok((closed_block, pending)) => {
if self.engine.is_proposal(&header) {
self.block_queue.mark_as_good(&[hash]);
proposed_blocks.push(bytes);
@@ -301,7 +306,7 @@ impl Importer {
let transactions_len = closed_block.transactions().len();
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), client);
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client);
import_results.push(route);
client.report.write().accrue_block(&header, transactions_len);
@@ -353,7 +358,7 @@ impl Importer {
imported
}
fn check_and_lock_block(&self, block: PreverifiedBlock, client: &Client) -> EthcoreResult<LockedBlock> {
fn check_and_lock_block(&self, bytes: &[u8], block: PreverifiedBlock, client: &Client) -> EthcoreResult<(LockedBlock, Option<PendingTransition>)> {
let engine = &*self.engine;
let header = block.header.clone();
@@ -437,7 +442,15 @@ impl Importer {
bail!(e);
}
Ok(locked_block)
let pending = self.check_epoch_end_signal(
&header,
bytes,
locked_block.receipts(),
locked_block.state().db(),
client
)?;
Ok((locked_block, pending))
}
/// Import a block with transaction receipts.
@@ -469,7 +482,8 @@ impl Importer {
// it is for reconstructing the state transition.
//
// The header passed is from the original block data and is sealed.
fn commit_block<B>(&self, block: B, header: &Header, block_data: encoded::Block, client: &Client) -> ImportRoute where B: Drain {
// TODO: should return an error if ImportRoute is none, issue #9910
fn commit_block<B>(&self, block: B, header: &Header, block_data: encoded::Block, pending: Option<PendingTransition>, client: &Client) -> ImportRoute where B: Drain {
let hash = &header.hash();
let number = header.number();
let parent = header.parent_hash();
@@ -524,15 +538,9 @@ impl Importer {
// check epoch end signal, potentially generating a proof on the current
// state.
self.check_epoch_end_signal(
&header,
block_data.raw(),
&receipts,
&state,
&chain,
&mut batch,
client
);
if let Some(pending) = pending {
chain.insert_pending_transition(&mut batch, header.hash(), pending);
}
state.journal_under(&mut batch, number, hash).expect("DB commit failed");
@@ -587,10 +595,8 @@ impl Importer {
block_bytes: &[u8],
receipts: &[Receipt],
state_db: &StateDB,
chain: &BlockChain,
batch: &mut DBTransaction,
client: &Client,
) {
) -> EthcoreResult<Option<PendingTransition>> {
use engines::EpochChange;
let hash = header.hash();
@@ -601,7 +607,6 @@ impl Importer {
match self.engine.signals_epoch_end(header, auxiliary) {
EpochChange::Yes(proof) => {
use engines::epoch::PendingTransition;
use engines::Proof;
let proof = match proof {
@@ -619,7 +624,7 @@ impl Importer {
let call = move |addr, data| {
let mut state_db = state_db.boxed_clone();
let backend = ::state::backend::Proving::new(state_db.as_hashdb_mut());
let backend = ::state::backend::Proving::new(state_db.as_hash_db_mut());
let transaction =
client.contract_call_tx(BlockId::Hash(*header.parent_hash()), addr, data);
@@ -638,11 +643,9 @@ impl Importer {
.transact(&transaction, options);
let res = match res {
Err(ExecutionError::Internal(e)) =>
Err(format!("Internal error: {}", e)),
Err(e) => {
trace!(target: "client", "Proved call failed: {}", e);
Ok((Vec::new(), state.drop().1.extract_proof()))
Err(e.to_string())
}
Ok(res) => Ok((res.output, state.drop().1.extract_proof())),
};
@@ -655,7 +658,7 @@ impl Importer {
Err(e) => {
warn!(target: "client", "Failed to generate transition proof for block {}: {}", hash, e);
warn!(target: "client", "Snapshots produced by this client may be incomplete");
Vec::new()
return Err(EngineError::FailedSystemCall(e).into())
}
}
}
@@ -663,13 +666,13 @@ impl Importer {
debug!(target: "client", "Block {} signals epoch end.", hash);
let pending = PendingTransition { proof: proof };
chain.insert_pending_transition(batch, hash, pending);
Ok(Some(PendingTransition { proof: proof }))
},
EpochChange::No => {},
EpochChange::No => Ok(None),
EpochChange::Unsure(_) => {
warn!(target: "client", "Detected invalid engine implementation.");
warn!(target: "client", "Engine claims to require more block data, but everything provided.");
Err(EngineError::InvalidEngine.into())
}
}
}
@@ -1173,7 +1176,7 @@ impl Client {
};
let processing_threads = self.config.snapshot.processing_threads;
snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hashdb(), writer, p, processing_threads)?;
snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hash_db(), writer, p, processing_threads)?;
Ok(())
}
@@ -1328,6 +1331,48 @@ impl snapshot::DatabaseRestore for Client {
}
}
impl BlockChainReset for Client {
fn reset(&self, num: u32) -> Result<(), String> {
if num as u64 > self.pruning_history() {
return Err("Attempting to reset to block with pruned state".into())
}
let (blocks_to_delete, best_block_hash) = self.chain.read()
.block_headers_from_best_block(num)
.ok_or("Attempted to reset past genesis block")?;
let mut db_transaction = DBTransaction::with_capacity((num + 1) as usize);
for hash in &blocks_to_delete {
db_transaction.delete(::db::COL_HEADERS, &hash.hash());
db_transaction.delete(::db::COL_BODIES, &hash.hash());
db_transaction.delete(::db::COL_EXTRA, &hash.hash());
Writable::delete::<H256, BlockNumberKey>
(&mut db_transaction, ::db::COL_EXTRA, &hash.number());
}
// update the new best block hash
db_transaction.put(::db::COL_EXTRA, b"best", &*best_block_hash);
self.db.read()
.key_value()
.write(db_transaction)
.map_err(|err| format!("could not complete reset operation; io error occured: {}", err))?;
let hashes = blocks_to_delete.iter().map(|b| b.hash()).collect::<Vec<_>>();
info!("Deleting block hashes {}",
Colour::Red
.bold()
.paint(format!("{:#?}", hashes))
);
info!("New best block hash {}", Colour::Green.bold().paint(format!("{:?}", best_block_hash)));
Ok(())
}
}
impl Nonce for Client {
fn nonce(&self, address: &Address, id: BlockId) -> Option<U256> {
self.state_at(id).and_then(|s| s.nonce(address).ok())
@@ -1661,15 +1706,17 @@ impl BlockChainClient for Client {
self.config.spec_name.clone()
}
fn set_spec_name(&self, new_spec_name: String) {
fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()> {
trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name);
if !self.enabled.load(AtomicOrdering::Relaxed) {
return;
return Err(());
}
if let Some(ref h) = *self.exit_handler.lock() {
(*h)(new_spec_name);
Ok(())
} else {
warn!("Not hypervised; cannot change chain.");
Err(())
}
}
@@ -1736,7 +1783,8 @@ impl BlockChainClient for Client {
};
let (root, db) = state.drop();
let trie = match self.factories.trie.readonly(db.as_hashdb(), &root) {
let db = &db.as_hash_db();
let trie = match self.factories.trie.readonly(db, &root) {
Ok(trie) => trie,
_ => {
trace!(target: "fatdb", "list_accounts: Couldn't open the DB");
@@ -1782,8 +1830,9 @@ impl BlockChainClient for Client {
};
let (_, db) = state.drop();
let account_db = self.factories.accountdb.readonly(db.as_hashdb(), keccak(account));
let trie = match self.factories.trie.readonly(account_db.as_hashdb(), &root) {
let account_db = &self.factories.accountdb.readonly(db.as_hash_db(), keccak(account));
let account_db = &account_db.as_hash_db();
let trie = match self.factories.trie.readonly(account_db, &root) {
Ok(trie) => trie,
_ => {
trace!(target: "fatdb", "list_storage: Couldn't open the DB");
@@ -2110,11 +2159,16 @@ impl BlockChainClient for Client {
fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error> {
let authoring_params = self.importer.miner.authoring_params();
let service_transaction_checker = ServiceTransactionChecker::default();
let gas_price = match service_transaction_checker.check_address(self, authoring_params.author) {
Ok(true) => U256::zero(),
_ => self.importer.miner.sensible_gas_price(),
};
let transaction = transaction::Transaction {
nonce: self.latest_nonce(&authoring_params.author),
action: Action::Call(address),
gas: self.importer.miner.sensible_gas_limit(),
gas_price: self.importer.miner.sensible_gas_price(),
gas_price,
value: U256::zero(),
data: data,
};
@@ -2328,7 +2382,20 @@ impl ImportSealedBlock for Client {
let block_data = block.rlp_bytes();
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
let pending = self.importer.check_epoch_end_signal(
&header,
&block_data,
block.receipts(),
block.state().db(),
self
)?;
let route = self.importer.commit_block(
block,
&header,
encoded::Block::new(block_data),
pending,
self
);
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), hash);
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
route
@@ -2436,7 +2503,7 @@ impl ProvingBlockChainClient for Client {
let mut jdb = self.state_db.read().journal_db().boxed_clone();
state::prove_transaction_virtual(
jdb.as_hashdb_mut(),
jdb.as_hash_db_mut(),
header.state_root().clone(),
&transaction,
self.engine.machine(),

View File

@@ -93,6 +93,7 @@ impl<'a> EvmTestClient<'a> {
ForkSpec::EIP158 => Some(ethereum::new_eip161_test()),
ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()),
ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()),
ForkSpec::ConstantinopleFix => Some(ethereum::new_constantinople_fix_test()),
ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()),
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
}

View File

@@ -36,8 +36,9 @@ pub use self::io_message::ClientIoMessage;
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
pub use self::traits::{
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks,
BlockChainReset
};
pub use state::StateInfo;
pub use self::traits::{BlockChainClient, EngineClient, ProvingBlockChainClient, IoClient};

View File

@@ -49,8 +49,9 @@ use types::views::BlockView;
use vm::Schedule;
use block::{OpenBlock, SealedBlock, ClosedBlock};
use call_contract::{CallContract, RegistryInfo};
use client::{
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, CallContract, TransactionInfo, RegistryInfo,
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, TransactionInfo,
PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode,
TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics,
ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock,
@@ -862,7 +863,7 @@ impl BlockChainClient for TestBlockChainClient {
fn spec_name(&self) -> String { "foundation".into() }
fn set_spec_name(&self, _: String) { unimplemented!(); }
fn set_spec_name(&self, _: String) -> Result<(), ()> { unimplemented!(); }
fn disable(&self) { self.disabled.store(true, AtomicOrder::Relaxed); }

View File

@@ -19,6 +19,7 @@ use std::sync::Arc;
use blockchain::{BlockReceipts, TreeRoute};
use bytes::Bytes;
use call_contract::{CallContract, RegistryInfo};
use ethcore_miner::pool::VerifiedTransaction;
use ethereum_types::{H256, U256, Address};
use evm::Schedule;
@@ -157,12 +158,6 @@ pub trait StateClient {
/// Provides various blockchain information, like block header, chain state etc.
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
/// Provides information on a blockchain service and it's registry
pub trait RegistryInfo {
/// Get the address of a particular blockchain service, if available.
fn registry_address(&self, name: String, block: BlockId) -> Option<Address>;
}
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
/// Provides methods to import block into blockchain
pub trait ImportBlock {
@@ -170,12 +165,6 @@ pub trait ImportBlock {
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
}
/// Provides `call_contract` method
pub trait CallContract {
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String>;
}
/// Provides `call` and `call_many` methods
pub trait Call {
/// Type representing chain state
@@ -371,7 +360,7 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra
fn spec_name(&self) -> String;
/// Set the chain via a spec name.
fn set_spec_name(&self, spec_name: String);
fn set_spec_name(&self, spec_name: String) -> Result<(), ()>;
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
@@ -482,3 +471,9 @@ pub trait ProvingBlockChainClient: BlockChainClient {
/// Get an epoch change signal by block hash.
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>>;
}
/// resets the blockchain
pub trait BlockChainReset {
/// reset to best_block - n
fn reset(&self, num: u32) -> Result<(), String>;
}

View File

@@ -24,7 +24,6 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::sync::{Weak, Arc};
use std::time::{UNIX_EPOCH, SystemTime, Duration};
use account_provider::AccountProvider;
use block::*;
use client::EngineClient;
use engines::{Engine, Seal, EngineError, ConstructedVerifier};
@@ -37,7 +36,7 @@ use hash::keccak;
use super::signer::EngineSigner;
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
use self::finality::RollingFinality;
use ethkey::{self, Password, Signature};
use ethkey::{self, Signature};
use io::{IoContext, IoHandler, TimerToken, IoService};
use itertools::{self, Itertools};
use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp};
@@ -48,6 +47,9 @@ use types::header::{Header, ExtendedHeader};
use types::ancestry_action::AncestryAction;
use unexpected::{Mismatch, OutOfBounds};
#[cfg(not(time_checked_add))]
use time_utils::CheckedSystemTime;
mod finality;
/// `AuthorityRound` params.
@@ -412,7 +414,7 @@ pub struct AuthorityRound {
transition_service: IoService<()>,
step: Arc<PermissionedStep>,
client: Arc<RwLock<Option<Weak<EngineClient>>>>,
signer: RwLock<EngineSigner>,
signer: RwLock<Option<Box<EngineSigner>>>,
validators: Box<ValidatorSet>,
validate_score_transition: u64,
validate_step_transition: u64,
@@ -571,8 +573,15 @@ fn verify_timestamp(step: &Step, header_step: u64) -> Result<(), BlockError> {
// NOTE This error might be returned only in early stage of verification (Stage 1).
// Returning it further won't recover the sync process.
trace!(target: "engine", "verify_timestamp: block too early");
let oob = oob.map(|n| SystemTime::now() + Duration::from_secs(n));
Err(BlockError::TemporarilyInvalid(oob).into())
let now = SystemTime::now();
let found = now.checked_add(Duration::from_secs(oob.found)).ok_or(BlockError::TimestampOverflow)?;
let max = oob.max.and_then(|m| now.checked_add(Duration::from_secs(m)));
let min = oob.min.and_then(|m| now.checked_add(Duration::from_secs(m)));
let new_oob = OutOfBounds { min, max, found };
Err(BlockError::TemporarilyInvalid(new_oob).into())
},
Ok(_) => Ok(()),
}
@@ -608,6 +617,7 @@ fn combine_proofs(signal_number: BlockNumber, set_proof: &[u8], finality_proof:
stream.out()
}
fn destructure_proofs(combined: &[u8]) -> Result<(BlockNumber, &[u8], &[u8]), Error> {
let rlp = Rlp::new(combined);
Ok((
@@ -623,7 +633,7 @@ trait AsMillis {
impl AsMillis for Duration {
fn as_millis(&self) -> u64 {
self.as_secs()*1_000 + (self.subsec_nanos()/1_000_000) as u64
self.as_secs() * 1_000 + (self.subsec_nanos() / 1_000_000) as u64
}
}
@@ -665,7 +675,7 @@ impl AuthorityRound {
can_propose: AtomicBool::new(true),
}),
client: Arc::new(RwLock::new(None)),
signer: Default::default(),
signer: RwLock::new(None),
validators: our_params.validators,
validate_score_transition: our_params.validate_score_transition,
validate_step_transition: our_params.validate_step_transition,
@@ -788,7 +798,7 @@ impl AuthorityRound {
return;
}
if let (true, Some(me)) = (current_step > parent_step + 1, self.signer.read().address()) {
if let (true, Some(me)) = (current_step > parent_step + 1, self.signer.read().as_ref().map(|s| s.address())) {
debug!(target: "engine", "Author {} built block with step gap. current step: {}, parent step: {}",
header.author(), current_step, parent_step);
let mut reported = HashSet::new();
@@ -1406,8 +1416,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
let first = chain_head.number() == 0;
// apply immediate transitions.
// Apply transitions that don't require finality and should be enacted immediately (e.g from chain spec)
if let Some(change) = self.validators.is_epoch_end(first, chain_head) {
info!(target: "engine", "Immediately applying validator set change signalled at block {}", chain_head.number());
self.epoch_manager.lock().note_new_epoch();
let change = combine_proofs(chain_head.number(), &change, &[]);
return Some(change)
}
@@ -1492,12 +1504,16 @@ impl Engine<EthereumMachine> for AuthorityRound {
self.validators.register_client(client);
}
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: Password) {
self.signer.write().set(ap, address, password);
fn set_signer(&self, signer: Box<EngineSigner>) {
*self.signer.write() = Some(signer);
}
fn sign(&self, hash: H256) -> Result<Signature, Error> {
Ok(self.signer.read().sign(hash)?)
Ok(self.signer.read()
.as_ref()
.ok_or(ethkey::Error::InvalidAddress)?
.sign(hash)?
)
}
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
@@ -1532,16 +1548,16 @@ mod tests {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use hash::keccak;
use accounts::AccountProvider;
use ethereum_types::{Address, H520, H256, U256};
use ethkey::Signature;
use types::header::Header;
use rlp::encode;
use block::*;
use test_helpers::{
generate_dummy_client_with_spec_and_accounts, get_temp_state_db,
generate_dummy_client_with_spec, get_temp_state_db,
TestNotify
};
use account_provider::AccountProvider;
use spec::Spec;
use types::transaction::{Action, Transaction};
use engines::{Seal, Engine, EngineError, EthEngine};
@@ -1620,14 +1636,14 @@ mod tests {
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b2 = b2.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) {
assert!(b1.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden.
assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None);
}
engine.set_signer(tap, addr2, "2".into());
engine.set_signer(Box::new((tap, addr2, "2".into())));
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) {
assert!(b2.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden.
@@ -1654,13 +1670,13 @@ mod tests {
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b2 = b2.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
match engine.generate_seal(b1.block(), &genesis_header) {
Seal::None | Seal::Proposal(_) => panic!("wrong seal"),
Seal::Regular(_) => {
engine.step();
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
match engine.generate_seal(b2.block(), &genesis_header) {
Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"),
Seal::None => {}
@@ -1768,7 +1784,7 @@ mod tests {
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 0);
aura.set_signer(Arc::new(AccountProvider::transient_provider()), Default::default(), "".into());
aura.set_signer(Box::new((Arc::new(AccountProvider::transient_provider()), Default::default(), "".into())));
// Do not report on steps skipped between genesis and first block.
header.set_number(1);
@@ -1878,12 +1894,12 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
let notify = Arc::new(TestNotify::default());
client.add_notify(notify.clone());
engine.register_client(Arc::downgrade(&client) as _);
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b1 = b1.close_and_lock().unwrap();
@@ -1917,7 +1933,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
let notify = Arc::new(TestNotify::default());
client.add_notify(notify.clone());
engine.register_client(Arc::downgrade(&client) as _);
@@ -1927,7 +1943,7 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
@@ -1944,9 +1960,9 @@ mod tests {
let b2 = b2.close_and_lock().unwrap();
// we will now seal a block with 1tx and include the accumulated empty step message
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) {
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash());
let empty_steps = ::rlp::encode_list(&vec![empty_step2]);
@@ -1970,7 +1986,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
let notify = Arc::new(TestNotify::default());
client.add_notify(notify.clone());
engine.register_client(Arc::downgrade(&client) as _);
@@ -1980,14 +1996,14 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
// step 3
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b2 = b2.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
assert_eq!(engine.generate_seal(b2.block(), &genesis_header), Seal::None);
engine.step();
@@ -1996,10 +2012,10 @@ mod tests {
let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b3 = b3.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
if let Seal::Regular(seal) = engine.generate_seal(b3.block(), &genesis_header) {
let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash());
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
let empty_step3 = sealed_empty_step(engine, 3, &genesis_header.hash());
let empty_steps = ::rlp::encode_list(&vec![empty_step2, empty_step3]);
@@ -2022,7 +2038,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
engine.register_client(Arc::downgrade(&client) as _);
// step 2
@@ -2030,7 +2046,7 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
@@ -2084,7 +2100,7 @@ mod tests {
);
// empty step with valid signature from incorrect proposer for step
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let empty_steps = vec![sealed_empty_step(engine, 1, &parent_header.hash())];
set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
@@ -2094,9 +2110,9 @@ mod tests {
);
// valid empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let empty_step2 = sealed_empty_step(engine, 2, &parent_header.hash());
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
let empty_step3 = sealed_empty_step(engine, 3, &parent_header.hash());
let empty_steps = vec![empty_step2, empty_step3];
@@ -2121,10 +2137,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(
Spec::new_test_round_block_reward_contract,
None,
);
let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract);
engine.register_client(Arc::downgrade(&client) as _);
// step 2
@@ -2144,7 +2157,7 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
@@ -2182,7 +2195,7 @@ mod tests {
let engine = &*spec.engine;
let addr1 = accounts[0];
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let mut header: Header = Header::default();
let empty_step = empty_step(engine, 1, &header.parent_hash());
@@ -2263,7 +2276,7 @@ mod tests {
header.set_author(accounts[0]);
// when
engine.set_signer(tap.clone(), accounts[1], "0".into());
engine.set_signer(Box::new((tap.clone(), accounts[1], "0".into())));
let empty_steps = vec![
sealed_empty_step(&*engine, 1, &parent.hash()),
sealed_empty_step(&*engine, 1, &parent.hash()),
@@ -2300,9 +2313,9 @@ mod tests {
header.set_author(accounts[0]);
// when
engine.set_signer(tap.clone(), accounts[1], "0".into());
engine.set_signer(Box::new((tap.clone(), accounts[1], "0".into())));
let es1 = sealed_empty_step(&*engine, 1, &parent.hash());
engine.set_signer(tap.clone(), accounts[0], "1".into());
engine.set_signer(Box::new((tap.clone(), accounts[0], "1".into())));
let es2 = sealed_empty_step(&*engine, 2, &parent.hash());
let mut empty_steps = vec![es2, es1];

View File

@@ -16,19 +16,18 @@
//! A blockchain engine that supports a basic, non-BFT proof-of-authority.
use std::sync::{Weak, Arc};
use ethereum_types::{H256, H520, Address};
use std::sync::Weak;
use ethereum_types::{H256, H520};
use parking_lot::RwLock;
use ethkey::{self, Password, Signature};
use account_provider::AccountProvider;
use ethkey::{self, Signature};
use block::*;
use engines::{Engine, Seal, ConstructedVerifier, EngineError};
use engines::signer::EngineSigner;
use error::{BlockError, Error};
use ethjson;
use client::EngineClient;
use machine::{AuxiliaryData, Call, EthereumMachine};
use types::header::{Header, ExtendedHeader};
use super::signer::EngineSigner;
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
/// `BasicAuthority` params.
@@ -76,7 +75,7 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err
/// Engine using `BasicAuthority`, trivial proof-of-authority consensus.
pub struct BasicAuthority {
machine: EthereumMachine,
signer: RwLock<EngineSigner>,
signer: RwLock<Option<Box<EngineSigner>>>,
validators: Box<ValidatorSet>,
}
@@ -85,7 +84,7 @@ impl BasicAuthority {
pub fn new(our_params: BasicAuthorityParams, machine: EthereumMachine) -> Self {
BasicAuthority {
machine: machine,
signer: Default::default(),
signer: RwLock::new(None),
validators: new_validator_set(our_params.validators),
}
}
@@ -190,12 +189,16 @@ impl Engine<EthereumMachine> for BasicAuthority {
self.validators.register_client(client);
}
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: Password) {
self.signer.write().set(ap, address, password);
fn set_signer(&self, signer: Box<EngineSigner>) {
*self.signer.write() = Some(signer);
}
fn sign(&self, hash: H256) -> Result<Signature, Error> {
Ok(self.signer.read().sign(hash)?)
Ok(self.signer.read()
.as_ref()
.ok_or_else(|| ethkey::Error::InvalidAddress)?
.sign(hash)?
)
}
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
@@ -214,7 +217,7 @@ mod tests {
use ethereum_types::H520;
use block::*;
use test_helpers::get_temp_state_db;
use account_provider::AccountProvider;
use accounts::AccountProvider;
use types::header::Header;
use spec::Spec;
use engines::Seal;
@@ -257,7 +260,7 @@ mod tests {
let spec = new_test_authority();
let engine = &*spec.engine;
engine.set_signer(Arc::new(tap), addr, "".into());
engine.set_signer(Box::new((Arc::new(tap), addr, "".into())));
let genesis_header = spec.genesis_header();
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]);
@@ -275,7 +278,7 @@ mod tests {
let engine = new_test_authority().engine;
assert!(!engine.seals_internally().unwrap());
engine.set_signer(Arc::new(tap), authority, "".into());
engine.set_signer(Box::new((Arc::new(tap), authority, "".into())));
assert!(engine.seals_internally().unwrap());
}
}

View File

@@ -25,7 +25,7 @@ use std::sync::Arc;
use hash::keccak;
use error::Error;
use machine::WithRewards;
use parity_machine::{Machine, WithBalances};
use parity_machine::Machine;
use trace;
use types::BlockNumber;
use super::{SystemOrCodeCall, SystemOrCodeCallKind};
@@ -152,7 +152,7 @@ impl BlockRewardContract {
/// Applies the given block rewards, i.e. adds the given balance to each beneficiary' address.
/// If tracing is enabled the operations are recorded.
pub fn apply_block_rewards<M: Machine + WithBalances + WithRewards>(
pub fn apply_block_rewards<M: Machine + WithRewards>(
rewards: &[(Address, RewardKind, U256)],
block: &mut M::LiveBlock,
machine: &M,
@@ -170,17 +170,14 @@ mod test {
use client::PrepareOpenBlock;
use ethereum_types::U256;
use spec::Spec;
use test_helpers::generate_dummy_client_with_spec_and_accounts;
use test_helpers::generate_dummy_client_with_spec;
use engines::SystemOrCodeCallKind;
use super::{BlockRewardContract, RewardKind};
#[test]
fn block_reward_contract() {
let client = generate_dummy_client_with_spec_and_accounts(
Spec::new_test_round_block_reward_contract,
None,
);
let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract);
let machine = Spec::new_test_machine();

View File

@@ -20,16 +20,17 @@ mod authority_round;
mod basic_authority;
mod instant_seal;
mod null_engine;
mod signer;
mod validator_set;
pub mod block_reward;
pub mod signer;
pub use self::authority_round::AuthorityRound;
pub use self::basic_authority::BasicAuthority;
pub use self::epoch::{EpochVerifier, Transition as EpochTransition};
pub use self::instant_seal::{InstantSeal, InstantSealParams};
pub use self::null_engine::NullEngine;
pub use self::signer::EngineSigner;
// TODO [ToDr] Remove re-export (#10130)
pub use types::engines::ForkChoice;
@@ -39,7 +40,6 @@ use std::sync::{Weak, Arc};
use std::collections::{BTreeMap, HashMap};
use std::{fmt, error};
use account_provider::AccountProvider;
use builtin::Builtin;
use vm::{EnvInfo, Schedule, CreateContractAddress, CallType, ActionValue};
use error::Error;
@@ -49,7 +49,7 @@ use snapshot::SnapshotComponents;
use spec::CommonParams;
use types::transaction::{self, UnverifiedTransaction, SignedTransaction};
use ethkey::{Password, Signature};
use ethkey::{Signature};
use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader};
use ethereum_types::{H256, U256, Address};
use unexpected::{Mismatch, OutOfBounds};
@@ -81,6 +81,8 @@ pub enum EngineError {
MalformedMessage(String),
/// Requires client ref, but none registered.
RequiresClient,
/// Invalid engine specification or implementation.
InvalidEngine,
}
impl fmt::Display for EngineError {
@@ -96,6 +98,7 @@ impl fmt::Display for EngineError {
FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg),
MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg),
RequiresClient => format!("Call requires client but none registered"),
InvalidEngine => format!("Invalid engine specification or implementation"),
};
f.write_fmt(format_args!("Engine error ({})", msg))
@@ -377,8 +380,8 @@ pub trait Engine<M: Machine>: Sync + Send {
/// Takes a header of a fully verified block.
fn is_proposal(&self, _verified_header: &M::Header) -> bool { false }
/// Register an account which signs consensus messages.
fn set_signer(&self, _account_provider: Arc<AccountProvider>, _address: Address, _password: Password) {}
/// Register a component which signs consensus messages.
fn set_signer(&self, _signer: Box<EngineSigner>) {}
/// Sign using the EngineSigner, to be used for consensus tx signing.
fn sign(&self, _hash: H256) -> Result<Signature, M::Error> { unimplemented!() }

View File

@@ -18,7 +18,7 @@ use engines::Engine;
use engines::block_reward::{self, RewardKind};
use ethereum_types::U256;
use machine::WithRewards;
use parity_machine::{Header, LiveBlock, WithBalances, TotalScoredHeader};
use parity_machine::{Machine, Header, LiveBlock, TotalScoredHeader};
use types::BlockNumber;
/// Params for a null engine.
@@ -58,7 +58,7 @@ impl<M: Default> Default for NullEngine<M> {
}
}
impl<M: WithBalances + WithRewards> Engine<M> for NullEngine<M>
impl<M: Machine + WithRewards> Engine<M> for NullEngine<M>
where M::ExtendedHeader: TotalScoredHeader,
<M::ExtendedHeader as TotalScoredHeader>::Value: Ord
{

View File

@@ -16,49 +16,68 @@
//! A signer used by Engines which need to sign messages.
use std::sync::Arc;
use ethereum_types::{H256, Address};
use ethkey::{Password, Signature};
use account_provider::{self, AccountProvider};
use ethkey::{self, Signature};
/// Everything that an Engine needs to sign messages.
pub struct EngineSigner {
account_provider: Arc<AccountProvider>,
address: Option<Address>,
password: Option<Password>,
pub trait EngineSigner: Send + Sync {
/// Sign a consensus message hash.
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error>;
/// Signing address
fn address(&self) -> Address;
}
impl Default for EngineSigner {
fn default() -> Self {
EngineSigner {
account_provider: Arc::new(AccountProvider::transient_provider()),
address: Default::default(),
password: Default::default(),
/// Creates a new `EngineSigner` from given key pair.
pub fn from_keypair(keypair: ethkey::KeyPair) -> Box<EngineSigner> {
Box::new(Signer(keypair))
}
struct Signer(ethkey::KeyPair);
impl EngineSigner for Signer {
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error> {
ethkey::sign(self.0.secret(), &hash)
}
fn address(&self) -> Address {
self.0.address()
}
}
#[cfg(test)]
mod test_signer {
use std::sync::Arc;
use ethkey::Password;
use accounts::{self, AccountProvider, SignError};
use super::*;
impl EngineSigner for (Arc<AccountProvider>, Address, Password) {
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error> {
match self.0.sign(self.1, Some(self.2.clone()), hash) {
Err(SignError::NotUnlocked) => unreachable!(),
Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress),
Err(SignError::Hardware(err)) => {
warn!("Error using hardware wallet for engine: {:?}", err);
Err(ethkey::Error::InvalidSecret)
},
Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err),
Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => {
warn!("Low level crypto error: {:?}", err);
Err(ethkey::Error::InvalidSecret)
},
Err(SignError::SStore(err)) => {
warn!("Error signing for engine: {:?}", err);
Err(ethkey::Error::InvalidSignature)
},
Ok(ok) => Ok(ok),
}
}
fn address(&self) -> Address {
self.1
}
}
}
impl EngineSigner {
/// Set up the signer to sign with given address and password.
pub fn set(&mut self, ap: Arc<AccountProvider>, address: Address, password: Password) {
self.account_provider = ap;
self.address = Some(address);
self.password = Some(password);
debug!(target: "poa", "Setting Engine signer to {}", address);
}
/// Sign a consensus message hash.
pub fn sign(&self, hash: H256) -> Result<Signature, account_provider::SignError> {
self.account_provider.sign(self.address.unwrap_or_else(Default::default), self.password.clone(), hash)
}
/// Signing address.
pub fn address(&self) -> Option<Address> {
self.address.clone()
}
/// Check if the signing address was set.
pub fn is_some(&self) -> bool {
self.address.is_some()
}
}

View File

@@ -141,17 +141,18 @@ mod tests {
use rlp::encode;
use spec::Spec;
use types::header::Header;
use account_provider::AccountProvider;
use miner::MinerService;
use accounts::AccountProvider;
use miner::{self, MinerService};
use types::ids::BlockId;
use test_helpers::generate_dummy_client_with_spec_and_accounts;
use client::{BlockChainClient, ChainInfo, BlockInfo, CallContract};
use test_helpers::generate_dummy_client_with_spec;
use call_contract::CallContract;
use client::{BlockChainClient, ChainInfo, BlockInfo};
use super::super::ValidatorSet;
use super::ValidatorContract;
#[test]
fn fetches_validators() {
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_contract);
let vc = Arc::new(ValidatorContract::new("0000000000000000000000000000000000000005".parse::<Address>().unwrap()));
vc.register_client(Arc::downgrade(&client) as _);
let last_hash = client.best_block_header().hash();
@@ -163,13 +164,14 @@ mod tests {
fn reports_validators() {
let tap = Arc::new(AccountProvider::transient_provider());
let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone()));
let client = generate_dummy_client_with_spec(Spec::new_validator_contract);
client.engine().register_client(Arc::downgrade(&client) as _);
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
// Make sure reporting can be done.
client.miner().set_gas_range_target((1_000_000.into(), 1_000_000.into()));
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
// Check a block that is a bit in future, reject it but don't report the validator.
let mut header = Header::default();

View File

@@ -150,15 +150,15 @@ mod tests {
use std::sync::Arc;
use std::collections::BTreeMap;
use hash::keccak;
use account_provider::AccountProvider;
use accounts::AccountProvider;
use client::{BlockChainClient, ChainInfo, BlockInfo, ImportBlock};
use engines::EpochChange;
use engines::validator_set::ValidatorSet;
use ethkey::Secret;
use types::header::Header;
use miner::MinerService;
use miner::{self, MinerService};
use spec::Spec;
use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data};
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
use types::ids::BlockId;
use ethereum_types::Address;
use verification::queue::kind::blocks::Unverified;
@@ -171,26 +171,29 @@ mod tests {
let s0: Secret = keccak("0").into();
let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap();
let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_multi, Some(tap));
let client = generate_dummy_client_with_spec(Spec::new_validator_multi);
client.engine().register_client(Arc::downgrade(&client) as _);
// Make sure txs go through.
client.miner().set_gas_range_target((1_000_000.into(), 1_000_000.into()));
// Wrong signer for the first block.
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
client.transact_contract(Default::default(), Default::default()).unwrap();
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 0);
// Right signer for the first block.
client.miner().set_author(v0, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v0, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 1);
// This time v0 is wrong.
client.transact_contract(Default::default(), Default::default()).unwrap();
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 1);
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 2);
// v1 is still good.

View File

@@ -445,19 +445,19 @@ mod tests {
use ethereum_types::Address;
use types::ids::BlockId;
use spec::Spec;
use account_provider::AccountProvider;
use accounts::AccountProvider;
use types::transaction::{Transaction, Action};
use client::{ChainInfo, BlockInfo, ImportBlock};
use ethkey::Secret;
use miner::MinerService;
use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data};
use miner::{self, MinerService};
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
use super::super::ValidatorSet;
use super::{ValidatorSafeContract, EVENT_NAME_HASH};
use verification::queue::kind::blocks::Unverified;
#[test]
fn fetches_validators() {
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
let vc = Arc::new(ValidatorSafeContract::new("0000000000000000000000000000000000000005".parse::<Address>().unwrap()));
vc.register_client(Arc::downgrade(&client) as _);
let last_hash = client.best_block_header().hash();
@@ -472,11 +472,12 @@ mod tests {
let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap();
let v1 = tap.insert_account(keccak("0").into(), &"".into()).unwrap();
let chain_id = Spec::new_validator_safe_contract().chain_id();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
client.engine().register_client(Arc::downgrade(&client) as _);
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(v1, Some("".into())).unwrap();
client.miner().set_author(miner::Author::Sealer(signer));
// Remove "1" validator.
let tx = Transaction {
nonce: 0.into(),
@@ -504,11 +505,13 @@ mod tests {
assert_eq!(client.chain_info().best_block_number, 1);
// Switch to the validator that is still there.
client.miner().set_author(v0, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v0, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 2);
// Switch back to the added validator, since the state is updated.
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
let tx = Transaction {
nonce: 2.into(),
gas_price: 0.into(),
@@ -539,7 +542,7 @@ mod tests {
use types::header::Header;
use types::log_entry::LogEntry;
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
let engine = client.engine().clone();
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
@@ -576,7 +579,7 @@ mod tests {
use types::header::Header;
use engines::{EpochChange, Proof};
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
let engine = client.engine().clone();
let mut new_header = Header::default();

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