Backport Beta 2.2.1 (#9905)

* Bump beta to version 2.2.1

* fix: Intermittent failing CI due to addr in use (#9885)

Allow OS to set port at runtime

* Use Weak reference in PubSubClient (#9886)

* Fix json tracer overflow (#9873)

* Fix json tracer overflow

* Replace trace_executed with a direct trace push

* Remove unused variable

* Add test for 5a51

* Remove duplicate json!

* Fix docker script (#9854)


* Dockerfile: change source path of the newly added check_sync.sh (#9869)

* Allow to seal work on latest block (#9876)

* Allow to seal work on latest block.

* Test from @todr to check sealing conditions.

* gitlab-ci: make android release build succeed (#9743)

* use docker cargo config file for android builds

* make android build succeed

* ethcore: use Machine::verify_transaction on parent block (#9900)

* ethcore: use Machine::verify_transaction on parent block

also fixes off-by-one activation of transaction permission contract

* ethcore: clarify call to verify_transaction

* foundation: #6692865, ropsten: #4417537, kovan: #9363457

* Remove rust-toolchain file (#9906)

* EIP-712 implementation (#9631)

* EIP-712 impl

* added more tests

* removed size parsing unwrap

* corrected TYPE_REGEX to disallow zero sized fixed length arrays, replaced LinkedHashSet with IndexSet, added API spec to docs, fixed Type::Byte encoding branch

* use Option<u64> instead of u64 for Type::Array::Length

* replace `.iter()` with  `.values()`

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

* tabify eip712.rs

* use proper comments for docs

* Cargo.lock: revert unrelated changes

* tabify encode.rs

* EIP 191 (#9701)

* added sign_191 rpc method

* fixed hash_structured_data return type

* added ConfirmationPayload::SignMessage for non-prefixed signatures, added tests for sign191

* renamed WithValidator -> PresignedTransaction

* rename applicationData to data in test

* adds docs for EIP191Version, renamed SignRequest to EIP191SignRequest

* light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure (#9824)

* fix start_gas, handle OOG exceptions & NotEnoughGas

* Change START_GAS: 50_000 -> 60_000
* When the `OutOfGas exception` is received then try to double the gas until it succeeds or block gas limit is reached
* When `NotEnoughBasGas error` is received then use the required gas provided in the response

* fix(light-fetch): ensure block_gas_limit is tried

Try the `block_gas_limit` before regard the execution as an error

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

Co-Authored-By: niklasad1 <niklasadolfsson1@gmail.com>

* simplify cargo audit

* Use block header for building finality (#9914)

* ci: nuke the gitlab caches (#9855)
This commit is contained in:
Thibaut Sardan 2018-11-14 15:23:44 +01:00 committed by GitHub
parent 5a7e54fb9e
commit 5c56fc5023
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 2146 additions and 117 deletions

View File

@ -9,16 +9,8 @@ image: parity/rust:gitlab-ci
variables: variables:
CI_SERVER_NAME: "GitLab CI" CI_SERVER_NAME: "GitLab CI"
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
BUILD_TARGET: ubuntu
BUILD_ARCH: amd64
CARGO_TARGET: x86_64-unknown-linux-gnu CARGO_TARGET: x86_64-unknown-linux-gnu
cache:
key: "${CI_JOB_NAME}"
paths:
- ./target
- ./.cargo
.releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries") .releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries")
only: &releaseable_branches only: &releaseable_branches
- stable - stable

148
Cargo.lock generated
View File

@ -424,6 +424,29 @@ name = "edit-distance"
version = "2.0.1" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "eip712"
version = "0.1.0"
dependencies = [
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lunarity-lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"validator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"validator_derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.5.0" version = "1.5.0"
@ -1061,6 +1084,26 @@ dependencies = [
"vm 0.1.0", "vm 0.1.0",
] ]
[[package]]
name = "failure"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure_derive"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "fake-fetch" name = "fake-fetch"
version = "0.0.1" version = "0.0.1"
@ -1173,6 +1216,14 @@ dependencies = [
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "gcc" name = "gcc"
version = "0.3.55" version = "0.3.55"
@ -1216,7 +1267,7 @@ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1389,6 +1440,11 @@ dependencies = [
"unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "if_chain"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "igd" name = "igd"
version = "0.7.0" version = "0.7.0"
@ -1407,7 +1463,7 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -1442,6 +1498,14 @@ dependencies = [
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "itertools"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.3" version = "0.4.3"
@ -1751,6 +1815,14 @@ dependencies = [
"linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "lunarity-lexer"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "macros" name = "macros"
version = "0.1.0" version = "0.1.0"
@ -2080,7 +2152,7 @@ version = "1.12.0"
dependencies = [ dependencies = [
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0", "panic_hook 0.1.0",
"parity-ethereum 2.2.0", "parity-ethereum 2.2.1",
] ]
[[package]] [[package]]
@ -2096,7 +2168,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-ethereum" name = "parity-ethereum"
version = "2.2.0" version = "2.2.1"
dependencies = [ dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2145,7 +2217,7 @@ dependencies = [
"parity-rpc-client 1.4.0", "parity-rpc-client 1.4.0",
"parity-runtime 0.1.0", "parity-runtime 0.1.0",
"parity-updater 1.12.0", "parity-updater 1.12.0",
"parity-version 2.2.0", "parity-version 2.2.1",
"parity-whisper 0.1.0", "parity-whisper 0.1.0",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2261,6 +2333,7 @@ version = "1.12.0"
dependencies = [ dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "cid 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"eip712 0.1.0",
"ethash 1.12.0", "ethash 1.12.0",
"ethcore 1.12.0", "ethcore 1.12.0",
"ethcore-devtools 1.12.0", "ethcore-devtools 1.12.0",
@ -2299,7 +2372,7 @@ dependencies = [
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-runtime 0.1.0", "parity-runtime 0.1.0",
"parity-updater 1.12.0", "parity-updater 1.12.0",
"parity-version 2.2.0", "parity-version 2.2.1",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2396,7 +2469,7 @@ dependencies = [
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-hash-fetch 1.12.0", "parity-hash-fetch 1.12.0",
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-version 2.2.0", "parity-version 2.2.1",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2406,7 +2479,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-version" name = "parity-version"
version = "2.2.0" version = "2.2.1"
dependencies = [ dependencies = [
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3176,6 +3249,17 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "synstructure"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "target_info" name = "target_info"
version = "0.1.0" version = "0.1.0"
@ -3515,6 +3599,14 @@ dependencies = [
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "toolshed"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "trace-time" name = "trace-time"
version = "0.1.1" version = "0.1.1"
@ -3687,6 +3779,34 @@ name = "utf8-ranges"
version = "1.0.1" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "validator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "validator_derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)",
"validator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "vec_map" name = "vec_map"
version = "0.8.1" version = "0.8.1"
@ -3972,6 +4092,8 @@ dependencies = [
"checksum ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a93a43ce2e9f09071449da36bfa7a1b20b950ee344b6904ff23de493b03b386" "checksum ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a93a43ce2e9f09071449da36bfa7a1b20b950ee344b6904ff23de493b03b386"
"checksum ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35b3c5a18bc5e73a32a110ac743ec04b02bbbcd3b71d3118d40a6113d509378a" "checksum ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35b3c5a18bc5e73a32a110ac743ec04b02bbbcd3b71d3118d40a6113d509378a"
"checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002" "checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002"
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
"checksum fixed-hash 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d5ec8112f00ea8a483e04748a85522184418fd1cf02890b626d8fc28683f7de" "checksum fixed-hash 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d5ec8112f00ea8a483e04748a85522184418fd1cf02890b626d8fc28683f7de"
@ -3982,6 +4104,7 @@ dependencies = [
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
@ -4001,13 +4124,15 @@ dependencies = [
"checksum hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)" = "78d50abbd1790e0f4c74cb1d4a2211b439bac661d54107ad5564c55e77906762" "checksum hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)" = "78d50abbd1790e0f4c74cb1d4a2211b439bac661d54107ad5564c55e77906762"
"checksum hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68f2aa6b1681795bf4da8063f718cd23145aa0c9a5143d9787b345aa60d38ee4" "checksum hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68f2aa6b1681795bf4da8063f718cd23145aa0c9a5143d9787b345aa60d38ee4"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec"
"checksum igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a254e265e8810deb357a9de757f784787ec415d056ededf410c0aa460afee9e" "checksum igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a254e265e8810deb357a9de757f784787ec415d056ededf410c0aa460afee9e"
"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum integer-encoding 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26746cbc2e680af687e88d717f20ff90079bd10fc984ad57d277cd0e37309fa5" "checksum integer-encoding 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26746cbc2e680af687e88d717f20ff90079bd10fc984ad57d277cd0e37309fa5"
"checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)" = "70783119ac90828aaba91eae39db32c6c1b8838deea3637e5238efa0130801ab" "checksum ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)" = "70783119ac90828aaba91eae39db32c6c1b8838deea3637e5238efa0130801ab"
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1" "checksum jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecfa3b81afc64d9a6539c4eece96ac9a93c551c713a313800dade8e33d7b5c1"
"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
@ -4038,6 +4163,7 @@ dependencies = [
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" "checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21"
"checksum lunarity-lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a1670671f305792567116d4660e6e5bd785d6fa973e817c3445c0a7a54cecb6"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" "checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
@ -4157,6 +4283,7 @@ dependencies = [
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b036b7b35e846707c0e55c2c9441fa47867c0f87fca416921db3261b1d8c741a" "checksum syn 0.15.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b036b7b35e846707c0e55c2c9441fa47867c0f87fca416921db3261b1d8c741a"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
@ -4189,6 +4316,7 @@ dependencies = [
"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" "checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c"
"checksum tokio-uds 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22e3aa6d1fcc19e635418dc0a30ab5bd65d347973d6f43f1a37bf8d9d1335fc9" "checksum tokio-uds 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22e3aa6d1fcc19e635418dc0a30ab5bd65d347973d6f43f1a37bf8d9d1335fc9"
"checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65" "checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65"
"checksum toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "450441e131c7663af72e63a33c02a6a1fbaaa8601dc652ed6757813bb55aeec7"
"checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9" "checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9"
"checksum transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e5866e5126b14358f1d7af4bf51a0be677a363799b90e655edcec8254edef1d2" "checksum transaction-pool 1.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e5866e5126b14358f1d7af4bf51a0be677a363799b90e655edcec8254edef1d2"
"checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e" "checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e"
@ -4211,6 +4339,8 @@ dependencies = [
"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f"
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" "checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" "checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
"checksum validator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "236a5eda3df2c877872e98dbc55d497d943792e6405d8fc65bd4f8a5e3b53c99"
"checksum validator_derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d360d6f5754972c0c1da14fb3d5580daa31aee566e1e45e2f8d3bf5950ecd3e9"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3365f36c57e5df714a34be40902b27a992eeddb9996eca52d0584611cf885d" "checksum vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3365f36c57e5df714a34be40902b27a992eeddb9996eca52d0584611cf885d"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"

View File

@ -2,7 +2,7 @@
description = "Parity Ethereum client" description = "Parity Ethereum client"
name = "parity-ethereum" name = "parity-ethereum"
# NOTE Make sure to update util/version/Cargo.toml as well # NOTE Make sure to update util/version/Cargo.toml as well
version = "2.2.0" version = "2.2.1"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]

View File

@ -177,8 +177,8 @@
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
}, },
"hardcodedSync": { "hardcodedSync": {
"header": "f90206a0391c42ff4f047145a6b9a14179c3cc404b31d92f30693e28cf2bba41f47f6329a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2930b35844a230f00e51431acae96fe543a0347a0fb280d4457e60a0b96577e1dde9e00905102cfd36def5c5b31dcc2284636136ea077f739c324e35c7448b14aa02186973d3c74cc1ab081498cd0c487a604873723a0e462d76b5204d14b13d1f1b39ea048a3b637f91d42c729c367d5bbdbd0a72d70b90100008003410402005000200009400030c40490500208480008414000a40048806408000080802008204400010001800c0020080c0a00400105a9080820400900240000084012030a1504030508000200005c4404a0c3490820000010400811040004708a1006910211444040c28001a800e920d00000940c200119111a10401001008044214002002080c21081801e008a320848a204400042400898004004010028840181106210080254a081112480031000410202440092c880be3894000120050500860880000108000c0080009e0000204007212840808cb80200601024020000210280100c018540b28a1041a62400000108204084000008808040000004870bc009a1914d7f8362f801837a121d8379ee5a845bbd53ca8573696e6731a0abce0f90ce69f740080eeb94d1cb13981fafe3bc6d020a44815acd86cbd3fc0a889501b04c0614e053", "header": "f90210a0b5950d9087e0e1d3dfc18cae9388fc798d9b3932a6efb4fc073081f5561adc8da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794829bd824b016326a401d083b33d092293333a830a00caa3307575bbbe59bb8f8a89f115ccb864866c2591d8d3ec3bffa6231532e52a024278597d4fddf58a4b55fe6a8bb7bf0e6cf1c6e75158b3d0d0b1bb9bb16647da01ba199a450390854e88ea5504144be61dd681e805aed7a1cc8bea61d5b61194bb901001902100820000000020110010418b02612064240040a4051001001a0024400e2484001141a422e56073887504031028220080010040501800000080080268040050018400100cc4710800419088000005a840a201c09011040086001260040000021004842021800024204400204a8a1180a8a0002164400202000115420602005512a20410088002248c000020e801803c051202030000420810912000401010604000801543084004414c051048082100000221684005c8015a40100040170025040132500014054900482500403088004000821194124a0b20000200229b9601c230180400802020800000408e49314200190121404002080218814a08085870ac84878814c3083662001837a2147837a050f845be9e82d8fe4b883e5bda9e7a59ee4bb99e9b1bca05714f772f5e2fa3a41a8c7435407b579b7c16397cf08eca605eadd9e63db7f6a88315d0b500d2cb0a8",
"totalDifficulty": "7128515864594819065361", "totalDifficulty": "7772265011609637471285",
"CHTs": [ "CHTs": [
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11", "0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
@ -3346,7 +3346,108 @@
"0xae4a71712cc96a5b30b45e3b92c339c2e975e4ed683f4d1fcadcdc121ff7c6bf", "0xae4a71712cc96a5b30b45e3b92c339c2e975e4ed683f4d1fcadcdc121ff7c6bf",
"0x226f6d8c71ec32c5eaab6b01c0fc1d00ae95e60b383d09560e90549b79eb1447", "0x226f6d8c71ec32c5eaab6b01c0fc1d00ae95e60b383d09560e90549b79eb1447",
"0xf3dec779841c9384df93bcefbba8700a292b570b29d286a7c9c5a442b4788a20", "0xf3dec779841c9384df93bcefbba8700a292b570b29d286a7c9c5a442b4788a20",
"0x63ef48e80efa45383857adcb0f31076393260cbad058d1938345ad13faae50b4" "0x63ef48e80efa45383857adcb0f31076393260cbad058d1938345ad13faae50b4",
"0x7ba213077278bd01ff874e760c3a0bfd4e5cf65bb18eed8b0f8076d81e16d05b",
"0x92eace1cff535745aae658d9ad90c372d41ce318a20716ae3b2c0958bdb48b33",
"0x76b2607fae8dbe532d8516c4c33e309f2c0a963bb68035f4361a2859d62d2daf",
"0xfb0c46a588438f4f217e183ef7772b649b5a45a318253496b01676253dedb568",
"0xd6dba12c700a0c5ca59b9d17f628066405de8e4399f92472cccce2e25e70ba4d",
"0x2390984444cbc9de301adaf0853f4f6ed2fb56fefeabce717306cf1e40da9618",
"0xa6992b0db82c50ce623febc7f16c8a316ce262255de11ad1914316b3d986fe66",
"0x96787cf8e0a70ffe5b84151ae8219362ba6d9465223c23c135590fe4cb9ab592",
"0x0b4e7fba24f6bed3790b8fc289e2715d9a3f4235c9316dd9d4f889f710a65ae4",
"0x49585a7af98ad032371df01c458fab933ac399ff4d2d35731a2d86fc136b5eb8",
"0x517947f22d8d56466dbb496f3e98fcd01864176af19be2112f2260e55bddbd58",
"0xbc0aa38cbc79c3557fa81e446071e6d531989d088c6311060bff971e430fa36b",
"0x5a0a88750db7ad3190dcaaf5bde2649e6fd99cc5b05979fff84ae689ed47b51b",
"0x9ad902d6abe59faabfa5fde485c2fe16f6f3e2c41aa8bdaba021e94a3c292dc8",
"0xbd6e7bf8b466940b9f619e3f433fb68c68d344974798996e454c925e2628b1b2",
"0x112b5e9d438eb79aa9d7b4488b6aa9f7edf7599dce805d8781510302da45e9a2",
"0x881255ae2cab543ee6b429e1b201c197cb35051d53f881cb51fc58f9c760e51d",
"0xcf56a4ed6b771e4905e6ba888390526eba8ba3483ead7585dee00c0eaea58cbc",
"0x12705d1609ee34bce0c82bab9da730452db57863371f5b84de84c4c135537237",
"0xa9abc081a75bfcde86ea830483be240cb3bcfa72ae34a16dfc35cb964dd7a457",
"0x65cf0c91f8567d8567ac3f00ddc19da0b916179266c7e42768fd5d7271e91092",
"0x07f15ccc91a47edfe9b67a79d05ed1da1410e3ac16e4a4c2147c3ef0de26ae62",
"0xb44eb7db9e4dbe8901bfac43ad54ef27576a3ac0c78218138715e03b3f9a782e",
"0x9ef66d20aeccdea66ade0fe8ccc0a85dbe9498305509c8919b670ae8e854a450",
"0xb10a7dbd4857f910ae8cca5d1b7a85923adaad65c4b00d1255813efef00c646f",
"0x20410bc64b58a1c221f7b38f293700591692c73a785d94a5548b336bd5db10da",
"0xed7176f398eb75ae6c1d4348d3882aade99573f8369ef00e809b1ff91b5a9191",
"0x35f06785e1f7e362682e969586322b1588624f6025692ca87db21cb199c382f4",
"0x9a6b06141660e2bd106f6d46afd2f3e64d72711ffe6a9c495887bc3932f7934e",
"0xd64e602a976e86d3948d0f4cf0b8f13a63558d5bdea5affb36eeb91007a653b3",
"0x71050553ca1da7234764a5486e4647fdad00652560eb47102c1d0fc039b4b63e",
"0x53ba43f79de58a957e8ac0d998ecb4999c68f423b1769d9e8df2405259dcdaa6",
"0x17b33d269609bd90fac57eaeb298bf489a3b8a985cfd9998d297c7e0628bc84c",
"0x9b47bba7ff6b283e76100e36246c0dcad836ff29a674fbb1c6d2f58e38e29f92",
"0x262f8387628500fa26e2cdca6b5938262c8fa81888daed41a09d880df136167f",
"0xb6c6d0ed2824a9818fa9476c99a810cf33a0c1fd3f2fb6b7a44603f2442525e7",
"0x6f3437e677dcc60cb587f6100eaa2e7ef5c76b57023b63ae61a6a8ed2750512d",
"0x4bb5aad759b0c6390cf4dbc6c32e78f2721c2be3f40ca3d11de880fbe90e456a",
"0xfbeced3e048769a07bfd50010de59cd24f2c534234abc1ee7f3fe9d7e3d9f482",
"0xbe871fdd431974370e8156fb9347377d1bb07990ff60296abbaaf2c38b4059d0",
"0xcbdf566fceb5adc33608a847c77b6f3501cdc4182ba98e04e1f7e8b8ae66ba5b",
"0xa06a5de4aeafdb5981ae02004a38c524116ebe557dda83abdf03141e4dfbd4cd",
"0x73660bb361b94287b85b6c41394bea5447e8e3ccffaba1772a765a8fc0fa9b27",
"0xf80439908d6173fe4fea42aeb07ddea2c644e581373dbe9dbb9d092f12fd2125",
"0x32d935f078bdbb9ae693bef4ab8316e7da701edf42f156568b639193b0ea24bf",
"0x8ef0b9f247b5b9d9e5a813877d03a518d1f06900e2fdf5743feda3537ab3777d",
"0x59f92f14340a77b94839b6ea61389691a6fa5bb2ddc5b2241e873b066d37fc61",
"0x0288bdae302901b701df46263f4b12bdd6bd76436c3ae1626936e1b4bb631ca7",
"0x2fcfd5a54d6bbe07d4063ef64fe4b164bd8cb89a8e03cb5fabee98bfef280e43",
"0xd8d1169b3a9aca48f167cd43e9617d3ecc74658ea61ace251beb370d3c05f86c",
"0xdb2c3ef7b8a8a18ad3a8ce7cb8a6be2e1ef2cd694fb3f1b2e0732f2e27c758cb",
"0xfbffbf26f4756bcf1cd217686597ffe9c1282a70b279c8b01ee5076ec31b1c2c",
"0x2cf1404cc8482698eccde40185740753c47319b1aa30d9204fe53922feaae9b8",
"0x553a9e079d09d3f8251947ab37891027fc3d041246f2e43f01321fc3523b508f",
"0x35954f131f276933c7ef3938f35c6011806c7dd637fa249451379003d740cbaa",
"0x1ee7a658e8a2368391810667c35b8b0e321d381907e2312e7789a3cc7b0341aa",
"0x4cb3c908526bc6ccbdd39d855b3b3649e59eec4322bf48f07598d98240101d0c",
"0x996eb99b0cb27fb5ec07873af17933f377ed2c131f02926bab74341c475a95a9",
"0x68a90de2c8ea439db0417b77a23eb66e7421268335be7e4f593a52b1093681fa",
"0x4325afa26bf545951a73c016d866f1c71a5855ef52202b7ad0c54dc23906936d",
"0xaf5111b606b0e6d699bb4fb61c8a0592af7eb45dd7357b3e896ebc3e798919ad",
"0x4de03498b2d532a8eb01a12edea2a15b8a907d6d23ccfc380507a5d294abce99",
"0x5d642ba55dc046ef1b84fe594ae2e46b844cc6590d580e2591ba9c0c1c942c24",
"0x8477bb69d6d23ae4f45e56c372d66f42ba7417cf5107136081b5ccdd208b1545",
"0x924f641a7cea7cf76ad8920b9ee7c39e74304169571b028fbe40e6ed255a90f4",
"0x4b39dbfae8635f286284009a0213c6d267d5f48485a25f2df855c5cac5e7d6ca",
"0x61827bf3a120a079111665f78ba2e5ad15943492e4ffdfc708e235f44ce92842",
"0xdc0c0dafc340277058a6f8e03bf4e5e733e05fa638e2a8c4ebe4521960bbdc20",
"0x7038c52c4e92d6ed20b19481ed63d432325f94ee2a3ad4c0d5e25fafe5b32bd6",
"0xe1f5a1123679ce45005d53672018e16648fd44c4a2251802f295d29ed876a0db",
"0x173a332438a181f6cf1773b2603556d229254861534f34ad65b2170b0cf47fb5",
"0x22a19ab1d828b5d05057f40f5cf798e27ec068fc584968987b7bbe440f52ac84",
"0x15b3e3b6e1de6b8a407ad7e325c53c4bfa9e73f23c6f3acedcdf68d759f73860",
"0x0347a8e310cbc921daf829002ba0c44399c4dd7c930ac1fca203272949e09dc9",
"0x9babeec2d3003ddb15fdcb89ec7b61c0d7f795145b58f55a17810447d5afe5be",
"0x62c14ff2ed414ede1e3fa7fc2fccbab0b8f284b9f38127823c3dc9eb55a08b44",
"0xb301a7c865abe0f42d9444b5c3b775dc6ab4c99effbe8d54cec29745ff4af01d",
"0x3fabed16363d78f34a13ca6b99cfc592671668d4281c5eb3ab07f4b9017a4ebc",
"0xb14af7c7331f7b5518e04bc31c8c2b63d9d497acac405bc22e1ab2431105b867",
"0xb7b90e8852ae132f858cb98635fd6e1267b141de7da6773ec4092d5c83def42b",
"0x1a5c8bed811fc72de8146516cc4d668fc4557baf48082503a2a5cc0e473b6e08",
"0x0060158b427095081a18fc57c4f56290873188960dc0e4d2b16cdd57b5761100",
"0x2f0dd546f4982d47b6e04ce282b19be8e165b5c89b5f03c1ac8c6d8be2af2b4f",
"0x229d31a50f46afeda23a2535c8b011a827383c981e7e59f67622359e4b307a10",
"0x10da7b2e78954845b506b9672ff93d3a617f187521116d442b364a1178f10f08",
"0x511325c034c772ff3a61b1c8d94e3c13f19cf1e93523a8924666833bc1e5b0ba",
"0x3a8b0251b2f7c99774d0a7863388422723b5405fd1db035ec5e30df90306e251",
"0x885c3b0507dcdd6e1cec187cf3d97ee12ce101ccf63d99c1c7fc77dd57ee0439",
"0xa76f1fdcf546ccb62f86ec7b85bd8eb662f696d7aed2f2ed2b3c769af90897b2",
"0xbec073b15a35de54487b60f92615cd44dbcb5a5fa9d1bcca2ea31437b2e45756",
"0x662013eba4201630ccc4a9b6fb1dac36f439cc6cd2b6f295c0260713d075108e",
"0x81b0148f7e690088330650b01c52831d50f3d30ba2fd2074bca5513c179ad30a",
"0x01614cb8f2f2bd6794a20513fffe99a36eee526b7145405db15f9c2ede980093",
"0xd3d8664a5464c8f681e37265948c4046e373843e602bee66c8583277397db258",
"0xdaf61a9e7157100cce6ea5bc405926fd4190fda7354edaafad9b6e468bb24422",
"0xeb05144e032621f7b1792dacbdc79c044a268442a9a9284ef1b2d1d60cadb29f",
"0xb1916e802e8e3eca2570d1a190d317cf38cf9f6b58119b65ed0d60b9749461ad",
"0x17e103cb26e7c5c7678a523f99f90387490bcca00916190e7e1b38274c52a375",
"0x105b8126ef037364f46a44fdca4fea1ec4c099de5a05918688249fb8844dfea0",
"0x7ca09f536bb9f0d7b3809c086918ba4750722edfd47153a8412fc761eb4783c8",
"0xc988cc2d92dcb85eaff8cf2f70ca49646cc5aff6c8e10b43a0581193137d3b92"
] ]
}, },
"nodes": [ "nodes": [

View File

@ -62,8 +62,8 @@
"gasLimit": "0x5B8D80" "gasLimit": "0x5B8D80"
}, },
"hardcodedSync": { "hardcodedSync": {
"header": "f90247a01865856fb6e4118598117560df31734c74cf725c8edae4db941055ac0afeb207a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e6d2b931f55a3f1701c7389d592a7778897879a054563efd593e9682943065880710af9187131127148575efc8bb51d80dfed41aa0a568a1653a6c7d559711be0b91a8e75db76c678dbdd286c75b88e4f0c0d31171a0dab32c5cbe9b9244a7af00afa7f6042a4ac923573e8f2f025b107abe1e3da999b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000004000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd8389b001837a120083046540845bbd803c9fde830200048f5061726974792d457468657265756d86312e32382e30826c698416ef600fb841387b51dae8bc8daa6cde190d3f44797690b4da1ce5fcfcd54bdbb2a6ee6d8c1f7649081ca28b5cd70067ee9f61e27d8184db83705102d5e1a269f2b631b4d5db01", "header": "f90247a0434ba1ebe3bc9d9d12886f616afee0eb785dd00d78aa64502045b249c8a3cc33a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940010f94b296a852aaac52ea6c5ac72e03afd032da0d1c1137be913218840c44bdb8f5709a59d8608b05be0dc2401402e11ff1bf2ada0eb50a864e57e19bd4c8499725a6a3841f706ff5d743e64f1d06db903aca62eaba0d4d77727f7253c109e6f048fa5b1583b6c2911ad77f7d59d8947d38a96a67729b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe838ee001837a120083013502845bea4f689fde830200088f5061726974792d457468657265756d86312e32392e30826c698416fa93dab841c80b3e34bacdc91e01f6a76c64a920a65edfea86b84e0fd59c6d8dbd7758f2dc4e3cb446de8dc07f3d8cb71375a6315f401cd1ce54c56694e4e01f7e774555e701",
"totalDifficulty": "3020091077015059097853315484608800838133866777", "totalDifficulty": "3135776192732436705400032023148164213445066062",
"CHTs": [ "CHTs": [
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac", "0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02", "0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
@ -4470,7 +4470,173 @@
"0xbe48c727fb6a32242229eaa09146c76522dcf6bed6d1c6fc1bebf86b5e4ccdb4", "0xbe48c727fb6a32242229eaa09146c76522dcf6bed6d1c6fc1bebf86b5e4ccdb4",
"0x8487b971e383272df82cd812a0bf3a2026b85bc3897b4ce9ce48afa00849fe00", "0x8487b971e383272df82cd812a0bf3a2026b85bc3897b4ce9ce48afa00849fe00",
"0x60d18b465172f59c0d71594b5273a90cb41db24a5d4c9fc37020f9d8c467a4a2", "0x60d18b465172f59c0d71594b5273a90cb41db24a5d4c9fc37020f9d8c467a4a2",
"0xab4e36d9f17c748c87d89c23b667e3f4e3265e77b62dbd9c92659026f8a53d12" "0xab4e36d9f17c748c87d89c23b667e3f4e3265e77b62dbd9c92659026f8a53d12",
"0x2c711e8eec1be3caef6e16a03dcca83dac3a565c93327c67f4e8ea9f2697d9e9",
"0x21d7a9a3f22a163767075aa693d82a962e4458b074bd8f3485c4ded1e47c1172",
"0x1509cac83867db4b888107974d5c8547dc4aa1db3b8e886291f0f9eb6bd7af58",
"0xa555eb6001982080479c9bdd3da9e8668bf90ca9538f16f27a45ae698ec85fb7",
"0x1d1f4019fa3ea7ec85ee0a411560738791f2d45fe5fe6242d07267183a852b96",
"0x2a8994caa5a27eb3081cc749cda5694da7ed3fbb8a1b4c67d7e92306cbd3c6ab",
"0x8389736ba114022ea97a6b3e755d75e74c3c370e9eb916c0f2d73a46a6f6c396",
"0x6a2e5d08ea64195a4153fc7bf26b7a99dcc9d31d8f58faa07510a1e87fb1ade4",
"0x78b66b38fd9b9cd3a5bc9c91c6f816153c2c28c1055f7ac9ad12ab61f9464850",
"0xb2f77834f7a88c4354763a28080d95be44dcb380d01f09292e679a6ed274b179",
"0x2070456b2bff0c30ae26b2435af82e153094aeea8102a75541e02a39e9ebe717",
"0x4e3bb2fbdc71602a62f0c423aa45398af09cf3ad24f0437027b4590e7056b882",
"0xe877208750e7569ce78215659ef78c1656e98b63ab6cc3e1381d7581afbea99f",
"0x8c9d8132d01b83cffd1a1fd9d19a3d2fb3a58a0a28602018db44f8b6dd5fe1aa",
"0xcece8a371b72873a660f4077f98b04d6a3cde1a150852db3a194a293e6a08b72",
"0xe72c8c7211acf2d67bf904cb3428c6fd69c8bd679d52deb3b2e749d5a3124b86",
"0x504f53693e747fbba7475dff1aad887ad0124d48cc7892ec488fda56e31e0de5",
"0xddb3ce7ac0c7e2d141df857e9e5c083d66f4a62ead742bf6631756a72fb643e3",
"0xdc1c6a45dd8308ea319671732de7578a65a025852a3cbe88aa9c5d770d662990",
"0xb6a9df772bdb5e7cdff569bb9d3078c081ed53e870f9171a5b0369d84fe6ce50",
"0x1b436a7d8c9af357c8175430e1d0d3057096c92bd8bd24fe285fa55673c68b72",
"0xa57ce7fed7521e26a908ead89253bc57939459b4c34fba583eececd0f9104e2a",
"0xb16c4f6bdce8de6657d049e2e41f91a1cef8623671eacb9ab02fff45cee7c0c3",
"0x8d23f3ea29767da41a2090cfceb56a65236a405031b69e614c78fb79c1847651",
"0x33149d4876fa24dea4e872ad1da120e01b14e8f9f8270611fced328a36df25ca",
"0x266c558486a85de2536e8849d49443e7d39797a6ed817ad7217633c28166bf06",
"0x2073a22a1f157025228f8fc82bdaff48d3cb1c9b004ac2cb867c2cbbe7cafd95",
"0xcf643d70f96101c99cedcc2d169b0196c564e7a8b235ae093ad25b1ba8981d01",
"0x1489101bebc1b60e4c0fa37a94bb946f1b51ba284c667e4b2f3270ef9d264d41",
"0xd2eceef739e2601390d872bdbb58f8d67864b000f7fbab07b0354c44279379e8",
"0xf67a02d7e7e6da127015e5137f90e30ab43c2e828e62c3f8fe68ad5a0a3011fb",
"0x01fe94220a07efc2bde2404c584f67e9b06e47eba05e50e71ad59710d9d6a9fd",
"0x509bc80d1a464116b4f234001c3f2d7aac7772cd6ec5fa6ef9606ab8ab273127",
"0xea497db1233691b3b86d8fc80ebffe28e6863f445a0b352a1286412a94ad2f6f",
"0x80074f0e2cb668b6a8e5b454db4ae5cf2482894f3ccb7648cfa26b3365a0a54b",
"0x56c8cd15e5e1a21c6f32f7211d18e1e56c89da688cf11b80c9e55718514eab24",
"0x6705989758f03a8c4ee93d44f53b4114a10337694197186b62ac2220188a6879",
"0x7581fbe2b0ae6e0a61d073fd1700c3111d2e3e8d9342d50800ba05d026c9edd6",
"0x254548091369ad8e0abbd2eb4e31e2c08c8e9dc0256fd0097e50e75831946924",
"0xac3119a5ba40f303a9a70ecdef9b6d4722c6adb6592a0cf52e5a312a1a0819c2",
"0xbdf30bc3cd852b882c5d410e6d4419e0f36ed17b761b58fe58ded980829d1cf8",
"0xebaeb5965563f6fa71006d8c2d285e093a167630c319cee2dfa961c4a583b60b",
"0x6cd6717885bd50263a97574e8a56a3ccbca88229bce595b38a454c1184ea94d5",
"0xc9bba3a4a72f0f08663e3af36e2bac2d4c8422b2e3c3bd29705e5b86e7c42a20",
"0xcc442230a4b6aed5a1eb2b8744a09aefe3cfb9e477816edfa829dfbd3f7c2bc7",
"0x4ee48471e3326144c7a48b15fa5f39691ad9f24b82430ca281eb961b18019e02",
"0x35016779dd877530f99b1d3372a0a77eff7ae831208d2bdfcd0979b838190acd",
"0xe3e9b2a4adc4b4e167376b33b8bf2a00bd64d52f66f4e7b291ade123e8c04402",
"0x5a7d1466e2538b62ceada9577079248788e912e23c4cbc52d7b82a1afbf28ec7",
"0xb8529c5a2b2dbfb72e70165b9c9291e7c02b43f157092a9b59f3b4cad85fb587",
"0x55e90fb666a950f38ae41732269cb69afca8643b75a99bce508a16e06685fc03",
"0x651f45996ed080d8a8dcb78550089331ad67c2df33330d1871dff956463aed3e",
"0x9c6b4a961663c59dde3a4f0fdf7b68b0b5f049719ba0d10d841855cffc7ee166",
"0x15c4d98e0ee4fa1535f83625a20bf1a491852884f8fe608eae6b9bde45986779",
"0xc7891cf34fcc61935a43f37bd7f23b674c785ef3b2718358fb627364f3d8b09b",
"0x8105fb76c9e1281f0f0d7c520dc6cd1d546d1b4b29cfa398eecd7965af57f408",
"0x2a141f1c4e1f1e7be5d10c444dde3d1b5fe1a69f23506d5ed1842957375a1208",
"0x9d2313d34a5a6873f2ae1e2684db00e3b693ba962796fe7e78d26a2c49104471",
"0x84d0245b1537ec1fae89fd39741d3b6427ceda3933f750befe4e2d8ec022fc1b",
"0x93d281ff6bfefc7f94058a0d87cb826b97728c9593ef4876b88c35d26b2163bf",
"0x9018a352b09cb36311d0b54bd83a33dcd5dca5ae7032f1d399fec3a0e5a9cb7a",
"0xf01486ea17dca0bb45c245c9ba76d20d1a2f4eb718b7d07fb5183736e5cd08c5",
"0xf797fec0a8cddb31ace66223e1355211e41211c4bfd33a416c8a1a86e497f630",
"0xf24aef69daf4e2b90b4f3bdedddbabbae86a7fd1182947da7306c8145f82cc88",
"0xdd14e34cd000ddb6ae6426dcd78cabbf6bfbe5b3ecd7553c4989b3891e506257",
"0xc01ece645c7430801ee26b20ad215e221f7de0e060fe004b450b372a6c4438a9",
"0x64c836653383bcb165207b80ee8f9377ad25ef1bcd6cf7ba166cca78419898ed",
"0x6b1cdfa195df272d7e35ccd843191d5725919c0d8b71f1abf4b950a954770503",
"0xebe51f94a9f445d83180c4f075d944fa2f05b5b784b7e3cb4bc1544020bd35cf",
"0x7007f6b2c04420d390fbdb6a9fc21edd3249c1a098f8a9383131b8be50c6f975",
"0x6b7e93d96f74fc2b068104a017fa5fa74836e8be5599865309361ad9305d9bb9",
"0xcccf2dc238c68464f3b0446e06fc48fedf202e366ace5734cdac5a7fe7c43342",
"0xfec77750c277cd6bb0937d25d7f598d07cbffb1117b6232e932a296f32b45ce5",
"0xb04e6883c11ba3f2b7f0301936c3dcb622f6f78b3d3d57e48c6dcba063038d6e",
"0x23fe83ea2f197cb97a3ce5f2afd75652cae993f30bc627e8b9572a0069ae088b",
"0x44cc6bf2cee513c826ecc0c130a32b61b0153129721ad2a70d4503b71c128247",
"0xb1a11be5f9b37faf1901b1405494af32084641dc02685ec33be7f6e82e360a42",
"0x284bdf9a6aa0ac964b0f5e72d0d47c713c919d72fa9e24f42b65d749efb6e2c3",
"0x96a0a0e92ed87946a322c9bca6c0ebf70e51e0e825e2ede85b975349f9bb2caa",
"0xd73becb6a3d9a155d46a96d17412cf015724a79b166d2961d24125d92e355947",
"0xd87f142746611ce081945999f42b8da49cbda03a10bf953ba043417861e27c77",
"0x4af010485b5385579a534693bd21ef3768c8920c5b5dc6f9ddf722cc68fd6550",
"0x65a2f4ec5cf3b37530fe0672418214618393db47ad1185f285b445cf5f53cf26",
"0x1d208df2a2785599565a40d934eb2c0cc1673c1dd43d11685d698122ecf24d6f",
"0x046b7211427f0027ed4b69b06cb43986d3cd53d1579a2e078f6904a06ee6587d",
"0x053fb3ccc35edc1a1623f8652dd8c239045b02b58ffe7d51337950ae43365990",
"0x0721f82b52ff87272e1b0af5f4dc16b90dfaaaf3ba56b91bef555d283c98a8ae",
"0x26e93e4e2d0df49a857bfcede7e6ac234d75b71617b561ce39c3db130449e4fb",
"0x5ed6d53c35a0aa52d9dd0a244f31be00426292c11676737c7283f567ba485dbc",
"0x047add17bd1601a06a32b721165ecb2afb55290e025a828696f234b95c52eae3",
"0x6f9e6884745cad7091646f7767a6b17ebffb6482ee4726f5c1f3b9e02d26b77f",
"0xab29ed5be2938fb19614da621ea9828eb338514309b3d56efc6f19b57b8f4f6a",
"0xd5f14043479e8e37c6545527b2e93a76763a654661af9a25adae2b37dac40672",
"0xc43635c1489c3cf3aa231419bfcf7bcb2455a812e4781e5947bb76cf0219d1e4",
"0x72117c92f8bab83ccc7fbe5fc6cd931c765238ebd67ad8c4fcf1353eb78c8df2",
"0x5deed7df3559ed75d7c2388a6e583067222684741143350f85d236bc5fb4075f",
"0x655bbc0590587c030902e32d88cc9113fcbdd5c3371820868768abaeacecb79c",
"0x1641c875e8e44b1fa71badcbb4f724a71e2f916d9cd212f09e9039ef41b1242f",
"0x40bacdc3f0b53522cdf2aefafa2bbd9c8e9f8fd25b4b33bc19a87d72a5de293d",
"0xc35c6cffaf93170662a6f3d4a0152c988b0f4916a33d037801f6f589a6140d08",
"0xd4e37125c0ca7844e048bac4e4c6069ec24b0493e4547f53679fc8df2a1e0d66",
"0x34c6bcf0e01dd55a1d3a82df0a2edcb2caccbc4be93fdfde32c7718276e59bbd",
"0x78e50d394d9d42ca8aae3f4dfccfb32fc3923073a6643c010fd49ec3897c4fe5",
"0xeba75c237fb213e893083c5ed0e28dde3ec1f5f1b60edfdddc17a54de9cdfaf3",
"0x4f35b9a67fc66492fea331378c479eba921fe0a6f0589b5ac07a44b1ea9b4995",
"0xbb4d09d98b27d672259b608f5075575cca49f87cce0519813c1ba4a614d369ee",
"0x805550ff80be2d3a543d5076961442f70dcd86e82762149c125d2ce371a32f69",
"0x7d81d766cc2d6c66c7bf07be0a416f2a4c0dd2bd94026270a410ea6a051dd4aa",
"0x30edcef101041c0e0acecb8d6c15a28c70b8894e56196cddefb5fb6b39658ceb",
"0xe5e8d21a00ccabb5cb50b4d04ee1dcc217fb9908e72bf0efab69d4ce7a0b7eab",
"0x3793f78e2e582b56fb3d24e3bd4aa69db4741e768795f9681285b0fd34ebd602",
"0x4a9378b4ad76df084739b2a63459ac67abf8eff7499210936fb9e6644265054a",
"0x2e47b62375a267e104ad2f8bfaf5c985fa7c6f4c438739810517e41141a825bd",
"0x73dd638affe08c104b37d53e6cb7884b8a9b4cd4afa4bbec6ef608bab4559dd9",
"0xc566dce73da1cc0d069a032045c44ac4ac86b145efd2cb1c363a2d403fd8d7cd",
"0xa1a04d193c5408d0edf85e771c6976c5dc8de08c87d906b6c9de1efa4b4fcbca",
"0x3245d987f205b01c54448d9a9d76bc7e4174c1021726a68f5feb6748ac373f8d",
"0x1f963274b936dde92281f2acd47d3685261b03845efc7d10ab8b02500c239af0",
"0xa1e6d69b28aea5d24c3dc301dfb0d6df8ee8fe693d1d0f419cde3b4d20d22a89",
"0x31b0711795c77cae9e1b62b87244a5eafa4b1764aa1620d53be7e779db060984",
"0xea141234dd00c54ec7912c80baca591b53a058b81fed1673317fa4ec37c2c715",
"0xc5902f3941d647da304e94062951b09f4d6da5bcff71517c7a35e8b49c6ac569",
"0x54c5677af7e31b84010f8b2941ffed5080e9b4d18b608fcbd230f163a5e04ba5",
"0x1a12c56542a01bc58288a58e8e526f2b2c81a5238c83bbfe4808d206b3b9d0e4",
"0xa398984bab81b7640674893496b2346eaa8257aad4cc8bb52474f7162fb6fa2d",
"0xf454a592314f1b7459d21eeb6ffe54c96ae2e25a7051dab1f8129518d3788cd2",
"0x12964f85bcc410fb40e89f518d749c7dc2be7546a960849dcf560eea2ec3d333",
"0xb176775c2ff94aedef2c099b936468986874d17eb563086215525acbee2fdbd1",
"0x250de6e94d60125bb680e862fcb70823d06e4f27308ea1ecea8a465d5febc860",
"0x731cc6817fec665290d7637c67fdbc72bbebae70a13f9346f47f3b368eb1e4a5",
"0x489e955cc77f16d8aa16bada320127380315eac978f0fd1033baa04911123332",
"0xa88623d9f89221dce46b55ca7248581b4e3ace94a7cccc9fd44a3b03412fa729",
"0x4a65c1808d79577b36dfb5fa74d0deb96e90d0105ee373d552685cc4f73d35d8",
"0x7aa8228e6f8fb98a23e1599e12ecd84c879475a23f10660e763e338a347c9002",
"0xa825d02023ab76478b83a2a61dcc5cf6c05ca741b960043adba3f13d1c99612a",
"0xd3c90e414048510d9594ae7a593e25641b6baf93f9625cc4a3caade094f02e07",
"0x4d631d9024a4e75111189835b4ec0007a6951d710512dd7b91a8d56da95e57b2",
"0x0158c7f49affa675f04aa4ebdf11e88bab8c6dc0abfecc0100d32489b0d59f1a",
"0x4ec96496694ef53e17b11b3122cc45cce3a4fe1a252fe9c0d379b302db1318ac",
"0xeec44b94d9f6c7359047d257ffd5f1f5cee87b3ebd6845dc1fe48be686a9ba69",
"0xe24c7b667382186196e5da605ce75a5cd9c7e4803fb2e268b4de5848737db026",
"0x14a551850f945f02fa2ab84c6ffe3d17930c81f5b15e94ce92342c3646b8cd9a",
"0x7e9a72469a52662bbcacd449dc7df8fa75e5cd1480dac3b635148a34e0f9e375",
"0x2dd4fd0394574c5d8c9272c42175e3a88d8501753bb25a77fa937123d0c2538d",
"0x6f044eb54fd2b8e51d89f6db2ee6e654b144d9e69cddf79b7899e06af5bf39f5",
"0x091d894513fca5d2239f6b5ce73737aa2657c90c2af196b2b893ba0b0205859c",
"0x78b9ca580e3eca0808e60420ead000365eeafa60c6394e055a653a7f536c8b6d",
"0x595cfe325aa600ef0d7de6b2eb717b33c92dfbb1e3ecb9487fe332c878e9f121",
"0xe1dcc22aa44a0243f67dcb0aef7e0eb1ceee269b0faa67633698f8ee29155115",
"0xddd3354d4167161c6b18173ae24fffac2cff12a8bcb3ddf1d964907716685cb3",
"0x55c02c02eb758f8c9aab60a2432d29e73b567e3e3d0148611ce4569fa074c5d9",
"0x5d07d5a7d45fe16a0521c55b3dd898b922c619e5b938535e2f974f11b4edfdc7",
"0xf75100a1a2f8d6daf0dc36569cbf579ed6e52838b163fe50b5deaad8fe7bd07d",
"0xb6391d028fbc88825eabf1dc4566e58112e6d3b7cfe6d387d0fa58df387df78f",
"0x8a58fab34ada4d30eecbad64a001015c91e446cf14e95c9d7a3d894530787b03",
"0xac13b36d0eb0483ab8cf21f49c78f9e32092c74c878ff520ed3a3c0080fdf5fd",
"0x358c1021fbdf028ec82b811cdeb504adc2611a1ab477e8a191f780592d598361",
"0x6a7af25eb6d089ad63712187d1414e8bd04fb6bfbac26e6086b1a3e2d66f6f7e",
"0x6bebf617fe66129dc8c9dadef1a74df05567ed2fc89f4e5c4dd36327d6b0a5e5",
"0xc658d76eb9f3fb91327c64668b08d3e9bfbbb2099bf5d9aeb6a61b8e4f893c39",
"0xfe68ecc66eaa625842068f8b5ad4bdf5cbce0c82ecfafa4bf48b08de49c58595",
"0x26eba0a168f2e5f3ffcb37955839d37432b39f2f447497854d42d802826fb1ee",
"0x8b4f8964062d0f00e40a41d21852a2e22abba1f4cf75f594797e368e4df21f7d",
"0x916993123d91b181d145e2668efed6eae3845fd76d4765df3a04d8adde8c7142",
"0x21b91051b5c5fbd22164a655de8485cfc2a9eff58ed09d6fbbb454560898daed",
"0xb52ca76065bcf43f06335977ab87d6c809dcf4e6cdfc452ac2018b77c64089a5"
] ]
}, },
"accounts": { "accounts": {

View File

@ -62,8 +62,8 @@
"gasLimit": "0x1000000" "gasLimit": "0x1000000"
}, },
"hardcodedSync":{ "hardcodedSync":{
"header": "f90217a00f0e017311206b97b47403eba05a16ada760a691a36f844ab8bc9082a4efedc9a067baeee20ae4f4216ab4b0c41198efd376aca23e44b1d6575c5949955547b72a946a9ecfa04e99726ec105517ac7ae1aba550bea6ca0e64d4fe9bee34d98e127f7f94f17535582d5bc6eeb6219f323b046b9a98c72b5a02d33ce5daab0436707c6d958dcf0bcd311ec7a72d7b33c20784178d5d95bc6e9a0a5b9cd4802fafaa9381ec0aa745cdb7ac953675e9df89474e5fe14fee134cf87b90100000008018000100000000000800000010000000050004000800000800014200010000001000000000001009001000000000000000000000000000000006004020600000000200001000108088002260441000020204000000000000000000280000000000200010001000000041008002000000004004c000000001000000000008000000000000800000400000201000000044001145000000000000001000a0200c04000a00010080100000020000000400002040000000000040000000040200001020000401000000800080080000400010000000200000008020020200000101000000000100400000000004400010020000200000000000001000000008453461c8683402001837a1200832c5216845bbd359199d88301080f846765746888676f312e31302e31856c696e7578a0c1da176f6642888b4369e14349ca7dc125ef7d4f5f7abad61bd7f6b95bfd46bf887d1a171a9f55dd67", "header": "f90205a0cd611d63e443c91cba1dc259c71fdb96bb70a1b78639166f7aa2a09b36843f7da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940d85c541489b4c67df516b86898e1ed59c8d639aa039cdbfba9ee1e91d15fead004292a7df0865204ee878daab2375683cc527df2ca0ebf5b5fe0ef82be8bda42e6767ad7881269cefe650c3a899f38f5ed1c05cad8da0578f443c4b0d0bd89e42a855436258f1b19d1a018f6769c5be7aca0679ce6008b90100000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000800000000000000008501856ef4de83436801837a121d830e1038845bea0191864b564f544845a08dcfeee7d79d54276d8bc35765ade21a51d277540a3d7a8e17fc26b6324487e488d70f2a90307e2ae3",
"totalDifficulty": "12027449412394243", "totalDifficulty": "14549054591321060",
"CHTs": [ "CHTs": [
"0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a", "0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a",
"0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc", "0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc",
@ -2116,7 +2116,112 @@
"0x40384a52564fae5df8c3e41827cdf584e38f3f555a54ca749b7b516619071d85", "0x40384a52564fae5df8c3e41827cdf584e38f3f555a54ca749b7b516619071d85",
"0xe52f7c17a4106594563ae7b724e5613e87d8442177f39a36b946b0e335be0e5b", "0xe52f7c17a4106594563ae7b724e5613e87d8442177f39a36b946b0e335be0e5b",
"0x7726202a7c255a9d7be47af6f3b44c1e379cda61237866554396fb6ec043482c", "0x7726202a7c255a9d7be47af6f3b44c1e379cda61237866554396fb6ec043482c",
"0x665da353f296cde80e3cbcb9c7f93b107d5676e5cd694b0bd33334d74789beb9" "0x665da353f296cde80e3cbcb9c7f93b107d5676e5cd694b0bd33334d74789beb9",
"0xa1157fb181aaa945793b029d3915b37103d050f1f695862d9cda90df4755c189",
"0x449c9daae1c38b3d3f6861b63dc611f147b8a29029927f85c32b5e549df8ee9d",
"0x5739fcf908f960416e5227ff6f95aeb00696f8eb7192968239458a0aebf42533",
"0xfaa6017362d6e64f9ae1b6d11764ddba77cd980261acb5bdbb17b7cdee2d3024",
"0x97fee586909cf8b3cfb2f2dd4e251cb642eb551f1e5d9fa557a21dcb66f430c0",
"0x9934d90e0b4ec5900107784116323b0f76d1d71491cf9c619520478b6eb97ded",
"0x8f5afe4fefb0de810442e27b2bce63e3a424f9e339a0e1f46f6ed26617a4a404",
"0xcd12ed1b75e624f93d9e4fe7dc65407b6d7963196e4082fb459ce354977355a1",
"0x6858ff0c07de87aa2a88498ae948efe6cffade00f3f21086f0a71b8364090846",
"0xaca944e99122e4fe41c62b88e67940332483c8aae2a3a615508f848ceb1c044e",
"0xa8bd3a6b9197bec8849737e6771f563d14d7415707776ce4bed9460588c55c9a",
"0x20e5f18e795844cfcf2326f52ab1e56f4a53a1ce405fd355e0d37de5f6d552ee",
"0x038821cd156d2d9e2aff1ce3525726c42f581ca3e9e2cc75df524a3dbdfe0feb",
"0xb79bd23e10d1e6c7ae749cecaa732966ce3c2e2ea8b640d43638f14d7b78a21c",
"0x2c4d3bcae4a76ffe6924555b320847211367ee37899b187d8fd4358d91264c2e",
"0x0896db7657d2aa8d02166bd4ceba7515b24147fcf0aa34223590fb80db64f848",
"0x95f3b077d9cff92709d46185a7dc5d723f257fb77641e436b0f1bf07947844a1",
"0x6fdd931a93229698b92e6419074bc308a372e0923b35321b725916c1c151cae0",
"0x8c337c36c2027d0f2fb96405f76d3190cdd01237f6a602e07976e09c4a2339e4",
"0x8091a859cf86c1e2c22c870ebc10334f50e05bac2a41153102bf3f698bf5156b",
"0x382435cc836bf1873e489cb4d42d1c1673c5d1b452ba2d16dbd1ca77b7b87a8c",
"0xac5a288b16ed708b00cbe956a14e2a64b321f40851ea25ab1aded7b096822ec6",
"0xee95229b736827a21e0b7154873da3da59e38a1ba3e3b1770de2ed973495ce23",
"0x5168b6e3b5274054fec17b94a82931bc229d0270e5e4c9aeb61539fe8ba4f4a3",
"0x588c6144dfbb33922873946a44f03092bd65d2f89a01b3973002ed38f48917bc",
"0x6c51a964953dc036043b6e8c7fba4a3f6e83295306767bcc3562d9a8cdb04497",
"0x2cfdde11cc2669c5b504c4a82c31ff03e3f0b3aff044519b44bc39405bbf3c9b",
"0xd93200e550400a7179ac7afc394b22b7c710192eadbf429389450e7167191fdb",
"0x5e32f497c606c01c9be8ce1cca5f3cf475f62cf38b2195244a7c93df7d064dde",
"0xb0b74e34fd3983aef31a0584b6a7483ee936622b5fffbdce1411a9db6171c685",
"0x69d0a96a2eca8d6a5c32e700d3f910330930a3348e98e5b276013fcf70c0fe5f",
"0xf49cbb26f2463d38fde553e483de2d4bc6dd85efe2d0e56a2a79810df6af6db9",
"0xe58aa167a26eadf11257f1fcb5da7eef50f9985b590320cc6c015176965ea58e",
"0x582f08d14023a661a9d9dfd1db8324be88fc631cb9136e92f379ad7703584414",
"0xb9c5e584f5e231c2c41b41799a945d60b7ec22487e587ef55e2d9710489c3c00",
"0xd8b70c6657a5bf1fa4b67c4fc046c1eda284d677c610dbacaf0d2d84e4d782dd",
"0x1e29fb536e468abf66b59dd6f48d177a5100a192f1807afc12bb5c97368b8c95",
"0x595ac042acdb51370bf6bfd2b2058dda4781dd7ec330474defb2d5dd00e7f50e",
"0x3d00887c6509b148c5fadde21014aae94924fef363fd5723d80d6a2028df1de5",
"0x9632d419c9fdc7e676b130806cb9c86631aade0adc6a129d3769908ff97e7ef3",
"0x2f91c7ce1158228c8264a6147c6ca396b0d536cdde997a922cde2772b786743f",
"0xf4c731ac2e2612b7e7afcf3ba5911a58a03ef075133923218f54a736b25acb81",
"0x6748a5143ad25f0a461257a47eeab8f057782a438274ced580ca2bd3725d6be3",
"0x05a113b04baf81b6396dd32d59a53908d07a374ebdf17314ec334b3330a16697",
"0xb1bafaef874da14b8a9f883f89a896ec37d9af1b0958f5a3867780278bfe940d",
"0xd93c67d29befe531330c37dfa8b64db7339c8ac35b8cb674d741a414d90d77ef",
"0xb4319281a05f00968367a349e626ec63227412193c30aaface14ac6f7a480024",
"0xf6dce891724a49024535047bee44f889d5228066a931a8f40c18c7efed60f31b",
"0xccdeb308e3402c7dc72588871c23fb4f6fdc60e2a63230f628c5a2951878535b",
"0x90958033b917eea42ffb8bf077ccab8b19c2448113e8a128815ab3441846404b",
"0xed3436553039948094f33cffaff91a7e2b1eab86b638de5c8eb09538c8df0a8e",
"0x0910ba3093e37abaf70ffc0ef6a3b9b82e8c5f7ae497eec14b753f23d0a25343",
"0xdc78d9fceec3add33b92e1a0ee402b80cd87946e0def46f284d26eac46be6bcd",
"0x1d71a82b8d4b89f73747d8073a36acf8496757d35bb452e9cfd74d758774f492",
"0x5399612937722b6fbcb90c1768a92bb35acd4da6168814c1d9deb6156cf35134",
"0xc7156ee3591ab91824b2d4868d28baf11855a63a801b3793f99fdde7867eac7f",
"0xd25b288f3333ea8e33b33f42edf7b64976281e4840599aa49b07da39f895073a",
"0xc6596a87c544e84cfaa2baaa4fb0a93f3fa9d1e6938426ea05a418568a1589b0",
"0xdbf30aa7f1cb3a6d7661934d7ea2ec0665843ea1ec9b05fddd77fdb33fa7d834",
"0xfac2628cb5d70c177e8defbf62b0448297ecb13962638b9a26c5d05203cb2937",
"0xe8c5a65edee74d59e7b9e2fb4779485958d95303fff95bfebc0c1f4bf24ef9bf",
"0x67d21b95f40ca7c991f37981393dcec3218e70d5402d82ecbfcb21ae532872bb",
"0xba19c10601ed47bffb755f791325c50af9229d5c25294f315116fdb3640ca35a",
"0xf4c026f65e31d4606541c4e679d30d7336cfeeb81e9893465eb08c310792c061",
"0x5425ff602e06947bda22cfb687ace85c10896b5d48de144149cba26bac9a35ae",
"0xe11f82e350c209213da7d977e2de5199559ad3793a24a226cb4be367c0aa3c4a",
"0x13fb0194f473a4af296184d3293005dffcd28f1cf4b986bdaacede4a0a096fa6",
"0x3dab80c9fc23caf409e38791f07e107da3b5d0d9d4a64f87164e6d455660591b",
"0x5901803b234ef0445acfcd884baf0777970d3b600b80ab137dc1015a5b790885",
"0x3735e2d0ac017cd2c0570830615ed9eb642183fee5b2c2155e5fefc1d4de2561",
"0xea9030afc249a1e4f6c86f4b19660ea63783824e8d1c3de30e38802f1aea9d12",
"0x9def3e76927de026a1a76f39c242263ffbf94b3ef42fb6e98626b67ec3d8a308",
"0x504886149f29d5eb02412202f04b45f23cc97a82206bdf237c433e83c52e386b",
"0xc84d3b9e84727c2d9279dfebcdf8104762e3b101dd9f39c9482a456f87bcf976",
"0xf4737cd864b198c8049ece5a4f18eea18b48a649997c42504b560188adfb6f2b",
"0x410894a208ff99bd3ec5f925aa7ff6932c4404390df9e337601fa7b7251d09ff",
"0xe6e7e7e2b54bcbe37eb7066b9a3c9b01b632d228c8ed5ef8f1871d9b7235a55b",
"0x8af02fe4657f956a9ede1a9b0a83d67367b43a8f5efdf6bd753d09f428b58960",
"0xdd056794fcb6f5b694934b17ef35577dbec8d04159fe447e0eba02e4ff4e9d96",
"0xef94a3289e9e197b04c17886373adbe66a451efe052fb419846006b5f659b91a",
"0x5558e5612dc3c222d76e7190409fc5d38479e08f6fdf4b7df299e6da968c2811",
"0x5f38cc5046a503d424c4b63cb060956babe0c1de050517d0067eccfa23cb664d",
"0x4c6a04827f46e51378e9ff3b811c878dead62da3ae20ef7d392c57512a09a719",
"0x68fd9806bea1d937063778b245a6788cd992e4fc614d5bce1ffe06e125f67701",
"0x0751a79f86c4220e81bbf6b4692976ed4c315f9b62937b23083f4db2370f04eb",
"0x5651840a2065a3468d97bf824e78455eb5e22b82b45fde7bb69b297c4c40e853",
"0x959d277feeb492ed3393fcd5774f1dde27c6018b07cc4fc93b937ee266ae12ea",
"0xa145f2ed353350a89de97e83433188adbd14107c16c654c131203442c34f2899",
"0xf888fc918eab6f88a5f6c6545d47a32dd558f10d00e86a9949cb3f144b7264e2",
"0x2fef7f5f1c149c87602cbe38766631abc992efaee26dd5b59e5bc361f6901cf4",
"0x5e0735a9be3eb97e790a93502a6f138a8863b0f0c20905bee0ac14d5aff4206a",
"0x9c40cbdab8e769c2c6f9de57c23621c5d8a25adaedd1ba9df17fa1680cd4e63f",
"0x995e6a00f5bc63f0a5d837a6671260771f12995b82da19c72a9546ae7b93f38f",
"0x10f647c754615b475543fca5ed9a4491503867fae619513dad966af63cb7ed2b",
"0x7e45b18bd06e946d20bc3807aa926aa5c0a10555b9dc18f9574136969b8f48d5",
"0x8a419fcb515eef5a139a37241872c095818fd276f77e6388c74b82ae49e6386f",
"0x2cb2d82e278d8ba47830ed3dbd6edf69d2e49721182488ffe0a01698071e7d40",
"0x1e9e5cb7a68e7a2decef900bd250bd31c1f024ddd240799327263c72940c7e59",
"0x3904821c4388b16e9851e3a7318f4177102da38525cd3e5e5708430a243470a1",
"0x7785b9d9ff6dfa45d945aaa393270bf8b62bbde46e941aa068606c173963e518",
"0xbff782fbbadfc752f5c2a239e49ab13200fc35cfba29a5332fe936a0367d336c",
"0x294a3fd73f102c7017c9208857dfb91ec7c323916dd1bb3c9f1fac2c7d952b4b",
"0x3a9fe3685814b6cff7a918e514a9d5375a1fc8268a48d5b78da93dfda115332f",
"0xc033a1836983d485e28e5a0825c953a76d4c7f4a8ec5f7eb0b11baf5ae2beb79",
"0xb088df91127cad5d72f8db96d7ea86dfdef55374bf982222a45df7d2b631ceb6"
] ]
}, },
"nodes": [ "nodes": [

View File

@ -481,7 +481,7 @@ impl Importer {
let mut batch = DBTransaction::new(); let mut batch = DBTransaction::new();
let ancestry_actions = self.engine.ancestry_actions(&block, &mut chain.ancestry_with_metadata_iter(*parent)); let ancestry_actions = self.engine.ancestry_actions(&header, &mut chain.ancestry_with_metadata_iter(*parent));
let receipts = block.receipts; let receipts = block.receipts;
let traces = block.traces.drain(); let traces = block.traces.drain();

View File

@ -798,6 +798,7 @@ impl AuthorityRound {
} }
}; };
let epoch_transition_hash = epoch_manager.epoch_transition_hash;
let ancestry_iter = ancestry.map(|header| { let ancestry_iter = ancestry.map(|header| {
let mut signers = vec![*header.author()]; let mut signers = vec![*header.author()];
signers.extend(parent_empty_steps_signers.drain(..)); signers.extend(parent_empty_steps_signers.drain(..));
@ -815,10 +816,11 @@ impl AuthorityRound {
None None
} }
}) })
.while_some(); .while_some()
.take_while(|&(h, _)| h != epoch_transition_hash);
if let Err(_) = epoch_manager.finality_checker.build_ancestry_subchain(ancestry_iter) { if let Err(e) = epoch_manager.finality_checker.build_ancestry_subchain(ancestry_iter) {
debug!(target: "engine", "inconsistent validator set within epoch"); debug!(target: "engine", "inconsistent validator set within epoch: {:?}", e);
return Vec::new(); return Vec::new();
} }
} }
@ -1448,9 +1450,9 @@ impl Engine<EthereumMachine> for AuthorityRound {
super::total_difficulty_fork_choice(new, current) super::total_difficulty_fork_choice(new, current)
} }
fn ancestry_actions(&self, block: &ExecutedBlock, ancestry: &mut Iterator<Item=ExtendedHeader>) -> Vec<AncestryAction> { fn ancestry_actions(&self, header: &Header, ancestry: &mut Iterator<Item=ExtendedHeader>) -> Vec<AncestryAction> {
let finalized = self.build_finality( let finalized = self.build_finality(
block.header(), header,
&mut ancestry.take_while(|e| !e.is_finalized).map(|e| e.header), &mut ancestry.take_while(|e| !e.is_finalized).map(|e| e.header),
); );

View File

@ -429,7 +429,7 @@ pub trait Engine<M: Machine>: Sync + Send {
/// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that /// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that
/// the ancestry exists. /// the ancestry exists.
fn ancestry_actions(&self, _block: &M::LiveBlock, _ancestry: &mut Iterator<Item=M::ExtendedHeader>) -> Vec<AncestryAction> { fn ancestry_actions(&self, _header: &M::Header, _ancestry: &mut Iterator<Item=M::ExtendedHeader>) -> Vec<AncestryAction> {
Vec::new() Vec::new()
} }

View File

@ -371,11 +371,11 @@ impl EthereumMachine {
} }
/// Does verification of the transaction against the parent state. /// Does verification of the transaction against the parent state.
pub fn verify_transaction<C: BlockInfo + CallContract>(&self, t: &SignedTransaction, header: &Header, client: &C) pub fn verify_transaction<C: BlockInfo + CallContract>(&self, t: &SignedTransaction, parent: &Header, client: &C)
-> Result<(), transaction::Error> -> Result<(), transaction::Error>
{ {
if let Some(ref filter) = self.tx_filter.as_ref() { if let Some(ref filter) = self.tx_filter.as_ref() {
if !filter.transaction_allowed(header.parent_hash(), header.number(), t, client) { if !filter.transaction_allowed(&parent.hash(), parent.number() + 1, t, client) {
return Err(transaction::Error::NotAllowed.into()) return Err(transaction::Error::NotAllowed.into())
} }
} }

View File

@ -576,10 +576,9 @@ impl Miner {
trace!(target: "miner", "requires_reseal: sealing enabled"); trace!(target: "miner", "requires_reseal: sealing enabled");
// Disable sealing if there were no requests for SEALING_TIMEOUT_IN_BLOCKS // Disable sealing if there were no requests for SEALING_TIMEOUT_IN_BLOCKS
let had_requests = sealing.last_request.map(|last_request| { let had_requests = sealing.last_request.map(|last_request|
best_block > last_request best_block.saturating_sub(last_request) <= SEALING_TIMEOUT_IN_BLOCKS
&& best_block - last_request <= SEALING_TIMEOUT_IN_BLOCKS ).unwrap_or(false);
}).unwrap_or(false);
// keep sealing enabled if any of the conditions is met // keep sealing enabled if any of the conditions is met
let sealing_enabled = self.forced_sealing() let sealing_enabled = self.forced_sealing()
@ -1394,6 +1393,33 @@ mod tests {
assert_eq!(miner.prepare_pending_block(&client), BlockPreparationStatus::NotPrepared); assert_eq!(miner.prepare_pending_block(&client), BlockPreparationStatus::NotPrepared);
} }
#[test]
fn should_not_return_stale_work_packages() {
// given
let client = TestBlockChainClient::default();
let miner = miner();
// initial work package should create the pending block
let res = miner.work_package(&client);
assert_eq!(res.unwrap().1, 1);
// This should be true, since there were some requests.
assert_eq!(miner.requires_reseal(0), true);
// when new block is imported
let client = generate_dummy_client(2);
let imported = [0.into()];
let empty = &[];
miner.chain_new_blocks(&*client, &imported, empty, &imported, empty, false);
// then
// This should be false, because it's too early.
assert_eq!(miner.requires_reseal(2), false);
// but still work package should be ready
let res = miner.work_package(&*client);
assert_eq!(res.unwrap().1, 3);
assert_eq!(miner.prepare_pending_block(&*client), BlockPreparationStatus::NotPrepared);
}
#[test] #[test]
fn should_not_use_pending_block_if_best_block_is_higher() { fn should_not_use_pending_block_if_best_block_is_higher() {
// given // given

View File

@ -147,7 +147,9 @@ pub fn verify_block_family<C: BlockInfo + CallContract>(header: &Header, parent:
verify_uncles(params.block, params.block_provider, engine)?; verify_uncles(params.block, params.block_provider, engine)?;
for tx in &params.block.transactions { for tx in &params.block.transactions {
engine.machine().verify_transaction(tx, header, params.client)?; // transactions are verified against the parent header since the current
// state wasn't available when the tx was created
engine.machine().verify_transaction(tx, parent, params.client)?;
} }
Ok(()) Ok(())

View File

@ -55,6 +55,22 @@ impl Informant {
Self::with_informant_in_depth(informant.subinfos.last_mut().expect("prepare/done_trace are not balanced"), depth - 1, f); Self::with_informant_in_depth(informant.subinfos.last_mut().expect("prepare/done_trace are not balanced"), depth - 1, f);
} }
} }
fn informant_trace(informant: &Informant, gas_used: U256) -> String {
let info = ::evm::Instruction::from_u8(informant.instruction).map(|i| i.info());
json!({
"pc": informant.pc,
"op": informant.instruction,
"opName": info.map(|i| i.name).unwrap_or(""),
"gas": format!("{:#x}", gas_used.saturating_add(informant.gas_cost)),
"gasCost": format!("{:#x}", informant.gas_cost),
"memory": format!("0x{}", informant.memory.to_hex()),
"stack": informant.stack,
"storage": informant.storage,
"depth": informant.depth,
}).to_string()
}
} }
impl vm::Informant for Informant { impl vm::Informant for Informant {
@ -125,22 +141,11 @@ impl trace::VMTracer for Informant {
fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) { fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) {
let subdepth = self.subdepth; let subdepth = self.subdepth;
Self::with_informant_in_depth(self, subdepth, |informant: &mut Informant| { Self::with_informant_in_depth(self, subdepth, |informant: &mut Informant| {
let mem_diff = informant.mem_written.clone().map(|(o, s)| (o, &(mem[o..o+s])));
let store_diff = informant.store_written.clone(); let store_diff = informant.store_written.clone();
let info = ::evm::Instruction::from_u8(informant.instruction).map(|i| i.info()); let info = ::evm::Instruction::from_u8(informant.instruction).map(|i| i.info());
let trace = json!({ let trace = Self::informant_trace(informant, gas_used);
"pc": informant.pc, informant.traces.push(trace);
"op": informant.instruction,
"opName": info.map(|i| i.name).unwrap_or(""),
"gas": format!("{:#x}", gas_used.saturating_add(informant.gas_cost)),
"gasCost": format!("{:#x}", informant.gas_cost),
"memory": format!("0x{}", informant.memory.to_hex()),
"stack": informant.stack,
"storage": informant.storage,
"depth": informant.depth,
});
informant.traces.push(trace.to_string());
informant.unmatched = false; informant.unmatched = false;
informant.gas_used = gas_used; informant.gas_used = gas_used;
@ -151,11 +156,11 @@ impl trace::VMTracer for Informant {
informant.stack.extend_from_slice(stack_push); informant.stack.extend_from_slice(stack_push);
// TODO [ToDr] Align memory? // TODO [ToDr] Align memory?
if let Some((pos, data)) = mem_diff { if let Some((pos, size)) = informant.mem_written.clone() {
if informant.memory.len() < (pos + data.len()) { if informant.memory.len() < (pos + size) {
informant.memory.resize(pos + data.len(), 0); informant.memory.resize(pos + size, 0);
} }
informant.memory[pos..pos + data.len()].copy_from_slice(data); informant.memory[pos..(pos + size)].copy_from_slice(&mem[pos..(pos + size)]);
} }
if let Some((pos, val)) = store_diff { if let Some((pos, val)) = store_diff {
@ -195,7 +200,12 @@ impl trace::VMTracer for Informant {
// print last line with final state: // print last line with final state:
self.gas_cost = 0.into(); self.gas_cost = 0.into();
let gas_used = self.gas_used; let gas_used = self.gas_used;
self.trace_executed(gas_used, &[], &[]); let subdepth = self.subdepth;
Self::with_informant_in_depth(&mut self, subdepth, |informant: &mut Informant| {
let trace = Self::informant_trace(informant, gas_used);
informant.traces.push(trace);
});
} else if !self.subtraces.is_empty() { } else if !self.subtraces.is_empty() {
self.traces.extend(mem::replace(&mut self.subtraces, vec![])); self.traces.extend(mem::replace(&mut self.subtraces, vec![]));
} }
@ -280,6 +290,17 @@ mod tests {
{"pc":0,"op":248,"opName":"","gas":"0xffff","gasCost":"0x0","memory":"0x","stack":[],"storage":{},"depth":1} {"pc":0,"op":248,"opName":"","gas":"0xffff","gasCost":"0x0","memory":"0x","stack":[],"storage":{},"depth":1}
"#, "#,
); );
run_test(
Informant::default(),
&compare_json,
"5A51",
0xfffff,
r#"
{"depth":1,"gas":"0xfffff","gasCost":"0x2","memory":"0x","op":90,"opName":"GAS","pc":0,"stack":[],"storage":{}}
{"depth":1,"gas":"0xffffd","gasCost":"0x0","memory":"0x","op":81,"opName":"MLOAD","pc":1,"stack":["0xffffd"],"storage":{}}
"#,
);
} }
#[test] #[test]

View File

@ -59,6 +59,7 @@ parity-updater = { path = "../updater" }
parity-version = { path = "../util/version" } parity-version = { path = "../util/version" }
patricia-trie = "0.3.0" patricia-trie = "0.3.0"
rlp = { version = "0.3.0", features = ["ethereum"] } rlp = { version = "0.3.0", features = ["ethereum"] }
eip712 = { path = "../util/EIP-712" }
stats = { path = "../util/stats" } stats = { path = "../util/stats" }
vm = { path = "../ethcore/vm" } vm = { path = "../ethcore/vm" }

View File

@ -63,6 +63,7 @@ extern crate parity_runtime;
extern crate parity_updater as updater; extern crate parity_updater as updater;
extern crate parity_version as version; extern crate parity_version as version;
extern crate patricia_trie as trie; extern crate patricia_trie as trie;
extern crate eip712;
extern crate rlp; extern crate rlp;
extern crate stats; extern crate stats;
extern crate vm; extern crate vm;

View File

@ -28,8 +28,7 @@ use tests::helpers::{GuardedAuthCodes, Server};
/// Setup a mock signer for tests /// Setup a mock signer for tests
pub fn serve() -> (Server<ws::Server>, usize, GuardedAuthCodes) { pub fn serve() -> (Server<ws::Server>, usize, GuardedAuthCodes) {
let port = 35000 + rand::random::<usize>() % 10000; let address = "127.0.0.1:0".parse().unwrap();
let address = format!("127.0.0.1:{}", port).parse().unwrap();
let io = MetaIoHandler::default(); let io = MetaIoHandler::default();
let authcodes = GuardedAuthCodes::new(); let authcodes = GuardedAuthCodes::new();
let stats = Arc::new(informant::RpcStats::default()); let stats = Arc::new(informant::RpcStats::default());
@ -44,6 +43,7 @@ pub fn serve() -> (Server<ws::Server>, usize, GuardedAuthCodes) {
extractors::WsExtractor::new(Some(&authcodes.path)), extractors::WsExtractor::new(Some(&authcodes.path)),
extractors::WsStats::new(stats), extractors::WsStats::new(stats),
).unwrap()); ).unwrap());
let port = res.addr().port() as usize;
(res, port, authcodes) (res, port, authcodes)
} }

View File

@ -49,7 +49,8 @@ use v1::types::{
RichRawTransaction as RpcRichRawTransaction, RichRawTransaction as RpcRichRawTransaction,
ConfirmationPayload as RpcConfirmationPayload, ConfirmationPayload as RpcConfirmationPayload,
ConfirmationResponse, ConfirmationResponse,
SignRequest as RpcSignRequest, EthSignRequest as RpcEthSignRequest,
EIP191SignRequest as RpcSignRequest,
DecryptRequest as RpcDecryptRequest, DecryptRequest as RpcDecryptRequest,
}; };
use rlp; use rlp;
@ -693,6 +694,19 @@ pub fn execute<D: Dispatcher + 'static>(
); );
Box::new(future::done(res)) Box::new(future::done(res))
}, },
ConfirmationPayload::SignMessage(address, data) => {
if accounts.is_hardware_address(&address) {
return Box::new(future::err(errors::account("Error signing message with hardware_wallet",
"Message signing is unsupported")));
}
let res = signature(&accounts, address, data, pass)
.map(|result| result
.map(|rsv| H520(rsv.into_electrum()))
.map(RpcH520::from)
.map(ConfirmationResponse::Signature)
);
Box::new(future::done(res))
},
ConfirmationPayload::Decrypt(address, data) => { ConfirmationPayload::Decrypt(address, data) => {
if accounts.is_hardware_address(&address) { if accounts.is_hardware_address(&address) {
return Box::new(future::err(errors::unsupported("Decrypting via hardware wallets is not supported.", None))); return Box::new(future::err(errors::unsupported("Decrypting via hardware wallets is not supported.", None)));
@ -775,8 +789,11 @@ pub fn from_rpc<D>(payload: RpcConfirmationPayload, default_account: Address, di
RpcConfirmationPayload::Decrypt(RpcDecryptRequest { address, msg }) => { RpcConfirmationPayload::Decrypt(RpcDecryptRequest { address, msg }) => {
Box::new(future::ok(ConfirmationPayload::Decrypt(address.into(), msg.into()))) Box::new(future::ok(ConfirmationPayload::Decrypt(address.into(), msg.into())))
}, },
RpcConfirmationPayload::EthSignMessage(RpcSignRequest { address, data }) => { RpcConfirmationPayload::EthSignMessage(RpcEthSignRequest { address, data }) => {
Box::new(future::ok(ConfirmationPayload::EthSignMessage(address.into(), data.into()))) Box::new(future::ok(ConfirmationPayload::EthSignMessage(address.into(), data.into())))
}, },
RpcConfirmationPayload::EIP191SignMessage(RpcSignRequest { address, data }) => {
Box::new(future::ok(ConfirmationPayload::SignMessage(address.into(), data.into())))
},
} }
} }

View File

@ -0,0 +1,61 @@
// 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/>.
//! EIP-191 compliant decoding + hashing
use v1::types::{EIP191Version, Bytes, PresignedTransaction};
use eip712::{hash_structured_data, EIP712};
use serde_json::{Value, from_value};
use v1::helpers::errors;
use jsonrpc_core::Error;
use v1::helpers::dispatch::eth_data_hash;
use hash::keccak;
use std::fmt::Display;
use ethereum_types::H256;
/// deserializes and hashes the message depending on the version specifier
pub fn hash_message(version: EIP191Version, message: Value) -> Result<H256, Error> {
let data = match version {
EIP191Version::StructuredData => {
let typed_data = from_value::<EIP712>(message)
.map_err(map_serde_err("StructuredData"))?;
hash_structured_data(typed_data)
.map_err(|err| errors::invalid_call_data(err.kind()))?
}
EIP191Version::PresignedTransaction => {
let data = from_value::<PresignedTransaction>(message)
.map_err(map_serde_err("WithValidator"))?;
let prefix = b"\x19\x00";
let data = [&prefix[..], &data.validator.0[..], &data.data.0[..]].concat();
keccak(data)
}
EIP191Version::PersonalMessage => {
let bytes = from_value::<Bytes>(message)
.map_err(map_serde_err("Bytes"))?;
eth_data_hash(bytes.0)
}
};
Ok(data)
}
fn map_serde_err<T: Display>(struct_name: &'static str) -> impl Fn(T) -> Error {
move |error: T| {
errors::invalid_call_data(format!("Error deserializing '{}': {}", struct_name, error))
}
}

View File

@ -286,6 +286,14 @@ pub fn signing(error: AccountError) -> Error {
} }
} }
pub fn invalid_call_data<T: fmt::Display>(error: T) -> Error {
Error {
code: ErrorCode::ServerError(codes::ENCODING_ERROR),
message: format!("{}", error),
data: None
}
}
pub fn password(error: AccountError) -> Error { pub fn password(error: AccountError) -> Error {
Error { Error {
code: ErrorCode::ServerError(codes::PASSWORD_INVALID), code: ErrorCode::ServerError(codes::PASSWORD_INVALID),

View File

@ -19,12 +19,12 @@
use std::cmp; use std::cmp;
use std::sync::Arc; use std::sync::Arc;
use light::on_demand::error::Error as OnDemandError;
use ethcore::basic_account::BasicAccount; use ethcore::basic_account::BasicAccount;
use ethcore::encoded; use ethcore::encoded;
use ethcore::filter::Filter as EthcoreFilter; use ethcore::filter::Filter as EthcoreFilter;
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use ethcore::executed::ExecutionError;
use jsonrpc_core::{Result, Error}; use jsonrpc_core::{Result, Error};
use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::{future, Future};
@ -38,6 +38,7 @@ use light::on_demand::{
request, OnDemand, HeaderRef, Request as OnDemandRequest, request, OnDemand, HeaderRef, Request as OnDemandRequest,
Response as OnDemandResponse, ExecutionResult, Response as OnDemandResponse, ExecutionResult,
}; };
use light::on_demand::error::Error as OnDemandError;
use light::request::Field; use light::request::Field;
use sync::LightSync; use sync::LightSync;
@ -202,8 +203,8 @@ impl LightFetch {
/// Helper for getting proved execution. /// Helper for getting proved execution.
pub fn proved_read_only_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send { pub fn proved_read_only_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
const DEFAULT_GAS_PRICE: u64 = 21_000; const DEFAULT_GAS_PRICE: u64 = 21_000;
// starting gas when gas not provided. // (21000 G_transaction + 32000 G_create + some marginal to allow a few operations)
const START_GAS: u64 = 50_000; const START_GAS: u64 = 60_000;
let (sync, on_demand, client) = (self.sync.clone(), self.on_demand.clone(), self.client.clone()); let (sync, on_demand, client) = (self.sync.clone(), self.on_demand.clone(), self.client.clone());
let req: CallRequestHelper = req.into(); let req: CallRequestHelper = req.into();
@ -615,28 +616,41 @@ struct ExecuteParams {
sync: Arc<LightSync>, sync: Arc<LightSync>,
} }
// has a peer execute the transaction with given params. If `gas_known` is false, // Has a peer execute the transaction with given params. If `gas_known` is false, this will set the `gas value` to the
// this will double the gas on each `OutOfGas` error. // `required gas value` unless it exceeds the block gas limit
fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = ExecutionResult, Error = Error> + Send { fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
if !gas_known { if !gas_known {
Box::new(future::loop_fn(params, |mut params| { Box::new(future::loop_fn(params, |mut params| {
execute_read_only_tx(true, params.clone()).and_then(move |res| { execute_read_only_tx(true, params.clone()).and_then(move |res| {
match res { match res {
Ok(executed) => { Ok(executed) => {
// TODO: how to distinguish between actual OOG and // `OutOfGas` exception, try double the gas
// exception? if let Some(vm::Error::OutOfGas) = executed.exception {
if executed.exception.is_some() { // block gas limit already tried, regard as an error and don't retry
let old_gas = params.tx.gas; if params.tx.gas >= params.hdr.gas_limit() {
params.tx.gas = params.tx.gas * 2u32; trace!(target: "light_fetch", "OutOutGas exception received, gas increase: failed");
if params.tx.gas > params.hdr.gas_limit() {
params.tx.gas = old_gas;
} else { } else {
params.tx.gas = cmp::min(params.tx.gas * 2_u32, params.hdr.gas_limit());
trace!(target: "light_fetch", "OutOutGas exception received, gas increased to {}",
params.tx.gas);
return Ok(future::Loop::Continue(params)) return Ok(future::Loop::Continue(params))
} }
} }
Ok(future::Loop::Break(Ok(executed))) Ok(future::Loop::Break(Ok(executed)))
} }
Err(ExecutionError::NotEnoughBaseGas { required, got }) => {
trace!(target: "light_fetch", "Not enough start gas provided required: {}, got: {}",
required, got);
if required <= params.hdr.gas_limit() {
params.tx.gas = required;
return Ok(future::Loop::Continue(params))
} else {
warn!(target: "light_fetch",
"Required gas is bigger than block header's gas dropping the request");
Ok(future::Loop::Break(Err(ExecutionError::NotEnoughBaseGas { required, got })))
}
}
// Non-recoverable execution error
failed => Ok(future::Loop::Break(failed)), failed => Ok(future::Loop::Break(failed)),
} }
}) })

View File

@ -25,6 +25,7 @@ pub mod light_fetch;
pub mod nonce; pub mod nonce;
pub mod oneshot; pub mod oneshot;
pub mod secretstore; pub mod secretstore;
pub mod eip191;
mod network_settings; mod network_settings;
mod poll_filter; mod poll_filter;

View File

@ -18,6 +18,7 @@ use ethereum_types::{U256, Address};
use bytes::Bytes; use bytes::Bytes;
use v1::types::{Origin, TransactionCondition}; use v1::types::{Origin, TransactionCondition};
use ethereum_types::H256;
/// Transaction request coming from RPC /// Transaction request coming from RPC
#[derive(Debug, Clone, Default, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Default, Eq, PartialEq, Hash)]
@ -117,6 +118,8 @@ pub enum ConfirmationPayload {
SignTransaction(FilledTransactionRequest), SignTransaction(FilledTransactionRequest),
/// Sign a message with an Ethereum specific security prefix. /// Sign a message with an Ethereum specific security prefix.
EthSignMessage(Address, Bytes), EthSignMessage(Address, Bytes),
/// Sign a message
SignMessage(Address, H256),
/// Decrypt request /// Decrypt request
Decrypt(Address, Bytes), Decrypt(Address, Bytes),
} }
@ -127,6 +130,7 @@ impl ConfirmationPayload {
ConfirmationPayload::SendTransaction(ref request) => request.from, ConfirmationPayload::SendTransaction(ref request) => request.from,
ConfirmationPayload::SignTransaction(ref request) => request.from, ConfirmationPayload::SignTransaction(ref request) => request.from,
ConfirmationPayload::EthSignMessage(ref address, _) => *address, ConfirmationPayload::EthSignMessage(ref address, _) => *address,
ConfirmationPayload::SignMessage(ref address, _) => *address,
ConfirmationPayload::Decrypt(ref address, _) => *address, ConfirmationPayload::Decrypt(ref address, _) => *address,
} }
} }

View File

@ -26,7 +26,7 @@ use ethkey::{public_to_address, recover, Signature};
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::{future, Future}; use jsonrpc_core::futures::{future, Future};
use v1::helpers::errors; use v1::helpers::{errors, eip191};
use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith}; use v1::helpers::dispatch::{self, eth_data_hash, Dispatcher, SignWith};
use v1::traits::Personal; use v1::traits::Personal;
use v1::types::{ use v1::types::{
@ -36,8 +36,11 @@ use v1::types::{
ConfirmationResponse as RpcConfirmationResponse, ConfirmationResponse as RpcConfirmationResponse,
TransactionRequest, TransactionRequest,
RichRawTransaction as RpcRichRawTransaction, RichRawTransaction as RpcRichRawTransaction,
EIP191Version,
}; };
use v1::metadata::Metadata; use v1::metadata::Metadata;
use eip712::{EIP712, hash_structured_data};
use jsonrpc_core::types::Value;
/// Account management (personal) rpc implementation. /// Account management (personal) rpc implementation.
pub struct PersonalClient<D: Dispatcher> { pub struct PersonalClient<D: Dispatcher> {
@ -150,6 +153,49 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
})) }))
} }
fn sign_191(&self, version: EIP191Version, data: Value, account: RpcH160, password: String) -> BoxFuture<RpcH520> {
let data = try_bf!(eip191::hash_message(version, data));
let dispatcher = self.dispatcher.clone();
let accounts = self.accounts.clone();
let payload = RpcConfirmationPayload::EIP191SignMessage((account.clone(), data.into()).into());
Box::new(dispatch::from_rpc(payload, account.into(), &dispatcher)
.and_then(|payload| {
dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Password(password.into()))
})
.map(|v| v.into_value())
.then(|res| match res {
Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature),
Err(e) => Err(e),
e => Err(errors::internal("Unexpected result", e)),
})
)
}
fn sign_typed_data(&self, typed_data: EIP712, account: RpcH160, password: String) -> BoxFuture<RpcH520> {
let data = match hash_structured_data(typed_data) {
Ok(d) => d,
Err(err) => return Box::new(future::err(errors::invalid_call_data(err.kind()))),
};
let dispatcher = self.dispatcher.clone();
let accounts = self.accounts.clone();
let payload = RpcConfirmationPayload::EIP191SignMessage((account.clone(), data.into()).into());
Box::new(dispatch::from_rpc(payload, account.into(), &dispatcher)
.and_then(|payload| {
dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Password(password.into()))
})
.map(|v| v.into_value())
.then(|res| match res {
Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature),
Err(e) => Err(e),
e => Err(errors::internal("Unexpected result", e)),
})
)
}
fn ec_recover(&self, data: RpcBytes, signature: RpcH520) -> BoxFuture<RpcH160> { fn ec_recover(&self, data: RpcBytes, signature: RpcH520) -> BoxFuture<RpcH160> {
let signature: H520 = signature.into(); let signature: H520 = signature.into();
let signature = Signature::from_electrum(&signature); let signature = Signature::from_electrum(&signature);

View File

@ -21,7 +21,7 @@ use std::time::Duration;
use parking_lot::RwLock; use parking_lot::RwLock;
use jsonrpc_core::{self as core, Result, MetaIoHandler}; use jsonrpc_core::{self as core, Result, MetaIoHandler};
use jsonrpc_core::futures::{Future, Stream, Sink}; use jsonrpc_core::futures::{future, Future, Stream, Sink};
use jsonrpc_macros::Trailing; use jsonrpc_macros::Trailing;
use jsonrpc_macros::pubsub::Subscriber; use jsonrpc_macros::pubsub::Subscriber;
use jsonrpc_pubsub::SubscriptionId; use jsonrpc_pubsub::SubscriptionId;
@ -42,7 +42,7 @@ impl<S: core::Middleware<Metadata>> PubSubClient<S> {
/// Creates new `PubSubClient`. /// Creates new `PubSubClient`.
pub fn new(rpc: MetaIoHandler<Metadata, S>, executor: Executor) -> Self { pub fn new(rpc: MetaIoHandler<Metadata, S>, executor: Executor) -> Self {
let poll_manager = Arc::new(RwLock::new(GenericPollManager::new(rpc))); let poll_manager = Arc::new(RwLock::new(GenericPollManager::new(rpc)));
let pm2 = poll_manager.clone(); let pm2 = Arc::downgrade(&poll_manager);
let timer = tokio_timer::wheel() let timer = tokio_timer::wheel()
.tick_duration(Duration::from_millis(500)) .tick_duration(Duration::from_millis(500))
@ -52,7 +52,13 @@ impl<S: core::Middleware<Metadata>> PubSubClient<S> {
let interval = timer.interval(Duration::from_millis(1000)); let interval = timer.interval(Duration::from_millis(1000));
executor.spawn(interval executor.spawn(interval
.map_err(|e| warn!("Polling timer error: {:?}", e)) .map_err(|e| warn!("Polling timer error: {:?}", e))
.for_each(move |_| pm2.read().tick()) .for_each(move |_| {
if let Some(pm2) = pm2.upgrade() {
pm2.read().tick()
} else {
Box::new(future::err(()))
}
})
); );
PubSubClient { PubSubClient {

View File

@ -215,6 +215,14 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
Err(err) => Err(errors::invalid_params("Invalid signature received.", err)), Err(err) => Err(errors::invalid_params("Invalid signature received.", err)),
} }
}, },
ConfirmationPayload::SignMessage(address, hash) => {
let signature = ethkey::Signature::from_electrum(&bytes.0);
match ethkey::verify_address(&address, &signature, &hash) {
Ok(true) => Ok(ConfirmationResponse::Signature(bytes.0.as_slice().into())),
Ok(false) => Err(errors::invalid_params("Sender address does not match the signature.", ())),
Err(err) => Err(errors::invalid_params("Invalid signature received.", err)),
}
},
ConfirmationPayload::Decrypt(_address, _data) => { ConfirmationPayload::Decrypt(_address, _data) => {
// TODO [ToDr]: Decrypt can we verify if the answer is correct? // TODO [ToDr]: Decrypt can we verify if the answer is correct?
Ok(ConfirmationResponse::Decrypt(bytes)) Ok(ConfirmationResponse::Decrypt(bytes))

View File

@ -25,12 +25,16 @@ use jsonrpc_core::IoHandler;
use parking_lot::Mutex; use parking_lot::Mutex;
use transaction::{Action, Transaction}; use transaction::{Action, Transaction};
use parity_runtime::Runtime; use parity_runtime::Runtime;
use hash::keccak;
use v1::{PersonalClient, Personal, Metadata}; use v1::{PersonalClient, Personal, Metadata};
use v1::helpers::nonce; use v1::helpers::{nonce, eip191};
use v1::helpers::dispatch::{eth_data_hash, FullDispatcher}; use v1::helpers::dispatch::{eth_data_hash, FullDispatcher};
use v1::tests::helpers::TestMinerService; use v1::tests::helpers::TestMinerService;
use v1::types::H520; use v1::types::{EIP191Version, PresignedTransaction, H520};
use rustc_hex::ToHex;
use serde_json::to_value;
use ethkey::Secret;
struct PersonalTester { struct PersonalTester {
_runtime: Runtime, _runtime: Runtime,
@ -328,3 +332,89 @@ fn should_unlock_account_permanently() {
assert_eq!(tester.io.handle_request_sync(&request), Some(response.into())); assert_eq!(tester.io.handle_request_sync(&request), Some(response.into()));
assert!(tester.accounts.sign(address, None, Default::default()).is_ok(), "Should unlock account."); assert!(tester.accounts.sign(address, None, Default::default()).is_ok(), "Should unlock account.");
} }
#[test]
fn sign_eip191_with_validator() {
let tester = setup();
let address = tester.accounts.new_account(&"password123".into()).unwrap();
let request = r#"{
"jsonrpc": "2.0",
"method": "personal_sign191",
"params": [
"0x00",
{
"validator": ""#.to_owned() + &format!("0x{:x}", address) + r#"",
"data": ""# + &format!("0x{:x}", keccak("hello world")) + r#""
},
""# + &format!("0x{:x}", address) + r#"",
"password123"
],
"id": 1
}"#;
let with_validator = to_value(PresignedTransaction {
validator: address.into(),
data: keccak("hello world").to_vec().into()
}).unwrap();
let result = eip191::hash_message(EIP191Version::PresignedTransaction, with_validator).unwrap();
let result = tester.accounts.sign(address, Some("password123".into()), result).unwrap().into_electrum();
let expected = r#"{"jsonrpc":"2.0","result":""#.to_owned() + &format!("0x{}", result.to_hex()) + r#"","id":1}"#;
let response = tester.io.handle_request_sync(&request).unwrap();
assert_eq!(response, expected)
}
#[test]
fn sign_eip191_structured_data() {
let tester = setup();
let secret: Secret = keccak("cow").into();
let address = tester.accounts.insert_account(secret, &"lol".into()).unwrap();
let request = r#"{
"jsonrpc": "2.0",
"method": "personal_sign191",
"params": [
"0x01",
{
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": "0x1",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"contents": "Hello, Bob!"
},
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "string" }
]
}
},
""#.to_owned() + &format!("0x{:x}", address) + r#"",
"lol"
],
"id": 1
}"#;
let expected = r#"{"jsonrpc":"2.0","result":"0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c","id":1}"#;
let response = tester.io.handle_request_sync(&request).unwrap();
assert_eq!(response, expected)
}

View File

@ -15,9 +15,10 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Personal rpc interface. //! Personal rpc interface.
use eip712::EIP712;
use jsonrpc_core::types::Value;
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use v1::types::{Bytes, U128, H160, H256, H520, TransactionRequest, RichRawTransaction as RpcRichRawTransaction, EIP191Version};
use v1::types::{Bytes, U128, H160, H256, H520, TransactionRequest, RichRawTransaction as RpcRichRawTransaction};
build_rpc_trait! { build_rpc_trait! {
/// Personal rpc interface. Safe (read-only) functions. /// Personal rpc interface. Safe (read-only) functions.
@ -42,6 +43,15 @@ build_rpc_trait! {
#[rpc(name = "personal_sign")] #[rpc(name = "personal_sign")]
fn sign(&self, Bytes, H160, String) -> BoxFuture<H520>; fn sign(&self, Bytes, H160, String) -> BoxFuture<H520>;
/// Produces an EIP-712 compliant signature with given account using the given password to unlock the
/// account during the request.
#[rpc(name = "personal_signTypedData")]
fn sign_typed_data(&self, EIP712, H160, String) -> BoxFuture<H520>;
/// Signs an arbitrary message based on the version specified
#[rpc(name = "personal_sign191")]
fn sign_191(&self, EIP191Version, Value, H160, String) -> BoxFuture<H520>;
/// Returns the account associated with the private key that was used to calculate the signature in /// Returns the account associated with the private key that was used to calculate the signature in
/// `personal_sign`. /// `personal_sign`.
#[rpc(name = "personal_ecRecover")] #[rpc(name = "personal_ecRecover")]

View File

@ -59,31 +59,62 @@ impl fmt::Display for ConfirmationPayload {
ConfirmationPayload::SendTransaction(ref transaction) => write!(f, "{}", transaction), ConfirmationPayload::SendTransaction(ref transaction) => write!(f, "{}", transaction),
ConfirmationPayload::SignTransaction(ref transaction) => write!(f, "(Sign only) {}", transaction), ConfirmationPayload::SignTransaction(ref transaction) => write!(f, "(Sign only) {}", transaction),
ConfirmationPayload::EthSignMessage(ref sign) => write!(f, "{}", sign), ConfirmationPayload::EthSignMessage(ref sign) => write!(f, "{}", sign),
ConfirmationPayload::EIP191SignMessage(ref sign) => write!(f, "{}", sign),
ConfirmationPayload::Decrypt(ref decrypt) => write!(f, "{}", decrypt), ConfirmationPayload::Decrypt(ref decrypt) => write!(f, "{}", decrypt),
} }
} }
} }
/// Sign request /// Ethereum-prefixed Sign request
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct SignRequest { pub struct EthSignRequest {
/// Address /// Address
pub address: H160, pub address: H160,
/// Hash to sign /// Hash to sign
pub data: Bytes, pub data: Bytes,
} }
impl From<(H160, Bytes)> for SignRequest { /// EIP191 Sign request
fn from(tuple: (H160, Bytes)) -> Self { #[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
SignRequest { #[serde(deny_unknown_fields)]
pub struct EIP191SignRequest {
/// Address
pub address: H160,
/// Hash to sign
pub data: H256,
}
impl From<(H160, H256)> for EIP191SignRequest {
fn from(tuple: (H160, H256)) -> Self {
EIP191SignRequest {
address: tuple.0, address: tuple.0,
data: tuple.1, data: tuple.1,
} }
} }
} }
impl fmt::Display for SignRequest { impl fmt::Display for EIP191SignRequest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"sign 0x{} with {}",
self.data.0.pretty(),
Colour::White.bold().paint(format!("0x{:?}", self.address)),
)
}
}
impl From<(H160, Bytes)> for EthSignRequest {
fn from(tuple: (H160, Bytes)) -> Self {
EthSignRequest {
address: tuple.0,
data: tuple.1,
}
}
}
impl fmt::Display for EthSignRequest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,
@ -169,8 +200,10 @@ pub enum ConfirmationPayload {
#[serde(rename="signTransaction")] #[serde(rename="signTransaction")]
SignTransaction(TransactionRequest), SignTransaction(TransactionRequest),
/// Signature /// Signature
#[serde(rename="sign")] #[serde(rename = "sign")]
EthSignMessage(SignRequest), EthSignMessage(EthSignRequest),
/// signature without prefix
EIP191SignMessage(EIP191SignRequest),
/// Decryption /// Decryption
#[serde(rename="decrypt")] #[serde(rename="decrypt")]
Decrypt(DecryptRequest), Decrypt(DecryptRequest),
@ -181,7 +214,11 @@ impl From<helpers::ConfirmationPayload> for ConfirmationPayload {
match c { match c {
helpers::ConfirmationPayload::SendTransaction(t) => ConfirmationPayload::SendTransaction(t.into()), helpers::ConfirmationPayload::SendTransaction(t) => ConfirmationPayload::SendTransaction(t.into()),
helpers::ConfirmationPayload::SignTransaction(t) => ConfirmationPayload::SignTransaction(t.into()), helpers::ConfirmationPayload::SignTransaction(t) => ConfirmationPayload::SignTransaction(t.into()),
helpers::ConfirmationPayload::EthSignMessage(address, data) => ConfirmationPayload::EthSignMessage(SignRequest { helpers::ConfirmationPayload::EthSignMessage(address, data) => ConfirmationPayload::EthSignMessage(EthSignRequest {
address: address.into(),
data: data.into(),
}),
helpers::ConfirmationPayload::SignMessage(address, data) => ConfirmationPayload::EIP191SignMessage(EIP191SignRequest {
address: address.into(), address: address.into(),
data: data.into(), data: data.into(),
}), }),

View File

@ -0,0 +1,57 @@
// 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/>.
//! EIP-191 specific types
use serde::{Deserialize, Deserializer};
use serde::de;
use v1::types::{H160, Bytes};
/// EIP-191 version specifier
#[derive(Debug)]
pub enum EIP191Version {
/// byte specifier for structured data (0x01)
StructuredData,
/// byte specifier for personal message (0x45)
PersonalMessage,
/// byte specifier for presignedtransaction (0x00)
PresignedTransaction
}
/// EIP-191 version 0x0 struct
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PresignedTransaction {
// address of intended validator
pub validator: H160,
// application specific data
pub data: Bytes
}
impl<'de> Deserialize<'de> for EIP191Version {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
let byte_version = match s.as_str() {
"0x00" => EIP191Version::PresignedTransaction,
"0x01" => EIP191Version::StructuredData,
"0x45" => EIP191Version::PersonalMessage,
other => return Err(de::Error::custom(format!("Invalid byte version '{}'", other))),
};
Ok(byte_version)
}
}

View File

@ -43,9 +43,10 @@ mod transaction_condition;
mod uint; mod uint;
mod work; mod work;
mod private_receipt; mod private_receipt;
mod eip191;
pub mod pubsub; pub mod pubsub;
pub use self::eip191::{EIP191Version, PresignedTransaction};
pub use self::account_info::{AccountInfo, ExtAccountInfo, HwAccountInfo}; pub use self::account_info::{AccountInfo, ExtAccountInfo, HwAccountInfo};
pub use self::bytes::Bytes; pub use self::bytes::Bytes;
pub use self::block::{RichBlock, Block, BlockTransactions, Header, RichHeader, Rich}; pub use self::block::{RichBlock, Block, BlockTransactions, Header, RichHeader, Rich};
@ -53,7 +54,7 @@ pub use self::block_number::{BlockNumber, LightBlockNumber, block_number_to_id};
pub use self::call_request::CallRequest; pub use self::call_request::CallRequest;
pub use self::confirmations::{ pub use self::confirmations::{
ConfirmationPayload, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, ConfirmationPayload, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken,
TransactionModification, SignRequest, DecryptRequest, Either TransactionModification, EIP191SignRequest, EthSignRequest, DecryptRequest, Either
}; };
pub use self::consensus_status::*; pub use self::consensus_status::*;
pub use self::derivation::{DeriveHash, DeriveHierarchical, Derive}; pub use self::derivation::{DeriveHash, DeriveHierarchical, Derive};

View File

@ -1 +0,0 @@
stable

View File

@ -31,7 +31,7 @@ COPY artifacts/x86_64-unknown-linux-gnu/$TARGET ./bin/$TARGET
RUN echo "#!/bin/bash \n ${TARGET} \$@" > ./entrypoint.sh RUN echo "#!/bin/bash \n ${TARGET} \$@" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh RUN chmod +x ./entrypoint.sh
ADD check_sync.sh /check_sync.sh COPY scripts/docker/hub/check_sync.sh /check_sync.sh
# setup ENTRYPOINT # setup ENTRYPOINT
EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp EXPOSE 5001 8080 8082 8083 8545 8546 8180 30303/tcp 30303/udp

View File

@ -6,18 +6,23 @@ set -u # treat unset variables as error
echo "__________Show ENVIROMENT__________" echo "__________Show ENVIROMENT__________"
echo "CI_SERVER_NAME: " $CI_SERVER_NAME echo "CI_SERVER_NAME: " $CI_SERVER_NAME
echo "CARGO_HOME: " $CARGO_HOME echo "CARGO_HOME: " $CARGO_HOME
echo "BUILD_TARGET: " $BUILD_TARGET
echo "BUILD_ARCH: " $BUILD_ARCH
echo "CARGO_TARGET: " $CARGO_TARGET echo "CARGO_TARGET: " $CARGO_TARGET
echo "CC: " $CC echo "CC: " $CC
echo "CXX: " $CXX echo "CXX: " $CXX
echo "__________CARGO CONFIG__________" echo "__________CARGO CONFIG__________"
mkdir -p .cargo if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
rm -f .cargo/config then
echo "[target.$CARGO_TARGET]" >> .cargo/config # use build container's cargo config
echo "linker= \"$CC\"" >> .cargo/config cat /.cargo/config
cat .cargo/config else
mkdir -p .cargo
rm -f .cargo/config
echo "[target.$CARGO_TARGET]" >> .cargo/config
echo "linker= \"$CC\"" >> .cargo/config
cat .cargo/config
fi
echo "_____ Building target: "$CARGO_TARGET" _____" echo "_____ Building target: "$CARGO_TARGET" _____"
time cargo build --target $CARGO_TARGET --release --features final time cargo build --target $CARGO_TARGET --release --features final
@ -32,15 +37,31 @@ mkdir -p artifacts
cd artifacts cd artifacts
mkdir -p $CARGO_TARGET mkdir -p $CARGO_TARGET
cd $CARGO_TARGET cd $CARGO_TARGET
cp ../../target/$CARGO_TARGET/release/parity ./parity cp -v ../../target/$CARGO_TARGET/release/parity ./parity
cp ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm
cp ../../target/$CARGO_TARGET/release/ethstore ./ethstore cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore
cp ../../target/$CARGO_TARGET/release/ethkey ./ethkey cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey
cp ../../target/$CARGO_TARGET/release/whisper ./whisper cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
strip -v ./*
# stripping can also be done on release build time
# export RUSTFLAGS="${RUSTFLAGS} -C link-arg=-s"
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
then
arm-linux-androideabi-strip -v ./*
else
strip -v ./*
fi
echo "_____ Calculating checksums _____" echo "_____ Calculating checksums _____"
for binary in $(ls) for binary in $(ls)
do do
rhash --sha256 $binary -o $binary.sha256 rhash --sha256 $binary -o $binary.sha256
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
then
echo "> ${binary} cannot be hashed with cross-compiled binary"
else
./parity tools hash $binary > $binary.sha3 ./parity tools hash $binary > $binary.sha3
fi
done done

View File

@ -8,8 +8,6 @@ set LIB="C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.
echo "__________Show ENVIROMENT__________" echo "__________Show ENVIROMENT__________"
echo "CI_SERVER_NAME: " $CI_SERVER_NAME echo "CI_SERVER_NAME: " $CI_SERVER_NAME
echo "CARGO_HOME: " $CARGO_HOME echo "CARGO_HOME: " $CARGO_HOME
echo "BUILD_TARGET: " $BUILD_TARGET
echo "BUILD_ARCH: " $BUILD_ARCH
echo "CARGO_TARGET: " $CARGO_TARGET echo "CARGO_TARGET: " $CARGO_TARGET
echo "_____ Building target: "$CARGO_TARGET" _____" echo "_____ Building target: "$CARGO_TARGET" _____"

View File

@ -3,5 +3,5 @@
set -e # fail on any error set -e # fail on any error
set -u # treat unset variables as error set -u # treat unset variables as error
CARGO_TARGET_DIR=./target cargo +stable install cargo-audit --force cargo install cargo-audit
cargo +stable audit cargo audit

23
util/EIP-712/Cargo.toml Normal file
View File

@ -0,0 +1,23 @@
[package]
name = "eip712"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
serde_derive = "1.0"
serde = "1.0"
serde_json = "1.0"
ethabi = "6.0"
keccak-hash = "0.1"
ethereum-types = "0.4"
failure = "0.1"
itertools = "0.7"
failure_derive = "0.1"
lazy_static = "1.1"
toolshed = "0.4"
regex = "1.0"
validator = "0.8"
validator_derive = "0.8"
lunarity-lexer = "0.1"
rustc-hex = "2.0"
indexmap = "1.0.2"

177
util/EIP-712/src/eip712.rs Normal file
View File

@ -0,0 +1,177 @@
// 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/>.
//! EIP712 structs
use serde_json::{Value};
use std::collections::HashMap;
use ethereum_types::{U256, H256, Address};
use regex::Regex;
use validator::Validate;
use validator::ValidationErrors;
pub(crate) type MessageTypes = HashMap<String, Vec<FieldType>>;
lazy_static! {
// match solidity identifier with the addition of '[(\d)*]*'
static ref TYPE_REGEX: Regex = Regex::new(r"^[a-zA-Z_$][a-zA-Z_$0-9]*(\[([1-9]\d*)*\])*$").unwrap();
static ref IDENT_REGEX: Regex = Regex::new(r"^[a-zA-Z_$][a-zA-Z_$0-9]*$").unwrap();
}
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
#[derive(Deserialize, Serialize, Validate, Debug, Clone)]
pub(crate) struct EIP712Domain {
pub(crate) name: String,
pub(crate) version: String,
pub(crate) chain_id: U256,
pub(crate) verifying_contract: Address,
#[serde(skip_serializing_if="Option::is_none")]
pub(crate) salt: Option<H256>,
}
/// EIP-712 struct
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
#[derive(Deserialize, Debug, Clone)]
pub struct EIP712 {
pub(crate) types: MessageTypes,
pub(crate) primary_type: String,
pub(crate) message: Value,
pub(crate) domain: EIP712Domain,
}
impl Validate for EIP712 {
fn validate(&self) -> Result<(), ValidationErrors> {
for field_types in self.types.values() {
for field_type in field_types {
field_type.validate()?;
}
}
Ok(())
}
}
#[derive(Serialize, Deserialize, Validate, Debug, Clone)]
pub(crate) struct FieldType {
#[validate(regex = "IDENT_REGEX")]
pub name: String,
#[serde(rename = "type")]
#[validate(regex = "TYPE_REGEX")]
pub type_: String,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::from_str;
#[test]
fn test_regex() {
let test_cases = vec!["unint bytes32", "Seun\\[]", "byte[]uint", "byte[7[]uint][]", "Person[0]"];
for case in test_cases {
assert_eq!(TYPE_REGEX.is_match(case), false)
}
let test_cases = vec!["bytes32", "Foo[]", "bytes1", "bytes32[][]", "byte[9]", "contents"];
for case in test_cases {
assert_eq!(TYPE_REGEX.is_match(case), true)
}
}
#[test]
fn test_deserialization() {
let string = r#"{
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": "0x1",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"contents": "Hello, Bob!"
},
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "string" }
]
}
}"#;
let _ = from_str::<EIP712>(string).unwrap();
}
#[test]
fn test_failing_deserialization() {
let string = r#"{
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": "0x1",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"contents": "Hello, Bob!"
},
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "7uint256[x] Seun" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet amen", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "string" }
]
}
}"#;
let data = from_str::<EIP712>(string).unwrap();
assert_eq!(data.validate().is_err(), true);
}
}

415
util/EIP-712/src/encode.rs Normal file
View File

@ -0,0 +1,415 @@
// 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/>.
//! EIP712 Encoder
use ethabi::{encode, Token as EthAbiToken};
use ethereum_types::{Address as EthAddress, U256, H256};
use keccak_hash::keccak;
use serde_json::Value;
use std::str::FromStr;
use itertools::Itertools;
use indexmap::IndexSet;
use serde_json::to_value;
use parser::{Parser, Type};
use error::{Result, ErrorKind, serde_error};
use eip712::{EIP712, MessageTypes};
use rustc_hex::FromHex;
use validator::Validate;
use std::collections::HashSet;
fn check_hex(string: &str) -> Result<()> {
if string.len() >= 2 && &string[..2] == "0x" {
return Ok(())
}
return Err(ErrorKind::HexParseError(
format!("Expected a 0x-prefixed string of even length, found {} length string", string.len()))
)?
}
/// given a type and HashMap<String, Vec<FieldType>>
/// returns a HashSet of dependent types of the given type
fn build_dependencies<'a>(message_type: &'a str, message_types: &'a MessageTypes) -> Option<(HashSet<&'a str>)>
{
if message_types.get(message_type).is_none() {
return None;
}
let mut types = IndexSet::new();
types.insert(message_type);
let mut deps = HashSet::new();
while let Some(item) = types.pop() {
if let Some(fields) = message_types.get(item) {
deps.insert(item);
for field in fields {
// seen this type before? or not a custom type skip
if deps.contains(&*field.type_) || !message_types.contains_key(&*field.type_) {
continue;
}
types.insert(&*field.type_);
}
}
};
return Some(deps)
}
fn encode_type(message_type: &str, message_types: &MessageTypes) -> Result<String> {
let deps = {
let mut temp = build_dependencies(message_type, message_types).ok_or_else(|| ErrorKind::NonExistentType)?;
temp.remove(message_type);
let mut temp = temp.into_iter().collect::<Vec<_>>();
(&mut temp[..]).sort_unstable();
temp.insert(0, message_type);
temp
};
let encoded = deps
.into_iter()
.filter_map(|dep| {
message_types.get(dep).map(|field_types| {
let types = field_types
.iter()
.map(|value| format!("{} {}", value.type_, value.name))
.join(",");
return format!("{}({})", dep, types);
})
})
.collect::<Vec<_>>()
.concat();
Ok(encoded)
}
fn type_hash(message_type: &str, typed_data: &MessageTypes) -> Result<H256> {
Ok(keccak(encode_type(message_type, typed_data)?))
}
fn encode_data(
parser: &Parser,
message_type: &Type,
message_types: &MessageTypes,
value: &Value,
field_name: Option<&str>
) -> Result<Vec<u8>>
{
let encoded = match message_type {
Type::Array {
inner,
length
} => {
let mut items = vec![];
let values = value.as_array().ok_or_else(|| serde_error("array", field_name))?;
// check if the type definition actually matches
// the length of items to be encoded
if length.is_some() && Some(values.len() as u64) != *length {
let array_type = format!("{}[{}]", *inner, length.unwrap());
return Err(ErrorKind::UnequalArrayItems(length.unwrap(), array_type, values.len() as u64))?
}
for item in values {
let mut encoded = encode_data(parser, &*inner, &message_types, item, field_name)?;
items.append(&mut encoded);
}
keccak(items).to_vec()
}
Type::Custom(ref ident) if message_types.get(&*ident).is_some() => {
let type_hash = (&type_hash(ident, &message_types)?).to_vec();
let mut tokens = encode(&[EthAbiToken::FixedBytes(type_hash)]);
for field in message_types.get(ident).expect("Already checked in match guard; qed") {
let value = &value[&field.name];
let type_ = parser.parse_type(&*field.type_)?;
let mut encoded = encode_data(parser, &type_, &message_types, &value, Some(&*field.name))?;
tokens.append(&mut encoded);
}
keccak(tokens).to_vec()
}
Type::Bytes => {
let string = value.as_str().ok_or_else(|| serde_error("string", field_name))?;
check_hex(&string)?;
let bytes = (&string[2..])
.from_hex::<Vec<u8>>()
.map_err(|err| ErrorKind::HexParseError(format!("{}", err)))?;
let bytes = keccak(&bytes).to_vec();
encode(&[EthAbiToken::FixedBytes(bytes)])
}
Type::Byte(_) => {
let string = value.as_str().ok_or_else(|| serde_error("string", field_name))?;
check_hex(&string)?;
let mut bytes = (&string[2..])
.from_hex::<Vec<u8>>()
.map_err(|err| ErrorKind::HexParseError(format!("{}", err)))?;
encode(&[EthAbiToken::FixedBytes(bytes)])
}
Type::String => {
let value = value.as_str().ok_or_else(|| serde_error("string", field_name))?;
let hash = keccak(value).to_vec();
encode(&[EthAbiToken::FixedBytes(hash)])
}
Type::Bool => encode(&[EthAbiToken::Bool(value.as_bool().ok_or_else(|| serde_error("bool", field_name))?)]),
Type::Address => {
let addr = value.as_str().ok_or_else(|| serde_error("string", field_name))?;
if addr.len() != 42 {
return Err(ErrorKind::InvalidAddressLength(addr.len()))?;
}
let address = EthAddress::from_str(&addr[2..]).map_err(|err| ErrorKind::HexParseError(format!("{}", err)))?;
encode(&[EthAbiToken::Address(address)])
}
Type::Uint | Type::Int => {
let string = value.as_str().ok_or_else(|| serde_error("int/uint", field_name))?;
check_hex(&string)?;
let uint = U256::from_str(&string[2..]).map_err(|err| ErrorKind::HexParseError(format!("{}", err)))?;
let token = if *message_type == Type::Uint {
EthAbiToken::Uint(uint)
} else {
EthAbiToken::Int(uint)
};
encode(&[token])
}
_ => return Err(ErrorKind::UnknownType(format!("{}", field_name.unwrap_or("")), format!("{}", *message_type)))?
};
Ok(encoded)
}
/// encodes and hashes the given EIP712 struct
pub fn hash_structured_data(typed_data: EIP712) -> Result<H256> {
// validate input
typed_data.validate()?;
// EIP-191 compliant
let prefix = (b"\x19\x01").to_vec();
let domain = to_value(&typed_data.domain).unwrap();
let parser = Parser::new();
let (domain_hash, data_hash) = (
encode_data(&parser, &Type::Custom("EIP712Domain".into()), &typed_data.types, &domain, None)?,
encode_data(&parser, &Type::Custom(typed_data.primary_type), &typed_data.types, &typed_data.message, None)?
);
let concat = [&prefix[..], &domain_hash[..], &data_hash[..]].concat();
Ok(keccak(concat))
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::from_str;
use rustc_hex::ToHex;
const JSON: &'static str = r#"{
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": "0x1",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"contents": "Hello, Bob!"
},
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "string" }
]
}
}"#;
#[test]
fn test_build_dependencies() {
let string = r#"{
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "string" }
]
}"#;
let value = from_str::<MessageTypes>(string).expect("alas error!");
let mail = "Mail";
let person = "Person";
let hashset = {
let mut temp = HashSet::new();
temp.insert(mail);
temp.insert(person);
temp
};
assert_eq!(build_dependencies(mail, &value), Some(hashset));
}
#[test]
fn test_encode_type() {
let string = r#"{
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "string" }
]
}"#;
let value = from_str::<MessageTypes>(string).expect("alas error!");
let mail = &String::from("Mail");
assert_eq!(
"Mail(Person from,Person to,string contents)Person(string name,address wallet)",
encode_type(&mail, &value).expect("alas error!")
)
}
#[test]
fn test_encode_type_hash() {
let string = r#"{
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "string" }
]
}"#;
let value = from_str::<MessageTypes>(string).expect("alas error!");
let mail = &String::from("Mail");
let hash = (type_hash(&mail, &value).expect("alas error!").0).to_hex::<String>();
assert_eq!(
hash,
"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2"
);
}
#[test]
fn test_hash_data() {
let typed_data = from_str::<EIP712>(JSON).expect("alas error!");
assert_eq!(
hash_structured_data(typed_data).expect("alas error!").to_hex::<String>(),
"be609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2"
)
}
#[test]
fn test_unequal_array_lengths() {
const TEST: &'static str = r#"{
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": "0x1",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": [{
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
}],
"contents": "Hello, Bob!"
},
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Person": [
{ "name": "name", "type": "string" },
{ "name": "wallet", "type": "address" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person[2]" },
{ "name": "contents", "type": "string" }
]
}
}"#;
let typed_data = from_str::<EIP712>(TEST).expect("alas error!");
assert_eq!(
hash_structured_data(typed_data).unwrap_err().kind(),
ErrorKind::UnequalArrayItems(2, "Person[2]".into(), 1)
)
}
}

125
util/EIP-712/src/error.rs Normal file
View File

@ -0,0 +1,125 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::fmt::{self, Display};
use failure::{Fail, Context, Backtrace};
use validator::ValidationErrors;
use validator::ValidationErrorsKind;
pub(crate) type Result<T> = ::std::result::Result<T, Error>;
/// Error type
#[derive(Debug)]
pub struct Error {
inner: Context<ErrorKind>,
}
/// Possible errors encountered while hashing/encoding an EIP-712 compliant data structure
#[derive(Clone, Fail, Debug, PartialEq)]
pub enum ErrorKind {
/// if we fail to deserialize from a serde::Value as a type specified in message types
/// fail with this error.
#[fail(display = "Expected type '{}' for field '{}'", _0, _1)]
UnexpectedType(String, String),
/// the primary type supplied doesn't exist in the MessageTypes
#[fail(display = "The given primaryType wasn't found in the types field")]
NonExistentType,
/// an invalid address was encountered during encoding
#[fail(display = "Address string should be a 0x-prefixed 40 character string, got '{}'", _0)]
InvalidAddressLength(usize),
/// a hex parse error occured
#[fail(display = "Failed to parse hex '{}'", _0)]
HexParseError(String),
/// the field was declared with a unknown type
#[fail(display = "The field '{}' has an unknown type '{}'", _0, _1)]
UnknownType(String, String),
/// Unexpected token
#[fail(display = "Unexpected token '{}' while parsing typename '{}'", _0, _1)]
UnexpectedToken(String, String),
/// the user has attempted to define a typed array with a depth > 10
#[fail(display = "Maximum depth for nested arrays is 10")]
UnsupportedArrayDepth,
/// FieldType validation error
#[fail(display = "{}", _0)]
ValidationError(String),
/// the typed array defined in message types was declared with a fixed length
/// that is of unequal length with the items to be encoded
#[fail(display = "Expected {} items for array type {}, got {} items", _0, _1, _2)]
UnequalArrayItems(u64, String, u64),
/// Typed array length doesn't fit into a u64
#[fail(display = "Attempted to declare fixed size with length {}", _0)]
InvalidArraySize(String)
}
pub(crate) fn serde_error(expected: &str, field: Option<&str>) -> ErrorKind {
ErrorKind::UnexpectedType(expected.to_owned(), field.unwrap_or("").to_owned())
}
impl Fail for Error {
fn cause(&self) -> Option<&Fail> {
self.inner.cause()
}
fn backtrace(&self) -> Option<&Backtrace> {
self.inner.backtrace()
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl Error {
/// extract the error kind
pub fn kind(&self) -> ErrorKind {
self.inner.get_context().clone()
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error { inner: Context::new(kind) }
}
}
impl From<Context<ErrorKind>> for Error {
fn from(inner: Context<ErrorKind>) -> Error {
Error { inner }
}
}
impl From<ValidationErrors> for Error {
fn from(error: ValidationErrors) -> Self {
let mut string: String = "".into();
for (field_name, error_kind) in error.errors() {
match error_kind {
ValidationErrorsKind::Field(validation_errors) => {
for error in validation_errors {
let str_error = format!(
"the field '{}', has an invalid value {}",
field_name,
error.params["value"]
);
string.push_str(&str_error);
}
},
_ => unreachable!("#[validate] is only used on fields for regex;\
its impossible to get any other ErrorKind; qed")
}
}
ErrorKind::ValidationError(string).into()
}
}

192
util/EIP-712/src/lib.rs Normal file
View File

@ -0,0 +1,192 @@
// 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/>.
//! EIP-712 encoding utilities
//!
//! # Specification
//!
//! `encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)`
//! - data adheres to 𝕊, a structure defined in the rigorous eip-712
//! - `\x01` is needed to comply with EIP-191
//! - `domainSeparator` and `hashStruct` are defined below
//!
//! ## A) domainSeparator
//!
//! `domainSeparator = hashStruct(eip712Domain)`
//! <br/>
//! <br/>
//! Struct named `EIP712Domain` with the following fields
//!
//! - `name: String`
//! - `version: String`
//! - `chain_id: U256`,
//! - `verifying_contract: H160`
//! - `salt: Option<H256>`
//!
//! ## C) hashStruct
//!
//! `hashStruct(s : 𝕊) = keccak256(typeHash ‖ encodeData(s))`
//! <br/>
//! `typeHash = keccak256(encodeType(typeOf(s)))`
//!
//! ### i) encodeType
//!
//! - `name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")"`
//! - each member is written as `type ‖ " " ‖ name`
//! - encodings cascade down and are sorted by name
//!
//! ### ii) encodeData
//!
//! - `enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)`
//! - each encoded member is 32-byte long
//!
//! #### a) atomic
//!
//! - `boolean` => `U256`
//! - `address` => `H160`
//! - `uint` => sign-extended `U256` in big endian order
//! - `bytes1:31` => `H@256`
//!
//! #### b) dynamic
//!
//! - `bytes` => `keccak256(bytes)`
//! - `string` => `keccak256(string)`
//!
//! #### c) referenced
//!
//! - `array` => `keccak256(encodeData(array))`
//! - `struct` => `rec(keccak256(hashStruct(struct)))`
//!
//! ## D) Example
//! ### Query
//! ```json
//! {
//! "jsonrpc": "2.0",
//! "method": "eth_signTypedData",
//! "params": [
//! "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
//! {
//! "types": {
//! "EIP712Domain": [
//! {
//! "name": "name",
//! "type": "string"
//! },
//! {
//! "name": "version",
//! "type": "string"
//! },
//! {
//! "name": "chainId",
//! "type": "uint256"
//! },
//! {
//! "name": "verifyingContract",
//! "type": "address"
//! }
//! ],
//! "Person": [
//! {
//! "name": "name",
//! "type": "string"
//! },
//! {
//! "name": "wallet",
//! "type": "address"
//! }
//! ],
//! "Mail": [
//! {
//! "name": "from",
//! "type": "Person"
//! },
//! {
//! "name": "to",
//! "type": "Person"
//! },
//! {
//! "name": "contents",
//! "type": "string"
//! }
//! ]
//! },
//! "primaryType": "Mail",
//! "domain": {
//! "name": "Ether Mail",
//! "version": "1",
//! "chainId": 1,
//! "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
//! },
//! "message": {
//! "from": {
//! "name": "Cow",
//! "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
//! },
//! "to": {
//! "name": "Bob",
//! "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
//! },
//! "contents": "Hello, Bob!"
//! }
//! }
//! ],
//! "id": 1
//! }
//! ```
//
//! ### Response
//! ```json
//! {
//! "id":1,
//! "jsonrpc": "2.0",
//! "result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
//! }
//! ```
#![warn(missing_docs, unused_extern_crates)]
extern crate serde_json;
extern crate ethabi;
extern crate ethereum_types;
extern crate keccak_hash;
extern crate itertools;
extern crate failure;
extern crate indexmap;
extern crate lunarity_lexer;
extern crate toolshed;
extern crate regex;
extern crate validator;
#[macro_use]
extern crate validator_derive;
#[macro_use]
extern crate failure_derive;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate lazy_static;
extern crate rustc_hex;
mod eip712;
mod error;
mod parser;
mod encode;
/// the EIP-712 encoding function
pub use encode::hash_structured_data;
/// encoding Error types
pub use error::{ErrorKind, Error};
/// EIP712 struct
pub use eip712::EIP712;

172
util/EIP-712/src/parser.rs Normal file
View File

@ -0,0 +1,172 @@
// 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/>.
//! Solidity type-name parsing
use lunarity_lexer::{Lexer, Token};
use error::*;
use toolshed::Arena;
use std::{fmt, result};
#[derive(Debug, Clone, PartialEq)]
pub enum Type {
Address,
Uint,
Int,
String,
Bool,
Bytes,
Byte(u8),
Custom(String),
Array {
length: Option<u64>,
inner: Box<Type>
}
}
impl From<Type> for String {
fn from(field_type: Type) -> String {
match field_type {
Type::Address => "address".into(),
Type::Uint => "uint".into(),
Type::Int => "int".into(),
Type::String => "string".into(),
Type::Bool => "bool".into(),
Type::Bytes => "bytes".into(),
Type::Byte(len) => format!("bytes{}", len),
Type::Custom(custom) => custom,
Type::Array {
inner,
length
} => {
let inner: String = (*inner).into();
match length {
None => format!("{}[]", inner),
Some(length) => format!("{}[{}]", inner, length)
}
}
}
}
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
let item: String = self.clone().into();
write!(f, "{}", item)
}
}
pub struct Parser {
arena: Arena,
}
impl Parser {
pub fn new() -> Self {
Parser {
arena: Arena::new()
}
}
/// the type string is being validated before it's parsed.
pub fn parse_type(&self, field_type: &str) -> Result<Type> {
#[derive(PartialEq)]
enum State { Open, Close }
let mut lexer = Lexer::new(&self.arena, field_type);
let mut token = None;
let mut state = State::Close;
let mut array_depth = 0;
let mut current_array_length: Option<u64> = None;
while lexer.token != Token::EndOfProgram {
let type_ = match lexer.token {
Token::Identifier => Type::Custom(lexer.token_as_str().to_owned()),
Token::TypeByte => Type::Byte(lexer.type_size.0),
Token::TypeBytes => Type::Bytes,
Token::TypeBool => Type::Bool,
Token::TypeUint => Type::Uint,
Token::TypeInt => Type::Int,
Token::TypeString => Type::String,
Token::TypeAddress => Type::Address,
Token::LiteralInteger => {
let length = lexer.token_as_str();
current_array_length = Some(length
.parse()
.map_err(|_|
ErrorKind::InvalidArraySize(length.into())
)?
);
lexer.consume();
continue;
},
Token::BracketOpen if token.is_some() && state == State::Close => {
state = State::Open;
lexer.consume();
continue
}
Token::BracketClose if array_depth < 10 => {
if state == State::Open && token.is_some() {
let length = current_array_length.take();
state = State::Close;
token = Some(Type::Array {
inner: Box::new(token.expect("if statement checks for some; qed")),
length
});
lexer.consume();
array_depth += 1;
continue
} else {
return Err(ErrorKind::UnexpectedToken(lexer.token_as_str().to_owned(), field_type.to_owned()))?
}
}
Token::BracketClose if array_depth == 10 => {
return Err(ErrorKind::UnsupportedArrayDepth)?
}
_ => return Err(ErrorKind::UnexpectedToken(lexer.token_as_str().to_owned(), field_type.to_owned()))?
};
token = Some(type_);
lexer.consume();
}
Ok(token.ok_or_else(|| ErrorKind::NonExistentType)?)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parser() {
let parser = Parser::new();
let source = "byte[][][7][][][][][][][]";
parser.parse_type(source).unwrap();
}
#[test]
fn test_nested_array() {
let parser = Parser::new();
let source = "byte[][][7][][][][][][][][]";
assert_eq!(parser.parse_type(source).is_err(), true);
}
#[test]
fn test_malformed_array_type() {
let parser = Parser::new();
let source = "byte[7[]uint][]";
assert_eq!(parser.parse_type(source).is_err(), true)
}
}

View File

@ -3,7 +3,7 @@
[package] [package]
name = "parity-version" name = "parity-version"
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
version = "2.2.0" version = "2.2.1"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"