Compare commits

..

19 Commits

Author SHA1 Message Date
GitLab Build Bot
a667de45fe [ci skip] js-precompiled 20180319-175725 2018-03-19 17:58:43 +00:00
Tomasz Drwięga
ff71e787db [stable] Postpone Kovan hard fork (#8137) (#8152)
* Postpone Kovan hard fork (#8137)

* ethcore: postpone Kovan hard fork

* util: update version fork metadata

* WASM libraries bump (#7970)

* update wasmi, parity-wasm, wasm-utils to latest version

* Update to new wasmi & error handling

* also utilize new stack limiter

* fix typo

* replace dependency url

* Cargo.lock update
2018-03-19 17:45:38 +00:00
GitLab Build Bot
0940fe91e5 [ci skip] js-precompiled 20180319-094121 2018-03-19 09:43:53 +00:00
GitLab Build Bot
f205490fb0 [ci skip] js-precompiled 20180319-082712 2018-03-19 08:28:13 +00:00
Tomasz Drwięga
dc8d6d819e Fix scripts. Force JS rebuild. (#8144) 2018-03-19 09:15:14 +01:00
Tomasz Drwięga
feef2f8791 [stable] Backports (#8133)
* updater: apply exponential backoff after download failure (#8059)

* updater: apply exponential backoff after download failure

* updater: reset backoff on new release

* Limit incoming connections.  (#8060)

* Limit ingress connections
* Optimized handshakes logging

* Max code size on Kovan (#8067)

* Enable code size limit on kovan

* Fix formatting.

* add some dos protection (#8084)

* more dos protection (#8104)

* Const time comparison (#8113)

* Use `subtle::slices_equal` for constant time comparison.

Also update the existing version of subtle in `ethcrypto` from
0.1 to 0.5

* Test specifically for InvalidPassword error.

* revert removing blooms (#8066)

* Revert "fix traces, removed bloomchain crate, closes #7228, closes #7167"

This reverts commit 1bf62038678295e5586f02a38a0c5aab9a9efe62.

* Revert "fixed broken logs (#7934)"

This reverts commit f8a2e53f3e.

* fixed broken logs

* bring back old lock order

* remove migration v13

* revert CURRENT_VERSION to 12 in migration.rs

* Fix compilation.

* Check one step deeper if we're on release track branches

* add missing pr

* Fix blooms?

* Fix tests compiilation.

* Fix size.
2018-03-19 07:00:16 +01:00
Tomasz Drwięga
3c15a501ca Check one step deeper if we're on release track branches (#8134) (#8140) 2018-03-17 08:04:58 +01:00
Tomasz Drwięga
b7682dabf4 Trigger js build. (#8121) 2018-03-15 10:18:13 +00:00
Rando
2acfdfc977 Stable backports (#8055)
* CI: Fix cargo cache (#7968)

* Fix cache

Blocking waiting for file lock on the registry index

* Only clean locked cargo cache on windows

* fixed ethstore sign (#8026)

* fix cache & snapcraft CI build (#8052)

after successful testing it is necessary to port in a ```beta``` and ```stable```

*  Add MCIP-6 Byzyantium transition to Musicoin spec (#7841)

* Add test chain spec for musicoin byzantium testnet

* Add MCIP-6 Byzyantium transition to Musicoin spec

* Update mcip6_byz.json

* ethcore: update musicoin byzantium block number

* ethcore: update musicoin byzantium block number

* ethcore: update musicoin bootnodes

* Update musicoin.json

* Update musicoin.json

* More bootnodes.
2018-03-14 13:50:58 +01:00
Tomasz Drwięga
a6d732ed14 [stable] Optimize JS build (#8093)
* Extract common chunks plugin.

* Fix common CSS.

* Fix js push for stable.

* Remove arguments to getPlugins.
2018-03-13 16:54:39 +01:00
GitLab Build Bot
a9a58d230e [ci skip] js-precompiled 20180313-123149 2018-03-13 12:33:12 +00:00
André Silva
edbff0d34d [Stable] Backports (#8058)
* fixed parsing ethash seals and verify_block_undordered (#8031)

* fix for verify_block_basic crashing on invalid transaction rlp (#8032)
2018-03-05 15:15:30 +01:00
Rando
94defd7f82 Make 1.9 stable (#8023)
* Make 1.9 stable

* Bump stable to 1.9.5

* Fix gitlab builds
2018-03-01 19:36:26 +01:00
Jaco Greeff
362fb1dfed Drop built-in dapps for stable (#8030) 2018-03-01 19:25:15 +01:00
GitLab Build Bot
caaac78971 [ci skip] js-precompiled 20180228-161406 2018-02-28 16:15:24 +00:00
GitLab Build Bot
1762e82676 [ci skip] js-precompiled 20180228-152326 2018-02-28 15:24:42 +00:00
Rando
6f21a32b2b Bump beta to 1.9.4 (#8016) 2018-02-28 15:59:05 +01:00
Tomasz Drwięga
86f6cea29d [beta] Backports (#8011)
* Hardware-wallet/usb-subscribe-refactor (#7860)

* Hardware-wallet fix

* More fine-grained initilization of callbacks by vendorID, productID and usb class
* Each device manufacturer gets a seperate handle thread each
* Replaced "dummy for loop" with a delay to wait for the device to boot-up properly
* Haven't been very carefully with checking dependencies cycles etc
* Inline comments explaining where shortcuts have been taken
* Need to test this on Windows machine and with Ledger (both models)

Signed-off-by: niklasad1 <niklasadolfsson1@gmail.com>

* Validate product_id of detected ledger devices

* closed_device => unlocked_device

* address comments

* add target in debug

* Address feedback

* Remove thread joining in HardwareWalletManager
* Remove thread handlers in HardwareWalletManager because this makes them unused

* fixed broken logs (#7934)

* fixed broken logs

* bring back old lock order

* removed bloom groups from blockchain

* revert unrelated changes

* simplify blockchain_block_blooms

* Bump WS (#7952)

* Calculate proper keccak256/sha3 using parity. (#7953)

* Increase max download limit to 128MB (#7965)

* fetch: increase max download limit to 64MB

* parity: increase download size limit for updater service

* Detect too large packets in snapshot sync. (#7977)

* fix traces, removed bloomchain crate, closes #7228, closes #7167 (#7979)

* Remvoe generator.rs

* Make block generator easier to use (#7888)

* Make block generator easier to use

* applied review suggestions

* rename BlockMetadata -> BlockOptions

* removed redundant uses of blockchain generator and genereator.next().unwrap() calls
2018-02-28 14:59:04 +01:00
GitLab Build Bot
3d6670972f [ci skip] js-precompiled 20180219-162828 2018-02-19 16:29:36 +00:00
113 changed files with 3653 additions and 1554 deletions

View File

@@ -9,12 +9,10 @@ variables:
CARGOFLAGS: ""
CI_SERVER_NAME: "GitLab CI"
LIBSSL: "libssl1.0.0 (>=1.0.0)"
CARGO_HOME: $CI_PROJECT_DIR/cargo
cache:
key: "$CI_BUILD_STAGE-$CI_BUILD_REF_NAME"
paths:
- target/
- cargo/
untracked: true
linux-stable:
stage: build
@@ -133,7 +131,7 @@ linux-aarch64:
name: "aarch64-unknown-linux-gnu_parity"
linux-snap:
stage: build
image: snapcore/snapcraft:stable
image: parity/snapcraft:gitlab-ci
only:
- stable
- beta

247
Cargo.lock generated
View File

@@ -106,7 +106,7 @@ name = "base64"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -115,7 +115,7 @@ name = "bigint"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -127,7 +127,7 @@ name = "bincode"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -183,22 +183,26 @@ dependencies = [
[[package]]
name = "bloomchain"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
version = "0.2.0"
dependencies = [
"ethcore-bigint 0.2.1",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bn"
version = "0.4.4"
source = "git+https://github.com/paritytech/bn#c9831a8d10d55045692394cbc10efe0321ddb16f"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byteorder"
version = "1.1.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -206,7 +210,7 @@ name = "bytes"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -270,9 +274,10 @@ name = "common-types"
version = "0.1.0"
dependencies = [
"bloomable 0.1.0",
"ethbloom 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethjson 0.1.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0",
@@ -454,7 +459,7 @@ dependencies = [
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -470,15 +475,25 @@ dependencies = [
"primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethbloom"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethcore"
version = "1.9.0"
dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bloomable 0.1.0",
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bloomchain 0.2.0",
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0",
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"ethash 1.9.0",
@@ -489,7 +504,7 @@ dependencies = [
"ethcore-io 1.9.0",
"ethcore-logger 1.9.0",
"ethcore-stratum 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethjson 0.1.0",
"ethkey 0.3.0",
"ethstore 0.2.0",
@@ -604,7 +619,7 @@ dependencies = [
"ethcore-bytes 0.1.0",
"ethcore-io 1.9.0",
"ethcore-network 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -678,19 +693,19 @@ dependencies = [
"snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethcore-secretstore"
version = "1.0.0"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.9.0",
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
"ethcore-logger 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethcrypto 0.1.0",
"ethkey 0.3.0",
"ethsync 1.9.0",
@@ -709,7 +724,7 @@ dependencies = [
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -736,7 +751,7 @@ dependencies = [
[[package]]
name = "ethcore-util"
version = "1.9.0"
version = "1.9.5"
dependencies = [
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
@@ -756,8 +771,8 @@ dependencies = [
"ethcore-bigint 0.2.1",
"ethkey 0.3.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -775,7 +790,7 @@ dependencies = [
name = "ethkey"
version = "0.3.0"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)",
"ethcore-bigint 0.2.1",
@@ -785,7 +800,7 @@ dependencies = [
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -814,6 +829,7 @@ dependencies = [
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -823,9 +839,10 @@ dependencies = [
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -854,7 +871,7 @@ dependencies = [
"ethcore-io 1.9.0",
"ethcore-light 1.9.0",
"ethcore-network 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethkey 0.3.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -878,7 +895,7 @@ version = "0.1.0"
dependencies = [
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"evmjit 1.9.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0",
@@ -898,7 +915,7 @@ dependencies = [
"ethcore 1.9.0",
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethjson 0.1.0",
"evm 0.1.0",
"panic_hook 0.1.0",
@@ -913,7 +930,7 @@ dependencies = [
name = "evmjit"
version = "1.9.0"
dependencies = [
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -972,6 +989,20 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.1.16"
@@ -1333,7 +1364,7 @@ dependencies = [
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ws 0.7.1 (git+https://github.com/tomusdrw/ws-rs)",
"ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)",
]
[[package]]
@@ -1343,7 +1374,7 @@ dependencies = [
"cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1421,7 +1452,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1529,6 +1560,11 @@ dependencies = [
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memory_units"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memorydb"
version = "0.1.1"
@@ -1664,7 +1700,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1679,7 +1715,7 @@ dependencies = [
name = "native-contracts"
version = "0.1.0"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1719,7 +1755,7 @@ dependencies = [
"ethcore-bytes 0.1.0",
"ethcore-io 1.9.0",
"ethcore-network 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb-memorydb 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1755,7 +1791,7 @@ name = "ntp"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1913,7 +1949,7 @@ dependencies = [
[[package]]
name = "parity"
version = "1.9.3"
version = "1.9.5"
dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1933,7 +1969,7 @@ dependencies = [
"ethcore-network 1.9.0",
"ethcore-secretstore 1.0.0",
"ethcore-stratum 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethkey 0.3.0",
"ethsync 1.9.0",
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1961,7 +1997,7 @@ dependencies = [
"parity-rpc 1.9.0",
"parity-rpc-client 1.4.0",
"parity-updater 1.9.0",
"parity-version 1.9.3",
"parity-version 1.9.5",
"parity-whisper 0.1.0",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"path 0.1.0",
@@ -1993,7 +2029,7 @@ dependencies = [
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
"ethcore-devtools 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"fetch 0.1.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2009,7 +2045,7 @@ dependencies = [
"parity-hash-fetch 1.9.0",
"parity-reactor 0.1.0",
"parity-ui 1.9.0",
"parity-version 1.9.3",
"parity-version 1.9.5",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2055,7 +2091,7 @@ dependencies = [
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"fetch 0.1.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0",
@@ -2105,7 +2141,7 @@ name = "parity-machine"
version = "0.1.0"
dependencies = [
"ethcore-bigint 0.2.1",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
]
[[package]]
@@ -2131,7 +2167,7 @@ dependencies = [
"ethcore-light 1.9.0",
"ethcore-logger 1.9.0",
"ethcore-network 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethcrypto 0.1.0",
"ethjson 0.1.0",
"ethkey 0.3.0",
@@ -2157,7 +2193,7 @@ dependencies = [
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-reactor 0.1.0",
"parity-updater 1.9.0",
"parity-version 1.9.3",
"parity-version 1.9.5",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2170,7 +2206,7 @@ dependencies = [
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
@@ -2216,8 +2252,8 @@ version = "1.9.0"
dependencies = [
"parity-ui-dev 1.9.0",
"parity-ui-old-dev 1.9.0",
"parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git)",
"parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git)",
"parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git)",
"parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2238,7 +2274,7 @@ dependencies = [
[[package]]
name = "parity-ui-old-precompiled"
version = "1.9.0"
source = "git+https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git#54398b761c19fbdfb47e3f2fc21eddec92f8ca40"
source = "git+https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git#4a84c8a0f15c048e37950d1c08d1b364e8c3d401"
dependencies = [
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2246,7 +2282,7 @@ dependencies = [
[[package]]
name = "parity-ui-precompiled"
version = "1.9.0"
source = "git+https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git#266a67a3a0112efcdcfdd8b1ef0721a28575bbc7"
source = "git+https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git#f1e0969378f00c8528062a9aebb7408f3dbd47de"
dependencies = [
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2259,13 +2295,13 @@ dependencies = [
"ethcore 1.9.0",
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethsync 1.9.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-hash-fetch 1.9.0",
"parity-reactor 0.1.0",
"parity-version 1.9.3",
"parity-version 1.9.5",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"path 0.1.0",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2274,7 +2310,7 @@ dependencies = [
[[package]]
name = "parity-version"
version = "1.9.3"
version = "1.9.5"
dependencies = [
"ethcore-bytes 0.1.0",
"rlp 0.2.1",
@@ -2286,10 +2322,10 @@ dependencies = [
[[package]]
name = "parity-wasm"
version = "0.23.0"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2299,7 +2335,7 @@ name = "parity-whisper"
version = "0.1.0"
dependencies = [
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"ethcore-network 1.9.0",
"ethcrypto 0.1.0",
@@ -2320,7 +2356,7 @@ dependencies = [
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2586,6 +2622,16 @@ dependencies = [
"magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "0.7.1"
@@ -2674,7 +2720,7 @@ dependencies = [
name = "rlp"
version = "0.2.1"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2739,7 +2785,7 @@ name = "rpc-cli"
version = "1.4.0"
dependencies = [
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-rpc 1.9.0",
"parity-rpc-client 1.4.0",
@@ -3026,11 +3072,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "subtle"
version = "0.1.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
@@ -3171,8 +3214,11 @@ dependencies = [
[[package]]
name = "tiny-keccak"
version = "1.3.1"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-core"
@@ -3461,11 +3507,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "vm"
version = "0.1.0"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0",
"ethcore-bigint 0.2.1",
"ethcore-bytes 0.1.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"ethjson 0.1.0",
"keccak-hash 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3482,39 +3528,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "wasm"
version = "0.1.0"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1",
"ethcore-logger 1.9.0",
"ethcore-util 1.9.0",
"ethcore-util 1.9.5",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
"wasmi 0.0.0 (git+https://github.com/pepyakin/wasmi)",
"wasmi 0.0.0 (git+https://github.com/paritytech/wasmi)",
]
[[package]]
name = "wasm-utils"
version = "0.1.0"
source = "git+https://github.com/paritytech/wasm-utils#6fdc1c4ed47a6acb0a4774da505a416dd637bc6d"
source = "git+https://github.com/paritytech/wasm-utils#9527b969a4928f6293369380defc7982493a678c"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmi"
version = "0.0.0"
source = "git+https://github.com/pepyakin/wasmi#551c99273042deaad869c17798060e2212deacab"
source = "git+https://github.com/paritytech/wasmi#7c88c6ad651ec6a6aa00b08e61c70853161a0a99"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3522,17 +3569,36 @@ name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ws"
version = "0.7.1"
source = "git+https://github.com/tomusdrw/ws-rs#f8306a798b7541d64624299a83a2c934f173beed"
version = "0.7.5"
source = "git+https://github.com/tomusdrw/ws-rs#368ce39e2aa8700d568ca29dbacaecdf1bf749d1"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3608,9 +3674,8 @@ dependencies = [
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d"
"checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "<none>"
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6"
"checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
@@ -3638,6 +3703,7 @@ dependencies = [
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
"checksum ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819a3adef0413a2519cbd9a19a35dd1c20c7a0110705beaba8aa4aa87eda95f"
"checksum ethbloom 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3d1d93b56bf23b8d38c71e4a5360607fc8e91d402ec20a7e90f4e896cfd21d2b"
"checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5"
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423"
@@ -3645,6 +3711,8 @@ dependencies = [
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "05a23db7bd162d4e8265968602930c476f688f0c180b44bdaf55e0cb2c687558"
"checksum futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "77d49e7de8b91b20d6fda43eea906637eff18b96702eb6b2872df8bfab1ad2b5"
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
@@ -3697,6 +3765,7 @@ dependencies = [
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
"checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
"checksum mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e3d709ffbb330e1566dc2f2a3c9b58a5ad4a381f740b810cd305dc3f089bc160"
"checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae"
@@ -3730,9 +3799,9 @@ dependencies = [
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "261c025c67ba416e9fe63aa9b3236520ce3c74cfbe43590c9cdcec4ccc8180e4"
"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
"checksum parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git)" = "<none>"
"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git)" = "<none>"
"checksum parity-wasm 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ba4b1d4236b76694f6ab8d8d00cdbe1e37c6dd1b5c803d26721f27e097d4d9"
"checksum parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git)" = "<none>"
"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git)" = "<none>"
"checksum parity-wasm 0.27.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3c21b85fed4e8490e716b7fcb247185ec201f28845be6e749ab864401463c7"
"checksum parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0dec124478845b142f68b446cbee953d14d4b41f1bc0425024417720dce693"
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
"checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412"
@@ -3759,6 +3828,7 @@ dependencies = [
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
@@ -3808,7 +3878,7 @@ dependencies = [
"checksum spmc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd1f11d1fb5fd41834e55ce0b85a186efbf2f2afd9fdb09e2c8d72f9bff1ad1a"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b811576c12506ff3f6da145585dc833edc32ee34c9fc021127d90e8134cc05c"
"checksum subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7f6353c2ee5407358d063a14cccc1630804527090a6fb5a9489ce4924280fb"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e"
@@ -3824,7 +3894,7 @@ dependencies = [
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292"
"checksum tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58911ed5eb275a8fd2f1f0418ed360a42f59329864b64e1e95377a9024498c01"
"checksum tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e85d419699ec4b71bfe35bbc25bb8771e52eff0471a7f75c853ad06e200b4f86"
"checksum tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ab83e7adb5677e42e405fa4ceff75659d93c4d7d7dd22f52fcec59ee9f02af"
"checksum tokio-named-pipes 0.1.0 (git+https://github.com/nikvolf/tokio-named-pipes)" = "<none>"
@@ -3857,10 +3927,13 @@ dependencies = [
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)" = "<none>"
"checksum wasmi 0.0.0 (git+https://github.com/pepyakin/wasmi)" = "<none>"
"checksum wasmi 0.0.0 (git+https://github.com/paritytech/wasmi)" = "<none>"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum ws 0.7.1 (git+https://github.com/tomusdrw/ws-rs)" = "<none>"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "<none>"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"

View File

@@ -1,7 +1,7 @@
[package]
description = "Parity Ethereum client"
name = "parity"
version = "1.9.3"
version = "1.9.5"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"

View File

@@ -13,8 +13,8 @@ rustc_version = "0.1"
parity-ui-dev = { path = "../../js", optional = true }
parity-ui-old-dev = { path = "../../js-old", optional = true }
# This is managed by the js/scripts/release.sh script on CI - keep it in a single line
parity-ui-old-precompiled = { git = "https://github.com/js-dist-paritytech/parity-beta-1-9-v1.git", optional = true }
parity-ui-precompiled = { git = "https://github.com/js-dist-paritytech/parity-beta-1-9-shell.git", optional = true }
parity-ui-old-precompiled = { git = "https://github.com/js-dist-paritytech/parity-stable-1-9-v1.git", optional = true }
parity-ui-precompiled = { git = "https://github.com/js-dist-paritytech/parity-stable-1-9-shell.git", optional = true }
[features]
no-precompiled-js = ["parity-ui-dev", "parity-ui-old-dev"]

View File

@@ -8,7 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ansi_term = "0.9"
bloomchain = "0.1"
bloomchain = { path = "../util/bloomchain" }
bn = { git = "https://github.com/paritytech/bn" }
byteorder = "1.0"
common-types = { path = "types" }

View File

@@ -26,6 +26,7 @@
"minGasLimit": "0x1388",
"networkID" : "0x1",
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0",
"eip98Transition": "0xffffffffffffffff",
"eip140Transition": "0x0",
"eip211Transition": "0x0",

View File

@@ -26,6 +26,7 @@
"minGasLimit": "0x1388",
"networkID" : "0x1",
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0",
"eip98Transition": "0xffffffffffffffff",
"eip140Transition": "0x0",
"eip210Transition": "0x0",

View File

@@ -25,7 +25,8 @@
"eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff",
"maxCodeSize": 24576
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x7fffffffffffffff"
},
"genesis": {
"seal": {

View File

@@ -25,7 +25,8 @@
"eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff",
"maxCodeSize": 24576
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0"
},
"genesis": {
"seal": {

View File

@@ -152,6 +152,7 @@
"eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"maxCodeSize": 24576,
"maxCodeSizeTransition": 2675000,
"eip140Transition": 4370000,
"eip211Transition": 4370000,
"eip214Transition": 4370000,

View File

@@ -34,13 +34,16 @@
"networkID" : "0x2A",
"forkBlock": 4297256,
"forkCanonHash": "0x0a66d93c2f727dca618fabaf70c39b37018c73d78b939d8b11efbbd09034778f",
"validateReceiptsTransition" : 1000000,
"eip155Transition": 1000000,
"maxCodeSize": 24576,
"maxCodeSizeTransition": 6600000,
"validateChainIdTransition": 1000000,
"validateReceiptsTransition" : 1000000,
"eip140Transition": 5067000,
"eip211Transition": 5067000,
"eip214Transition": 5067000,
"eip658Transition": 5067000
"eip658Transition": 5067000,
"wasmActivationTransition": 6600000
},
"genesis": {
"seal": {

View File

@@ -40,7 +40,8 @@
"eip211Transition":"0x7fffffffffffff",
"eip214Transition":"0x7fffffffffffff",
"eip658Transition":"0x7fffffffffffff",
"maxCodeSize":"0x6000"
"maxCodeSize":"0x6000",
"maxCodeSizeTransition": "0x7fffffffffffff"
},
"genesis":{
"seal":{

View File

@@ -0,0 +1,161 @@
{
"name":"Musicoin Byzantium Test",
"dataDir":"mcip6test",
"engine":{
"Ethash":{
"params":{
"minimumDifficulty":"0x020000",
"difficultyBoundDivisor":"0x0800",
"durationLimit":"0x0d",
"homesteadTransition":"0x17",
"eip100bTransition":"0x2a",
"eip150Transition":"0x2a",
"eip160Transition":"0x7fffffffffffff",
"eip161abcTransition":"0x7fffffffffffff",
"eip161dTransition":"0x7fffffffffffff",
"eip649Transition":"0x2a",
"blockReward":"0x1105a0185b50a80000",
"mcip3Transition":"0x17",
"mcip3MinerReward":"0xd8d726b7177a80000",
"mcip3UbiReward":"0x2b5e3af16b1880000",
"mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310",
"mcip3DevReward":"0xc249fdd327780000",
"mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536"
}
}
},
"params":{
"gasLimitBoundDivisor":"0x0400",
"registrar":"0x5C271c4C9A67E7D73b7b3669d47504741354f21D",
"accountStartNonce":"0x00",
"maximumExtraDataSize":"0x20",
"minGasLimit":"0x1388",
"networkID":"0x76740c",
"forkBlock":"0x2b",
"forkCanonHash":"0x23c3171e864a5d513a3ef85e4cf86dac4cc36b89e5b8e63bf0ebcca68b9e43c9",
"eip86Transition":"0x7fffffffffffff",
"eip98Transition":"0x7fffffffffffff",
"eip140Transition":"0x2a",
"eip155Transition":"0x2a",
"eip211Transition":"0x2a",
"eip214Transition":"0x2a",
"eip658Transition":"0x2a",
"maxCodeSize":"0x6000",
"maxCodeSizeTransition": "0x7fffffffffffff"
},
"genesis":{
"seal":{
"ethereum":{
"nonce":"0x000000000000002a",
"mixHash":"0x00000000000000000000000000000000000000647572616c65787365646c6578"
}
},
"difficulty":"0x3d0900",
"author":"0x0000000000000000000000000000000000000000",
"timestamp":"0x00",
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData":"",
"gasLimit":"0x7a1200"
},
"nodes":[
"enode://5ddc110733f6d34101973cdef3f9b43484159acf6f816d3b1ee92bc3c98ea453e857bb1207edf0ec0242008ab3a0f9f05eeaee99d47bd414c08a5bdf4847de13@176.9.3.148:30303",
"enode://38f074f4db8e64dfbaf87984bf290eef67772a901a7113d1b62f36216be152b8450c393d6fc562a5e38f04f99bc8f439a99010a230b1d92dc1df43bf0bd00615@176.9.3.148:30403"
],
"accounts":{
"0000000000000000000000000000000000000001":{
"balance":"1",
"builtin":{
"name":"ecrecover",
"pricing":{
"linear":{
"base":3000,
"word":0
}
}
}
},
"0000000000000000000000000000000000000002":{
"balance":"1",
"builtin":{
"name":"sha256",
"pricing":{
"linear":{
"base":60,
"word":12
}
}
}
},
"0000000000000000000000000000000000000003":{
"balance":"1",
"builtin":{
"name":"ripemd160",
"pricing":{
"linear":{
"base":600,
"word":120
}
}
}
},
"0000000000000000000000000000000000000004":{
"balance":"1",
"builtin":{
"name":"identity",
"pricing":{
"linear":{
"base":15,
"word":3
}
}
}
},
"0000000000000000000000000000000000000005":{
"builtin":{
"name":"modexp",
"activate_at":"0x2a",
"pricing":{
"modexp":{
"divisor":20
}
}
}
},
"0000000000000000000000000000000000000006":{
"builtin":{
"name":"alt_bn128_add",
"activate_at":"0x2a",
"pricing":{
"linear":{
"base":500,
"word":0
}
}
}
},
"0000000000000000000000000000000000000007":{
"builtin":{
"name":"alt_bn128_mul",
"activate_at":"0x2a",
"pricing":{
"linear":{
"base":40000,
"word":0
}
}
}
},
"0000000000000000000000000000000000000008":{
"builtin":{
"name":"alt_bn128_pairing",
"activate_at":"0x2a",
"pricing":{
"alt_bn128_pairing":{
"base":100000,
"pair":80000
}
}
}
}
}
}

View File

@@ -8,12 +8,12 @@
"difficultyBoundDivisor":"0x0800",
"durationLimit":"0x0d",
"homesteadTransition":"0x118c30",
"eip100bTransition":"0x7fffffffffffff",
"eip150Transition":"0x7fffffffffffff",
"eip100bTransition":"0x21e88e",
"eip150Transition":"0x21e88e",
"eip160Transition":"0x7fffffffffffff",
"eip161abcTransition":"0x7fffffffffffff",
"eip161dTransition":"0x7fffffffffffff",
"eip649Transition":"0x7fffffffffffff",
"eip649Transition":"0x21e88e",
"blockReward":"0x1105a0185b50a80000",
"mcip3Transition":"0x124f81",
"mcip3MinerReward":"0xd8d726b7177a80000",
@@ -31,16 +31,17 @@
"maximumExtraDataSize":"0x20",
"minGasLimit":"0x1388",
"networkID":"0x76740f",
"forkBlock":"0x5b6",
"forkCanonHash":"0xa5e88ad9e34d113e264e307bc27e8471452c8fc13780324bb3abb96fd0558343",
"forkBlock":"0x1d8015",
"forkCanonHash":"0x380602acf82b629a0be6b5adb2b4a801e960a07dc8261bf196d21befdbb8f2f9",
"eip86Transition":"0x7fffffffffffff",
"eip98Transition":"0x7fffffffffffff",
"eip140Transition":"0x7fffffffffffff",
"eip155Transition":"0x7fffffffffffff",
"eip211Transition":"0x7fffffffffffff",
"eip214Transition":"0x7fffffffffffff",
"eip658Transition":"0x7fffffffffffff",
"maxCodeSize":"0x6000"
"eip140Transition":"0x21e88e",
"eip155Transition":"0x21e88e",
"eip211Transition":"0x21e88e",
"eip214Transition":"0x21e88e",
"eip658Transition":"0x21e88e",
"maxCodeSize":"0x6000",
"maxCodeSizeTransition": "0x7fffffffffffff"
},
"genesis":{
"seal":{
@@ -57,12 +58,9 @@
"gasLimit":"0x7a1200"
},
"nodes":[
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303",
"enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303",
"enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303",
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
"enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303",
"enode://09fcd36d553044c8b499b9b9e13a228ffd99572c513f77073d41f009717c464cd4399c0e665d6aff1590324254ee4e698b2b2533b1998dd04d896b9d6aff7895@35.185.67.35:30303",
"enode://89e51a34770a0badf8ea18c4c4d2c361cde707abd60031d99b1ab3010363e1898230a516ddb37d974af8d8db1b322779d7fe0caae0617bed4924d1b4968cf92b@35.231.48.142:30303",
"enode://b58c0c71f08864c0cf7fa9dea2c4cbefae5ae7a36cc30d286603b24982d25f3ccc056b589119324c51768fc2054b8c529ecf682e06e1e9980170b93ff194ed7a@132.148.132.9:30303",
"enode://d302f52c8789ad87ee528f1431a67f1aa646c9bec17babb4665dfb3d61de5b9119a70aa77b2147a5f28854092ba09769323c1c552a6ac6f6a34cbcf767e2d2fe@158.69.248.48:30303",
"enode://c72564bce8331ae298fb8ece113a456e3927d7e5989c2be3e445678b3600579f722410ef9bbfe339335d676af77343cb21b5b1703b7bebc32be85fce937a2220@191.252.185.71:30303",
"enode://e3ae4d25ee64791ff98bf17c37acf90933359f2505c00f65c84f6863231a32a94153cadb0a462e428f18f35ded6bd91cd91033d26576a28558c22678be9cfaee@5.63.158.137:35555"
@@ -119,7 +117,7 @@
"0000000000000000000000000000000000000005":{
"builtin":{
"name":"modexp",
"activate_at":"0x7fffffffffffff",
"activate_at":"0x21e88e",
"pricing":{
"modexp":{
"divisor":20
@@ -130,7 +128,7 @@
"0000000000000000000000000000000000000006":{
"builtin":{
"name":"alt_bn128_add",
"activate_at":"0x7fffffffffffff",
"activate_at":"0x21e88e",
"pricing":{
"linear":{
"base":500,
@@ -142,7 +140,7 @@
"0000000000000000000000000000000000000007":{
"builtin":{
"name":"alt_bn128_mul",
"activate_at":"0x7fffffffffffff",
"activate_at":"0x21e88e",
"pricing":{
"linear":{
"base":40000,
@@ -154,7 +152,7 @@
"0000000000000000000000000000000000000008":{
"builtin":{
"name":"alt_bn128_pairing",
"activate_at":"0x7fffffffffffff",
"activate_at":"0x21e88e",
"pricing":{
"alt_bn128_pairing":{
"base":100000,

View File

@@ -29,6 +29,7 @@
"forkBlock": 641350,
"forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb",
"maxCodeSize": 24576,
"maxCodeSizeTransition": 10,
"eip155Transition": 10,
"eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",

View File

@@ -26,6 +26,7 @@
"minGasLimit": "0x1388",
"networkID" : "0x1",
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0",
"eip98Transition": "5",
"eip140Transition": "5",
"eip211Transition": "5",

View File

@@ -32,7 +32,7 @@ pub struct BlockInfo {
}
/// Describes location of newly inserted block.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub enum BlockLocation {
/// It's part of the canon chain.
CanonChain,
@@ -44,7 +44,7 @@ pub enum BlockLocation {
BranchBecomingCanonChain(BranchBecomingCanonChainData),
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct BranchBecomingCanonChainData {
/// Hash of the newest common ancestor with old canon chain.
pub ancestor: H256,

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,6 @@
use std::ops;
use std::io::Write;
use bloomchain;
use blooms::{GroupPosition, BloomGroup};
use db::Key;
use engines::epoch::{Transition as EpochTransition};
@@ -98,32 +97,17 @@ impl ops::Deref for LogGroupKey {
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct LogGroupPosition(GroupPosition);
impl From<bloomchain::group::GroupPosition> for LogGroupPosition {
fn from(position: bloomchain::group::GroupPosition) -> Self {
LogGroupPosition(From::from(position))
}
}
impl HeapSizeOf for LogGroupPosition {
fn heap_size_of_children(&self) -> usize {
self.0.heap_size_of_children()
}
}
impl Key<BloomGroup> for LogGroupPosition {
impl Key<BloomGroup> for GroupPosition {
type Target = LogGroupKey;
fn key(&self) -> Self::Target {
let mut result = [0u8; 6];
result[0] = ExtrasIndex::BlocksBlooms as u8;
result[1] = self.0.level;
result[2] = (self.0.index >> 24) as u8;
result[3] = (self.0.index >> 16) as u8;
result[4] = (self.0.index >> 8) as u8;
result[5] = self.0.index as u8;
result[1] = self.level;
result[2] = (self.index >> 24) as u8;
result[3] = (self.index >> 16) as u8;
result[4] = (self.index >> 8) as u8;
result[5] = self.index as u8;
LogGroupKey(result)
}
}

View File

@@ -0,0 +1,219 @@
// Copyright 2015-2017 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/>.
//! Blockchain generator for tests.
use std::collections::VecDeque;
use bigint::prelude::{U256, H256};
use bloomchain::Bloom;
use bytes::Bytes;
use header::Header;
use rlp::encode;
use transaction::SignedTransaction;
use views::BlockView;
/// Helper structure, used for encoding blocks.
#[derive(Default, Clone, RlpEncodable)]
pub struct Block {
pub header: Header,
pub transactions: Vec<SignedTransaction>,
pub uncles: Vec<Header>
}
impl Block {
#[inline]
pub fn header(&self) -> Header {
self.header.clone()
}
#[inline]
pub fn hash(&self) -> H256 {
BlockView::new(&self.encoded()).header_view().hash()
}
#[inline]
pub fn number(&self) -> u64 {
self.header.number()
}
#[inline]
pub fn encoded(&self) -> Bytes {
encode(self).into_vec()
}
}
#[derive(Debug)]
pub struct BlockOptions {
pub difficulty: U256,
pub bloom: Bloom,
pub transactions: Vec<SignedTransaction>,
}
impl Default for BlockOptions {
fn default() -> Self {
BlockOptions {
difficulty: 10.into(),
bloom: Bloom::default(),
transactions: Vec::new(),
}
}
}
#[derive(Clone)]
pub struct BlockBuilder {
blocks: VecDeque<Block>,
}
impl BlockBuilder {
pub fn genesis() -> Self {
let mut blocks = VecDeque::with_capacity(1);
blocks.push_back(Block::default());
BlockBuilder {
blocks,
}
}
#[inline]
pub fn add_block(&self) -> Self {
self.add_block_with(|| BlockOptions::default())
}
#[inline]
pub fn add_blocks(&self, count: usize) -> Self {
self.add_blocks_with(count, || BlockOptions::default())
}
#[inline]
pub fn add_block_with<T>(&self, get_metadata: T) -> Self where T: Fn() -> BlockOptions {
self.add_blocks_with(1, get_metadata)
}
#[inline]
pub fn add_block_with_difficulty<T>(&self, difficulty: T) -> Self where T: Into<U256> {
let difficulty = difficulty.into();
self.add_blocks_with(1, move || BlockOptions {
difficulty,
..Default::default()
})
}
#[inline]
pub fn add_block_with_transactions<T>(&self, transactions: T) -> Self
where T: IntoIterator<Item = SignedTransaction> {
let transactions = transactions.into_iter().collect::<Vec<_>>();
self.add_blocks_with(1, || BlockOptions {
transactions: transactions.clone(),
..Default::default()
})
}
#[inline]
pub fn add_block_with_bloom(&self, bloom: Bloom) -> Self {
self.add_blocks_with(1, move || BlockOptions {
bloom,
..Default::default()
})
}
pub fn add_blocks_with<T>(&self, count: usize, get_metadata: T) -> Self where T: Fn() -> BlockOptions {
assert!(count > 0, "There must be at least 1 block");
let mut parent_hash = self.last().hash();
let mut parent_number = self.last().number();
let mut blocks = VecDeque::with_capacity(count);
for _ in 0..count {
let mut block = Block::default();
let metadata = get_metadata();
let block_number = parent_number + 1;
block.header.set_parent_hash(parent_hash);
block.header.set_number(block_number);
block.header.set_log_bloom(metadata.bloom);
block.header.set_difficulty(metadata.difficulty);
block.transactions = metadata.transactions;
parent_hash = block.hash();
parent_number = block_number;
blocks.push_back(block);
}
BlockBuilder {
blocks,
}
}
#[inline]
pub fn last(&self) -> &Block {
self.blocks.back().expect("There is always at least 1 block")
}
}
#[derive(Clone)]
pub struct BlockGenerator {
builders: VecDeque<BlockBuilder>,
}
impl BlockGenerator {
pub fn new<T>(builders: T) -> Self where T: IntoIterator<Item = BlockBuilder> {
BlockGenerator {
builders: builders.into_iter().collect(),
}
}
}
impl Iterator for BlockGenerator {
type Item = Block;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.builders.front_mut() {
Some(ref mut builder) => {
if let Some(block) = builder.blocks.pop_front() {
return Some(block);
}
},
None => return None,
}
self.builders.pop_front();
}
}
}
#[cfg(test)]
mod tests {
use super::{BlockBuilder, BlockOptions, BlockGenerator};
#[test]
fn test_block_builder() {
let genesis = BlockBuilder::genesis();
let block_1 = genesis.add_block();
let block_1001 = block_1.add_blocks(1000);
let block_1002 = block_1001.add_block_with(|| BlockOptions::default());
let generator = BlockGenerator::new(vec![genesis, block_1, block_1001, block_1002]);
assert_eq!(generator.count(), 1003);
}
#[test]
fn test_block_builder_fork() {
let genesis = BlockBuilder::genesis();
let block_10a = genesis.add_blocks(10);
let block_11b = genesis.add_blocks(11);
assert_eq!(block_10a.last().number(), 10);
assert_eq!(block_11b.last().number(), 11);
}
}

View File

@@ -1,72 +0,0 @@
// Copyright 2015-2017 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 rlp::*;
use bigint::hash::{H256, H2048};
use bytes::Bytes;
use header::Header;
use transaction::SignedTransaction;
use super::fork::Forkable;
use super::bloom::WithBloom;
use super::complete::CompleteBlock;
use super::transaction::WithTransaction;
/// Helper structure, used for encoding blocks.
#[derive(Default)]
pub struct Block {
pub header: Header,
pub transactions: Vec<SignedTransaction>,
pub uncles: Vec<Header>
}
impl Encodable for Block {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(3);
s.append(&self.header);
s.append_list(&self.transactions);
s.append_list(&self.uncles);
}
}
impl Forkable for Block {
fn fork(mut self, fork_number: usize) -> Self where Self: Sized {
let difficulty = self.header.difficulty().clone() - fork_number.into();
self.header.set_difficulty(difficulty);
self
}
}
impl WithBloom for Block {
fn with_bloom(mut self, bloom: H2048) -> Self where Self: Sized {
self.header.set_log_bloom(bloom);
self
}
}
impl WithTransaction for Block {
fn with_transaction(mut self, transaction: SignedTransaction) -> Self where Self: Sized {
self.transactions.push(transaction);
self
}
}
impl CompleteBlock for Block {
fn complete(mut self, parent_hash: H256) -> Bytes {
self.header.set_parent_hash(parent_hash);
encode(&self).into_vec()
}
}

View File

@@ -1,35 +0,0 @@
// Copyright 2015-2017 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 bigint::hash::H2048;
pub trait WithBloom {
fn with_bloom(self, bloom: H2048) -> Self where Self: Sized;
}
pub struct Bloom<'a, I> where I: 'a {
pub iter: &'a mut I,
pub bloom: H2048,
}
impl<'a, I> Iterator for Bloom<'a, I> where I: Iterator, <I as Iterator>::Item: WithBloom {
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|item| item.with_bloom(self.bloom.clone()))
}
}

View File

@@ -1,52 +0,0 @@
// Copyright 2015-2017 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 bigint::hash::H256;
use bytes::Bytes;
use views::BlockView;
#[derive(Default, Clone)]
pub struct BlockFinalizer {
parent_hash: H256
}
impl BlockFinalizer {
pub fn fork(&self) -> Self {
self.clone()
}
}
pub trait CompleteBlock {
fn complete(self, parent_hash: H256) -> Bytes;
}
pub struct Complete<'a, I> where I: 'a {
pub iter: &'a mut I,
pub finalizer: &'a mut BlockFinalizer,
}
impl<'a, I> Iterator for Complete<'a, I> where I: Iterator, <I as Iterator>::Item: CompleteBlock {
type Item = Bytes;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|item| {
let rlp = item.complete(self.finalizer.parent_hash.clone());
self.finalizer.parent_hash = BlockView::new(&rlp).header_view().hash();
rlp
})
}
}

View File

@@ -1,42 +0,0 @@
// Copyright 2015-2017 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/>.
pub trait Forkable {
fn fork(self, fork_number: usize) -> Self where Self: Sized;
}
pub struct Fork<I> {
pub iter: I,
pub fork_number: usize,
}
impl<I> Clone for Fork<I> where I: Iterator + Clone {
fn clone(&self) -> Self {
Fork {
iter: self.iter.clone(),
fork_number: self.fork_number
}
}
}
impl<I> Iterator for Fork<I> where I: Iterator, <I as Iterator>::Item: Forkable {
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|item| item.fork(self.fork_number))
}
}

View File

@@ -1,179 +0,0 @@
// Copyright 2015-2017 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 bigint::prelude::U256;
use bigint::hash::H2048;
use bytes::Bytes;
use header::BlockNumber;
use transaction::SignedTransaction;
use super::fork::Fork;
use super::bloom::Bloom;
use super::complete::{BlockFinalizer, CompleteBlock, Complete};
use super::block::Block;
use super::transaction::Transaction;
/// Chain iterator interface.
pub trait ChainIterator: Iterator + Sized {
/// Should be called to create a fork of current iterator.
/// Blocks generated by fork will have lower difficulty than current chain.
fn fork(&self, fork_number: usize) -> Fork<Self> where Self: Clone;
/// Should be called to make every consecutive block have given bloom.
fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self>;
/// Should be called to make every consecutive block have given transaction.
fn with_transaction(&mut self, transaction: SignedTransaction) -> Transaction<Self>;
/// Should be called to complete block. Without complete, block may have incorrect hash.
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self>;
/// Completes and generates block.
fn generate<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Option<Bytes> where Self::Item: CompleteBlock;
}
impl<I> ChainIterator for I where I: Iterator + Sized {
fn fork(&self, fork_number: usize) -> Fork<Self> where I: Clone {
Fork {
iter: self.clone(),
fork_number: fork_number
}
}
fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self> {
Bloom {
iter: self,
bloom: bloom
}
}
fn with_transaction(&mut self, transaction: SignedTransaction) -> Transaction<Self> {
Transaction {
iter: self,
transaction: transaction,
}
}
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self> {
Complete {
iter: self,
finalizer: finalizer
}
}
fn generate<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Option<Bytes> where <I as Iterator>::Item: CompleteBlock {
self.complete(finalizer).next()
}
}
/// Blockchain generator.
#[derive(Clone)]
pub struct ChainGenerator {
/// Next block number.
number: BlockNumber,
/// Next block difficulty.
difficulty: U256,
}
impl ChainGenerator {
fn prepare_block(&self) -> Block {
let mut block = Block::default();
block.header.set_number(self.number);
block.header.set_difficulty(self.difficulty);
block
}
}
impl Default for ChainGenerator {
fn default() -> Self {
ChainGenerator {
number: 0,
difficulty: 1000.into(),
}
}
}
impl Iterator for ChainGenerator {
type Item = Block;
fn next(&mut self) -> Option<Self::Item> {
let block = self.prepare_block();
self.number += 1;
Some(block)
}
}
mod tests {
use bigint::hash::{H256, H2048};
use views::BlockView;
use blockchain::generator::{ChainIterator, ChainGenerator, BlockFinalizer};
#[test]
fn canon_chain_generator() {
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
let genesis_rlp = canon_chain.generate(&mut finalizer).unwrap();
let genesis = BlockView::new(&genesis_rlp);
assert_eq!(genesis.header_view().parent_hash(), H256::default());
assert_eq!(genesis.header_view().number(), 0);
let b1_rlp = canon_chain.generate(&mut finalizer).unwrap();
let b1 = BlockView::new(&b1_rlp);
assert_eq!(b1.header_view().parent_hash(), genesis.header_view().hash());
assert_eq!(b1.header_view().number(), 1);
let mut fork_chain = canon_chain.fork(1);
let b2_rlp_fork = fork_chain.generate(&mut finalizer.fork()).unwrap();
let b2_fork = BlockView::new(&b2_rlp_fork);
assert_eq!(b2_fork.header_view().parent_hash(), b1.header_view().hash());
assert_eq!(b2_fork.header_view().number(), 2);
let b2_rlp = canon_chain.generate(&mut finalizer).unwrap();
let b2 = BlockView::new(&b2_rlp);
assert_eq!(b2.header_view().parent_hash(), b1.header_view().hash());
assert_eq!(b2.header_view().number(), 2);
assert!(b2.header_view().difficulty() > b2_fork.header_view().difficulty());
}
#[test]
fn with_bloom_generator() {
let bloom = H2048([0x1; 256]);
let mut gen = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
let block0_rlp = gen.with_bloom(bloom).generate(&mut finalizer).unwrap();
let block1_rlp = gen.generate(&mut finalizer).unwrap();
let block0 = BlockView::new(&block0_rlp);
let block1 = BlockView::new(&block1_rlp);
assert_eq!(block0.header_view().number(), 0);
assert_eq!(block0.header_view().parent_hash(), H256::default());
assert_eq!(block1.header_view().number(), 1);
assert_eq!(block1.header_view().parent_hash(), block0.header_view().hash());
}
#[test]
fn generate_1000_blocks() {
let generator = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
let blocks: Vec<_> = generator.take(1000).complete(&mut finalizer).collect();
assert_eq!(blocks.len(), 1000);
}
}

View File

@@ -1,27 +0,0 @@
// Copyright 2015-2017 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/>.
//! Blockchain generator for tests.
mod bloom;
mod block;
mod complete;
mod fork;
pub mod generator;
mod transaction;
pub use self::complete::BlockFinalizer;
pub use self::generator::{ChainIterator, ChainGenerator};

View File

@@ -1,35 +0,0 @@
// Copyright 2015-2017 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 transaction::SignedTransaction;
pub trait WithTransaction {
fn with_transaction(self, transaction: SignedTransaction) -> Self where Self: Sized;
}
pub struct Transaction<'a, I> where I: 'a {
pub iter: &'a mut I,
pub transaction: SignedTransaction,
}
impl <'a, I> Iterator for Transaction<'a, I> where I: Iterator, <I as Iterator>::Item: WithTransaction {
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|item| item.with_transaction(self.transaction.clone()))
}
}

View File

@@ -2,8 +2,8 @@ use std::collections::HashMap;
use bigint::hash::H256;
use header::BlockNumber;
use blockchain::block_info::BlockInfo;
use blooms::BloomGroup;
use super::extras::{BlockDetails, BlockReceipts, TransactionAddress, LogGroupPosition};
use blockchain::extras::{BlockDetails, BlockReceipts, TransactionAddress};
use blooms::{BloomGroup, GroupPosition};
/// Block extras update info.
pub struct ExtrasUpdate<'a> {
@@ -20,7 +20,7 @@ pub struct ExtrasUpdate<'a> {
/// Modified block receipts.
pub block_receipts: HashMap<H256, BlockReceipts>,
/// Modified blocks blooms.
pub blocks_blooms: HashMap<LogGroupPosition, BloomGroup>,
pub blocks_blooms: HashMap<GroupPosition, BloomGroup>,
/// Modified transaction addresses (None signifies removed transactions).
pub transactions_addresses: HashMap<H256, Option<TransactionAddress>>,
}

View File

@@ -28,13 +28,6 @@ impl From<LogBloom> for Bloom {
}
}
impl From<bc::Bloom> for Bloom {
fn from(bloom: bc::Bloom) -> Self {
let bytes: [u8; 256] = bloom.into();
Bloom(LogBloom::from(bytes))
}
}
impl Into<bc::Bloom> for Bloom {
fn into(self) -> bc::Bloom {
let log = self.0;

View File

@@ -15,58 +15,39 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain::group as bc;
use rlp::*;
use bloomchain::{Bloom, BloomCompat};
use heapsize::HeapSizeOf;
use super::Bloom;
/// Represents group of X consecutive blooms.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct BloomGroup {
blooms: Vec<Bloom>,
}
impl BloomGroup {
pub fn accrue_bloom_group(&mut self, group: &BloomGroup) {
for (bloom, other) in self.blooms.iter_mut().zip(group.blooms.iter()) {
bloom.accrue_bloom(other);
}
}
}
impl From<bc::BloomGroup> for BloomGroup {
fn from(group: bc::BloomGroup) -> Self {
let blooms = group.blooms
.into_iter()
.map(From::from)
.collect();
BloomGroup {
blooms: blooms
blooms: group.blooms
}
}
}
impl Into<bc::BloomGroup> for BloomGroup {
fn into(self) -> bc::BloomGroup {
let blooms = self.blooms
.into_iter()
.map(Into::into)
.collect();
bc::BloomGroup {
blooms: blooms
blooms: self.blooms
}
}
}
impl Decodable for BloomGroup {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
let blooms = rlp.as_list()?;
let group = BloomGroup {
blooms: blooms
};
Ok(group)
}
}
impl Encodable for BloomGroup {
fn rlp_append(&self, s: &mut RlpStream) {
s.append_list(&self.blooms);
}
}
impl HeapSizeOf for BloomGroup {
fn heap_size_of_children(&self) -> usize {
self.blooms.heap_size_of_children()

View File

@@ -29,7 +29,7 @@ use error::{BlockError, Error};
use header::{Header, BlockNumber};
use engines::{self, Engine};
use ethjson;
use rlp::{self, UntrustedRlp};
use rlp::UntrustedRlp;
use machine::EthereumMachine;
use semantic_version::SemanticVersion;
@@ -41,6 +41,38 @@ const MAX_SNAPSHOT_BLOCKS: u64 = 30000;
const DEFAULT_EIP649_DELAY: u64 = 3_000_000;
/// Ethash specific seal
#[derive(Debug, PartialEq)]
pub struct Seal {
/// Ethash seal mix_hash
pub mix_hash: H256,
/// Ethash seal nonce
pub nonce: H64,
}
impl Seal {
/// Tries to parse rlp as ethash seal.
pub fn parse_seal<T: AsRef<[u8]>>(seal: &[T]) -> Result<Self, Error> {
if seal.len() != 2 {
return Err(BlockError::InvalidSealArity(
Mismatch {
expected: 2,
found: seal.len()
}
).into());
}
let mix_hash = UntrustedRlp::new(seal[0].as_ref()).as_val::<H256>()?;
let nonce = UntrustedRlp::new(seal[1].as_ref()).as_val::<H64>()?;
let seal = Seal {
mix_hash,
nonce,
};
Ok(seal)
}
}
/// Ethash params.
#[derive(Debug, PartialEq)]
pub struct EthashParams {
@@ -177,13 +209,12 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, header: &Header) -> BTreeMap<String, String> {
if header.seal().len() == self.seal_fields() {
map![
"nonce".to_owned() => format!("0x{}", header.nonce().hex()),
"mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())
]
} else {
BTreeMap::default()
match Seal::parse_seal(header.seal()) {
Ok(seal) => map![
"nonce".to_owned() => format!("0x{}", seal.nonce.hex()),
"mixHash".to_owned() => format!("0x{}", seal.mix_hash.hex())
],
_ => BTreeMap::default()
}
}
@@ -269,13 +300,7 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
fn verify_block_basic(&self, header: &Header) -> Result<(), Error> {
// check the seal fields.
if header.seal().len() != self.seal_fields() {
return Err(From::from(BlockError::InvalidSealArity(
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
)));
}
UntrustedRlp::new(&header.seal()[0]).as_val::<H256>()?;
UntrustedRlp::new(&header.seal()[1]).as_val::<H64>()?;
let seal = Seal::parse_seal(header.seal())?;
// TODO: consider removing these lines.
let min_difficulty = self.ethash_params.minimum_difficulty;
@@ -285,9 +310,10 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
let difficulty = Ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
&header.bare_hash().0,
header.nonce().low_u64(),
&header.mix_hash().0
seal.nonce.low_u64(),
&seal.mix_hash.0
)));
if &difficulty < header.difficulty() {
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
}
@@ -300,17 +326,20 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
}
fn verify_block_unordered(&self, header: &Header) -> Result<(), Error> {
if header.seal().len() != self.seal_fields() {
return Err(From::from(BlockError::InvalidSealArity(
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
)));
}
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, header.nonce().low_u64());
let seal = Seal::parse_seal(header.seal())?;
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, seal.nonce.low_u64());
let mix = H256(result.mix_hash);
let difficulty = Ethash::boundary_to_difficulty(&H256(result.value));
trace!(target: "miner", "num: {}, seed: {}, h: {}, non: {}, mix: {}, res: {}" , header.number() as u64, H256(slow_hash_block_number(header.number() as u64)), header.bare_hash(), header.nonce().low_u64(), H256(result.mix_hash), H256(result.value));
if mix != header.mix_hash() {
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: header.mix_hash() })));
trace!(target: "miner", "num: {num}, seed: {seed}, h: {h}, non: {non}, mix: {mix}, res: {res}",
num = header.number() as u64,
seed = H256(slow_hash_block_number(header.number() as u64)),
h = header.bare_hash(),
non = seal.nonce.low_u64(),
mix = H256(result.mix_hash),
res = H256(result.value));
if mix != seal.mix_hash {
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: seal.mix_hash })));
}
if &difficulty < header.difficulty() {
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
@@ -441,18 +470,6 @@ impl Ethash {
}
}
impl Header {
/// Get the nonce field of the header.
pub fn nonce(&self) -> H64 {
rlp::decode(&self.seal()[1])
}
/// Get the mix hash field of the header.
pub fn mix_hash(&self) -> H256 {
rlp::decode(&self.seal()[0])
}
}
fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u64) -> (u64, U256) {
let eras = if block_number != 0 && block_number % era_rounds == 0 {
block_number / era_rounds - 1
@@ -637,7 +654,7 @@ mod tests {
#[test]
fn can_do_seal_unordered_verification_fail() {
let engine = test_spec().engine;
let header: Header = Header::default();
let header = Header::default();
let verify_result = engine.verify_block_unordered(&header);
@@ -648,6 +665,17 @@ mod tests {
}
}
#[test]
fn can_do_seal_unordered_verification_fail2() {
let engine = test_spec().engine;
let mut header = Header::default();
header.set_seal(vec![vec![], vec![]]);
let verify_result = engine.verify_block_unordered(&header);
// rlp error, shouldn't panic
assert!(verify_result.is_err());
}
#[test]
fn can_do_seal256_verification_fail() {
let engine = test_spec().engine;

View File

@@ -155,8 +155,8 @@ pub mod verification;
pub mod views;
mod cache_manager;
mod blooms;
mod basic_types;
mod blooms;
mod pod_account;
mod state_db;
mod account_db;

View File

@@ -264,15 +264,9 @@ impl EthereumMachine {
} else if block_number < ext.eip150_transition {
Schedule::new_homestead()
} else {
// There's no max_code_size transition so we tie it to eip161abc
let max_code_size = if block_number >= ext.eip161abc_transition {
self.params.max_code_size as usize
} else {
usize::max_value()
};
let max_code_size = self.params.max_code_size(block_number);
let mut schedule = Schedule::new_post_eip150(
max_code_size,
max_code_size as _,
block_number >= ext.eip160_transition,
block_number >= ext.eip161abc_transition,
block_number >= ext.eip161d_transition

View File

@@ -57,6 +57,8 @@ pub enum Error {
VersionNotSupported(u64),
/// Max chunk size is to small to fit basic account data.
ChunkTooSmall,
/// Oversized chunk
ChunkTooLarge,
/// Snapshots not supported by the consensus engine.
SnapshotsUnsupported,
/// Bad epoch transition.
@@ -85,6 +87,7 @@ impl fmt::Display for Error {
Error::Trie(ref err) => err.fmt(f),
Error::VersionNotSupported(ref ver) => write!(f, "Snapshot version {} is not supprted.", ver),
Error::ChunkTooSmall => write!(f, "Chunk size is too small."),
Error::ChunkTooLarge => write!(f, "Chunk size is too large."),
Error::SnapshotsUnsupported => write!(f, "Snapshots unsupported by consensus engine."),
Error::BadEpochProof(i) => write!(f, "Bad epoch proof for transition to epoch {}", i),
Error::WrongChunkFormat(ref msg) => write!(f, "Wrong chunk format: {}", msg),

View File

@@ -77,6 +77,11 @@ mod traits;
// Try to have chunks be around 4MB (before compression)
const PREFERRED_CHUNK_SIZE: usize = 4 * 1024 * 1024;
// Maximal chunk size (decompressed)
// Snappy::decompressed_len estimation may sometimes yield results greater
// than PREFERRED_CHUNK_SIZE so allow some threshold here.
const MAX_CHUNK_SIZE: usize = PREFERRED_CHUNK_SIZE / 4 * 5;
// Minimum supported state chunk version.
const MIN_SUPPORTED_STATE_CHUNK_VERSION: u64 = 1;
// current state chunk version.

View File

@@ -23,7 +23,7 @@ use std::path::PathBuf;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService};
use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE};
use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter};
use blockchain::BlockChain;
@@ -130,6 +130,11 @@ impl Restoration {
// feeds a state chunk, aborts early if `flag` becomes false.
fn feed_state(&mut self, hash: H256, chunk: &[u8], flag: &AtomicBool) -> Result<(), Error> {
if self.state_chunks_left.contains(&hash) {
let expected_len = snappy::decompressed_len(chunk)?;
if expected_len > MAX_CHUNK_SIZE {
trace!(target: "snapshot", "Discarding large chunk: {} vs {}", expected_len, MAX_CHUNK_SIZE);
return Err(::snapshot::Error::ChunkTooLarge.into());
}
let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?;
self.state.feed(&self.snappy_buffer[..len], flag)?;
@@ -147,6 +152,11 @@ impl Restoration {
// feeds a block chunk
fn feed_blocks(&mut self, hash: H256, chunk: &[u8], engine: &EthEngine, flag: &AtomicBool) -> Result<(), Error> {
if self.block_chunks_left.contains(&hash) {
let expected_len = snappy::decompressed_len(chunk)?;
if expected_len > MAX_CHUNK_SIZE {
trace!(target: "snapshot", "Discarding large chunk: {} vs {}", expected_len, MAX_CHUNK_SIZE);
return Err(::snapshot::Error::ChunkTooLarge.into());
}
let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?;
self.secondary.feed(&self.snappy_buffer[..len], engine, flag)?;

View File

@@ -19,7 +19,7 @@
use devtools::RandomTempPath;
use error::Error;
use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer};
use blockchain::generator::{BlockGenerator, BlockBuilder};
use blockchain::BlockChain;
use snapshot::{chunk_secondary, Error as SnapshotError, Progress, SnapshotComponents};
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
@@ -35,9 +35,10 @@ use std::sync::atomic::AtomicBool;
const SNAPSHOT_MODE: ::snapshot::PowSnapshot = ::snapshot::PowSnapshot { blocks: 30000, max_restore_blocks: 30000 };
fn chunk_and_restore(amount: u64) {
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
let genesis = canon_chain.generate(&mut finalizer).unwrap();
let genesis = BlockBuilder::genesis();
let rest = genesis.add_blocks(amount as usize);
let generator = BlockGenerator::new(vec![rest]);
let genesis = genesis.last();
let engine = ::spec::Spec::new_test().engine;
let new_path = RandomTempPath::create_dir();
@@ -45,13 +46,12 @@ fn chunk_and_restore(amount: u64) {
snapshot_path.push("SNAP");
let old_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());
let bc = BlockChain::new(Default::default(), &genesis.encoded(), old_db.clone());
// build the blockchain.
let mut batch = DBTransaction::new();
for _ in 0..amount {
let block = canon_chain.generate(&mut finalizer).unwrap();
bc.insert_block(&mut batch, &block, vec![]);
for block in generator {
bc.insert_block(&mut batch, &block.encoded(), vec![]);
bc.commit();
}
@@ -82,7 +82,7 @@ fn chunk_and_restore(amount: u64) {
// restore it.
let new_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone());
let new_chain = BlockChain::new(Default::default(), &genesis.encoded(), new_db.clone());
let mut rebuilder = SNAPSHOT_MODE.rebuilder(new_chain, new_db.clone(), &manifest).unwrap();
let reader = PackedReader::new(&snapshot_path).unwrap().unwrap();
@@ -97,15 +97,19 @@ fn chunk_and_restore(amount: u64) {
drop(rebuilder);
// and test it.
let new_chain = BlockChain::new(Default::default(), &genesis, new_db);
let new_chain = BlockChain::new(Default::default(), &genesis.encoded(), new_db);
assert_eq!(new_chain.best_block_hash(), best_hash);
}
#[test]
fn chunk_and_restore_500() { chunk_and_restore(500) }
fn chunk_and_restore_500() {
chunk_and_restore(500)
}
#[test]
fn chunk_and_restore_40k() { chunk_and_restore(40000) }
fn chunk_and_restore_4k() {
chunk_and_restore(4000)
}
#[test]
fn checks_flag() {
@@ -120,17 +124,12 @@ fn checks_flag() {
stream.append_empty_data().append_empty_data();
let genesis = {
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
canon_chain.generate(&mut finalizer).unwrap()
};
let genesis = BlockBuilder::genesis();
let chunk = stream.out();
let db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
let engine = ::spec::Spec::new_test().engine;
let chain = BlockChain::new(Default::default(), &genesis, db.clone());
let chain = BlockChain::new(Default::default(), &genesis.last().encoded(), db.clone());
let manifest = ::snapshot::ManifestData {
version: 2,

View File

@@ -120,6 +120,8 @@ pub struct CommonParams {
pub node_permission_contract: Option<Address>,
/// Maximum contract code size that can be deployed.
pub max_code_size: u64,
/// Number of first block where max code size limit is active.
pub max_code_size_transition: BlockNumber,
/// Transaction permission managing contract address.
pub transaction_permission_contract: Option<Address>,
}
@@ -127,11 +129,20 @@ pub struct CommonParams {
impl CommonParams {
/// Schedule for an EVM in the post-EIP-150-era of the Ethereum main net.
pub fn schedule(&self, block_number: u64) -> ::vm::Schedule {
let mut schedule = ::vm::Schedule::new_post_eip150(self.max_code_size as _, true, true, true);
let mut schedule = ::vm::Schedule::new_post_eip150(self.max_code_size(block_number) as _, true, true, true);
self.update_schedule(block_number, &mut schedule);
schedule
}
/// Returns max code size at given block.
pub fn max_code_size(&self, block_number: u64) -> u64 {
if block_number >= self.max_code_size_transition {
self.max_code_size
} else {
u64::max_value()
}
}
/// Apply common spec config parameters to the schedule.
pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) {
schedule.have_create2 = block_number >= self.eip86_transition;
@@ -228,6 +239,7 @@ impl From<ethjson::spec::Params> for CommonParams {
registrar: p.registrar.map_or_else(Address::new, Into::into),
node_permission_contract: p.node_permission_contract.map(Into::into),
max_code_size: p.max_code_size.map_or(u64::max_value(), Into::into),
max_code_size_transition: p.max_code_size_transition.map_or(0, Into::into),
transaction_permission_contract: p.transaction_permission_contract.map(Into::into),
wasm_activation_transition: p.wasm_activation_transition.map_or(
BlockNumber::max_value(),

View File

@@ -1,77 +0,0 @@
use bloomchain::Bloom;
use bloomchain::group::{BloomGroup, GroupPosition};
use basic_types::LogBloom;
/// Helper structure representing bloom of the trace.
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct BlockTracesBloom(LogBloom);
impl From<LogBloom> for BlockTracesBloom {
fn from(bloom: LogBloom) -> BlockTracesBloom {
BlockTracesBloom(bloom)
}
}
impl From<Bloom> for BlockTracesBloom {
fn from(bloom: Bloom) -> BlockTracesBloom {
let bytes: [u8; 256] = bloom.into();
BlockTracesBloom(LogBloom::from(bytes))
}
}
impl Into<Bloom> for BlockTracesBloom {
fn into(self) -> Bloom {
let log = self.0;
Bloom::from(log.0)
}
}
/// Represents group of X consecutive blooms.
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct BlockTracesBloomGroup {
blooms: Vec<BlockTracesBloom>,
}
impl From<BloomGroup> for BlockTracesBloomGroup {
fn from(group: BloomGroup) -> Self {
let blooms = group.blooms
.into_iter()
.map(From::from)
.collect();
BlockTracesBloomGroup {
blooms: blooms
}
}
}
impl Into<BloomGroup> for BlockTracesBloomGroup {
fn into(self) -> BloomGroup {
let blooms = self.blooms
.into_iter()
.map(Into::into)
.collect();
BloomGroup {
blooms: blooms
}
}
}
/// Represents `BloomGroup` position in database.
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct TraceGroupPosition {
/// Bloom level.
pub level: u8,
/// Group index.
pub index: u32,
}
impl From<GroupPosition> for TraceGroupPosition {
fn from(p: GroupPosition) -> Self {
TraceGroupPosition {
level: p.level as u8,
index: p.index as u32,
}
}
}

View File

@@ -279,7 +279,6 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
} else {
self.traces(block_hash).expect("Traces database is incomplete.").bloom()
})
.map(blooms::Bloom::from)
.map(Into::into)
.collect();

View File

@@ -16,7 +16,6 @@
//! Tracing
mod bloom;
mod config;
mod db;
mod executive_tracer;

View File

@@ -17,12 +17,13 @@
//! Trace filters type definitions
use std::ops::Range;
use bloomchain::{Filter as BloomFilter, Bloom, Number};
use hash::keccak;
use util::Address;
use bloomable::Bloomable;
use basic_types::LogBloom;
use bloomable::Bloomable;
use bloomchain::{Filter as BloomFilter, Number, Bloom};
use hash::keccak;
use trace::flat::FlatTrace;
use util::Address;
use super::trace::{Action, Res};
/// Addresses filter.
@@ -90,9 +91,6 @@ pub struct Filter {
impl BloomFilter for Filter {
fn bloom_possibilities(&self) -> Vec<Bloom> {
self.bloom_possibilities()
.into_iter()
.map(|b| Bloom::from(b.0))
.collect()
}
fn range(&self) -> Range<Number> {

View File

@@ -28,7 +28,7 @@ use client::BlockChainClient;
use engines::EthEngine;
use error::{BlockError, Error};
use header::{BlockNumber, Header};
use transaction::SignedTransaction;
use transaction::{SignedTransaction, UnverifiedTransaction};
use views::BlockView;
use bigint::hash::H256;
@@ -69,11 +69,9 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &EthEngine) ->
verify_header_params(&u, engine, false)?;
engine.verify_block_basic(&u)?;
}
// Verify transactions.
// TODO: either use transaction views or cache the decoded transactions.
let v = BlockView::new(bytes);
for t in v.transactions() {
engine.verify_transaction_basic(&t, &header)?;
for t in UntrustedRlp::new(bytes).at(1)?.iter().map(|rlp| rlp.as_val::<UnverifiedTransaction>()) {
engine.verify_transaction_basic(&t?, &header)?;
}
Ok(())
}
@@ -355,6 +353,7 @@ mod tests {
use types::log_entry::{LogEntry, LocalizedLogEntry};
use time::get_time;
use encoded;
use rlp;
fn check_ok(result: Result<(), Error>) {
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
@@ -508,6 +507,27 @@ mod tests {
Ok(())
}
#[test]
fn test_verify_block_basic_with_invalid_transactions() {
let spec = Spec::new_test();
let engine = &*spec.engine;
let block = {
let mut rlp = rlp::RlpStream::new_list(3);
let mut header = Header::default();
// that's an invalid transaction list rlp
let invalid_transactions = vec![vec![0u8]];
header.set_transactions_root(ordered_trie_root(invalid_transactions.clone()));
header.set_gas_limit(engine.params().min_gas_limit);
rlp.append(&header);
rlp.append_list::<Vec<u8>, _>(&invalid_transactions);
rlp.append_raw(&rlp::EMPTY_LIST_RLP, 1);
rlp.out()
};
assert!(basic_test(&block, engine).is_err());
}
#[test]
fn test_verify_block() {
use rlp::RlpStream;

View File

@@ -12,6 +12,7 @@ ethcore-util = { path = "../../util" }
ethcore-bigint = { path = "../../util/bigint" }
ethjson = { path = "../../json" }
bloomable = { path = "../../util/bloomable" }
ethbloom = "0.2.5"
keccak-hash = { path = "../../util/hash" }
heapsize = "0.4"

View File

@@ -17,7 +17,7 @@
//! Blockchain filter
use util::Address;
use bigint::hash::{H256, H2048};
use bigint::hash::{H256, H2048 as Bloom};
use bloomable::Bloomable;
use ids::BlockId;
use log_entry::LogEntry;
@@ -75,15 +75,15 @@ impl Clone for Filter {
impl Filter {
/// Returns combinations of each address and topic.
pub fn bloom_possibilities(&self) -> Vec<H2048> {
pub fn bloom_possibilities(&self) -> Vec<Bloom> {
let blooms = match self.address {
Some(ref addresses) if !addresses.is_empty() =>
addresses.iter().map(|ref address| {
let mut bloom = H2048::default();
let mut bloom = Bloom::default();
bloom.shift_bloomed(&keccak(address));
bloom
}).collect(),
_ => vec![H2048::default()]
_ => vec![Bloom::default()]
};
self.topics.iter().fold(blooms, |bs, topic| match *topic {
@@ -93,7 +93,7 @@ impl Filter {
let mut b = bloom.clone();
b.shift_bloomed(&keccak(topic));
b
}).collect::<Vec<H2048>>()
}).collect::<Vec<Bloom>>()
}).collect()
})
}

View File

@@ -24,6 +24,7 @@ extern crate rlp;
#[macro_use]
extern crate rlp_derive;
extern crate bloomable;
extern crate ethbloom;
extern crate keccak_hash as hash;
extern crate heapsize;

View File

@@ -119,8 +119,8 @@ pub struct Schedule {
/// Wasm cost table
pub struct WasmCosts {
/// Arena allocator cost, per byte
pub alloc: u32,
/// Default opcode cost
pub regular: u32,
/// Div operations multiplier.
pub div: u32,
/// Div operations multiplier.
@@ -135,17 +135,20 @@ pub struct WasmCosts {
pub initial_mem: u32,
/// Grow memory cost, per page (64kb)
pub grow_mem: u32,
/// Memory copy cost, per byte
pub memcpy: u32,
/// Max stack height (native WebAssembly stack limiter)
pub max_stack_height: u32,
/// Cost of wasm opcode is calculated as TABLE_ENTRY_COST * `opcodes_mul` / `opcodes_div`
pub opcodes_mul: u32,
/// Cost of wasm opcode is calculated as TABLE_ENTRY_COST * `opcodes_mul` / `opcodes_div`
pub opcodes_div: u32,
}
impl Default for WasmCosts {
fn default() -> Self {
WasmCosts {
alloc: 2,
regular: 1,
div: 16,
mul: 4,
mem: 2,
@@ -153,6 +156,8 @@ impl Default for WasmCosts {
static_address: 40,
initial_mem: 4096,
grow_mem: 8192,
memcpy: 1,
max_stack_height: 64*1024,
opcodes_mul: 3,
opcodes_div: 8,
}

View File

@@ -8,9 +8,9 @@ byteorder = "1.0"
ethcore-util = { path = "../../util" }
ethcore-bigint = { path = "../../util/bigint" }
log = "0.3"
parity-wasm = "0.23"
parity-wasm = "0.27"
libc = "0.2"
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
vm = { path = "../vm" }
ethcore-logger = { path = "../../logger" }
wasmi = { git = "https://github.com/pepyakin/wasmi" }
wasmi = { git = "https://github.com/paritytech/wasmi" }

View File

@@ -19,7 +19,7 @@
use std::cell::RefCell;
use wasmi::{
self, Signature, Error, FuncRef, FuncInstance, MemoryDescriptor,
MemoryRef, MemoryInstance,
MemoryRef, MemoryInstance, memory_units,
};
/// Internal ids all functions runtime supports. This is just a glue for wasmi interpreter
@@ -219,7 +219,10 @@ impl ImportResolver {
let mut mem_ref = self.memory.borrow_mut();
if mem_ref.is_none() {
*mem_ref = Some(
MemoryInstance::alloc(0, Some(0)).expect("Memory allocation (0, 0) should not fail; qed")
MemoryInstance::alloc(
memory_units::Pages(0),
Some(memory_units::Pages(0)),
).expect("Memory allocation (0, 0) should not fail; qed")
);
}
}
@@ -229,7 +232,7 @@ impl ImportResolver {
/// Returns memory size module initially requested
pub fn memory_size(&self) -> Result<u32, Error> {
Ok(self.memory_ref().size())
Ok(self.memory_ref().current_size().0 as u32)
}
}
@@ -281,7 +284,10 @@ impl wasmi::ModuleImportResolver for ImportResolver {
{
Err(Error::Instantiation("Module requested too much memory".to_owned()))
} else {
let mem = MemoryInstance::alloc(descriptor.initial(), descriptor.maximum())?;
let mem = MemoryInstance::alloc(
memory_units::Pages(descriptor.initial() as usize),
descriptor.maximum().map(|x| memory_units::Pages(x as usize)),
)?;
*self.memory.borrow_mut() = Some(mem.clone());
Ok(mem)
}

View File

@@ -35,7 +35,7 @@ mod panic_payload;
mod parser;
use vm::{GasLeft, ReturnData, ActionParams};
use wasmi::Error as InterpreterError;
use wasmi::{Error as InterpreterError, Trap};
use runtime::{Runtime, RuntimeContext};
@@ -43,17 +43,29 @@ use bigint::uint::U256;
/// Wrapped interpreter error
#[derive(Debug)]
pub struct Error(InterpreterError);
pub enum Error {
Interpreter(InterpreterError),
Trap(Trap),
}
impl From<InterpreterError> for Error {
fn from(e: InterpreterError) -> Self {
Error(e)
Error::Interpreter(e)
}
}
impl From<Trap> for Error {
fn from(e: Trap) -> Self {
Error::Trap(e)
}
}
impl From<Error> for vm::Error {
fn from(e: Error) -> Self {
vm::Error::Wasm(format!("Wasm runtime error: {:?}", e.0))
match e {
Error::Interpreter(e) => vm::Error::Wasm(format!("Wasm runtime error: {:?}", e)),
Error::Trap(e) => vm::Error::Wasm(format!("Wasm contract trap: {:?}", e)),
}
}
}
@@ -66,19 +78,25 @@ impl From<runtime::Error> for vm::Error {
}
}
enum ExecutionOutcome {
Suicide,
Return,
NotSpecial,
}
impl vm::Vm for WasmInterpreter {
fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
let (module, data) = parser::payload(&params, ext.schedule().wasm())?;
let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error)?;
let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error::Interpreter)?;
let instantiation_resolover = env::ImportResolver::with_limit(16);
let instantiation_resolver = env::ImportResolver::with_limit(16);
let module_instance = wasmi::ModuleInstance::new(
&loaded_module,
&wasmi::ImportsBuilder::new().with_resolver("env", &instantiation_resolover)
).map_err(Error)?;
&wasmi::ImportsBuilder::new().with_resolver("env", &instantiation_resolver)
).map_err(Error::Interpreter)?;
let adjusted_gas = params.gas * U256::from(ext.schedule().wasm().opcodes_div) /
U256::from(ext.schedule().wasm().opcodes_mul);
@@ -88,13 +106,13 @@ impl vm::Vm for WasmInterpreter {
return Err(vm::Error::Wasm("Wasm interpreter cannot run contracts with gas (wasm adjusted) >= 2^64".to_owned()));
}
let initial_memory = instantiation_resolover.memory_size().map_err(Error)?;
let initial_memory = instantiation_resolver.memory_size().map_err(Error::Interpreter)?;
trace!(target: "wasm", "Contract requested {:?} pages of initial memory", initial_memory);
let (gas_left, result) = {
let mut runtime = Runtime::with_params(
ext,
instantiation_resolover.memory_ref(),
instantiation_resolver.memory_ref(),
// cannot overflow, checked above
adjusted_gas.low_u64(),
data.to_vec(),
@@ -115,33 +133,29 @@ impl vm::Vm for WasmInterpreter {
assert!(runtime.schedule().wasm().initial_mem < 1 << 16);
runtime.charge(|s| initial_memory as u64 * s.wasm().initial_mem as u64)?;
let module_instance = module_instance.run_start(&mut runtime).map_err(Error)?;
let module_instance = module_instance.run_start(&mut runtime).map_err(Error::Trap)?;
match module_instance.invoke_export("call", &[], &mut runtime) {
Ok(_) => { },
Err(InterpreterError::Host(boxed)) => {
match boxed.downcast_ref::<runtime::Error>() {
None => {
return Err(vm::Error::Wasm("Invalid user error used in interpreter".to_owned()));
}
Some(runtime_err) => {
match *runtime_err {
runtime::Error::Suicide => {
// Suicide uses trap to break execution
}
ref any_err => {
trace!(target: "wasm", "Error executing contract: {:?}", boxed);
return Err(vm::Error::from(Error::from(InterpreterError::Host(Box::new(any_err.clone())))));
}
}
}
let invoke_result = module_instance.invoke_export("call", &[], &mut runtime);
let mut execution_outcome = ExecutionOutcome::NotSpecial;
if let Err(InterpreterError::Trap(ref trap)) = invoke_result {
if let wasmi::TrapKind::Host(ref boxed) = *trap.kind() {
let ref runtime_err = boxed.downcast_ref::<runtime::Error>()
.expect("Host errors other than runtime::Error never produced; qed");
match **runtime_err {
runtime::Error::Suicide => { execution_outcome = ExecutionOutcome::Suicide; },
runtime::Error::Return => { execution_outcome = ExecutionOutcome::Return; },
_ => {}
}
},
Err(err) => {
trace!(target: "wasm", "Error executing contract: {:?}", err);
return Err(vm::Error::from(Error::from(err)))
}
}
if let (ExecutionOutcome::NotSpecial, Err(e)) = (execution_outcome, invoke_result) {
trace!(target: "wasm", "Error executing contract: {:?}", e);
return Err(vm::Error::from(Error::from(e)));
}
(
runtime.gas_left().expect("Cannot fail since it was not updated since last charge"),
runtime.into_result(),

View File

@@ -22,14 +22,18 @@ use parity_wasm::elements::{self, Deserialize};
use parity_wasm::peek_size;
fn gas_rules(wasm_costs: &vm::WasmCosts) -> rules::Set {
rules::Set::new({
let mut vals = ::std::collections::HashMap::with_capacity(4);
vals.insert(rules::InstructionType::Load, wasm_costs.mem as u32);
vals.insert(rules::InstructionType::Store, wasm_costs.mem as u32);
vals.insert(rules::InstructionType::Div, wasm_costs.div as u32);
vals.insert(rules::InstructionType::Mul, wasm_costs.mul as u32);
vals
}).with_grow_cost(wasm_costs.grow_mem)
rules::Set::new(
wasm_costs.regular,
{
let mut vals = ::std::collections::HashMap::with_capacity(8);
vals.insert(rules::InstructionType::Load, rules::Metering::Fixed(wasm_costs.mem as u32));
vals.insert(rules::InstructionType::Store, rules::Metering::Fixed(wasm_costs.mem as u32));
vals.insert(rules::InstructionType::Div, rules::Metering::Fixed(wasm_costs.div as u32));
vals.insert(rules::InstructionType::Mul, rules::Metering::Fixed(wasm_costs.mul as u32));
vals
})
.with_grow_cost(wasm_costs.grow_mem)
.with_forbidden_floats()
}
/// Splits payload to code and data according to params.params_type, also
@@ -71,7 +75,12 @@ pub fn payload<'a>(params: &'a vm::ActionParams, wasm_costs: &vm::WasmCosts)
let contract_module = wasm_utils::inject_gas_counter(
deserialized_module,
&gas_rules(wasm_costs),
);
).map_err(|_| vm::Error::Wasm(format!("Wasm contract error: bytecode invalid")))?;
let contract_module = wasm_utils::stack_height::inject_limiter(
contract_module,
wasm_costs.max_stack_height,
).map_err(|_| vm::Error::Wasm(format!("Wasm contract error: stack limiter failure")))?;
let data = match params.params_type {
vm::ParamsType::Embedded => {

View File

@@ -20,7 +20,7 @@ use util::Address;
use bigint::prelude::U256;
use bigint::hash::H256;
use vm::{self, CallType};
use wasmi::{self, MemoryRef, RuntimeArgs, RuntimeValue, Error as InterpreterError};
use wasmi::{self, MemoryRef, RuntimeArgs, RuntimeValue, Error as InterpreterError, Trap, TrapKind};
use super::panic_payload;
pub struct RuntimeContext {
@@ -52,6 +52,8 @@ pub enum Error {
MemoryAccessViolation,
/// Native code resulted in suicide
Suicide,
/// Native code requested execution to finish
Return,
/// Suicide was requested but coudn't complete
SuicideAbort,
/// Invalid gas state inside interpreter
@@ -72,15 +74,40 @@ pub enum Error {
Other,
/// Syscall signature mismatch
InvalidSyscall,
/// Unreachable instruction encountered
Unreachable,
/// Invalid virtual call
InvalidVirtualCall,
/// Division by zero
DivisionByZero,
/// Invalid conversion to integer
InvalidConversionToInt,
/// Stack overflow
StackOverflow,
/// Panic with message
Panic(String),
}
impl wasmi::HostError for Error { }
impl From<Trap> for Error {
fn from(trap: Trap) -> Self {
match *trap.kind() {
TrapKind::Unreachable => Error::Unreachable,
TrapKind::MemoryAccessOutOfBounds => Error::MemoryAccessViolation,
TrapKind::TableAccessOutOfBounds | TrapKind::ElemUninitialized => Error::InvalidVirtualCall,
TrapKind::DivisionByZero => Error::DivisionByZero,
TrapKind::InvalidConversionToInt => Error::InvalidConversionToInt,
TrapKind::UnexpectedSignature => Error::InvalidVirtualCall,
TrapKind::StackOverflow => Error::StackOverflow,
TrapKind::Host(_) => Error::Other,
}
}
}
impl From<InterpreterError> for Error {
fn from(interpreter_err: InterpreterError) -> Self {
match interpreter_err {
fn from(err: InterpreterError) -> Self {
match err {
InterpreterError::Value(_) => Error::InvalidSyscall,
InterpreterError::Memory(_) => Error::MemoryAccessViolation,
_ => Error::Other,
@@ -98,6 +125,7 @@ impl ::std::fmt::Display for Error {
Error::InvalidGasState => write!(f, "Invalid gas state"),
Error::BalanceQueryError => write!(f, "Balance query resulted in an error"),
Error::Suicide => write!(f, "Suicide result"),
Error::Return => write!(f, "Return result"),
Error::Unknown => write!(f, "Unknown runtime function invoked"),
Error::AllocationFailed => write!(f, "Memory allocation failed (OOM)"),
Error::BadUtf8 => write!(f, "String encoding is bad utf-8 sequence"),
@@ -105,6 +133,11 @@ impl ::std::fmt::Display for Error {
Error::Log => write!(f, "Error occured while logging an event"),
Error::InvalidSyscall => write!(f, "Invalid syscall signature encountered at runtime"),
Error::Other => write!(f, "Other unspecified error"),
Error::Unreachable => write!(f, "Unreachable instruction encountered"),
Error::InvalidVirtualCall => write!(f, "Invalid virtual call"),
Error::DivisionByZero => write!(f, "Division by zero"),
Error::StackOverflow => write!(f, "Stack overflow"),
Error::InvalidConversionToInt => write!(f, "Invalid conversion to integer"),
Error::Panic(ref msg) => write!(f, "Panic: {}", msg),
}
}
@@ -161,12 +194,14 @@ impl<'a> Runtime<'a> {
/// Intuition about the return value sense is to aswer the question 'are we allowed to continue?'
fn charge_gas(&mut self, amount: u64) -> bool {
let prev = self.gas_counter;
if prev + amount > self.gas_limit {
// exceeds gas
false
} else {
self.gas_counter = prev + amount;
true
match prev.checked_add(amount) {
// gas charge overflow protection
None => false,
Some(val) if val > self.gas_limit => false,
Some(_) => {
self.gas_counter = prev + amount;
true
}
}
}
@@ -220,8 +255,8 @@ impl<'a> Runtime<'a> {
/// Read from the storage to wasm memory.
pub fn storage_read(&mut self, args: RuntimeArgs) -> Result<()>
{
let key = self.h256_at(args.nth(0)?)?;
let val_ptr: u32 = args.nth(1)?;
let key = self.h256_at(args.nth_checked(0)?)?;
let val_ptr: u32 = args.nth_checked(1)?;
let val = self.ext.storage_at(&key).map_err(|_| Error::StorageReadError)?;
@@ -235,8 +270,8 @@ impl<'a> Runtime<'a> {
/// Write to storage from wasm memory.
pub fn storage_write(&mut self, args: RuntimeArgs) -> Result<()>
{
let key = self.h256_at(args.nth(0)?)?;
let val_ptr: u32 = args.nth(1)?;
let key = self.h256_at(args.nth_checked(0)?)?;
let val_ptr: u32 = args.nth_checked(1)?;
let val = self.h256_at(val_ptr)?;
let former_val = self.ext.storage_at(&key).map_err(|_| Error::StorageUpdateError)?;
@@ -264,14 +299,14 @@ impl<'a> Runtime<'a> {
/// Return. Syscall takes 2 arguments - pointer in sandboxed memory where result is and
/// the length of the result.
pub fn ret(&mut self, args: RuntimeArgs) -> Result<()> {
let ptr: u32 = args.nth(0)?;
let len: u32 = args.nth(1)?;
let ptr: u32 = args.nth_checked(0)?;
let len: u32 = args.nth_checked(1)?;
trace!(target: "wasm", "Contract ret: {} bytes @ {}", len, ptr);
self.result = self.memory.get(ptr, len as usize)?;
Ok(())
Err(Error::Return)
}
/// Destroy the runtime, returning currently recorded result of the execution.
@@ -287,7 +322,7 @@ impl<'a> Runtime<'a> {
/// Report gas cost with the params passed in wasm stack
fn gas(&mut self, args: RuntimeArgs) -> Result<()> {
let amount: u32 = args.nth(0)?;
let amount: u32 = args.nth_checked(0)?;
if self.charge_gas(amount as u64) {
Ok(())
} else {
@@ -302,7 +337,10 @@ impl<'a> Runtime<'a> {
/// Write input bytes to the memory location using the passed pointer
fn fetch_input(&mut self, args: RuntimeArgs) -> Result<()> {
let ptr: u32 = args.nth(0)?;
let args_len = self.args.len() as u64;
self.charge(|s| args_len * s.wasm().memcpy as u64)?;
let ptr: u32 = args.nth_checked(0)?;
self.memory.set(ptr, &self.args[..])?;
Ok(())
}
@@ -310,8 +348,8 @@ impl<'a> Runtime<'a> {
/// User panic. Contract can invoke this when he encounters unrecoverable error.
fn panic(&mut self, args: RuntimeArgs) -> Result<()>
{
let payload_ptr: u32 = args.nth(0)?;
let payload_len: u32 = args.nth(1)?;
let payload_ptr: u32 = args.nth_checked(0)?;
let payload_len: u32 = args.nth_checked(1)?;
let raw_payload = self.memory.get(payload_ptr, payload_len as usize)?;
let payload = panic_payload::decode(&raw_payload);
@@ -345,26 +383,26 @@ impl<'a> Runtime<'a> {
{
trace!(target: "wasm", "runtime: CALL({:?})", call_type);
let gas: u64 = args.nth(0)?;
let gas: u64 = args.nth_checked(0)?;
trace!(target: "wasm", " gas: {:?}", gas);
let address = self.address_at(args.nth(1)?)?;
let address = self.address_at(args.nth_checked(1)?)?;
trace!(target: "wasm", " address: {:?}", address);
let vofs = if use_val { 1 } else { 0 };
let val = if use_val { Some(self.u256_at(args.nth(2)?)?) } else { None };
let val = if use_val { Some(self.u256_at(args.nth_checked(2)?)?) } else { None };
trace!(target: "wasm", " val: {:?}", val);
let input_ptr: u32 = args.nth(2 + vofs)?;
let input_ptr: u32 = args.nth_checked(2 + vofs)?;
trace!(target: "wasm", " input_ptr: {:?}", input_ptr);
let input_len: u32 = args.nth(3 + vofs)?;
let input_len: u32 = args.nth_checked(3 + vofs)?;
trace!(target: "wasm", " input_len: {:?}", input_len);
let result_ptr: u32 = args.nth(4 + vofs)?;
let result_ptr: u32 = args.nth_checked(4 + vofs)?;
trace!(target: "wasm", " result_ptr: {:?}", result_ptr);
let result_alloc_len: u32 = args.nth(5 + vofs)?;
let result_alloc_len: u32 = args.nth_checked(5 + vofs)?;
trace!(target: "wasm", " result_len: {:?}", result_alloc_len);
if let Some(ref val) = val {
@@ -464,7 +502,7 @@ impl<'a> Runtime<'a> {
pub fn value(&mut self, args: RuntimeArgs) -> Result<()> {
let val = self.context.value;
self.return_u256_ptr(args.nth(0)?, val)
self.return_u256_ptr(args.nth_checked(0)?, val)
}
pub fn create(&mut self, args: RuntimeArgs) -> Result<RuntimeValue>
@@ -474,13 +512,13 @@ impl<'a> Runtime<'a> {
// fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
//
trace!(target: "wasm", "runtime: CREATE");
let endowment = self.u256_at(args.nth(0)?)?;
let endowment = self.u256_at(args.nth_checked(0)?)?;
trace!(target: "wasm", " val: {:?}", endowment);
let code_ptr: u32 = args.nth(1)?;
let code_ptr: u32 = args.nth_checked(1)?;
trace!(target: "wasm", " code_ptr: {:?}", code_ptr);
let code_len: u32 = args.nth(2)?;
let code_len: u32 = args.nth_checked(2)?;
trace!(target: "wasm", " code_len: {:?}", code_len);
let result_ptr: u32 = args.nth(3)?;
let result_ptr: u32 = args.nth_checked(3)?;
trace!(target: "wasm", "result_ptr: {:?}", result_ptr);
let code = self.memory.get(code_ptr, code_len as usize)?;
@@ -522,13 +560,13 @@ impl<'a> Runtime<'a> {
fn debug(&mut self, args: RuntimeArgs) -> Result<()>
{
let msg_ptr: u32 = args.nth(0)?;
let msg_len: u32 = args.nth(1)?;
trace!(target: "wasm", "Contract debug message: {}", {
let msg_ptr: u32 = args.nth_checked(0)?;
let msg_len: u32 = args.nth_checked(1)?;
let msg = String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
.map_err(|_| Error::BadUtf8)?;
trace!(target: "wasm", "Contract debug message: {}", msg);
String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
.map_err(|_| Error::BadUtf8)?
});
Ok(())
}
@@ -536,7 +574,7 @@ impl<'a> Runtime<'a> {
/// Pass suicide to state runtime
pub fn suicide(&mut self, args: RuntimeArgs) -> Result<()>
{
let refund_address = self.address_at(args.nth(0)?)?;
let refund_address = self.address_at(args.nth_checked(0)?)?;
if self.ext.exists(&refund_address).map_err(|_| Error::SuicideAbort)? {
trace!(target: "wasm", "Suicide: refund to existing address {}", refund_address);
@@ -554,8 +592,8 @@ impl<'a> Runtime<'a> {
pub fn blockhash(&mut self, args: RuntimeArgs) -> Result<()> {
self.adjusted_charge(|schedule| schedule.blockhash_gas as u64)?;
let hash = self.ext.blockhash(&U256::from(args.nth::<u64>(0)?));
self.memory.set(args.nth(1)?, &*hash)?;
let hash = self.ext.blockhash(&U256::from(args.nth_checked::<u64>(0)?));
self.memory.set(args.nth_checked(1)?, &*hash)?;
Ok(())
}
@@ -566,32 +604,32 @@ impl<'a> Runtime<'a> {
pub fn coinbase(&mut self, args: RuntimeArgs) -> Result<()> {
let coinbase = self.ext.env_info().author;
self.return_address_ptr(args.nth(0)?, coinbase)
self.return_address_ptr(args.nth_checked(0)?, coinbase)
}
pub fn difficulty(&mut self, args: RuntimeArgs) -> Result<()> {
let difficulty = self.ext.env_info().difficulty;
self.return_u256_ptr(args.nth(0)?, difficulty)
self.return_u256_ptr(args.nth_checked(0)?, difficulty)
}
pub fn gaslimit(&mut self, args: RuntimeArgs) -> Result<()> {
let gas_limit = self.ext.env_info().gas_limit;
self.return_u256_ptr(args.nth(0)?, gas_limit)
self.return_u256_ptr(args.nth_checked(0)?, gas_limit)
}
pub fn address(&mut self, args: RuntimeArgs) -> Result<()> {
let address = self.context.address;
self.return_address_ptr(args.nth(0)?, address)
self.return_address_ptr(args.nth_checked(0)?, address)
}
pub fn sender(&mut self, args: RuntimeArgs) -> Result<()> {
let sender = self.context.sender;
self.return_address_ptr(args.nth(0)?, sender)
self.return_address_ptr(args.nth_checked(0)?, sender)
}
pub fn origin(&mut self, args: RuntimeArgs) -> Result<()> {
let origin = self.context.origin;
self.return_address_ptr(args.nth(0)?, origin)
self.return_address_ptr(args.nth_checked(0)?, origin)
}
pub fn timestamp(&mut self) -> Result<RuntimeValue> {
@@ -601,12 +639,10 @@ impl<'a> Runtime<'a> {
pub fn elog(&mut self, args: RuntimeArgs) -> Result<()>
{
// signature is:
// pub fn elog(topic_ptr: *const u8, topic_count: u32, data_ptr: *const u8, data_len: u32);
let topic_ptr: u32 = args.nth(0)?;
let topic_count: u32 = args.nth(1)?;
let data_ptr: u32 = args.nth(2)?;
let data_len: u32 = args.nth(3)?;
let topic_ptr: u32 = args.nth_checked(0)?;
let topic_count: u32 = args.nth_checked(1)?;
let data_ptr: u32 = args.nth_checked(2)?;
let data_len: u32 = args.nth_checked(3)?;
if topic_count > 4 {
return Err(Error::Log.into());
@@ -639,7 +675,7 @@ impl<'a> Runtime<'a> {
mod ext_impl {
use wasmi::{Externals, RuntimeArgs, RuntimeValue, Error};
use wasmi::{Externals, RuntimeArgs, RuntimeValue, Trap};
use env::ids::*;
macro_rules! void {
@@ -659,7 +695,7 @@ mod ext_impl {
&mut self,
index: usize,
args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Error> {
) -> Result<Option<RuntimeValue>, Trap> {
match index {
STORAGE_WRITE_FUNC => void!(self.storage_write(args)),
STORAGE_READ_FUNC => void!(self.storage_read(args)),

View File

@@ -209,7 +209,7 @@ fn dispersion() {
result,
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
);
assert_eq!(gas_left, U256::from(93_972));
assert_eq!(gas_left, U256::from(94_013));
}
#[test]
@@ -237,7 +237,7 @@ fn suicide_not() {
result,
vec![0u8]
);
assert_eq!(gas_left, U256::from(94_970));
assert_eq!(gas_left, U256::from(94_984));
}
#[test]
@@ -269,7 +269,7 @@ fn suicide() {
};
assert!(ext.suicides.contains(&refund));
assert_eq!(gas_left, U256::from(94_933));
assert_eq!(gas_left, U256::from(94_925));
}
#[test]
@@ -299,7 +299,7 @@ fn create() {
assert!(ext.calls.contains(
&FakeCall {
call_type: FakeCallType::Create,
gas: U256::from(60_917),
gas: U256::from(60_914),
sender_address: None,
receive_address: None,
value: Some(1_000_000_000.into()),
@@ -307,7 +307,7 @@ fn create() {
code_address: None,
}
));
assert_eq!(gas_left, U256::from(60_903));
assert_eq!(gas_left, U256::from(60_900));
}
#[test]
@@ -467,7 +467,7 @@ fn realloc() {
}
};
assert_eq!(result, vec![0u8; 2]);
assert_eq!(gas_left, U256::from(94_352));
assert_eq!(gas_left, U256::from(94_372));
}
#[test]
@@ -543,7 +543,7 @@ fn keccak() {
};
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
assert_eq!(gas_left, U256::from(84_223));
assert_eq!(gas_left, U256::from(84_240));
}
// math_* tests check the ability of wasm contract to perform big integer operations
@@ -572,7 +572,7 @@ fn math_add() {
U256::from_dec_str("1888888888888888888888888888887").unwrap(),
(&result[..]).into()
);
assert_eq!(gas_left, U256::from(93_818));
assert_eq!(gas_left, U256::from(93_814));
}
// multiplication
@@ -594,7 +594,7 @@ fn math_mul() {
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
(&result[..]).into()
);
assert_eq!(gas_left, U256::from(93_304));
assert_eq!(gas_left, U256::from(93_300));
}
// subtraction
@@ -616,7 +616,7 @@ fn math_sub() {
U256::from_dec_str("111111111111111111111111111111").unwrap(),
(&result[..]).into()
);
assert_eq!(gas_left, U256::from(93_831));
assert_eq!(gas_left, U256::from(93_826));
}
// subtraction with overflow
@@ -658,7 +658,7 @@ fn math_div() {
U256::from_dec_str("1125000").unwrap(),
(&result[..]).into()
);
assert_eq!(gas_left, U256::from(90_607));
assert_eq!(gas_left, U256::from(90_603));
}
#[test]
@@ -686,7 +686,7 @@ fn storage_metering() {
};
// 0 -> not 0
assert_eq!(gas_left, U256::from(74_410));
assert_eq!(gas_left, U256::from(74_338));
// #2
@@ -705,7 +705,7 @@ fn storage_metering() {
};
// not 0 -> not 0
assert_eq!(gas_left, U256::from(89_410));
assert_eq!(gas_left, U256::from(89_338));
}
// This test checks the ability of wasm contract to invoke
@@ -793,7 +793,7 @@ fn externs() {
"Gas limit requested and returned does not match"
);
assert_eq!(gas_left, U256::from(92_089));
assert_eq!(gas_left, U256::from(92_110));
}
#[test]
@@ -819,7 +819,7 @@ fn embedded_keccak() {
};
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
assert_eq!(gas_left, U256::from(84_223));
assert_eq!(gas_left, U256::from(84_240));
}
/// This test checks the correctness of log extern
@@ -854,5 +854,5 @@ fn events() {
assert_eq!(&log_entry.data, b"gnihtemos");
assert_eq!(&result, b"gnihtemos");
assert_eq!(gas_left, U256::from(81_235));
assert_eq!(gas_left, U256::from(81_292));
}

View File

@@ -9,4 +9,4 @@ tiny-keccak = "1.3"
eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
ethkey = { path = "../ethkey" }
ethcore-bigint = { path = "../util/bigint" }
subtle = "0.1"
subtle = "0.5"

View File

@@ -308,7 +308,7 @@ pub mod ecies {
hmac.raw_result(&mut mac);
// constant time compare to avoid timing attack.
if ::subtle::arrays_equal(&mac[..], msg_mac) != 1 {
if ::subtle::slices_equal(&mac[..], msg_mac) != 1 {
return Err(Error::InvalidMessage);
}

View File

@@ -22,6 +22,10 @@ ethcore-bigint = { path = "../util/bigint" }
dir = { path = "../util/dir" }
smallvec = "0.4"
parity-wordlist = "1.0"
subtle = "0.5"
tempdir = "0.3"
[dev-dependencies]
matches = "0.1"
[lib]

View File

@@ -266,7 +266,7 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
let password = load_password(&args.arg_password)?;
let account_ref = open_args_vault_account(&store, address, &args)?;
let signature = store.sign(&account_ref, &password, &message)?;
Ok(format!("0x{:?}", signature))
Ok(format!("0x{}", signature))
} else if args.cmd_public {
let address = args.arg_address.parse().map_err(|_| ethstore::Error::InvalidAccount)?;
let password = load_password(&args.arg_password)?;

View File

@@ -21,6 +21,7 @@ use crypto::Keccak256;
use random::Random;
use smallvec::SmallVec;
use account::{Cipher, Kdf, Aes128Ctr, Pbkdf2, Prf};
use subtle;
/// Encrypted data
#[derive(Debug, PartialEq, Clone)]
@@ -136,7 +137,7 @@ impl Crypto {
let mac = crypto::derive_mac(&derived_right_bits, &self.ciphertext).keccak256();
if mac != self.mac {
if subtle::slices_equal(&mac, &self.mac) == 0 {
return Err(Error::InvalidPassword);
}
@@ -158,7 +159,7 @@ impl Crypto {
#[cfg(test)]
mod tests {
use ethkey::{Generator, Random};
use super::Crypto;
use super::{Crypto, Error};
#[test]
fn crypto_with_secret_create() {
@@ -169,11 +170,10 @@ mod tests {
}
#[test]
#[should_panic]
fn crypto_with_secret_invalid_password() {
let keypair = Random.generate().unwrap();
let crypto = Crypto::with_secret(keypair.secret(), "this is sparta", 10240);
let _ = crypto.secret("this is sparta!").unwrap();
assert_matches!(crypto.secret("this is sparta!"), Err(Error::InvalidPassword))
}
#[test]

View File

@@ -28,6 +28,7 @@ extern crate rustc_hex;
extern crate serde;
extern crate serde_json;
extern crate smallvec;
extern crate subtle;
extern crate time;
extern crate tiny_keccak;
extern crate tempdir;
@@ -42,7 +43,11 @@ extern crate log;
#[macro_use]
extern crate serde_derive;
pub mod accounts_dir;
#[cfg(test)]
#[macro_use]
extern crate matches;
pub mod accounts_dir;
pub mod ethkey;
mod account;

View File

@@ -22,16 +22,21 @@ use super::{WalletInfo, KeyPath};
use bigint::hash::H256;
use ethkey::{Address, Signature};
use hidapi;
use libusb;
use parking_lot::{Mutex, RwLock};
use std::cmp::min;
use std::fmt;
use std::str::FromStr;
use std::sync::Arc;
use std::sync::{Arc, Weak};
use std::time::Duration;
use std::thread;
/// Ledger vendor ID
pub const LEDGER_VID: u16 = 0x2c97;
/// Legder product IDs: [Nano S and Blue]
pub const LEDGER_PIDS: [u16; 2] = [0x0000, 0x0001];
const LEDGER_VID: u16 = 0x2c97;
const LEDGER_PIDS: [u16; 2] = [0x0000, 0x0001]; // Nano S and Blue
const ETH_DERIVATION_PATH_BE: [u8; 17] = [4, 0x80, 0, 0, 44, 0x80, 0, 0, 60, 0x80, 0, 0, 0, 0, 0, 0, 0]; // 44'/60'/0'/0
const ETC_DERIVATION_PATH_BE: [u8; 21] = [5, 0x80, 0, 0, 44, 0x80, 0, 0, 60, 0x80, 0x02, 0x73, 0xd0, 0x80, 0, 0, 0, 0, 0, 0, 0]; // 44'/60'/160720'/0'/0
@@ -54,10 +59,14 @@ pub enum Error {
Protocol(&'static str),
/// Hidapi error.
Usb(hidapi::HidError),
/// Libusb error
LibUsb(libusb::Error),
/// Device with request key is not available.
KeyNotFound,
/// Signing has been cancelled by user.
UserCancel,
/// Invalid Device
InvalidDevice,
}
impl fmt::Display for Error {
@@ -65,8 +74,10 @@ impl fmt::Display for Error {
match *self {
Error::Protocol(ref s) => write!(f, "Ledger protocol error: {}", s),
Error::Usb(ref e) => write!(f, "USB communication error: {}", e),
Error::LibUsb(ref e) => write!(f, "LibUSB communication error: {}", e),
Error::KeyNotFound => write!(f, "Key not found"),
Error::UserCancel => write!(f, "Operation has been cancelled"),
Error::InvalidDevice => write!(f, "Unsupported product was entered"),
}
}
}
@@ -77,6 +88,12 @@ impl From<hidapi::HidError> for Error {
}
}
impl From<libusb::Error> for Error {
fn from(err: libusb::Error) -> Error {
Error::LibUsb(err)
}
}
/// Ledger device manager.
pub struct Manager {
usb: Arc<Mutex<hidapi::HidApi>>,
@@ -234,16 +251,7 @@ impl Manager {
fn open_path<R, F>(&self, f: F) -> Result<R, Error>
where F: Fn() -> Result<R, &'static str>
{
let mut err = Error::KeyNotFound;
// Try to open device a few times.
for _ in 0..10 {
match f() {
Ok(handle) => return Ok(handle),
Err(e) => err = From::from(e),
}
::std::thread::sleep(Duration::from_millis(200));
}
Err(err)
f().map_err(Into::into)
}
fn send_apdu(handle: &hidapi::HidDevice, command: u8, p1: u8, p2: u8, data: &[u8]) -> Result<Vec<u8>, Error> {
@@ -333,6 +341,54 @@ impl Manager {
message.truncate(new_len);
Ok(message)
}
fn is_valid_ledger(device: &libusb::Device) -> Result<(), Error> {
let desc = device.device_descriptor()?;
let vendor_id = desc.vendor_id();
let product_id = desc.product_id();
if vendor_id == LEDGER_VID && LEDGER_PIDS.contains(&product_id) {
Ok(())
} else {
Err(Error::InvalidDevice)
}
}
}
/// Ledger event handler
/// A seperate thread is handling incoming events
pub struct EventHandler {
ledger: Weak<Manager>,
}
impl EventHandler {
/// Ledger event handler constructor
pub fn new(ledger: Weak<Manager>) -> Self {
Self { ledger: ledger }
}
}
impl libusb::Hotplug for EventHandler {
fn device_arrived(&mut self, device: libusb::Device) {
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
debug!(target: "hw", "Ledger arrived");
// Wait for the device to boot up
thread::sleep(Duration::from_millis(1000));
if let Err(e) = ledger.update_devices() {
debug!(target: "hw", "Ledger connect error: {:?}", e);
}
}
}
fn device_left(&mut self, device: libusb::Device) {
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
debug!(target: "hw", "Ledger left");
if let Err(e) = ledger.update_devices() {
debug!(target: "hw", "Ledger disconnect error: {:?}", e);
}
}
}
}
#[test]

View File

@@ -33,13 +33,15 @@ use ethkey::{Address, Signature};
use parking_lot::Mutex;
use std::fmt;
use std::sync::{Arc, Weak};
use std::sync::Arc;
use std::sync::atomic;
use std::sync::atomic::AtomicBool;
use std::thread;
use std::time::Duration;
use bigint::prelude::uint::U256;
const USB_DEVICE_CLASS_DEVICE: u8 = 0;
/// Hardware wallet error.
#[derive(Debug)]
pub enum Error {
@@ -128,84 +130,78 @@ impl From<libusb::Error> for Error {
/// Hardware wallet management interface.
pub struct HardwareWalletManager {
update_thread: Option<thread::JoinHandle<()>>,
exiting: Arc<AtomicBool>,
ledger: Arc<ledger::Manager>,
trezor: Arc<trezor::Manager>,
}
struct EventHandler {
ledger: Weak<ledger::Manager>,
trezor: Weak<trezor::Manager>,
}
impl libusb::Hotplug for EventHandler {
fn device_arrived(&mut self, _device: libusb::Device) {
debug!("USB Device arrived");
if let (Some(l), Some(t)) = (self.ledger.upgrade(), self.trezor.upgrade()) {
for _ in 0..10 {
let l_devices = l.update_devices().unwrap_or_else(|e| {
debug!("Error enumerating Ledger devices: {}", e);
0
});
let t_devices = t.update_devices().unwrap_or_else(|e| {
debug!("Error enumerating Trezor devices: {}", e);
0
});
if l_devices + t_devices > 0 {
break;
}
thread::sleep(Duration::from_millis(200));
}
}
}
fn device_left(&mut self, _device: libusb::Device) {
debug!("USB Device lost");
if let (Some(l), Some(t)) = (self.ledger.upgrade(), self.trezor.upgrade()) {
l.update_devices().unwrap_or_else(|e| {debug!("Error enumerating Ledger devices: {}", e); 0});
t.update_devices().unwrap_or_else(|e| {debug!("Error enumerating Trezor devices: {}", e); 0});
}
}
}
impl HardwareWalletManager {
/// Hardware wallet constructor
pub fn new() -> Result<HardwareWalletManager, Error> {
let usb_context = Arc::new(libusb::Context::new()?);
let usb_context_trezor = Arc::new(libusb::Context::new()?);
let usb_context_ledger = Arc::new(libusb::Context::new()?);
let hidapi = Arc::new(Mutex::new(hidapi::HidApi::new().map_err(|e| Error::Hid(e.to_string().clone()))?));
let ledger = Arc::new(ledger::Manager::new(hidapi.clone()));
let trezor = Arc::new(trezor::Manager::new(hidapi.clone()));
usb_context.register_callback(
None, None, None,
Box::new(EventHandler {
ledger: Arc::downgrade(&ledger),
trezor: Arc::downgrade(&trezor),
}),
)?;
// Subscribe to TREZOR V1
// Note, this support only TREZOR V1 becasue TREZOR V2 has another vendorID for some reason
// Also, we now only support one product as the second argument specifies
usb_context_trezor.register_callback(
Some(trezor::TREZOR_VID), Some(trezor::TREZOR_PIDS[0]), Some(USB_DEVICE_CLASS_DEVICE),
Box::new(trezor::EventHandler::new(Arc::downgrade(&trezor))))?;
// Subscribe to all Ledger Devices
// This means that we need to check that the given productID is supported
// None => LIBUSB_HOTPLUG_MATCH_ANY, in other words that all are subscribed to
// More info can be found: http://libusb.sourceforge.net/api-1.0/group__hotplug.html#gae6c5f1add6cc754005549c7259dc35ea
usb_context_ledger.register_callback(
Some(ledger::LEDGER_VID), None, Some(USB_DEVICE_CLASS_DEVICE),
Box::new(ledger::EventHandler::new(Arc::downgrade(&ledger))))?;
let exiting = Arc::new(AtomicBool::new(false));
let thread_exiting = exiting.clone();
let thread_exiting_ledger = exiting.clone();
let thread_exiting_trezor = exiting.clone();
let l = ledger.clone();
let t = trezor.clone();
let thread = thread::Builder::new()
.name("hw_wallet".to_string())
// Ledger event thread
thread::Builder::new()
.name("hw_wallet_ledger".to_string())
.spawn(move || {
if let Err(e) = l.update_devices() {
debug!("Error updating ledger devices: {}", e);
}
if let Err(e) = t.update_devices() {
debug!("Error updating trezor devices: {}", e);
debug!(target: "hw", "Ledger couldn't connect at startup, error: {}", e);
//debug!("Ledger could not connect at startup, error: {}", e);
}
loop {
usb_context.handle_events(Some(Duration::from_millis(500)))
.unwrap_or_else(|e| debug!("Error processing USB events: {}", e));
if thread_exiting.load(atomic::Ordering::Acquire) {
usb_context_ledger.handle_events(Some(Duration::from_millis(500)))
.unwrap_or_else(|e| debug!(target: "hw", "Ledger event handler error: {}", e));
if thread_exiting_ledger.load(atomic::Ordering::Acquire) {
break;
}
}
})
.ok();
// Trezor event thread
thread::Builder::new()
.name("hw_wallet_trezor".to_string())
.spawn(move || {
if let Err(e) = t.update_devices() {
debug!(target: "hw", "Trezor couldn't connect at startup, error: {}", e);
}
loop {
usb_context_trezor.handle_events(Some(Duration::from_millis(500)))
.unwrap_or_else(|e| debug!(target: "hw", "Trezor event handler error: {}", e));
if thread_exiting_trezor.load(atomic::Ordering::Acquire) {
break;
}
}
})
.ok();
Ok(HardwareWalletManager {
update_thread: thread,
exiting: exiting,
ledger: ledger,
trezor: trezor,
@@ -259,10 +255,10 @@ impl HardwareWalletManager {
impl Drop for HardwareWalletManager {
fn drop(&mut self) {
// Indicate to the USB Hotplug handlers that they
// shall terminate but don't wait for them to terminate.
// If they don't terminate for some reason USB Hotplug events will be handled
// even if the HardwareWalletManger has been dropped
self.exiting.store(true, atomic::Ordering::Release);
if let Some(thread) = self.update_thread.take() {
thread.thread().unpark();
thread.join().ok();
}
}
}

View File

@@ -24,23 +24,26 @@ use super::{WalletInfo, TransactionInfo, KeyPath};
use bigint::hash::H256;
use ethkey::{Address, Signature};
use hidapi;
use libusb;
use parking_lot::{Mutex, RwLock};
use protobuf;
use protobuf::{Message, ProtobufEnum};
use std::cmp::{min, max};
use std::fmt;
use std::sync::Arc;
use std::sync::{Arc, Weak};
use std::time::Duration;
use bigint::prelude::uint::U256;
use trezor_sys::messages::{EthereumAddress, PinMatrixAck, MessageType, EthereumTxRequest, EthereumSignTx, EthereumGetAddress, EthereumTxAck, ButtonAck};
const TREZOR_VID: u16 = 0x534c;
const TREZOR_PIDS: [u16; 1] = [0x0001]; // Trezor v1, keeping this as an array to leave room for Trezor v2 which is in progress
/// Trezor v1 vendor ID
pub const TREZOR_VID: u16 = 0x534c;
/// Trezor product IDs
pub const TREZOR_PIDS: [u16; 1] = [0x0001];
const ETH_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003C, 0x80000000, 0, 0]; // m/44'/60'/0'/0/0
const ETC_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003D, 0x80000000, 0, 0]; // m/44'/61'/0'/0/0
/// Hardware wallet error.
#[derive(Debug)]
pub enum Error {
@@ -55,7 +58,7 @@ pub enum Error {
/// The Message Type given in the trezor RPC call is not something we recognize
BadMessageType,
/// Trying to read from a closed device at the given path
ClosedDevice(String),
LockedDevice(String),
}
impl fmt::Display for Error {
@@ -66,7 +69,7 @@ impl fmt::Display for Error {
Error::KeyNotFound => write!(f, "Key not found"),
Error::UserCancel => write!(f, "Operation has been cancelled"),
Error::BadMessageType => write!(f, "Bad Message Type in RPC call"),
Error::ClosedDevice(ref s) => write!(f, "Device is closed, needs PIN to perform operations: {}", s),
Error::LockedDevice(ref s) => write!(f, "Device is locked, needs PIN to perform operations: {}", s),
}
}
}
@@ -83,11 +86,11 @@ impl From<protobuf::ProtobufError> for Error {
}
}
/// Ledger device manager.
/// Ledger device manager
pub struct Manager {
usb: Arc<Mutex<hidapi::HidApi>>,
devices: RwLock<Vec<Device>>,
closed_devices: RwLock<Vec<String>>,
locked_devices: RwLock<Vec<String>>,
key_path: RwLock<KeyPath>,
}
@@ -109,7 +112,7 @@ impl Manager {
Manager {
usb: hidapi,
devices: RwLock::new(Vec::new()),
closed_devices: RwLock::new(Vec::new()),
locked_devices: RwLock::new(Vec::new()),
key_path: RwLock::new(KeyPath::Ethereum),
}
}
@@ -120,7 +123,7 @@ impl Manager {
usb.refresh_devices();
let devices = usb.devices();
let mut new_devices = Vec::new();
let mut closed_devices = Vec::new();
let mut locked_devices = Vec::new();
let mut error = None;
for usb_device in devices {
let is_trezor = usb_device.vendor_id == TREZOR_VID;
@@ -139,7 +142,7 @@ impl Manager {
}
match self.read_device_info(&usb, &usb_device) {
Ok(device) => new_devices.push(device),
Err(Error::ClosedDevice(path)) => closed_devices.push(path.to_string()),
Err(Error::LockedDevice(path)) => locked_devices.push(path.to_string()),
Err(e) => {
warn!("Error reading device: {:?}", e);
error = Some(e);
@@ -147,9 +150,9 @@ impl Manager {
}
}
let count = new_devices.len();
trace!("Got devices: {:?}, closed: {:?}", new_devices, closed_devices);
trace!("Got devices: {:?}, closed: {:?}", new_devices, locked_devices);
*self.devices.write() = new_devices;
*self.closed_devices.write() = closed_devices;
*self.locked_devices.write() = locked_devices;
match error {
Some(e) => Err(e),
None => Ok(count),
@@ -173,7 +176,7 @@ impl Manager {
},
})
}
Ok(None) => Err(Error::ClosedDevice(dev_info.path.clone())),
Ok(None) => Err(Error::LockedDevice(dev_info.path.clone())),
Err(e) => Err(e),
}
}
@@ -189,7 +192,7 @@ impl Manager {
}
pub fn list_locked_devices(&self) -> Vec<String> {
(*self.closed_devices.read()).clone()
(*self.locked_devices.read()).clone()
}
/// Get wallet info.
@@ -200,16 +203,7 @@ impl Manager {
fn open_path<R, F>(&self, f: F) -> Result<R, Error>
where F: Fn() -> Result<R, &'static str>
{
let mut err = Error::KeyNotFound;
// Try to open device a few times.
for _ in 0..10 {
match f() {
Ok(handle) => return Ok(handle),
Err(e) => err = From::from(e),
}
::std::thread::sleep(Duration::from_millis(200));
}
Err(err)
f().map_err(Into::into)
}
pub fn pin_matrix_ack(&self, device_path: &str, pin: &str) -> Result<bool, Error> {
@@ -406,6 +400,42 @@ impl Manager {
}
}
/// Trezor event handler
/// A separate thread is handeling incoming events
pub struct EventHandler {
trezor: Weak<Manager>,
}
impl EventHandler {
// Trezor event handler constructor
pub fn new(trezor: Weak<Manager>) -> Self {
Self { trezor: trezor }
}
}
impl libusb::Hotplug for EventHandler {
fn device_arrived(&mut self, _device: libusb::Device) {
debug!(target: "hw", "Trezor V1 arrived");
if let Some(trezor) = self.trezor.upgrade() {
// Wait for the device to boot up
::std::thread::sleep(Duration::from_millis(1000));
if let Err(e) = trezor.update_devices() {
debug!(target: "hw", "Trezor V1 connect error: {:?}", e);
}
}
}
fn device_left(&mut self, _device: libusb::Device) {
debug!(target: "hw", "Trezor V1 left");
if let Some(trezor) = self.trezor.upgrade() {
if let Err(e) = trezor.update_devices() {
debug!(target: "hw", "Trezor V1 disconnect error: {:?}", e);
}
}
}
}
#[test]
#[ignore]
/// This test can't be run without an actual trezor device connected

View File

@@ -4,7 +4,7 @@ set -e
# variables
PVER="1-9"
PTYPE="v1"
TRACK="beta"
TRACK="stable"
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
PRE_REPO="js-dist-paritytech/parity-${TRACK}-${PVER}-${PTYPE}.git"
PRE_REPO_TOKEN="https://${GITHUB_JS_PRECOMPILED}:@github.com/${PRE_REPO}"

View File

@@ -1 +1 @@
// test script 25
// test script 26

235
js/package-lock.json generated
View File

@@ -45,15 +45,15 @@
"dev": true
},
"@parity/dapp-dapp-methods": {
"version": "github:js-dist-paritytech/dapp-dapp-methods#b649fb9056d49bbf4fde719f91a4cfcaf529f9f6",
"version": "github:js-dist-paritytech/dapp-dapp-methods#01dcabc56ecea95cdc87dde81598b7e8469375d6",
"dev": true,
"requires": {
"@parity/api": "2.1.15",
"@parity/mobx": "1.1.2",
"@parity/ui": "3.0.22",
"mobx": "3.5.1",
"@parity/ui": "3.1.4",
"mobx": "3.6.2",
"mobx-react": "4.3.5",
"prop-types": "15.6.0",
"prop-types": "15.6.1",
"react": "16.2.0",
"react-dom": "16.2.0",
"react-intl": "2.4.0",
@@ -79,16 +79,97 @@
"@parity/shared": "2.2.23"
}
},
"@parity/ui": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@parity/ui/-/ui-3.1.4.tgz",
"integrity": "sha512-aG79IOxMBeRsu92Zlq3QsR6Z6PAmlhmOdU9tQP+F9XB/44Y4sGxfSDNucGucWz/Jz0VGerJn53CoACa4Yj5uYA==",
"dev": true,
"requires": {
"@parity/api": "2.1.15",
"@parity/etherscan": "2.1.3",
"@parity/mobx": "1.1.2",
"@parity/shared": "2.2.23",
"babel-runtime": "6.26.0",
"bignumber.js": "4.1.0",
"brace": "0.11.0",
"date-difference": "1.0.0",
"eventemitter3": "2.0.3",
"file-saver": "1.3.3",
"geopattern": "1.2.3",
"js-sha3": "0.6.1",
"keycode": "2.1.9",
"lodash": "4.17.4",
"moment": "2.19.2",
"qrcode-generator": "1.3.1",
"react-ace": "5.7.0",
"react-copy-to-clipboard": "5.0.1",
"react-datetime": "2.11.0",
"react-dom": "16.1.1",
"react-dropzone": "4.2.3",
"react-element-to-jsx-string": "13.1.0",
"react-event-listener": "0.5.2",
"react-intl": "2.4.0",
"react-markdown": "3.0.2",
"react-portal": "4.0.0",
"react-qr-reader": "2.0.1",
"react-redux": "5.0.6",
"react-router": "3.2.0",
"react-tooltip": "3.4.0",
"recharts": "1.0.0-beta.2",
"redux": "3.7.2",
"semantic-ui-css": "2.2.12",
"semantic-ui-react": "0.76.0",
"zxcvbn": "4.4.2"
},
"dependencies": {
"react-dom": {
"version": "16.1.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.1.tgz",
"integrity": "sha512-q06jiwST8SEPAMIEkAsu7BgynEZtqF87VrTc70XsW7nxVhWEu2Y4MF5UfxxHQO/mNtQHQWP0YcFxmwm9oMrMaQ==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.1"
}
},
"semantic-ui-react": {
"version": "0.76.0",
"resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-0.76.0.tgz",
"integrity": "sha512-CdiIT8n7ZwUlytZkYsQMnaVGmoIZI/mVs4lijvLcR568kcnlRkYYaFKhMLq5tFDQU6+QhdTD+8WebF7ov0Ql6Q==",
"dev": true,
"requires": {
"babel-runtime": "6.26.0",
"classnames": "2.2.5",
"lodash": "4.17.4",
"prop-types": "15.6.1"
}
}
}
},
"bignumber.js": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
"integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==",
"dev": true
},
"js-sha3": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz",
"integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=",
"dev": true
},
"mobx": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.5.1.tgz",
"integrity": "sha1-jmguxTXPROBABbnjfi32asyXWkI=",
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz",
"integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg==",
"dev": true
},
"prop-types": {
"version": "15.6.0",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
"integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
@@ -105,7 +186,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
},
"react-dom": {
@@ -117,7 +198,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
},
"semantic-ui-react": {
@@ -130,21 +211,20 @@
"classnames": "2.2.5",
"fbjs": "0.8.16",
"lodash": "4.17.4",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
}
}
},
"@parity/dapp-dapp-visible": {
"version": "github:js-dist-paritytech/dapp-dapp-visible#28546f312ea9877ebeea9c52afea1e7ec943cd0d",
"version": "github:js-dist-paritytech/dapp-dapp-visible#14e6499495a3421c4a6da4728b8d99dfa1656e1c",
"dev": true,
"requires": {
"@parity/api": "2.1.15",
"@parity/mobx": "1.1.2",
"@parity/ui": "3.0.22",
"mobx": "3.5.1",
"@parity/ui": "3.1.4",
"mobx": "3.6.2",
"mobx-react": "4.3.5",
"prop-types": "15.6.0",
"prop-types": "15.6.1",
"react": "16.2.0",
"react-dom": "16.2.0",
"react-intl": "2.4.0",
@@ -170,16 +250,97 @@
"@parity/shared": "2.2.23"
}
},
"@parity/ui": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@parity/ui/-/ui-3.1.4.tgz",
"integrity": "sha512-aG79IOxMBeRsu92Zlq3QsR6Z6PAmlhmOdU9tQP+F9XB/44Y4sGxfSDNucGucWz/Jz0VGerJn53CoACa4Yj5uYA==",
"dev": true,
"requires": {
"@parity/api": "2.1.15",
"@parity/etherscan": "2.1.3",
"@parity/mobx": "1.1.2",
"@parity/shared": "2.2.23",
"babel-runtime": "6.26.0",
"bignumber.js": "4.1.0",
"brace": "0.11.0",
"date-difference": "1.0.0",
"eventemitter3": "2.0.3",
"file-saver": "1.3.3",
"geopattern": "1.2.3",
"js-sha3": "0.6.1",
"keycode": "2.1.9",
"lodash": "4.17.4",
"moment": "2.19.2",
"qrcode-generator": "1.3.1",
"react-ace": "5.7.0",
"react-copy-to-clipboard": "5.0.1",
"react-datetime": "2.11.0",
"react-dom": "16.1.1",
"react-dropzone": "4.2.3",
"react-element-to-jsx-string": "13.1.0",
"react-event-listener": "0.5.2",
"react-intl": "2.4.0",
"react-markdown": "3.0.2",
"react-portal": "4.0.0",
"react-qr-reader": "2.0.1",
"react-redux": "5.0.6",
"react-router": "3.2.0",
"react-tooltip": "3.4.0",
"recharts": "1.0.0-beta.2",
"redux": "3.7.2",
"semantic-ui-css": "2.2.12",
"semantic-ui-react": "0.76.0",
"zxcvbn": "4.4.2"
},
"dependencies": {
"react-dom": {
"version": "16.1.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.1.tgz",
"integrity": "sha512-q06jiwST8SEPAMIEkAsu7BgynEZtqF87VrTc70XsW7nxVhWEu2Y4MF5UfxxHQO/mNtQHQWP0YcFxmwm9oMrMaQ==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.1"
}
},
"semantic-ui-react": {
"version": "0.76.0",
"resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-0.76.0.tgz",
"integrity": "sha512-CdiIT8n7ZwUlytZkYsQMnaVGmoIZI/mVs4lijvLcR568kcnlRkYYaFKhMLq5tFDQU6+QhdTD+8WebF7ov0Ql6Q==",
"dev": true,
"requires": {
"babel-runtime": "6.26.0",
"classnames": "2.2.5",
"lodash": "4.17.4",
"prop-types": "15.6.1"
}
}
}
},
"bignumber.js": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
"integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==",
"dev": true
},
"js-sha3": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz",
"integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=",
"dev": true
},
"mobx": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.5.1.tgz",
"integrity": "sha1-jmguxTXPROBABbnjfi32asyXWkI=",
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz",
"integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg==",
"dev": true
},
"prop-types": {
"version": "15.6.0",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
"integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
@@ -196,7 +357,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
},
"react-dom": {
@@ -208,7 +369,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
},
"semantic-ui-react": {
@@ -221,7 +382,7 @@
"classnames": "2.2.5",
"fbjs": "0.8.16",
"lodash": "4.17.4",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
}
}
@@ -254,9 +415,9 @@
"@parity/mobx": "1.1.2",
"@parity/ui": "3.0.22",
"format-number": "3.0.0",
"mobx": "3.5.1",
"mobx": "3.6.2",
"mobx-react": "4.3.5",
"prop-types": "15.6.0",
"prop-types": "15.6.1",
"react": "16.2.0",
"react-dom": "16.2.0",
"react-intl": "2.4.0",
@@ -284,15 +445,15 @@
}
},
"mobx": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.5.1.tgz",
"integrity": "sha1-jmguxTXPROBABbnjfi32asyXWkI=",
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz",
"integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg==",
"dev": true
},
"prop-types": {
"version": "15.6.0",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
"integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
@@ -309,7 +470,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
},
"react-dom": {
@@ -321,7 +482,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
"prop-types": "15.6.1"
}
}
}

View File

@@ -21,10 +21,10 @@
"Parity"
],
"scripts": {
"build": "npm run build:inject && npm run build:app && npm run build:embed",
"build": "npm run build:inject && npm run build:app:embed",
"build:app": "webpack --config webpack/app",
"build:inject": "webpack --config webpack/inject",
"build:embed": "cross-env EMBED=1 node webpack/embed",
"build:app:embed": "cross-env EMBED=1 node webpack/embed",
"build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js",
"ci:build": "cross-env NODE_ENV=production npm run build",
"clean": "rimraf ./.build ./.coverage ./.happypack",

View File

@@ -4,7 +4,7 @@ set -e
# variables
PVER="1-9"
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
BRANCH="beta"
BRANCH="stable"
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"
echo "*** [cargo] Setting up GitHub config for parity"

View File

@@ -4,7 +4,7 @@ set -e
# variables
PVER="1-9"
PTYPE="shell"
TRACK="beta"
TRACK="stable"
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
PRE_REPO="js-dist-paritytech/parity-${TRACK}-${PVER}-${PTYPE}.git"
PRE_REPO_TOKEN="https://${GITHUB_JS_PRECOMPILED}:@github.com/${PRE_REPO}"

View File

@@ -1 +1 @@
// test script 31
// test script 32

14
js/src/Dapps/blacklist.js Normal file
View File

@@ -0,0 +1,14 @@
module.exports = [
// tokendeploy
'0xf9f2d620c2e08f83e45555247146c62185e4ab7cf82a4b9002a265a0d020348f',
// methodreg
'0xf49089046f53f5d2e5f3513c1c32f5ff57d986e46309a42d2b249070e4e72c46',
// dappreg
'0x7bbc4f1a27628781b96213e781a1b8eec6982c1db8fac739af6e4c5a55862c03',
// githubhint
'0x058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75',
// console
'0xa635a9326814bded464190eddf0bdb90ce92d40ea2359cf553ea80e3c5a4076c',
// registry
'0xd1adaede68d344519025e2ff574650cd99d3830fe6d274c7a7843cdc00e17938'
];

View File

@@ -29,6 +29,8 @@ import DappCard from './DappCard';
import styles from './dapps.css';
import BLACKLIST from './blacklist';
@observer
class Dapps extends Component {
static contextTypes = {
@@ -53,8 +55,10 @@ class Dapps extends Component {
}
}
renderSection = (apps) => (
apps && apps.length > 0 &&
renderSection = (_apps) => {
const apps = _apps.filter(({ id }) => !BLACKLIST.includes(id));
return apps && apps.length > 0 &&
<div className={ styles.dapps }>
{
apps.map((app, index) => (
@@ -68,8 +72,8 @@ class Dapps extends Component {
/>
))
}
</div>
)
</div>;
}
render () {
return (

View File

@@ -19,6 +19,7 @@ const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const flatten = require('lodash.flatten');
const webpack = require('webpack');
// const ReactIntlAggregatePlugin = require('react-intl-aggregate-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WebpackErrorNotificationPlugin = require('webpack-error-notification');
@@ -29,12 +30,14 @@ const rulesEs6 = require('./rules/es6');
const rulesParity = require('./rules/parity');
const Shared = require('./shared');
const BLACKLIST = require('../src/Dapps/blacklist');
const DAPPS_BUILTIN = require('@parity/shared/lib/config/dappsBuiltin.json');
const DAPPS_VIEWS = require('@parity/shared/lib/config/dappsViews.json');
const DAPPS_ALL = []
.concat(DAPPS_BUILTIN, DAPPS_VIEWS)
.filter((dapp) => !dapp.skipBuild)
.filter((dapp) => dapp.package);
.filter((dapp) => dapp.package)
.filter(({ id }) => !BLACKLIST.includes(id));
const FAVICON = path.resolve(__dirname, '../node_modules/@parity/shared/assets/images/parity-logo-black-no-text.png');
@@ -45,9 +48,10 @@ const EMBED = process.env.EMBED;
const isProd = ENV === 'production';
const isEmbed = EMBED === '1' || EMBED === 'true';
const entry = isEmbed
? { embed: ['babel-polyfill', './embed.js'] }
: { bundle: ['babel-polyfill', './index.parity.js'] };
const entry = {
embed: ['babel-polyfill', './embed.js'],
bundle: ['babel-polyfill', './index.parity.js']
};
module.exports = {
cache: !isProd,
@@ -162,23 +166,30 @@ module.exports = {
},
plugins: (function () {
let plugins = Shared.getPlugins().concat(
new WebpackErrorNotificationPlugin(),
new ExtractTextPlugin({
filename: `${isEmbed ? 'embed' : 'bundle'}.css`
}),
);
if (!isEmbed) {
plugins = [].concat(
plugins,
let plugins = []
.concat(Shared.getPlugins())
.concat(
new WebpackErrorNotificationPlugin(),
new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
})
)
.concat(
new HtmlWebpackPlugin({
title: 'Parity Bar',
filename: 'embed.html',
template: './index.parity.ejs',
favicon: FAVICON,
chunks: ['commons', 'embed']
}),
new HtmlWebpackPlugin({
title: 'Parity',
filename: 'index.html',
template: './index.parity.ejs',
favicon: FAVICON,
chunks: ['bundle']
chunks: ['commons', 'bundle']
}),
new CopyWebpackPlugin(
@@ -244,16 +255,11 @@ module.exports = {
{}
)
);
}
if (isEmbed) {
plugins.push(
new HtmlWebpackPlugin({
title: 'Parity Bar',
filename: 'embed.html',
template: './index.parity.ejs',
favicon: FAVICON,
chunks: ['embed']
if (isProd) {
plugins.unshift(
new webpack.optimize.CommonsChunkPlugin({
name: 'commons'
})
);
}

View File

@@ -19,7 +19,6 @@ const webpack = require('webpack');
const HappyPack = require('happypack');
const PackageJson = require('../package.json');
const EMBED = process.env.EMBED;
const ENV = process.env.NODE_ENV || 'development';
const isProd = ENV === 'production';
const UI_VERSION = PackageJson
@@ -38,7 +37,6 @@ function getPlugins (_isProd = isProd) {
const plugins = [
new webpack.DefinePlugin({
'process.env': {
EMBED: JSON.stringify(EMBED),
NODE_ENV: JSON.stringify(ENV),
RPC_ADDRESS: JSON.stringify(process.env.RPC_ADDRESS),
PARITY_URL: JSON.stringify(process.env.PARITY_URL),

View File

@@ -113,6 +113,9 @@ pub struct Params {
/// See main EthashParams docs.
#[serde(rename="maxCodeSize")]
pub max_code_size: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="maxCodeSizeTransition")]
pub max_code_size_transition: Option<Uint>,
/// Transaction permission contract address.
#[serde(rename="transactionPermissionContract")]
pub transaction_permission_contract: Option<Address>,

View File

@@ -462,7 +462,7 @@
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>VERSION</key>
<string>1.9.3</string>
<string>1.9.5</string>
</dict>
<key>UUID</key>
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>

View File

@@ -10,7 +10,7 @@
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
!define VERSIONMAJOR 1
!define VERSIONMINOR 9
!define VERSIONBUILD 3
!define VERSIONBUILD 5
!define ARGS ""
!define FIRST_START_ARGS "--mode=passive ui"

View File

@@ -676,11 +676,15 @@ pub fn execute_impl(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>)
let event_loop = EventLoop::spawn();
// the updater service
let mut updater_fetch = fetch.clone();
// parity binaries should be smaller than 128MB
updater_fetch.set_limit(Some(128 * 1024 * 1024));
let updater = Updater::new(
Arc::downgrade(&(service.client() as Arc<BlockChainClient>)),
Arc::downgrade(&sync_provider),
update_policy,
fetch.clone(),
updater_fetch,
event_loop.remote(),
);
service.add_notify(updater.clone());

View File

@@ -22,13 +22,10 @@ echo "Parity version: " $VER
echo "Branch: " $CI_BUILD_REF_NAME
echo "--------------------"
echo "Rhash version:"
# NOTE for md5 and sha256 we want to display filename as well
# hence we use --* instead of -p *
MD5_BIN="rhash --md5"
SHA256_BIN="rhash --sha256"
# NOTE For SHA3 we need only hash (hence -p)
SHA3_BIN="rhash -p %{sha3-256}"
set_env () {
echo "Set ENVIROMENT"
@@ -51,6 +48,12 @@ set_env_win () {
echo "@ signtool sign /f "\%"1 /p "\%"2 /tr http://timestamp.comodoca.com /du https://parity.io "\%"3" > sign.cmd
}
build () {
if [[ "windows" = $IDENT ]]
then
# This is a nasty hack till we figure out the proper cargo caching strategy
echo "Remove index"
rm -rf cargo/registry/index/*.
fi
echo "Build parity:"
cargo build --target $PLATFORM --features final --release
echo "Build evmbin:"
@@ -70,14 +73,12 @@ strip_binaries () {
calculate_checksums () {
echo "Checksum calculation:"
rhash --version
rm -rf *.md5
rm -rf *.sha256
export SHA3="$($SHA3_BIN target/$PLATFORM/release/parity$S3WIN)"
# NOTE rhash 1.3.1 doesnt support keccak, workaround
if [ "$SHA3" == "%{sha3-256}" ]; then
export SHA3="$(target/$PLATFORM/release/parity$S3WIN tools hash target/$PLATFORM/release/parity$S3WIN)"
fi
BIN="target/$PLATFORM/release/parity$S3WIN"
export SHA3="$($BIN tools hash $BIN)"
echo "Parity file SHA3: $SHA3"
$MD5_BIN target/$PLATFORM/release/parity$S3WIN > parity$S3WIN.md5
@@ -312,7 +313,7 @@ case $BUILD_PLATFORM in
snapcraft clean
echo "Prepare snapcraft.yaml for build on Gitlab CI in Docker image"
sed -i 's/git/'"$VER"'/g' snap/snapcraft.yaml
if [[ "$CI_BUILD_REF_NAME" = "beta" || "$VER" == *1.9* ]];
if [[ "$CI_BUILD_REF_NAME" = "stable" || "$VER" == *1.9* ]];
then
sed -i -e 's/grade: devel/grade: stable/' snap/snapcraft.yaml;
fi

View File

@@ -4,12 +4,12 @@ set -e # fail on any error
set -u # treat unset variables as error
if [[ "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" ]]; then
export GIT_COMPARE=$CI_COMMIT_REF_NAME;
export GIT_COMPARE=$CI_COMMIT_REF_NAME~;
else
export GIT_COMPARE=master;
fi
export JS_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep ^js/ | wc -l)"
export JS_OLD_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep ^js-old/ | wc -l)"
export JS_FILES_MODIFIED=1
export JS_OLD_FILES_MODIFIED=1
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ | wc -l)"
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"

View File

@@ -18,6 +18,7 @@ use std::fs;
use std::io::Write;
use std::path::{PathBuf};
use std::sync::{Arc, Weak};
use std::time::{Duration, Instant};
use ethcore::client::{BlockId, BlockChainClient, ChainNotify};
use ethsync::{SyncProvider};
@@ -85,6 +86,8 @@ struct UpdaterState {
capability: CapState,
disabled: bool,
backoff: Option<(u32, Instant)>,
}
/// Service for checking for updates and determining whether we can achieve consensus.
@@ -216,7 +219,19 @@ impl Updater {
let fetched = s.fetching.take().unwrap();
let dest = self.updates_path(&Self::update_file_name(&fetched.version));
if !dest.exists() {
let b = result.map_err(|e| (format!("Unable to fetch update ({}): {:?}", fetched.version, e), false))?;
let b = match result {
Ok(b) => {
s.backoff = None;
b
},
Err(e) => {
let mut n = s.backoff.map(|b| b.0 + 1).unwrap_or(1);
s.backoff = Some((n, Instant::now() + Duration::from_secs(2usize.pow(n) as u64)));
return Err((format!("Unable to fetch update ({}): {:?}", fetched.version, e), false));
},
};
info!(target: "updater", "Fetched latest version ({}) OK to {}", fetched.version, b.display());
fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| (format!("Unable to create updates path: {:?}", e), true))?;
fs::copy(&b, &dest).map_err(|e| (format!("Unable to copy update: {:?}", e), true))?;
@@ -287,12 +302,14 @@ impl Updater {
drop(s);
self.fetch_done(Ok(PathBuf::new()));
} else {
info!(target: "updater", "Attempting to get parity binary {}", b);
s.fetching = Some(latest.track.clone());
drop(s);
let weak_self = self.weak_self.lock().clone();
let f = move |r: Result<PathBuf, fetch::Error>| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) };
self.fetcher.lock().as_ref().expect("Created on `new`; qed").fetch(b, Box::new(f));
if s.backoff.iter().all(|&(_, instant)| Instant::now() >= instant) {
info!(target: "updater", "Attempting to get parity binary {}", b);
s.fetching = Some(latest.track.clone());
drop(s);
let weak_self = self.weak_self.lock().clone();
let f = move |r: Result<PathBuf, fetch::Error>| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) };
self.fetcher.lock().as_ref().expect("Created on `new`; qed").fetch(b, Box::new(f));
}
}
}
}
@@ -321,6 +338,11 @@ impl Updater {
}
let mut s = self.state.lock();
if s.latest != latest {
s.backoff = None;
}
s.latest = latest;
s.capability = capability;
}

View File

@@ -3,7 +3,7 @@ description = "Ethcore utility library"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "ethcore-util"
version = "1.9.0"
version = "1.9.5"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]

3
util/bloomchain/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
target
Cargo.lock
*.swp

View File

@@ -0,0 +1,15 @@
[package]
description = "Standalone blockchain bloom filter"
homepage = "https://github.com/debris/bloomchain"
name = "bloomchain"
version = "0.2.0"
authors = ["debris <marek.kotewicz@gmail.com>"]
license = "MIT"
keywords = ["ethereum", "ethcore", "bloom", "chain", "filter"]
[dependencies]
ethcore-bigint = { path = "../bigint" }
[dev-dependencies]
rustc-hex = "1.0"
rand = "0.4"

View File

@@ -0,0 +1,9 @@
# bloomchain
Standalone blockchain bloom filter.
[![Build Status][travis-image]][travis-url]
[travis-image]: https://travis-ci.org/paritytech/bloomchain.svg?branch=master
[travis-url]: https://travis-ci.org/paritytech/bloomchain
[Documentation](http://paritytech.github.io/bloomchain/bloomchain/index.html)

View File

@@ -0,0 +1,188 @@
use std::collections::{HashMap, HashSet};
use std::ops::Range;
use number::Number;
use position::{Position, Manager as PositionManager};
use Bloom;
use filter::Filter;
use config::Config;
use database::BloomDatabase;
/// Prepares all bloom database operations.
pub struct BloomChain<'a> {
positioner: PositionManager,
db: &'a BloomDatabase,
}
impl<'a> BloomChain<'a> {
/// Creates new bloom chain.
pub fn new(config: Config, db: &'a BloomDatabase) -> Self {
let positioner = PositionManager::new(config.elements_per_index, config.levels);
BloomChain {
positioner: positioner,
db: db,
}
}
/// Internal function which does bloom search recursively.
fn blocks(&self, range: &Range<Number>, bloom: &Bloom, level: usize, offset: usize) -> Option<Vec<usize>> {
let index = self.positioner.position(offset, level);
match self.db.bloom_at(&index) {
None => return None,
Some(level_bloom) => match level {
// if we are on the lowest level
0 if level_bloom.contains_bloom(bloom) => return Some(vec![offset]),
// return None if current level doesnt contain given bloom
_ if !level_bloom.contains_bloom(bloom) => return None,
// continue processing && go down
_ => ()
}
};
let level_size = self.positioner.level_size(level - 1);
let from_position = self.positioner.position(range.start, level - 1);
let to_position = self.positioner.position(range.end, level - 1);
let res: Vec<usize> = self.positioner.lower_level_positions(&index).into_iter()
// chose only blooms in range
.filter(|li| li.index >= from_position.index && li.index <= to_position.index)
// map them to offsets
.map(|li| li.index * level_size)
// get all blocks that may contain our bloom
// filter existing ones
.filter_map(|off| self.blocks(range, bloom, level - 1, off))
// flatten nested structures
.flat_map(|v| v)
.collect();
Some(res)
}
/// Inserts the bloom at all filter levels.
pub fn insert(&self, number: Number, bloom: Bloom) -> HashMap<Position, Bloom> {
let mut result: HashMap<Position, Bloom> = HashMap::new();
for level in 0..self.positioner.levels() {
let position = self.positioner.position(number, level);
let new_bloom = match self.db.bloom_at(&position) {
Some(mut old_bloom) => {
old_bloom.accrue_bloom(&bloom);
old_bloom
},
None => bloom.clone(),
};
result.insert(position, new_bloom);
}
result
}
/// Resets data in range.
/// Inserts new data.
/// Inserted data may exceed reseted range.
pub fn replace(&self, range: &Range<Number>, blooms: Vec<Bloom>) -> HashMap<Position, Bloom> {
let mut result: HashMap<Position, Bloom> = HashMap::new();
// insert all new blooms at level 0
for (i, bloom) in blooms.iter().enumerate() {
result.insert(self.positioner.position(range.start + i, 0), bloom.clone());
}
// reset the rest of blooms
for reset_number in range.start + blooms.len()..(range.end + 1) {
result.insert(self.positioner.position(reset_number, 0), Bloom::default());
}
for level in 1..self.positioner.levels() {
for i in 0..blooms.len() {
let index = self.positioner.position(range.start + i, level);
let new_bloom = {
// use new blooms before db blooms where necessary
let bloom_at = | index | { result.get(&index).cloned().or_else(|| self.db.bloom_at(&index)) };
self.positioner.lower_level_positions(&index)
.into_iter()
// get blooms
// filter existing ones
.filter_map(bloom_at)
// BitOr all of them
.fold(Bloom::default(), |mut acc, bloom| {
acc.accrue_bloom(&bloom);
acc
})
};
result.insert(index, new_bloom);
}
}
result
}
/// Returns all numbers with given bloom.
pub fn with_bloom(&self, range: &Range<Number>, bloom: &Bloom) -> Vec<Number> {
let mut result = vec![];
// lets start from highest level
let max_level = self.positioner.max_level();
let level_size = self.positioner.level_size(max_level);
let from_position = self.positioner.position(range.start, max_level);
let to_position = self.positioner.position(range.end, max_level);
for index in from_position.index..to_position.index + 1 {
// offset will be used to calculate where we are right now
let offset = level_size * index;
// go doooown!
if let Some(blocks) = self.blocks(range, bloom, max_level, offset) {
result.extend(blocks);
}
}
result
}
/// Filter the chain returing all numbers matching the filter.
pub fn filter(&self, filter: &Filter) -> Vec<Number> {
let range = filter.range();
let mut blocks = filter.bloom_possibilities()
.into_iter()
.flat_map(|ref bloom| self.with_bloom(&range, bloom))
.collect::<HashSet<Number>>()
.into_iter()
.collect::<Vec<Number>>();
blocks.sort();
blocks
}
}
const BLOOM_SIZE: usize = 256;
pub trait BloomCompat {
fn contains_bloom(&self, bloom: &Self) -> bool where Self: Sized;
fn accrue_bloom(&mut self, bloom: &Self) where Self:Sized;
}
impl BloomCompat for Bloom {
fn contains_bloom(&self, bloom_ref: &Self) -> bool {
assert_eq!(self.0.len(), BLOOM_SIZE);
assert_eq!(bloom_ref.0.len(), BLOOM_SIZE);
for i in 0..BLOOM_SIZE {
let a = self.0[i];
let b = bloom_ref.0[i];
if (a & b) != b {
return false;
}
}
true
}
fn accrue_bloom(&mut self, bloom_ref: &Self) {
assert_eq!(self.0.len(), BLOOM_SIZE);
assert_eq!(bloom_ref.0.len(), BLOOM_SIZE);
for i in 0..BLOOM_SIZE {
self.0[i] |= bloom_ref.0[i];
}
}
}

View File

@@ -0,0 +1,17 @@
/// `BloomChain` configuration.
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Config {
/// Number of levels.
pub levels: usize,
/// Number of elements in a single index.
pub elements_per_index: usize,
}
impl Default for Config {
fn default() -> Self {
Config {
levels: 3,
elements_per_index: 16,
}
}
}

View File

@@ -0,0 +1,7 @@
use position::Position;
use Bloom;
/// Readonly `Bloom` database.
pub trait BloomDatabase {
fn bloom_at(&self, position: &Position) -> Option<Bloom>;
}

View File

@@ -0,0 +1,11 @@
use std::ops::Range;
use Bloom;
use number::Number;
/// Should be used to filter blocks from `BloomChain`.
pub trait Filter {
/// All bloom possibilities that we are searching for.
fn bloom_possibilities(&self) -> Vec<Bloom>;
/// Range of search.
fn range(&self) -> Range<Number>;
}

View File

@@ -0,0 +1,31 @@
use Bloom;
use config::Config;
use database::BloomDatabase;
use position::Position;
use group::position::Manager as PositionManager;
use super::BloomGroupDatabase;
/// Bridge between `BloomDatabase` and `BloomGroupDatabase`.
pub struct GroupDatabaseBridge<'a> {
positioner: PositionManager,
db: &'a BloomGroupDatabase,
}
impl<'a> GroupDatabaseBridge<'a> {
pub fn new(config: Config, db: &'a BloomGroupDatabase) -> Self {
let positioner = PositionManager::new(config.elements_per_index);
GroupDatabaseBridge {
positioner: positioner,
db: db,
}
}
}
impl<'a> BloomDatabase for GroupDatabaseBridge<'a> {
fn bloom_at(&self, position: &Position) -> Option<Bloom> {
let position = self.positioner.position(position);
self.db.blooms_at(&position.group)
.and_then(|group| group.blooms.into_iter().nth(position.number))
}
}

View File

@@ -0,0 +1,70 @@
use std::collections::HashMap;
use std::ops::Range;
use Bloom;
use chain::BloomChain;
use config::Config;
use number::Number;
use filter::Filter;
use position::Position as BloomPosition;
use super::{GroupDatabaseBridge, BloomGroupDatabase, BloomGroup, GroupPosition};
use super::position::Manager as PositionManager;
/// Performs all bloom database operations using `BloomGroup`s.
pub struct BloomGroupChain<'a> {
config: Config,
db: &'a BloomGroupDatabase,
bridge: GroupDatabaseBridge<'a>,
}
impl<'a> BloomGroupChain<'a> {
pub fn new(config: Config, db: &'a BloomGroupDatabase) -> Self {
let bridge = GroupDatabaseBridge::new(config, db);
BloomGroupChain {
config: config,
db: db,
bridge: bridge,
}
}
fn group_blooms(&self, blooms: HashMap<BloomPosition, Bloom>) -> HashMap<GroupPosition, BloomGroup> {
let positioner = PositionManager::new(self.config.elements_per_index);
blooms.into_iter()
.fold(HashMap::new(), | mut acc, (position, bloom) | {
{
let position = positioner.position(&position);
let group = acc
.entry(position.group.clone())
.or_insert_with(|| self.db
.blooms_at(&position.group)
.unwrap_or_else(|| BloomGroup::new(self.config.elements_per_index))
);
assert_eq!(self.config.elements_per_index, group.blooms.len());
group.blooms[position.number] = bloom;
}
acc
})
}
pub fn insert(&self, number: Number, bloom: Bloom) -> HashMap<GroupPosition, BloomGroup> {
let bloom_chain = BloomChain::new(self.config, &self.bridge);
let modified_blooms = bloom_chain.insert(number, bloom);
self.group_blooms(modified_blooms)
}
pub fn replace(&self, range: &Range<Number>, blooms: Vec<Bloom>) -> HashMap<GroupPosition, BloomGroup> {
let bloom_chain = BloomChain::new(self.config, &self.bridge);
let modified_blooms = bloom_chain.replace(range, blooms);
self.group_blooms(modified_blooms)
}
pub fn with_bloom(&self, range: &Range<Number>, bloom: &Bloom) -> Vec<Number> {
let bloom_chain = BloomChain::new(self.config, &self.bridge);
bloom_chain.with_bloom(range, bloom)
}
pub fn filter(&self, filter: &Filter) -> Vec<Number> {
let bloom_chain = BloomChain::new(self.config, &self.bridge);
bloom_chain.filter(filter)
}
}

View File

@@ -0,0 +1,6 @@
use group::{GroupPosition, BloomGroup};
/// Readonly `BloomGroup` database.
pub trait BloomGroupDatabase {
fn blooms_at(&self, position: &GroupPosition) -> Option<BloomGroup>;
}

View File

@@ -0,0 +1,17 @@
use Bloom;
/// Group of blooms that are in the same index.
#[derive(Debug, Clone)]
pub struct BloomGroup {
pub blooms: Vec<Bloom>,
}
impl BloomGroup {
pub fn new(size: usize) -> Self {
let blooms = (0..size).into_iter().map(|_| Bloom::default()).collect();
BloomGroup {
blooms: blooms
}
}
}

View File

@@ -0,0 +1,16 @@
//! Bloom grouping.
//!
//! Optimization gathering together blooms that are in the same index and are likely to be retrived together.
mod bridge;
mod chain;
mod database;
mod group;
mod position;
pub use self::bridge::GroupDatabaseBridge;
pub use self::chain::BloomGroupChain;
pub use self::database::BloomGroupDatabase;
pub use self::group::BloomGroup;
pub use self::position::GroupPosition;

View File

@@ -0,0 +1,28 @@
use super::{Position, GroupPosition};
use position::Position as BloomPosition;
pub struct Manager {
index_size: usize
}
impl Manager {
pub fn new(index_size: usize) -> Self {
Manager {
index_size: index_size
}
}
pub fn group_position(&self, pos: &BloomPosition) -> GroupPosition {
GroupPosition {
level: pos.level,
index: pos.index / self.index_size,
}
}
pub fn position(&self, pos: &BloomPosition) -> Position {
Position {
group: self.group_position(pos),
number: pos.index % self.index_size,
}
}
}

View File

@@ -0,0 +1,5 @@
mod position;
mod manager;
pub use self::position::{Position, GroupPosition};
pub use self::manager::Manager;

View File

@@ -0,0 +1,17 @@
/// Uniquely identifies bloom group position.
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct GroupPosition {
/// Bloom level.
pub level: usize,
/// Index of the group.
pub index: usize,
}
/// Uniquely identifies bloom position including the position in the group.
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct Position {
/// Group position.
pub group: GroupPosition,
/// Number in group.
pub number: usize,
}

View File

@@ -0,0 +1,17 @@
extern crate ethcore_bigint as bigint;
mod chain;
mod config;
mod database;
pub mod group;
mod number;
mod position;
mod filter;
pub use bigint::hash::H2048 as Bloom;
pub use chain::{BloomChain, BloomCompat};
pub use config::Config;
pub use database::BloomDatabase;
pub use number::Number;
pub use position::Position;
pub use filter::Filter;

View File

@@ -0,0 +1,2 @@
/// Represents block number.
pub type Number = usize;

View File

@@ -0,0 +1,142 @@
//! Simplifies working with bloom indexes.
use super::Position;
/// Simplifies working with bloom indexes.
pub struct Manager {
index_size: usize,
level_sizes: Vec<usize>,
}
impl Manager {
/// Creates new indexer.
pub fn new(index_size: usize, levels: usize) -> Self {
if levels == 0 {
panic!("Manager requires at least 1 level.");
}
let mut level_sizes = vec![1];
level_sizes.extend_from_slice(&(1..).into_iter()
.scan(1, |acc, _| {
*acc = *acc * index_size;
Some(*acc)
})
.take(levels - 1)
.collect::<Vec<usize>>());
Manager {
index_size: index_size,
level_sizes: level_sizes,
}
}
/// Unsafely get level size.
pub fn level_size(&self, level: usize) -> usize {
self.level_sizes[level as usize]
}
/// Converts block number and level to `Position`.
pub fn position(&self, block_number: usize, level: usize) -> Position {
Position {
level: level,
index: block_number / self.level_size(level),
}
}
/// Return bloom which are dependencies for given index.
///
/// Bloom indexes are ordered from lowest to highest.
pub fn lower_level_positions(&self, index: &Position) -> Vec<Position> {
// this is the lowest level
if index.level == 0 {
return vec![];
}
let new_level = index.level - 1;
let offset = self.index_size * index.index;
(0..self.index_size)
.map(|i| Position {
level: new_level,
index: offset + i
})
.collect()
}
/// Return number of levels.
pub fn levels(&self) -> usize {
self.level_sizes.len()
}
/// Returns max indexer level.
pub fn max_level(&self) -> usize {
self.level_sizes.len() - 1
}
}
#[cfg(test)]
mod tests {
use position::Position;
use super::*;
#[test]
fn test_level_size() {
let indexer = Manager::new(16, 3);
assert_eq!(indexer.level_size(0), 1);
assert_eq!(indexer.level_size(1), 16);
assert_eq!(indexer.level_size(2), 256);
}
#[test]
fn test_position() {
let indexer = Manager::new(16, 3);
let bi0 = indexer.position(0, 0);
assert_eq!(bi0.level, 0);
assert_eq!(bi0.index, 0);
let bi1 = indexer.position(1, 0);
assert_eq!(bi1.level, 0);
assert_eq!(bi1.index, 1);
let bi2 = indexer.position(2, 0);
assert_eq!(bi2.level, 0);
assert_eq!(bi2.index, 2);
let bi3 = indexer.position(3, 1);
assert_eq!(bi3.level, 1);
assert_eq!(bi3.index, 0);
let bi4 = indexer.position(15, 1);
assert_eq!(bi4.level, 1);
assert_eq!(bi4.index, 0);
let bi5 = indexer.position(16, 1);
assert_eq!(bi5.level, 1);
assert_eq!(bi5.index, 1);
let bi6 = indexer.position(255, 2);
assert_eq!(bi6.level, 2);
assert_eq!(bi6.index, 0);
let bi7 = indexer.position(256, 2);
assert_eq!(bi7.level, 2);
assert_eq!(bi7.index, 1);
}
#[test]
fn test_lower_level_positions() {
let indexer = Manager::new(16, 3);
let bi = indexer.position(256, 2);
assert_eq!(bi.level, 2);
assert_eq!(bi.index, 1);
let mut ebis = vec![];
for i in 16..32 {
ebis.push(Position { level: 1, index: i});
}
let bis = indexer.lower_level_positions(&bi);
assert_eq!(ebis, bis);
}
}

View File

@@ -0,0 +1,5 @@
pub mod position;
pub mod manager;
pub use self::position::Position;
pub use self::manager::Manager;

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