Compare commits

...

6 Commits
main ... v2.0.5

Author SHA1 Message Date
Afri Schoedon
7dc4d349a1
Backports for 2.0.5 stable (#9519)
* parity-version: mark 2.0.5 track stable

* deps: bump fs-swap to 0.2.4

* Remove initial token for WS. (#9545)

* version: mark release critical

* Increase Gas-floor-target and Gas Cap (#9564)

+ Gas-floor-target increased to 8M by default

+ Gas-cap increased to 10M by default

* Improve P2P discovery (#9526)

* Add `target` to Rust traces

* network-devp2p: Don't remove discovery peer in main sync

* network-p2p: Refresh discovery more often

* Update Peer discovery protocol

* Run discovery more often when not enough nodes connected

* Start the first discovery early

* Update fast discovery rate

* Fix tests

* Fix `ping` tests

* Fixing remote Node address ; adding PingPong round

* Fix tests: update new +1 PingPong round

* Increase slow Discovery rate
Check in flight FindNode before pings

* Add `deprecated` to deprecated_echo_hash

* Refactor `discovery_round` branching

* net_version caches network_id to avoid redundant aquire of sync read lock (#9544)

* net_version caches network_id to avoid redundant aquire of sync read lock, #8746

* use lower_hex display formatting for net_peerCount rpc method
2018-09-17 13:56:25 +02:00
Denis S. Soldatov aka General-Beck
47d7197fb9
Update snapcraft.yaml (#9530)
fix DEPRICATED `prepare `
fix TODO https://bugs.launchpad.net/snapcraft/+bug/1778530
2018-09-11 22:32:10 +03:00
Afri Schoedon
e2e1d221d5
Beta backports to 2.0.4 (#9452)
* parity-version: bump beta to 2.0.4

* [light/jsonrpc] Provide the actual account for `eth_coinbase` RPC and unify error handeling for light and full client (#9383)

* Provide the actual `account` for eth_coinbase

The previous implementation always provided the `zero address` on
`eth_coinbase` RPC. Now, instead the actual address is returned on
success or an error when no account(s) is found!

* full client `eth_coinbase` return err

In the full-client return an error when no account is found instead of
returning the `zero address`

* Remove needless blocks on single import

* Remove needless `static` lifetime on const

* Fix `rpc_eth_author` test

* parity: print correct keys path on startup (#9501)

* aura: don't report skipped primaries when empty steps are enabled (#9435)

* Only check warp syncing for eth_getWorks (#9484)

* Only check warp syncing for eth_getWorks

* Use SyncStatus::is_snapshot_syncing

* Fix Snapshot restoration failure on Windows (#9491)

* Close Blooms DB files before DB restoration

* PR Grumbles I

* PR Grumble

* Grumble
2018-09-10 22:52:45 +02:00
Afri Schoedon
a0a2beddfe
beta backports for 2.0.3 (#9229)
* parity-version: bump beta to 2.0.2

* remove ssl from dockerfiles, closes #8880 (#9195)

* snap: remove ssl dependencies from snapcraft definition (#9222)

* parity-version: bump beta to 2.0.3

* Remove all dapp permissions related settings (#9120)

* Completely remove all dapps struct from rpc

* Remove unused pub use

* Remove dapp policy/permission func in ethcore

* Remove all dapps settings from rpc

* Fix rpc tests

* Use both origin and user_agent

* Address grumbles

* Address grumbles

* Fix tests

* Check if synced when using eth_getWork (#9193) (#9210)

* Check if synced when using eth_getWork (#9193)

* Don't use fn syncing

* Fix identation

* Fix typo

* Don't check for warping

* rpc: avoid calling queue_info twice on eth_getWork

* Fix potential as_usize overflow when casting from U256 in miner (#9221)

* Allow old blocks from peers with lower difficulty (#9226)

Previously we only allow downloading of old blocks if the peer
difficulty was greater than our syncing difficulty. This change allows
downloading of blocks from peers where the difficulty is greater then
the last downloaded old block.

* Update Dockerfile (#9242)

* Update Dockerfile

fix Docker build

* fix dockerfile paths: parity -> parity-ethereum (#9248)

* Propagate transactions for next 4 blocks. (#9265)

Closes #9255 

This PR also removes the limit of max 64 transactions per packet, currently we only attempt to prevent the packet size to go over 8MB. This will only be the case for super-large transactions or high-block-gas-limit chains.

Patching this is important only for chains that have blocks that can fit more than 4k transactions (over 86M block gas limit)

For mainnet, we should actually see a tiny bit faster propagation since instead of computing 4k pending set, we only need `4 * 8M / 21k = 1523` transactions.

Running some tests on `dekompile` node right now, to check how it performs in the wild.

* Update tobalaba.json (#9313)

* Fix load share (#9321)

* fix(light_sync): calculate `load_share` properly

* refactor(api.rs): extract `light_params` fn, add test

* style(api.rs): add trailing commas

* ethcore: fix pow difficulty validation (#9328)

* ethcore: fix pow difficulty validation

* ethcore: validate difficulty is not zero

* ethcore: add issue link to regression test

* ethcore: fix tests

* ethcore: move difficulty_to_boundary to ethash crate

* ethcore: reuse difficulty_to_boundary and boundary_to_difficulty

* ethcore: fix grumbles in difficulty_to_boundary_aux

* Light client `Provide default nonce in transactions when it´s missing` (#9370)

* Provide `default_nonce` in tx`s when it´s missing

When `nonce` is missing in a `EthTransaction` will cause it to fall in
these cases provide `default_nonce` value instead!

* Changed http:// to https:// on Yasm link (#9369)

Changed http:// to https:// on Yasm link in README.md

* Provide `default_nonce` in tx`s when it´s missing

When `nonce` is missing in a `EthTransaction` will cause it to fall in
these cases provide `default_nonce` value instead!

* Address grumbles

* ethcore: kovan: delay activation of strict score validation (#9406)

* Better support for eth_getLogs in light mode (#9186)

* Light client on-demand request for headers range.

* Cache headers in HeaderWithAncestors response.

Also fulfills request locally if all headers are in cache.

* LightFetch::logs fetches missing headers on demand.

* LightFetch::logs limit the number of headers requested at a time.

* LightFetch::logs refactor header fetching logic.

* Enforce limit on header range length in light client logs request.

* Fix light request tests after struct change.

* Respond to review comments.

* Add update docs script to CI (#9219)

* Add update docs script to CI

Added a script to CI that will use the jsonrpc tool to update rpc
documentation then commit and push those to the wiki repo.

* fix gitlab ci lint

* Only apply jsonrpc docs update on tags

* Update gitlab-rpc-docs.sh

* Copy correct parity repo to jsonrpc folder

Copy correct parity repo to jsonrpc folder before attempting to build docs since the CI runner clones the repo as parity and not parity-ethereum.

* Fix JSONRPC docs CI job

Update remote config in wiki repo before pushing changes using a github
token for authentication. Add message to wiki tag when pushing changes.
Use project directory to correctly copy parity code base into the
jsonrpc repo for doc generation.

* Fix set_remote_wiki function call in CI

* Prevent blockchain & miner racing when accessing pending block. (#9310)

* Prevent blockchain & miner racing when accessing pending block.

* Fix unavailability of pending block during reseal.

* Prevent sync restart if import queue full (#9381)

* Add POA Networks: Core and Sokol (#9413)

* ethcore: add poa network and sokol chainspecs

* rpc: simplify chain spec docs

* cli: rearrange networks by main/test and size/range

* parity: don't blacklist 0x00a328 on sokol testnet

* parity: add sokol and poanet to params and clean up a bit, add tests

* ethcore: add the poa networks and clean up a bit

* ethcore: fix path to poacore chain spec

* parity: rename poa networks to poacore and poasokol

* parity: fix configuration tests

* parity: fix parameter tests

* ethcore: rename POA Core and POA Sokol

* Update tobalaba.json (#9419)

* Update hardcoded sync (#9421)

- Update foundation hardcoded header to block 6219777 
- Update ropsten hardcoded header to block 3917825 
- Update kovan hardcoded header to block 8511489
2018-08-31 15:44:12 +02:00
Afri Schoedon
e7dc0bed16
Backports to 2.0.1-beta (#9145)
* parity-version: bump beta to 2.0.1

* ci: update version strings for snaps

* Be more graceful on Aura difficulty validation (#9164)

* Be more graceful on Aura difficulty validation

* test: rejects_step_backwards

* test: proposer_switching

* test: rejects_future_block

* test: reports_skipped

* test: verify_empty_seal_steps

* Remove node-health (#9119)

* Remove node-health

* Remove ntp_servers

* Add --ntp-servers as legacy instead of removing it

* Add --ntp-servers to deprecated args

* Remove unused stuff

* Remove _legacy_ntp_servers

* parity: fix UserDefaults json parser (#9189)

* parity: fix UserDefaults json parser

* parity: use serde_derive for UserDefaults

* parity: support deserialization of old UserDefault json format

* parity: make UserDefaults serde backwards compatible

* parity: tabify indentation in UserDefaults

* Fix bugfix hard fork logic (#9138)

* Fix bugfix hard fork logic

* Remove dustProtectionTransition from bugfix category

EIP-168 is not enabled by default

* Remove unnecessary 'static

* Disable per-sender limit for local transactions. (#9148)

* Disable per-sender limit for local transactions.

* Add a missing new line.

* rpc: fix is_major_importing sync state condition (#9112)

* rpc: fix is_major_importing sync state condition

* rpc: fix informant printout when waiting for peers

* fix verification in ethcore-sync collect_blocks (#9135)

* docker: update hub dockerfile (#9173)

* update Dockerfile for hub

update to Ubuntu Xenial 16.04
fix cmake version

* docker: fix tab indentation in hub dockerfile

* rpc: fix broken merge

* rcp: remove node_health leftover from merge

* rpc: remove dapps leftover from merge
2018-07-26 22:15:36 +02:00
Afri Schoedon
6eae372524
Backports to 2.0.0-beta (#9094)
* parity-version: betalize 2.0

* Multiple improvements to discovery ping handling (#8771)

* discovery: Only add nodes to routing table after receiving pong.

Previously the discovery algorithm would add nodes to the routing table
before confirming that the endpoint is participating in the protocol. This
now tracks in-flight pings and adds to the routing table only after receiving
a response.

* discovery: Refactor packet creation into its own function.

This function is useful inside unit tests.

* discovery: Additional testing for new add_node behavior.

* discovery: Track expiration of pings to non-yet-in-bucket nodes.

Now that we may ping nodes before adding to a k-bucket, the timeout tracking
must be separate from BucketEntry.

* discovery: Verify echo hash on pong packets.

Stores packet hash with in-flight requests and matches with pong response.

* discovery: Track timeouts on FIND_NODE requests.

* discovery: Retry failed pings with exponential backoff.

UDP packets may get dropped, so instead of immediately booting nodes that fail
to respond to a ping, retry 4 times with exponential backoff.

* !fixup Use slice instead of Vec for request_backoff.

* Add separate database directory for light client (#8927) (#9064)

* Add seperate default DB path for light client (#8927)

* Improve readability

* Revert "Replace `std::env::home_dir` with `dirs::home_dir` (#9077)" (#9097)

* Revert "Replace `std::env::home_dir` with `dirs::home_dir` (#9077)"

This reverts commit 7e779327eb.

* Restore some of the changes

* Update parity-common

* Offload cull to IoWorker. (#9099)

* Fix work-notify. (#9104)

* Update hidapi, fixes #7542 (#9108)

* docker: add cmake dependency (#9111)

* Update light client hardcoded headers (#9098)

* Insert Kovan hardcoded headers until #7690241

* Insert Kovan hardcoded headers until block 7690241

* Insert Ropsten hardcoded headers until #3612673

* Insert Mainnet hardcoded headers until block 5941249

* Make sure to produce full blocks. (#9115)

* Insert ETC (classic) hardcoded headers until block #6170625 (#9121)

* fix verification in ethcore-sync collect_blocks (#9135)

* Completely remove all dapps struct from rpc (#9107)

* Completely remove all dapps struct from rpc

* Remove unused pub use

* `evm bench` fix broken dependencies (#9134)

* `evm bench` use valid dependencies

Benchmarks of the `evm` used stale versions of a couple a crates that
this commit fixes!

* fix warnings

* Update snapcraft.yaml (#9132)
2018-07-17 13:47:14 +02:00
135 changed files with 6519 additions and 3136 deletions

View File

@ -2,6 +2,7 @@ stages:
- test
- push-release
- build
- docs
variables:
RUST_BACKTRACE: "1"
RUSTFLAGS: ""
@ -220,6 +221,15 @@ test-rust-nightly:
- rust
- rust-nightly
allow_failure: true
json-rpc-docs:
stage: docs
only:
- tags
image: parity/rust:gitlab-ci
script:
- scripts/gitlab-rpc-docs.sh
tags:
- docs
push-release:
stage: push-release
only:

295
Cargo.lock generated
View File

@ -76,7 +76,7 @@ name = "base64"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -85,7 +85,7 @@ name = "base64"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -94,9 +94,9 @@ name = "bincode"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -131,7 +131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "blooms-db"
version = "0.1.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -141,15 +141,16 @@ dependencies = [
[[package]]
name = "bn"
version = "0.4.4"
source = "git+https://github.com/paritytech/bn#964b48fad5dffbaa124c2f10699e76faf5846c4e"
source = "git+https://github.com/paritytech/bn#2a71dbde5ca93451c8da2135767896a64483759e"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byteorder"
version = "1.2.1"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -157,7 +158,7 @@ name = "bytes"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -217,6 +218,22 @@ dependencies = [
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cmake"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "common-types"
version = "0.1.0"
@ -231,14 +248,6 @@ dependencies = [
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "conv"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam"
version = "0.3.2"
@ -310,6 +319,11 @@ name = "crunchy"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crunchy"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ct-logs"
version = "0.2.0"
@ -328,11 +342,6 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "custom_derive"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "daemonize"
version = "0.2.3"
@ -351,20 +360,10 @@ name = "dir"
version = "0.1.1"
dependencies = [
"app_dirs 1.2.1 (git+https://github.com/paritytech/app-dirs-rs)",
"dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"journaldb 0.2.0",
]
[[package]]
name = "dirs"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "docopt"
version = "0.8.3"
@ -372,7 +371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -443,7 +442,7 @@ dependencies = [
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -471,8 +470,9 @@ version = "1.12.0"
dependencies = [
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (git+https://github.com/paritytech/parity-common)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -487,7 +487,7 @@ dependencies = [
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -498,7 +498,7 @@ dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"blooms-db 0.1.0",
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0",
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -533,7 +533,7 @@ dependencies = [
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"macros 0.1.0",
"memory-cache 0.1.0",
"memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)",
"memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)",
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
@ -608,7 +608,7 @@ dependencies = [
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-cache 0.1.0",
"memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)",
"memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)",
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
@ -617,9 +617,9 @@ dependencies = [
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rlp_derive 0.1.0",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"triehash-ethereum 0.2.0",
@ -713,7 +713,7 @@ dependencies = [
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -751,7 +751,7 @@ dependencies = [
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rlp_derive 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -762,7 +762,7 @@ dependencies = [
name = "ethcore-secretstore"
version = "1.0.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-contract 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -784,7 +784,7 @@ dependencies = [
"parity-crypto 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -836,6 +836,7 @@ dependencies = [
name = "ethcore-sync"
version = "1.12.0"
dependencies = [
"common-types 0.1.0",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.12.0",
"ethcore-io 1.12.0",
@ -862,7 +863,7 @@ dependencies = [
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"trace-time 0.1.0",
"triehash-ethereum 0.2.0",
]
@ -892,7 +893,7 @@ dependencies = [
"ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"uint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -901,7 +902,7 @@ name = "ethereum-types-serialize"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -910,7 +911,7 @@ version = "0.1.0"
dependencies = [
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -919,7 +920,7 @@ dependencies = [
name = "ethkey"
version = "0.3.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -931,7 +932,7 @@ dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -946,7 +947,7 @@ dependencies = [
"panic_hook 0.1.0",
"parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -967,10 +968,10 @@ dependencies = [
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -987,7 +988,7 @@ dependencies = [
"panic_hook 0.1.0",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1022,7 +1023,7 @@ dependencies = [
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
@ -1090,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fs-swap"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1173,7 +1174,7 @@ dependencies = [
[[package]]
name = "hashdb"
version = "0.2.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1203,7 +1204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hidapi"
version = "0.3.1"
source = "git+https://github.com/paritytech/hidapi-rs#70ec4bd1b755ec5dd32ad2be0c8345864147c8bc"
source = "git+https://github.com/paritytech/hidapi-rs#d4d323767d6f27cf5a3d73fbae0b0f2134d579bf"
dependencies = [
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1331,7 +1332,7 @@ dependencies = [
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)",
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)",
"memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)",
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"plain_hasher 0.1.0 (git+https://github.com/paritytech/parity-common)",
@ -1345,7 +1346,7 @@ source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#6b972
dependencies = [
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1382,7 +1383,7 @@ source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#6b972
dependencies = [
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1437,7 +1438,7 @@ dependencies = [
[[package]]
name = "keccak-hash"
version = "0.1.2"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1465,7 +1466,7 @@ dependencies = [
[[package]]
name = "kvdb"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
@ -1474,7 +1475,7 @@ dependencies = [
[[package]]
name = "kvdb-memorydb"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1483,11 +1484,11 @@ dependencies = [
[[package]]
name = "kvdb-rocksdb"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fs-swap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1653,8 +1654,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memorydb"
version = "0.2.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
version = "0.2.1"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashdb 0.2.0 (git+https://github.com/paritytech/parity-common)",
@ -1804,39 +1805,11 @@ dependencies = [
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "node-health"
version = "0.1.0"
dependencies = [
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"ntp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-reactor 0.1.0",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ntp"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num"
version = "0.1.42"
@ -1951,19 +1924,19 @@ dependencies = [
[[package]]
name = "parity-bytes"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
[[package]]
name = "parity-clib"
version = "1.12.0"
dependencies = [
"parity-ethereum 2.0.0",
"parity-ethereum 2.0.5",
]
[[package]]
name = "parity-crypto"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1974,7 +1947,7 @@ dependencies = [
[[package]]
name = "parity-ethereum"
version = "2.0.0"
version = "2.0.5"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2012,7 +1985,6 @@ dependencies = [
"mem 0.1.0",
"migration-rocksdb 0.1.0",
"node-filter 1.12.0",
"node-health 0.1.0",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0",
@ -2024,7 +1996,7 @@ dependencies = [
"parity-rpc 1.12.0",
"parity-rpc-client 1.4.0",
"parity-updater 1.12.0",
"parity-version 2.0.0",
"parity-version 2.0.5",
"parity-whisper 0.1.0",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"path 0.1.1 (git+https://github.com/paritytech/parity-common)",
@ -2037,7 +2009,7 @@ dependencies = [
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2099,7 +2071,7 @@ dependencies = [
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2158,21 +2130,21 @@ dependencies = [
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"macros 0.1.0",
"multihash 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"node-health 0.1.0",
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parity-crypto 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parity-reactor 0.1.0",
"parity-updater 1.12.0",
"parity-version 2.0.0",
"parity-version 2.0.5",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
"plain_hasher 0.1.0 (git+https://github.com/paritytech/parity-common)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0",
@ -2196,7 +2168,7 @@ dependencies = [
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-rpc 1.12.0",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2234,7 +2206,7 @@ dependencies = [
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parity-hash-fetch 1.12.0",
"parity-version 2.0.0",
"parity-version 2.0.5",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"path 0.1.1 (git+https://github.com/paritytech/parity-common)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2245,7 +2217,7 @@ dependencies = [
[[package]]
name = "parity-version"
version = "2.0.0"
version = "2.0.5"
dependencies = [
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
@ -2260,7 +2232,7 @@ name = "parity-wasm"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2268,7 +2240,7 @@ name = "parity-whisper"
version = "0.1.0"
dependencies = [
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-network 1.12.0",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0",
@ -2283,11 +2255,11 @@ dependencies = [
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2320,7 +2292,7 @@ dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2328,15 +2300,12 @@ dependencies = [
[[package]]
name = "path"
version = "0.1.1"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
dependencies = [
"dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
[[package]]
name = "patricia-trie"
version = "0.2.1"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashdb 0.2.0 (git+https://github.com/paritytech/parity-common)",
@ -2411,7 +2380,7 @@ dependencies = [
[[package]]
name = "plain_hasher"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2479,7 +2448,7 @@ dependencies = [
"hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"primal-bit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2512,7 +2481,7 @@ dependencies = [
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethjson 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
@ -2524,7 +2493,7 @@ name = "pwasm-utils"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2561,6 +2530,23 @@ dependencies = [
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rayon"
version = "1.0.1"
@ -2647,9 +2633,9 @@ dependencies = [
[[package]]
name = "rlp"
version = "0.2.1"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2807,7 +2793,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.37"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -2835,7 +2821,7 @@ name = "serde_ignored"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2846,7 +2832,7 @@ dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2904,7 +2890,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "0.4.3"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2913,7 +2899,7 @@ dependencies = [
[[package]]
name = "snappy"
version = "0.1.0"
source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73"
source = "git+https://github.com/paritytech/rust-snappy#798408ffef8f86dd51481673aca10f5348d7491b"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
@ -2922,9 +2908,9 @@ dependencies = [
[[package]]
name = "snappy-sys"
version = "0.1.0"
source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73"
source = "git+https://github.com/paritytech/rust-snappy#798408ffef8f86dd51481673aca10f5348d7491b"
dependencies = [
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3284,7 +3270,7 @@ name = "toml"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -3301,7 +3287,7 @@ dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"trace-time 0.1.0",
]
@ -3324,7 +3310,7 @@ dependencies = [
[[package]]
name = "trie-standardmap"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (git+https://github.com/paritytech/parity-common)",
@ -3335,7 +3321,7 @@ dependencies = [
[[package]]
name = "triehash"
version = "0.2.0"
source = "git+https://github.com/paritytech/parity-common#a72c34f82ff7ccc0f49827bb7f8c5d1fbff794bb"
source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c962a0b27e2caf3b9474"
dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3357,7 +3343,7 @@ name = "uint"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3474,7 +3460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "vm"
version = "0.1.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethjson 0.1.0",
@ -3495,7 +3481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "wasm"
version = "0.1.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-logger 1.12.0",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3511,7 +3497,7 @@ name = "wasmi"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3549,7 +3535,7 @@ dependencies = [
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0",
"parity-whisper 0.1.0",
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3587,7 +3573,7 @@ name = "ws"
version = "0.7.5"
source = "git+https://github.com/tomusdrw/ws-rs#f12d19c4c19422fc79af28a3181f598bc07ecd1e"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3647,14 +3633,15 @@ dependencies = [
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "<none>"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9"
"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
"checksum cid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d85ee025368e69063c420cbb2ed9f852cb03a5e69b73be021e65726ce03585b6"
"checksum clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f4a2b3bb7ef3c672d7c13d15613211d5a6976b6892c598b0fcb5d40765f19c2"
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "95470235c31c726d72bf2e1f421adc1e65b9d561bf5529612cbe1a72da1467b3"
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2"
@ -3663,12 +3650,11 @@ dependencies = [
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
"checksum ct-logs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61cd11fb222fecf889f4531855c614548e92e8bd2eb178e35296885df5ee9a7c"
"checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "<none>"
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
"checksum daemonize 0.2.3 (git+https://github.com/paritytech/daemonize)" = "<none>"
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
"checksum dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37a76dd8b997af7107d0bb69d43903cf37153a18266f8b3fdb9911f28efb5444"
"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a34f5204fbc13582de418611cf3a7dcdd07c6d312a5b631597ba72c06b9d9c9"
@ -3688,7 +3674,7 @@ dependencies = [
"checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum fs-swap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67f816b2a5f8a6628764a4323d1a8d9ad5303266c4e4e4486ba680f477ba7e62"
"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
@ -3746,7 +3732,7 @@ dependencies = [
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
"checksum memorydb 0.2.0 (git+https://github.com/paritytech/parity-common)" = "<none>"
"checksum memorydb 0.2.1 (git+https://github.com/paritytech/parity-common)" = "<none>"
"checksum mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e3d709ffbb330e1566dc2f2a3c9b58a5ad4a381f740b810cd305dc3f089bc160"
"checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae"
"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe"
@ -3759,7 +3745,6 @@ dependencies = [
"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f"
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum ntp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06b0d2de4a2cd60c3ac85c98a1fc23668bc97bef2b10b706bccd88efb229497d"
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
"checksum num-bigint 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "81b483ea42927c463e191802e7334556b48e7875297564c0e9951bd3a0ae53e3"
"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
@ -3803,6 +3788,8 @@ dependencies = [
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
"checksum rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "12397506224b2f93e6664ffc4f664b29be8208e5157d3d90b44f09b5fae470ea"
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
@ -3828,7 +3815,7 @@ dependencies = [
"checksum sct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1137b767bbe1c4d30656993bdd97422ed41255d9400b105d735f8c7d9e800632"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
"checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920"
"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f"
"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce"
"checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
@ -3842,7 +3829,7 @@ dependencies = [
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d"
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
"checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"
"checksum smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10"
"checksum snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
"checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
"checksum socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "06dc9f86ee48652b7c80f3d254e3b9accb67a928c562c64d10d7b016d3d98dab"

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.0.0"
version = "2.0.5"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
@ -32,7 +32,7 @@ futures-cpupool = "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-1.11" }
ethcore = { path = "ethcore", features = ["work-notify", "price-info", "stratum"] }
ethcore = { path = "ethcore", features = ["parity"] }
parity-bytes = { git = "https://github.com/paritytech/parity-common" }
ethcore-io = { path = "util/io" }
ethcore-light = { path = "ethcore/light" }
@ -46,7 +46,6 @@ ethcore-transaction = { path = "ethcore/transaction" }
ethereum-types = "0.3"
node-filter = { path = "ethcore/node_filter" }
ethkey = { path = "ethkey" }
node-health = { path = "node-health" }
rlp = { git = "https://github.com/paritytech/parity-common" }
rpc-cli = { path = "rpc_cli" }
parity-hash-fetch = { path = "hash-fetch" }
@ -88,6 +87,7 @@ winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] }
daemonize = { git = "https://github.com/paritytech/daemonize" }
[features]
miner-debug = ["ethcore/miner-debug"]
json-tests = ["ethcore/json-tests"]
test-heavy = ["ethcore/test-heavy"]
evm-debug = ["ethcore/evm-debug"]

View File

@ -5,7 +5,7 @@ WORKDIR /build
# install tools and dependencies
RUN apk add --no-cache gcc musl-dev pkgconfig g++ make curl \
eudev-dev rust cargo git file binutils \
libusb-dev linux-headers perl
libusb-dev linux-headers perl cmake
# show backtraces
ENV RUST_BACKTRACE 1

View File

@ -23,24 +23,6 @@ RUN /usr/local/android-ndk-r16b/build/tools/make-standalone-toolchain.sh \
--arch=arm --install-dir=/opt/ndk-standalone --stl=libc++ --platform=android-26
ENV PATH $PATH:/opt/ndk-standalone/bin
# Compiling OpenSSL for Android
RUN cd /root && \
git clone git://git.openssl.org/openssl.git && \
cd openssl && \
git checkout OpenSSL_1_1_0-stable
ENV CROSS_SYSROOT /opt/ndk-standalone/sysroot
RUN cd /root/openssl && \
./Configure android-armeabi --cross-compile-prefix=arm-linux-androideabi- \
-static no-stdio no-ui \
-I/usr/local/android-ndk-r16b/sysroot/usr/include \
-I/usr/local/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi \
-L/usr/local/android-ndk-r16b/sysroot/usr/lib \
--prefix=/opt/ndk-standalone/sysroot/usr
RUN cd /root/openssl && \
make build_libs && \
make install_dev
RUN rm -rf /root/openssl
# Compiling libudev for Android
# This is the most hacky part of the process, as we need to apply a patch and pass specific
# options that the compiler environment doesn't define.

View File

@ -3,7 +3,7 @@ WORKDIR /build
# install tools and dependencies
RUN yum -y update&& \
yum install -y git make gcc-c++ gcc file binutils
yum install -y git make gcc-c++ gcc file binutils cmake
# install rustup
RUN curl -sSf https://static.rust-lang.org/rustup.sh -o rustup.sh &&\

View File

@ -1,4 +1,4 @@
FROM ubuntu:14.04
FROM ubuntu:xenial
MAINTAINER Parity Technologies <devops@parity.io>
WORKDIR /build
#ENV for build TAG
@ -13,6 +13,7 @@ RUN apt-get update && \
# add-apt-repository
software-properties-common \
make \
cmake \
curl \
wget \
git \
@ -22,8 +23,6 @@ RUN apt-get update && \
libc6-dev \
binutils \
file \
openssl \
libssl-dev \
libudev-dev \
pkg-config \
dpkg-dev \
@ -35,14 +34,13 @@ RUN apt-get update && \
# show backtraces
RUST_BACKTRACE=1 && \
# build parity
cd /build&&git clone https://github.com/paritytech/parity && \
cd parity && \
cd /build&&git clone https://github.com/paritytech/parity-ethereum && \
cd parity-ethereum && \
git pull&& \
git checkout $BUILD_TAG && \
cargo build --verbose --release --features final && \
#ls /build/parity/target/release/parity && \
strip /build/parity/target/release/parity && \
file /build/parity/target/release/parity&&mkdir -p /parity&& cp /build/parity/target/release/parity /parity&&\
strip /build/parity-ethereum/target/release/parity && \
file /build/parity-ethereum/target/release/parity&&mkdir -p /parity&& cp /build/parity-ethereum/target/release/parity /parity&&\
#cleanup Docker image
rm -rf /root/.cargo&&rm -rf /root/.multirust&&rm -rf /root/.rustup&&rm -rf /build&&\
apt-get purge -y \
@ -51,6 +49,7 @@ cd /build&&git clone https://github.com/paritytech/parity && \
# add-apt-repository
software-properties-common \
make \
cmake \
curl \
wget \
git \

View File

@ -6,7 +6,7 @@ RUN apt-get -y update && \
apt-get install -y --force-yes --no-install-recommends \
curl git make g++ gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \
libc6-arm64-cross libc6-dev-arm64-cross wget file ca-certificates \
binutils-aarch64-linux-gnu \
binutils-aarch64-linux-gnu cmake \
&& \
apt-get clean

View File

@ -6,7 +6,7 @@ RUN apt-get -y update && \
apt-get install -y --force-yes --no-install-recommends \
curl git make g++ gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf \
libc6-dev-armhf-cross wget file ca-certificates \
binutils-arm-linux-gnueabihf \
binutils-arm-linux-gnueabihf cmake \
&& \
apt-get clean

View File

@ -6,11 +6,11 @@ RUN apt-get update && \
apt-get install -y \
g++ \
build-essential \
cmake \
curl \
git \
file \
binutils \
libssl-dev \
pkg-config \
libudev-dev

View File

@ -6,13 +6,14 @@ authors = ["Parity Technologies <admin@parity.io>"]
[lib]
[dependencies]
log = "0.3"
keccak-hash = { git = "https://github.com/paritytech/parity-common" }
primal = "0.2.3"
parking_lot = "0.6"
crunchy = "0.1.0"
memmap = "0.6"
either = "1.0.0"
ethereum-types = "0.3"
keccak-hash = { git = "https://github.com/paritytech/parity-common" }
log = "0.4"
memmap = "0.6"
parking_lot = "0.6"
primal = "0.2.3"
[dev-dependencies]
tempdir = "0.3"

View File

@ -16,10 +16,11 @@
#![cfg_attr(feature = "benches", feature(test))]
extern crate primal;
extern crate parking_lot;
extern crate either;
extern crate ethereum_types;
extern crate memmap;
extern crate parking_lot;
extern crate primal;
#[macro_use]
extern crate crunchy;
@ -38,6 +39,7 @@ mod shared;
pub use cache::{NodeCacheBuilder, OptimizeFor};
pub use compute::{ProofOfWork, quick_get_difficulty, slow_hash_block_number};
use compute::Light;
use ethereum_types::{U256, U512};
use keccak::H256;
use parking_lot::Mutex;
pub use seed_compute::SeedHashCompute;
@ -136,6 +138,29 @@ impl EthashManager {
}
}
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
pub fn boundary_to_difficulty(boundary: &ethereum_types::H256) -> U256 {
difficulty_to_boundary_aux(&**boundary)
}
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
pub fn difficulty_to_boundary(difficulty: &U256) -> ethereum_types::H256 {
difficulty_to_boundary_aux(difficulty).into()
}
fn difficulty_to_boundary_aux<T: Into<U512>>(difficulty: T) -> ethereum_types::U256 {
let difficulty = difficulty.into();
assert!(!difficulty.is_zero());
if difficulty == U512::one() {
U256::max_value()
} else {
// difficulty > 1, so result should never overflow 256 bits
U256::from((U512::one() << 256) / difficulty)
}
}
#[test]
fn test_lru() {
use tempdir::TempDir;
@ -155,6 +180,43 @@ fn test_lru() {
assert_eq!(ethash.cache.lock().prev_epoch.unwrap(), 0);
}
#[test]
fn test_difficulty_to_boundary() {
use ethereum_types::H256;
use std::str::FromStr;
assert_eq!(difficulty_to_boundary(&U256::from(1)), H256::from(U256::max_value()));
assert_eq!(difficulty_to_boundary(&U256::from(2)), H256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(difficulty_to_boundary(&U256::from(4)), H256::from_str("4000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap());
}
#[test]
fn test_difficulty_to_boundary_regression() {
use ethereum_types::H256;
// the last bit was originally being truncated when performing the conversion
// https://github.com/paritytech/parity-ethereum/issues/8397
for difficulty in 1..9 {
assert_eq!(U256::from(difficulty), boundary_to_difficulty(&difficulty_to_boundary(&difficulty.into())));
assert_eq!(H256::from(difficulty), difficulty_to_boundary(&boundary_to_difficulty(&difficulty.into())));
assert_eq!(U256::from(difficulty), boundary_to_difficulty(&boundary_to_difficulty(&difficulty.into()).into()));
assert_eq!(H256::from(difficulty), difficulty_to_boundary(&difficulty_to_boundary(&difficulty.into()).into()));
}
}
#[test]
#[should_panic]
fn test_difficulty_to_boundary_panics_on_zero() {
difficulty_to_boundary(&U256::from(0));
}
#[test]
#[should_panic]
fn test_boundary_to_difficulty_panics_on_zero() {
boundary_to_difficulty(&ethereum_types::H256::from(0));
}
#[cfg(feature = "benches")]
mod benchmarks {
extern crate test;

View File

@ -80,6 +80,17 @@ tempdir = "0.3"
trie-standardmap = { git = "https://github.com/paritytech/parity-common" }
[features]
parity = ["work-notify", "price-info", "stratum"]
# Large optional features that are enabled by default for Parity,
# but might be omitted for other dependent crates.
work-notify = ["ethcore-miner/work-notify"]
price-info = ["ethcore-miner/price-info"]
stratum = ["ethcore-stratum"]
# Disables seal verification for mined blocks.
# This allows you to submit any seal via RPC to test and benchmark
# how fast pending block get's created while running on the mainnet.
miner-debug = []
# Display EVM debug traces.
evm-debug = ["evm/evm-debug"]
# Display EVM debug traces when running tests.
@ -97,6 +108,3 @@ test-heavy = []
benches = []
# Compile test helpers
test-helpers = ["tempdir"]
work-notify = ["ethcore-miner/work-notify"]
price-info = ["ethcore-miner/price-info"]
stratum = ["ethcore-stratum"]

View File

@ -16,17 +16,16 @@
#![feature(test)]
extern crate test;
extern crate ethcore_util as util;
extern crate rand;
extern crate bn;
extern crate parity_crypto;
extern crate ethereum_types;
extern crate ethkey;
extern crate parity_crypto;
extern crate rand;
extern crate rustc_hex;
extern crate ethcore_bigint;
extern crate test;
use self::test::{Bencher};
use rand::{StdRng};
use self::test::Bencher;
use rand::StdRng;
#[bench]
fn bn_128_pairing(b: &mut Bencher) {
@ -62,8 +61,7 @@ fn bn_128_mul(b: &mut Bencher) {
fn sha256(b: &mut Bencher) {
use parity_crypto::digest::sha256;
let mut input: [u8; 256] = [0; 256];
let mut out = [0; 32];
let input = [0_u8; 256];
b.iter(|| {
sha256(&input);
@ -74,7 +72,7 @@ fn sha256(b: &mut Bencher) {
fn ecrecover(b: &mut Bencher) {
use rustc_hex::FromHex;
use ethkey::{Signature, recover as ec_recover};
use ethcore_bigint::hash::H256;
use ethereum_types::H256;
let input = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
let hash = H256::from_slice(&input[0..32]);
let v = H256::from_slice(&input[32..64]);

View File

@ -43,7 +43,7 @@ pub mod provider;
mod types;
pub use self::cache::Cache;
pub use self::provider::Provider;
pub use self::provider::{Provider, MAX_HEADERS_PER_REQUEST};
pub use self::transaction_queue::TransactionQueue;
pub use types::request as request;

View File

@ -70,9 +70,6 @@ const PROPAGATE_TIMEOUT_INTERVAL: Duration = Duration::from_secs(5);
const RECALCULATE_COSTS_TIMEOUT: TimerToken = 3;
const RECALCULATE_COSTS_INTERVAL: Duration = Duration::from_secs(60 * 60);
/// Max number of transactions in a single packet.
const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64;
// minimum interval between updates.
const UPDATE_INTERVAL: Duration = Duration::from_millis(5000);
@ -648,7 +645,7 @@ impl LightProtocol {
fn propagate_transactions(&self, io: &IoContext) {
if self.capabilities.read().tx_relay { return }
let ready_transactions = self.provider.ready_transactions(MAX_TRANSACTIONS_TO_PROPAGATE);
let ready_transactions = self.provider.transactions_to_propagate();
if ready_transactions.is_empty() { return }
trace!(target: "pip", "propagate transactions: {} ready", ready_transactions.len());

View File

@ -171,8 +171,8 @@ impl Provider for TestProvider {
})
}
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction> {
self.0.client.ready_transactions(max_len)
fn transactions_to_propagate(&self) -> Vec<PendingTransaction> {
self.0.client.transactions_to_propagate()
}
}

View File

@ -204,6 +204,8 @@ fn guess_capabilities(requests: &[CheckedRequest]) -> Capabilities {
caps.serve_headers = true,
CheckedRequest::HeaderByHash(_, _) =>
caps.serve_headers = true,
CheckedRequest::HeaderWithAncestors(_, _) =>
caps.serve_headers = true,
CheckedRequest::TransactionIndex(_, _) => {} // hashes yield no info.
CheckedRequest::Signal(_, _) =>
caps.serve_headers = true,

View File

@ -16,6 +16,7 @@
//! Request types, verification, and verification errors.
use std::cmp;
use std::sync::Arc;
use bytes::Bytes;
@ -47,6 +48,8 @@ pub enum Request {
HeaderProof(HeaderProof),
/// A request for a header by hash.
HeaderByHash(HeaderByHash),
/// A request for a header by hash with a range of its ancestors.
HeaderWithAncestors(HeaderWithAncestors),
/// A request for the index of a transaction.
TransactionIndex(TransactionIndex),
/// A request for block receipts.
@ -136,6 +139,7 @@ macro_rules! impl_single {
// implement traits for each kind of request.
impl_single!(HeaderProof, HeaderProof, (H256, U256));
impl_single!(HeaderByHash, HeaderByHash, encoded::Header);
impl_single!(HeaderWithAncestors, HeaderWithAncestors, Vec<encoded::Header>);
impl_single!(TransactionIndex, TransactionIndex, net_request::TransactionIndexResponse);
impl_single!(Receipts, BlockReceipts, Vec<Receipt>);
impl_single!(Body, Body, encoded::Block);
@ -246,6 +250,7 @@ impl From<encoded::Header> for HeaderRef {
pub enum CheckedRequest {
HeaderProof(HeaderProof, net_request::IncompleteHeaderProofRequest),
HeaderByHash(HeaderByHash, net_request::IncompleteHeadersRequest),
HeaderWithAncestors(HeaderWithAncestors, net_request::IncompleteHeadersRequest),
TransactionIndex(TransactionIndex, net_request::IncompleteTransactionIndexRequest),
Receipts(BlockReceipts, net_request::IncompleteReceiptsRequest),
Body(Body, net_request::IncompleteBodyRequest),
@ -267,6 +272,16 @@ impl From<Request> for CheckedRequest {
};
CheckedRequest::HeaderByHash(req, net_req)
}
Request::HeaderWithAncestors(req) => {
let net_req = net_request::IncompleteHeadersRequest {
start: req.block_hash.map(Into::into),
skip: 0,
max: req.ancestor_count + 1,
reverse: true,
};
trace!(target: "on_demand", "HeaderWithAncestors Request, {:?}", net_req);
CheckedRequest::HeaderWithAncestors(req, net_req)
}
Request::HeaderProof(req) => {
let net_req = net_request::IncompleteHeaderProofRequest {
num: req.num().into(),
@ -335,6 +350,7 @@ impl CheckedRequest {
match self {
CheckedRequest::HeaderProof(_, req) => NetRequest::HeaderProof(req),
CheckedRequest::HeaderByHash(_, req) => NetRequest::Headers(req),
CheckedRequest::HeaderWithAncestors(_, req) => NetRequest::Headers(req),
CheckedRequest::TransactionIndex(_, req) => NetRequest::TransactionIndex(req),
CheckedRequest::Receipts(_, req) => NetRequest::Receipts(req),
CheckedRequest::Body(_, req) => NetRequest::Body(req),
@ -390,6 +406,27 @@ impl CheckedRequest {
None
}
CheckedRequest::HeaderWithAncestors(_, ref req) => {
if req.skip != 1 || !req.reverse {
return None;
}
if let Some(&net_request::HashOrNumber::Hash(start)) = req.start.as_ref() {
let mut result = Vec::with_capacity(req.max as usize);
let mut hash = start;
let mut cache = cache.lock();
for _ in 0..req.max {
match cache.block_header(&hash) {
Some(header) => {
hash = header.parent_hash();
result.push(header);
}
None => return None,
}
}
Some(Response::HeaderWithAncestors(result))
} else { None }
}
CheckedRequest::Receipts(ref check, ref req) => {
// empty transactions -> no receipts
if check.0.as_ref().ok().map_or(false, |hdr| hdr.receipts_root() == KECCAK_NULL_RLP) {
@ -458,6 +495,7 @@ macro_rules! match_me {
match $me {
CheckedRequest::HeaderProof($check, $req) => $e,
CheckedRequest::HeaderByHash($check, $req) => $e,
CheckedRequest::HeaderWithAncestors($check, $req) => $e,
CheckedRequest::TransactionIndex($check, $req) => $e,
CheckedRequest::Receipts($check, $req) => $e,
CheckedRequest::Body($check, $req) => $e,
@ -487,6 +525,15 @@ impl IncompleteRequest for CheckedRequest {
_ => Ok(()),
}
}
CheckedRequest::HeaderWithAncestors(ref check, ref req) => {
req.check_outputs(&mut f)?;
// make sure the output given is definitively a hash.
match check.block_hash {
Field::BackReference(r, idx) => f(r, idx, OutputKind::Hash),
_ => Ok(()),
}
}
CheckedRequest::TransactionIndex(_, ref req) => req.check_outputs(f),
CheckedRequest::Receipts(_, ref req) => req.check_outputs(f),
CheckedRequest::Body(_, ref req) => req.check_outputs(f),
@ -507,15 +554,46 @@ impl IncompleteRequest for CheckedRequest {
fn complete(self) -> Result<Self::Complete, net_request::NoSuchOutput> {
match self {
CheckedRequest::HeaderProof(_, req) => req.complete().map(CompleteRequest::HeaderProof),
CheckedRequest::HeaderByHash(_, req) => req.complete().map(CompleteRequest::Headers),
CheckedRequest::TransactionIndex(_, req) => req.complete().map(CompleteRequest::TransactionIndex),
CheckedRequest::Receipts(_, req) => req.complete().map(CompleteRequest::Receipts),
CheckedRequest::Body(_, req) => req.complete().map(CompleteRequest::Body),
CheckedRequest::Account(_, req) => req.complete().map(CompleteRequest::Account),
CheckedRequest::Code(_, req) => req.complete().map(CompleteRequest::Code),
CheckedRequest::Execution(_, req) => req.complete().map(CompleteRequest::Execution),
CheckedRequest::Signal(_, req) => req.complete().map(CompleteRequest::Signal),
CheckedRequest::HeaderProof(_, req) => {
trace!(target: "on_demand", "HeaderProof request completed {:?}", req);
req.complete().map(CompleteRequest::HeaderProof)
}
CheckedRequest::HeaderByHash(_, req) => {
trace!(target: "on_demand", "HeaderByHash request completed {:?}", req);
req.complete().map(CompleteRequest::Headers)
}
CheckedRequest::HeaderWithAncestors(_, req) => {
trace!(target: "on_demand", "HeaderWithAncestors request completed {:?}", req);
req.complete().map(CompleteRequest::Headers)
}
CheckedRequest::TransactionIndex(_, req) => {
trace!(target: "on_demand", "TransactionIndex request completed {:?}", req);
req.complete().map(CompleteRequest::TransactionIndex)
}
CheckedRequest::Receipts(_, req) => {
trace!(target: "on_demand", "Receipt request completed {:?}", req);
req.complete().map(CompleteRequest::Receipts)
}
CheckedRequest::Body(_, req) => {
trace!(target: "on_demand", "Block request completed {:?}", req);
req.complete().map(CompleteRequest::Body)
}
CheckedRequest::Account(_, req) => {
trace!(target: "on_demand", "Account request completed {:?}", req);
req.complete().map(CompleteRequest::Account)
}
CheckedRequest::Code(_, req) => {
trace!(target: "on_demand", "Code request completed {:?}", req);
req.complete().map(CompleteRequest::Code)
}
CheckedRequest::Execution(_, req) => {
trace!(target: "on_demand", "Execution request completed {:?}", req);
req.complete().map(CompleteRequest::Execution)
}
CheckedRequest::Signal(_, req) => {
trace!(target: "on_demand", "Signal request completed {:?}", req);
req.complete().map(CompleteRequest::Signal)
}
}
}
@ -551,6 +629,9 @@ impl net_request::CheckedRequest for CheckedRequest {
CheckedRequest::HeaderByHash(ref prover, _) =>
expect!((&NetResponse::Headers(ref res), &CompleteRequest::Headers(ref req)) =>
prover.check_response(cache, &req.start, &res.headers).map(Response::HeaderByHash)),
CheckedRequest::HeaderWithAncestors(ref prover, _) =>
expect!((&NetResponse::Headers(ref res), &CompleteRequest::Headers(ref req)) =>
prover.check_response(cache, &req.start, &res.headers).map(Response::HeaderWithAncestors)),
CheckedRequest::TransactionIndex(ref prover, _) =>
expect!((&NetResponse::TransactionIndex(ref res), _) =>
prover.check_response(cache, res).map(Response::TransactionIndex)),
@ -584,6 +665,8 @@ pub enum Response {
HeaderProof((H256, U256)),
/// Response to a header-by-hash request.
HeaderByHash(encoded::Header),
/// Response to a header-by-hash with ancestors request.
HeaderWithAncestors(Vec<encoded::Header>),
/// Response to a transaction-index request.
TransactionIndex(net_request::TransactionIndexResponse),
/// Response to a receipts request.
@ -625,6 +708,10 @@ pub enum Error {
Decoder(::rlp::DecoderError),
/// Empty response.
Empty,
/// Response data length exceeds request max.
TooManyResults(u64, u64),
/// Response data is incomplete.
TooFewResults(u64, u64),
/// Trie lookup error (result of bad proof)
Trie(TrieError),
/// Bad inclusion proof
@ -641,6 +728,8 @@ pub enum Error {
WrongTrieRoot(H256, H256),
/// Wrong response kind.
WrongKind,
/// Wrong sequence of headers.
WrongHeaderSequence,
}
impl From<::rlp::DecoderError> for Error {
@ -701,6 +790,65 @@ impl HeaderProof {
}
}
/// Request for a header by hash with a range of ancestors.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HeaderWithAncestors {
/// Hash of the last block in the range to fetch.
pub block_hash: Field<H256>,
/// Number of headers before the last block to fetch in addition.
pub ancestor_count: u64,
}
impl HeaderWithAncestors {
/// Check a response for the headers.
pub fn check_response(
&self,
cache: &Mutex<::cache::Cache>,
start: &net_request::HashOrNumber,
headers: &[encoded::Header]
) -> Result<Vec<encoded::Header>, Error> {
let expected_hash = match (self.block_hash, start) {
(Field::Scalar(ref h), &net_request::HashOrNumber::Hash(ref h2)) => {
if h != h2 { return Err(Error::WrongHash(*h, *h2)) }
*h
}
(_, &net_request::HashOrNumber::Hash(h2)) => h2,
_ => return Err(Error::HeaderByNumber),
};
let start_header = headers.first().ok_or(Error::Empty)?;
let start_hash = start_header.hash();
if start_hash != expected_hash {
return Err(Error::WrongHash(expected_hash, start_hash));
}
let expected_len = 1 + cmp::min(self.ancestor_count, start_header.number());
let actual_len = headers.len() as u64;
match actual_len.cmp(&expected_len) {
cmp::Ordering::Less =>
return Err(Error::TooFewResults(expected_len, actual_len)),
cmp::Ordering::Greater =>
return Err(Error::TooManyResults(expected_len, actual_len)),
cmp::Ordering::Equal => (),
};
for (header, prev_header) in headers.iter().zip(headers[1..].iter()) {
if header.number() != prev_header.number() + 1 ||
header.parent_hash() != prev_header.hash()
{
return Err(Error::WrongHeaderSequence)
}
}
let mut cache = cache.lock();
for header in headers {
cache.insert_block_header(header.hash(), header.clone());
}
Ok(headers.to_vec())
}
}
/// Request for a header by hash.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HeaderByHash(pub Field<H256>);
@ -993,6 +1141,83 @@ mod tests {
assert!(HeaderByHash(hash.into()).check_response(&cache, &hash.into(), &[raw_header]).is_ok())
}
#[test]
fn check_header_with_ancestors() {
let mut last_header_hash = H256::default();
let mut headers = (0..11).map(|num| {
let mut header = Header::new();
header.set_number(num);
header.set_parent_hash(last_header_hash);
last_header_hash = header.hash();
header
}).collect::<Vec<_>>();
headers.reverse(); // because responses are in reverse order
let raw_headers = headers.iter()
.map(|hdr| encoded::Header::new(::rlp::encode(hdr).into_vec()))
.collect::<Vec<_>>();
let mut invalid_successor = Header::new();
invalid_successor.set_number(11);
invalid_successor.set_parent_hash(headers[1].hash());
let raw_invalid_successor = encoded::Header::new(::rlp::encode(&invalid_successor).into_vec());
let cache = Mutex::new(make_cache());
let header_with_ancestors = |hash, count| {
HeaderWithAncestors {
block_hash: hash,
ancestor_count: count
}
};
// Correct responses
assert!(header_with_ancestors(headers[0].hash().into(), 0)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]).is_ok());
assert!(header_with_ancestors(headers[0].hash().into(), 2)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..3]).is_ok());
assert!(header_with_ancestors(headers[0].hash().into(), 10)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]).is_ok());
assert!(header_with_ancestors(headers[2].hash().into(), 2)
.check_response(&cache, &headers[2].hash().into(), &raw_headers[2..5]).is_ok());
assert!(header_with_ancestors(headers[2].hash().into(), 10)
.check_response(&cache, &headers[2].hash().into(), &raw_headers[2..11]).is_ok());
assert!(header_with_ancestors(invalid_successor.hash().into(), 0)
.check_response(&cache, &invalid_successor.hash().into(), &[raw_invalid_successor.clone()]).is_ok());
// Incorrect responses
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 0)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]),
Err(Error::WrongHash(invalid_successor.hash(), headers[0].hash())));
assert_eq!(header_with_ancestors(headers[0].hash().into(), 0)
.check_response(&cache, &headers[0].hash().into(), &[]),
Err(Error::Empty));
assert_eq!(header_with_ancestors(headers[0].hash().into(), 10)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..10]),
Err(Error::TooFewResults(11, 10)));
assert_eq!(header_with_ancestors(headers[0].hash().into(), 9)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]),
Err(Error::TooManyResults(10, 11)));
let response = &[raw_headers[0].clone(), raw_headers[2].clone()];
assert_eq!(header_with_ancestors(headers[0].hash().into(), 1)
.check_response(&cache, &headers[0].hash().into(), response),
Err(Error::WrongHeaderSequence));
let response = &[raw_invalid_successor.clone(), raw_headers[0].clone()];
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1)
.check_response(&cache, &invalid_successor.hash().into(), response),
Err(Error::WrongHeaderSequence));
let response = &[raw_invalid_successor.clone(), raw_headers[1].clone()];
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1)
.check_response(&cache, &invalid_successor.hash().into(), response),
Err(Error::WrongHeaderSequence));
}
#[test]
fn check_body() {
use rlp::RlpStream;

View File

@ -33,6 +33,9 @@ use transaction_queue::TransactionQueue;
use request;
/// Maximum allowed size of a headers request.
pub const MAX_HEADERS_PER_REQUEST: u64 = 512;
/// Defines the operations that a provider for the light subprotocol must fulfill.
pub trait Provider: Send + Sync {
/// Provide current blockchain info.
@ -54,7 +57,6 @@ pub trait Provider: Send + Sync {
/// results within must adhere to the `skip` and `reverse` parameters.
fn block_headers(&self, req: request::CompleteHeadersRequest) -> Option<request::HeadersResponse> {
use request::HashOrNumber;
const MAX_HEADERS_TO_SEND: u64 = 512;
if req.max == 0 { return None }
@ -83,7 +85,7 @@ pub trait Provider: Send + Sync {
}
};
let max = ::std::cmp::min(MAX_HEADERS_TO_SEND, req.max);
let max = ::std::cmp::min(MAX_HEADERS_PER_REQUEST, req.max);
let headers: Vec<_> = (0u64..max)
.map(|x: u64| x.saturating_mul(req.skip.saturating_add(1)))
@ -128,7 +130,7 @@ pub trait Provider: Send + Sync {
fn header_proof(&self, req: request::CompleteHeaderProofRequest) -> Option<request::HeaderProofResponse>;
/// Provide pending transactions.
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction>;
fn transactions_to_propagate(&self) -> Vec<PendingTransaction>;
/// Provide a proof-of-execution for the given transaction proof request.
/// Returns a vector of all state items necessary to execute the transaction.
@ -283,8 +285,8 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
.map(|(_, proof)| ::request::ExecutionResponse { items: proof })
}
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction> {
BlockChainClient::ready_transactions(self, max_len)
fn transactions_to_propagate(&self) -> Vec<PendingTransaction> {
BlockChainClient::transactions_to_propagate(self)
.into_iter()
.map(|tx| tx.pending().clone())
.collect()
@ -370,12 +372,10 @@ impl<L: AsLightClient + Send + Sync> Provider for LightProvider<L> {
None
}
fn ready_transactions(&self, max_len: usize) -> Vec<PendingTransaction> {
fn transactions_to_propagate(&self) -> Vec<PendingTransaction> {
let chain_info = self.chain_info();
let mut transactions = self.txqueue.read()
.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp);
transactions.truncate(max_len);
transactions
self.txqueue.read()
.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -173,9 +173,9 @@
"gasLimit": "0x1388",
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
},
"hardcodedSync": {
"header": "f90207a0cdaf426b80edd4363b336b351cbfec8c38b44847cdbd814aa92e92bc9ec05333a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949435d50503aee35c8757ae4933f7a0ab56597805a03f28b2b384dbfd29bc0a10343e8a419e61b92782f880046170bf1d11455e94bba0f3712ef3ff24efe1afc7da11ffb2ca495a94fe7958f42e9f1599d66ed72af13ba06d01d03a15f807da601bd2dfde7490bbe91d9bb11c11eda435db9daad6e7b1efb9010000008c0000c000000000440100108040000082000800000000000000040801001004001000000010000000001000043300001000008000800000002000200040000000580c0004108000040c0008000006000000000280800080000800000000402000000a000000a810226200002881004000208006020000000510030000100040010100000086c20000000009000100000190008c80060000008000202080420008056040000000001000400001100010140822800220000c804004002000108000160001400200088082008000000412100010080205011000000800a0000810021005000000000002840000000400000000880000006000000000200002870bfca554dbc6398358b001837a137083473c8e845b27f4fd86436f72746578a0dbf31fd28bd8f69f1103196e1782a9dfb636bcfa726362ab0767235cb8d56e7188264402501145497f",
"totalDifficulty": "4838383800145139949936",
"hardcodedSync": {
"header": "f9020ba0c7139a7f4b14c2e12dbe34aeb92711b37747bf8698ecdd6f2c3b1f5f3840e288a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452e44f279f4203dcf680395379e5f9990a69f13ca06e817f8a9b206f93a393da76a3ece2a74b98eaecc4dae0cfa8f409455e88ccb4a0d739197170d2bc6bbb24fac0ce695982090702082fe1541bb7634f018dfe87b3a038503b7299fb1c113a78b4a3a5dfd997ef32e7fbf722fc178dfcb21e1af1f7f5b9010000020000000000000008000000000010000000000000000000000000000200000002000000000008000000000000000000000000000000000000000000000000000000000000000001004008000000000000000000000000000080000000000008000000080000000000008000000000000000000000000000040210004000000010000000400000000001040000000200000000000000440008000000040000000000000000000000000010000000000000000000000000000000800000000000100002000000000000000000002000000000000000000000000000000000000080000000100000000000000000040400000000000000004000000000000000870c90e059b181c6835ee8018379fb9583065150845b833d198a7777772e62772e636f6da0171fc2d066507ea10c8c2d7bedd5ccc3f0dfb4d590a3998a614013326c0b213a88b4fd884826187393",
"totalDifficulty": "6255555800944520547241",
"CHTs": [
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
@ -3014,7 +3014,206 @@
"0x118b3ae7ad25ab96fe8a63973312c758d4ce9ecd39cc24913c26a65b4b5534de",
"0x19cd088af8dbe2d3e6ca7987d9ee1564ea2256f482840b1d2f0da85060de9a86",
"0x98bc07422cf8b0c4d1428afb759300d9a7637de2518528d34f7d237be7e863be",
"0x0c64526b393066911c7da3f17f9e652cfa38112ae324e3c84416e811d3fe7cad"
"0x0c64526b393066911c7da3f17f9e652cfa38112ae324e3c84416e811d3fe7cad",
"0xa30cbfaf518996ba776b426a7068faad4ee49775db45565ebd327f9c679a45b4",
"0xd3e1a807f5940ee1a321b20b7931bef90515132ea9959df94e55529e05802cab",
"0x338aef579d9ec8acc1a0411c1674bcf213d03aa7d4bbc56707e081829ce30004",
"0x68c7a603089a220273f019001a39bfa9194590a6fa6d8ba960ddf4888b105a6b",
"0xd6a9d2c354e1dd77322800d24774eb03b589dd94bcdb3cc2b70437ed70411e6a",
"0x39c017c42ad571564792bf5741b3ae786ff0c24ebcb5ee46882ce0545b8a2262",
"0xf5caea6b23f4085c9f94c880d89b1c23eb69c03dc098b426143ae4b28969a2d8",
"0x959eebc05ff0dfae8c7e6699f069b38b5f2e5bc8c155bc35fc7f578d2d112993",
"0x199e90557d4d9e13c3e7a4b5b4ef6fe52cd2c724c36eaa44b7fa151efebbbeee",
"0x0bfe35d253227696e76f92ff13e4c545c57fca51186a16f687e76d2e6707d34f",
"0xadf8b7678f98b0e5009130d9d5d77add6e460b67b0529abc5315c44dadea0cb4",
"0x86582f3a98b218939aefd7eea438ee278d1faaf41920e8c72922c46fd56f1c32",
"0x001b728a4737fdd53cde20341fa0adec9aa8ab7c7c1db244fbd509a6c4f3f364",
"0x9207900bfdd6c87e2ba8498c0372706799604a207930eeb331580459d17f89cb",
"0xd2192fcf74cad70e6f7986a0b088de8658a14638a4c03d7ae616a88ceea00ba2",
"0xbf6f6b91742eebe70204eb7a70196ef636fc2db4d4c4f89cd5826fbf990a945d",
"0x5c1210951949402fe3b012577f1af0d3e285a0b39c3fe19c84f7930e003c06de",
"0xa16d57f777f94f032f7f2f75b2e25ebd11559effee98b39a5a1e7cc804cfbf06",
"0x1b9561fb8035ec6955454d6710f053d7ad3d8e0753aaac568ac3bc98f874465e",
"0x1a622da786425e0b65b9083a451a419c75e16908fa04d89ddc2c11d94ffe65a0",
"0xbfcb9b1d847eb40b6808e45bf3d2fb8f6588d6f103167be65f246d0733afd1f7",
"0x2317640589ab9d52e7f5e8dda95ff3b1beceacc5832341e9053b71209bfad07f",
"0xa10611b829dbb533e565ad01632b26b1fd642a4393e7fdd9b8f235f11bb606c8",
"0xe4ea4173982f342e396356b0bb0eb47e6748461ecce0f34dbe8fc084cf6a9fbc",
"0xd58399c0d0ae878338d2915eaf2d65f2d1e29eb8d551d254e68bce7a8235adcb",
"0xc0c8b73ffc675a207f73903c49d81131e6831e4c8e071b988ed9f2a5d2277024",
"0xe1ca77bafa66bb055c671978b3d1bd5df32f8e269330507f071afd627012b6af",
"0x67a1093cbddf41264009d1dbbc33fbc25a337339be0727e70c512b585897749c",
"0x0fd615782db5cf4c0a3686721cbc6245696c1bc9b403a9eaffae00968d2c8ece",
"0xc3c2dcaee8954ca86d9b3e4e98c4bb4f6b6bc183f9eb062016c5a25b2280717b",
"0x70265915f5ed94d589afafa3d0d0eab6310195cc690aa82bd65e4a488b398c58",
"0xde3fead8ce29c04a86dcb081da2cabda5366d28de5ebfe2f8064780413f71edf",
"0x0ae43394fcf6ebdabdcc1ede314fe779eb61a12eab807a9d3437d9167e2247e3",
"0x3241127e2c7fbb3db9fe0c602b0c94e22c684b7910ffcf09c1c443e567f95e4d",
"0xcb94ba286eeaa1129b490bb5891e603fd35e85c97c2132c1216d1774f9017f35",
"0xbf396cd23c29ef21fb535880ef621457fb71981f856f2a09c494cd005d38f981",
"0x3df0c90ed7aba260e820ca1d28ce1778149e163524e306309aa346bbadedcf2b",
"0x66a2724f7481aa3ab83a8f1bae2caef8a7bc607c7ffd5bbb1cf3766741db804f",
"0x7a0c3492f4022322e10d81bc10a5db9aceec81d1ab70cdffd31418b79d750fd2",
"0x96a826cb667924ed75ec708bf07cf4c7c05f84a0132e154b71eaf6e193590e87",
"0xcc7030fe617c318a31984d04e3d7f2ff2196894bc429f3f64bfd69b969dc9b56",
"0x3fa94aae223f5aeb593246f1a93d6d694b48946c09d879e791f1188a9dedc4c0",
"0xd49e51fc324fe58159575c0c24171f4eb1aaf58ed8e1311c3849538c8cec3ce1",
"0xc474123906eae5cd48a10e0d93fcbbd653f0c6d25275f827d4fac51e696c3d91",
"0xacd7b790a19026fa3f3b0a354878d4fcd79dc600f7ba5cedd2eefffe1ceda76c",
"0x41b311a188cd7ce1444d258dc379994b81a895226276c7bfe5e6cb29a5f92142",
"0xda0ae01db7f73f07fce46b94c24d6e400598378a6baf01123dd710c5425fb8c9",
"0xe62e08175a02b575e28b9e029a838c365e3ce4278f60c2d3b5d529768a4b47c4",
"0x99b804c8d0feda7f9df961527d634fb8b2d477a362e1d8158856885a13425fa9",
"0xe73597be8ef7d78f862c7a94a8ccff17f559816eba2f830821c6f6436898f9fb",
"0x36de9ee4c80853c865b16904cd8f6c0e9a99ff9e7bf05100bfbc76789cedd4d1",
"0xf480b762872373102393461ff3a21323a1df799c315fd167780a45d7bfaae84e",
"0x303b66babd21e72449cad413e04bdb0bc3ebcbb84a79dd30ed7c972c5341b82b",
"0xbf111684fbe44a973594f31cdee2c94e807bff9cf7584c22dcd609d8234f6e62",
"0x79b26cc3bbf49b6f25afbff7e97e4e45f2dcb359095fdbeb7fb7addee692afc3",
"0x2839d620cc140ba838ecba6e7e52db8cf7b5cd4cf4857f72f3bfbc9b1cf0fbd9",
"0x93074136f4eec367adcf27955d38efc0dc6da514693bfc97935c7871793e35ea",
"0x21f5af18a4cf0096b6e6a3d4c98f4043cfee5c4ee085ce106f86b713160144b8",
"0x90d16b403e2deca6cd5c80e52eba0b84b2875e1dfd75fffb1a2f82bc91eb6942",
"0x8a5cb6854c19a865f51e3ee9eaf8e843a97b272f6467634ba40e547a435ef624",
"0x9afe42a0dffca8ec063c83908fd6237d6130c9dfeab57078bdd02b6ac6d0ea07",
"0xa05cc6108b475d3e68e280e98f514cfb6df4f004e1b7708fcfd4528d346bea6b",
"0x71f10879b875caefab46669e8525b9c0487bbe3247e43a6cdb1dedbfb4d4ba33",
"0x7debdafd2b1410469fd76e2a39dcd1b8f400292f5359ecd39186a5be0f9e44b8",
"0x076f8741b668f3f715a7142f5c1592ffb58ca13e8612edc340619a1ca6ce3f2a",
"0xe312bb85cd945eb45f72868e6651633964f22ce3ffcbd0f3701bf57ac0c13edd",
"0xe6eae7aad7fed9c690a14eb7aa107c83a5e54736940ac6d82e251181e1103eae",
"0x794c8ade9063600442f83d4be14d7bbb191c692314253a2c62dcb33f3e7d28bd",
"0x6fd9db41dc1074a4349a6d3881757ad931bdf9ec261fc4e0a5ba9cfa5fafbf41",
"0x37557ead7100564651992a919949af3f39f3eacc03aa0ea158dd59abc4e2a93d",
"0x7a3b01cf210dfc42e4e41c95af1af357d15409fecae888abf4fa35149f44ed2e",
"0x89e952ed9afda8aa0ff80ceb90e5857dc7fc3cb6259ac6089da5fed49223cf42",
"0xf1ae8d3769142a1f3c8bc0ecf8454f05b09354a2ad5c921d0a6845417bc2f244",
"0xa04e022b2afd83a1e14d0d67595070b29f196dcfc05d92b2ce7c582d67af4a00",
"0xa3a0c85dfc3d8055a29de34492b3e231691bb6e9ca06684a205837ab9870c72e",
"0xee2529ad0af60748cc0bd8d97189d878643a52710dd200f79f27d8a4a4c8c093",
"0xac88fe07805a058f1341ed89795f0e5e9ace050de0742f863c1c9c63b17aed12",
"0x8fddc716ab43397541f6b22644949c6d7214b01ca8223310a34840df37c47746",
"0x3cbb4d1a2ea6fce170de64b1f4bbb8d9239fe191018b737e62eda77aeb7d0306",
"0x3807421ad84d6f2f9d5d830364a0455d6846e114b87cd08a3cb9a33e40c7c084",
"0x283199cbf0e1c997025bd36522619417d9e6184073b830fb22c3de106a68b598",
"0xcbc85a7ee2122abad27b1f5a07bd15d864af382a62fd552092b7feec4d2e4856",
"0x84586eae7108f2e1217d53be81f26bff7cc35409c64c1af827bb5263d813302f",
"0x5d2d93535aa7db5e2204e419ecf4d7c0647ce40522806bd24ecf348eb49a1f17",
"0x3a6118c84312f120c0d3e4ae4ec0b8103448da31953fa27a8400ed7e4875897e",
"0x4a0d1639274d31dc5d9eb49338b204e9cc9610913c0320e7da74a02ed2486fb6",
"0xa7770b7cf4f83c387344cff6ddd3441dd131333df0f210a57a271fc1a61f08f8",
"0x35066ce607eafc9bdd3386097a98c844bda683ce29faf25708b1a2f3e25c9aca",
"0x7068b1f5c017ff5b995f2c65db7daed3cd9fd0e658322ee2debbba7de3ebdd72",
"0xfbcf8cec0ed675d12ab4fab45754fd00a329d19ad77afe4413a0581bb6dab8dd",
"0x78035e412813b0a3f7e3f46bafe436b57b83278499fe8b8a1bdb3066f538d0b1",
"0x28bfbcd7eb38793a1ea711b6dd73c55da0faee3a9707c743737f0692dc6b56a1",
"0x9fb1607599329b61570a0daeb7b1a93210ac286e02a64ae309e1950cdd76c5e5",
"0x8903d98196291218a50fe03a5cd51592e1b458315491d735187cb39d0e21f397",
"0x97aa20d84821d36a44ce18eff501df95549c8266220ad612d0ba9d293d65271a",
"0x3245e35a2c6d46002dbf5bfedee31fd28a88409edbc55ee1ef7972a249b1cce2",
"0xd6149428168dbf78ab2f706f041a61e3074e3d18ed47bd343d54c3e4f2e051fe",
"0x9f4a04d0e3a2b8773a258bfcdee5242e44761aa1a1d2f9a7162f04a2b85de6c8",
"0x0162a3449c2be2a0a45a771027e5fb67169c5a56c4ef6f386093fa79f9942fce",
"0x5c1196a72f2c6fb5771e0390ef25499acd52c6aeeac3615ff17dcf2c405069ca",
"0x319097551b7df30bc67f5ee6f068cf3b34e71371b91635e9009af7acfe97e12d",
"0x8b89e2e091824d0c3276128543991cf7c35a82bed4b92b4e67aeb4652033a823",
"0x75d6dd431d5568625946b3578e68d47523518cb2e141369aee5273fb7cdc4013",
"0xc473b7b23c164759487af8c96865f0f3af3f3e40e9607665f94f937c3334f604",
"0x1f61783925fc03f3f5465f37aad2276c466ddb91a47db036f042c0b2edbbf643",
"0x3f6370976528cc31e4d099711329d5c670a2538623621b164d470fd7ee2cfb17",
"0x3705bd7548fcdeb0dbb3162394edb2adcd5128524eb837b71a04ff0c9c21c22b",
"0xe15e99e427efae16230af47e59ff89b76df25db44fa2dfe95d2419b6de35ee7a",
"0xbb4a17b5e4879b52e6a4838df9525ae01b168197db2910caea805011588559a7",
"0x60e6cc67da461bafef5c3b7e4f9e964a24c3146c4fc22c2e046301e457d1cdfc",
"0x72ef37234da6fe157e0e87b11528c3e41d115f10f1dcfce60e54d83c1406989a",
"0x63c3a73812427f73be785d4690a6ff81912d3ac17c8d76970ded284383ec97a2",
"0xf88c0457e00ec47c27ddc6d99fe6c0b82bf9249018a96b1c7e6b90e906adfaad",
"0x9258fa102e450844e091b58dfff2fd05b8fa099d53667626e340fda7ff7f9bd1",
"0x68adeaa1063528386db31407596442f815769731da8b560272ba3e1b8817a11a",
"0x222a41b6e681d2acf8a9fbd9310d34145a3c49160c29681b95c85176abadddf2",
"0x00745c4bb8cf5fb63700444f9258eb94e4b527ba8739fed4bbd7b13083854929",
"0xf27199044245d103b296bb81188982baa87175843b06424e0b5fe9dc6e005705",
"0xe00c3bfee8d71930faae9ca720f25f342ad166f438c07b0664c0c2d6b9f82c58",
"0x05e2bd6caee8a926c0f61bd0e5553b304656cf4749f54bb45b72d2a84fcf2378",
"0xcff8627a22e37d1087c3b858079a4f90a1fac65cd397dce26be8c3efe2515e1e",
"0x4885a5f8fb2e367a9edb32b02ad4390a4ef8f317a0e7d3bcfd5eccb9d8d05b1d",
"0x194638cb01699bfdb67b09ce5e2e8d5dbcfd403ae325a7a0311923ba5207c5b6",
"0x20e7c0ec1db7ca6adeeeb0c7950b7911e1627bb173425c4eaa105cfcc9c43db6",
"0x1010eb2f28d04da879c67f4c9e51fd480753081eac6123c5161502f3180764f0",
"0x09a0d0aac41a4e2fadb48c1751011fb46774f10ee263567d823e275aa0a33ec3",
"0xde190e4dde46d967a4e32ecfda15323c7f4081f40d5f245916055af44b008e81",
"0x21870402899f8c05003a175f2c0d37fdfb52c9bda3eea3ac8616c832fd8ac173",
"0xbec735492b66890aeb0ccb5611a84a908477269c2336e076c42cbb620cee8861",
"0xb9daeedd739766f82a95505a9e71daa503a5f0c3ee1a6a97f842b2ffb6ddc6ad",
"0x9f30d706fc86c7322a10a3c572df2ef4f2f49bcb49c5afc2c6299cf051e2e38f",
"0x9dc1d641fab155885db408328e60c06d97a0e3327b64a18d46e7ced7cacff446",
"0x252594a4da3cc4e794d954e88c15a2c847dd84d895eca06b9365a85a71fc46eb",
"0x979ea7682319cb0674066b10eb7919a87ad1ec0618ddb24723f13c55899cbb6c",
"0x570b4dce3b4613a8266688291f06bafa9d3b7828e3e6a9bfd27e7d2f3ba59125",
"0x39e97e3c20af2dcfa347ec193cae2c00100effd4f3987bfe21973db8c5e11fc5",
"0xf66b0859b41bf7dc53dd23762ecc593f4572a8a9f82b4c51257af1eda6344bcf",
"0xfc32a5b84537ed5947874eca72d189f74676855be5ded4d32eac2ebc0c3a3306",
"0xa89c577f12bedcc225cdfbf86ebe8112aef97b9c34a504dda52cea4f40f72be1",
"0x67e4b71c08fd93f1c37cc60826c5d8c18e14b89a7f271e0828b114de39aff694",
"0x342279789cd6a721f5f4866e3a16d19f88b24ac277563ec7b0716ecdf8dace3d",
"0x220a5babb290dc16440f4b01bc117c41af5073110b1375cae0317f9fd364d44c",
"0xbc1019eec10ff493e095915f66d46f0855b55aa681352774dc300d54147efb00",
"0xa9cc80ffc08c2b4c38fa178e3ac56ef982d0487b7139ed241fdda3894f4b67e2",
"0xb35267a4b6020a2e53e112f4ba7807ec50ba78a3b2d64fc3e3bfe918bb25bd9e",
"0xd5021c0c199dbb1b61e5e0d4bcd59fd064ddb6d6611421e57161f9c37fba91f0",
"0xea0af5bbcc015b06951c9ff3df3c233f4bdd6ef8eab97f0b3a9e10b01efd7a5a",
"0xc060f20f45851e6de2fe1dcb6d8996add5335c34892f84a1db711d0c47c5da4a",
"0xbd30199b078305b459565598fea6740a4d187e4813d3887f72d7958ebcc8da48",
"0xeafa07e96737a0e53ee7a09bc1b394ae4c1ec6c937901a8066b0cb6b6908aff5",
"0x68abed404e0a66ded23d152fc5544b14b0a4fe918a51b667f2dc827575c12136",
"0x27da4b5111565097dba6e6dade4f0275ea8234b50f391aa270bb3cfb361e6331",
"0x85126b95e3532b5045710f60d0aa3f6b0e801130722bc7d85a67479e0b1fba25",
"0x658afe5a3d3b0916372785f952d92069045b747fc67be6c8bce3d695a434d058",
"0x9017ad7725867d37402da5ef1727289abcdf9982a0c7dbd7fa6f175ef8ff5f90",
"0x892a34192371a1de6d4c2ceabeff5aa9e26c3f41e74260d305872f366bdb73d1",
"0x786a848c13f84c87ca554654f0ab35f7fea5014669d919595e087e6463c47253",
"0xf1235641dd0ac33ed19e39ee58e282f2e0dd8edc0949e0510f2c65469d85e1ef",
"0xa55273939373f7a4052d8bc36501fe17d9b571fd170041ada7b4385d49ecb5e6",
"0x79ba81c39c2e7dad9768cdbf754242dc2b5b74fde750c32ee153ab121a633406",
"0x74ef128355bdc842c1b109d4b1d3dc6f85a21a110b32fe1b4ce71cd282a20ba5",
"0xf0a05137693ab9dae7624cbf4abce1554d4921014cda61584d649c66e9eb09f0",
"0x5566a8d7495aae3cb42e66bcc683bb194f53894e3281812484bf36da583b7d9a",
"0xbe65f10ed3eb5e862850eb4e30c73172f5417634b087b1dece7df97dda2857c9",
"0x5ad40161397a2d0f53d71284d878e711b6d73930d2a79a789e4bf08223e9eeb9",
"0x1a88c4e12ba89abf67c8f8de223964e4f3d0ee8951b9a1851c9172b278b956e8",
"0xc1bae22721de65936975b20b01380c7707cb603622106a166c1472bdcaaaf94b",
"0x68106522840c17b0e93b0cacfdbb1d2c5b219cb90aa61a5d0b04a0291caa4b82",
"0x0e8a214b18b92fc025bd374a8d9859244b3855a7d3a364d1a0e092546a17b2b0",
"0x584294fe2fc330adfcbbaf251480f2c727da2d38ce54ffcc1b363adb9c0fdb0a",
"0xb86b9042acd8d6dd4eaa967b3dce6e4e49cbad95f4a7cfea95299da0cb3aecab",
"0x99d4f215dabbe6bcd894d4ce7ee6d16a4543c38d9ab19a4f3b933f37eaa7fa5f",
"0xd078bfda23ecf966b656aabf0bb69d27902d33773b2471145268426846a5a1b8",
"0x87234af13d71e681c987c38fcc3661889b406e298e3a1ffbd5115fe6fe6e65c8",
"0xb9f78fdabc8cd4fbb08fd1e1d00ed552c4bc7cba0672ce91c52deb2834a7b223",
"0x76704df0766b51c9327acf08ffd35fb9c3f041b73808094b0d4ae1f7e7d7d0b8",
"0xb5e4ec16c993e2ade6e951099512deb2f8fd07956e4d97dfc639a7eeef96d336",
"0xc9c919862f5a82a5381e7def2883049fbbb99f24be9902152323811e32db40bc",
"0x8df21edd784b8b776ffd603a6da87a6602e6424cb3905d977b909a7b10160abe",
"0xd5c524bf24c3c8f2e9cccd5aff20b96fbb8f2045f37ef1014eeea1b82787361f",
"0xb64756c799db5e1eca16416cb833605916a9bbbcb3c82a54def34f16e6fcfdaa",
"0xfac273bab2facbfc28e2c53c03a44e69ddadfbf57b08499bb43855abae456f1c",
"0x43f8990cdc4735bc47fd89cd23c9a99d5453885b1903d4b3185b6b0413735ff6",
"0x7420a69d819df5f4106fc9e315e8c125c8876a3a1cae8ef7198a921c121792ec",
"0x696861af19fa56f07d5e2eacffa3508cc3638b7acfe4789c002929dfdc47fc3a",
"0x86c80d2150fca01803a41a900e66b764ce82af2e0ec19fde53971afbb6390ead",
"0x9cf14af73b44b555ceec13119567723ae8e8af927a6f24846635ff5000acfec6",
"0x95b50e682e4b6b2a08606a62bce427682ce484c2056d891dc206fae9e062d3f0",
"0x789755e975f432a059cb5cbeb067c8f9dfd97b54d8d1a45a1e47592d9eb770d6",
"0x87b682b780890ad3d542c76548d7d5287fb244291d62619ed079340293a245d6",
"0x8c0155b066048d9e95f5eb1b6ecfcc179feb71ee0426301b03f778573eeee7a7",
"0x0fe45f09ef25d05e5c42751a35714af86a5d7a4fa235956edaa36dd0e5ea7533",
"0x3b5ee72615fcc04f48cec067ba2d1d9bc0e64c4cdf9d5bcf97c1a999ae940245",
"0xcf773973676c9b0e31a549d78a6bbc79826c471b6fed42078d9b35a08d1d28a0",
"0xd5ecadc4dba308c0d790adea1e118d6984716600091d341276311631acfbb267",
"0xf344c0cf6516f0fa6617e48076726aefbdaaf5a31f67ad8199bc3f6e426bf904",
"0x3f3d2d33f36ba9009e9a72f3f5bbcb5df5392a19fc7afc8d37823aaf52b03477",
"0x346a89411f090d559ff90e670bf0a385b1b09f117fc9ffa18b09d3b6d5d8e45c",
"0x5bc5689e2b4572b8ceea472cc7827e22cbfd018920beebf5c5b25f65f5cd5357"
]
},
"nodes": [

View File

@ -19,7 +19,7 @@
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
]
},
"validateScoreTransition": 1000000,
"validateScoreTransition": 4301764,
"validateStepTransition": 1500000,
"maximumUncleCountTransition": 5067000,
"maximumUncleCount": 0
@ -56,8 +56,8 @@
"gasLimit": "0x5B8D80"
},
"hardcodedSync": {
"header": "f9023ea070413bfe3ceb9160c7dee87bf060a0cc5e324f7c539cfce4e78802ff805063b6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e4a10650e5a6d6001c38ff8e64f97016a1645ca0f8ac12c30b4fd0d27a1a50c090659014574b554ba6e9cdb76f57efbcfbd390a9a0b474ac6cc4673c17c5f511a8b43cc44dbb01bb028735830163667d7a3a2582b9a0bcd44b7c04fa24760df7d733ca8ecd99e8da89de0716e6017fffa434bfd7519ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd83755801837a11f88301d8de845b27471c96d583010b038650617269747986312e32362e31826c698416c9d1c7b8418bc805f23fb01fdd498b37df5519f49691d65160fe6a6794b8106e2ecc4782407f0dae3a512546b7d93e89bbb2a761c750553deeea1f9401231f56ae0ccb059201",
"totalDifficulty": "2566410291882451733317698215999610733750372193",
"header": "f9023ea00861b3771ffb84fce48b8ba3c54a09f81e91ccb38c401261f06d370098889a43a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e6d2b931f55a3f1701c7389d592a7778897879a071cc81d58cdd21d1e17f7389e55c530cd9f94cc15bb32af6477320682327dcffa06090021a7c09ae5e75e443410ebdb76de04f1eafb0ab910daae96ee6eec560eaa032510bf257dd03b11f3b4761b94b495a5b5a18cd6eb17c77785e0f46e2ffc882b901000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd8381e001837a12008306697a845b83bd6096d583010b068650617269747986312e32372e30826c698416e0ef58b841117e2088e2835bf2afcd5d48f42b3bf2a1f33435f21f089ead2a6bae7d01c1486e645b460bb3c726a827ff1eb50e0579f3410563bae090fc256cf1d8d594b82100",
"totalDifficulty": "2845866505151538604560067685603735513869853136",
"CHTs": [
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
@ -3813,7 +3813,408 @@
"0x5d71aff2a12d4f1d05c7f760d07b417a39eb0eaa72a01333befc6a2eb6b7d72a",
"0x8dd7de9195d2852aeb6812638ba22e73ff5ca0a8ad921c6e924cae1dd5952255",
"0x8f1828b4cdc6c38c112b1ffee7790953112dd2225ec82581a5095e5ae4d71cae",
"0xfeac88ae6c8529e87a55a259f475b7d162d01e8fa5f36c90d4665dd6105b1743"
"0xfeac88ae6c8529e87a55a259f475b7d162d01e8fa5f36c90d4665dd6105b1743",
"0x2e37011bd97c6e8a24e130fdc2c60c39b14ab3eb426a4f654bf3158a19aca88b",
"0xdb59b565de21902c50e2e204374ae1ce487656eb74145c103a86707b45a63eaf",
"0xf75c26a7214acf2d050ff5c7cc8b76e1a90540410b5c8b2bc9edbfe8fb2268e6",
"0x6ca7554f2abfd22951bec80f9d280abb6f060dde4a9a829ff7a0457d67a99edd",
"0x0324bceb8b61fa7092396764d7e1933697806c6d785446e3bbab3fc3be0ab259",
"0xeb4880f177e3e673f8ee04be1451a38bd8a2c0bac681d82a19327ae2d9769d32",
"0xec6a868cd9fba9e4f5b0d4276f44aee71056fbb7f425f717d0ce9d1fa5442ded",
"0xdc12b36d165eae197487ec930e35489545d2867b6fb9f8604d279337b6a8f949",
"0xcf1241b1c9b054df34638e99447bb0359aa01ad13c38650b872f2d727e6f68f6",
"0x713765e9b76c73c2de58c480600a7125972246fdcce2324993cd6bbe49cce67f",
"0x81e096e97dd8bf1d206d0ed41c9feaad24d344323ff74707112ee8fac218994e",
"0x8943c2246d5ae3e8db5fc012e9613642c6b713e5f2a89d00f09fa73246f88d5f",
"0x5b2d0bcbd893fab4e58d4ef698d1e8d3001799b61e758b7711f319e2b8eaa645",
"0xf3e4da2cf4579f52b7e4d632d93b79714487ef179a8f5d5c46af9154efad20fd",
"0xa2348ea2cd7a5a32779e9d292a9428fa475fae790f08e42f7699ef5eb2489188",
"0x62dd923966e02db7d0d27cfdd4aeac081f9827288c8b54d9f19035331a109f53",
"0xaa1aafa8f9d9d3e0668eff761fbfc2657d1e1906c077d93200ec000643c6c272",
"0xbf40cb21561989004434d6d908451d5b63045c89c2ac9b1eb617ec0054dc18be",
"0xdae53edbb07fe84623451da0e25da631ad3465e5bc12ef8fd8323c8a72f57130",
"0x685115b38f307f984c7c90e85d167d62b0ec2c924a0bca5f23b1cac12a8f72fa",
"0x2ad7e8f86c872504d7c2c48b0db141955d770acc84222fd725ffbd2dc4095b1d",
"0x9268b3b175aa6025b959b8fcdb416c39dd339e6f1fde3c427bd1bada36e4384c",
"0x502ee814cecc8454abb95591b0d07ed5170db94af7fda8878b9b4287fd68c9f8",
"0x6b19baf6b7eae36c0b1d2754645ff282fc2905802ca6394ac00bc22eb1582eb9",
"0xecad17ae39f897ab38850cac40480b4fafcafd6624f8fdfcaa69849f3fa101ec",
"0xb0804719b391b4b5f554a49f99df3a9d1c3a9884cefc268dcb27e3821aebe385",
"0x3018401c9a31f97881852c1bd65a964bfd3011659725c849a8de4b5ad8f26490",
"0x48a6b687e62a42dc44ecb56f4187e293d6f87d328b1edf409c8f2fa6568dfddc",
"0x8e3bc1ec926a68e22ed525485186a4d9160a54bd3e80107bb77c09911564effa",
"0xd7a7cce632e1746120476a3271ea09689380eb833d5538310fa0029f9174e0de",
"0x7bae074c51f3b547568d18e85b73fcb9b5f8040ed5f96f3523f53197150517a4",
"0x9ba39f376b9444dab04e0a52e4728ec842a0aa4880d9aa9819de3f0694f46e60",
"0x40a2b84bd3d05d28d51a39deae5f23b4f7370c70ac70d1cc81224eac4939d69f",
"0x2b9f57c8c43284ba929df8f896a966afbdd341f145b6b2b2fa98382950ad915d",
"0xcaf3d2a336cf17c9b2d7116a14e654bcece012b07bc020ac30feb71d7f6cead1",
"0xd3b68cf2337ca26a9c4bf6b6b286dc65bf66641d5e9c241f4c1b147994253ac5",
"0xefc11a5944a8061c87f274515e810fee13f4c350c625a988c27ed276b6c55b6d",
"0x7a93732151f7145059424aa823b24e26341cfa57f612e6de3bddbe23562ae918",
"0x2594b625d0f5ed52425ccda4e7898a8a554300791027af6f3a19239a15868ea8",
"0x1db00091145b1b0830983b5eaa5cd3d0e4ad71c09d1b2dc20c47815bc2de5917",
"0x60563bce11f028691cf78da7326f22a4ab01d980020e61bcf2e4bdb5912b7b1d",
"0xe6515bdf1f22469a4218f54791d12698d1bc555b3e54b04cf46b10effa8ce74c",
"0x990831a56958a6bf131697e2f35ab2a45fa228eb7435c7e65814ba28778d513f",
"0x1b6e4085f0e291a8ee4d7e90158dcf15702b4e6e634d1d3bb5c4bab11bf70068",
"0xd0d4a6061bcab0f8e645ea16b285eee7f2ff84c7765d7543aa318edbced2408d",
"0x2da1a609eb1b572a47f187dd5a1e9f4cb1e1885c841f91ca82137e01a9eb4288",
"0x1293686df427f9ee1c2116000735642b3d09511cf2889dde21e1bee427d8c273",
"0x8a990d66370eaab3a46d9e4fa9b7d0c621020cd3b897d9e5b3e5fea6a6979f3c",
"0x10030534d5a06bce47d72998ad4c042f5e445a505920723d14b1d93a3a23af82",
"0xf29a399e8879386e4c2bd8e873dc8aed612cfa8dfa9e5b56f9c51d4c4d1774ad",
"0xb252062ccbb11c3181338d9912ed0d4dabcfa4d61860c211f2f702a641fe936e",
"0x822c7abd11b80c862bd67d39e16a208c8462936ca86b5cd5dd20c51d35cbfbb1",
"0x6b62aea651f1407f94906db704a364f70d827e0efba981a8515d1f515a46b266",
"0xa57b7661c0471cbd7eb35becdf468622df8338a48a075b722ebc5550bbf6b9ae",
"0xefc593d38afead5ee1fea5d8b41a52bd2a5b5a059774d0b951bb7eadaa41a46a",
"0xa556e684c26e7fd6f902b82ecdf721fc292c35e0d2240c1f362c4861c366c4c6",
"0xc9f274efc308d1e97ba9b59c92735d1ab2a72d033ed02a543dab301610e96e33",
"0xd7b43559126f88c59392fc54e2b416d2a67014abce12ddf61764df989a897bd3",
"0xc860842132de3d8c1d0ba2cdc0a7c2853ee568789f1190738862667e3539a958",
"0x2f330354084635eb507cd54549ab89fecc41886d295b1d8c91efd8ca27fe4f7d",
"0xda6edc97997b9cea1bc90662c6a8180fa03cef6189e09c86f36adb91400abe74",
"0x0d2853b5a3f02ae9e4a1c5a0534a5329d2e877d4d77f60dddb36b84b4fdf7e2f",
"0xf048b5acc9e9191ce0ab8c390bfe03d89cbed91db5b9e7c7452b01bf56bcf5ac",
"0x30fb6f6093bf59794d37ddf850c315dd9491a4cf5df378b4468dca96acf78e77",
"0xa04eeaa9d1d767c0f93553af3a259390a9576e8b6015ffa8f0e4fdf37f41f28e",
"0x02411cd53ac55407e0d31520a8c3274a2f4d1fbb2541bb140f30f25843c76860",
"0x65bc790d632d5fe2446c65325df875ba59af3c3aa7357bbbbf47c7e5f7663a7d",
"0x5f364562fed351d932eff956c3ac489ea51ad2cb12a81bd8db4fe0b76e3cbb92",
"0x104f7070d5da1aca5c8b20a96d36638e4b5f8be4e86be83f0aed7234fcece445",
"0xb2fc7a73d8d859d531e51532928671ea59ae6538d4572fd5c2d76c70920aff7f",
"0x7ebecf446825dd0010fbf47afce8b9c3b3901c839ec46269eb8744bd799699ca",
"0xc64002b5a70f18b7c51ea3d3f5246fe8db16781e146d777aaa12f3b765d108e9",
"0x9d136068c7002d2780abfefcaedc79424d3e89b17718ec369d9e64ab7b63a81f",
"0x7b9819e62e92dcead89329bcb3f1a1d6bd10794d1a22d30c3d0369a264029543",
"0x8a8c9e66f343d09d5b7897c491c851143ca4f337ddcb5c2b1462b150e22c6f47",
"0x9d86faa1a5d355d6071e09c8cca50e2dd7e7dc117c2e4f6c0136a2789e84aa8b",
"0x234e156c10a80422ca1aafd49d614e02b698a0d89a7080f87db5dd5169b419bf",
"0xafbb572b8d9119ba8126fdd5a593663db3a3e6165a60f1f439902a6321a8d243",
"0xcbfeb8af8c93b11eaddb05df2f2a8772da694f9cc16878d3154d0857f17274ae",
"0x7253cf6bd2b4d158c2bd60acf5fda9dff6cbc6468ca9b549efcd824410d2e719",
"0x67fa14af20fe738ec5c9414401149a1f198207969768a5b982454146ef720b85",
"0x6c0ddef53c7d58839c3013f2accb72190b7dcc52fbe5d71f4a20f849dd72725f",
"0x89e77c0dd9fcb4b4d4d10c25903ff5b905f5d64b6bed9a0736e9dc2035ade3eb",
"0x42466344821fc29dcdb5fe7dcbda00b3779736ca90f87ca1802207f61633877b",
"0x6e2303e8ed41e6d39488c57dff8d50c548a7079a26c3fb86d925c0aca5b8f67b",
"0xb8a14969606442bd94048f2b2dc7b87662d801097537f51c8eb8f026c52f1fe9",
"0xd7ee25e0bfd080d89c475942575fa055ce5ae268a6f01b916b399f6ff7e94a39",
"0xaf5e7da13dc0ab08ba5185074657acaa2ce753a20a364f3a97d230c247bc8d1c",
"0x92f9106bc9ccbb4e0b4c0d1b96c5bf347d856884eca91a0bcf29e896789fd9c2",
"0x4bc12bfadacd6af0737646b813b1a4a9c005e97ef4b090bb74b7475b50c85dfe",
"0x91e4ef72d0bdef33e2e2c8acbdd7926182568f559397bfc086b96979e7c4f53b",
"0xb2f57e050021b238e0b47b0b46a641644645db5bbd987e8d957038655d1fa83a",
"0xaf221401f4cfa3db7879237b40c68300060df9f65dbf68bb02694837eaa8af7a",
"0x2dd280e98a0d6bc950b7f3f0bd11a9e74105d4d15463184a3f8c03d40f3193ef",
"0x2538560e5b802a89a021685f994acbdb3181f25d0cae17160aedfc619ca2954b",
"0x133cfa3f5d6a00f7392a6b0c6a97a9ba10ec50b24cfbbe6028995258cbaa065e",
"0xc120807872f07adeb144905ff323ea79880389a2815f8441befbfa82835555b2",
"0xa2c5c5a3cbf6db506dfc13285b07c24ca7e70d9e75d80fe711c3082ba119d77a",
"0x837622b7bbb8bb18b3d42058426ef97e3fbc2842d2b64b339733b52313557562",
"0x29eda2468556699747beef75f015e6772980056cf367b819d05a4822b7d54712",
"0xc6ec29323368dc29a1d4c3c11e945ef7fdb56db78808c4c9688ab5f9eb7f27cd",
"0x44b368ab63e1fe0e0da031a4e6628ed1a4fc69fa4083cc056dd9443400be3326",
"0xf153dbc5fc03a89e80d2808ecd45e9fe6453d112508d32ffc6305d5a577d14d8",
"0x32452c0d51df7a85eac3edec46bbfe376c971ac4df4512d7e050e6fa711373ca",
"0x70cb25f3d60126cf0104a40b2a49b44ef8a42f60b93f929594938ac00647b639",
"0xed63fb33d707b93e45e958d5d5f9d3f0898c3676e43eeca55c788cbb2df3170d",
"0x93ff103a026350b0e9c2b30c36e079145892e8e3756678e8ae4b0065fb6a04ec",
"0xa466cdf6063bfe155ed75c115484ce113227385eff2cdc07dd90405239842f3f",
"0x2883c296d9ce6b1e6e7b4f471e841437603ecbb867570cbc46d86f0f26871600",
"0xea5e5b84183a3a709a51c1c6f3e7b039c4663d7495b9bdcfbd4ecb0a95ea994c",
"0xc0e97318bd3ee2957c09d6acedac77ce6b219608e5dd63ef512aa08d63c3a114",
"0xd3ccc7fcd24076afdf6249f671de402b515a131913df2da17118be47b3720b33",
"0x4f5be5a6edd66ec496207b33cefd00722f3167b9e6f2a44d9613c4c7d6541aba",
"0xfecdd1844517d0523a7b45d7b51769728902b881b7fc308f486e850c870eef5b",
"0x01a22dea1d0e25885e0a03e56489bcaf6747e712ceb5a42c74430fa6ffcc1c21",
"0x06cc521a05ce856dc55041b90dc4bbafffee578c1c315b5cfa4cc2d1ccba891f",
"0xac21d4b08fbf2891e0b3645b870695434fe703101f74e7fcf0d0e1304ce65b54",
"0xd62584c47aa1d8554cc08cf675bed128e541df54900fbfae958877595ad168ff",
"0xd8f1806ddaee8e729218fea1911efc5e663666ffb3acad4a2fda3757700d6d88",
"0x9dab2acfe01506a185276145deeecdb5c8fe0937feacffd40fb25a83e8eecc72",
"0xf0b74c6b1a441fc2ee8b2f25d2f03307164014d42a0784683a9d6cb7d2179064",
"0x7d590f0bcc891e30996adf8583803a9dd1271442c3f0e69502addbd371437767",
"0x3a66601fff95b0aa0d0660c12788ad56d2383cae290ceb2fb9ff41794abbc55a",
"0x36e94b03402f18c689f5234973ce1e626a82aac085dbdd682b51cce21f8c1872",
"0x00abd1d34c7e55f58681866558cb844c11faa55e8cac70ede75811f55341cfde",
"0x9983fc20e63e77ec0680522035b03167403681674ec62293cd6b7fe360c69157",
"0xe98b658fb8b6b7fba7463562f86348bf1e3534bc9148e8559423b3ee5ab68472",
"0x77ea189d3a408a8c5b1792881d93ba7a471f90a976ed334cfbdf865ff94cf20f",
"0xfbe2fb93b3ecb384679870205f2be2f47140f8d832f841ba8653e00d68056c82",
"0x330f5f04314ae57097db5258d861b993cbdc2ca0522421917463b94636a99d1b",
"0xa59cbefffd0e1cff04bd4004d21fbb64c4ca542b98220487ccc79a39a6a0fba8",
"0xe08f21b0f5ab216c1009c904939515d0ef8d8ca80f8c3cd5465944bb6550e728",
"0x37f1db42a7e99ea8b6d7f9ec5bfb39f9613cf79d98345816533b85726c64dab8",
"0x8c226434c5115b7ac0f894d8c4389a1e38a3118fa0993b59a42291286b85bd7e",
"0xa9977dc362eba9d32d13188dffa6cd0178e0b8c29cc24a3c04cd6cb0781fc133",
"0x502a68fcd1c187d662ff6852179d7602b04b5ec3141ffb39841b571bbc6cce25",
"0x09a716a32626ad3443d7f5f6e5fce5145e8b962a531464e36aae6356ae93b15f",
"0x2c165daaf0e8a4433d8bf97091bb573f1a7cbc7e82f2af353af9c580fbffa8c6",
"0xd8b47ed7ed3bb85bf44ac2b5e5916bbb282353f71dea6e172434f05cb1276c4b",
"0x2bff102b5209c88370b2deaf941653c364a90b39a6c3402336b8b3c9b47731a9",
"0xf6011e416be00e243d9b6b57df1bec2458d271b2a8a964292521f6f8bc7355de",
"0x8f4a6d08359aa81c14391d8483bb8e621c24bac1e32b2c5c505d5617487bd06d",
"0xd2f89aa90547e1956491879dd5924a50142d76460532f00423cfe70f36546873",
"0x929b13fbde5275f999f145a273219d6f7f4c25ac29b4eab3f89d68305e7f4341",
"0x1e7e79d55594c3555eb7d90e4b5bcc8b59ecd98848884b81ac5c2d53bebd5cbb",
"0x11c2705c4a89fa9187f63dfc7a8bd4e2c087d6e937e777393f1e2856f6f00104",
"0x294b40af144ac5046bd2a5451d1cc9900858e0e351f3f78b50b2dbc203111600",
"0x26432c2ba81f919c085a4d2326c22bac341c17f456d8a93a1971c0fd741ea79a",
"0xc488baa35e04ed6bf20753fcf856f31a98c00be65d51b73c6a5490d18fb89d71",
"0x915e1768627ebbee21159a0562d8a5df69b05f057fdc8b4bb69bcadaeadf2ae6",
"0x2303b2be6801e3fe8c02c0d0355069240da4f617b47a4ce6bbfaaae56a1e0915",
"0x0e4af9d5e2cab6a62d9203979db08996bd1f111a315049859e2093e83e465262",
"0xe54756890992736382616fceb3999d22ae462b9b5f8b1da072277da2df6b5f4b",
"0xb5aa407d54e2ea651563333d3d330af0cf45a992bf89db0c229962454c4da4cf",
"0x88832a6db2c8c3d899dc59154ca323c08c5eaa8c05d142978490246e7b4ba7ad",
"0xdca9619220c991618eca5cb18b1c14c6fe4167614a8360c9e1737c93a129e714",
"0x3fad9a66462792be9f771b39b6f64e537683a74441b85b53f9c5e6a2fb687100",
"0x6dc5466ae00317d52511d9e153ffa37cb6060639a010c8db25b33aed702b486e",
"0x2a2ca3148598d3106bae23b6f66a24e3e93afeb576d283ba6822220780008e95",
"0x480f699ec76a16530e382c2e8d91c7edd3ec0d393ccdeb28c7d692eb52b0af96",
"0x082d3f5dcff2a41e2fad715d64eef361271648bd976d895b40765089c544b65e",
"0xed14dc5ed74dfdda8b45dfcfe99e8581767cac57505805a4945b79e2110bf92c",
"0x6890d1a6c90f5c1020ea4439957ea54df3cc22f14e22047f63c9a93696210b95",
"0x55ae4e30fc02206a0f389e03c0ef5b1409f8fe34d6a5dbd5487af608e3b82369",
"0xa709e308a7899591337d59ea459098364c1d6638202047583851acc5e6df5017",
"0xaed8371c95bccbe53effffee29f40a3e9656bc95cceefa364f7191415dbe15bd",
"0xa7450bb8e1ff3c7b53bada0cb8ae783e561a3ef74cd3be0d19cb9ac5ae807aea",
"0x9fdebd0ae46437e3421d7f0a95a76f47b34f0e0eda37d69c078ef5b44411c027",
"0xa18a165a98307fb994401171c41e375a4637fcf2beeaec8c18fd24304b068570",
"0x930f3cd1edb90c020c19a6f6a8b86c86981c3ebb8fc19073f09c345fa4b0ea6e",
"0xe4c0549658dbbf4f541c60606c8b85dba190f58e5af0bcfbed101e0ff4a8f455",
"0xcfd5428494534819ee14e002c69987fc54207917e83a2b6e97a1e1b801a5d939",
"0x0cc3a6a2a5de66f64f5491908b5585eb3464fda42c7a58a9100a8cd0ce763b04",
"0xcf635d0b4522c64a9b00902770ae33b618580983bb32b94134a69ca8f6c6258f",
"0x2cf5c41cf911dff328ef15253a7419733a104cf9cd1846af43d5fdcd914b321c",
"0x6d4ea125dbf83b8a9dcba40c4a81673a365ce81dd8eb1fc10510ee7e80a40b1f",
"0x9c68f243fdf1738f9218c30664318278afa8f461c13bf5e1bf30133d3fa6347e",
"0x62aa880648363c1f3b5bbba3e73dc58566870ddbde0911c5e11aca003a13b525",
"0x286a2b6f2e35c2a6900a02d37d82263dc55a3c40d6c40488258af61f8cb8b589",
"0x296136ec9fba18ad43a5435acbc3006e52a182aea1e3eb005f25ceaafde2d0de",
"0x9ebd2127fa6f5f43a03fcad8dea37bde3893f627b48e63b9e2c6e33af811a95a",
"0xe8e58e2b6fe45ba1881eef4ec1e1d954e12793ee68060d50b9c9502009725317",
"0xf831613def863279307f637be60e9608179e9a148557585034d20816ed7d5553",
"0x9ac311437bfcaa1c66e1c32fa18f8964ca9d9ffe3cb3be306b64519b35051e48",
"0x931a4862f94054ec0f96037a225f1c3421ef99d8e4a8f774407cf913273bf4ec",
"0x07dead0442ebccefbadb2859e0f462fe8d3e6677c7fd04b0f35165ceb017c171",
"0xc4afb80e1dcb56ab83d5b20475d2212b6c55ab63fee058a914661657d2b1187e",
"0xe198b8ed96c1b7dcefab5197036f1e5789ea6622dcca2d817e63537b00710b6f",
"0x728b8b91918a059e3f46ec7658bc5948016f76ec200d91ec3a163bad8ad6bfd6",
"0xacdebce23301e49e068c83a73ad8484d8af7a0c28d066e62787542e154b42559",
"0x7f66807da0c2b155126b1d3a69488b10de7f0ca38f6cfe6fa670dce511a1f667",
"0xabf510ce1a016b5b3d4610b3cc5c9dec43a6a66f3555a70e1c16cd451e8894c6",
"0x56ee11eb3233fefdc056827fccbea1ff2be8a3f460038eef68a1c730bc1104cf",
"0xbc4df43d4acd0fc2cea064abc5b5d1754b29073533652448d44c09adc1d32998",
"0xf61b97d2d1e537a6d20438f4729bb59ffc8db6b7375c6e710b4be9e136f1e19d",
"0xf89f04d5cde25522103d1e175d68dfb4955b4519a5c2cda1a041298579174be1",
"0x702c60e25d6a10ac9657553e376f2385cc94737ee292a3ae671ec02af982ad84",
"0x5194589410d5f02de764bba1c25da027861793270c956c56e67e017d89323799",
"0xc448a3b8bb1b6efed04d84f82d63aa0c7ca19d3cbf817efe4db82b897ad6a019",
"0xdee875d8c517db5cf20b745be7ea1d389612e47880657d003c6bfcfdbc8a6303",
"0x0528ce8bc52f4878268be5e00b5028c9af85cf61a6279e75240e2adf7b498ac2",
"0x6cc80f5c62a1510d9cc97ca8b4c6245938ddbefce782635dde0ca2516932fa21",
"0x184f9e305ce4fa0bdb47ad00bc7d10691bfbd7cb13b9c9d4d82c37678e8df080",
"0x69456f4aae64f57b3709d6c6701a1894802a4db96374da6b979b87aeaa5e301e",
"0x60d1bd0acd9013472acc0b8ce0b90a088f35d5c19645146ed8b3c6330ec92052",
"0x09f87c83c6be698b2eff45ffbeef79254e5ff8d3534831c79346e5b837110c1d",
"0xc5fc2dab2c43c27132f31a915423a6d6a30a560e4aa266483ef2ef1ac48d0fba",
"0x87a147b03150b429b0c86569db27ecde32c1bb9a48b1ea4426d8dfb895339673",
"0x1a68fd5e6efa8e5183843fad88d6445fe8b07c01b884f30563ce527e6b10749d",
"0x4123e02f2c2869bfd99f3138aac82bcf1923260ac28f33bc4ff2dfcd54c48e4b",
"0x452345c2de5fb18422b4327a79053cfff33f277f0e3fc69bf2073d0bda4dfb74",
"0x830eb26c402a88c6281b0a48a93ab16a64a8e4244f87d589b471a3ceb4577f6a",
"0x84445f1f8805d911009a3e55ebda5e12ff347e5a34d0028ca44a2a26846ba903",
"0xf91a600ecc8aa47f838a8d877487c15babc10ff97a5be8bbe4c3eb705fb04dc5",
"0x01e749439d413c66340934dce9d4c55179375208069fefbf89aef7c3c7f02bb8",
"0xacfb6917a7365046ccbad1ca8fdaccf8164c216ba8d96cf64af5340ee3aec2c7",
"0xa1c20a4bb21a0a99f3a38818c05a3ba66e8321f24dcc7ab26487810be8211dbc",
"0x7c88ea06f3c8cab9ac0b29376f53fff4b56672a1704520fbe8de0e3ca0bf8acc",
"0xc19e59ef2361963b94bb211b8f6c172670ed83fce3d54b3e00d1a82f292d1d2f",
"0x386ebf9ab1a551ddaf599d9384e70a34a961ec55d5f609c088c6fdbf38add80f",
"0x8a635842c7d38cb2bae11ebe3f6ec09e2d41ef6b7093e4ea8cbf079df97f06e8",
"0x2d12afbf38c0378d287693cc7fd49f3e068d454ac5ea7bc76f6b3e505bb09f27",
"0x33b7eb72362caff0e54cd853549bc4a802345d774856558a8b128e494ec63948",
"0x31eef3a0c2c9f586ad2305d8ed9831619ad6ce2aee9a16800cf4aa048b1d593d",
"0xfbeb707dd62204a0f3a06ef9046fba5b3b88fff3a38b5b08cc3213f5965c69c8",
"0xc8913325245c39d0609c6af407354e9d309c5d582c8957a90c86c944d2f5c6aa",
"0xbedd0ccdb57b01e688c14d6230aa84f5912cf13a72839f654eede63ca05ff52e",
"0x0b0b7435e02cbc3654eabd042c32409f4e178cb60f5e306ba041c985378cc286",
"0x749b3fade2cbe924b3d76f2b9e216c1675e8687bf7ede81b090ea36a4468871a",
"0x9a59125cd56262bf0b6d2393be4ba8f769b9d5a53b644a0700c9905dc4d91c14",
"0xdd2001f6cbcaf2d29a7d022e6f723e4691390f56ed6a599cb58bee74c64c67a7",
"0x05870eb07cf5d1c1013fedd8cbab73b7341e930a0c02e2dfe898d5299981e34d",
"0xef78e2f60d74c818cbf8996913c08a7c5abedb3f0f7ca412737c071cd6a38ccc",
"0x636a6d39d02bc22c139d9e203b1ae8b2dc485cb596641ba6e05929296e87ffc4",
"0x8cd6e1340deed5cf75bb30c3183807b653c7ccca712f379d5f885ef1a4100945",
"0x549d904ec260af5776c241a80c2075e31869b8da7026a078fe158c0b0d646b11",
"0xc73927c3be804cdab32e543e78f38f8e0899d7f0418e0b37af336c2bb37269cd",
"0x62a4d4dc610995d0f08756056ac199c3f0959674eee8d4503067b822e37bd1a5",
"0x4b4a3cb0ac65532d63592978b1afe838cceb7cac04d30a58cd4d73af4b99d2de",
"0x2c5aa96bb3b58a76b4acefd0275f9f7f82418501ac2c2052e0a5f43eaa4eed64",
"0xd6b8f1a8e502a93e14a8177bd750fb7e7974b7527f50bee37690b523dbeb077e",
"0xaf38bbf2941d5ac311f8ab4cec22642049473bb3a8493ecc27cce73dad188797",
"0x778b83f79934655d67e52a38c09410e5b5cc28b26f4f70b84d2bdff5519bcc74",
"0xcc016a4cf3d1f7119704551809e89c1b4f95d1dfc4cb7f95db2c5d2a6ff1036a",
"0x6b904799fc1df35a787bd7b1ce4337697bad98b25b2bbf264a7bc68d452df41c",
"0x915536046dad19310976f8d158795e4237bec7fd5c2d2fc8ab1fd6a3b5b75e43",
"0xc84167f477d317ed1e6b1452cd746d43ed679f4ff2eae84b1676ae99d3bb0fca",
"0x71758a9fb0e66a7a04a076569cd3bb41d5b91cd1cc26b21a773e67524af84e63",
"0x54f60d40ea84652f938d2856533d82a7c0b91091a0ad009f48e599a917b52bb1",
"0x618cec420aeabdbdedb8afba71b0d0408da5095ea3231455b6c817f9a585d437",
"0x57cf387db60cc35262bfa939b0272af7c490720e496b5f8cbbed6b4b26397824",
"0x7c8973551ad57c278a0d8702cfed004dac293e2b9464debdc48fa88be033ba5c",
"0xc80eed1b2bf137a5574d40252d4d02d0e3f87618c79b764407d8009a2b4932e2",
"0x09ab540be725d669810c498557b61a53b343104c5303cccaeb31e518782d64d0",
"0xc996eeca57ce9a7ed79f6db45ecefe1710abc4b3e21dec8f707eb5f7632c9c43",
"0x160af8ed3f5f55bfe0a9129da94ed002277580b297e29cbe23a962c41eed1cf4",
"0xb8935e0d55dad821ba5605607cd6a025d6ff76ac3d9d855fbdb3d000ef864dec",
"0x10f6dcd55318225d362a40859030fed3199ae015791ccf4c4bb343e7cb97822f",
"0x6f3a76c93761f73bd148c57f2bd00670c20bbd19338b7fddbbca65e598b70ab5",
"0x6e99e5531942dde6d881eac1f03c6fd2ba6f9d79b6f88408eca815d84ff48157",
"0xb05ebff5d64b736d36b372da80fe28d6e76b64c74e1ca94f1a859936c7ecfe7b",
"0x815a140ac8538595dd724ab2c31e13d30c03ed3b64d2cbc72871fe402c7c88b8",
"0xf4376c81472e0b3995618f7845887159eec1e929b8a485c2693219f4d5ade069",
"0x30ff47cd807666e5ac48659bbfdcf8883fc1c9ea4e9be8b397dbc969a82f8d95",
"0x74e35254636ae2f72005ec69e62273e9cb7387fbd4234aa58184e11725e2f569",
"0xb4f3de4e9a22e787077a53017e72bcc8ec26a1499c98305dabb61ce6582cbb09",
"0x3a05acc943f2b7d0c93cb4c5fcbbfa3ab9e536a2cda7f1c325fe3748401b4f71",
"0xd75d428c14fcc7ceb929328989235a5fc46f8ed3e0136d81dfc15866756455a1",
"0x20833cf410b3a0626a6c7e07d5fe09bee17b218416725ec3fac716597e1f6576",
"0xed31b1b593289be968e483888fc80e5c360beb66626702f388a0848bf104687a",
"0xf55fdb35314f9b873a70bb207536eb2e22958ff9264f1e088b0dd82bb9358b2a",
"0x701d2b5d8794e244d85366d13fa0382827ccbcf557ae2735bc3f88bcb5c778d9",
"0x0492794944f7d179da85f68eec5ce4575a90b7a6f161ae199373ac4685c6c665",
"0xb1fb246d93a6ca7a0ce6518a4d0cbaab074bf2ada05fad7a6d199cb830bebf8f",
"0x77172f0acbcf0eb3ffc2e314b548210fc74c10826162b2d63195cb984d606623",
"0xc9f684762b2378428ebf3dc8e207fe8d2b33c5a0ae1510ef44e2dda7e5979faa",
"0xeb864bdea464cbc95b1e3a4be62231f91d1230179b7bf61f755abf5f05cbc9a3",
"0x10fb3751407e792cd70fced2271f125d438d9cf3843d9ac6f89681616d0cb1ad",
"0x79f96b934d4b22eb9315230c113fcfe0ee2828133e10b14cf2e9b3a8007dd7ec",
"0xf8c0546c0c5eb3d9ee16295c5e0fb510a0ff3f55cb654313db2d8ec6195ee996",
"0xcdc41342d4045064634291c9bbce68efd7227bc2832b372502fd4907f1957ca3",
"0x7c09a67309e6a0993fe1cabb7528e5cab4ba6a79042b22b3a6cbb10778cdecc3",
"0x7d5c881d1a199b82608d7e27456788164041cb1e5ece5e3b813db550cb402203",
"0x4f7238409440404425f9f60c034696e4713bab4f4e507b76bdb2697d1117ad70",
"0x8e8642cc65aae464b068178c4c2276dc8860b63cdd8f3447ba07a0e7a9b20c71",
"0x59fd79b1b77ddb040cb6bd45f10ec5ebbc7ba421e14dd79755e568774010041f",
"0xc8bfd004b479e0ac8e2e798045343198909a6f5657625028bd28af69de58d9d0",
"0xb550f5483d01e8d32258708d82d463f28658d5155a15da214bb2c748e27365e6",
"0xeb7de7083d7c73f3f443e6d009e97783ecefd77157b830cab2ae7d41a91b0b0c",
"0x6f3145fafbfa23c5667b646b3b5fe12b0fb08e45f09e62e9254efed6ed812880",
"0x66cbab429d401739e655ee55de9dc3ee6223230e38daadb1fee88da03c46197e",
"0x410eb1081b98fc38f2447bcd358a0996bb9660f949b4d9d6a6596aa41de59557",
"0x2fb84f43e9750be8f37cd293742776ec76d95170689710254d7847369626d6c8",
"0xf1d6c7c8a81aeb7611531452bc46b69db1b56a31c1c835ec5b497b6f4aad2b8e",
"0x1449b942575209a4bfcac57d594cba694bf494e98e154142d5423deb193ad2dc",
"0xa14bbe0f97892409b86989212bf815a5024769707bb8fea7479417402a346f05",
"0x1ebaf8a3c224720c6cb4079b8e355411f0181318dff7766faa204d4292e6593f",
"0x70169dab4258b561057c427b3d31de403d87302180db843d3ac6fcece4a8bff6",
"0xeafa1e0854e1d0dedffc92fe173f2333d3a0581199fd3c63ea69356206329d65",
"0x54de1a943017c40959dbfc25e318b0055b0e041cb170b0f34e1fe76f41bf2f15",
"0xb4ce2d897abe390b9b53be9809fbc1dce8d23c2d726dfa1d0e1419d8caf2c6a5",
"0xca872995f8268bb0855fc685e69d590defd10fc6befb61a57ae75255ef92cc23",
"0x3e3606562cdf9f8460c18efeca2d7f3649ac96fcd81d2bbd501e73a01c729f27",
"0xec09b7014e049e25e0749f0a0899a2893605003f128bca3bfbe92a00c9dbbda8",
"0x9421e443b91c741c80138137362f7b30dd9a0db6a815a3b4a799ec12ba6de4c4",
"0x78c95ab7995ca6058f64f7fc4af9575923bfa70a092ad2268f0b2a3a20dcc247",
"0x386b36edeea33668de333683b1ec3d9c665f150aa96cf78be27fdfd8f185479e",
"0xc732d05a6122e07f7566a2a751adf5da1cd1ee23dc0b34c0cfe7cc12f0970c5f",
"0x283d97620ed18ac85ab1d2c613d64df485b6efa26aa6efa71f840240a95cc240",
"0xce779d27aacf6e512f5b52f96507325568f754b31db766cb4aede53c9e1845af",
"0x50bbb90f2a3cf4c479be3e118936246db591f98e37caef06fbee553502b4c364",
"0xcdf95c14c577f913331709c5d044fa536a4afbc06cd8d60ea7b5d9ac463e86e1",
"0x3a7d03a8ed71d0ef15ed70677ece7a2ea32ad1e96ea5c3266a1d9f580efa862e",
"0xda132c0fa137c542b06170fe085b483afdbc97c63b4546079262ed0fe1125c1b",
"0xe4cc4056951325ee41cbb70fb823eccad0f266e032e839a2e3a8e851f0a6c73a",
"0xc301415694835a5bf36e226ffa42d2fa8069dba6be6becbc2a7a6653c295e8a4",
"0x1856c6fbe4494ba46fb87deed5c10e361a83ee73bfbc8f1b604c6fc0301f62db",
"0x1b822bd73acd2fed2f8daf6936ddc8175507f373e701217b645cd6cb2ef2019f",
"0xdaec59b4c520d6b5be4d82b1b1338a5dd55c9df443d697fbab750c337f6986d3",
"0xce6ff73593693f7cda1159724457a2aebf0ca608105a5926fc98afe5010349b1",
"0x53c50cc4da6192ddfa851aa104f92c865ce212a87500098d18100394140ad6ce",
"0xf015a6887a543a0849a128cec761f10f7d94f7be083f739c767c727aa9ed95d1",
"0xa54bdb8a7ce7327aee991715a7d673d403f2248574bbc0ae5aeb9a32b3d9528d",
"0x47d46b4777a303430fa4e45305b31a113acb4aeebf205ca215447f9d27ea401b",
"0x7a9504b64ca570814194b95acb8400357667122b5b1fa4cef386b35e28de2c61",
"0xa63e5964474672c45b8b021b7cc408e30364c163c800fc302f342f119689e022",
"0x988eaa51716d4cb523fdd5fed04dcc195c5fe00a8e4b6135fe70b6f09520bdb0",
"0xfb8a8f98809114b3d433875844e5fe90cf0321b772aaf86863f96e8013b8de7c",
"0xc893ef50496aa272414f6a06af7d53281fbc7265a3e389a42c7c49d32d24fc46",
"0x4956f7747cb6489eeeb92b1c759f54d534397074c9cd017b2f5181187248449f",
"0x4b48dfaa0b7984d4eea56cc40c5130936f98752e1c2d02762b5caab600c39691",
"0x23df05dd92b7e6c024c02fef9cc6aef2ceea2d0a4827de1f87bc7eb4f8c8907c",
"0x47ba2e8a2e5d4fd0bb04be0d76a2d553d4bbfc574d1b5c715393fea03672f4dd",
"0xa8553d8cc2aa6cfa89c96564022be9e89aa5a6b0b98d88fb7976583cb2b4d2ef",
"0xaa3e7684a3a9daeb343a10566c21ed1fccb46f4ac4b80efaa8725127468b7072",
"0x55acb0e629a6b654ba723f330770a4238cee9aa9b98fc4536a7c8bcf6050b9e0",
"0xcf2cc1a66e1d9e2fcd8709c6e695bef0ea95e4d14523d34a544adacaef0bf786",
"0x6d955c9a59acd3c90593b8eb22dcd614a89ec947d554a0fc8323e817cea7b332",
"0xe29b3ce7a0e8325135a33a1127d1db2f17637090712a0b440bcc3a3bd6301186",
"0x47187e16fd16d67eb94e48e2f35eb520191ce412b95c1d18443487887700c516",
"0xe2ea962ec229af7a26687783a7ba8f65490d9aed8f34bdf7aeb978c901f67c1f",
"0xcbbc65451fd646ce67f78593806e3b66379d1a3aed301e6e67df9e3ecfd3cdea",
"0xedc8308273c7ec9b50c8c328c62cda10e4e8505e3f67d134d0961d0fda239747",
"0x57d5dda883a2dc7ef9b36453edcf481d97c06113d7a060131dd39133ded06e6a",
"0x9392ffa1001ca3a85455471b660ee9d89c8d6d421fb4b00d7ef1eaef22747009",
"0x0751d3a58d8bfce5febe6980c821c92f9bf5beb8685358375640f751fc5c8369",
"0x6ad5fcb53f602b55dc728c7850f628ed5c500b65c6b0d22c077fc4df980d9306",
"0xb9f2d92291fede8a3def3f527a8449f6e330d587df1ec3daedc1f42cdcbd6af2",
"0x85eef96182742e4090221c1ac4433c106467e48f8c46ead864e6150d7d50946d",
"0x6e800d685f7f68839978c124f300aedb6c34dd7ccd7b2dcd3144223d0e3db527",
"0x9395edff6ff47843cda1e5cee061f449dcb7b5a0ca07daf9788079aa7c5b2ca3",
"0xa2995f2cd9a79024f92ecfaac2cbb17a9325b3f54480bf2ae5f3d171132780f6",
"0xef907147aaa023015d9b8f3e7414dd4b84e551af0d9f19fb918ad5f632096657",
"0xa44d76467ee5fd7acc90c13bb12740b3fa8a0096ad0be0e3619841e67323c5ba",
"0xaa574a790a0a50cdac6be3819be64c67427f5a891a0029333da60a01680d83f3",
"0x531d9c8a5d68299fd55cfe498922d54af8b119500f7e6bc0c1b66b45234dab1d",
"0x45cc89de803b6eea973d45c26b4b4287d322dae61163ecebdd3db92f8a40be52",
"0xb305c50ca54418553d0a08c2a01908f3d413ee3eafb55eeb4cfe32aaad32597c",
"0x5767e979f2322c81537baf5d300d24e736373eb399c0e7ae989fc0f177c40bcd",
"0xe3646fedcf2aa89d6ab6a6a225cbfcf539317e4c59be2655b46f0d89142d9b18",
"0x9edc1e15d3b2e5eb5f0b60f15e3b39b0be95ddf0bb6e4d18f4c52322b66c7867",
"0x5bf071715890e9f227fc66c705e782add56e39eadd30dc982066fc067ac64fcd",
"0xddb572bdf8c2ff6ce8a0d9b6b2c95cbb33dfa9b96bde4b74812ac016a93770e2",
"0xf0687ab1fb94e49d1e113b1fb0127548d60ca1dcf341a1952d16dec090aa2736",
"0x94308074a4ed0dda1ebaf569b6cd5b4b6f7e77bbc41c737c78462a1ab330e3c1",
"0xa7141bddbfa78144aae11810acf034e48bffc3368c862d4f750112899150936d",
"0x1560476607eb8c091ffbc0ec21cb3091c3385f9c83f8d27c4a301ac200a92820",
"0x8c0b77737383dde0abf21d1350f0d2c285344720c314c564717ffa034acb1739",
"0x2782b37efd53e9a34ed2742be32de2480de342a384d81bdf3359d3686a3b504f",
"0x6e9848f3a434e019bc209a02ec769dc63e084b9c0f00472c218589dd3c256017",
"0x721d8f1bc957b825d3abe06a6ad9d8bba2e03b915aa779ac42fd9e5bc247411a",
"0xb937b6dbba5291fd35427afb0126ffd47962a07c3bbd6c77e4b80f6bf751c684",
"0xa5461d8dd8d05bf13875c6b2b62c82d371163d2f8ca80c2c0ee4d94061355a7b",
"0x58901227df5457e57c74db16ed72b9b6f9303de046e7adf6fc269db7ee9e0a28",
"0x33cb303cd28fa770e6c9f067831cb1829a8ccce845ac6bdce7d3da5d4ba8f3d1",
"0x3ea819ffcb3839d7a16ce09958849118a801152ecedc92de0ae5154f6c8a5d1f",
"0x001ed88b63827a6c71d7214b42551990e3f313720d982ea5f1049ede4f9d228a",
"0x2e346b0acbeeeb88e08ca6af0f2bcc3669e093475d8c224f23a45d4e2fca462c",
"0xb4ed38878080e2128b706ca1ac4c92c0def02a8ec094d07312068c10f6b144ca",
"0xd0d3c577cf73421791431a6f00452f33fd06f771de9ae2caa32ef2c93bd03951",
"0xb3dc9827308478b197b3995e39aa930d40df8cb98fcb2958c6ff8ece2bbd4c16",
"0x44547163a565de79110c1e42b81151a6e304df14953e648742558efa6f63672f",
"0x487a072363419adfe51ce0b8be352c0f497e5720617e9a237500293459cb7bc0",
"0xe7e9d6bbc5de3d62822c92cec484926d935038fff8be29ff3743008499000d9f",
"0xe151cd789208eeaa791f146f7e7efd46c17e2f8aaf061ba5bdbd7357a32cea39",
"0xf5e2de235cd7ecbc34828c244da80de6c9c452c253e6c876d9843bf5bc665daf",
"0xd0bdde209238ddc6ccd1e06e6e69c2c16b38ebac8b9f3202d46bd6bebacdd893",
"0x5c3cab37f5d83ad8fe9349ba88ead08f36e71f149f10642c819ae53b26ccb0a6",
"0x1d069657a6a467ecb3a781a3d72a8b701faf497e1098fbb9c04ae29820fa4e75",
"0x8fa114b013195af63e697432f3be7017ce8fd6e7ec26f23f832b003e82f17ce0",
"0x2664fa9d45f83ddb5c8a758c6fa3201abe7ea14571c886815585c543f245b301",
"0xd6c3528e946a4461efa56df07020008870ed64fde08cd72e7f8be581207f0d1a",
"0xdc4c0f579f3e44278905dbc69610f7d1025e068f75e5475400d96c97297fe5a3",
"0x06124cac7f9a1c10d48216905db968c9580b3744ff89b37b9b49e7308b04da8a",
"0x5c0c6c98bce9c64b7b62d62ecf02f435ce54b76c58883da177611774c79d5fba",
"0x424553682070092aa2ab3e454c66dac9d6bf6baae6379d91405a47fa48a3f200",
"0x3d09aa437ff840909ec6024c1e407ee7b5622561e4991b76968c146ae1c4976b",
"0x3ef50c81169af169c100f58f3afcb8e2f926d957b2adbaca8787be5d4e8d7233",
"0x8783eaeb56ca2d7fec84e0e272b77271fdfd6c14452a2e1dd83de770c5d99a1a",
"0x861024460895378ba100c5d0c05e62bb6cac8b21ae529ab5cab39eb6c6cabd90",
"0x1c741ed9eda60e5ac585e2f48f06fb988367c2c40a0d8111bb04b260fe44ec6b"
]
},
"accounts": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -52,9 +52,9 @@
"extraData": "0x3535353535353535353535353535353535353535353535353535353535353535",
"gasLimit": "0x1000000"
},
"hardcodedSync": {
"header": "f90214a04d45aaeb1f0e00495b99f5fdc46c2c1e6b0fd48c693678de72afc1cb6f47a086a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794120c78af68df5957e776554d138a6b75f2c34b6ca0f2746b213421be4ec9cab40fa41aabfb4a3e8acccb6506d6cea4863774374dafa0225a348dfb2ef00db09da39b1a11b31741b6d14fd4456cdf4c2528961f398b74a09528322c1ce98449eed355ddabe0192fac920910a0d88965444b9efc1ac218eab901008000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000040000000000000000000000200000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000100000000000000000400000000000000000000000000000000000000000000000000000000000000000000008426e4d4518334e0018389545c8306529d845b284db896d583010a068650617269747986312e32362e32826c69a066f990a9ad374c2cb0017e96d3776e6c787f679d77c9079fe2b046279453d0f88851bec8da753bda19",
"totalDifficulty": "8635599198809021",
"hardcodedSync":{
"header": "f9020fa0a415a8dcd55fe9c93372da415ff6897036e48cd3c1a5ff8ffe119eea1096ecd6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479443d58f2096e015db88e44346e73d8c59cb1753bda0100f05d66d36782b7c061c724d8d07619cc61053eda41badc8d2cb9292898ebaa00a60317b490365f40f0528e1f559b0f49facb6638c82a9490d368e963647c704a0118b536c3bdabf90273d527dfc26914c7878176fff16cee8fbb150e00ffcdd29b9010000000000000000040000002040000000000000000000000000000000000000000040020000000000010800000000000010000000000200000800000000600400000000080100c000004002080000000045000000008000080000000020000200404010010200010004000000000008020000008000000000000000108010440000800080000400010000080010820008000410800000100000000000000000000240244000000010000000000010010000000000002000000000000000000004000000020000001000002000000000000000013000000100000800008000200000104000000000000080000080200402010000000000000000001020000008008501602a8414833bc8018347b7a983476d40845b838083904d696e656420627920416e74506f6f6ca0f540bc9cfa258b97576bfb9a79518b2c07ed73a98bc6baa61cf7af4b40ad5b6988965658a406315a8a",
"totalDifficulty": "9811143388018700",
"CHTs": [
"0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a",
"0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc",
@ -1747,7 +1747,228 @@
"0x8baa0703e1a050c40f85dc850fe477881f432c951b1cc1b2b71ffb68ab7fe0d7",
"0x14ca94dfd343548e32ef5659c043d6e28f0e577fd38da1ee12f11c08e281d775",
"0xef25357970c76a8b72a6e52f49bc30651f711c7df70444d4667e80febc0e3b2a",
"0x41b8b4ebd5919dad3bc609ded524b97403d88f019367f0f4f622561131644ffb"
"0x41b8b4ebd5919dad3bc609ded524b97403d88f019367f0f4f622561131644ffb",
"0xb29a8ad1157621d0120aedbd8dfeb4b318979bd43a5b018bf7b9ce33d85da312",
"0x9ddf78b5d67ef40454867ed33de83a01cbd8c18fe09da3d9f991a196811dfccd",
"0x3604121f9cfbb5cf552cf8bfc9a7958332eb97131158e4f40f4eda481e553991",
"0xf1778830f694720a6f990f9d476b0f365e8a74880253b55ee16f5cbd6c8082a4",
"0x89831626d154fbe84a4c62c3e2638cd00e42b3844c7c7b98cfad113abdbc5347",
"0x650573f5ef274b2aeb40642e25fbd661cb0eff66245d7cc8f6fb9e9daa80fc12",
"0x479f6c652173efe94abaa850bffe1557847b26f286467013a4d72973e05e8e54",
"0x7096619d5716c34592ac2d9907ac28a74c6f6b1ebb1962a0217df82bf3e714d4",
"0xb7c7edbd8ae7eed58e973dc0750adfd04042ed56baabf372b111fce3e4b4469a",
"0x25529b597bd15317e55767b3fbfecad0657aaeda99f098186b41b70811f7af2a",
"0xd790747b09f925fd155b7bbdb5ccd89d873277163e4fe7054bbf71c0b26b8072",
"0x3aa0b221d1c4743a06692f645f38a8128d55f1c07cfa6e9711b0d2e0f2e0e738",
"0x26fb5017218cbe4250d2ceae751e99b9a34d7befa162dc248ac008c5d1221e71",
"0x0e4ada59854027601f8f81fbdceb95228db667eb65fed97cefbb35dba21d3b52",
"0xd3be75ae2da3e271dd85cd8226d789aa12d108a4b0d2681462f6539637572e50",
"0x6f041891c8219b508138f67c95a1765d08c5ec06b9ce585f52f837806fce0609",
"0x9e106515d0e80b41397b2e8e98adbb7333e76265917339a62063a07d9a7ed311",
"0x25f47483ecc5ec32f94b3dbcb4d42a4cdbf5c279e93567e14afc742a4619d3e0",
"0x5d81afc54f6b68bd820dcc629ff7e9d8397da56ffedef9addab0eec620de0757",
"0x36e192130485f248925d4b0d2fd98745a76099eb13f53093621d216d0aff0d6c",
"0xb906e5e33b63f6cc355c13b8461a260ee25376ee96909fad2c6ac121ad831496",
"0xd68e7e0d136e30f67ccb7c21e4dc43b0ad5536584e4b77c9da8d903a04e9d212",
"0x5aa7847a4bddda7fbffa62325da920a21a11524ac1b691bc3b55e4d1790f24bc",
"0x331f95f062ed1d38dd02b5ab6a95dd238ef97c5ee9777c938697340c902b4b5d",
"0x8c6a580c8b07567f747bf20946023c3b581c51075cce5cd5d47b0d81d8922135",
"0x8b89483810a49626f90846a0b49ad3e2172657dfa3003d58fa2a43d12c8f4090",
"0x944f9a5754800a33d903c8a464d602fc9da6af8ff3990c3eb669ac9cd17891f9",
"0xc75c82a2c1ecd875d16f343a58835d756740902c246d3b1deae97e49aa19f98b",
"0x1d2e0f2f87ff2b08514b18855c343966d42e0f1a048ddd3d316dca6e06292db9",
"0xa6508507463e53b3a840dd55ed9be57c8a56e1533c9001276750bdf19796f8ea",
"0x01eb6b636b1852e8f9066c12d4e6b7b06b90a325be4d97e08f7f560bab4796a1",
"0x8a0d77fb41f50808ff0a46dc9f3831a2b5093f55ec2e94a3d2e92373ff3b5695",
"0xea3383ba1d30891d1e236db2b31373541f51a9e5c4b4d017cc4960480dd20311",
"0x01129e8d7eff516a225cc0db090e4e38362d9eb2d0571ce00f4417836de2e375",
"0x92feaefb7f9466814a0220e536fe5ee73560507d071e059827d406329e609f87",
"0xac149150c11b3bdc660320a0e955f154fa3137549a73951207659e2b903c145b",
"0xcb68cdb224f9b3b0b0f3ca0056e70817146c9ebc75876dd952e6ca8ea896f2ac",
"0x157565282a12d790452e343c9762c2124456039729f3a8f97a2cee60d85628fa",
"0x42eadc181d59d8d8b26b37e0e9c9052e45bde72090d330bf9cf21d9d3c7d9048",
"0x1ea0ec8879b200e259a3a2a0f2a7aa292301784fa422f7c32ed5d945183948b2",
"0x06aeb2956be9d74ae4ff0b8a6c1874ed8ba46a186616356dc060bea1cbe5c628",
"0x814b0382b52a155a4e35639aeb3d8c859afc4fe5d151de3b0f1bac646e40f2eb",
"0xb30bf3e85be41a2a9e53321ee9f03c7078516c72c7e2d8e7e3134de709b61c36",
"0x1f97f5d334b5e6ebc72f5b846f24c7911f4fd1653f89b3477ce4b8108342810f",
"0x84c6fd181c28ad159ff18d203d14f966668468c9ef0a5d6dbd863886a7e0af1e",
"0x4b2e6947d55ea504bf205bae9dfc0e5402efd33757eea4da00a8ed2a6a3838ae",
"0x85f31d45128bb91cd3490b58a0a641ef77246ea9c83de30fa89b621307fd96f3",
"0xd362f5e6f8cbb216e66eaf49e4df25e01504ac729da86c530871a34e11d302f6",
"0xb7860983b043bc13ce5a27135eea12ffaeff71879404b18af3079b98da156bf2",
"0xf2ff82a679b2b90cb9f4a3bb903eb7ab36ee1c47cbe40024d8d570f5e16bbf4e",
"0x7e34a7e6673146b6bb7f78593b6093ef15b8e9fd1271b33dc5f7d17876b31871",
"0x725c97f83b4cf213296ef353e1c8d64854ef08983fd61320088b8d9e2ab33849",
"0x18085800d10fc7845148835d0ef0ac980a82eeafc44e12bfa296f9c38fc6e19d",
"0xc6c3cf95310cfd0254f0f8e93a3c25bad2b17df04f9c51a25927b80d02e06b69",
"0x822213c1b03cf68ecadc0b7572d37266207d5fe4efd5e56a924b0a1aab8a8e84",
"0x1ff46ffd2dd880cca76244f6af1fd8bddbb4b9ec58f86639821a16f2ff08f3a8",
"0xe9d00df19d716dc859922f2e6c907263191c8e531498ea557869ea1115317c95",
"0x6d3f1edebd562e9d1a236ed7a1d9104fd8f5a086cd78d35c7a65f27c269d98ca",
"0xfea701ced5bca0d5043512700598d3eafa0b89dc02f3c157cd1d52bcf4d84d9b",
"0x556c1cd8ff3ebc2ccd4eee9f1ad3837e346ecda961da17c0ee9cd4d084a47653",
"0x5606be2fba065424af76c94d4156ea82f77d9872ddac7a4c2517957a169e58f9",
"0x8d0223425b48487db1b371c966c7688435f4b9fcda75b088f0aac203d6657cb1",
"0xfceb55d8f3048a3f2255562e0a9ee342439253abcd048fac151ef4b910048e22",
"0x360f76e4f2ef49632e3bf8cfc3afeccff6917e98a48d3568148c3bb13f9d2d7e",
"0xd87bbf8397204cc2af883362646b0ae95392303935ec1997ab052c194e0ef117",
"0x9f1dad9dfecaaf117ab5277caf672b70540578e703c2024d3f23bb7cf8d6410b",
"0x5e130ccb23b7b66dd2fbdd912d6006d2820071dafe2890f593f952028aaa19c0",
"0xccd2f182107992fb9b002b87cdf7990cb2810b202b2ae5d6ef5e0b3bd69632e2",
"0x4b40cd83205f8b946ca9f11fc3306872650e658e631511fd4080bc8ca749d913",
"0x652acc59b71ca20bb65ca195d1a4b3e177f6a3985bdcd6120e1a45b7d4a0c7ca",
"0x49a5e2580ceb329665244e489592aea27d54da8189a665d9435e037ea70c46a5",
"0x379801356beb3a8e5fa7311792c69c7ac1f675a9c08c837f9f0e9f53c243d6a7",
"0xfeff4543c70356b7d9767c26b228cac8452c95bc4875e92a60d7e6fc50468667",
"0x82eb18827313399cb3b0d3c975eb9a9480c3aa5587ce72d321bedccaaab56115",
"0xa644c582a751a6d8cbf30e59d6e770a6f441c017b486cdb23e6b9c48c614967d",
"0x75e6f4d4185515a3c58dea60b55d5e50af053bb261db2d3de00f812a4072ee2c",
"0x9018506876afe91cd2cded037f41c5ee8503fede2a59c47dfe7ea1b36c460f73",
"0x0b8bc06bf211f715291846c6c34b805b6aee91ef4e8c63cf3d15ec79b44ddae8",
"0x150e43fee00d798b8611d4e03838072d8b9c8ee3771e840ee2c161a541d6b643",
"0xe98c938110bd4227c660a9bdccba3b5ce5b8414d909514502e8f354f96abce69",
"0x0fdc3bd666d74a99e623f6d4957bcbfb17395bbdacb52b18ecf7aa5d2e4ad2ce",
"0x2c72d738e803c0522b5f424731ad6327548ef08ded4caf4ae0466b2cf171ac4b",
"0xa7709a082f8a2ed01e2e88c4a2d18930f510fe5b831d2a1bbb1a85a858f19e54",
"0x8ccb960803f6b6e87515ec20a36734128da0dd6e65845013d89996070d3cbc69",
"0x4ab2e49286c8505f32ca54314d1b5c3b2952578d191c69d1cc7ba78a000a01d4",
"0x6bb792b52949c952f20b9d11274c8a05edb44c4070d949bdfddcb0eef2464454",
"0xf61eccaeddac91487b2f5d7b3ec57d1ccbdd0e1307d2f624319fff525149941f",
"0x2dcf01b0d9ce31c13c20959618f2e5e0c7f8c48521f00c12c99d28bfcf202f57",
"0xb1e83745e6013706904b7322350c8b453aaaba0a61ba89f35eef8f19759ceeb4",
"0x8a2cd4944bee70696aa216b453774f4d915dee4bb78c8f7ff55410cddec318fe",
"0x49a78ff97bd4938cd030df23e5ff4d84ace59ef3fdc0099941d8ad7f82235894",
"0x61e2096919419c8856a5473f135f4f9febb102f80eecc90ad60baaed77a99d29",
"0xb95709562a26564e57cafa00d0969305ffdd0aea7e523ba90957a6cbad6ceb70",
"0xb7a6438f176aed77a9c6470e28ab8cf19dad8f77dd3313cfbbbc9276761f454b",
"0xc85a1c37b5a4e1e8ae67df31b369f0b44cdcf66418b42206e5b4a738a0a0bae7",
"0xf034b0d125eb1bd1bbde1fe413aef80fdc136339eed062b97cb9da2f4bc94ba5",
"0xcddbaba3e9e1680a2d1586a1e9e2268afb51b4894f2b41fb2eac5f667b6cb655",
"0x971b2fbd25a97bc710c30b6b98efc90428a7e423c09fe772622e7ea37d18e49c",
"0x8571bcf05c836a59a5d3216634ed1f691edb7bcddc7b5412bc513ae9e1fc0423",
"0x0543d8abe5e1bd541a5bc994b0c7ea5a556575d2e9302d1dc36348ebb7ab9e82",
"0xebd8f9095619980043f234bf4f7682534ae6a15b4584e9d1ae524138471467c3",
"0xd0699a768c873ca5bd615ab5b0fd9c7c6c649c4245b58cb622210ac2bfcf3111",
"0x35bd5a50b11033878751d985459657bd4c0206584cd1def98a355d7ffb0539f4",
"0xd476d2b8b62b720520ba0990137629f83db9c6896f1e788fa5bf08614af1f2bb",
"0x2a8034765c582c07580c0da45c4216bb513171d073a99cbca2fa2adc0c05dbf8",
"0x084b45a575706daccfbbbcc321a9546b0c911861f2639d81f210b77680f60fb7",
"0x499bfc54ba17718aa8f74ceb412dd9b6b6c7d1cbde4d8ad2385a5d5d77e98915",
"0x8638684b06607afb53385f477f0f295453f14e36161da6dc7728336475303a9d",
"0xa686ad8ccc3507627712d203f7ff3be65c289da67269388d0ad8949ad3a5a589",
"0x6d262ff8babed3a603f400501cd77344585fff92e5bab5f5848873042ab87cb0",
"0xb5755234055b3534fceeafcc84d0d77dac220d3466e1dbbbe7d7d44c345e1eec",
"0x92a54b989a1aafd36f979ff0f1fc73f9b1508628f054430234f4460cd9f3959d",
"0x1a48d9bb57e9a70b03c066c97ff9520c177b8361f2b3c343ac71fd8cbdbadba5",
"0xc9e103919e8b6827a1fd57a3e99155a24810f524fb69a7e3fbf486707b2da690",
"0x22a5ba2899ce696fe691a2c545b98ddecb7c0a844cff2375e50e0a0f0f9cf9b3",
"0x154890ebebe7f014aa88f8da52c9713e2b0cc8b9b6c7d29b354afa000c2eb429",
"0xf9a72e3ce36943a442d0dbc7a869a6344003d6a7ee4d344c1899ab8b96746a6b",
"0x270fe45a526aa3bcc8e4a5be075610ae9b15d6fe48b04c6ff0c82a1c7f56e0d8",
"0x9eacbdd695faa85bdbff10bcefcd5edfcc489c3380cb1c73ab5ca6cba2492995",
"0xca15124d292e0465c7e50276cfd374c82391bb668d68a3b19c67fbb9e68b0bba",
"0x9a8cfd3f1b8ad178c982feed1fc306dc996da3d928e99a6f8ad240e55f52cc3e",
"0xc173b14778977c5d6dcb1079023c493406911c6d6791ad08104f847323aff7cf",
"0x82b3e9b9a407ff0596aa7eabdeba10dded85fbf3258d12949ed4f46484e0f649",
"0xb8a009c28a2328b7c95531bc64e072388d797130652ea0a84159c801af562a5f",
"0x80e45ff8b60d28dbb45530b7b56e049e605d28087df7133766de0e151dfbd01c",
"0x7667e9cd22c5427e6f37f215b1d9cd90b2659d5db0bb499daa382e09fcfd58e3",
"0x825014f354bee6aa4cf5283f86e8293c0ea6faf07862abe2cfa12740a0d846d3",
"0xbe9116073311dc303fa29f7a226ff79fd39ec2ffbd2d2270652b972a701aef54",
"0xb3fd19eb6b0163156a350156b15e660853f68a903ea6ed758bf80b2fbc5a655b",
"0x3c5a408909bf485e8c3d8e683d8ae4e7b7149d1f01874807428a3f88e1293d4f",
"0xc759f51aceddb90e6e4273fb9439908592dea649f5202f530d15d455c5c8c7c8",
"0x1fc97f79d1b1d72da309bf2027ae193f0594ecb77c07a472421baadda577a24c",
"0x09c4fd284e5c0672ad031629e58fb2776d1e772c6041c91433f287304dfdcd1a",
"0x8c6b40f8700a0638ca5b7bb003c2de6b54e731881a072988cb78ba89557db1d6",
"0xcbc701507f4f970d8dbf15306d6ac5bdd46b6f58bfd2dd07db4ee01c65aab5f7",
"0x6b911e52f43696cab429c0e511fc40011846af92a2631f4d3f2cd040567f021f",
"0x4fa5373f6eeacba61818052da8a9787c4ed86be0bffe0672c0aea792cc3d2d49",
"0x518ceeb36cf1a406b89040ab0c60e380068f5f6571d042d3bd9a9d7af1b12204",
"0x82039214db7d3beae631682e9249b06f98e16153f864c2026a6edcb0727a6532",
"0x9a9e534af83084007e54dadbce2a0224008a8c42356c2ea650606e8e72d2ad8d",
"0xc4dc0b662ac8d4d987b8c2c65cd27fb8992f65d598bbc25f017c45b7032451f9",
"0xa921f124b5275f07b2c064d477d5779963096632f03c54ac9c87917bc4aa6e52",
"0xb4fe786c84a19c8db63117c421ce53244436d0c04384c62d508a88589f4e5c83",
"0xd57ea382802130e3ee8e7671be2b40a1392ebc6528e2e10d9d51f2899ac7ea54",
"0x224523fcd11abd078840803bbde2c3d1d359a0c2cfdd6f9110a93ac4d3c49845",
"0x5da21f79c0f1030e2a5dbfa283becced75e7ff223ef14a6cb5527434503ac71a",
"0x3e315746e89fd3e662f4dfe28245457c3b8a4ea6d9450b93639424a6d8ef7d41",
"0xe142bd09a6967021c4c5a5c7491b0df3b1bcf13564ac934a2668e1b2252e4723",
"0x2e9ab88b366cba155d1f6093e4edbbafd80032b07a192a35942aeea1bf0f1074",
"0xbcbd1b446853135abae9f330d63a06119a93fb53b63c621941f5a74324c384a1",
"0x7816de8933a433aa2719c99db24e692e6ac6551416b08f803302c7751fcfa3ee",
"0x52c53032dd84842dff6580013ab1edca7c251598ba5fc8b903c40e3d9e537095",
"0x771222b46cdcbeba729436ef39f81732aaf4893da720c1e7b59ebb3fd38ab9d6",
"0xfc440de1896e1b2848f2cc5c7d62c0a6b0019008de8aab41df5395586d340d4c",
"0x0df9b803307465e54cc77ee60dd6988e3d713d496ac0209509c5312ad0f19888",
"0x88179429086844e69122c70b6af8b689abea11e13ba0809743532663e3047c3e",
"0x503898d86c4038eb76124e18459e0d57ec25b177fc79bb87eeccce3fa75f0037",
"0xf46efd490382e4e4a3ac0e10926b46ec56e833769acfe3879acffb13030cfe9d",
"0x6efde5293a9d22e688165f2a51bb83e3b53584f9ef5bacc0bd1d99f5c7df18d4",
"0xc03dc313d9be55674000d061851c139f4c57c6fb46106b98c3442832a51c5f3a",
"0x8ec2accb7c89019d0fe2a31ddada0b8251ebe88a439de9d68be73c0994a6523a",
"0x36ec73d7e8c0181f6335c668ad7713f8eed607e0c302b43413f904b26160bdc1",
"0xa53e90d88a751a78397adc6d2fb4f93ad2b38f0ebd00b32932c4b2a39a276d9f",
"0xea2a25111ca37a53c8fade1ef65097f0cb85e00881b1ff201d36c9151a8e1a0f",
"0x8c1a24ac75821a4b0570c22b682c6030c678244b059ffd4b21e4d3cd05afb585",
"0xd230d46b14f9586f7b1947add191a69ed381cb6fdaa9b28c28869da8c6724dc6",
"0x4e8c717de6c94b4be274f052d9df627c945afe18df35c58a90a035759dce6b48",
"0xdefefe94ca6d93b78ef9f92911eec4c2ae0c10148691755f1624f86445a3b2b2",
"0xfa6c031ec69c7dac9f9b6524054806e2fa524c3200fdeac030d3bf7029ab776b",
"0x9204683278cad559a3f9ed2ec1f6539f34efb17957830d0aaa92b73cd0994732",
"0x2bb26a0cc5eb7424033e8bf552c7964573a0954e5b6aae32a51d95d951fc044b",
"0xf6e3827687af53fc532ba163d7ebd5ce18ffa6384157982b6dfdb1f4be82faf5",
"0x627bda246bf499f4498e8c512c8f601e36a1dcd778f21a598736f83b5b33fbd8",
"0x5816773273e4ef45fbacbe920dc3420602d8134fffe302459891cd6e65627f6f",
"0x7cd637fa8a5bb32dfd7c076c34e0e536d7c6710f1888f5ec18d64191a9930744",
"0xfe016a6e9ffd59237b349a817ba8c36f7775fef6513c4d430fbfc20ce72fcb1d",
"0x7c466b30cf23cb7115a3855d9d9c537c29f380ecfd7aaa0a6e59d9680bc43971",
"0xc49551e5eb138d28f5557ea8e8a8bbc7c058084ba0edf8f6bf64471928ecde43",
"0x7366cd68072f52c5644dc9fbe2e72339705dddd2b03690dd748265723944e754",
"0xbfb7c3bed071283cc18cca4192e2bdc1f97aee9b7185d493a29f20ed4d52ae3d",
"0x40c9fbfde126c8c92cf6d15a18be4b5a4da39ff60ce45cf5e9a2c1782244947a",
"0x1358333dd1b82e7c805dced5dcc2edd5d5784fe8104b64eabc598096c26d05ed",
"0x0a9777f7711b6d9f6cc6ad4a78b716199b57f026d1f30f04ded5d2cd8286322c",
"0x7a848ef083a03e4112c75bef258633779cc495df4ac5529e12c8eadc484baad7",
"0x17025c4c255f509163d11df3cac35c1de823e5ec71cfd66693393882d81fddb8",
"0xed0a2fe0dfe85c7d606d0d1b355518a48220e91202ec1c1178c8b37c86e1c9cb",
"0x4674e5e97dc0c615b03c34c702ceb07aec48cd7e8edc953a188d194a8cab35c1",
"0xa004c31b7a6f6511d7eeda4c400c5ede847ce2ea4339641b6c419f688cc4e574",
"0x1bb6c124e94df05e091f6aea45e7658351fd21318e91105274a15be4f7a7a632",
"0xc365b8bab2d6b902508d075195a1e23b04c97e40217c4ffa49fe16bb13e5b575",
"0x93c1383e2ab52ded5fc86e1b6f6e292c0d0977e8756e1fcbf87b099682060e25",
"0x2921b874e3855d9afca966d5088e9b1cfe59f37db54bf0c1e8bc5c5a97e7ef6c",
"0xfee916dad70495cb45c6ac632241a73869f0f553bf7172cc4e63fa382a5e1077",
"0xc63d63b401941d11edf755d7b6564b4fcba1f84ed99cd08f1580faf2c224478c",
"0x8069f00ca36baba06b310e28f6873e78b3ded25b456d95dad7eef4c517e7d096",
"0x48dc0968af32e91a8a3f252bc0082d7c22f8dd9797e4fa774d5b5365386a4602",
"0x861ffb24def147c4577aaa332aa2b5d3165542c4fd1e1882a9050e5de10f1f57",
"0x9fdfb7305249e7a38068f8099b74c5584a2f2df3f0514371f20042a6c0d2c85e",
"0x90212f15c5d6b686810e1895a139bbc26141181c3c472ee28ef9904553a2faed",
"0xdf967dfde0b63153142628dae7522307afb35b24146d9fc1d35874914244eec8",
"0xfb17a9d9e9a5ab6d742f55c0e8d80c5e5d722e9411e84bc47b1d2fe5fc33dd71",
"0x56b2c30b802088f9ebf0918c7ce44b50a96a0eac98f89e1711f53452006259c2",
"0x4c38b33bd4089a48a65369955540219b44af520000b8f8c346bdc96d47dc2479",
"0x7d3487d3823204a94e557b7a942d7c657c1b49d9f40f2d739a9099d4438695b3",
"0x2f82f94eb74aa2c0fb91bdb38ba0b416ce7e033c7e2a74aea113d201b225e24d",
"0xce8ac4b2f0f74601280bc3df0f5955d033e5c511372d812b36dffbca4b2e4736",
"0xb6ea6c89e91ecca1fbd723188a77370e9d23c3df8aac282cbcbe000b13d31b57",
"0xb8b8b7cb900482562227a0a1256ddbe822cdcf134a196e29b1aa6fd92423a4ed",
"0x0f47ab9f4985c3175e0a30a237d4f7c42db4a58f95344a86a818e459296610fe",
"0xc26a55a23eb390fc83fbdc9f07ee3ce09e8a2b28bc09386323ffc0844e13be24",
"0x1d5e97a7fdf5f34192e9b6dd255c41b63e24e1b4ef4ea43ae510fd1f50abb022",
"0x58b6120c4f0a1004e51703e77decb1c85bdd40bc83654d3f8ce5f7e3b4b6ca25",
"0xa2f4b27f5641d9294ee0411bcabc574f94b294ed8c50c9ae0c3d58caea7d6ba9",
"0xc4d6d3a8b4debec7ec7f3e2a6e1c64de46ec1187ed6e87fa2d87412c9874a3a6",
"0xfb59d9b66471893988d0fed17898fe2b7873d85aed217c20b6f438ed70fc340b",
"0x850df664737f288ae16d701878ad04f399b367fccaa2ddbf975d77868bea7cf5",
"0x4dfe47362c005896f82ac2d02a12ee9418693cd2f5d1bcfdc321980897171993",
"0xb652952de1bf9e1174e5f6a37b069b437792672a37a9e0159c4f36b6e64306b4",
"0xb72dd6cb5df1b00dbbd84e097e2da79af2ce60559697ab4c93b0a8b85b2ee406",
"0xb96fd4a94ac30c10f757691f7f06f25a4900fe424f4eb7ccf322e2f95249b914",
"0x99fd442599036f161ccef1ae8088c5ef694c1819f5b76d9d2fa8f979935f69f8"
]
},
"nodes": [

View File

@ -16,7 +16,16 @@
"gasLimitBoundDivisor": "0x400",
"minGasLimit": "0x1388",
"networkID": "0x62121",
"wasmActivationTransition": 4000000
"wasmActivationTransition": 7250000,
"eip140Transition": 7250000,
"eip211Transition": 7250000,
"eip214Transition": 7250000,
"eip658Transition": 7250000,
"maxCodeSize": 24576,
"maxCodeSizeTransition": 7250000,
"registrar": "0xb8624dc8cb3ca3147c178ac4c21734eb49e04071"
},
"genesis": {
"seal": {
@ -43,12 +52,22 @@
},
"0x4ba15b56452521c0826a35a6f2022e1210fc519b": {
"balance": "0x7E37BE2022B2B09472D89C0000"
}
},
"0x0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "activate_at": 7250000, "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0x0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "activate_at": 7250000, "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0x0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "activate_at": 7250000, "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0x0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "activate_at": 7250000, "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 7250000, "pricing": { "modexp": { "divisor": 20 } } } },
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 7250000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 7250000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 7250000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
},
"nodes": [
"enode://147573f46fe9f5cc38fbe070089a31390baec5dd2827c8f2ef168833e4d0254fbee3969a02c5b9910ea5d5b23d86a6ed5eabcda17cc12007b7d9178b6c697aa5@37.120.168.56:30303",
"enode://a370d5fd55959f20af6d1565b151a760c1372f5a2aaf674d4892cd4fd2de0d1f672781cd40e0d4e4b51c5823527ddec73b31cc14ac685449d9f0866996a16b9f@13.76.165.180:30303",
"enode://da019fa5fb1fda105100d68a986938ec15ac5c6ff69d6e4ad3e350e377057f3e67e33aea5feb22d5cdcfc22041d141c8453c77baa64a216fff98f191ca76b3ec@18.220.108.238:30303",
"enode://49498fb8cdcd79c813ccdaa9496a3a4be0a187a3183e99adbc04d9c90b9a62ad59f0b6832f6e43b48e63fbebf74ec5438eb0d6d9098330edf36413d276fedf81@13.80.148.117:30303"
"enode://eda34244538d72f42605a6fc8b8a34b15714c683989e8b29dc9e7a2b2088da490a5b32f2c149bec5a5c482bf03ec2c4f38b833ae31e36fcb26fb05fd094b2a88@18.197.33.9:30303",
"enode://12e903e900137b02b22e01f7918bd6e7310773c313e4e577281f35597e394a3e0b54c7314a8970a9776c5a3e5dc4daee289215dea3897bcb6d5cf0bb1dd2d356@18.197.31.231:30303",
"enode://423fdb91b37ec0714af0c19f625ec4af3ada2844367a36e45a05703577a84f7f0e9483585d4950a35c9e3738dba8c6abd7e1ce278d9a1f3f28065bc009f409cd@52.221.203.209:30303",
"enode://a9327d37d07799817d4a3e13d49fb4f5cc1486d4adf3ec8a6b98be62c4d7a5453914a5139dbe124809a388514cb0be37f9fa799539abe2250672f6d3d778b821@18.191.209.251:30303"
]
}

View File

@ -94,6 +94,7 @@ impl ClientService {
let pruning = config.pruning;
let client = Client::new(config, &spec, blockchain_db.clone(), miner.clone(), io_service.channel())?;
miner.set_io_channel(io_service.channel());
let snapshot_params = SnapServiceParams {
engine: spec.engine.clone(),

View File

@ -18,9 +18,9 @@
mod stores;
use self::stores::{AddressBook, DappsSettingsStore, NewDappsPolicy};
use self::stores::AddressBook;
use std::collections::{HashMap, HashSet};
use std::collections::HashMap;
use std::fmt;
use std::time::{Instant, Duration};
@ -96,20 +96,6 @@ impl From<SSError> for SignError {
/// `AccountProvider` errors.
pub type Error = SSError;
/// Dapp identifier
#[derive(Default, Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct DappId(String);
impl From<DappId> for String {
fn from(id: DappId) -> String { id.0 }
}
impl From<String> for DappId {
fn from(id: String) -> DappId { DappId(id) }
}
impl<'a> From<&'a str> for DappId {
fn from(id: &'a str) -> DappId { DappId(id.to_owned()) }
}
fn transient_sstore() -> EthMultiStore {
EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")
}
@ -125,8 +111,6 @@ pub struct AccountProvider {
unlocked: RwLock<HashMap<StoreAccountRef, AccountData>>,
/// Address book.
address_book: RwLock<AddressBook>,
/// Dapps settings.
dapps_settings: RwLock<DappsSettingsStore>,
/// Accounts on disk
sstore: Box<SecretStore>,
/// Accounts unlocked with rolling tokens
@ -167,7 +151,7 @@ impl AccountProvider {
/// Creates new account provider.
pub fn new(sstore: Box<SecretStore>, settings: AccountProviderSettings) -> Self {
let mut hardware_store = None;
if settings.enable_hardware_wallets {
match HardwareWalletManager::new() {
Ok(manager) => {
@ -195,7 +179,6 @@ impl AccountProvider {
unlocked_secrets: RwLock::new(HashMap::new()),
unlocked: RwLock::new(HashMap::new()),
address_book: RwLock::new(address_book),
dapps_settings: RwLock::new(DappsSettingsStore::new(&sstore.local_path())),
sstore: sstore,
transient_sstore: transient_sstore(),
hardware_store: hardware_store,
@ -210,7 +193,6 @@ impl AccountProvider {
unlocked_secrets: RwLock::new(HashMap::new()),
unlocked: RwLock::new(HashMap::new()),
address_book: RwLock::new(AddressBook::transient()),
dapps_settings: RwLock::new(DappsSettingsStore::transient()),
sstore: Box::new(EthStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")),
transient_sstore: transient_sstore(),
hardware_store: None,
@ -290,9 +272,14 @@ impl AccountProvider {
)
}
/// Returns the address of default account.
pub fn default_account(&self) -> Result<Address, Error> {
Ok(self.accounts()?.first().cloned().unwrap_or_default())
}
/// Returns addresses of hardware accounts.
pub fn hardware_accounts(&self) -> Result<Vec<Address>, Error> {
if let Some(accounts) = self.hardware_store.as_ref().map(|h| h.list_wallets()) {
if let Some(accounts) = self.hardware_store.as_ref().map(|h| h.list_wallets()) {
if !accounts.is_empty() {
return Ok(accounts.into_iter().map(|a| a.address).collect());
}
@ -308,7 +295,7 @@ impl AccountProvider {
Some(Ok(s)) => Ok(s),
}
}
/// Provide a pin to a locked hardware wallet on USB path to unlock it
pub fn hardware_pin_matrix_ack(&self, path: &str, pin: &str) -> Result<bool, SignError> {
match self.hardware_store.as_ref().map(|h| h.pin_matrix_ack(path, pin)) {
@ -318,175 +305,6 @@ impl AccountProvider {
}
}
/// Sets addresses of accounts exposed for unknown dapps.
/// `None` means that all accounts will be visible.
/// If not `None` or empty it will also override default account.
pub fn set_new_dapps_addresses(&self, accounts: Option<Vec<Address>>) -> Result<(), Error> {
let current_default = self.new_dapps_default_address()?;
self.dapps_settings.write().set_policy(match accounts {
None => NewDappsPolicy::AllAccounts {
default: current_default,
},
Some(accounts) => NewDappsPolicy::Whitelist(accounts),
});
Ok(())
}
/// Gets addresses of accounts exposed for unknown dapps.
/// `None` means that all accounts will be visible.
pub fn new_dapps_addresses(&self) -> Result<Option<Vec<Address>>, Error> {
Ok(match self.dapps_settings.read().policy() {
NewDappsPolicy::AllAccounts { .. } => None,
NewDappsPolicy::Whitelist(accounts) => Some(accounts),
})
}
/// Sets a default account for unknown dapps.
/// This account will always be returned as the first one.
pub fn set_new_dapps_default_address(&self, address: Address) -> Result<(), Error> {
if !self.valid_addresses()?.contains(&address) {
return Err(SSError::InvalidAccount.into());
}
let mut settings = self.dapps_settings.write();
let new_policy = match settings.policy() {
NewDappsPolicy::AllAccounts { .. } => NewDappsPolicy::AllAccounts { default: address },
NewDappsPolicy::Whitelist(list) => NewDappsPolicy::Whitelist(Self::insert_default(list, address)),
};
settings.set_policy(new_policy);
Ok(())
}
/// Inserts given address as first in the vector, preventing duplicates.
fn insert_default(mut addresses: Vec<Address>, default: Address) -> Vec<Address> {
if let Some(position) = addresses.iter().position(|address| address == &default) {
addresses.swap(0, position);
} else {
addresses.insert(0, default);
}
addresses
}
/// Returns a list of accounts that new dapp should see.
/// First account is always the default account.
fn new_dapps_addresses_list(&self) -> Result<Vec<Address>, Error> {
match self.dapps_settings.read().policy() {
NewDappsPolicy::AllAccounts { default } => if default.is_zero() {
self.accounts()
} else {
Ok(Self::insert_default(self.accounts()?, default))
},
NewDappsPolicy::Whitelist(accounts) => {
let addresses = self.filter_addresses(accounts)?;
if addresses.is_empty() {
Ok(vec![self.accounts()?.get(0).cloned().unwrap_or(0.into())])
} else {
Ok(addresses)
}
},
}
}
/// Gets a default account for new dapps
/// Will return zero address in case the default is not set and there are no accounts configured.
pub fn new_dapps_default_address(&self) -> Result<Address, Error> {
Ok(self.new_dapps_addresses_list()?
.get(0)
.cloned()
.unwrap_or(0.into())
)
}
/// Gets a list of dapps recently requesting accounts.
pub fn recent_dapps(&self) -> Result<HashMap<DappId, u64>, Error> {
Ok(self.dapps_settings.read().recent_dapps())
}
/// Marks dapp as recently used.
pub fn note_dapp_used(&self, dapp: DappId) -> Result<(), Error> {
let mut dapps = self.dapps_settings.write();
dapps.mark_dapp_used(dapp.clone());
Ok(())
}
/// Gets addresses visible for given dapp.
pub fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<Address>, Error> {
let accounts = self.dapps_settings.read().settings().get(&dapp).map(|settings| {
(settings.accounts.clone(), settings.default.clone())
});
match accounts {
Some((Some(accounts), Some(default))) => self.filter_addresses(Self::insert_default(accounts, default)),
Some((Some(accounts), None)) => self.filter_addresses(accounts),
Some((None, Some(default))) => self.filter_addresses(Self::insert_default(self.new_dapps_addresses_list()?, default)),
_ => self.new_dapps_addresses_list(),
}
}
/// Returns default account for particular dapp falling back to other allowed accounts if necessary.
pub fn dapp_default_address(&self, dapp: DappId) -> Result<Address, Error> {
let dapp_default = self.dapp_addresses(dapp)?
.get(0)
.cloned();
match dapp_default {
Some(default) => Ok(default),
None => self.new_dapps_default_address(),
}
}
/// Sets default address for given dapp.
/// Does not alter dapp addresses, but this account will always be returned as the first one.
pub fn set_dapp_default_address(&self, dapp: DappId, address: Address) -> Result<(), Error> {
if !self.valid_addresses()?.contains(&address) {
return Err(SSError::InvalidAccount.into());
}
self.dapps_settings.write().set_default(dapp, address);
Ok(())
}
/// Sets addresses visible for given dapp.
/// If `None` - falls back to dapps addresses
/// If not `None` and not empty it will also override default account.
pub fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<Address>>) -> Result<(), Error> {
let (addresses, default) = match addresses {
Some(addresses) => {
let addresses = self.filter_addresses(addresses)?;
let default = addresses.get(0).cloned();
(Some(addresses), default)
},
None => (None, None),
};
let mut settings = self.dapps_settings.write();
if let Some(default) = default {
settings.set_default(dapp.clone(), default);
}
settings.set_accounts(dapp, addresses);
Ok(())
}
fn valid_addresses(&self) -> Result<HashSet<Address>, Error> {
Ok(self.addresses_info().into_iter()
.map(|(address, _)| address)
.chain(self.accounts()?)
.collect())
}
/// Removes addresses that are neither accounts nor in address book.
fn filter_addresses(&self, addresses: Vec<Address>) -> Result<Vec<Address>, Error> {
let valid = self.valid_addresses()?;
Ok(addresses.into_iter()
.filter(|a| valid.contains(&a))
.collect()
)
}
/// Returns each address along with metadata.
pub fn addresses_info(&self) -> HashMap<Address, AccountMeta> {
self.address_book.read().get()
@ -849,7 +667,7 @@ impl AccountProvider {
#[cfg(test)]
mod tests {
use super::{AccountProvider, Unlock, DappId};
use super::{AccountProvider, Unlock};
use std::time::{Duration, Instant};
use ethstore::ethkey::{Generator, Random, Address};
use ethstore::{StoreAccountRef, Derivation};
@ -977,96 +795,6 @@ mod tests {
assert!(ap.sign_with_token(kp.address(), token, Default::default()).is_err(), "Second usage of the same token should fail.");
}
#[test]
fn should_reset_dapp_addresses_to_default() {
// given
let ap = AccountProvider::transient_provider();
let app = DappId("app1".into());
// add accounts to address book
ap.set_address_name(1.into(), "1".into());
ap.set_address_name(2.into(), "2".into());
// set `AllAccounts` policy
ap.set_new_dapps_addresses(Some(vec![1.into(), 2.into()])).unwrap();
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
// Alter and check
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 3.into()])).unwrap();
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
// Reset back to default
ap.set_dapp_addresses(app.clone(), None).unwrap();
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
}
#[test]
fn should_set_dapps_default_address() {
// given
let ap = AccountProvider::transient_provider();
let app = DappId("app1".into());
// set `AllAccounts` policy
ap.set_new_dapps_addresses(None).unwrap();
// add accounts to address book
ap.set_address_name(1.into(), "1".into());
ap.set_address_name(2.into(), "2".into());
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 2.into(), 3.into()])).unwrap();
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
// when setting empty list
ap.set_dapp_addresses(app.clone(), Some(vec![])).unwrap();
// then default account is intact
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
// alter default account
ap.set_dapp_default_address("app1".into(), 2.into()).unwrap();
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![2.into()]);
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 2.into());
}
#[test]
fn should_set_dapps_policy_and_default_account() {
// given
let ap = AccountProvider::transient_provider();
// default_account should be always available
assert_eq!(ap.new_dapps_default_address().unwrap(), 0.into());
let address = ap.new_account(&"test".into()).unwrap();
ap.set_address_name(1.into(), "1".into());
// Default account set to first account by default
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
// Even when returning nothing
ap.set_new_dapps_addresses(Some(vec![])).unwrap();
// Default account is still returned
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
// change to all
ap.set_new_dapps_addresses(None).unwrap();
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
// change to non-existent account
ap.set_new_dapps_addresses(Some(vec![2.into()])).unwrap();
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
// change to a addresses
ap.set_new_dapps_addresses(Some(vec![1.into()])).unwrap();
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![1.into()]);
// it overrides default account
assert_eq!(ap.new_dapps_default_address().unwrap(), 1.into());
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
ap.set_new_dapps_default_address(address).unwrap();
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
}
#[test]
fn should_not_return_blacklisted_account() {
// given

View File

@ -14,21 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Address Book and Dapps Settings Store
//! Address Book Store
use std::{fs, fmt, hash, ops};
use std::sync::atomic::{self, AtomicUsize};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use ethstore::ethkey::Address;
use ethjson::misc::{
AccountMeta,
DappsSettings as JsonSettings,
DappsHistory as JsonDappsHistory,
NewDappsPolicy as JsonNewDappsPolicy,
};
use account_provider::DappId;
use ethjson::misc::AccountMeta;
/// Disk-backed map from Address to String. Uses JSON.
pub struct AddressBook {
@ -88,214 +81,6 @@ impl AddressBook {
}
}
/// Dapps user settings
#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct DappsSettings {
/// A list of visible accounts
pub accounts: Option<Vec<Address>>,
/// Default account
pub default: Option<Address>,
}
impl From<JsonSettings> for DappsSettings {
fn from(s: JsonSettings) -> Self {
DappsSettings {
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
default: s.default.map(Into::into),
}
}
}
impl From<DappsSettings> for JsonSettings {
fn from(s: DappsSettings) -> Self {
JsonSettings {
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
default: s.default.map(Into::into),
}
}
}
/// Dapps user settings
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum NewDappsPolicy {
AllAccounts {
default: Address,
},
Whitelist(Vec<Address>),
}
impl From<JsonNewDappsPolicy> for NewDappsPolicy {
fn from(s: JsonNewDappsPolicy) -> Self {
match s {
JsonNewDappsPolicy::AllAccounts { default } => NewDappsPolicy::AllAccounts {
default: default.into(),
},
JsonNewDappsPolicy::Whitelist(accounts) => NewDappsPolicy::Whitelist(
accounts.into_iter().map(Into::into).collect()
),
}
}
}
impl From<NewDappsPolicy> for JsonNewDappsPolicy {
fn from(s: NewDappsPolicy) -> Self {
match s {
NewDappsPolicy::AllAccounts { default } => JsonNewDappsPolicy::AllAccounts {
default: default.into(),
},
NewDappsPolicy::Whitelist(accounts) => JsonNewDappsPolicy::Whitelist(
accounts.into_iter().map(Into::into).collect()
),
}
}
}
/// Transient dapps data
#[derive(Default, Debug, Clone, Eq, PartialEq)]
pub struct TransientDappsData {
/// Timestamp of last access
pub last_accessed: u64,
}
impl From<JsonDappsHistory> for TransientDappsData {
fn from(s: JsonDappsHistory) -> Self {
TransientDappsData {
last_accessed: s.last_accessed,
}
}
}
impl From<TransientDappsData> for JsonDappsHistory {
fn from(s: TransientDappsData) -> Self {
JsonDappsHistory {
last_accessed: s.last_accessed,
}
}
}
enum TimeProvider {
Clock,
Incremenetal(AtomicUsize)
}
impl TimeProvider {
fn get(&self) -> u64 {
match *self {
TimeProvider::Clock => {
::std::time::UNIX_EPOCH.elapsed()
.expect("Correct time is required to be set")
.as_secs()
},
TimeProvider::Incremenetal(ref time) => {
time.fetch_add(1, atomic::Ordering::SeqCst) as u64
},
}
}
}
const MAX_RECENT_DAPPS: usize = 50;
/// Disk-backed map from DappId to Settings. Uses JSON.
pub struct DappsSettingsStore {
/// Dapps Settings
settings: DiskMap<DappId, DappsSettings>,
/// New Dapps Policy
policy: DiskMap<String, NewDappsPolicy>,
/// Transient Data of recently Accessed Dapps
history: DiskMap<DappId, TransientDappsData>,
/// Time
time: TimeProvider,
}
impl DappsSettingsStore {
/// Creates new store at given directory path.
pub fn new(path: &Path) -> Self {
let mut r = DappsSettingsStore {
settings: DiskMap::new(path, "dapps_accounts.json".into()),
policy: DiskMap::new(path, "dapps_policy.json".into()),
history: DiskMap::new(path, "dapps_history.json".into()),
time: TimeProvider::Clock,
};
r.settings.revert(JsonSettings::read);
r.policy.revert(JsonNewDappsPolicy::read);
r.history.revert(JsonDappsHistory::read);
r
}
/// Creates transient store (no changes are saved to disk).
pub fn transient() -> Self {
DappsSettingsStore {
settings: DiskMap::transient(),
policy: DiskMap::transient(),
history: DiskMap::transient(),
time: TimeProvider::Incremenetal(AtomicUsize::new(1)),
}
}
/// Get copy of the dapps settings
pub fn settings(&self) -> HashMap<DappId, DappsSettings> {
self.settings.clone()
}
/// Returns current new dapps policy
pub fn policy(&self) -> NewDappsPolicy {
self.policy.get("default").cloned().unwrap_or(NewDappsPolicy::AllAccounts {
default: 0.into(),
})
}
/// Returns recent dapps with last accessed timestamp
pub fn recent_dapps(&self) -> HashMap<DappId, u64> {
self.history.iter().map(|(k, v)| (k.clone(), v.last_accessed)).collect()
}
/// Marks recent dapp as used
pub fn mark_dapp_used(&mut self, dapp: DappId) {
{
let entry = self.history.entry(dapp).or_insert_with(|| Default::default());
entry.last_accessed = self.time.get();
}
// Clear extraneous entries
while self.history.len() > MAX_RECENT_DAPPS {
let min = self.history.iter()
.min_by_key(|&(_, ref v)| v.last_accessed)
.map(|(ref k, _)| k.clone())
.cloned();
match min {
Some(k) => self.history.remove(&k),
None => break,
};
}
self.history.save(JsonDappsHistory::write);
}
/// Sets current new dapps policy
pub fn set_policy(&mut self, policy: NewDappsPolicy) {
self.policy.insert("default".into(), policy);
self.policy.save(JsonNewDappsPolicy::write);
}
/// Sets accounts for specific dapp.
pub fn set_accounts(&mut self, id: DappId, accounts: Option<Vec<Address>>) {
{
let settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
settings.accounts = accounts;
}
self.settings.save(JsonSettings::write);
}
/// Sets a default account for specific dapp.
pub fn set_default(&mut self, id: DappId, default: Address) {
{
let settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
settings.default = Some(default);
}
self.settings.save(JsonSettings::write);
}
}
/// Disk-serializable HashMap
#[derive(Debug)]
struct DiskMap<K: hash::Hash + Eq, V> {
@ -366,8 +151,7 @@ impl<K: hash::Hash + Eq, V> DiskMap<K, V> {
#[cfg(test)]
mod tests {
use super::{AddressBook, DappsSettingsStore, DappsSettings, NewDappsPolicy};
use account_provider::DappId;
use super::AddressBook;
use std::collections::HashMap;
use ethjson::misc::AccountMeta;
use tempdir::TempDir;
@ -398,63 +182,4 @@ mod tests {
3.into() => AccountMeta{name: "Three".to_owned(), meta: "{}".to_owned(), uuid: None}
]);
}
#[test]
fn should_save_and_reload_dapps_settings() {
// given
let tempdir = TempDir::new("").unwrap();
let mut b = DappsSettingsStore::new(tempdir.path());
// when
b.set_accounts("dappOne".into(), Some(vec![1.into(), 2.into()]));
// then
let b = DappsSettingsStore::new(tempdir.path());
assert_eq!(b.settings(), hash_map![
"dappOne".into() => DappsSettings {
accounts: Some(vec![1.into(), 2.into()]),
default: None,
}
]);
}
#[test]
fn should_maintain_a_map_of_recent_dapps() {
let mut store = DappsSettingsStore::transient();
assert!(store.recent_dapps().is_empty(), "Initially recent dapps should be empty.");
let dapp1: DappId = "dapp1".into();
let dapp2: DappId = "dapp2".into();
store.mark_dapp_used(dapp1.clone());
let recent = store.recent_dapps();
assert_eq!(recent.len(), 1);
assert_eq!(recent.get(&dapp1), Some(&1));
store.mark_dapp_used(dapp2.clone());
let recent = store.recent_dapps();
assert_eq!(recent.len(), 2);
assert_eq!(recent.get(&dapp1), Some(&1));
assert_eq!(recent.get(&dapp2), Some(&2));
}
#[test]
fn should_store_dapps_policy() {
// given
let tempdir = TempDir::new("").unwrap();
let mut store = DappsSettingsStore::new(tempdir.path());
// Test default policy
assert_eq!(store.policy(), NewDappsPolicy::AllAccounts {
default: 0.into(),
});
// when
store.set_policy(NewDappsPolicy::Whitelist(vec![1.into(), 2.into()]));
// then
let store = DappsSettingsStore::new(tempdir.path());
assert_eq!(store.policy.clone(), hash_map![
"default".into() => NewDappsPolicy::Whitelist(vec![1.into(), 2.into()])
]);
}
}

View File

@ -35,6 +35,7 @@ use encoded;
use engines::epoch::{Transition as EpochTransition, PendingTransition as PendingEpochTransition};
use engines::ForkChoice;
use ethereum_types::{H256, Bloom, BloomRef, U256};
use error::Error as EthcoreError;
use header::*;
use heapsize::HeapSizeOf;
use itertools::Itertools;
@ -60,6 +61,21 @@ pub trait BlockChainDB: Send + Sync {
/// Trace blooms database.
fn trace_blooms(&self) -> &blooms_db::Database;
/// Restore the DB from the given path
fn restore(&self, new_db: &str) -> Result<(), EthcoreError> {
// First, close the Blooms databases
self.blooms().close()?;
self.trace_blooms().close()?;
// Restore the key_value DB
self.key_value().restore(new_db)?;
// Re-open the Blooms databases
self.blooms().reopen()?;
self.trace_blooms().reopen()?;
Ok(())
}
}
/// Generic database handler. This trait contains one function `open`. When called, it opens database with a

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::{HashSet, BTreeMap, VecDeque};
use std::fmt;
use std::cmp;
use std::str::FromStr;
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::sync::{Arc, Weak};
@ -50,13 +50,16 @@ use client::{
};
use encoded;
use engines::{EthEngine, EpochTransition, ForkChoice};
use error::{ImportErrorKind, BlockImportErrorKind, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError};
use error::{
ImportErrorKind, BlockImportErrorKind, ExecutionError, CallError, BlockError, ImportResult,
QueueError, QueueErrorKind, Error as EthcoreError
};
use vm::{EnvInfo, LastHashes};
use evm::Schedule;
use executive::{Executive, Executed, TransactOptions, contract_address};
use factory::{Factories, VmFactory};
use header::{BlockNumber, Header, ExtendedHeader};
use io::{IoChannel, IoError};
use io::IoChannel;
use log_entry::LocalizedLogEntry;
use miner::{Miner, MinerService};
use ethcore_miner::pool::VerifiedTransaction;
@ -200,7 +203,7 @@ pub struct Client {
/// Flag changed by `sleep` and `wake_up` methods. Not to be confused with `enabled`.
liveness: AtomicBool,
io_channel: Mutex<IoChannel<ClientIoMessage>>,
io_channel: RwLock<IoChannel<ClientIoMessage>>,
/// List of actors to be notified on certain chain events
notify: RwLock<Vec<Weak<ChainNotify>>>,
@ -761,7 +764,7 @@ impl Client {
db: RwLock::new(db.clone()),
state_db: RwLock::new(state_db),
report: RwLock::new(Default::default()),
io_channel: Mutex::new(message_channel),
io_channel: RwLock::new(message_channel),
notify: RwLock::new(Vec::new()),
queue_transactions: IoChannelQueue::new(config.transaction_verification_queue_size),
queue_ancient_blocks: IoChannelQueue::new(MAX_ANCIENT_BLOCKS_QUEUE_SIZE),
@ -995,7 +998,7 @@ impl Client {
/// Replace io channel. Useful for testing.
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
*self.io_channel.lock() = io_channel;
*self.io_channel.write() = io_channel;
}
/// Get a copy of the best block's state.
@ -1293,9 +1296,7 @@ impl snapshot::DatabaseRestore for Client {
let mut tracedb = self.tracedb.write();
self.importer.miner.clear();
let db = self.db.write();
db.key_value().restore(new_db)?;
db.blooms().reopen()?;
db.trace_blooms().reopen()?;
db.restore(new_db)?;
let cache_size = state_db.cache_size();
*state_db = StateDB::new(journaldb::new(db.key_value().clone(), self.pruning, ::db::COL_STATE), cache_size);
@ -1952,7 +1953,25 @@ impl BlockChainClient for Client {
(*self.build_last_hashes(&self.chain.read().best_block_hash())).clone()
}
fn ready_transactions(&self, max_len: usize) -> Vec<Arc<VerifiedTransaction>> {
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>> {
const PROPAGATE_FOR_BLOCKS: u32 = 4;
const MIN_TX_TO_PROPAGATE: usize = 256;
let block_gas_limit = *self.best_block_header().gas_limit();
let min_tx_gas: U256 = self.latest_schedule().tx_gas.into();
let max_len = if min_tx_gas.is_zero() {
usize::max_value()
} else {
cmp::max(
MIN_TX_TO_PROPAGATE,
cmp::min(
(block_gas_limit / min_tx_gas) * PROPAGATE_FOR_BLOCKS,
// never more than usize
usize::max_value().into()
).as_u64() as usize
)
};
self.importer.miner.ready_transactions(self, max_len, ::miner::PendingOrdering::Priority)
}
@ -2011,7 +2030,7 @@ impl IoClient for Client {
fn queue_transactions(&self, transactions: Vec<Bytes>, peer_id: usize) {
trace_time!("queue_transactions");
let len = transactions.len();
self.queue_transactions.queue(&mut self.io_channel.lock(), len, move |client| {
self.queue_transactions.queue(&self.io_channel.read(), len, move |client| {
trace_time!("import_queued_transactions");
let txs: Vec<UnverifiedTransaction> = transactions
@ -2060,7 +2079,7 @@ impl IoClient for Client {
let queued = self.queued_ancient_blocks.clone();
let lock = self.ancient_blocks_import_lock.clone();
match self.queue_ancient_blocks.queue(&mut self.io_channel.lock(), 1, move |client| {
self.queue_ancient_blocks.queue(&self.io_channel.read(), 1, move |client| {
trace_time!("import_ancient_block");
// Make sure to hold the lock here to prevent importing out of order.
// We use separate lock, cause we don't want to block queueing.
@ -2085,14 +2104,13 @@ impl IoClient for Client {
break;
}
}
}) {
Ok(_) => Ok(hash),
Err(e) => bail!(BlockImportErrorKind::Other(format!("{}", e))),
}
})?;
Ok(hash)
}
fn queue_consensus_message(&self, message: Bytes) {
match self.queue_consensus_message.queue(&mut self.io_channel.lock(), 1, move |client| {
match self.queue_consensus_message.queue(&self.io_channel.read(), 1, move |client| {
if let Err(e) = client.engine().handle_message(&message) {
debug!(target: "poa", "Invalid message received: {}", e);
}
@ -2202,7 +2220,14 @@ impl ImportSealedBlock for Client {
route
};
let route = ChainRoute::from([route].as_ref());
self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), self.engine.seals_internally().is_some());
self.importer.miner.chain_new_blocks(
self,
&[h.clone()],
&[],
route.enacted(),
route.retracted(),
self.engine.seals_internally().is_some(),
);
self.notify(|notify| {
notify.new_blocks(
vec![h.clone()],
@ -2497,21 +2522,6 @@ mod tests {
}
}
#[derive(Debug)]
enum QueueError {
Channel(IoError),
Full(usize),
}
impl fmt::Display for QueueError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
QueueError::Channel(ref c) => fmt::Display::fmt(c, fmt),
QueueError::Full(limit) => write!(fmt, "The queue is full ({})", limit),
}
}
}
/// Queue some items to be processed by IO client.
struct IoChannelQueue {
currently_queued: Arc<AtomicUsize>,
@ -2526,11 +2536,11 @@ impl IoChannelQueue {
}
}
pub fn queue<F>(&self, channel: &mut IoChannel<ClientIoMessage>, count: usize, fun: F) -> Result<(), QueueError> where
pub fn queue<F>(&self, channel: &IoChannel<ClientIoMessage>, count: usize, fun: F) -> Result<(), QueueError> where
F: Fn(&Client) + Send + Sync + 'static,
{
let queue_size = self.currently_queued.load(AtomicOrdering::Relaxed);
ensure!(queue_size < self.limit, QueueError::Full(self.limit));
ensure!(queue_size < self.limit, QueueErrorKind::Full(self.limit));
let currently_queued = self.currently_queued.clone();
let result = channel.send(ClientIoMessage::execute(move |client| {
@ -2543,7 +2553,7 @@ impl IoChannelQueue {
self.currently_queued.fetch_add(count, AtomicOrdering::SeqCst);
Ok(())
},
Err(e) => Err(QueueError::Channel(e)),
Err(e) => bail!(QueueErrorKind::Channel(e)),
}
}
}

View File

@ -805,8 +805,8 @@ impl BlockChainClient for TestBlockChainClient {
self.traces.read().clone()
}
fn ready_transactions(&self, max_len: usize) -> Vec<Arc<VerifiedTransaction>> {
self.miner.ready_transactions(self, max_len, miner::PendingOrdering::Priority)
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>> {
self.miner.ready_transactions(self, 4096, miner::PendingOrdering::Priority)
}
fn signing_chain_id(&self) -> Option<u64> { None }

View File

@ -320,8 +320,8 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra
/// Get last hashes starting from best block.
fn last_hashes(&self) -> LastHashes;
/// List all transactions that are allowed into the next block.
fn ready_transactions(&self, max_len: usize) -> Vec<Arc<VerifiedTransaction>>;
/// List all ready transactions that should be propagated to other peers.
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>>;
/// Sorted list of transaction gas prices from at least last sample_size blocks.
fn gas_price_corpus(&self, sample_size: usize) -> ::stats::Corpus<U256> {

View File

@ -984,8 +984,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
self.clear_empty_steps(parent_step);
// report any skipped primaries between the parent block and
// the block we're sealing
self.report_skipped(header, step, u64::from(parent_step) as usize, &*validators, set_number);
// the block we're sealing, unless we have empty steps enabled
if header.number() < self.empty_steps_transition {
self.report_skipped(header, step, u64::from(parent_step) as usize, &*validators, set_number);
}
let mut fields = vec![
encode(&step).into_vec(),
@ -1149,9 +1151,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
// If empty step messages are enabled we will validate the messages in the seal, missing messages are not
// reported as there's no way to tell whether the empty step message was never sent or simply not included.
if header.number() >= self.empty_steps_transition {
let validate_empty_steps = || -> Result<(), Error> {
let empty_steps_len = if header.number() >= self.empty_steps_transition {
let validate_empty_steps = || -> Result<usize, Error> {
let empty_steps = header_empty_steps(header)?;
let empty_steps_len = empty_steps.len();
for empty_step in empty_steps {
if empty_step.step <= parent_step || empty_step.step >= step {
Err(EngineError::InsufficientProof(
@ -1168,16 +1171,27 @@ impl Engine<EthereumMachine> for AuthorityRound {
format!("invalid empty step proof: {:?}", empty_step)))?;
}
}
Ok(())
Ok(empty_steps_len)
};
if let err @ Err(_) = validate_empty_steps() {
self.validators.report_benign(header.author(), set_number, header.number());
return err;
match validate_empty_steps() {
Ok(len) => len,
Err(err) => {
self.validators.report_benign(header.author(), set_number, header.number());
return Err(err);
},
}
} else {
self.report_skipped(header, step, parent_step, &*validators, set_number);
0
};
if header.number() >= self.validate_score_transition {
let expected_difficulty = calculate_score(parent_step.into(), step.into(), empty_steps_len.into());
if header.difficulty() != &expected_difficulty {
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() })));
}
}
Ok(())
@ -1412,7 +1426,7 @@ mod tests {
use engines::{Seal, Engine, EngineError, EthEngine};
use engines::validator_set::TestSet;
use error::{Error, ErrorKind};
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep};
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
#[test]
fn has_valid_metadata() {
@ -1518,12 +1532,15 @@ mod tests {
let engine = Spec::new_test_round().engine;
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
// Two validators.
// Spec starts with step 2.
header.set_difficulty(calculate_score(U256::from(0), U256::from(2), U256::zero()));
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
header.set_seal(vec![encode(&2usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
assert!(engine.verify_block_external(&header).is_err());
header.set_difficulty(calculate_score(U256::from(0), U256::from(1), U256::zero()));
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
assert!(engine.verify_block_external(&header).is_ok());
@ -1544,9 +1561,10 @@ mod tests {
let engine = Spec::new_test_round().engine;
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
// Two validators.
// Spec starts with step 2.
header.set_difficulty(calculate_score(U256::from(0), U256::from(1), U256::zero()));
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
header.set_seal(vec![encode(&1usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
assert!(engine.verify_block_external(&header).is_ok());
@ -1573,8 +1591,10 @@ mod tests {
// Two validators.
// Spec starts with step 2.
header.set_seal(vec![encode(&5usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
header.set_difficulty(calculate_score(U256::from(4), U256::from(5), U256::zero()));
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
header.set_seal(vec![encode(&3usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
header.set_difficulty(calculate_score(U256::from(4), U256::from(3), U256::zero()));
assert!(engine.verify_block_family(&header, &parent_header).is_err());
}
@ -1608,6 +1628,7 @@ mod tests {
parent_header.set_seal(vec![encode(&1usize).into_vec()]);
parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
let mut header: Header = Header::default();
header.set_difficulty(calculate_score(U256::from(1), U256::from(3), U256::zero()));
header.set_gas_limit("222222".parse::<U256>().unwrap());
header.set_seal(vec![encode(&3usize).into_vec()]);
@ -1967,16 +1988,15 @@ mod tests {
let empty_step3 = sealed_empty_step(engine, 3, &parent_header.hash());
let empty_steps = vec![empty_step2, empty_step3];
header.set_difficulty(calculate_score(U256::from(0), U256::from(4), U256::from(2)));
let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap();
header.set_seal(vec![
encode(&4usize).into_vec(),
encode(&(&*signature as &[u8])).into_vec(),
::rlp::encode_list(&empty_steps).into_vec(),
]);
assert!(match engine.verify_block_family(&header, &parent_header) {
Ok(_) => true,
_ => false,
});
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
}
#[test]

View File

@ -151,6 +151,24 @@ impl error::Error for BlockError {
}
}
error_chain! {
types {
QueueError, QueueErrorKind, QueueErrorResultExt, QueueErrorResult;
}
errors {
#[doc = "Queue is full"]
Full(limit: usize) {
description("Queue is full")
display("The queue is full ({})", limit)
}
}
foreign_links {
Channel(IoError) #[doc = "Io channel error"];
}
}
error_chain! {
types {
ImportError, ImportErrorKind, ImportErrorResultExt, ImportErrorResult;
@ -184,6 +202,7 @@ error_chain! {
links {
Import(ImportError, ImportErrorKind) #[doc = "Import error"];
Queue(QueueError, QueueErrorKind) #[doc = "Io channel queue error"];
}
foreign_links {

View File

@ -20,7 +20,7 @@ use std::collections::BTreeMap;
use std::sync::Arc;
use hash::{KECCAK_EMPTY_LIST_RLP};
use engines::block_reward::{self, RewardKind};
use ethash::{quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
use ethereum_types::{H256, H64, U256, Address};
use unexpected::{OutOfBounds, Mismatch};
use block::*;
@ -280,11 +280,18 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
block_reward::apply_block_rewards(&rewards, block, &self.machine)
}
#[cfg(not(feature = "miner-debug"))]
fn verify_local_seal(&self, header: &Header) -> Result<(), Error> {
self.verify_block_basic(header)
.and_then(|_| self.verify_block_unordered(header))
}
#[cfg(feature = "miner-debug")]
fn verify_local_seal(&self, _header: &Header) -> Result<(), Error> {
warn!("Skipping seal verification, running in miner testing mode.");
Ok(())
}
fn verify_block_basic(&self, header: &Header) -> Result<(), Error> {
// check the seal fields.
let seal = Seal::parse_seal(header.seal())?;
@ -295,7 +302,7 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
return Err(From::from(BlockError::DifficultyOutOfBounds(OutOfBounds { min: Some(min_difficulty), max: None, found: header.difficulty().clone() })))
}
let difficulty = Ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
let difficulty = ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
&header.bare_hash().0,
seal.nonce.low_u64(),
&seal.mix_hash.0
@ -317,7 +324,7 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, seal.nonce.low_u64());
let mix = H256(result.mix_hash);
let difficulty = Ethash::boundary_to_difficulty(&H256(result.value));
let difficulty = ethash::boundary_to_difficulty(&H256(result.value));
trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}",
num = header.number() as u64,
seed = H256(slow_hash_block_number(header.number() as u64)),
@ -440,25 +447,6 @@ impl Ethash {
}
target
}
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
pub fn boundary_to_difficulty(boundary: &H256) -> U256 {
let d = U256::from(*boundary);
if d <= U256::one() {
U256::max_value()
} else {
((U256::one() << 255) / d) << 1
}
}
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
pub fn difficulty_to_boundary(difficulty: &U256) -> H256 {
if *difficulty <= U256::one() {
U256::max_value().into()
} else {
(((U256::one() << 255) / *difficulty) << 1).into()
}
}
}
fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u64) -> (u64, U256) {
@ -759,16 +747,6 @@ mod tests {
}
}
#[test]
fn test_difficulty_to_boundary() {
// result of f(0) is undefined, so do not assert the result
let _ = Ethash::difficulty_to_boundary(&U256::from(0));
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(1)), H256::from(U256::max_value()));
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(2)), H256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(4)), H256::from_str("4000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap());
}
#[test]
fn difficulty_frontier() {
let machine = new_homestead_test_machine();

View File

@ -41,31 +41,31 @@ fn load_machine(b: &[u8]) -> EthereumMachine {
Spec::load_machine(b).expect("chain spec is invalid")
}
/// Create a new Foundation Olympic chain spec.
pub fn new_olympic<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/olympic.json"))
}
/// Create a new Foundation Mainnet chain spec.
/// Create a new Foundation mainnet chain spec.
pub fn new_foundation<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/foundation.json"))
}
/// Create a new Classic Mainnet chain spec without the DAO hardfork.
/// Create a new Classic mainnet chain spec without the DAO hardfork.
pub fn new_classic<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/classic.json"))
}
/// Create a new POA Network mainnet chain spec.
pub fn new_poanet<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/poacore.json"))
}
/// Create a new Tobalaba mainnet chain spec.
pub fn new_tobalaba<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/tobalaba.json"))
}
/// Create a new Expanse mainnet chain spec.
pub fn new_expanse<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/expanse.json"))
}
/// Create a new Tobalaba chain spec.
pub fn new_tobalaba<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/tobalaba.json"))
}
/// Create a new Musicoin mainnet chain spec.
pub fn new_musicoin<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/musicoin.json"))
@ -86,19 +86,29 @@ pub fn new_social<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/social.json"))
}
/// Create a new Olympic testnet chain spec.
pub fn new_olympic<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/olympic.json"))
}
/// Create a new Morden testnet chain spec.
pub fn new_morden<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/morden.json"))
}
/// Create a new Ropsten testnet chain spec.
pub fn new_ropsten<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/ropsten.json"))
}
/// Create a new Kovan testnet chain spec.
pub fn new_kovan<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/kovan.json"))
}
/// Create a new Foundation Ropsten chain spec.
pub fn new_ropsten<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/ropsten.json"))
}
/// Create a new Morden chain spec.
pub fn new_morden<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/morden.json"))
/// Create a new POA Sokol testnet chain spec.
pub fn new_sokol<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/poasokol.json"))
}
// For tests

View File

@ -28,6 +28,7 @@ use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStat
#[cfg(feature = "work-notify")]
use ethcore_miner::work_notify::NotifyWork;
use ethereum_types::{H256, U256, Address};
use io::IoChannel;
use parking_lot::{Mutex, RwLock};
use rayon::prelude::*;
use transaction::{
@ -44,7 +45,7 @@ use block::{ClosedBlock, IsBlock, Block, SealedBlock};
use client::{
BlockChain, ChainInfo, CallContract, BlockProducer, SealedBlockImporter, Nonce
};
use client::BlockId;
use client::{BlockId, ClientIoMessage};
use executive::contract_address;
use header::{Header, BlockNumber};
use miner;
@ -96,7 +97,7 @@ const DEFAULT_MINIMAL_GAS_PRICE: u64 = 20_000_000_000;
/// before stopping attempts to push more transactions to the block.
/// This is an optimization that prevents traversing the entire pool
/// in case we have only a fraction of available block gas limit left.
const MAX_SKIPPED_TRANSACTIONS: usize = 8;
const MAX_SKIPPED_TRANSACTIONS: usize = 128;
/// Configures the behaviour of the miner.
#[derive(Debug, PartialEq)]
@ -211,6 +212,7 @@ pub struct Miner {
transaction_queue: Arc<TransactionQueue>,
engine: Arc<EthEngine>,
accounts: Option<Arc<AccountProvider>>,
io_channel: RwLock<Option<IoChannel<ClientIoMessage>>>,
}
impl Miner {
@ -227,7 +229,12 @@ impl Miner {
}
/// Creates new instance of miner Arc.
pub fn new(options: MinerOptions, gas_pricer: GasPricer, spec: &Spec, accounts: Option<Arc<AccountProvider>>) -> Self {
pub fn new(
options: MinerOptions,
gas_pricer: GasPricer,
spec: &Spec,
accounts: Option<Arc<AccountProvider>>,
) -> Self {
let limits = options.pool_limits.clone();
let verifier_options = options.pool_verification_options.clone();
let tx_queue_strategy = options.tx_queue_strategy;
@ -251,6 +258,7 @@ impl Miner {
transaction_queue: Arc::new(TransactionQueue::new(limits, verifier_options, tx_queue_strategy)),
accounts,
engine: spec.engine.clone(),
io_channel: RwLock::new(None),
}
}
@ -270,6 +278,11 @@ impl Miner {
}, GasPricer::new_fixed(minimal_gas_price), spec, accounts)
}
/// Sets `IoChannel`
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
*self.io_channel.write() = Some(io_channel);
}
/// Clear all pending block states
pub fn clear(&self) {
self.sealing.lock().queue.reset();
@ -293,14 +306,15 @@ impl Miner {
/// Retrieves an existing pending block iff it's not older than given block number.
///
/// NOTE: This will not prepare a new pending block if it's not existing.
/// See `map_pending_block` for alternative behaviour.
fn map_existing_pending_block<F, T>(&self, f: F, latest_block_number: BlockNumber) -> Option<T> where
F: FnOnce(&ClosedBlock) -> T,
{
self.sealing.lock().queue
.peek_last_ref()
.and_then(|b| {
if b.block().header().number() > latest_block_number {
// to prevent a data race between block import and updating pending block
// we allow the number to be equal.
if b.block().header().number() >= latest_block_number {
Some(f(b))
} else {
None
@ -339,7 +353,7 @@ impl Miner {
// if at least one was pushed successfully, close and enqueue new ClosedBlock;
// otherwise, leave everything alone.
// otherwise, author a fresh block.
let mut open_block = match sealing.queue.pop_if(|b| b.block().header().parent_hash() == &best_hash) {
let mut open_block = match sealing.queue.get_pending_if(|b| b.block().header().parent_hash() == &best_hash) {
Some(old_block) => {
trace!(target: "miner", "prepare_block: Already have previous work; updating and returning");
// add transactions to old_block
@ -384,7 +398,7 @@ impl Miner {
let max_transactions = if min_tx_gas.is_zero() {
usize::max_value()
} else {
(*open_block.block().header().gas_limit() / min_tx_gas).as_u64() as usize
MAX_SKIPPED_TRANSACTIONS.saturating_add(cmp::min(*open_block.block().header().gas_limit() / min_tx_gas, u64::max_value().into()).as_u64() as usize)
};
let pending: Vec<Arc<_>> = self.transaction_queue.pending(
@ -589,7 +603,7 @@ impl Miner {
{
let mut sealing = self.sealing.lock();
sealing.next_mandatory_reseal = Instant::now() + self.options.reseal_max_period;
sealing.queue.push(block.clone());
sealing.queue.set_pending(block.clone());
sealing.queue.use_last_ref();
}
@ -651,7 +665,7 @@ impl Miner {
);
let is_new = original_work_hash.map_or(true, |h| h != block_hash);
sealing.queue.push(block);
sealing.queue.set_pending(block);
#[cfg(feature = "work-notify")]
{
@ -1042,10 +1056,12 @@ impl miner::MinerService for Miner {
// refuse to seal the first block of the chain if it contains hard forks
// which should be on by default.
if block.block().header().number() == 1 && self.engine.params().contains_bugfix_hard_fork() {
warn!("Your chain specification contains one or more hard forks which are required to be \
on by default. Please remove these forks and start your chain again.");
return;
if block.block().header().number() == 1 {
if let Some(name) = self.engine.params().nonzero_bugfix_hard_fork() {
warn!("Your chain specification contains one or more hard forks which are required to be \
on by default. Please remove these forks and start your chain again: {}.", name);
return;
}
}
match self.engine.seals_internally() {
@ -1058,7 +1074,7 @@ impl miner::MinerService for Miner {
Some(false) => {
trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now");
// anyway, save the block for later use
self.sealing.lock().queue.push(block);
self.sealing.lock().queue.set_pending(block);
},
None => {
trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work");
@ -1176,7 +1192,32 @@ impl miner::MinerService for Miner {
// (thanks to Ready), but culling can take significant amount of time,
// so best to leave it after we create some work for miners to prevent increased
// uncle rate.
self.transaction_queue.cull(client);
// If the io_channel is available attempt to offload culling to a separate task
// to avoid blocking chain_new_blocks
if let Some(ref channel) = *self.io_channel.read() {
let queue = self.transaction_queue.clone();
let nonce_cache = self.nonce_cache.clone();
let engine = self.engine.clone();
let accounts = self.accounts.clone();
let refuse_service_transactions = self.options.refuse_service_transactions;
let cull = move |chain: &::client::Client| {
let client = PoolClient::new(
chain,
&nonce_cache,
&*engine,
accounts.as_ref().map(|x| &**x),
refuse_service_transactions,
);
queue.cull(client);
};
if let Err(e) = channel.send(ClientIoMessage::execute(cull)) {
warn!(target: "miner", "Error queueing cull: {:?}", e);
}
} else {
self.transaction_queue.cull(client);
}
}
}

View File

@ -16,8 +16,11 @@
//! Blockchain access for transaction pool.
use std::fmt;
use std::collections::HashMap;
use std::{
collections::HashMap,
fmt,
sync::Arc,
};
use ethereum_types::{H256, U256, Address};
use ethcore_miner::pool;
@ -37,9 +40,9 @@ use miner;
use miner::service_transaction_checker::ServiceTransactionChecker;
/// Cache for state nonces.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct NonceCache {
nonces: RwLock<HashMap<Address, U256>>,
nonces: Arc<RwLock<HashMap<Address, U256>>>,
limit: usize
}
@ -47,7 +50,7 @@ impl NonceCache {
/// Create new cache with a limit of `limit` entries.
pub fn new(limit: usize) -> Self {
NonceCache {
nonces: RwLock::new(HashMap::with_capacity(limit / 2)),
nonces: Arc::new(RwLock::new(HashMap::with_capacity(limit / 2))),
limit,
}
}

View File

@ -22,8 +22,7 @@ use std::fmt;
use client::{Client, ImportSealedBlock};
use ethereum_types::{H64, H256, clean_0x, U256};
use ethereum::ethash::Ethash;
use ethash::SeedHashCompute;
use ethash::{self, SeedHashCompute};
#[cfg(feature = "work-notify")]
use ethcore_miner::work_notify::NotifyWork;
#[cfg(feature = "work-notify")]
@ -167,7 +166,7 @@ impl StratumJobDispatcher {
/// Serializes payload for stratum service
fn payload(&self, pow_hash: H256, difficulty: U256, number: u64) -> String {
// TODO: move this to engine
let target = Ethash::difficulty_to_boundary(&difficulty);
let target = ethash::difficulty_to_boundary(&difficulty);
let seed_hash = &self.seed_compute.lock().hash_block_number(number);
let seed_hash = H256::from_slice(&seed_hash[..]);
format!(

View File

@ -57,7 +57,7 @@ fn fmt_err<F: ::std::fmt::Display>(f: F) -> String {
/// Parameters common to ethereum-like blockchains.
/// NOTE: when adding bugfix hard-fork parameters,
/// add to `contains_bugfix_hard_fork`
/// add to `nonzero_bugfix_hard_fork`
///
/// we define a "bugfix" hard fork as any hard fork which
/// you would put on-by-default in a new chain.
@ -188,13 +188,21 @@ impl CommonParams {
}
}
/// Whether these params contain any bug-fix hard forks.
pub fn contains_bugfix_hard_fork(&self) -> bool {
self.eip98_transition != 0 && self.eip155_transition != 0 &&
self.validate_receipts_transition != 0 && self.eip86_transition != 0 &&
self.eip140_transition != 0 && self.eip210_transition != 0 &&
self.eip211_transition != 0 && self.eip214_transition != 0 &&
self.validate_chain_id_transition != 0 && self.dust_protection_transition != 0
/// Return Some if the current parameters contain a bugfix hard fork not on block 0.
pub fn nonzero_bugfix_hard_fork(&self) -> Option<&str> {
if self.eip155_transition != 0 {
return Some("eip155Transition");
}
if self.validate_receipts_transition != 0 {
return Some("validateReceiptsTransition");
}
if self.validate_chain_id_transition != 0 {
return Some("validateChainIdTransition");
}
None
}
}

View File

@ -334,11 +334,11 @@ fn does_not_propagate_delayed_transactions() {
client.miner().import_own_transaction(&*client, tx0).unwrap();
client.miner().import_own_transaction(&*client, tx1).unwrap();
assert_eq!(0, client.ready_transactions(10).len());
assert_eq!(0, client.transactions_to_propagate().len());
assert_eq!(0, client.miner().ready_transactions(&*client, 10, PendingOrdering::Priority).len());
push_blocks_to_client(&client, 53, 2, 2);
client.flush_queue();
assert_eq!(2, client.ready_transactions(10).len());
assert_eq!(2, client.transactions_to_propagate().len());
assert_eq!(2, client.miner().ready_transactions(&*client, 10, PendingOrdering::Priority).len());
}

View File

@ -8,6 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[lib]
[dependencies]
common-types = { path = "../types" }
parity-bytes = { git = "https://github.com/paritytech/parity-common" }
ethcore-network = { path = "../../util/network" }
ethcore-network-devp2p = { path = "../../util/network-devp2p" }

View File

@ -24,6 +24,8 @@ use devp2p::NetworkService;
use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind,
ConnectionFilter};
use types::pruning_info::PruningInfo;
use ethereum_types::{H256, H512, U256};
use io::{TimerToken};
use ethcore::ethstore::ethkey::Secret;
@ -39,7 +41,10 @@ use chain::{ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_62,
PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3};
use light::client::AsLightClient;
use light::Provider;
use light::net::{self as light_net, LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext};
use light::net::{
self as light_net, LightProtocol, Params as LightParams,
Capabilities, Handler as LightHandler, EventContext, SampleStore,
};
use network::IpFilter;
use private_tx::PrivateTxHandler;
use transaction::UnverifiedTransaction;
@ -256,11 +261,35 @@ pub struct EthSync {
light_subprotocol_name: [u8; 3],
}
fn light_params(
network_id: u64,
max_peers: u32,
pruning_info: PruningInfo,
sample_store: Option<Box<SampleStore>>,
) -> LightParams {
const MAX_LIGHTSERV_LOAD: f64 = 0.5;
let mut light_params = LightParams {
network_id: network_id,
config: Default::default(),
capabilities: Capabilities {
serve_headers: true,
serve_chain_since: Some(pruning_info.earliest_chain),
serve_state_since: Some(pruning_info.earliest_state),
tx_relay: true,
},
sample_store: sample_store,
};
let max_peers = ::std::cmp::max(max_peers, 1);
light_params.config.load_share = MAX_LIGHTSERV_LOAD / max_peers as f64;
light_params
}
impl EthSync {
/// Creates and register protocol with the network service
pub fn new(params: Params, connection_filter: Option<Arc<ConnectionFilter>>) -> Result<Arc<EthSync>, Error> {
const MAX_LIGHTSERV_LOAD: f64 = 0.5;
let pruning_info = params.chain.pruning_info();
let light_proto = match params.config.serve_light {
false => None,
@ -271,20 +300,12 @@ impl EthSync {
.map(|mut p| { p.push("request_timings"); light_net::FileStore(p) })
.map(|store| Box::new(store) as Box<_>);
let mut light_params = LightParams {
network_id: params.config.network_id,
config: Default::default(),
capabilities: Capabilities {
serve_headers: true,
serve_chain_since: Some(pruning_info.earliest_chain),
serve_state_since: Some(pruning_info.earliest_state),
tx_relay: true,
},
sample_store: sample_store,
};
let max_peers = ::std::cmp::min(params.network_config.max_peers, 1);
light_params.config.load_share = MAX_LIGHTSERV_LOAD / max_peers as f64;
let light_params = light_params(
params.config.network_id,
params.network_config.max_peers,
pruning_info,
sample_store,
);
let mut light_proto = LightProtocol::new(params.provider, light_params);
light_proto.add_handler(Arc::new(TxRelay(params.chain.clone())));
@ -916,3 +937,19 @@ impl LightSyncProvider for LightSync {
Default::default() // TODO
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn light_params_load_share_depends_on_max_peers() {
let pruning_info = PruningInfo {
earliest_chain: 0,
earliest_state: 0,
};
let params1 = light_params(0, 10, pruning_info.clone(), None);
let params2 = light_params(0, 20, pruning_info, None);
assert!(params1.config.load_share > params2.config.load_share)
}
}

View File

@ -23,11 +23,11 @@ use std::cmp;
use heapsize::HeapSizeOf;
use ethereum_types::H256;
use rlp::Rlp;
use ethcore::block::Block;
use ethcore::views::BlockView;
use ethcore::header::{BlockNumber, Header as BlockHeader};
use ethcore::client::{BlockStatus, BlockId, BlockImportError, BlockImportErrorKind};
use ethcore::block::Block;
use ethcore::error::{ImportErrorKind, BlockError};
use ethcore::error::{ImportErrorKind, QueueErrorKind, BlockError};
use sync_io::SyncIo;
use blocks::BlockCollection;
@ -477,18 +477,19 @@ impl BlockDownloader {
for block_and_receipts in blocks {
let block = block_and_receipts.block;
let receipts = block_and_receipts.receipts;
// Perform basic block verification
if !Block::is_good(&block) {
debug!(target: "sync", "Bad block rlp: {:?}", block);
bad = true;
break;
}
let (h, number, parent) = {
let header = view!(BlockView, &block).header_view();
(header.hash(), header.number(), header.parent_hash())
};
// Perform basic block verification
if !Block::is_good(&block) {
debug!(target: "sync", "Bad block rlp {:?} : {:?}", h, block);
bad = true;
break;
}
if self.target_hash.as_ref().map_or(false, |t| t == &h) {
self.state = State::Complete;
trace!(target: "sync", "Sync target reached");
@ -526,6 +527,10 @@ impl BlockDownloader {
debug!(target: "sync", "Block temporarily invalid, restarting sync");
break;
},
Err(BlockImportError(BlockImportErrorKind::Queue(QueueErrorKind::Full(limit)), _)) => {
debug!(target: "sync", "Block import queue full ({}), restarting sync", limit);
break;
},
Err(e) => {
debug!(target: "sync", "Bad block {:?} : {:?}", h, e);
bad = true;

View File

@ -149,12 +149,6 @@ const MAX_NEW_HASHES: usize = 64;
const MAX_NEW_BLOCK_AGE: BlockNumber = 20;
// maximal packet size with transactions (cannot be greater than 16MB - protocol limitation).
const MAX_TRANSACTION_PACKET_SIZE: usize = 8 * 1024 * 1024;
// Maximal number of transactions queried from miner to propagate.
// This set is used to diff with transactions known by the peer and
// we will send a difference of length up to `MAX_TRANSACTIONS_TO_PROPAGATE`.
const MAX_TRANSACTIONS_TO_QUERY: usize = 4096;
// Maximal number of transactions in sent in single packet.
const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64;
// Min number of blocks to be behind for a snapshot sync
const SNAPSHOT_RESTORE_THRESHOLD: BlockNumber = 30000;
const SNAPSHOT_MIN_PEERS: usize = 3;
@ -761,14 +755,24 @@ impl ChainSync {
}
}
// Only ask for old blocks if the peer has a higher difficulty
if force || higher_difficulty {
// Only ask for old blocks if the peer has a higher difficulty than the last imported old block
let last_imported_old_block_difficulty = self.old_blocks.as_mut().and_then(|d| {
io.chain().block_total_difficulty(BlockId::Number(d.last_imported_block_number()))
});
if force || last_imported_old_block_difficulty.map_or(true, |ld| peer_difficulty.map_or(true, |pd| pd > ld)) {
if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) {
SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::OldBlocks);
return;
}
} else {
trace!(target: "sync", "peer {} is not suitable for asking old blocks", peer_id);
trace!(
target: "sync",
"peer {:?} is not suitable for requesting old blocks, last_imported_old_block_difficulty={:?}, peer_difficulty={:?}",
peer_id,
last_imported_old_block_difficulty,
peer_difficulty
);
self.deactivate_peer(io, peer_id);
}
},

View File

@ -29,11 +29,9 @@ use transaction::SignedTransaction;
use super::{
random,
ChainSync,
MAX_TRANSACTION_PACKET_SIZE,
MAX_PEER_LAG_PROPAGATION,
MAX_PEERS_PROPAGATION,
MAX_TRANSACTION_PACKET_SIZE,
MAX_TRANSACTIONS_TO_PROPAGATE,
MAX_TRANSACTIONS_TO_QUERY,
MIN_PEERS_PROPAGATION,
CONSENSUS_DATA_PACKET,
NEW_BLOCK_HASHES_PACKET,
@ -121,7 +119,7 @@ impl SyncPropagator {
return 0;
}
let transactions = io.chain().ready_transactions(MAX_TRANSACTIONS_TO_QUERY);
let transactions = io.chain().transactions_to_propagate();
if transactions.is_empty() {
return 0;
}
@ -184,7 +182,6 @@ impl SyncPropagator {
// Get hashes of all transactions to send to this peer
let to_send = all_transactions_hashes.difference(&peer_info.last_sent_transactions)
.take(MAX_TRANSACTIONS_TO_PROPAGATE)
.cloned()
.collect::<HashSet<_>>();
if to_send.is_empty() {
@ -205,7 +202,7 @@ impl SyncPropagator {
let appended = packet.append_raw_checked(&transaction.drain(), 1, MAX_TRANSACTION_PACKET_SIZE);
if !appended {
// Maximal packet size reached just proceed with sending
debug!("Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len());
debug!(target: "sync", "Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len());
to_send = to_send.into_iter().take(pushed).collect();
break;
}

View File

@ -21,6 +21,7 @@
//! https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
//!
extern crate common_types as types;
extern crate ethcore_network as network;
extern crate ethcore_network_devp2p as devp2p;
extern crate parity_bytes as bytes;

View File

@ -1,53 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Dapps settings de/serialization.
use hash;
/// Settings for specific dapp.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct DappsSettings {
/// A list of accounts this Dapp can see.
pub accounts: Option<Vec<hash::Address>>,
/// Default account
pub default: Option<hash::Address>,
}
impl_serialization!(String => DappsSettings);
/// History for specific dapp.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct DappsHistory {
/// Last accessed timestamp
pub last_accessed: u64,
}
impl_serialization!(String => DappsHistory);
/// Accounts policy for new dapps.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum NewDappsPolicy {
/// All accounts are exposed by default.
AllAccounts {
/// Default account, which should be returned as the first one.
default: hash::Address,
},
/// Only accounts listed here are exposed by default for new dapps.
Whitelist(Vec<hash::Address>),
}
impl_serialization!(String => NewDappsPolicy);

View File

@ -48,7 +48,5 @@ macro_rules! impl_serialization {
}
mod account_meta;
mod dapps_settings;
pub use self::dapps_settings::{DappsSettings, DappsHistory, NewDappsPolicy};
pub use self::account_meta::AccountMeta;

View File

@ -24,6 +24,7 @@ use hash::Address;
pub struct EthashParams {
/// See main EthashParams docs.
#[serde(rename="minimumDifficulty")]
#[serde(deserialize_with="uint::validate_non_zero")]
pub minimum_difficulty: Uint,
/// See main EthashParams docs.
#[serde(rename="difficultyBoundDivisor")]

View File

@ -143,6 +143,10 @@ impl txpool::Scoring<VerifiedTransaction> for NonceAndGasPrice {
}
}
}
fn should_ignore_sender_limit(&self, new: &VerifiedTransaction) -> bool {
new.priority().is_local()
}
}
#[cfg(test)]

View File

@ -116,12 +116,11 @@ fn should_never_drop_local_transactions_from_different_senders() {
let r1 = txq.import(TestClient::new(), vec![tx1].local());
let r2 = txq.import(TestClient::new(), vec![tx2].local());
assert_eq!(r1, vec![Ok(())]);
// max-per-sender is reached, that's ok.
assert_eq!(r2, vec![Err(transaction::Error::LimitReached)]);
assert_eq!(txq.status().status.transaction_count, 1);
assert_eq!(r2, vec![Ok(())]);
assert_eq!(txq.status().status.transaction_count, 2);
// then
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 1.into()));
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 2.into()));
// when
let tx1 = Tx::gas_price(2).signed();
@ -134,8 +133,8 @@ fn should_never_drop_local_transactions_from_different_senders() {
// then
assert_eq!(res, vec![Ok(()), Ok(())]);
assert_eq!(res2, vec![Ok(()), Ok(())]);
assert_eq!(txq.status().status.transaction_count, 5);
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 1.into()));
assert_eq!(txq.status().status.transaction_count, 6);
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 2.into()));
}
#[test]

View File

@ -67,19 +67,10 @@ impl WorkPoster {
}
}
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
fn difficulty_to_boundary(difficulty: &U256) -> H256 {
if *difficulty <= U256::one() {
U256::max_value().into()
} else {
(((U256::one() << 255) / *difficulty) << 1).into()
}
}
impl NotifyWork for WorkPoster {
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) {
// TODO: move this to engine
let target = difficulty_to_boundary(&difficulty);
let target = ethash::difficulty_to_boundary(&difficulty);
let seed_hash = &self.seed_compute.lock().hash_block_number(number);
let seed_hash = H256::from_slice(&seed_hash[..]);
let body = format!(

View File

@ -1,18 +0,0 @@
[package]
name = "node-health"
description = "Node's health status"
version = "0.1.0"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
futures = "0.1"
futures-cpupool = "0.1"
log = "0.3"
ntp = "0.5.0"
parking_lot = "0.6"
serde = "1.0"
serde_derive = "1.0"
time = "0.1.35"
parity-reactor = { path = "../util/reactor" }

View File

@ -1,122 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Reporting node's health.
use std::sync::Arc;
use std::time::Duration;
use futures::Future;
use futures::sync::oneshot;
use types::{HealthInfo, HealthStatus, Health};
use time::{TimeChecker, MAX_DRIFT};
use parity_reactor::Remote;
use parking_lot::Mutex;
use {SyncStatus};
const TIMEOUT: Duration = Duration::from_secs(5);
const PROOF: &str = "Only one closure is invoked.";
/// A struct enabling you to query for node's health.
#[derive(Debug, Clone)]
pub struct NodeHealth {
sync_status: Arc<SyncStatus>,
time: TimeChecker,
remote: Remote,
}
impl NodeHealth {
/// Creates new `NodeHealth`.
pub fn new(sync_status: Arc<SyncStatus>, time: TimeChecker, remote: Remote) -> Self {
NodeHealth { sync_status, time, remote, }
}
/// Query latest health report.
pub fn health(&self) -> Box<Future<Item = Health, Error = ()> + Send> {
trace!(target: "dapps", "Checking node health.");
// Check timediff
let sync_status = self.sync_status.clone();
let time = self.time.time_drift();
let (tx, rx) = oneshot::channel();
let tx = Arc::new(Mutex::new(Some(tx)));
let tx2 = tx.clone();
self.remote.spawn_with_timeout(
move |_| time.then(move |result| {
let _ = tx.lock().take().expect(PROOF).send(Ok(result));
Ok(())
}),
TIMEOUT,
move || {
let _ = tx2.lock().take().expect(PROOF).send(Err(()));
},
);
Box::new(rx.map_err(|err| {
warn!(target: "dapps", "Health request cancelled: {:?}", err);
}).and_then(move |time| {
// Check peers
let peers = {
let (connected, max) = sync_status.peers();
let (status, message) = match connected {
0 => {
(HealthStatus::Bad, "You are not connected to any peers. There is most likely some network issue. Fix connectivity.".into())
},
1 => (HealthStatus::NeedsAttention, "You are connected to only one peer. Your node might not be reliable. Check your network connection.".into()),
_ => (HealthStatus::Ok, "".into()),
};
HealthInfo { status, message, details: (connected, max) }
};
// Check sync
let sync = {
let is_syncing = sync_status.is_major_importing();
let (status, message) = if is_syncing {
(HealthStatus::NeedsAttention, "Your node is still syncing, the values you see might be outdated. Wait until it's fully synced.".into())
} else {
(HealthStatus::Ok, "".into())
};
HealthInfo { status, message, details: is_syncing }
};
// Check time
let time = {
let (status, message, details) = match time {
Ok(Ok(diff)) if diff < MAX_DRIFT && diff > -MAX_DRIFT => {
(HealthStatus::Ok, "".into(), diff)
},
Ok(Ok(diff)) => {
(HealthStatus::Bad, format!(
"Your clock is not in sync. Detected difference is too big for the protocol to work: {}ms. Synchronize your clock.",
diff,
), diff)
},
Ok(Err(err)) => {
(HealthStatus::NeedsAttention, format!(
"Unable to reach time API: {}. Make sure that your clock is synchronized.",
err,
), 0)
},
Err(_) => {
(HealthStatus::NeedsAttention, "Time API request timed out. Make sure that the clock is synchronized.".into(), 0)
},
};
HealthInfo { status, message, details, }
};
Ok(Health { peers, sync, time})
}))
}
}

View File

@ -1,49 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Node Health status reporting.
#![warn(missing_docs)]
extern crate futures;
extern crate futures_cpupool;
extern crate ntp;
extern crate time as time_crate;
extern crate parity_reactor;
extern crate parking_lot;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
mod health;
mod time;
mod types;
pub use futures_cpupool::CpuPool;
pub use health::NodeHealth;
pub use types::{Health, HealthInfo, HealthStatus};
pub use time::{TimeChecker, Error};
/// Indicates sync status
pub trait SyncStatus: ::std::fmt::Debug + Send + Sync {
/// Returns true if there is a major sync happening.
fn is_major_importing(&self) -> bool;
/// Returns number of connected and ideal peers.
fn peers(&self) -> (usize, usize);
}

View File

@ -1,357 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Periodically checks node's time drift using [SNTP](https://tools.ietf.org/html/rfc1769).
//!
//! An NTP packet is sent to the server with a local timestamp, the server then completes the packet, yielding the
//! following timestamps:
//!
//! Timestamp Name ID When Generated
//! ------------------------------------------------------------
//! Originate Timestamp T1 time request sent by client
//! Receive Timestamp T2 time request received at server
//! Transmit Timestamp T3 time reply sent by server
//! Destination Timestamp T4 time reply received at client
//!
//! The drift is defined as:
//!
//! drift = ((T2 - T1) + (T3 - T4)) / 2.
//!
use std::io;
use std::{fmt, mem, time};
use std::collections::VecDeque;
use std::sync::atomic::{self, AtomicUsize};
use std::sync::Arc;
use futures::{self, Future};
use futures::future::{self, IntoFuture};
use futures_cpupool::{CpuPool, CpuFuture};
use ntp;
use parking_lot::RwLock;
use time_crate::{Duration, Timespec};
/// Time checker error.
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
/// No servers are currently available for a query.
NoServersAvailable,
/// There was an error when trying to reach the NTP server.
Ntp(String),
/// IO error when reading NTP response.
Io(String),
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
match *self {
NoServersAvailable => write!(fmt, "No NTP servers available"),
Ntp(ref err) => write!(fmt, "NTP error: {}", err),
Io(ref err) => write!(fmt, "Connection Error: {}", err),
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self { Error::Io(format!("{}", err)) }
}
impl From<ntp::errors::Error> for Error {
fn from(err: ntp::errors::Error) -> Self { Error::Ntp(format!("{}", err)) }
}
/// NTP time drift checker.
pub trait Ntp {
/// Returned Future.
type Future: IntoFuture<Item=Duration, Error=Error>;
/// Returns the current time drift.
fn drift(&self) -> Self::Future;
}
const SERVER_MAX_POLL_INTERVAL_SECS: u64 = 60;
#[derive(Debug)]
struct Server {
pub address: String,
next_call: RwLock<time::Instant>,
failures: AtomicUsize,
}
impl Server {
pub fn is_available(&self) -> bool {
*self.next_call.read() < time::Instant::now()
}
pub fn report_success(&self) {
self.failures.store(0, atomic::Ordering::SeqCst);
self.update_next_call(1)
}
pub fn report_failure(&self) {
let errors = self.failures.fetch_add(1, atomic::Ordering::SeqCst);
self.update_next_call(1 << errors)
}
fn update_next_call(&self, delay: usize) {
*self.next_call.write() = time::Instant::now() + time::Duration::from_secs(delay as u64 * SERVER_MAX_POLL_INTERVAL_SECS);
}
}
impl<T: AsRef<str>> From<T> for Server {
fn from(t: T) -> Self {
Server {
address: t.as_ref().to_owned(),
next_call: RwLock::new(time::Instant::now()),
failures: Default::default(),
}
}
}
/// NTP client using the SNTP algorithm for calculating drift.
#[derive(Clone)]
pub struct SimpleNtp {
addresses: Vec<Arc<Server>>,
pool: CpuPool,
}
impl fmt::Debug for SimpleNtp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f
.debug_struct("SimpleNtp")
.field("addresses", &self.addresses)
.finish()
}
}
impl SimpleNtp {
fn new<T: AsRef<str>>(addresses: &[T], pool: CpuPool) -> SimpleNtp {
SimpleNtp {
addresses: addresses.iter().map(Server::from).map(Arc::new).collect(),
pool: pool,
}
}
}
impl Ntp for SimpleNtp {
type Future = future::Either<
CpuFuture<Duration, Error>,
future::FutureResult<Duration, Error>,
>;
fn drift(&self) -> Self::Future {
use self::future::Either::{A, B};
let server = self.addresses.iter().find(|server| server.is_available());
server.map(|server| {
let server = server.clone();
A(self.pool.spawn_fn(move || {
debug!(target: "dapps", "Fetching time from {}.", server.address);
match ntp::request(&server.address) {
Ok(packet) => {
let dest_time = ::time_crate::now_utc().to_timespec();
let orig_time = Timespec::from(packet.orig_time);
let recv_time = Timespec::from(packet.recv_time);
let transmit_time = Timespec::from(packet.transmit_time);
let drift = ((recv_time - orig_time) + (transmit_time - dest_time)) / 2;
server.report_success();
Ok(drift)
},
Err(err) => {
server.report_failure();
Err(err.into())
},
}
}))
}).unwrap_or_else(|| B(future::err(Error::NoServersAvailable)))
}
}
// NOTE In a positive scenario first results will be seen after:
// MAX_RESULTS * UPDATE_TIMEOUT_INCOMPLETE_SECS seconds.
const MAX_RESULTS: usize = 4;
const UPDATE_TIMEOUT_OK_SECS: u64 = 6 * 60 * 60;
const UPDATE_TIMEOUT_WARN_SECS: u64 = 15 * 60;
const UPDATE_TIMEOUT_ERR_SECS: u64 = 60;
const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10;
/// Maximal valid time drift.
pub const MAX_DRIFT: i64 = 10_000;
type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
#[derive(Debug, Clone)]
/// A time checker.
pub struct TimeChecker<N: Ntp = SimpleNtp> {
ntp: N,
last_result: Arc<RwLock<(time::Instant, VecDeque<Result<i64, Error>>)>>,
}
impl TimeChecker<SimpleNtp> {
/// Creates new time checker given the NTP server address.
pub fn new<T: AsRef<str>>(ntp_addresses: &[T], pool: CpuPool) -> Self {
let last_result = Arc::new(RwLock::new(
// Assume everything is ok at the very beginning.
(time::Instant::now(), vec![Ok(0)].into())
));
let ntp = SimpleNtp::new(ntp_addresses, pool);
TimeChecker {
ntp,
last_result,
}
}
}
impl<N: Ntp> TimeChecker<N> where <N::Future as IntoFuture>::Future: Send + 'static {
/// Updates the time
pub fn update(&self) -> BoxFuture<i64, Error> {
trace!(target: "dapps", "Updating time from NTP.");
let last_result = self.last_result.clone();
Box::new(self.ntp.drift().into_future().then(move |res| {
let res = res.map(|d| d.num_milliseconds());
if let Err(Error::NoServersAvailable) = res {
debug!(target: "dapps", "No NTP servers available. Selecting an older result.");
return select_result(last_result.read().1.iter());
}
// Update the results.
let mut results = mem::replace(&mut last_result.write().1, VecDeque::new());
let has_all_results = results.len() >= MAX_RESULTS;
let valid_till = time::Instant::now() + time::Duration::from_secs(
match res {
Ok(time) if has_all_results && time < MAX_DRIFT => UPDATE_TIMEOUT_OK_SECS,
Ok(_) if has_all_results => UPDATE_TIMEOUT_WARN_SECS,
Err(_) if has_all_results => UPDATE_TIMEOUT_ERR_SECS,
_ => UPDATE_TIMEOUT_INCOMPLETE_SECS,
}
);
trace!(target: "dapps", "New time drift received: {:?}", res);
// Push the result.
results.push_back(res);
while results.len() > MAX_RESULTS {
results.pop_front();
}
// Select a response and update last result.
let res = select_result(results.iter());
*last_result.write() = (valid_till, results);
res
}))
}
/// Returns a current time drift or error if last request to NTP server failed.
pub fn time_drift(&self) -> BoxFuture<i64, Error> {
// return cached result
{
let res = self.last_result.read();
if res.0 > time::Instant::now() {
return Box::new(futures::done(select_result(res.1.iter())));
}
}
// or update and return result
self.update()
}
}
fn select_result<'a, T: Iterator<Item=&'a Result<i64, Error>>>(results: T) -> Result<i64, Error> {
let mut min = None;
for res in results {
min = Some(match (min.take(), res) {
(Some(Ok(min)), &Ok(ref new)) => Ok(::std::cmp::min(min, *new)),
(Some(Ok(old)), &Err(_)) => Ok(old),
(_, ref new) => (*new).clone(),
})
}
min.unwrap_or_else(|| Err(Error::Ntp("NTP server unavailable.".into())))
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use std::cell::{Cell, RefCell};
use std::time::Instant;
use time::Duration;
use futures::{future, Future};
use super::{Ntp, TimeChecker, Error};
use parking_lot::RwLock;
#[derive(Clone)]
struct FakeNtp(RefCell<Vec<Duration>>, Cell<u64>);
impl FakeNtp {
fn new() -> FakeNtp {
FakeNtp(
RefCell::new(vec![Duration::milliseconds(150)]),
Cell::new(0))
}
}
impl Ntp for FakeNtp {
type Future = future::FutureResult<Duration, Error>;
fn drift(&self) -> Self::Future {
self.1.set(self.1.get() + 1);
future::ok(self.0.borrow_mut().pop().expect("Unexpected call to drift()."))
}
}
fn time_checker() -> TimeChecker<FakeNtp> {
let last_result = Arc::new(RwLock::new(
(Instant::now(), vec![Err(Error::Ntp("NTP server unavailable".into()))].into())
));
TimeChecker {
ntp: FakeNtp::new(),
last_result: last_result,
}
}
#[test]
fn should_fetch_time_on_start() {
// given
let time = time_checker();
// when
let diff = time.time_drift().wait().unwrap();
// then
assert_eq!(diff, 150);
assert_eq!(time.ntp.1.get(), 1);
}
#[test]
fn should_not_fetch_twice_if_timeout_has_not_passed() {
// given
let time = time_checker();
// when
let diff1 = time.time_drift().wait().unwrap();
let diff2 = time.time_drift().wait().unwrap();
// then
assert_eq!(diff1, 150);
assert_eq!(diff2, 150);
assert_eq!(time.ntp.1.get(), 1);
}
}

View File

@ -1,57 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Base health types.
/// Health API endpoint status.
#[derive(Debug, PartialEq, Serialize)]
pub enum HealthStatus {
/// Everything's OK.
#[serde(rename = "ok")]
Ok,
/// Node health need attention
/// (the issue is not critical, but may need investigation)
#[serde(rename = "needsAttention")]
NeedsAttention,
/// There is something bad detected with the node.
#[serde(rename = "bad")]
Bad,
}
/// Represents a single check in node health.
/// Cointains the status of that check and apropriate message and details.
#[derive(Debug, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct HealthInfo<T> {
/// Check status.
pub status: HealthStatus,
/// Human-readable message.
pub message: String,
/// Technical details of the check.
pub details: T,
}
/// Node Health status.
#[derive(Debug, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Health {
/// Status of peers.
pub peers: HealthInfo<(usize, usize)>,
/// Sync status.
pub sync: HealthInfo<bool>,
/// Time diff info.
pub time: HealthInfo<i64>,
}

View File

@ -288,7 +288,7 @@ usage! {
ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(),
"--chain=[CHAIN]",
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, homestead, mainnet, morden, ropsten, classic, expanse, tobalaba, musicoin, ellaism, easthub, social, testnet, kovan or dev.",
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, tobalaba, expanse, musicoin, ellaism, easthub, social, olympic, morden, ropsten, kovan, poasokol, testnet, or dev.",
ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| c.parity.as_ref()?.keys_path.clone(),
"--keys-path=[PATH]",
@ -700,11 +700,11 @@ usage! {
"--price-update-period=[T]",
"T will be allowed to pass between each gas price update. T may be daily, hourly, a number of seconds, or a time string of the form \"2 days\", \"30 minutes\" etc..",
ARG arg_gas_floor_target: (String) = "4700000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(),
ARG arg_gas_floor_target: (String) = "8000000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(),
"--gas-floor-target=[GAS]",
"Amount of gas per block to target when sealing a new block.",
ARG arg_gas_cap: (String) = "6283184", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(),
ARG arg_gas_cap: (String) = "10000000", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(),
"--gas-cap=[GAS]",
"A cap on how large we will raise the gas limit per block due to transaction volume.",
@ -794,10 +794,6 @@ usage! {
"--no-config",
"Don't load a configuration file.",
ARG arg_ntp_servers: (String) = "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123", or |c: &Config| c.misc.as_ref()?.ntp_servers.clone().map(|vec| vec.join(",")),
"--ntp-servers=[HOSTS]",
"Comma separated list of NTP servers to provide current time (host:port). Used to verify node health. Parity uses pool.ntp.org NTP servers; consider joining the pool: http://www.pool.ntp.org/join.html",
ARG arg_logging: (Option<String>) = None, or |c: &Config| c.misc.as_ref()?.logging.clone(),
"-l, --logging=[LOGGING]",
"Specify the logging level. Must conform to the same format as RUST_LOG.",
@ -1077,6 +1073,10 @@ usage! {
ARG arg_dapps_path: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_path.clone(),
"--dapps-path=[PATH]",
"Specify directory where dapps should be installed.",
ARG arg_ntp_servers: (Option<String>) = None, or |_| None,
"--ntp-servers=[HOSTS]",
"Does nothing; checking if clock is sync with NTP servers is now done on the UI.",
}
}
@ -1350,7 +1350,6 @@ struct Snapshots {
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Misc {
ntp_servers: Option<Vec<String>>,
logging: Option<String>,
log_file: Option<String>,
color: Option<bool>,
@ -1713,7 +1712,7 @@ mod tests {
arg_reseal_max_period: 60000u64,
flag_reseal_on_uncle: false,
arg_work_queue_size: 20usize,
arg_tx_gas_limit: Some("6283184".into()),
arg_tx_gas_limit: Some("10000000".into()),
arg_tx_time_limit: Some(100u64),
arg_relay_set: "cheap".into(),
arg_min_gas_price: Some(0u64),
@ -1722,8 +1721,8 @@ mod tests {
arg_poll_lifetime: 60u32,
arg_usd_per_eth: "auto".into(),
arg_price_update_period: "hourly".into(),
arg_gas_floor_target: "4700000".into(),
arg_gas_cap: "6283184".into(),
arg_gas_floor_target: "8000000".into(),
arg_gas_cap: "10000000".into(),
arg_extra_data: Some("Parity".into()),
flag_tx_queue_no_unfamiliar_locals: false,
arg_tx_queue_size: 8192usize,
@ -1818,7 +1817,7 @@ mod tests {
flag_can_restart: false,
// -- Miscellaneous Options
arg_ntp_servers: "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123".into(),
arg_ntp_servers: None,
flag_version: false,
arg_logging: Some("own_tx=trace".into()),
arg_log_file: Some("/var/log/parity.log".into()),
@ -2024,7 +2023,6 @@ mod tests {
disable_periodic: Some(true),
}),
misc: Some(Misc {
ntp_servers: Some(vec!["0.parity.pool.ntp.org:123".into()]),
logging: Some("own_tx=trace".into()),
log_file: Some("/var/log/parity.log".into()),
color: Some(true),

View File

@ -125,14 +125,14 @@ min_gas_price = 0
usd_per_tx = "0.0001"
usd_per_eth = "auto"
price_update_period = "hourly"
gas_floor_target = "4700000"
gas_cap = "6283184"
gas_floor_target = "8000000"
gas_cap = "10000000"
tx_queue_size = 8192
tx_queue_gas = "off"
tx_queue_strategy = "gas_factor"
tx_queue_ban_count = 1
tx_queue_ban_time = 180 #s
tx_gas_limit = "6283184"
tx_gas_limit = "10000000"
tx_time_limit = 100 #ms
tx_queue_no_unfamiliar_locals = false
extra_data = "Parity"

View File

@ -75,7 +75,6 @@ scale_verifiers = false
disable_periodic = true
[misc]
ntp_servers = ["0.parity.pool.ntp.org:123"]
logging = "own_tx=trace"
log_file = "/var/log/parity.log"
color = true

View File

@ -348,7 +348,6 @@ impl Configuration {
miner_options: self.miner_options()?,
gas_price_percentile: self.args.arg_gas_price_percentile,
poll_lifetime: self.args.arg_poll_lifetime,
ntp_servers: self.ntp_servers(),
ws_conf: ws_conf,
http_conf: http_conf,
ipc_conf: ipc_conf,
@ -574,10 +573,6 @@ impl Configuration {
})
}
fn ntp_servers(&self) -> Vec<String> {
self.args.arg_ntp_servers.split(",").map(str::to_owned).collect()
}
fn secretstore_config(&self) -> Result<SecretStoreConfiguration, String> {
Ok(SecretStoreConfiguration {
enabled: self.secretstore_enabled(),
@ -939,7 +934,13 @@ impl Configuration {
let is_using_base_path = self.args.arg_base_path.is_some();
// If base_path is set and db_path is not we default to base path subdir instead of LOCAL.
let base_db_path = if is_using_base_path && self.args.arg_db_path.is_none() {
"$BASE/chains"
if self.args.flag_light {
"$BASE/chains_light"
} else {
"$BASE/chains"
}
} else if self.args.flag_light {
self.args.arg_db_path.as_ref().map_or(dir::CHAINS_PATH_LIGHT, |s| &s)
} else {
self.args.arg_db_path.as_ref().map_or(dir::CHAINS_PATH, |s| &s)
};
@ -1362,12 +1363,6 @@ mod tests {
miner_options: Default::default(),
gas_price_percentile: 50,
poll_lifetime: 60,
ntp_servers: vec![
"0.parity.pool.ntp.org:123".into(),
"1.parity.pool.ntp.org:123".into(),
"2.parity.pool.ntp.org:123".into(),
"3.parity.pool.ntp.org:123".into(),
],
ws_conf: Default::default(),
http_conf: Default::default(),
ipc_conf: Default::default(),

View File

@ -225,6 +225,10 @@ pub fn find_deprecated(args: &Args) -> Vec<Deprecated> {
result.push(Deprecated::Removed("--dapps-path"));
}
if args.arg_ntp_servers.is_some() {
result.push(Deprecated::Removed("--ntp-servers"));
}
result
}
@ -256,6 +260,7 @@ mod tests {
args.arg_dapps_pass = Some(Default::default());
args.flag_dapps_apis_all = true;
args.flag_fast_and_loose = true;
args.arg_ntp_servers = Some(Default::default());
args
}), vec![
Deprecated::DoesNothing("--warp"),
@ -276,6 +281,7 @@ mod tests {
Deprecated::Removed("--dapps-pass"),
Deprecated::Replaced("--dapps-apis-all", "--jsonrpc-apis"),
Deprecated::Removed("--fast-and-loose"),
Deprecated::Removed("--ntp-servers"),
]);
}
}

View File

@ -35,7 +35,7 @@ use io::{TimerToken, IoContext, IoHandler};
use light::Cache as LightDataCache;
use light::client::{LightChainClient, LightChainNotify};
use number_prefix::{binary_prefix, Standalone, Prefixed};
use parity_rpc::{is_major_importing};
use parity_rpc::is_major_importing_or_waiting;
use parity_rpc::informant::RpcStats;
use ethereum_types::H256;
use bytes::Bytes;
@ -128,7 +128,7 @@ impl InformantData for FullNodeInformantData {
fn is_major_importing(&self) -> bool {
let state = self.sync.as_ref().map(|sync| sync.status().state);
is_major_importing(state, self.client.queue_info())
is_major_importing_or_waiting(state, self.client.queue_info(), false)
}
fn report(&self) -> Report {
@ -142,7 +142,8 @@ impl InformantData for FullNodeInformantData {
cache_sizes.insert("queue", queue_info.mem_used);
cache_sizes.insert("chain", blockchain_cache_info.total());
let (importing, sync_info) = match (self.sync.as_ref(), self.net.as_ref()) {
let importing = self.is_major_importing();
let sync_info = match (self.sync.as_ref(), self.net.as_ref()) {
(Some(sync), Some(net)) => {
let status = sync.status();
let num_peers_range = net.num_peers_range();
@ -150,16 +151,15 @@ impl InformantData for FullNodeInformantData {
cache_sizes.insert("sync", status.mem_used);
let importing = is_major_importing(Some(status.state), queue_info.clone());
(importing, Some(SyncInfo {
Some(SyncInfo {
last_imported_block_number: status.last_imported_block_number.unwrap_or(chain_info.best_block_number),
last_imported_old_block_number: status.last_imported_old_block_number,
num_peers: status.num_peers,
max_peers: status.current_max_peers(num_peers_range.start, num_peers_range.end - 1),
snapshot_sync: status.is_snapshot_syncing(),
}))
})
}
_ => (is_major_importing(self.sync.as_ref().map(|s| s.status().state), queue_info.clone()), None),
_ => None
};
Report {

View File

@ -57,7 +57,6 @@ extern crate ethcore_transaction as transaction;
extern crate ethereum_types;
extern crate ethkey;
extern crate kvdb;
extern crate node_health;
extern crate panic_hook;
extern crate parity_hash_fetch as hash_fetch;
extern crate parity_ipfs_api;
@ -80,9 +79,6 @@ extern crate log as rlog;
#[cfg(feature = "secretstore")]
extern crate ethcore_secretstore;
#[cfg(feature = "dapps")]
extern crate parity_dapps;
#[cfg(test)]
#[macro_use]
extern crate pretty_assertions;

View File

@ -32,17 +32,19 @@ use user_defaults::UserDefaults;
#[derive(Debug, PartialEq)]
pub enum SpecType {
Foundation,
Morden,
Ropsten,
Tobalaba,
Kovan,
Olympic,
Classic,
Poanet,
Tobalaba,
Expanse,
Musicoin,
Ellaism,
Easthub,
Social,
Olympic,
Morden,
Ropsten,
Kovan,
Sokol,
Dev,
Custom(String),
}
@ -58,18 +60,20 @@ impl str::FromStr for SpecType {
fn from_str(s: &str) -> Result<Self, Self::Err> {
let spec = match s {
"foundation" | "frontier" | "homestead" | "mainnet" => SpecType::Foundation,
"frontier-dogmatic" | "homestead-dogmatic" | "classic" => SpecType::Classic,
"morden" | "classic-testnet" => SpecType::Morden,
"ropsten" => SpecType::Ropsten,
"kovan" | "testnet" => SpecType::Kovan,
"ethereum" | "frontier" | "homestead" | "byzantium" | "foundation" | "mainnet" => SpecType::Foundation,
"classic" | "frontier-dogmatic" | "homestead-dogmatic" => SpecType::Classic,
"poanet" | "poacore" => SpecType::Poanet,
"tobalaba" => SpecType::Tobalaba,
"olympic" => SpecType::Olympic,
"expanse" => SpecType::Expanse,
"musicoin" => SpecType::Musicoin,
"ellaism" => SpecType::Ellaism,
"easthub" => SpecType::Easthub,
"social" => SpecType::Social,
"olympic" => SpecType::Olympic,
"morden" | "classic-testnet" => SpecType::Morden,
"ropsten" => SpecType::Ropsten,
"kovan" | "testnet" => SpecType::Kovan,
"sokol" | "poasokol" => SpecType::Sokol,
"dev" => SpecType::Dev,
other => SpecType::Custom(other.into()),
};
@ -81,17 +85,19 @@ impl fmt::Display for SpecType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
SpecType::Foundation => "foundation",
SpecType::Morden => "morden",
SpecType::Ropsten => "ropsten",
SpecType::Olympic => "olympic",
SpecType::Classic => "classic",
SpecType::Poanet => "poanet",
SpecType::Tobalaba => "tobalaba",
SpecType::Expanse => "expanse",
SpecType::Musicoin => "musicoin",
SpecType::Ellaism => "ellaism",
SpecType::Easthub => "easthub",
SpecType::Social => "social",
SpecType::Olympic => "olympic",
SpecType::Morden => "morden",
SpecType::Ropsten => "ropsten",
SpecType::Kovan => "kovan",
SpecType::Tobalaba => "tobalaba",
SpecType::Sokol => "sokol",
SpecType::Dev => "dev",
SpecType::Custom(ref custom) => custom,
})
@ -103,17 +109,19 @@ impl SpecType {
let params = params.into();
match *self {
SpecType::Foundation => Ok(ethereum::new_foundation(params)),
SpecType::Morden => Ok(ethereum::new_morden(params)),
SpecType::Ropsten => Ok(ethereum::new_ropsten(params)),
SpecType::Olympic => Ok(ethereum::new_olympic(params)),
SpecType::Classic => Ok(ethereum::new_classic(params)),
SpecType::Poanet => Ok(ethereum::new_poanet(params)),
SpecType::Tobalaba => Ok(ethereum::new_tobalaba(params)),
SpecType::Expanse => Ok(ethereum::new_expanse(params)),
SpecType::Musicoin => Ok(ethereum::new_musicoin(params)),
SpecType::Ellaism => Ok(ethereum::new_ellaism(params)),
SpecType::Easthub => Ok(ethereum::new_easthub(params)),
SpecType::Social => Ok(ethereum::new_social(params)),
SpecType::Tobalaba => Ok(ethereum::new_tobalaba(params)),
SpecType::Olympic => Ok(ethereum::new_olympic(params)),
SpecType::Morden => Ok(ethereum::new_morden(params)),
SpecType::Ropsten => Ok(ethereum::new_ropsten(params)),
SpecType::Kovan => Ok(ethereum::new_kovan(params)),
SpecType::Sokol => Ok(ethereum::new_sokol(params)),
SpecType::Dev => Ok(Spec::new_instant()),
SpecType::Custom(ref filename) => {
let file = fs::File::open(filename).map_err(|e| format!("Could not load specification file at {}: {}", filename, e))?;
@ -278,7 +286,7 @@ impl Default for MinerExtras {
author: Default::default(),
engine_signer: Default::default(),
extra_data: version_data(),
gas_range_target: (4_700_000.into(), 6_283_184.into()),
gas_range_target: (8_000_000.into(), 10_000_000.into()),
work_notify: Default::default(),
}
}
@ -334,7 +342,7 @@ pub fn fatdb_switch_to_bool(switch: Switch, user_defaults: &UserDefaults, _algor
}
pub fn mode_switch_to_bool(switch: Option<Mode>, user_defaults: &UserDefaults) -> Result<Mode, String> {
Ok(switch.unwrap_or(user_defaults.mode.clone()))
Ok(switch.unwrap_or(user_defaults.mode().clone()))
}
#[cfg(test)]
@ -345,17 +353,31 @@ mod tests {
#[test]
fn test_spec_type_parsing() {
assert_eq!(SpecType::Foundation, "foundation".parse().unwrap());
assert_eq!(SpecType::Foundation, "frontier".parse().unwrap());
assert_eq!(SpecType::Foundation, "homestead".parse().unwrap());
assert_eq!(SpecType::Foundation, "byzantium".parse().unwrap());
assert_eq!(SpecType::Foundation, "mainnet".parse().unwrap());
assert_eq!(SpecType::Foundation, "foundation".parse().unwrap());
assert_eq!(SpecType::Kovan, "testnet".parse().unwrap());
assert_eq!(SpecType::Kovan, "kovan".parse().unwrap());
assert_eq!(SpecType::Morden, "morden".parse().unwrap());
assert_eq!(SpecType::Ropsten, "ropsten".parse().unwrap());
assert_eq!(SpecType::Olympic, "olympic".parse().unwrap());
assert_eq!(SpecType::Foundation, "ethereum".parse().unwrap());
assert_eq!(SpecType::Classic, "classic".parse().unwrap());
assert_eq!(SpecType::Classic, "frontier-dogmatic".parse().unwrap());
assert_eq!(SpecType::Classic, "homestead-dogmatic".parse().unwrap());
assert_eq!(SpecType::Poanet, "poanet".parse().unwrap());
assert_eq!(SpecType::Poanet, "poacore".parse().unwrap());
assert_eq!(SpecType::Tobalaba, "tobalaba".parse().unwrap());
assert_eq!(SpecType::Expanse, "expanse".parse().unwrap());
assert_eq!(SpecType::Musicoin, "musicoin".parse().unwrap());
assert_eq!(SpecType::Ellaism, "ellaism".parse().unwrap());
assert_eq!(SpecType::Easthub, "easthub".parse().unwrap());
assert_eq!(SpecType::Social, "social".parse().unwrap());
assert_eq!(SpecType::Olympic, "olympic".parse().unwrap());
assert_eq!(SpecType::Morden, "morden".parse().unwrap());
assert_eq!(SpecType::Morden, "classic-testnet".parse().unwrap());
assert_eq!(SpecType::Ropsten, "ropsten".parse().unwrap());
assert_eq!(SpecType::Kovan, "kovan".parse().unwrap());
assert_eq!(SpecType::Kovan, "testnet".parse().unwrap());
assert_eq!(SpecType::Sokol, "sokol".parse().unwrap());
assert_eq!(SpecType::Sokol, "poasokol".parse().unwrap());
}
#[test]
@ -366,13 +388,19 @@ mod tests {
#[test]
fn test_spec_type_display() {
assert_eq!(format!("{}", SpecType::Foundation), "foundation");
assert_eq!(format!("{}", SpecType::Ropsten), "ropsten");
assert_eq!(format!("{}", SpecType::Morden), "morden");
assert_eq!(format!("{}", SpecType::Olympic), "olympic");
assert_eq!(format!("{}", SpecType::Classic), "classic");
assert_eq!(format!("{}", SpecType::Poanet), "poanet");
assert_eq!(format!("{}", SpecType::Tobalaba), "tobalaba");
assert_eq!(format!("{}", SpecType::Expanse), "expanse");
assert_eq!(format!("{}", SpecType::Musicoin), "musicoin");
assert_eq!(format!("{}", SpecType::Ellaism), "ellaism");
assert_eq!(format!("{}", SpecType::Easthub), "easthub");
assert_eq!(format!("{}", SpecType::Social), "social");
assert_eq!(format!("{}", SpecType::Olympic), "olympic");
assert_eq!(format!("{}", SpecType::Morden), "morden");
assert_eq!(format!("{}", SpecType::Ropsten), "ropsten");
assert_eq!(format!("{}", SpecType::Kovan), "kovan");
assert_eq!(format!("{}", SpecType::Sokol), "sokol");
assert_eq!(format!("{}", SpecType::Dev), "dev");
assert_eq!(format!("{}", SpecType::Custom("foo/bar".into())), "foo/bar");
}

View File

@ -20,7 +20,6 @@ use std::str::FromStr;
use std::sync::{Arc, Weak};
pub use parity_rpc::signer::SignerService;
pub use parity_rpc::dapps::LocalDapp;
use ethcore_service::PrivateTxService;
use ethcore::account_provider::AccountProvider;
@ -35,7 +34,6 @@ use jsonrpc_core::{self as core, MetaIoHandler};
use light::client::LightChainClient;
use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache};
use miner::external::ExternalMiner;
use node_health::NodeHealth;
use parity_reactor;
use parity_rpc::dispatch::{FullDispatcher, LightDispatcher};
use parity_rpc::informant::{ActivityNotifier, ClientNotifier};
@ -225,7 +223,6 @@ pub struct FullDependencies {
pub settings: Arc<NetworkSettings>,
pub net_service: Arc<ManageNetwork>,
pub updater: Arc<Updater>,
pub health: NodeHealth,
pub geth_compatibility: bool,
pub ws_address: Option<Host>,
pub fetch: FetchClient,
@ -330,7 +327,6 @@ impl FullDependencies {
self.sync.clone(),
self.updater.clone(),
self.net_service.clone(),
self.health.clone(),
self.secret_store.clone(),
self.logger.clone(),
self.settings.clone(),
@ -431,7 +427,6 @@ pub struct LightDependencies<T> {
pub secret_store: Arc<AccountProvider>,
pub logger: Arc<RotatingLogger>,
pub settings: Arc<NetworkSettings>,
pub health: NodeHealth,
pub on_demand: Arc<::light::on_demand::OnDemand>,
pub cache: Arc<Mutex<LightDataCache>>,
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
@ -545,7 +540,6 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.secret_store.clone(),
self.logger.clone(),
self.settings.clone(),
self.health.clone(),
signer,
self.ws_address.clone(),
self.gas_price_percentile,

View File

@ -15,7 +15,6 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::any::Any;
use std::fmt;
use std::sync::{Arc, Weak};
use std::time::{Duration, Instant};
use std::thread;
@ -33,7 +32,6 @@ use ethcore_logger::{Config as LogConfig, RotatingLogger};
use ethcore_service::ClientService;
use ethereum_types::Address;
use sync::{self, SyncConfig};
#[cfg(feature = "work-notify")]
use miner::work_notify::WorkPoster;
use futures::IntoFuture;
use futures_cpupool::CpuPool;
@ -43,7 +41,6 @@ use journaldb::Algorithm;
use light::Cache as LightDataCache;
use miner::external::ExternalMiner;
use node_filter::NodeFilter;
use node_health;
use parity_reactor::EventLoop;
use parity_rpc::{Origin, Metadata, NetworkSettings, informant, is_major_importing};
use updater::{UpdatePolicy, Updater};
@ -96,7 +93,6 @@ pub struct RunCmd {
pub miner_options: MinerOptions,
pub gas_price_percentile: usize,
pub poll_lifetime: u32,
pub ntp_servers: Vec<String>,
pub ws_conf: rpc::WsConfiguration,
pub http_conf: rpc::HttpConfiguration,
pub ipc_conf: rpc::IpcConfiguration,
@ -189,7 +185,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
//print out running parity environment
print_running_environment(&spec.name, &cmd.dirs, &db_dirs);
print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
info!("Running in experimental {} mode.", Colour::Blue.bold().paint("Light Client"));
@ -288,28 +284,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
// the dapps server
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config));
let node_health = {
struct LightSyncStatus(Arc<LightSync>);
impl fmt::Debug for LightSyncStatus {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "Light Sync Status")
}
}
impl node_health::SyncStatus for LightSyncStatus {
fn is_major_importing(&self) -> bool { self.0.is_major_importing() }
fn peers(&self) -> (usize, usize) {
let peers = sync::LightSyncProvider::peer_numbers(&*self.0);
(peers.connected, peers.max)
}
}
let sync_status = Arc::new(LightSyncStatus(light_sync.clone()));
node_health::NodeHealth::new(
sync_status.clone(),
node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()),
event_loop.remote(),
)
};
// start RPCs
let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
@ -317,7 +291,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
client: client.clone(),
sync: light_sync.clone(),
net: light_sync.clone(),
health: node_health,
secret_store: account_provider,
logger: logger,
settings: Arc::new(cmd.net_settings),
@ -429,7 +402,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
}
//print out running parity environment
print_running_environment(&spec.name, &cmd.dirs, &db_dirs);
print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
// display info about used pruning algorithm
info!("State DB configuration: {}{}{}",
@ -504,19 +477,17 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
cmd.miner_options,
cmd.gas_pricer_conf.to_gas_pricer(fetch.clone(), cpu_pool.clone()),
&spec,
Some(account_provider.clone())
Some(account_provider.clone()),
));
miner.set_author(cmd.miner_extras.author, None).expect("Fails only if password is Some; password is None; qed");
miner.set_gas_range_target(cmd.miner_extras.gas_range_target);
miner.set_extra_data(cmd.miner_extras.extra_data);
#[cfg(feature = "work-notify")]
{
if !cmd.miner_extras.work_notify.is_empty() {
miner.add_work_listener(Box::new(
WorkPoster::new(&cmd.miner_extras.work_notify, fetch.clone(), event_loop.remote())
));
}
if !cmd.miner_extras.work_notify.is_empty() {
miner.add_work_listener(Box::new(
WorkPoster::new(&cmd.miner_extras.work_notify, fetch.clone(), event_loop.remote())
));
}
let engine_signer = cmd.miner_extras.engine_signer;
@ -721,40 +692,11 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
let secret_store = account_provider.clone();
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config));
// the dapps server
let node_health = {
let (sync, client) = (sync_provider.clone(), client.clone());
struct SyncStatus(Arc<sync::SyncProvider>, Arc<Client>, sync::NetworkConfiguration);
impl fmt::Debug for SyncStatus {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "Dapps Sync Status")
}
}
impl node_health::SyncStatus for SyncStatus {
fn is_major_importing(&self) -> bool {
is_major_importing(Some(self.0.status().state), self.1.queue_info())
}
fn peers(&self) -> (usize, usize) {
let status = self.0.status();
(status.num_peers, status.current_max_peers(self.2.min_peers, self.2.max_peers) as usize)
}
}
let sync_status = Arc::new(SyncStatus(sync, client, net_conf));
node_health::NodeHealth::new(
sync_status.clone(),
node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()),
event_loop.remote(),
)
};
let deps_for_rpc_apis = Arc::new(rpc_apis::FullDependencies {
signer_service: signer_service,
snapshot: snapshot_service.clone(),
client: client.clone(),
sync: sync_provider.clone(),
health: node_health,
net: manage_network.clone(),
secret_store: secret_store,
miner: miner.clone(),
@ -824,13 +766,13 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
user_defaults.pruning = algorithm;
user_defaults.tracing = tracing;
user_defaults.fat_db = fat_db;
user_defaults.mode = mode;
user_defaults.set_mode(mode);
user_defaults.save(&user_defaults_path)?;
// tell client how to save the default mode if it gets changed.
client.on_user_defaults_change(move |mode: Option<Mode>| {
if let Some(mode) = mode {
user_defaults.mode = mode;
user_defaults.set_mode(mode);
}
let _ = user_defaults.save(&user_defaults_path); // discard failures - there's nothing we can do
});
@ -984,9 +926,9 @@ fn daemonize(_pid_file: String) -> Result<(), String> {
Err("daemon is no supported on windows".into())
}
fn print_running_environment(spec_name: &String, dirs: &Directories, db_dirs: &DatabaseDirectories) {
fn print_running_environment(data_dir: &str, dirs: &Directories, db_dirs: &DatabaseDirectories) {
info!("Starting {}", Colour::White.bold().paint(version()));
info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(spec_name).to_string_lossy().into_owned()));
info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(data_dir).to_string_lossy().into_owned()));
info!("DB path {}", Colour::White.bold().paint(db_dirs.db_root_path().to_string_lossy().into_owned()));
}
@ -1002,7 +944,7 @@ fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str,
hardware_wallet_classic_key: spec == &SpecType::Classic,
unlock_keep_secret: cfg.enable_fast_unlock,
blacklisted_accounts: match *spec {
SpecType::Morden | SpecType::Ropsten | SpecType::Kovan | SpecType::Dev => vec![],
SpecType::Morden | SpecType::Ropsten | SpecType::Kovan | SpecType::Sokol | SpecType::Dev => vec![],
_ => vec![
"00a329c0648769a73afac7f9381e08fb43dbea72".into()
],

View File

@ -17,12 +17,13 @@
//! Parity upgrade logic
use semver::{Version, SemVerError};
use std::collections::HashMap;
use std::collections::*;
use std::fs::{self, File, create_dir_all};
use std::env;
use std::io;
use std::io::{Read, Write};
use std::path::{PathBuf, Path};
use dir::{DatabaseDirectories, default_data_path, home_dir};
use dir::{DatabaseDirectories, default_data_path};
use dir::helpers::replace_home;
use journaldb::Algorithm;
@ -105,7 +106,7 @@ fn with_locked_version<F>(db_path: Option<&str>, script: F) -> Result<usize, Err
where F: Fn(&Version) -> Result<usize, Error>
{
let mut path = db_path.map_or({
let mut path = home_dir().expect("Applications should have a home dir");
let mut path = env::home_dir().expect("Applications should have a home dir");
path.push(".parity");
path
}, PathBuf::from);

View File

@ -14,107 +14,130 @@
// 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 std::fs::File;
use std::io::Write;
use std::path::Path;
use std::collections::BTreeMap;
use std::time::Duration;
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::{Error, Visitor, MapAccess};
use serde::de::value::MapAccessDeserializer;
use serde_json::Value;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::de::from_reader;
use serde_json::ser::to_string;
use journaldb::Algorithm;
use ethcore::client::Mode;
use ethcore::client::{Mode as ClientMode};
#[derive(Clone)]
pub struct Seconds(Duration);
impl Seconds {
pub fn value(&self) -> u64 {
self.0.as_secs()
}
}
impl From<u64> for Seconds {
fn from(s: u64) -> Seconds {
Seconds(Duration::from_secs(s))
}
}
impl From<Duration> for Seconds {
fn from(d: Duration) -> Seconds {
Seconds(d)
}
}
impl Into<Duration> for Seconds {
fn into(self) -> Duration {
self.0
}
}
impl Serialize for Seconds {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_u64(self.value())
}
}
impl<'de> Deserialize<'de> for Seconds {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let secs = u64::deserialize(deserializer)?;
Ok(Seconds::from(secs))
}
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase", tag = "mode")]
pub enum Mode {
Active,
Passive {
#[serde(rename = "mode.timeout")]
timeout: Seconds,
#[serde(rename = "mode.alarm")]
alarm: Seconds,
},
Dark {
#[serde(rename = "mode.timeout")]
timeout: Seconds,
},
Offline,
}
impl Into<ClientMode> for Mode {
fn into(self) -> ClientMode {
match self {
Mode::Active => ClientMode::Active,
Mode::Passive { timeout, alarm } => ClientMode::Passive(timeout.into(), alarm.into()),
Mode::Dark { timeout } => ClientMode::Dark(timeout.into()),
Mode::Offline => ClientMode::Off,
}
}
}
impl From<ClientMode> for Mode {
fn from(mode: ClientMode) -> Mode {
match mode {
ClientMode::Active => Mode::Active,
ClientMode::Passive(timeout, alarm) => Mode::Passive { timeout: timeout.into(), alarm: alarm.into() },
ClientMode::Dark(timeout) => Mode::Dark { timeout: timeout.into() },
ClientMode::Off => Mode::Offline,
}
}
}
#[derive(Serialize, Deserialize)]
pub struct UserDefaults {
pub is_first_launch: bool,
#[serde(with = "algorithm_serde")]
pub pruning: Algorithm,
pub tracing: bool,
pub fat_db: bool,
pub mode: Mode,
#[serde(flatten)]
mode: Mode,
}
impl Serialize for UserDefaults {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
impl UserDefaults {
pub fn mode(&self) -> ClientMode {
self.mode.clone().into()
}
pub fn set_mode(&mut self, mode: ClientMode) {
self.mode = mode.into();
}
}
mod algorithm_serde {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de::Error;
use journaldb::Algorithm;
pub fn serialize<S>(algorithm: &Algorithm, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
let mut map: BTreeMap<String, Value> = BTreeMap::new();
map.insert("is_first_launch".into(), Value::Bool(self.is_first_launch));
map.insert("pruning".into(), Value::String(self.pruning.as_str().into()));
map.insert("tracing".into(), Value::Bool(self.tracing));
map.insert("fat_db".into(), Value::Bool(self.fat_db));
let mode_str = match self.mode {
Mode::Off => "offline",
Mode::Dark(timeout) => {
map.insert("mode.timeout".into(), Value::Number(timeout.as_secs().into()));
"dark"
},
Mode::Passive(timeout, alarm) => {
map.insert("mode.timeout".into(), Value::Number(timeout.as_secs().into()));
map.insert("mode.alarm".into(), Value::Number(alarm.as_secs().into()));
"passive"
},
Mode::Active => "active",
};
map.insert("mode".into(), Value::String(mode_str.into()));
map.serialize(serializer)
}
}
struct UserDefaultsVisitor;
impl<'a> Deserialize<'a> for UserDefaults {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'a> {
deserializer.deserialize_any(UserDefaultsVisitor)
}
}
impl<'a> Visitor<'a> for UserDefaultsVisitor {
type Value = UserDefaults;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a valid UserDefaults object")
algorithm.as_str().serialize(serializer)
}
fn visit_map<V>(self, visitor: V) -> Result<Self::Value, V::Error> where V: MapAccess<'a> {
let mut map: BTreeMap<String, Value> = Deserialize::deserialize(MapAccessDeserializer::new(visitor))?;
let pruning: Value = map.remove("pruning").ok_or_else(|| Error::custom("missing pruning"))?;
let pruning = pruning.as_str().ok_or_else(|| Error::custom("invalid pruning value"))?;
let pruning = pruning.parse().map_err(|_| Error::custom("invalid pruning method"))?;
let tracing: Value = map.remove("tracing").ok_or_else(|| Error::custom("missing tracing"))?;
let tracing = tracing.as_bool().ok_or_else(|| Error::custom("invalid tracing value"))?;
let fat_db: Value = map.remove("fat_db").unwrap_or_else(|| Value::Bool(false));
let fat_db = fat_db.as_bool().ok_or_else(|| Error::custom("invalid fat_db value"))?;
let mode: Value = map.remove("mode").unwrap_or_else(|| Value::String("active".to_owned()));
let mode = match mode.as_str().ok_or_else(|| Error::custom("invalid mode value"))? {
"offline" => Mode::Off,
"dark" => {
let timeout = map.remove("mode.timeout").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))?;
Mode::Dark(Duration::from_secs(timeout))
},
"passive" => {
let timeout = map.remove("mode.timeout").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value"))?;
let alarm = map.remove("mode.alarm").and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.alarm value"))?;
Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm))
},
"active" => Mode::Active,
_ => { return Err(Error::custom("invalid mode value")); },
};
let user_defaults = UserDefaults {
is_first_launch: false,
pruning: pruning,
tracing: tracing,
fat_db: fat_db,
mode: mode,
};
Ok(user_defaults)
pub fn deserialize<'de, D>(deserializer: D) -> Result<Algorithm, D::Error>
where D: Deserializer<'de> {
let pruning = String::deserialize(deserializer)?;
pruning.parse().map_err(|_| Error::custom("invalid pruning method"))
}
}

View File

@ -54,11 +54,11 @@ ethkey = { path = "../ethkey" }
ethstore = { path = "../ethstore" }
fetch = { path = "../util/fetch" }
keccak-hash = { git = "https://github.com/paritytech/parity-common" }
node-health = { path = "../node-health" }
parity-reactor = { path = "../util/reactor" }
parity-updater = { path = "../updater" }
parity-version = { path = "../util/version" }
patricia-trie = { git = "https://github.com/paritytech/parity-common" }
plain_hasher = { git = "https://github.com/paritytech/parity-common" }
rlp = { git = "https://github.com/paritytech/parity-common" }
stats = { path = "../util/stats" }
vm = { path = "../ethcore/vm" }

View File

@ -50,8 +50,6 @@ impl TimeProvider for DefaultTimeProvider {
const TIME_THRESHOLD: u64 = 7;
/// minimal length of hash
const TOKEN_LENGTH: usize = 16;
/// special "initial" token used for authorization when there are no tokens yet.
const INITIAL_TOKEN: &'static str = "initial";
/// Separator between fields in serialized tokens file.
const SEPARATOR: &'static str = ";";
/// Number of seconds to keep unused tokens.
@ -163,16 +161,6 @@ impl<T: TimeProvider> AuthCodes<T> {
let as_token = |code| keccak(format!("{}:{}", code, time));
// Check if it's the initial token.
if self.is_empty() {
let initial = &as_token(INITIAL_TOKEN) == hash;
// Initial token can be used only once.
if initial {
let _ = self.generate_new();
}
return initial;
}
// look for code
for code in &mut self.codes {
if &as_token(&code.code) == hash {
@ -239,7 +227,7 @@ mod tests {
}
#[test]
fn should_return_true_if_code_is_initial_and_store_is_empty() {
fn should_return_false_even_if_code_is_initial_and_store_is_empty() {
// given
let code = "initial";
let time = 99;
@ -250,7 +238,7 @@ mod tests {
let res2 = codes.is_valid(&generate_hash(code, time), time);
// then
assert_eq!(res1, true);
assert_eq!(res1, false);
assert_eq!(res2, false);
}

View File

@ -25,7 +25,7 @@ pub trait HttpMetaExtractor: Send + Sync + 'static {
/// Type of Metadata
type Metadata: jsonrpc_core::Metadata;
/// Extracts metadata from given params.
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>, dapps_origin: Option<String>) -> Self::Metadata;
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>) -> Self::Metadata;
}
pub struct MetaExtractor<T> {
@ -49,7 +49,6 @@ impl<M, T> http::MetaExtractor<M> for MetaExtractor<T> where
let origin = as_string(req.headers().get_raw("origin"));
let user_agent = as_string(req.headers().get_raw("user-agent"));
let dapps_origin = as_string(req.headers().get_raw("x-parity-origin"));
self.extractor.read_metadata(origin, user_agent, dapps_origin)
self.extractor.read_metadata(origin, user_agent)
}
}

View File

@ -60,11 +60,11 @@ extern crate ethkey;
extern crate ethstore;
extern crate fetch;
extern crate keccak_hash as hash;
extern crate node_health;
extern crate parity_reactor;
extern crate parity_updater as updater;
extern crate parity_version as version;
extern crate patricia_trie as trie;
extern crate plain_hasher;
extern crate rlp;
extern crate stats;
extern crate vm;
@ -118,8 +118,8 @@ pub use http::{
AccessControlAllowOrigin, Host, DomainsValidation
};
pub use v1::{NetworkSettings, Metadata, Origin, informant, dispatch, signer, dapps};
pub use v1::block_import::is_major_importing;
pub use v1::{NetworkSettings, Metadata, Origin, informant, dispatch, signer};
pub use v1::block_import::{is_major_importing, is_major_importing_or_waiting};
pub use v1::extractors::{RpcExtractor, WsExtractor, WsStats, WsDispatcher};
pub use authcodes::{AuthCodes, TimeProvider};
pub use http_common::HttpMetaExtractor;

View File

@ -73,7 +73,7 @@ mod testsing {
// when
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
let expected = "34\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown via RPC\",\"id\":1}\n\n0\n\n";
let expected = "4B\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / unknown agent via RPC\",\"id\":1}\n\n0\n\n";
let res = request(server,
&format!("\
POST / HTTP/1.1\r\n\
@ -98,7 +98,7 @@ mod testsing {
// when
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
let expected = "38\n{\"jsonrpc\":\"2.0\",\"result\":\"curl/7.16.3 via RPC\",\"id\":1}\n\n0\n\n";
let expected = "49\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / curl/7.16.3 via RPC\",\"id\":1}\n\n0\n\n";
let res = request(server,
&format!("\
POST / HTTP/1.1\r\n\
@ -116,59 +116,4 @@ mod testsing {
res.assert_status("HTTP/1.1 200 OK");
assert_eq!(res.body, expected);
}
#[test]
fn should_extract_dapp_origin() {
// given
let (server, address) = serve();
// when
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
let expected = "3A\n{\"jsonrpc\":\"2.0\",\"result\":\"Dapp http://parity.io\",\"id\":1}\n\n0\n\n";
let res = request(server,
&format!("\
POST / HTTP/1.1\r\n\
Host: {}\r\n\
Content-Type: application/json\r\n\
Content-Length: {}\r\n\
Origin: http://parity.io\r\n\
Connection: close\r\n\
User-Agent: curl/7.16.3\r\n\
\r\n\
{}
", address, req.len(), req)
);
// then
res.assert_status("HTTP/1.1 200 OK");
assert_eq!(res.body, expected);
}
#[test]
fn should_extract_dapp_origin_from_extension() {
// given
let (server, address) = serve();
// when
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
let expected = "44\n{\"jsonrpc\":\"2.0\",\"result\":\"Dapp http://wallet.ethereum.org\",\"id\":1}\n\n0\n\n";
let res = request(server,
&format!("\
POST / HTTP/1.1\r\n\
Host: {}\r\n\
Content-Type: application/json\r\n\
Content-Length: {}\r\n\
Origin: null\r\n\
X-Parity-Origin: http://wallet.ethereum.org\r\n\
Connection: close\r\n\
User-Agent: curl/7.16.3\r\n\
\r\n\
{}
", address, req.len(), req)
);
// then
res.assert_status("HTTP/1.1 200 OK");
assert_eq!(res.body, expected);
}
}

View File

@ -136,7 +136,7 @@ mod testing {
}
#[test]
fn should_allow_initial_connection_but_only_once() {
fn should_not_allow_initial_connection_even_once() {
// given
let (server, port, authcodes) = serve();
let code = "initial";
@ -160,26 +160,9 @@ mod testing {
timestamp,
)
);
let response2 = http_client::request(server.addr(),
&format!("\
GET / HTTP/1.1\r\n\
Host: 127.0.0.1:{}\r\n\
Connection: Close\r\n\
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\
Sec-WebSocket-Protocol:{:?}_{}\r\n\
Sec-WebSocket-Version: 13\r\n\
\r\n\
{{}}
",
port,
keccak(format!("{}:{}", code, timestamp)),
timestamp,
)
);
// then
assert_eq!(response1.status, "HTTP/1.1 101 Switching Protocols".to_owned());
assert_eq!(response2.status, "HTTP/1.1 403 Forbidden".to_owned());
http_client::assert_security_headers_present(&response2.headers, None);
assert_eq!(response1.status, "HTTP/1.1 403 Forbidden".to_owned());
http_client::assert_security_headers_present(&response1.headers, None);
}
}

View File

@ -36,14 +36,13 @@ pub struct RpcExtractor;
impl HttpMetaExtractor for RpcExtractor {
type Metadata = Metadata;
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>, dapps_origin: Option<String>) -> Metadata {
fn read_metadata(&self, origin: Option<String>, user_agent: Option<String>) -> Metadata {
Metadata {
origin: match (origin.as_ref().map(|s| s.as_str()), user_agent, dapps_origin) {
(Some("null"), _, Some(dapp)) => Origin::Dapps(dapp.into()),
(Some(dapp), _, _) => Origin::Dapps(dapp.to_owned().into()),
(None, Some(service), _) => Origin::Rpc(service.into()),
(None, _, _) => Origin::Rpc("unknown".into()),
},
origin: Origin::Rpc(
format!("{} / {}",
origin.unwrap_or("unknown origin".to_string()),
user_agent.unwrap_or("unknown agent".to_string()))
),
session: None,
}
}
@ -76,16 +75,15 @@ impl ws::MetaExtractor<Metadata> for WsExtractor {
fn extract(&self, req: &ws::RequestContext) -> Metadata {
let id = req.session_id as u64;
let dapp = req.origin.as_ref().map(|origin| (&**origin).into()).unwrap_or_default();
let origin = match self.authcodes_path {
Some(ref path) => {
let authorization = req.protocols.get(0).and_then(|p| auth_token_hash(&path, p, true));
match authorization {
Some(id) => Origin::Signer { session: id.into(), dapp: dapp },
None => Origin::Ws { session: id.into(), dapp: dapp },
Some(id) => Origin::Signer { session: id.into() },
None => Origin::Ws { session: id.into() },
}
},
None => Origin::Ws { session: id.into(), dapp: dapp },
None => Origin::Ws { session: id.into() },
};
let session = Some(Arc::new(Session::new(req.sender())));
Metadata {
@ -253,26 +251,13 @@ mod tests {
let extractor = RpcExtractor;
// when
let meta1 = extractor.read_metadata(None, None, None);
let meta2 = extractor.read_metadata(None, Some("http://parity.io".to_owned()), None);
let meta3 = extractor.read_metadata(None, Some("http://parity.io".to_owned()), Some("ignored".into()));
let meta1 = extractor.read_metadata(None, None);
let meta2 = extractor.read_metadata(None, Some("http://parity.io".to_owned()));
let meta3 = extractor.read_metadata(None, Some("http://parity.io".to_owned()));
// then
assert_eq!(meta1.origin, Origin::Rpc("unknown".into()));
assert_eq!(meta2.origin, Origin::Rpc("http://parity.io".into()));
assert_eq!(meta3.origin, Origin::Rpc("http://parity.io".into()));
}
#[test]
fn should_dapps_origin() {
// given
let extractor = RpcExtractor;
let dapp = "https://wallet.ethereum.org".to_owned();
// when
let meta = extractor.read_metadata(Some("null".into()), None, Some(dapp.clone()));
// then
assert_eq!(meta.origin, Origin::Dapps(dapp.into()));
assert_eq!(meta1.origin, Origin::Rpc("unknown origin / unknown agent".into()));
assert_eq!(meta2.origin, Origin::Rpc("unknown origin / http://parity.io".into()));
assert_eq!(meta3.origin, Origin::Rpc("unknown origin / http://parity.io".into()));
}
}

View File

@ -19,16 +19,23 @@
use ethcore::client::BlockQueueInfo;
use sync::SyncState;
/// Check if client is during major sync or during block import.
pub fn is_major_importing(sync_state: Option<SyncState>, queue_info: BlockQueueInfo) -> bool {
/// Check if client is during major sync or during block import and allows defining whether 'waiting for peers' should
/// be considered a syncing state.
pub fn is_major_importing_or_waiting(sync_state: Option<SyncState>, queue_info: BlockQueueInfo, waiting_is_syncing_state: bool) -> bool {
let is_syncing_state = sync_state.map_or(false, |s| match s {
SyncState::Idle | SyncState::NewBlocks | SyncState::WaitingPeers => false,
SyncState::Idle | SyncState::NewBlocks => false,
SyncState::WaitingPeers if !waiting_is_syncing_state => false,
_ => true,
});
let is_verifying = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3;
is_verifying || is_syncing_state
}
/// Check if client is during major sync or during block import.
pub fn is_major_importing(sync_state: Option<SyncState>, queue_info: BlockQueueInfo) -> bool {
is_major_importing_or_waiting(sync_state, queue_info, true)
}
#[cfg(test)]
mod tests {
use ethcore::client::BlockQueueInfo;

View File

@ -1,27 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Dapps Service
use v1::types::LocalDapp;
/// Dapps Server service.
pub trait DappsService: Send + Sync + 'static {
/// List available local dapps.
fn list_dapps(&self) -> Vec<LocalDapp>;
/// Refresh local dapps list
fn refresh_local_dapps(&self) -> bool;
}

View File

@ -19,6 +19,7 @@
use std::fmt;
use ethcore::account_provider::{SignError as AccountError};
use ethcore::client::BlockId;
use ethcore::error::{Error as EthcoreError, ErrorKind, CallError};
use jsonrpc_core::{futures, Error, ErrorCode, Value};
use rlp::DecoderError;
@ -100,6 +101,14 @@ pub fn request_rejected_limit() -> Error {
}
}
pub fn request_rejected_param_limit(limit: u64, items_desc: &str) -> Error {
Error {
code: ErrorCode::ServerError(codes::REQUEST_REJECTED_LIMIT),
message: format!("Requested data size exceeds limit of {} {}.", limit, items_desc),
data: None,
}
}
pub fn account<T: fmt::Debug>(error: &str, details: T) -> Error {
Error {
code: ErrorCode::ServerError(codes::ACCOUNT_ERROR),
@ -211,14 +220,6 @@ pub fn signer_disabled() -> Error {
}
}
pub fn dapps_disabled() -> Error {
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "Dapps Server is disabled. This API is not available.".into(),
data: None,
}
}
pub fn ws_disabled() -> Error {
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
@ -430,6 +431,19 @@ pub fn filter_not_found() -> Error {
}
}
pub fn filter_block_not_found(id: BlockId) -> Error {
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), // Specified in EIP-234.
message: "One of the blocks specified in filter (fromBlock, toBlock or blockHash) cannot be found".into(),
data: Some(Value::String(match id {
BlockId::Hash(hash) => format!("0x{:x}", hash),
BlockId::Number(number) => format!("0x{:x}", number),
BlockId::Earliest => "earliest".to_string(),
BlockId::Latest => "latest".to_string(),
})),
}
}
// on-demand sender cancelled.
pub fn on_demand_cancel(_cancel: futures::sync::oneshot::Canceled) -> Error {
internal("on-demand sender cancelled", "")

View File

@ -16,18 +16,14 @@
use transaction::{Transaction, SignedTransaction, Action};
use ethereum_types::U256;
use jsonrpc_core::Error;
use v1::helpers::CallRequest;
pub fn sign_call(request: CallRequest, gas_cap: bool) -> Result<SignedTransaction, Error> {
let max_gas = 50_000_000.into();
pub fn sign_call(request: CallRequest) -> Result<SignedTransaction, Error> {
let max_gas = U256::from(50_000_000);
let gas = match request.gas {
Some(gas) if gas_cap && gas > max_gas => {
warn!("Gas limit capped to {} (from {})", max_gas, gas);
max_gas
}
Some(gas) => gas,
None if gas_cap => max_gas,
None => max_gas * 10,
};
let from = request.from.unwrap_or(0.into());

View File

@ -16,6 +16,7 @@
//! Helpers for fetching blockchain data either from the light client or the network.
use std::cmp;
use std::sync::Arc;
use ethcore::basic_account::BasicAccount;
@ -31,7 +32,7 @@ use jsonrpc_macros::Trailing;
use light::cache::Cache;
use light::client::LightChainClient;
use light::cht;
use light::{cht, MAX_HEADERS_PER_REQUEST};
use light::on_demand::{
request, OnDemand, HeaderRef, Request as OnDemandRequest,
Response as OnDemandResponse, ExecutionResult,
@ -42,12 +43,13 @@ use sync::LightSync;
use ethereum_types::{U256, Address};
use hash::H256;
use parking_lot::Mutex;
use plain_hasher::H256FastMap;
use transaction::{Action, Transaction as EthTransaction, SignedTransaction, LocalizedTransaction};
use v1::helpers::{CallRequest as CallRequestHelper, errors, dispatch};
use v1::types::{BlockNumber, CallRequest, Log, Transaction};
const NO_INVALID_BACK_REFS: &'static str = "Fails only on invalid back-references; back-references here known to be valid; qed";
const NO_INVALID_BACK_REFS: &str = "Fails only on invalid back-references; back-references here known to be valid; qed";
/// Helper for fetching blockchain data either from the light client or the network
/// as necessary.
@ -207,7 +209,7 @@ impl LightFetch {
}
};
let from = req.from.unwrap_or(Address::zero());
let from = req.from.unwrap_or_else(|| Address::zero());
let nonce_fut = match req.nonce {
Some(nonce) => Either::A(future::ok(Some(nonce))),
None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))),
@ -232,29 +234,16 @@ impl LightFetch {
// fetch missing transaction fields from the network.
Box::new(nonce_fut.join(gas_price_fut).and_then(move |(nonce, gas_price)| {
let action = req.to.map_or(Action::Create, Action::Call);
let value = req.value.unwrap_or_else(U256::zero);
let data = req.data.unwrap_or_default();
future::done(match (nonce, req.gas) {
(Some(n), Some(gas)) => Ok((true, EthTransaction {
nonce: n,
action: action,
gas: gas,
gas_price: gas_price,
value: value,
data: data,
})),
(Some(n), None) => Ok((false, EthTransaction {
nonce: n,
action: action,
gas: START_GAS.into(),
gas_price: gas_price,
value: value,
data: data,
})),
(None, _) => Err(errors::unknown_block()),
})
future::done(
Ok((req.gas.is_some(), EthTransaction {
nonce: nonce.unwrap_or_default(),
action: req.to.map_or(Action::Create, Action::Call),
gas: req.gas.unwrap_or_else(|| START_GAS.into()),
gas_price,
value: req.value.unwrap_or_else(U256::zero),
data: req.data.unwrap_or_default(),
}))
)
}).join(header_fut).and_then(move |((gas_known, tx), hdr)| {
// then request proved execution.
// TODO: get last-hashes from network.
@ -312,55 +301,67 @@ impl LightFetch {
use std::collections::BTreeMap;
use jsonrpc_core::futures::stream::{self, Stream};
// early exit for "to" block before "from" block.
let best_number = self.client.chain_info().best_block_number;
let block_number = |id| match id {
BlockId::Earliest => Some(0),
BlockId::Latest => Some(best_number),
BlockId::Hash(h) => self.client.block_header(BlockId::Hash(h)).map(|hdr| hdr.number()),
BlockId::Number(x) => Some(x),
};
const MAX_BLOCK_RANGE: u64 = 1000;
match (block_number(filter.to_block), block_number(filter.from_block)) {
(Some(to), Some(from)) if to < from => return Either::A(future::ok(Vec::new())),
(Some(_), Some(_)) => {},
_ => return Either::A(future::err(errors::unknown_block())),
}
let fetcher = self.clone();
self.headers_range_by_block_id(filter.from_block, filter.to_block, MAX_BLOCK_RANGE)
.and_then(move |mut headers| {
if headers.is_empty() {
return Either::A(future::ok(Vec::new()));
}
let maybe_future = self.sync.with_context(move |ctx| {
// find all headers which match the filter, and fetch the receipts for each one.
// match them with their numbers for easy sorting later.
let bit_combos = filter.bloom_possibilities();
let receipts_futures: Vec<_> = self.client.ancestry_iter(filter.to_block)
.take_while(|ref hdr| BlockId::Number(hdr.number()) != filter.from_block)
.take_while(|ref hdr| BlockId::Hash(hdr.hash()) != filter.from_block)
.filter(|ref hdr| {
let hdr_bloom = hdr.log_bloom();
bit_combos.iter().find(|&bloom| hdr_bloom & *bloom == *bloom).is_some()
})
.map(|hdr| (hdr.number(), request::BlockReceipts(hdr.into())))
.map(|(num, req)| self.on_demand.request(ctx, req).expect(NO_INVALID_BACK_REFS).map(move |x| (num, x)))
.collect();
let on_demand = &fetcher.on_demand;
// as the receipts come in, find logs within them which match the filter.
// insert them into a BTreeMap to maintain order by number and block index.
stream::futures_unordered(receipts_futures)
.fold(BTreeMap::new(), move |mut matches, (num, receipts)| {
for (block_index, log) in receipts.into_iter().flat_map(|r| r.logs).enumerate() {
if filter.matches(&log) {
matches.insert((num, block_index), log.into());
}
}
future::ok(matches)
}) // and then collect them into a vector.
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
.map_err(errors::on_demand_cancel)
});
let maybe_future = fetcher.sync.with_context(move |ctx| {
// find all headers which match the filter, and fetch the receipts for each one.
// match them with their numbers for easy sorting later.
let bit_combos = filter.bloom_possibilities();
let receipts_futures: Vec<_> = headers.drain(..)
.filter(|ref hdr| {
let hdr_bloom = hdr.log_bloom();
bit_combos.iter().any(|bloom| hdr_bloom.contains_bloom(bloom))
})
.map(|hdr| (hdr.number(), hdr.hash(), request::BlockReceipts(hdr.into())))
.map(|(num, hash, req)| on_demand.request(ctx, req).expect(NO_INVALID_BACK_REFS).map(move |x| (num, hash, x)))
.collect();
match maybe_future {
Some(fut) => Either::B(Either::A(fut)),
None => Either::B(Either::B(future::err(errors::network_disabled()))),
}
// as the receipts come in, find logs within them which match the filter.
// insert them into a BTreeMap to maintain order by number and block index.
stream::futures_unordered(receipts_futures)
.fold(BTreeMap::new(), move |mut matches, (num, hash, receipts)| {
let mut block_index = 0;
for (transaction_index, receipt) in receipts.into_iter().enumerate() {
for (transaction_log_index, log) in receipt.logs.into_iter().enumerate() {
if filter.matches(&log) {
matches.insert((num, block_index), Log {
address: log.address.into(),
topics: log.topics.into_iter().map(Into::into).collect(),
data: log.data.into(),
block_hash: Some(hash.into()),
block_number: Some(num.into()),
// No way to easily retrieve transaction hash, so let's just skip it.
transaction_hash: None,
transaction_index: Some(transaction_index.into()),
log_index: Some(block_index.into()),
transaction_log_index: Some(transaction_log_index.into()),
log_type: "mined".into(),
removed: false,
});
}
block_index += 1;
}
}
future::ok(matches)
}) // and then collect them into a vector.
.map(|matches| matches.into_iter().map(|(_, v)| v).collect())
.map_err(errors::on_demand_cancel)
});
match maybe_future {
Some(fut) => Either::B(Either::A(fut)),
None => Either::B(Either::B(future::err(errors::network_disabled()))),
}
})
}
// Get a transaction by hash. also returns the index in the block.
@ -438,6 +439,150 @@ impl LightFetch {
None => Box::new(future::err(errors::network_disabled())) as Box<Future<Item = _, Error = _> + Send>
}
}
fn headers_range_by_block_id(
&self,
from_block: BlockId,
to_block: BlockId,
max: u64
) -> impl Future<Item = Vec<encoded::Header>, Error = Error> {
let fetch_hashes = [from_block, to_block].iter()
.filter_map(|block_id| match block_id {
BlockId::Hash(hash) => Some(hash.clone()),
_ => None,
})
.collect::<Vec<_>>();
let best_number = self.client.chain_info().best_block_number;
let fetcher = self.clone();
self.headers_by_hash(&fetch_hashes[..]).and_then(move |mut header_map| {
let (from_block_num, to_block_num) = {
let block_number = |id| match id {
&BlockId::Earliest => 0,
&BlockId::Latest => best_number,
&BlockId::Hash(ref h) =>
header_map.get(h).map(|hdr| hdr.number())
.expect("from_block and to_block headers are fetched by hash; this closure is only called on from_block and to_block; qed"),
&BlockId::Number(x) => x,
};
(block_number(&from_block), block_number(&to_block))
};
if to_block_num < from_block_num {
// early exit for "to" block before "from" block.
return Either::A(future::err(errors::filter_block_not_found(to_block)));
} else if to_block_num - from_block_num >= max {
return Either::A(future::err(errors::request_rejected_param_limit(max, "blocks")));
}
let to_header_hint = match to_block {
BlockId::Hash(ref h) => header_map.remove(h),
_ => None,
};
let headers_fut = fetcher.headers_range(from_block_num, to_block_num, to_header_hint);
Either::B(headers_fut.map(move |headers| {
// Validate from_block if it's a hash
let last_hash = headers.last().map(|hdr| hdr.hash());
match (last_hash, from_block) {
(Some(h1), BlockId::Hash(h2)) if h1 != h2 => Vec::new(),
_ => headers,
}
}))
})
}
fn headers_by_hash(&self, hashes: &[H256]) -> impl Future<Item = H256FastMap<encoded::Header>, Error = Error> {
let mut refs = H256FastMap::with_capacity_and_hasher(hashes.len(), Default::default());
let mut reqs = Vec::with_capacity(hashes.len());
for hash in hashes {
refs.entry(*hash).or_insert_with(|| {
self.make_header_requests(BlockId::Hash(*hash), &mut reqs)
.expect("make_header_requests never fails for BlockId::Hash; qed")
});
}
self.send_requests(reqs, move |res| {
let headers = refs.drain()
.map(|(hash, header_ref)| {
let hdr = extract_header(&res, header_ref)
.expect("these responses correspond to requests that header_ref belongs to; \
qed");
(hash, hdr)
})
.collect();
headers
})
}
fn headers_range(
&self,
from_number: u64,
to_number: u64,
to_header_hint: Option<encoded::Header>
) -> impl Future<Item = Vec<encoded::Header>, Error = Error> {
let range_length = (to_number - from_number + 1) as usize;
let mut headers: Vec<encoded::Header> = Vec::with_capacity(range_length);
let iter_start = match to_header_hint {
Some(hdr) => {
let block_id = BlockId::Hash(hdr.parent_hash());
headers.push(hdr);
block_id
}
None => BlockId::Number(to_number),
};
headers.extend(self.client.ancestry_iter(iter_start)
.take_while(|hdr| hdr.number() >= from_number));
let fetcher = self.clone();
future::loop_fn(headers, move |mut headers| {
let remaining = range_length - headers.len();
if remaining == 0 {
return Either::A(future::ok(future::Loop::Break(headers)));
}
let mut reqs: Vec<request::Request> = Vec::with_capacity(2);
let start_hash = if let Some(hdr) = headers.last() {
hdr.parent_hash().into()
} else {
let cht_root = cht::block_to_cht_number(to_number)
.and_then(|cht_num| fetcher.client.cht_root(cht_num as usize));
let cht_root = match cht_root {
Some(cht_root) => cht_root,
None => return Either::A(future::err(errors::unknown_block())),
};
let header_proof = request::HeaderProof::new(to_number, cht_root)
.expect("HeaderProof::new is Some(_) if cht::block_to_cht_number() is Some(_); \
this would return above if block_to_cht_number returned None; qed");
let idx = reqs.len();
let hash_ref = Field::back_ref(idx, 0);
reqs.push(header_proof.into());
hash_ref
};
let max = cmp::min(remaining as u64, MAX_HEADERS_PER_REQUEST);
reqs.push(request::HeaderWithAncestors {
block_hash: start_hash,
ancestor_count: max - 1,
}.into());
Either::B(fetcher.send_requests(reqs, |mut res| {
match res.last_mut() {
Some(&mut OnDemandResponse::HeaderWithAncestors(ref mut res_headers)) =>
headers.extend(res_headers.drain(..)),
_ => panic!("reqs has at least one entry; each request maps to a response; qed"),
};
future::Loop::Continue(headers)
}))
})
}
}
#[derive(Clone)]

View File

@ -18,7 +18,6 @@
pub mod errors;
pub mod block_import;
pub mod dapps;
pub mod dispatch;
pub mod fake_sign;
pub mod ipfs;

View File

@ -17,9 +17,8 @@
use std::collections::BTreeMap;
use ethereum_types::{U256, Address};
use parking_lot::{Mutex, RwLock};
use ethcore::account_provider::DappId;
use v1::helpers::{ConfirmationRequest, ConfirmationPayload, oneshot, errors};
use v1::types::{ConfirmationResponse, H160 as RpcH160, Origin, DappId as RpcDappId};
use v1::types::{ConfirmationResponse, H160 as RpcH160, Origin};
use jsonrpc_core::Error;
@ -30,14 +29,6 @@ pub type ConfirmationResult = Result<ConfirmationResponse, Error>;
pub enum DefaultAccount {
/// Default account is known
Provided(Address),
/// Should use default account for dapp
ForDapp(DappId),
}
impl From<RpcDappId> for DefaultAccount {
fn from(dapp_id: RpcDappId) -> Self {
DefaultAccount::ForDapp(dapp_id.into())
}
}
impl From<RpcH160> for DefaultAccount {

View File

@ -21,20 +21,19 @@ use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
use std::sync::Arc;
use rlp::{self, Rlp};
use ethereum_types::{U256, H64, H160, H256, Address};
use ethereum_types::{U256, H64, H256, Address};
use parking_lot::Mutex;
use ethash::SeedHashCompute;
use ethcore::account_provider::{AccountProvider, DappId};
use ethash::{self, SeedHashCompute};
use ethcore::account_provider::AccountProvider;
use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo};
use ethcore::ethereum::Ethash;
use ethcore::filter::Filter as EthcoreFilter;
use ethcore::header::{BlockNumber as EthBlockNumber};
use ethcore::log_entry::LogEntry;
use ethcore::miner::{self, MinerService};
use ethcore::snapshot::SnapshotService;
use ethcore::encoded;
use sync::{SyncProvider};
use sync::SyncProvider;
use miner::external::ExternalMinerService;
use transaction::{SignedTransaction, LocalizedTransaction};
@ -53,7 +52,7 @@ use v1::types::{
};
use v1::metadata::Metadata;
const EXTRA_INFO_PROOF: &'static str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed";
const EXTRA_INFO_PROOF: &str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed";
/// Eth RPC options
pub struct EthClientOptions {
@ -400,13 +399,6 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> EthClient<C, SN, S
Ok(Some(block))
}
fn dapp_accounts(&self, dapp: DappId) -> Result<Vec<H160>> {
self.accounts
.note_dapp_used(dapp.clone())
.and_then(|_| self.accounts.dapp_addresses(dapp))
.map_err(|e| errors::account("Could not fetch accounts.", e))
}
fn get_state(&self, number: BlockNumber) -> StateOrBlock {
match number {
BlockNumber::Num(num) => BlockId::Number(num).into(),
@ -509,15 +501,17 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
}
}
fn author(&self, meta: Metadata) -> Result<RpcH160> {
let dapp = meta.dapp_id();
let mut miner = self.miner.authoring_params().author;
fn author(&self) -> Result<RpcH160> {
let miner = self.miner.authoring_params().author;
if miner == 0.into() {
miner = self.dapp_accounts(dapp.into())?.get(0).cloned().unwrap_or_default();
self.accounts.accounts()
.ok()
.and_then(|a| a.first().cloned())
.map(From::from)
.ok_or_else(|| errors::account("No accounts were found", ""))
} else {
Ok(RpcH160::from(miner))
}
Ok(RpcH160::from(miner))
}
fn is_mining(&self) -> Result<bool> {
@ -532,10 +526,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)))
}
fn accounts(&self, meta: Metadata) -> Result<Vec<RpcH160>> {
let dapp = meta.dapp_id();
let accounts = self.dapp_accounts(dapp.into())?;
fn accounts(&self) -> Result<Vec<RpcH160>> {
let accounts = self.accounts.accounts()
.map_err(|e| errors::account("Could not fetch accounts.", e))?;
Ok(accounts.into_iter().map(Into::into).collect())
}
@ -744,9 +737,11 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
// check if we're still syncing and return empty strings in that case
{
//TODO: check if initial sync is complete here
//let sync = self.sync;
if /*sync.status().state != SyncState::Idle ||*/ self.client.queue_info().total_queue_size() > MAX_QUEUE_SIZE_TO_MINE_ON {
let sync_status = self.sync.status();
let queue_info = self.client.queue_info();
let total_queue_size = queue_info.total_queue_size();
if sync_status.is_snapshot_syncing() || total_queue_size > MAX_QUEUE_SIZE_TO_MINE_ON {
trace!(target: "miner", "Syncing. Cannot give any work.");
return Err(errors::no_work());
}
@ -769,7 +764,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
})?;
let (pow_hash, number, timestamp, difficulty) = work;
let target = Ethash::difficulty_to_boundary(&difficulty);
let target = ethash::difficulty_to_boundary(&difficulty);
let seed_hash = self.seed_compute.lock().hash_block_number(number);
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
@ -836,9 +831,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
self.send_raw_transaction(raw)
}
fn call(&self, meta: Self::Metadata, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
let request = CallRequest::into(request);
let signed = try_bf!(fake_sign::sign_call(request, meta.is_dapp()));
let signed = try_bf!(fake_sign::sign_call(request));
let num = num.unwrap_or_default();
@ -876,9 +871,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
))
}
fn estimate_gas(&self, meta: Self::Metadata, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
let request = CallRequest::into(request);
let signed = try_bf!(fake_sign::sign_call(request, meta.is_dapp()));
let signed = try_bf!(fake_sign::sign_call(request));
let num = num.unwrap_or_default();
let (state, header) = if num == BlockNumber::Pending {

View File

@ -29,7 +29,7 @@ use light::client::LightChainClient;
use light::{cht, TransactionQueue};
use light::on_demand::{request, OnDemand};
use ethcore::account_provider::{AccountProvider, DappId};
use ethcore::account_provider::AccountProvider;
use ethcore::encoded;
use ethcore::filter::Filter as EthcoreFilter;
use ethcore::ids::BlockId;
@ -252,8 +252,12 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
}
}
fn author(&self, _meta: Self::Metadata) -> Result<RpcH160> {
Ok(Default::default())
fn author(&self) -> Result<RpcH160> {
self.accounts.accounts()
.ok()
.and_then(|a| a.first().cloned())
.map(From::from)
.ok_or_else(|| errors::account("No accounts were found", ""))
}
fn is_mining(&self) -> Result<bool> {
@ -271,12 +275,8 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
.unwrap_or_else(Default::default))
}
fn accounts(&self, meta: Metadata) -> Result<Vec<RpcH160>> {
let dapp: DappId = meta.dapp_id().into();
self.accounts
.note_dapp_used(dapp.clone())
.and_then(|_| self.accounts.dapp_addresses(dapp))
fn accounts(&self) -> Result<Vec<RpcH160>> {
self.accounts.accounts()
.map_err(|e| errors::account("Could not fetch accounts.", e))
.map(|accs| accs.into_iter().map(Into::<RpcH160>::into).collect())
}
@ -398,7 +398,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
self.send_raw_transaction(raw)
}
fn call(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
match res {
Ok(exec) => Ok(exec.output.into()),
@ -407,7 +407,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
}))
}
fn estimate_gas(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
// TODO: binary chop for more accurate estimates.
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
match res {

View File

@ -26,7 +26,6 @@ use ethstore::random_phrase;
use sync::LightSyncProvider;
use ethcore::account_provider::AccountProvider;
use ethcore_logger::RotatingLogger;
use node_health::{NodeHealth, Health};
use ethcore::ids::BlockId;
use light::client::LightChainClient;
@ -44,7 +43,7 @@ use v1::types::{
Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, DappId, ChainStatus,
OperationsInfo, ChainStatus,
AccountInfo, HwAccountInfo, Header, RichHeader,
};
use Host;
@ -56,7 +55,6 @@ pub struct ParityClient {
accounts: Arc<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
health: NodeHealth,
signer: Option<Arc<SignerService>>,
ws_address: Option<Host>,
eip86_transition: u64,
@ -71,7 +69,6 @@ impl ParityClient {
accounts: Arc<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
health: NodeHealth,
signer: Option<Arc<SignerService>>,
ws_address: Option<Host>,
gas_price_percentile: usize,
@ -81,7 +78,6 @@ impl ParityClient {
accounts,
logger,
settings,
health,
signer,
ws_address,
eip86_transition: client.eip86_transition(),
@ -105,13 +101,10 @@ impl ParityClient {
impl Parity for ParityClient {
type Metadata = Metadata;
fn accounts_info(&self, dapp: Trailing<DappId>) -> Result<BTreeMap<H160, AccountInfo>> {
let dapp = dapp.unwrap_or_default();
fn accounts_info(&self) -> Result<BTreeMap<H160, AccountInfo>> {
let store = &self.accounts;
let dapp_accounts = store
.note_dapp_used(dapp.clone().into())
.and_then(|_| store.dapp_addresses(dapp.into()))
.accounts()
.map_err(|e| errors::account("Could not fetch accounts.", e))?
.into_iter().collect::<HashSet<_>>();
@ -142,10 +135,9 @@ impl Parity for ParityClient {
Ok(store.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))?)
}
fn default_account(&self, meta: Self::Metadata) -> Result<H160> {
let dapp_id = meta.dapp_id();
fn default_account(&self) -> Result<H160> {
Ok(self.accounts
.dapp_addresses(dapp_id.into())
.accounts()
.ok()
.and_then(|accounts| accounts.get(0).cloned())
.map(|acc| acc.into())
@ -326,10 +318,6 @@ impl Parity for ParityClient {
Ok(map)
}
fn dapps_url(&self) -> Result<String> {
Err(errors::dapps_disabled())
}
fn ws_url(&self) -> Result<String> {
helpers::to_url(&self.ws_address)
.ok_or_else(|| errors::ws_disabled())
@ -433,12 +421,7 @@ impl Parity for ParityClient {
ipfs::cid(content)
}
fn call(&self, _meta: Self::Metadata, _requests: Vec<CallRequest>, _block: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
fn call(&self, _requests: Vec<CallRequest>, _block: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
Err(errors::light_unimplemented(None))
}
fn node_health(&self) -> BoxFuture<Health> {
Box::new(self.health.health()
.map_err(|err| errors::internal("Health API failure.", err)))
}
}

View File

@ -29,7 +29,7 @@ use jsonrpc_core::{Result, BoxFuture};
use jsonrpc_core::futures::Future;
use v1::helpers::errors;
use v1::traits::ParitySet;
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction, LocalDapp};
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
/// Parity-specific rpc interface for operations altering the settings.
pub struct ParitySetClient<F> {
@ -137,14 +137,6 @@ impl<F: Fetch> ParitySet for ParitySetClient<F> {
Box::new(self.pool.spawn(future))
}
fn dapps_refresh(&self) -> Result<bool> {
Err(errors::dapps_disabled())
}
fn dapps_list(&self) -> Result<Vec<LocalDapp>> {
Err(errors::dapps_disabled())
}
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>> {
Err(errors::light_unimplemented(None))
}

View File

@ -46,11 +46,11 @@ impl Traces for TracesClient {
Err(errors::light_unimplemented(None))
}
fn call(&self, _meta: Self::Metadata, _request: CallRequest, _flags: TraceOptions, _block: Trailing<BlockNumber>) -> Result<TraceResults> {
fn call(&self, _request: CallRequest, _flags: TraceOptions, _block: Trailing<BlockNumber>) -> Result<TraceResults> {
Err(errors::light_unimplemented(None))
}
fn call_many(&self, _meta: Self::Metadata, _request: Vec<(CallRequest, TraceOptions)>, _block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
fn call_many(&self, _request: Vec<(CallRequest, TraceOptions)>, _block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
Err(errors::light_unimplemented(None))
}

View File

@ -22,7 +22,12 @@ use v1::traits::Net;
/// Net rpc implementation.
pub struct NetClient<S: ?Sized> {
sync: Arc<S>
sync: Arc<S>,
/// Cached `network_id`.
///
/// We cache it to avoid redundant aquire of sync read lock.
/// https://github.com/paritytech/parity-ethereum/issues/8746
network_id: u64,
}
impl<S: ?Sized> NetClient<S> where S: SyncProvider {
@ -30,17 +35,18 @@ impl<S: ?Sized> NetClient<S> where S: SyncProvider {
pub fn new(sync: &Arc<S>) -> Self {
NetClient {
sync: sync.clone(),
network_id: sync.status().network_id,
}
}
}
impl<S: ?Sized> Net for NetClient<S> where S: SyncProvider + 'static {
fn version(&self) -> Result<String> {
Ok(format!("{}", self.sync.status().network_id).to_owned())
Ok(format!("{}", self.network_id))
}
fn peer_count(&self) -> Result<String> {
Ok(format!("0x{:x}", self.sync.status().num_peers as u64).to_owned())
Ok(format!("{:#x}", self.sync.status().num_peers as u64))
}
fn is_listening(&self) -> Result<bool> {

View File

@ -32,10 +32,9 @@ use ethcore::ids::BlockId;
use ethcore::miner::{self, MinerService};
use ethcore::state::StateInfo;
use ethcore_logger::RotatingLogger;
use node_health::{NodeHealth, Health};
use updater::{Service as UpdateService};
use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::{future, Future};
use jsonrpc_core::futures::future;
use jsonrpc_macros::Trailing;
use v1::helpers::{self, errors, fake_sign, ipfs, SigningQueue, SignerService, NetworkSettings};
use v1::metadata::Metadata;
@ -45,7 +44,7 @@ use v1::types::{
Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, DappId, ChainStatus,
OperationsInfo, ChainStatus,
AccountInfo, HwAccountInfo, RichHeader,
block_number_to_id
};
@ -58,7 +57,6 @@ pub struct ParityClient<C, M, U> {
updater: Arc<U>,
sync: Arc<SyncProvider>,
net: Arc<ManageNetwork>,
health: NodeHealth,
accounts: Arc<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
@ -77,7 +75,6 @@ impl<C, M, U> ParityClient<C, M, U> where
sync: Arc<SyncProvider>,
updater: Arc<U>,
net: Arc<ManageNetwork>,
health: NodeHealth,
accounts: Arc<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
@ -91,7 +88,6 @@ impl<C, M, U> ParityClient<C, M, U> where
sync,
updater,
net,
health,
accounts,
logger,
settings,
@ -110,12 +106,8 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
{
type Metadata = Metadata;
fn accounts_info(&self, dapp: Trailing<DappId>) -> Result<BTreeMap<H160, AccountInfo>> {
let dapp = dapp.unwrap_or_default();
let dapp_accounts = self.accounts
.note_dapp_used(dapp.clone().into())
.and_then(|_| self.accounts.dapp_addresses(dapp.into()))
fn accounts_info(&self) -> Result<BTreeMap<H160, AccountInfo>> {
let dapp_accounts = self.accounts.accounts()
.map_err(|e| errors::account("Could not fetch accounts.", e))?
.into_iter().collect::<HashSet<_>>();
@ -139,16 +131,13 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
.collect()
)
}
fn locked_hardware_accounts_info(&self) -> Result<Vec<String>> {
self.accounts.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))
}
fn default_account(&self, meta: Self::Metadata) -> Result<H160> {
let dapp_id = meta.dapp_id();
Ok(self.accounts
.dapp_default_address(dapp_id.into())
fn default_account(&self) -> Result<H160> {
Ok(self.accounts.default_account()
.map(Into::into)
.ok()
.unwrap_or_default())
@ -347,10 +336,6 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
)
}
fn dapps_url(&self) -> Result<String> {
Err(errors::dapps_disabled())
}
fn ws_url(&self) -> Result<String> {
helpers::to_url(&self.ws_address)
.ok_or_else(|| errors::ws_disabled())
@ -435,11 +420,11 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
ipfs::cid(content)
}
fn call(&self, meta: Self::Metadata, requests: Vec<CallRequest>, num: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
fn call(&self, requests: Vec<CallRequest>, num: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
let requests = requests
.into_iter()
.map(|request| Ok((
fake_sign::sign_call(request.into(), meta.is_dapp())?,
fake_sign::sign_call(request.into())?,
Default::default()
)))
.collect::<Result<Vec<_>>>()?;
@ -470,9 +455,4 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
.map(|res| res.into_iter().map(|res| res.output.into()).collect())
.map_err(errors::call)
}
fn node_health(&self) -> BoxFuture<Health> {
Box::new(self.health.health()
.map_err(|err| errors::internal("Health API failure.", err)))
}
}

View File

@ -25,7 +25,7 @@ use ethcore::account_provider::AccountProvider;
use jsonrpc_core::Result;
use v1::helpers::errors;
use v1::traits::ParityAccounts;
use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, DappId, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo};
use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, Derive, DeriveHierarchical, DeriveHash, ExtAccountInfo};
use ethkey::Password;
/// Account management (personal) rpc implementation.
@ -143,61 +143,6 @@ impl ParityAccounts for ParityAccountsClient {
Ok(true)
}
fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<RpcH160>>) -> Result<bool> {
self.accounts.set_dapp_addresses(dapp.into(), addresses.map(into_vec))
.map_err(|e| errors::account("Couldn't set dapp addresses.", e))
.map(|_| true)
}
fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<RpcH160>> {
self.accounts.dapp_addresses(dapp.into())
.map_err(|e| errors::account("Couldn't get dapp addresses.", e))
.map(into_vec)
}
fn set_dapp_default_address(&self, dapp: DappId, address: RpcH160) -> Result<bool> {
self.accounts.set_dapp_default_address(dapp.into(), address.into())
.map_err(|e| errors::account("Couldn't set dapp default address.", e))
.map(|_| true)
}
fn dapp_default_address(&self, dapp: DappId) -> Result<RpcH160> {
self.accounts.dapp_default_address(dapp.into())
.map_err(|e| errors::account("Couldn't get dapp default address.", e))
.map(Into::into)
}
fn set_new_dapps_addresses(&self, addresses: Option<Vec<RpcH160>>) -> Result<bool> {
self.accounts
.set_new_dapps_addresses(addresses.map(into_vec))
.map_err(|e| errors::account("Couldn't set dapps addresses.", e))
.map(|_| true)
}
fn new_dapps_addresses(&self) -> Result<Option<Vec<RpcH160>>> {
self.accounts.new_dapps_addresses()
.map_err(|e| errors::account("Couldn't get dapps addresses.", e))
.map(|accounts| accounts.map(into_vec))
}
fn set_new_dapps_default_address(&self, address: RpcH160) -> Result<bool> {
self.accounts.set_new_dapps_default_address(address.into())
.map_err(|e| errors::account("Couldn't set new dapps default address.", e))
.map(|_| true)
}
fn new_dapps_default_address(&self) -> Result<RpcH160> {
self.accounts.new_dapps_default_address()
.map_err(|e| errors::account("Couldn't get new dapps default address.", e))
.map(Into::into)
}
fn recent_dapps(&self) -> Result<BTreeMap<DappId, u64>> {
self.accounts.recent_dapps()
.map_err(|e| errors::account("Couldn't get recent dapps.", e))
.map(|map| map.into_iter().map(|(k, v)| (k.into(), v)).collect())
}
fn import_geth_accounts(&self, addresses: Vec<RpcH160>) -> Result<Vec<RpcH160>> {
self.accounts
.import_geth_accounts(into_vec(addresses), false)

View File

@ -31,7 +31,7 @@ use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::Future;
use v1::helpers::errors;
use v1::traits::ParitySet;
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction, LocalDapp};
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
/// Parity-specific rpc interface for operations altering the settings.
pub struct ParitySetClient<C, M, U, F = fetch::Client> {
@ -182,14 +182,6 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
Box::new(self.pool.spawn(future))
}
fn dapps_refresh(&self) -> Result<bool> {
Err(errors::dapps_disabled())
}
fn dapps_list(&self) -> Result<Vec<LocalDapp>> {
Err(errors::dapps_disabled())
}
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>> {
Ok(self.updater.upgrade_ready().map(Into::into))
}

View File

@ -58,14 +58,14 @@ impl<D: Dispatcher> PersonalClient<D> {
}
impl<D: Dispatcher + 'static> PersonalClient<D> {
fn do_sign_transaction(&self, meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<(PendingTransaction, D)> {
fn do_sign_transaction(&self, _meta: Metadata, request: TransactionRequest, password: String) -> BoxFuture<(PendingTransaction, D)> {
let dispatcher = self.dispatcher.clone();
let accounts = self.accounts.clone();
let default = match request.from.as_ref() {
Some(account) => Ok(account.clone().into()),
None => accounts
.dapp_default_address(meta.dapp_id().into())
.default_account()
.map_err(|e| errors::account("Cannot find default account.", e)),
};

View File

@ -100,14 +100,14 @@ impl Private for PrivateClient {
})
}
fn private_call(&self, meta: Self::Metadata, block_number: BlockNumber, request: CallRequest) -> Result<Bytes, Error> {
fn private_call(&self, block_number: BlockNumber, request: CallRequest) -> Result<Bytes, Error> {
let id = match block_number {
BlockNumber::Pending => return Err(errors::private_message_block_id_not_supported()),
num => block_number_to_id(num)
};
let request = CallRequest::into(request);
let signed = fake_sign::sign_call(request, meta.is_dapp())?;
let signed = fake_sign::sign_call(request)?;
let client = self.unwrap_manager()?;
let executed_result = client.private_call(id, &signed).map_err(|e| errors::private_message(e))?;
Ok(executed_result.output.into())

View File

@ -112,7 +112,6 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
let accounts = self.accounts.clone();
let default_account = match default_account {
DefaultAccount::Provided(acc) => acc,
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
};
let dispatcher = self.dispatcher.clone();
@ -138,8 +137,8 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
type Metadata = Metadata;
fn compose_transaction(&self, meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
let default_account = self.accounts.dapp_default_address(meta.dapp_id().into()).ok().unwrap_or_default();
fn compose_transaction(&self, _meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
let default_account = self.accounts.default_account().ok().unwrap_or_default();
Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into))
}
@ -164,7 +163,7 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
let remote = self.remote.clone();
let confirmations = self.confirmations.clone();
Box::new(self.dispatch(RpcConfirmationPayload::SendTransaction(request), meta.dapp_id().into(), meta.origin)
Box::new(self.dispatch(RpcConfirmationPayload::SendTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()), meta.origin)
.map(|result| match result {
DispatchResult::Value(v) => RpcEither::Or(v),
DispatchResult::Future(id, future) => {
@ -221,7 +220,7 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> {
let res = self.dispatch(
RpcConfirmationPayload::SendTransaction(request),
meta.dapp_id().into(),
DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()),
meta.origin,
);
@ -236,7 +235,7 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
fn sign_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcRichRawTransaction> {
let res = self.dispatch(
RpcConfirmationPayload::SignTransaction(request),
meta.dapp_id().into(),
DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()),
meta.origin,
);

View File

@ -55,7 +55,6 @@ impl<D: Dispatcher + 'static> SigningUnsafeClient<D> {
let accounts = self.accounts.clone();
let default = match account {
DefaultAccount::Provided(acc) => acc,
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
};
let dis = self.dispatcher.clone();
@ -80,8 +79,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
}))
}
fn send_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> {
Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), meta.dapp_id().into())
fn send_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcH256> {
Box::new(self.handle(RpcConfirmationPayload::SendTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()))
.then(|res| match res {
Ok(RpcConfirmationResponse::SendTransaction(hash)) => Ok(hash),
Err(e) => Err(e),
@ -89,8 +88,8 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
}))
}
fn sign_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcRichRawTransaction> {
Box::new(self.handle(RpcConfirmationPayload::SignTransaction(request), meta.dapp_id().into())
fn sign_transaction(&self, _meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcRichRawTransaction> {
Box::new(self.handle(RpcConfirmationPayload::SignTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()))
.then(|res| match res {
Ok(RpcConfirmationResponse::SignTransaction(tx)) => Ok(tx),
Err(e) => Err(e),
@ -102,9 +101,9 @@ impl<D: Dispatcher + 'static> EthSigning for SigningUnsafeClient<D>
impl<D: Dispatcher + 'static> ParitySigning for SigningUnsafeClient<D> {
type Metadata = Metadata;
fn compose_transaction(&self, meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
fn compose_transaction(&self, _meta: Metadata, transaction: RpcTransactionRequest) -> BoxFuture<RpcTransactionRequest> {
let accounts = self.accounts.clone();
let default_account = accounts.dapp_default_address(meta.dapp_id().into()).ok().unwrap_or_default();
let default_account = accounts.default_account().ok().unwrap_or_default();
Box::new(self.dispatcher.fill_optional_fields(transaction.into(), default_account, true).map(Into::into))
}

View File

@ -87,11 +87,11 @@ impl<C, S> Traces for TracesClient<C> where
.map(LocalizedTrace::from))
}
fn call(&self, meta: Self::Metadata, request: CallRequest, flags: TraceOptions, block: Trailing<BlockNumber>) -> Result<TraceResults> {
fn call(&self, request: CallRequest, flags: TraceOptions, block: Trailing<BlockNumber>) -> Result<TraceResults> {
let block = block.unwrap_or_default();
let request = CallRequest::into(request);
let signed = fake_sign::sign_call(request, meta.is_dapp())?;
let signed = fake_sign::sign_call(request)?;
let id = match block {
BlockNumber::Num(num) => BlockId::Number(num),
@ -109,13 +109,13 @@ impl<C, S> Traces for TracesClient<C> where
.map_err(errors::call)
}
fn call_many(&self, meta: Self::Metadata, requests: Vec<(CallRequest, TraceOptions)>, block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
fn call_many(&self, requests: Vec<(CallRequest, TraceOptions)>, block: Trailing<BlockNumber>) -> Result<Vec<TraceResults>> {
let block = block.unwrap_or_default();
let requests = requests.into_iter()
.map(|(request, flags)| {
let request = CallRequest::into(request);
let signed = fake_sign::sign_call(request, meta.is_dapp())?;
let signed = fake_sign::sign_call(request)?;
Ok((signed, to_call_analytics(flags)))
})
.collect::<Result<Vec<_>>>()?;

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