Merge branch 'master' into light-poa

This commit is contained in:
Robert Habermeier 2017-08-23 15:49:02 +02:00
commit 871a9c063e
384 changed files with 20373 additions and 4349 deletions

12
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,12 @@
_Before filing a new issue, please **provide the following information**._
> I'm running:
>
> - **Parity version**: 0.0.0
> - **Operating system**: Windows / MacOS / Linux
> - **And installed**: via installer / homebrew / binaries / from source
_Your issue description goes here below. Try to include **actual** vs. **expected behavior** and **steps to reproduce** the issue._
---

View File

@ -1,41 +1,45 @@
## Parity [v1.6.10](https://github.com/paritytech/parity/releases/tag/v1.6.10) (2017-07-23) ## Parity [v1.7.0](https://github.com/paritytech/parity/releases/tag/v1.7.0) (2017-07-28)
This is a hotfix release for the stable channel addressing the recent [multi-signature wallet vulnerability](https://blog.parity.io/security-alert-high-2/). Note, upgrading is not mandatory, and all future multi-sig wallets created by any version of Parity are secure.
All Changes:
- Backports for stable [#6116](https://github.com/paritytech/parity/pull/6116)
- Remove chunk to restore from pending set only upon successful import [#6112](https://github.com/paritytech/parity/pull/6112)
- Blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874)
- Bump snap version and tweak importing detection logic [#6079](https://github.com/paritytech/parity/pull/6079) (modified to work)
- Fix docker build for stable [#6118](https://github.com/paritytech/parity/pull/6118)
- Backported wallet fix [#6104](https://github.com/paritytech/parity/pull/6104)
- Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102))
- Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103))
- Bump to v1.6.10
## Parity [v1.7.0](https://github.com/paritytech/parity/releases/tag/v1.7.0) (2017-07-23)
Parity 1.7.0 is a major release introducing several important features: Parity 1.7.0 is a major release introducing several important features:
- **Experimental [Light client](https://github.com/paritytech/parity/wiki/The-Parity-Light-Protocol-(PIP)) support**. Start Parity with `--light` to enable light mode. - **Experimental [Light client](https://github.com/paritytech/parity/wiki/The-Parity-Light-Protocol-(PIP)) support**. Start Parity with `--light` to enable light mode. Please, note: The wallet UI integration for the light client is not included, yet.
- **Experimental web wallet**. A hosted version of Parity that keeps the keys and signs transactions using your browser storage. Try it at https://wallet.parity.io or run your own with `--public-node`. - **Experimental web wallet**. A hosted version of Parity that keeps the keys and signs transactions using your browser storage. Try it at https://wallet.parity.io or run your own with `--public-node`.
- **WASM contract support**. Private networks can run contracts compiled into WASM bytecode. _More information and documentation to follow_. - **WASM contract support**. Private networks can run contracts compiled into WASM bytecode. _More information and documentation to follow_.
- **DApps and RPC server merge**. DApp and RPC are now available through a single API endpoint. DApp server related settings are deprecated. - **DApps and RPC server merge**. DApp and RPC are now available through a single API endpoint. DApp server related settings are deprecated.
- **Export accounts from the wallet**. Backing up your keys can now simply be managed through the wallet interface. - **Export accounts from the wallet**. Backing up your keys can now simply be managed through the wallet interface.
- **PoA/Kovan validator set contract**. The PoA network validator-set management via smart contract is now supported by warp and light sync. - **PoA/Kovan validator set contract**. The PoA network validator-set management via smart contract is now supported by warp and, in the near future, light sync.
- **PubSub API**. https://github.com/paritytech/parity/wiki/JSONRPC-Parity-Pub-Sub-module - **PubSub API**. https://github.com/paritytech/parity/wiki/JSONRPC-Parity-Pub-Sub-module
- **Signer apps for IOS and Android**. - **Signer apps for IOS and Android**.
Full list of included changes: Full list of included changes:
- Backports [#6163](https://github.com/paritytech/parity/pull/6163)
- Light client improvements ([#6156](https://github.com/paritytech/parity/pull/6156))
- No seal checking
- Import command and --no-seal-check for light client
- Fix eth_call
- Tweak registry dapps lookup
- Ignore failed requests to non-server peers
- Fix connecting to wildcard addresses. ([#6167](https://github.com/paritytech/parity/pull/6167))
- Don't display an overlay in case the time sync check fails. ([#6164](https://github.com/paritytech/parity/pull/6164))
- Small improvements to time estimation.
- Temporarily disable NTP time check by default.
- Light client fixes ([#6148](https://github.com/paritytech/parity/pull/6148)) [#6151](https://github.com/paritytech/parity/pull/6151)
- Light client fixes
- Fix memory-lru-cache
- Clear pending reqs on disconnect
- Filter tokens logs from current block, not genesis ([#6128](https://github.com/paritytech/parity/pull/6128)) [#6141](https://github.com/paritytech/parity/pull/6141)
- Fix QR scanner returning null on confirm [#6122](https://github.com/paritytech/parity/pull/6122)
- Check QR before lowercase ([#6119](https://github.com/paritytech/parity/pull/6119)) [#6120](https://github.com/paritytech/parity/pull/6120) - Check QR before lowercase ([#6119](https://github.com/paritytech/parity/pull/6119)) [#6120](https://github.com/paritytech/parity/pull/6120)
- Remove chunk to restore from pending set only upon successful import [#6117](https://github.com/paritytech/parity/pull/6117) - Remove chunk to restore from pending set only upon successful import [#6117](https://github.com/paritytech/parity/pull/6117)
- Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094) - Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094)
- Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095) - Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095)
- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108)
- Backported wallet fix [#6105](https://github.com/paritytech/parity/pull/6105) - Backported wallet fix [#6105](https://github.com/paritytech/parity/pull/6105)
- Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102)) - Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102))
- Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103)) - Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103))
- Place RETURNDATA behind block number gate [#6095](https://github.com/paritytech/parity/pull/6095)
- Fixed node address detection on incoming connection [#6094](https://github.com/paritytech/parity/pull/6094)
- Bump snap version and tweak importing detection logic ([#6079](https://github.com/paritytech/parity/pull/6079)) [#6081](https://github.com/paritytech/parity/pull/6081) - Bump snap version and tweak importing detection logic ([#6079](https://github.com/paritytech/parity/pull/6079)) [#6081](https://github.com/paritytech/parity/pull/6081)
- bump last tick just before printing info and restore sync detection - bump last tick just before printing info and restore sync detection
- bump kovan snapshot version - bump kovan snapshot version
@ -439,6 +443,23 @@ Full list of included changes:
- Update the Wallet Library Registry key [#4817](https://github.com/paritytech/parity/pull/4817) - Update the Wallet Library Registry key [#4817](https://github.com/paritytech/parity/pull/4817)
- Update Wallet to new Wallet Code [#4805](https://github.com/paritytech/parity/pull/4805) - Update Wallet to new Wallet Code [#4805](https://github.com/paritytech/parity/pull/4805)
## Parity [v1.6.10](https://github.com/paritytech/parity/releases/tag/v1.6.10) (2017-07-25)
This is a hotfix release for the stable channel addressing the recent [multi-signature wallet vulnerability](https://blog.parity.io/security-alert-high-2/). Note, upgrading is not mandatory, and all future multi-sig wallets created by any version of Parity are secure.
All Changes:
- Backports for stable [#6116](https://github.com/paritytech/parity/pull/6116)
- Remove chunk to restore from pending set only upon successful import [#6112](https://github.com/paritytech/parity/pull/6112)
- Blacklist bad snapshot manifest hashes upon failure [#5874](https://github.com/paritytech/parity/pull/5874)
- Bump snap version and tweak importing detection logic [#6079](https://github.com/paritytech/parity/pull/6079) (modified to work)
- Fix docker build for stable [#6118](https://github.com/paritytech/parity/pull/6118)
- Update wallet library binaries [#6108](https://github.com/paritytech/parity/pull/6108)
- Backported wallet fix [#6104](https://github.com/paritytech/parity/pull/6104)
- Fix initialisation bug. ([#6102](https://github.com/paritytech/parity/pull/6102))
- Update wallet library modifiers ([#6103](https://github.com/paritytech/parity/pull/6103))
- Bump to v1.6.10
## Parity [v1.6.9](https://github.com/paritytech/parity/releases/tag/v1.6.9) (2017-07-16) ## Parity [v1.6.9](https://github.com/paritytech/parity/releases/tag/v1.6.9) (2017-07-16)
This is a first stable release of 1.6 series. It contains a number of minor fixes and introduces the `--reseal-on-uncles` option for miners. This is a first stable release of 1.6 series. It contains a number of minor fixes and introduces the `--reseal-on-uncles` option for miners.

170
Cargo.lock generated
View File

@ -1,6 +1,15 @@
[root] [root]
name = "using_queue" name = "wasm"
version = "0.1.0" version = "0.1.0"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-logger 1.8.0",
"ethcore-util 1.8.0",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.12.1 (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)",
]
[[package]] [[package]]
name = "advapi32-sys" name = "advapi32-sys"
@ -116,10 +125,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bigint" name = "bigint"
version = "3.0.0" version = "4.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -181,6 +191,14 @@ name = "blastfig"
version = "0.3.3" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bloomable"
version = "0.1.0"
dependencies = [
"ethcore-bigint 0.1.3",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "bloomchain" name = "bloomchain"
version = "0.1.0" version = "0.1.0"
@ -220,6 +238,15 @@ name = "cfg-if"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chainspec"
version = "0.1.0"
dependencies = [
"ethjson 0.1.0",
"serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "cid" name = "cid"
version = "0.2.2" version = "0.2.2"
@ -271,9 +298,11 @@ dependencies = [
name = "common-types" name = "common-types"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bloomable 0.1.0",
"ethcore-util 1.8.0", "ethcore-util 1.8.0",
"ethjson 0.1.0", "ethjson 0.1.0",
"rlp 0.2.0", "rlp 0.2.0",
"rlp_derive 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -318,7 +347,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "crunchy" name = "crunchy"
version = "0.1.3" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -443,14 +472,14 @@ dependencies = [
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "ethash" name = "ethash"
version = "1.8.0" version = "1.8.0"
dependencies = [ dependencies = [
"crunchy 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -462,6 +491,7 @@ name = "ethcore"
version = "1.8.0" version = "1.8.0"
dependencies = [ dependencies = [
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit-set 0.4.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.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bn 0.4.4 (git+https://github.com/paritytech/bn)", "bn 0.4.4 (git+https://github.com/paritytech/bn)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -498,19 +528,24 @@ dependencies = [
"price-info 1.7.0", "price-info 1.7.0",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0", "rlp 0.2.0",
"rlp_derive 0.1.0",
"rust-crypto 0.2.36 (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)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0", "stats 0.1.0",
"table 0.1.0",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"using_queue 0.1.0",
"vm 0.1.0",
"wasm 0.1.0",
] ]
[[package]] [[package]]
name = "ethcore-bigint" name = "ethcore-bigint"
version = "0.1.3" version = "0.1.3"
dependencies = [ dependencies = [
"bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 4.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -620,11 +655,13 @@ dependencies = [
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0", "rlp 0.2.0",
"rlp_derive 0.1.0",
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"stats 0.1.0", "stats 0.1.0",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
] ]
[[package]] [[package]]
@ -656,6 +693,7 @@ dependencies = [
"ethcrypto 0.1.0", "ethcrypto 0.1.0",
"ethkey 0.2.0", "ethkey 0.2.0",
"igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -668,7 +706,7 @@ dependencies = [
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -689,6 +727,7 @@ dependencies = [
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.5 (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.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"native-contracts 0.1.0", "native-contracts 0.1.0",
"parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -738,7 +777,6 @@ dependencies = [
"ethcore-devtools 1.8.0", "ethcore-devtools 1.8.0",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"lru-cache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -751,11 +789,9 @@ dependencies = [
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"sha3 0.1.0", "sha3 0.1.0",
"table 0.1.0",
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"using_queue 0.1.0",
"vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -768,7 +804,7 @@ dependencies = [
"ethkey 0.2.0", "ethkey 0.2.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -776,7 +812,7 @@ name = "ethjson"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.8.0", "ethcore-bigint 0.1.3",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -794,7 +830,7 @@ dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (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)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -830,7 +866,7 @@ dependencies = [
"smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -862,6 +898,7 @@ dependencies = [
"ethcore-util 1.8.0", "ethcore-util 1.8.0",
"ethkey 0.2.0", "ethkey 0.2.0",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -878,6 +915,7 @@ dependencies = [
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0", "common-types 0.1.0",
"ethcore-logger 1.8.0",
"ethcore-util 1.8.0", "ethcore-util 1.8.0",
"ethjson 0.1.0", "ethjson 0.1.0",
"evmjit 1.8.0", "evmjit 1.8.0",
@ -886,6 +924,7 @@ dependencies = [
"parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0", "rlp 0.2.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (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)", "wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
] ]
@ -901,13 +940,14 @@ dependencies = [
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
] ]
[[package]] [[package]]
name = "evmjit" name = "evmjit"
version = "1.8.0" version = "1.8.0"
dependencies = [ dependencies = [
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1149,6 +1189,11 @@ dependencies = [
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ipnetwork"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "isatty" name = "isatty"
version = "0.1.1" version = "0.1.1"
@ -1175,7 +1220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "jsonrpc-core" name = "jsonrpc-core"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1187,7 +1232,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-http-server" name = "jsonrpc-http-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1200,7 +1245,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-ipc-server" name = "jsonrpc-ipc-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1213,7 +1258,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-macros" name = "jsonrpc-macros"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1223,7 +1268,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-minihttp-server" name = "jsonrpc-minihttp-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1238,7 +1283,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-pubsub" name = "jsonrpc-pubsub"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1248,7 +1293,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-server-utils" name = "jsonrpc-server-utils"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1261,7 +1306,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-tcp-server" name = "jsonrpc-tcp-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1275,7 +1320,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-ws-server" name = "jsonrpc-ws-server"
version = "7.0.0" version = "7.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#4d3ec22c7aba426988a678b489b2791e95283699" source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#b5490782884218c5ccf74cd61e54904cb3a3aeed"
dependencies = [ dependencies = [
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1504,7 +1549,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"ring 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1539,7 +1584,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.8.0", "ethcore-bigint 0.1.3",
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"native-contract-generator 0.1.0", "native-contract-generator 0.1.0",
] ]
@ -1745,7 +1790,7 @@ dependencies = [
[[package]] [[package]]
name = "parity" name = "parity"
version = "1.7.0" version = "1.8.0"
dependencies = [ dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1763,6 +1808,7 @@ dependencies = [
"ethcore-ipc-tests 0.1.0", "ethcore-ipc-tests 0.1.0",
"ethcore-light 1.8.0", "ethcore-light 1.8.0",
"ethcore-logger 1.8.0", "ethcore-logger 1.8.0",
"ethcore-network 1.8.0",
"ethcore-secretstore 1.0.0", "ethcore-secretstore 1.0.0",
"ethcore-stratum 1.8.0", "ethcore-stratum 1.8.0",
"ethcore-util 1.8.0", "ethcore-util 1.8.0",
@ -1771,6 +1817,7 @@ dependencies = [
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1816,6 +1863,7 @@ dependencies = [
"fetch 0.1.0", "fetch 0.1.0",
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1924,10 +1972,10 @@ dependencies = [
"ethkey 0.2.0", "ethkey 0.2.0",
"ethstore 0.1.0", "ethstore 0.1.0",
"ethsync 1.8.0", "ethsync 1.8.0",
"evm 0.1.0",
"fetch 0.1.0", "fetch 0.1.0",
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
"jsonrpc-ipc-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-ipc-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
@ -1953,6 +2001,7 @@ dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"transient-hashmap 0.4.0 (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",
] ]
[[package]] [[package]]
@ -2009,7 +2058,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-ui-precompiled" name = "parity-ui-precompiled"
version = "1.4.0" version = "1.4.0"
source = "git+https://github.com/paritytech/js-precompiled.git#5a357d01c459d3f371a87bfa138567b30603222c" source = "git+https://github.com/paritytech/js-precompiled.git#416ced84c23b1a776d53ee4a3023eb4eb4736cf8"
dependencies = [ dependencies = [
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2070,7 +2119,7 @@ dependencies = [
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -2165,10 +2214,10 @@ dependencies = [
name = "price-info" name = "price-info"
version = "1.7.0" version = "1.7.0"
dependencies = [ dependencies = [
"ethcore-util 1.8.0",
"fetch 0.1.0", "fetch 0.1.0",
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2261,7 +2310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "quote" name = "quote"
version = "0.3.10" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -2352,6 +2401,15 @@ dependencies = [
"rustc-hex 1.0.0 (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 = "rlp_derive"
version = "0.1.0"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "rocksdb" name = "rocksdb"
version = "0.4.5" version = "0.4.5"
@ -2409,7 +2467,7 @@ dependencies = [
name = "rpc-cli" name = "rpc-cli"
version = "1.4.0" version = "1.4.0"
dependencies = [ dependencies = [
"bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 4.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.8.0", "ethcore-util 1.8.0",
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-rpc 1.8.0", "parity-rpc 1.8.0",
@ -2544,7 +2602,7 @@ name = "serde_derive"
version = "1.0.9" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2558,6 +2616,14 @@ dependencies = [
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "serde_ignored"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.2" version = "1.0.2"
@ -2678,7 +2744,7 @@ name = "syn"
version = "0.11.11" version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2812,7 +2878,7 @@ dependencies = [
[[package]] [[package]]
name = "tiny-keccak" name = "tiny-keccak"
version = "1.2.1" version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -3035,6 +3101,10 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "using_queue"
version = "0.1.0"
[[package]] [[package]]
name = "utf8-ranges" name = "utf8-ranges"
version = "1.0.0" version = "1.0.0"
@ -3063,6 +3133,20 @@ dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "vm"
version = "0.1.0"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0",
"ethcore-util 1.8.0",
"ethjson 0.1.0",
"evmjit 1.8.0",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0",
]
[[package]] [[package]]
name = "void" name = "void"
version = "1.0.2" version = "1.0.2"
@ -3071,7 +3155,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "wasm-utils" name = "wasm-utils"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/paritytech/wasm-utils#fee06b6d5826c2dc1fc1aa183b0c2c75e3e140c3" source = "git+https://github.com/paritytech/wasm-utils#9462bcc0680f0ec2c876abdf75bae981dd4344a5"
dependencies = [ dependencies = [
"clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3161,7 +3245,7 @@ dependencies = [
"checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff" "checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff"
"checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1" "checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1"
"checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c" "checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c"
"checksum bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0673c930652d3d4d6dcd5c45b5db4fa5f8f33994d7323618c43c083b223e8c" "checksum bigint 4.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c9f1cd09cdcafcccdab1fd58797d39b7d4d203238b2e3768807590723bdf0"
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e" "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
"checksum bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6e1e6fb1c9e3d6fcdec57216a74eaa03e41f52a22f13a16438251d8e88b89da" "checksum bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6e1e6fb1c9e3d6fcdec57216a74eaa03e41f52a22f13a16438251d8e88b89da"
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
@ -3186,7 +3270,7 @@ dependencies = [
"checksum core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20a6d0448d3a99d977ae4a2aa5a98d886a923e863e81ad9ff814645b6feb3bbd" "checksum core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20a6d0448d3a99d977ae4a2aa5a98d886a923e863e81ad9ff814645b6feb3bbd"
"checksum core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05eed248dc504a5391c63794fe4fb64f46f071280afaa1b73308f3c0ce4574c5" "checksum core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05eed248dc504a5391c63794fe4fb64f46f071280afaa1b73308f3c0ce4574c5"
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
"checksum crunchy 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6aa9cb5f2d7bffc4eecfaf924fe450549dc4f0c3a6502298dc24f968b1eabbe" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec"
"checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "<none>" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "<none>"
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" "checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
@ -3226,6 +3310,7 @@ dependencies = [
"checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76" "checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76"
"checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb" "checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb"
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
"checksum ipnetwork 0.12.6 (registry+https://github.com/rust-lang/crates.io-index)" = "232e76922883005380e831068f731ef0305541c9f77b30df3a1635047b16f370"
"checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c" "checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c"
"checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a" "checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a"
"checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5" "checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5"
@ -3313,7 +3398,7 @@ dependencies = [
"checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd" "checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd"
"checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c" "checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c"
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a" "checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
"checksum quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6732e32663c9c271bfc7c1823486b471f18c47a2dbf87c066897b7b51afc83be" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" "checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
"checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20" "checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"
"checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8" "checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"
@ -3345,6 +3430,7 @@ dependencies = [
"checksum serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c6b751a2e8d5df57a5ff71b5b4fc8aaee9ee28ff1341d640dd130bb5f4f7a" "checksum serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c6b751a2e8d5df57a5ff71b5b4fc8aaee9ee28ff1341d640dd130bb5f4f7a"
"checksum serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f6ca58905ebd3c3b285a8a6d4f3ac92b92c0d7951d5649b1bdd212549c06639" "checksum serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f6ca58905ebd3c3b285a8a6d4f3ac92b92c0d7951d5649b1bdd212549c06639"
"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
"checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
"checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" "checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b"
"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480"
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
@ -3375,7 +3461,7 @@ dependencies = [
"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
"checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" "checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af"
"checksum tiny-keccak 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b50173faa6ee499206f77b189d7ff3bef40f6969f228c9ec22b82080df9aa41" "checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292"
"checksum tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e958104a67877907c1454386d5482fe8e965a55d60be834a15a44328e7dc76" "checksum tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e958104a67877907c1454386d5482fe8e965a55d60be834a15a44328e7dc76"
"checksum tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "48f55df1341bb92281f229a6030bc2abffde2c7a44c6d6b802b7687dd8be0775" "checksum tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "48f55df1341bb92281f229a6030bc2abffde2c7a44c6d6b802b7687dd8be0775"
"checksum tokio-minihttp 0.1.0 (git+https://github.com/tomusdrw/tokio-minihttp)" = "<none>" "checksum tokio-minihttp 0.1.0 (git+https://github.com/tomusdrw/tokio-minihttp)" = "<none>"

View File

@ -1,7 +1,7 @@
[package] [package]
description = "Parity Ethereum client" description = "Parity Ethereum client"
name = "parity" name = "parity"
version = "1.7.0" version = "1.8.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
@ -41,6 +41,7 @@ ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
ethcore-light = { path = "ethcore/light" } ethcore-light = { path = "ethcore/light" }
ethcore-logger = { path = "logger" } ethcore-logger = { path = "logger" }
ethcore-stratum = { path = "stratum" } ethcore-stratum = { path = "stratum" }
ethcore-network = { path = "util/network" }
ethkey = { path = "ethkey" } ethkey = { path = "ethkey" }
rlp = { path = "util/rlp" } rlp = { path = "util/rlp" }
rpc-cli = { path = "rpc_cli" } rpc-cli = { path = "rpc_cli" }
@ -65,6 +66,7 @@ rustc_version = "0.2"
[dev-dependencies] [dev-dependencies]
ethcore-ipc-tests = { path = "ipc/tests" } ethcore-ipc-tests = { path = "ipc/tests" }
pretty_assertions = "0.1" pretty_assertions = "0.1"
ipnetwork = "0.12.6"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = "0.2" winapi = "0.2"
@ -108,4 +110,4 @@ lto = false
panic = "abort" panic = "abort"
[workspace] [workspace]
members = ["ethstore/cli", "ethkey/cli", "evmbin", "whisper"] members = ["ethstore/cli", "ethkey/cli", "evmbin", "whisper", "chainspec"]

View File

@ -1,61 +1,47 @@
# [Parity](https://parity.io/parity.html) # [Parity](https://parity.io/parity.html) - fast, light, and robust Ethereum client
### Fast, light, and robust Ethereum implementation
### [Download latest release](https://github.com/paritytech/parity/releases) [![build status](https://gitlab.parity.io/parity/parity/badges/master/build.svg)](https://gitlab.parity.io/parity/parity/commits/master)
[![Snap Status](https://build.snapcraft.io/badge/paritytech/parity.svg)](https://build.snapcraft.io/user/paritytech/parity)
[![GPLv3](https://img.shields.io/badge/license-GPL%20v3-green.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html)
[![build status](https://gitlab.parity.io/parity/parity/badges/master/build.svg)](https://gitlab.parity.io/parity/parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![GPLv3][license-image]][license-url] [![Snap Status](https://build.snapcraft.io/badge/paritytech/parity.svg)](https://build.snapcraft.io/user/paritytech/parity) - [Download the latest release here.](https://github.com/paritytech/parity/releases)
### Join the chat! ### Join the chat!
Parity [![Join the chat at https://gitter.im/ethcore/parity][gitter-image]][gitter-url] and Get in touch with us on Gitter:
parity.js [![Join the chat at https://gitter.im/ethcore/parity.js](https://badges.gitter.im/ethcore/parity.js.svg)](https://gitter.im/ethcore/parity.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Gitter: Parity](https://img.shields.io/badge/gitter-parity-4AB495.svg)](https://gitter.im/paritytech/parity)
[![Gitter: Parity.js](https://img.shields.io/badge/gitter-parity.js-4AB495.svg)](https://gitter.im/paritytech/parity.js)
[Internal Documentation][doc-url] [![Gitter: Parity/Miners](https://img.shields.io/badge/gitter-parity/miners-4AB495.svg)](https://gitter.im/paritytech/parity/miners)
[![Gitter: Parity-PoA](https://img.shields.io/badge/gitter-parity--poa-4AB495.svg)](https://gitter.im/paritytech/parity-poa)
Be sure to check out [our wiki][wiki-url] for more information.
[coveralls-image]: https://coveralls.io/repos/github/paritytech/parity/badge.svg?branch=master
[coveralls-url]: https://coveralls.io/github/paritytech/parity?branch=master
[gitter-image]: https://badges.gitter.im/Join%20Chat.svg
[gitter-url]: https://gitter.im/ethcore/parity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[license-image]: https://img.shields.io/badge/license-GPL%20v3-green.svg
[license-url]: https://www.gnu.org/licenses/gpl-3.0.en.html
[doc-url]: https://paritytech.github.io/parity/ethcore/index.html
[wiki-url]: https://github.com/paritytech/parity/wiki
Be sure to check out [our wiki](https://github.com/paritytech/parity/wiki) and the [internal documentation](https://paritytech.github.io/parity/ethcore/index.html) for more information.
---- ----
## About Parity ## About Parity
Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs.
cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs.
Parity comes with a built-in wallet. To access [Parity Wallet](http://web3.site/) simply go to http://web3.site/ (if you don't have access to the internet, but still want to use the service, you can also use http://127.0.0.1:8180/). It includes various functionality allowing you to:
Parity comes with a built-in wallet. To access [Parity Wallet](http://web3.site/) simply go to http://web3.site/ (if you don't have access to the internet, but still want to use the service, you can also use http://127.0.0.1:8180/). It
includes various functionality allowing you to:
- create and manage your Ethereum accounts; - create and manage your Ethereum accounts;
- manage your Ether and any Ethereum tokens; - manage your Ether and any Ethereum tokens;
- create and register your own tokens; - create and register your own tokens;
- and much more. - and much more.
By default, Parity will also run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number By default, Parity will also run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number of RPC APIs.
of RPC APIs.
If you run into an issue while using parity, feel free to file one in this repository If you run into an issue while using parity, feel free to file one in this repository or hop on our [gitter chat room](https://gitter.im/paritytech/parity) to ask a question. We are glad to help!
or hop on our [gitter chat room][gitter-url] to ask a question. We are glad to help!
**For security-critical issues**, please refer to the security policy outlined in `SECURITY.MD`. **For security-critical issues**, please refer to the security policy outlined in `SECURITY.MD`.
Parity's current release is 1.6. You can download it at https://github.com/paritytech/parity/releases or follow the instructions Parity's current release is 1.7. You can download it at https://github.com/paritytech/parity/releases or follow the instructions below to build from source.
below to build from source.
---- ----
## Build dependencies ## Build dependencies
**Parity requires Rust version 1.18.0 to build** **Parity requires Rust version 1.19.0 to build**
We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have rustup, you can install it like this: We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have rustup, you can install it like this:

9
chainspec/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "chainspec"
version = "0.1.0"
authors = ["debris <marek.kotewicz@gmail.com>"]
[dependencies]
ethjson = { path = "../json" }
serde_json = "1.0"
serde_ignored = "0.0.4"

48
chainspec/src/main.rs Normal file
View File

@ -0,0 +1,48 @@
extern crate serde_json;
extern crate serde_ignored;
extern crate ethjson;
use std::collections::BTreeSet;
use std::{fs, env, process};
use ethjson::spec::Spec;
fn quit(s: &str) -> ! {
println!("{}", s);
process::exit(1);
}
fn main() {
let mut args = env::args();
if args.len() != 2 {
quit("You need to specify chainspec.json\n\
\n\
./chainspec <chainspec.json>");
}
let path = args.nth(1).expect("args.len() == 2; qed");
let file = match fs::File::open(&path) {
Ok(file) => file,
Err(_) => quit(&format!("{} could not be opened", path)),
};
let mut unused = BTreeSet::new();
let mut deserializer = serde_json::Deserializer::from_reader(file);
let spec: Result<Spec, _> = serde_ignored::deserialize(&mut deserializer, |field| {
unused.insert(field.to_string());
});
if let Err(err) = spec {
quit(&format!("{} {}", path, err.to_string()));
}
if !unused.is_empty() {
let err = unused.into_iter()
.map(|field| format!("{} unexpected field `{}`", path, field))
.collect::<Vec<_>>()
.join("\n");
quit(&err);
}
println!("{} is valid", path);
}

View File

@ -27,6 +27,7 @@ time = "0.1.35"
unicase = "1.3" unicase = "1.3"
url = "1.0" url = "1.0"
zip = { version = "0.1", default-features = false } zip = { version = "0.1", default-features = false }
itertools = "0.5"
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" } jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" } jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }

View File

@ -21,7 +21,7 @@ use hyper::method::Method;
use hyper::status::StatusCode; use hyper::status::StatusCode;
use api::{response, types}; use api::{response, types};
use api::time::TimeChecker; use api::time::{TimeChecker, MAX_DRIFT};
use apps::fetcher::Fetcher; use apps::fetcher::Fetcher;
use handlers::{self, extract_url}; use handlers::{self, extract_url};
use endpoint::{Endpoint, Handler, EndpointPath}; use endpoint::{Endpoint, Handler, EndpointPath};
@ -122,7 +122,6 @@ impl RestApiRouter {
// Check time // Check time
let time = { let time = {
const MAX_DRIFT: i64 = 500;
let (status, message, details) = match time { let (status, message, details) = match time {
Ok(Ok(diff)) if diff < MAX_DRIFT && diff > -MAX_DRIFT => { Ok(Ok(diff)) if diff < MAX_DRIFT && diff > -MAX_DRIFT => {
(HealthStatus::Ok, "".into(), diff) (HealthStatus::Ok, "".into(), diff)

View File

@ -33,17 +33,22 @@
use std::io; use std::io;
use std::{fmt, mem, time}; use std::{fmt, mem, time};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::atomic::{self, AtomicUsize};
use std::sync::Arc;
use futures::{self, Future, BoxFuture}; use futures::{self, Future, BoxFuture};
use futures_cpupool::CpuPool; use futures::future::{self, IntoFuture};
use futures_cpupool::{CpuPool, CpuFuture};
use ntp; use ntp;
use time::{Duration, Timespec}; use time::{Duration, Timespec};
use util::{Arc, RwLock}; use util::RwLock;
/// Time checker error. /// Time checker error.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum Error { pub enum Error {
/// No servers are currently available for a query.
NoServersAvailable,
/// There was an error when trying to reach the NTP server. /// There was an error when trying to reach the NTP server.
Ntp(String), Ntp(String),
/// IO error when reading NTP response. /// IO error when reading NTP response.
@ -55,6 +60,7 @@ impl fmt::Display for Error {
use self::Error::*; use self::Error::*;
match *self { match *self {
NoServersAvailable => write!(fmt, "No NTP servers available"),
Ntp(ref err) => write!(fmt, "NTP error: {}", err), Ntp(ref err) => write!(fmt, "NTP error: {}", err),
Io(ref err) => write!(fmt, "Connection Error: {}", err), Io(ref err) => write!(fmt, "Connection Error: {}", err),
} }
@ -71,58 +77,123 @@ impl From<ntp::errors::Error> for Error {
/// NTP time drift checker. /// NTP time drift checker.
pub trait Ntp { pub trait Ntp {
/// Returned Future.
type Future: IntoFuture<Item=Duration, Error=Error>;
/// Returns the current time drift. /// Returns the current time drift.
fn drift(&self) -> BoxFuture<Duration, Error>; fn drift(&self) -> Self::Future;
}
const SERVER_MAX_POLL_INTERVAL_SECS: u64 = 60;
#[derive(Debug)]
struct Server {
pub address: String,
next_call: RwLock<time::Instant>,
failures: AtomicUsize,
}
impl Server {
pub fn is_available(&self) -> bool {
*self.next_call.read() < time::Instant::now()
}
pub fn report_success(&self) {
self.failures.store(0, atomic::Ordering::SeqCst);
self.update_next_call(1)
}
pub fn report_failure(&self) {
let errors = self.failures.fetch_add(1, atomic::Ordering::SeqCst);
self.update_next_call(1 << errors)
}
fn update_next_call(&self, delay: usize) {
*self.next_call.write() = time::Instant::now() + time::Duration::from_secs(delay as u64 * SERVER_MAX_POLL_INTERVAL_SECS);
}
}
impl<T: AsRef<str>> From<T> for Server {
fn from(t: T) -> Self {
Server {
address: t.as_ref().to_owned(),
next_call: RwLock::new(time::Instant::now()),
failures: Default::default(),
}
}
} }
/// NTP client using the SNTP algorithm for calculating drift. /// NTP client using the SNTP algorithm for calculating drift.
#[derive(Clone)] #[derive(Clone)]
pub struct SimpleNtp { pub struct SimpleNtp {
address: Arc<String>, addresses: Vec<Arc<Server>>,
pool: CpuPool, pool: CpuPool,
} }
impl fmt::Debug for SimpleNtp { impl fmt::Debug for SimpleNtp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Ntp {{ address: {} }}", self.address) f
.debug_struct("SimpleNtp")
.field("addresses", &self.addresses)
.finish()
} }
} }
impl SimpleNtp { impl SimpleNtp {
fn new(address: &str, pool: CpuPool) -> SimpleNtp { fn new<T: AsRef<str>>(addresses: &[T], pool: CpuPool) -> SimpleNtp {
SimpleNtp { SimpleNtp {
address: Arc::new(address.to_owned()), addresses: addresses.iter().map(Server::from).map(Arc::new).collect(),
pool: pool, pool: pool,
} }
} }
} }
impl Ntp for SimpleNtp { impl Ntp for SimpleNtp {
fn drift(&self) -> BoxFuture<Duration, Error> { type Future = future::Either<
let address = self.address.clone(); CpuFuture<Duration, Error>,
if &*address == "none" { future::FutureResult<Duration, Error>,
return futures::future::err(Error::Ntp("NTP server is not provided.".into())).boxed(); >;
}
self.pool.spawn_fn(move || { fn drift(&self) -> Self::Future {
let packet = ntp::request(&*address)?; use self::future::Either::{A, B};
let dest_time = ::time::now_utc().to_timespec();
let orig_time = Timespec::from(packet.orig_time);
let recv_time = Timespec::from(packet.recv_time);
let transmit_time = Timespec::from(packet.transmit_time);
let drift = ((recv_time - orig_time) + (transmit_time - dest_time)) / 2; let server = self.addresses.iter().find(|server| server.is_available());
server.map(|server| {
let server = server.clone();
A(self.pool.spawn_fn(move || {
debug!(target: "dapps", "Fetching time from {}.", server.address);
Ok(drift) match ntp::request(&server.address) {
}).boxed() Ok(packet) => {
let dest_time = ::time::now_utc().to_timespec();
let orig_time = Timespec::from(packet.orig_time);
let recv_time = Timespec::from(packet.recv_time);
let transmit_time = Timespec::from(packet.transmit_time);
let drift = ((recv_time - orig_time) + (transmit_time - dest_time)) / 2;
server.report_success();
Ok(drift)
},
Err(err) => {
server.report_failure();
Err(err.into())
},
}
}))
}).unwrap_or_else(|| B(future::err(Error::NoServersAvailable)))
} }
} }
// NOTE In a positive scenario first results will be seen after: // NOTE In a positive scenario first results will be seen after:
// MAX_RESULTS * UPDATE_TIMEOUT_OK_SECS seconds. // MAX_RESULTS * UPDATE_TIMEOUT_INCOMPLETE_SECS seconds.
const MAX_RESULTS: usize = 7; const MAX_RESULTS: usize = 4;
const UPDATE_TIMEOUT_OK_SECS: u64 = 30; const UPDATE_TIMEOUT_OK_SECS: u64 = 6 * 60 * 60;
const UPDATE_TIMEOUT_ERR_SECS: u64 = 2; const UPDATE_TIMEOUT_WARN_SECS: u64 = 15 * 60;
const UPDATE_TIMEOUT_ERR_SECS: u64 = 60;
const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10;
/// Maximal valid time drift.
pub const MAX_DRIFT: i64 = 500;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
/// A time checker. /// A time checker.
@ -133,13 +204,13 @@ pub struct TimeChecker<N: Ntp = SimpleNtp> {
impl TimeChecker<SimpleNtp> { impl TimeChecker<SimpleNtp> {
/// Creates new time checker given the NTP server address. /// Creates new time checker given the NTP server address.
pub fn new(ntp_address: String, pool: CpuPool) -> Self { pub fn new<T: AsRef<str>>(ntp_addresses: &[T], pool: CpuPool) -> Self {
let last_result = Arc::new(RwLock::new( let last_result = Arc::new(RwLock::new(
// Assume everything is ok at the very beginning. // Assume everything is ok at the very beginning.
(time::Instant::now(), vec![Ok(0)].into()) (time::Instant::now(), vec![Ok(0)].into())
)); ));
let ntp = SimpleNtp::new(&ntp_address, pool); let ntp = SimpleNtp::new(ntp_addresses, pool);
TimeChecker { TimeChecker {
ntp, ntp,
@ -148,22 +219,34 @@ impl TimeChecker<SimpleNtp> {
} }
} }
impl<N: Ntp> TimeChecker<N> { impl<N: Ntp> TimeChecker<N> where <N::Future as IntoFuture>::Future: Send + 'static {
/// Updates the time /// Updates the time
pub fn update(&self) -> BoxFuture<i64, Error> { pub fn update(&self) -> BoxFuture<i64, Error> {
trace!(target: "dapps", "Updating time from NTP.");
let last_result = self.last_result.clone(); let last_result = self.last_result.clone();
self.ntp.drift().then(move |res| { self.ntp.drift().into_future().then(move |res| {
let res = res.map(|d| d.num_milliseconds());
if let Err(Error::NoServersAvailable) = res {
debug!(target: "dapps", "No NTP servers available. Selecting an older result.");
return select_result(last_result.read().1.iter());
}
// Update the results.
let mut results = mem::replace(&mut last_result.write().1, VecDeque::new()); let mut results = mem::replace(&mut last_result.write().1, VecDeque::new());
let has_all_results = results.len() >= MAX_RESULTS;
let valid_till = time::Instant::now() + time::Duration::from_secs( let valid_till = time::Instant::now() + time::Duration::from_secs(
if res.is_ok() && results.len() == MAX_RESULTS { match res {
UPDATE_TIMEOUT_OK_SECS Ok(time) if has_all_results && time < MAX_DRIFT => UPDATE_TIMEOUT_OK_SECS,
} else { Ok(_) if has_all_results => UPDATE_TIMEOUT_WARN_SECS,
UPDATE_TIMEOUT_ERR_SECS Err(_) if has_all_results => UPDATE_TIMEOUT_ERR_SECS,
_ => UPDATE_TIMEOUT_INCOMPLETE_SECS,
} }
); );
trace!(target: "dapps", "New time drift received: {:?}", res);
// Push the result. // Push the result.
results.push_back(res.map(|d| d.num_milliseconds())); results.push_back(res);
while results.len() > MAX_RESULTS { while results.len() > MAX_RESULTS {
results.pop_front(); results.pop_front();
} }
@ -208,7 +291,7 @@ mod tests {
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::time::Instant; use std::time::Instant;
use time::Duration; use time::Duration;
use futures::{self, BoxFuture, Future}; use futures::{future, Future};
use super::{Ntp, TimeChecker, Error}; use super::{Ntp, TimeChecker, Error};
use util::RwLock; use util::RwLock;
@ -223,9 +306,11 @@ mod tests {
} }
impl Ntp for FakeNtp { impl Ntp for FakeNtp {
fn drift(&self) -> BoxFuture<Duration, Error> { type Future = future::FutureResult<Duration, Error>;
fn drift(&self) -> Self::Future {
self.1.set(self.1.get() + 1); self.1.set(self.1.get() + 1);
futures::future::ok(self.0.borrow_mut().pop().expect("Unexpected call to drift().")).boxed() future::ok(self.0.borrow_mut().pop().expect("Unexpected call to drift()."))
} }
} }

View File

@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
@ -30,8 +29,8 @@ use {WebProxyTokens, ParentFrameSettings};
mod app; mod app;
mod cache; mod cache;
mod fs;
mod ui; mod ui;
pub mod fs;
pub mod fetcher; pub mod fetcher;
pub mod manifest; pub mod manifest;
@ -64,9 +63,10 @@ pub fn all_endpoints<F: Fetch>(
web_proxy_tokens: Arc<WebProxyTokens>, web_proxy_tokens: Arc<WebProxyTokens>,
remote: Remote, remote: Remote,
fetch: F, fetch: F,
) -> Endpoints { ) -> (Vec<String>, Endpoints) {
// fetch fs dapps at first to avoid overwriting builtins // fetch fs dapps at first to avoid overwriting builtins
let mut pages = fs::local_endpoints(dapps_path, embeddable.clone()); let mut pages = fs::local_endpoints(dapps_path.clone(), embeddable.clone());
let local_endpoints: Vec<String> = pages.keys().cloned().collect();
for path in extra_dapps { for path in extra_dapps {
if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), embeddable.clone()) { if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), embeddable.clone()) {
pages.insert(id, endpoint); pages.insert(id, endpoint);
@ -80,10 +80,10 @@ pub fn all_endpoints<F: Fetch>(
pages.insert("proxy".into(), ProxyPac::boxed(embeddable.clone(), dapps_domain.to_owned())); pages.insert("proxy".into(), ProxyPac::boxed(embeddable.clone(), dapps_domain.to_owned()));
pages.insert(WEB_PATH.into(), Web::boxed(embeddable.clone(), web_proxy_tokens.clone(), remote.clone(), fetch.clone())); pages.insert(WEB_PATH.into(), Web::boxed(embeddable.clone(), web_proxy_tokens.clone(), remote.clone(), fetch.clone()));
Arc::new(pages) (local_endpoints, pages)
} }
fn insert<T : WebApp + Default + 'static>(pages: &mut BTreeMap<String, Box<Endpoint>>, id: &str, embed_at: Embeddable) { fn insert<T : WebApp + Default + 'static>(pages: &mut Endpoints, id: &str, embed_at: Embeddable) {
pages.insert(id.to_owned(), Box::new(match embed_at { pages.insert(id.to_owned(), Box::new(match embed_at {
Embeddable::Yes(address) => PageEndpoint::new_safe_to_embed(T::default(), address), Embeddable::Yes(address) => PageEndpoint::new_safe_to_embed(T::default(), address),
Embeddable::No => PageEndpoint::new(T::default()), Embeddable::No => PageEndpoint::new(T::default()),

View File

@ -16,7 +16,6 @@
//! URL Endpoint traits //! URL Endpoint traits
use std::sync::Arc;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use hyper::{self, server, net}; use hyper::{self, server, net};
@ -39,7 +38,7 @@ pub struct EndpointInfo {
pub icon_url: String, pub icon_url: String,
} }
pub type Endpoints = Arc<BTreeMap<String, Box<Endpoint>>>; pub type Endpoints = BTreeMap<String, Box<Endpoint>>;
pub type Handler = server::Handler<net::HttpStream> + Send; pub type Handler = server::Handler<net::HttpStream> + Send;
pub trait Endpoint : Send + Sync { pub trait Endpoint : Send + Sync {

View File

@ -31,8 +31,7 @@ pub use self::redirect::Redirection;
pub use self::streaming::StreamingHandler; pub use self::streaming::StreamingHandler;
use std::iter; use std::iter;
use util::Itertools; use itertools::Itertools;
use url::Url; use url::Url;
use hyper::{server, header, net, uri}; use hyper::{server, header, net, uri};
use {apps, address, Embeddable}; use {apps, address, Embeddable};
@ -67,10 +66,20 @@ pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embedd
// Allow fonts from data: and HTTPS. // Allow fonts from data: and HTTPS.
b"font-src 'self' data: https:;".to_vec(), b"font-src 'self' data: https:;".to_vec(),
// Allow inline scripts and scripts eval (webpack/jsconsole) // Allow inline scripts and scripts eval (webpack/jsconsole)
b"script-src 'self' 'unsafe-inline' 'unsafe-eval';".to_vec(), {
// Same restrictions as script-src (fallback) with additional let script_src = embeddable_on.as_ref()
.map(|e| e.extra_script_src.iter()
.map(|&(ref host, port)| address(host, port))
.join(" ")
).unwrap_or_default();
format!(
"script-src 'self' 'unsafe-inline' 'unsafe-eval' {};",
script_src
).into_bytes()
},
// Same restrictions as script-src with additional
// blob: that is required for camera access (worker) // blob: that is required for camera access (worker)
b"worker-src 'self' 'unsafe-inline' 'unsafe-eval' blob: ;".to_vec(), b"worker-src 'self' 'unsafe-inline' 'unsafe-eval' https: blob:;".to_vec(),
// Restrict everything else to the same origin. // Restrict everything else to the same origin.
b"default-src 'self';".to_vec(), b"default-src 'self';".to_vec(),
// Run in sandbox mode (although it's not fully safe since we allow same-origin and script) // Run in sandbox mode (although it's not fully safe since we allow same-origin and script)
@ -90,7 +99,7 @@ pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embedd
.into_iter() .into_iter()
.chain(embed.extra_embed_on .chain(embed.extra_embed_on
.iter() .iter()
.map(|&(ref host, port)| format!("{}:{}", host, port)) .map(|&(ref host, port)| address(host, port))
); );
let ancestors = if embed.host == "127.0.0.1" { let ancestors = if embed.host == "127.0.0.1" {

View File

@ -22,6 +22,7 @@
extern crate base32; extern crate base32;
extern crate futures; extern crate futures;
extern crate futures_cpupool; extern crate futures_cpupool;
extern crate itertools;
extern crate linked_hash_map; extern crate linked_hash_map;
extern crate mime_guess; extern crate mime_guess;
extern crate ntp; extern crate ntp;
@ -69,9 +70,11 @@ mod web;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use std::collections::HashMap;
use std::mem;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use std::collections::HashMap; use util::RwLock;
use jsonrpc_http_server::{self as http, hyper, Origin}; use jsonrpc_http_server::{self as http, hyper, Origin};
@ -101,36 +104,59 @@ impl<F> WebProxyTokens for F where F: Fn(String) -> Option<Origin> + Send + Sync
} }
/// Current supported endpoints. /// Current supported endpoints.
#[derive(Default, Clone)]
pub struct Endpoints { pub struct Endpoints {
endpoints: endpoint::Endpoints, local_endpoints: Arc<RwLock<Vec<String>>>,
endpoints: Arc<RwLock<endpoint::Endpoints>>,
dapps_path: PathBuf,
embeddable: Option<ParentFrameSettings>,
} }
impl Endpoints { impl Endpoints {
/// Returns a current list of app endpoints. /// Returns a current list of app endpoints.
pub fn list(&self) -> Vec<apps::App> { pub fn list(&self) -> Vec<apps::App> {
self.endpoints.iter().filter_map(|(ref k, ref e)| { self.endpoints.read().iter().filter_map(|(ref k, ref e)| {
e.info().map(|ref info| apps::App::from_info(k, info)) e.info().map(|ref info| apps::App::from_info(k, info))
}).collect() }).collect()
} }
/// Check for any changes in the local dapps folder and update.
pub fn refresh_local_dapps(&self) {
let new_local = apps::fs::local_endpoints(&self.dapps_path, self.embeddable.clone());
let old_local = mem::replace(&mut *self.local_endpoints.write(), new_local.keys().cloned().collect());
let (_, to_remove): (_, Vec<_>) = old_local
.into_iter()
.partition(|k| new_local.contains_key(&k.clone()));
let mut endpoints = self.endpoints.write();
// remove the dead dapps
for k in to_remove {
endpoints.remove(&k);
}
// new dapps to be added
for (k, v) in new_local {
if !endpoints.contains_key(&k) {
endpoints.insert(k, v);
}
}
}
} }
/// Dapps server as `jsonrpc-http-server` request middleware. /// Dapps server as `jsonrpc-http-server` request middleware.
pub struct Middleware { pub struct Middleware {
endpoints: Endpoints,
router: router::Router, router: router::Router,
endpoints: endpoint::Endpoints,
} }
impl Middleware { impl Middleware {
/// Get local endpoints handle. /// Get local endpoints handle.
pub fn endpoints(&self) -> Endpoints { pub fn endpoints(&self) -> &Endpoints {
Endpoints { &self.endpoints
endpoints: self.endpoints.clone(),
}
} }
/// Creates new middleware for UI server. /// Creates new middleware for UI server.
pub fn ui<F: Fetch>( pub fn ui<F: Fetch>(
ntp_server: &str, ntp_servers: &[String],
pool: CpuPool, pool: CpuPool,
remote: Remote, remote: Remote,
dapps_domain: &str, dapps_domain: &str,
@ -146,7 +172,7 @@ impl Middleware {
).embeddable_on(None).allow_dapps(false)); ).embeddable_on(None).allow_dapps(false));
let special = { let special = {
let mut special = special_endpoints( let mut special = special_endpoints(
ntp_server, ntp_servers,
pool, pool,
content_fetcher.clone(), content_fetcher.clone(),
remote.clone(), remote.clone(),
@ -164,18 +190,19 @@ impl Middleware {
); );
Middleware { Middleware {
router: router,
endpoints: Default::default(), endpoints: Default::default(),
router: router,
} }
} }
/// Creates new Dapps server middleware. /// Creates new Dapps server middleware.
pub fn dapps<F: Fetch>( pub fn dapps<F: Fetch>(
ntp_server: &str, ntp_servers: &[String],
pool: CpuPool, pool: CpuPool,
remote: Remote, remote: Remote,
ui_address: Option<(String, u16)>, ui_address: Option<(String, u16)>,
extra_embed_on: Vec<(String, u16)>, extra_embed_on: Vec<(String, u16)>,
extra_script_src: Vec<(String, u16)>,
dapps_path: PathBuf, dapps_path: PathBuf,
extra_dapps: Vec<PathBuf>, extra_dapps: Vec<PathBuf>,
dapps_domain: &str, dapps_domain: &str,
@ -184,15 +211,15 @@ impl Middleware {
web_proxy_tokens: Arc<WebProxyTokens>, web_proxy_tokens: Arc<WebProxyTokens>,
fetch: F, fetch: F,
) -> Self { ) -> Self {
let embeddable = as_embeddable(ui_address, extra_embed_on, dapps_domain); let embeddable = as_embeddable(ui_address, extra_embed_on, extra_script_src, dapps_domain);
let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new( let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new(
hash_fetch::urlhint::URLHintContract::new(registrar), hash_fetch::urlhint::URLHintContract::new(registrar),
sync_status.clone(), sync_status.clone(),
remote.clone(), remote.clone(),
fetch.clone(), fetch.clone(),
).embeddable_on(embeddable.clone()).allow_dapps(true)); ).embeddable_on(embeddable.clone()).allow_dapps(true));
let endpoints = apps::all_endpoints( let (local_endpoints, endpoints) = apps::all_endpoints(
dapps_path, dapps_path.clone(),
extra_dapps, extra_dapps,
dapps_domain, dapps_domain,
embeddable.clone(), embeddable.clone(),
@ -200,10 +227,16 @@ impl Middleware {
remote.clone(), remote.clone(),
fetch.clone(), fetch.clone(),
); );
let endpoints = Endpoints {
endpoints: Arc::new(RwLock::new(endpoints)),
dapps_path,
local_endpoints: Arc::new(RwLock::new(local_endpoints)),
embeddable: embeddable.clone(),
};
let special = { let special = {
let mut special = special_endpoints( let mut special = special_endpoints(
ntp_server, ntp_servers,
pool, pool,
content_fetcher.clone(), content_fetcher.clone(),
remote.clone(), remote.clone(),
@ -225,8 +258,8 @@ impl Middleware {
); );
Middleware { Middleware {
router: router, endpoints,
endpoints: endpoints, router,
} }
} }
} }
@ -237,8 +270,8 @@ impl http::RequestMiddleware for Middleware {
} }
} }
fn special_endpoints( fn special_endpoints<T: AsRef<str>>(
ntp_server: &str, ntp_servers: &[T],
pool: CpuPool, pool: CpuPool,
content_fetcher: Arc<apps::fetcher::Fetcher>, content_fetcher: Arc<apps::fetcher::Fetcher>,
remote: Remote, remote: Remote,
@ -250,7 +283,7 @@ fn special_endpoints(
special.insert(router::SpecialEndpoint::Api, Some(api::RestApi::new( special.insert(router::SpecialEndpoint::Api, Some(api::RestApi::new(
content_fetcher, content_fetcher,
sync_status, sync_status,
api::TimeChecker::new(ntp_server.into(), pool), api::TimeChecker::new(ntp_servers, pool),
remote, remote,
))); )));
special special
@ -263,12 +296,14 @@ fn address(host: &str, port: u16) -> String {
fn as_embeddable( fn as_embeddable(
ui_address: Option<(String, u16)>, ui_address: Option<(String, u16)>,
extra_embed_on: Vec<(String, u16)>, extra_embed_on: Vec<(String, u16)>,
extra_script_src: Vec<(String, u16)>,
dapps_domain: &str, dapps_domain: &str,
) -> Option<ParentFrameSettings> { ) -> Option<ParentFrameSettings> {
ui_address.map(|(host, port)| ParentFrameSettings { ui_address.map(|(host, port)| ParentFrameSettings {
host, host,
port, port,
extra_embed_on, extra_embed_on,
extra_script_src,
dapps_domain: dapps_domain.to_owned(), dapps_domain: dapps_domain.to_owned(),
}) })
} }
@ -289,8 +324,10 @@ pub struct ParentFrameSettings {
pub host: String, pub host: String,
/// Port /// Port
pub port: u16, pub port: u16,
/// Additional pages the pages can be embedded on. /// Additional URLs the dapps can be embedded on.
pub extra_embed_on: Vec<(String, u16)>, pub extra_embed_on: Vec<(String, u16)>,
/// Additional URLs the dapp scripts can be loaded from.
pub extra_script_src: Vec<(String, u16)>,
/// Dapps Domain (web3.site) /// Dapps Domain (web3.site)
pub dapps_domain: String, pub dapps_domain: String,
} }

View File

@ -28,7 +28,8 @@ use jsonrpc_http_server as http;
use apps; use apps;
use apps::fetcher::Fetcher; use apps::fetcher::Fetcher;
use endpoint::{Endpoint, Endpoints, EndpointPath, Handler}; use endpoint::{Endpoint, EndpointPath, Handler};
use Endpoints;
use handlers; use handlers;
use Embeddable; use Embeddable;
@ -50,26 +51,27 @@ pub struct Router {
dapps_domain: String, dapps_domain: String,
} }
impl http::RequestMiddleware for Router { impl Router {
fn on_request(&self, req: &server::Request<HttpStream>, control: &Control) -> http::RequestMiddlewareAction { fn resolve_request(&self, req: &server::Request<HttpStream>, control: Control, refresh_dapps: bool) -> (bool, Option<Box<Handler>>) {
// Choose proper handler depending on path / domain // Choose proper handler depending on path / domain
let url = handlers::extract_url(req); let url = handlers::extract_url(req);
let endpoint = extract_endpoint(&url, &self.dapps_domain); let endpoint = extract_endpoint(&url, &self.dapps_domain);
let referer = extract_referer_endpoint(req, &self.dapps_domain); let referer = extract_referer_endpoint(req, &self.dapps_domain);
let is_utils = endpoint.1 == SpecialEndpoint::Utils; let is_utils = endpoint.1 == SpecialEndpoint::Utils;
let is_origin_set = req.headers().get::<header::Origin>().is_some();
let is_get_request = *req.method() == hyper::Method::Get; let is_get_request = *req.method() == hyper::Method::Get;
let is_head_request = *req.method() == hyper::Method::Head; let is_head_request = *req.method() == hyper::Method::Head;
let has_dapp = |dapp: &str| self.endpoints
.as_ref()
.map_or(false, |endpoints| endpoints.endpoints.read().contains_key(dapp));
trace!(target: "dapps", "Routing request to {:?}. Details: {:?}", url, req); trace!(target: "dapps", "Routing request to {:?}. Details: {:?}", url, req);
let control = control.clone();
debug!(target: "dapps", "Handling endpoint request: {:?}", endpoint); debug!(target: "dapps", "Handling endpoint request: {:?}", endpoint);
let handler: Option<Box<Handler>> = match (endpoint.0, endpoint.1, referer) {
(is_utils, match (endpoint.0, endpoint.1, referer) {
// Handle invalid web requests that we can recover from // Handle invalid web requests that we can recover from
(ref path, SpecialEndpoint::None, Some((ref referer, ref referer_url))) (ref path, SpecialEndpoint::None, Some((ref referer, ref referer_url)))
if referer.app_id == apps::WEB_PATH if referer.app_id == apps::WEB_PATH
&& self.endpoints.as_ref().map(|ep| ep.contains_key(apps::WEB_PATH)).unwrap_or(false) && has_dapp(apps::WEB_PATH)
&& !is_web_endpoint(path) && !is_web_endpoint(path)
=> =>
{ {
@ -88,11 +90,13 @@ impl http::RequestMiddleware for Router {
.map(|special| special.to_async_handler(path.clone().unwrap_or_default(), control)) .map(|special| special.to_async_handler(path.clone().unwrap_or_default(), control))
}, },
// Then delegate to dapp // Then delegate to dapp
(Some(ref path), _, _) if self.endpoints.as_ref().map(|ep| ep.contains_key(&path.app_id)).unwrap_or(false) => { (Some(ref path), _, _) if has_dapp(&path.app_id) => {
trace!(target: "dapps", "Resolving to local/builtin dapp."); trace!(target: "dapps", "Resolving to local/builtin dapp.");
Some(self.endpoints Some(self.endpoints
.as_ref() .as_ref()
.expect("endpoints known to be set; qed") .expect("endpoints known to be set; qed")
.endpoints
.read()
.get(&path.app_id) .get(&path.app_id)
.expect("endpoints known to contain key; qed") .expect("endpoints known to contain key; qed")
.to_async_handler(path.clone(), control)) .to_async_handler(path.clone(), control))
@ -110,13 +114,19 @@ impl http::RequestMiddleware for Router {
=> =>
{ {
trace!(target: "dapps", "Resolving to 404."); trace!(target: "dapps", "Resolving to 404.");
Some(Box::new(handlers::ContentHandler::error( if refresh_dapps {
hyper::StatusCode::NotFound, debug!(target: "dapps", "Refreshing dapps and re-trying.");
"404 Not Found", self.endpoints.as_ref().map(|endpoints| endpoints.refresh_local_dapps());
"Requested content was not found.", return self.resolve_request(req, control, false)
None, } else {
self.embeddable_on.clone(), Some(Box::new(handlers::ContentHandler::error(
))) hyper::StatusCode::NotFound,
"404 Not Found",
"Requested content was not found.",
None,
self.embeddable_on.clone(),
)))
}
}, },
// Any other GET|HEAD requests to home page. // Any other GET|HEAD requests to home page.
_ if (is_get_request || is_head_request) && self.special.contains_key(&SpecialEndpoint::Home) => { _ if (is_get_request || is_head_request) && self.special.contains_key(&SpecialEndpoint::Home) => {
@ -130,8 +140,15 @@ impl http::RequestMiddleware for Router {
trace!(target: "dapps", "Resolving to RPC call."); trace!(target: "dapps", "Resolving to RPC call.");
None None
} }
}; })
}
}
impl http::RequestMiddleware for Router {
fn on_request(&self, req: &server::Request<HttpStream>, control: &Control) -> http::RequestMiddlewareAction {
let control = control.clone();
let is_origin_set = req.headers().get::<header::Origin>().is_some();
let (is_utils, handler) = self.resolve_request(req, control, self.endpoints.is_some());
match handler { match handler {
Some(handler) => http::RequestMiddlewareAction::Respond { Some(handler) => http::RequestMiddlewareAction::Respond {
should_validate_hosts: !is_utils, should_validate_hosts: !is_utils,

View File

@ -39,7 +39,7 @@ fn should_resolve_dapp() {
// then // then
response.assert_status("HTTP/1.1 404 Not Found"); response.assert_status("HTTP/1.1 404 Not Found");
assert_eq!(registrar.calls.lock().len(), 2); assert_eq!(registrar.calls.lock().len(), 4);
assert_security_headers_for_embed(&response.headers); assert_security_headers_for_embed(&response.headers);
} }

View File

@ -255,11 +255,12 @@ impl Server {
fetch: F, fetch: F,
) -> Result<Server, http::Error> { ) -> Result<Server, http::Error> {
let middleware = Middleware::dapps( let middleware = Middleware::dapps(
"pool.ntp.org:123", &["0.pool.ntp.org:123".into(), "1.pool.ntp.org:123".into()],
CpuPool::new(4), CpuPool::new(4),
remote, remote,
signer_address, signer_address,
vec![], vec![],
vec![],
dapps_path, dapps_path,
extra_dapps, extra_dapps,
DAPPS_DOMAIN.into(), DAPPS_DOMAIN.into(),

View File

@ -204,4 +204,3 @@ fn should_serve_utils() {
assert_eq!(response.body.contains("function(){"), true); assert_eq!(response.body.contains("function(){"), true);
assert_security_headers(&response.headers); assert_security_headers(&response.headers);
} }

View File

@ -241,5 +241,3 @@ impl<F: Fetch> server::Handler<net::HttpStream> for WebHandler<F> {
} }
} }
} }

View File

@ -47,12 +47,18 @@ num_cpus = "1.2"
price-info = { path = "../price-info" } price-info = { path = "../price-info" }
rand = "0.3" rand = "0.3"
rlp = { path = "../util/rlp" } rlp = { path = "../util/rlp" }
rlp_derive = { path = "../util/rlp_derive" }
rust-crypto = "0.2.34" rust-crypto = "0.2.34"
rustc-hex = "1.0" rustc-hex = "1.0"
semver = "0.6" semver = "0.6"
stats = { path = "../util/stats" } stats = { path = "../util/stats" }
time = "0.1" time = "0.1"
transient-hashmap = "0.4" transient-hashmap = "0.4"
using_queue = { path = "../util/using_queue" }
table = { path = "../util/table" }
bloomable = { path = "../util/bloomable" }
vm = { path = "vm" }
wasm = { path = "wasm" }
[dev-dependencies] [dev-dependencies]
native-contracts = { path = "native_contracts", features = ["test_contracts"] } native-contracts = { path = "native_contracts", features = ["test_contracts"] }

View File

@ -13,7 +13,9 @@ ethjson = { path = "../../json" }
lazy_static = "0.2" lazy_static = "0.2"
log = "0.3" log = "0.3"
rlp = { path = "../../util/rlp" } rlp = { path = "../../util/rlp" }
vm = { path = "../vm" }
parity-wasm = "0.12" parity-wasm = "0.12"
ethcore-logger = { path = "../../logger" }
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
[dev-dependencies] [dev-dependencies]

View File

@ -25,7 +25,7 @@ extern crate test;
use self::test::{Bencher, black_box}; use self::test::{Bencher, black_box};
use util::*; use util::*;
use evm::action_params::ActionParams; use vm::ActionParams;
use evm::{self, Factory, VMType}; use evm::{self, Factory, VMType};
use evm::tests::FakeExt; use evm::tests::FakeExt;

View File

@ -17,142 +17,8 @@
//! Evm interface. //! Evm interface.
use std::{ops, cmp, fmt}; use std::{ops, cmp, fmt};
use util::{U128, U256, U512, trie}; use util::{U128, U256, U512};
use action_params::ActionParams; use vm::{Ext, Result, ReturnData, GasLeft, Error};
use {Ext};
use super::wasm;
/// Evm errors.
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
/// `OutOfGas` is returned when transaction execution runs out of gas.
/// The state should be reverted to the state from before the
/// transaction execution. But it does not mean that transaction
/// was invalid. Balance still should be transfered and nonce
/// should be increased.
OutOfGas,
/// `BadJumpDestination` is returned when execution tried to move
/// to position that wasn't marked with JUMPDEST instruction
BadJumpDestination {
/// Position the code tried to jump to.
destination: usize
},
/// `BadInstructions` is returned when given instruction is not supported
BadInstruction {
/// Unrecognized opcode
instruction: u8,
},
/// `StackUnderflow` when there is not enough stack elements to execute instruction
StackUnderflow {
/// Invoked instruction
instruction: &'static str,
/// How many stack elements was requested by instruction
wanted: usize,
/// How many elements were on stack
on_stack: usize
},
/// When execution would exceed defined Stack Limit
OutOfStack {
/// Invoked instruction
instruction: &'static str,
/// How many stack elements instruction wanted to push
wanted: usize,
/// What was the stack limit
limit: usize
},
/// Built-in contract failed on given input
BuiltIn(&'static str),
/// When execution tries to modify the state in static context
MutableCallInStaticContext,
/// Likely to cause consensus issues.
Internal(String),
/// Wasm runtime error
Wasm(String),
}
impl From<Box<trie::TrieError>> for Error {
fn from(err: Box<trie::TrieError>) -> Self {
Error::Internal(format!("Internal error: {}", err))
}
}
impl From<wasm::RuntimeError> for Error {
fn from(err: wasm::RuntimeError) -> Self {
Error::Wasm(format!("Runtime error: {:?}", err))
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
match *self {
OutOfGas => write!(f, "Out of gas"),
BadJumpDestination { destination } => write!(f, "Bad jump destination {:x}", destination),
BadInstruction { instruction } => write!(f, "Bad instruction {:x}", instruction),
StackUnderflow { instruction, wanted, on_stack } => write!(f, "Stack underflow {} {}/{}", instruction, wanted, on_stack),
OutOfStack { instruction, wanted, limit } => write!(f, "Out of stack {} {}/{}", instruction, wanted, limit),
BuiltIn(name) => write!(f, "Built-in failed: {}", name),
Internal(ref msg) => write!(f, "Internal error: {}", msg),
MutableCallInStaticContext => write!(f, "Mutable call in static context"),
Wasm(ref msg) => write!(f, "Internal error: {}", msg),
}
}
}
/// A specialized version of Result over EVM errors.
pub type Result<T> = ::std::result::Result<T, Error>;
/// Return data buffer. Holds memory from a previous call and a slice into that memory.
#[derive(Debug)]
pub struct ReturnData {
mem: Vec<u8>,
offset: usize,
size: usize,
}
impl ::std::ops::Deref for ReturnData {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.mem[self.offset..self.offset + self.size]
}
}
impl ReturnData {
/// Create empty `ReturnData`.
pub fn empty() -> Self {
ReturnData {
mem: Vec::new(),
offset: 0,
size: 0,
}
}
/// Create `ReturnData` from give buffer and slice.
pub fn new(mem: Vec<u8>, offset: usize, size: usize) -> Self {
ReturnData {
mem: mem,
offset: offset,
size: size,
}
}
}
/// Gas Left: either it is a known value, or it needs to be computed by processing
/// a return instruction.
#[derive(Debug)]
pub enum GasLeft {
/// Known gas left
Known(U256),
/// Return or Revert instruction must be processed.
NeedsReturn {
/// Amount of gas left.
gas_left: U256,
/// Return data buffer.
data: ReturnData,
/// Apply or revert state changes on revert.
apply_state: bool
},
}
/// Finalization result. Gas Left: either it is a known value, or it needs to be computed by processing /// Finalization result. Gas Left: either it is a known value, or it needs to be computed by processing
/// a return instruction. /// a return instruction.
@ -281,15 +147,6 @@ impl CostType for usize {
} }
} }
/// Evm interface
pub trait Evm {
/// This function should be used to execute transaction.
///
/// It returns either an error, a known amount of gas left, or parameters to be used
/// to compute the final gas left.
fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft>;
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use util::U256; use util::U256;

View File

@ -17,7 +17,7 @@
//! Evm factory. //! Evm factory.
//! //!
use std::sync::Arc; use std::sync::Arc;
use evm::Evm; use vm::Vm;
use util::U256; use util::U256;
use super::interpreter::SharedCache; use super::interpreter::SharedCache;
use super::vmtype::VMType; use super::vmtype::VMType;
@ -33,7 +33,7 @@ impl Factory {
/// Create fresh instance of VM /// Create fresh instance of VM
/// Might choose implementation depending on supplied gas. /// Might choose implementation depending on supplied gas.
#[cfg(feature = "jit")] #[cfg(feature = "jit")]
pub fn create(&self, gas: U256) -> Box<Evm> { pub fn create(&self, gas: U256) -> Box<Vm> {
match self.evm { match self.evm {
VMType::Jit => { VMType::Jit => {
Box::new(super::jit::JitEvm::default()) Box::new(super::jit::JitEvm::default())
@ -49,7 +49,7 @@ impl Factory {
/// Create fresh instance of VM /// Create fresh instance of VM
/// Might choose implementation depending on supplied gas. /// Might choose implementation depending on supplied gas.
#[cfg(not(feature = "jit"))] #[cfg(not(feature = "jit"))]
pub fn create(&self, gas: U256) -> Box<Evm> { pub fn create(&self, gas: U256) -> Box<Vm> {
match self.evm { match self.evm {
VMType::Interpreter => if Self::can_fit_in_usize(gas) { VMType::Interpreter => if Self::can_fit_in_usize(gas) {
Box::new(super::interpreter::Interpreter::<usize>::new(self.evm_cache.clone())) Box::new(super::interpreter::Interpreter::<usize>::new(self.evm_cache.clone()))

View File

@ -14,18 +14,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::cmp;
use util::*; use util::*;
use super::u256_to_address; use super::u256_to_address;
use {evm, ext}; use {evm, vm};
use instructions::{self, Instruction, InstructionInfo}; use instructions::{self, Instruction, InstructionInfo};
use interpreter::stack::Stack; use interpreter::stack::Stack;
use schedule::Schedule; use vm::Schedule;
macro_rules! overflowing { macro_rules! overflowing {
($x: expr) => {{ ($x: expr) => {{
let (v, overflow) = $x; let (v, overflow) = $x;
if overflow { return Err(evm::Error::OutOfGas); } if overflow { return Err(vm::Error::OutOfGas); }
v v
}} }}
} }
@ -59,16 +60,16 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
} }
} }
pub fn verify_gas(&self, gas_cost: &Gas) -> evm::Result<()> { pub fn verify_gas(&self, gas_cost: &Gas) -> vm::Result<()> {
match &self.current_gas < gas_cost { match &self.current_gas < gas_cost {
true => Err(evm::Error::OutOfGas), true => Err(vm::Error::OutOfGas),
false => Ok(()) false => Ok(())
} }
} }
/// How much gas is provided to a CALL/CREATE, given that we need to deduct `needed` for this operation /// How much gas is provided to a CALL/CREATE, given that we need to deduct `needed` for this operation
/// and that we `requested` some. /// and that we `requested` some.
pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option<U256>) -> evm::Result<Gas> { pub fn gas_provided(&self, schedule: &Schedule, needed: Gas, requested: Option<U256>) -> vm::Result<Gas> {
// Try converting requested gas to `Gas` (`U256/u64`) // Try converting requested gas to `Gas` (`U256/u64`)
// but in EIP150 even if we request more we should never fail from OOG // but in EIP150 even if we request more we should never fail from OOG
let requested = requested.map(Gas::from_u256); let requested = requested.map(Gas::from_u256);
@ -82,7 +83,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
}; };
if let Some(Ok(r)) = requested { if let Some(Ok(r)) = requested {
Ok(min(r, max_gas_provided)) Ok(cmp::min(r, max_gas_provided))
} else { } else {
Ok(max_gas_provided) Ok(max_gas_provided)
} }
@ -107,12 +108,12 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
/// it will be the amount of gas that the current context provides to the child context. /// it will be the amount of gas that the current context provides to the child context.
pub fn requirements( pub fn requirements(
&mut self, &mut self,
ext: &ext::Ext, ext: &vm::Ext,
instruction: Instruction, instruction: Instruction,
info: &InstructionInfo, info: &InstructionInfo,
stack: &Stack<U256>, stack: &Stack<U256>,
current_mem_size: usize, current_mem_size: usize,
) -> evm::Result<InstructionRequirements<Gas>> { ) -> vm::Result<InstructionRequirements<Gas>> {
let schedule = ext.schedule(); let schedule = ext.schedule();
let tier = instructions::get_tier_idx(info.tier); let tier = instructions::get_tier_idx(info.tier);
let default_gas = Gas::from(schedule.tier_step_gas[tier]); let default_gas = Gas::from(schedule.tier_step_gas[tier]);
@ -291,7 +292,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
}) })
} }
fn mem_gas_cost(&self, schedule: &Schedule, current_mem_size: usize, mem_size: &Gas) -> evm::Result<(Gas, Gas, usize)> { fn mem_gas_cost(&self, schedule: &Schedule, current_mem_size: usize, mem_size: &Gas) -> vm::Result<(Gas, Gas, usize)> {
let gas_for_mem = |mem_size: Gas| { let gas_for_mem = |mem_size: Gas| {
let s = mem_size >> 5; let s = mem_size >> 5;
// s * memory_gas + s * s / quad_coeff_div // s * memory_gas + s * s / quad_coeff_div
@ -319,12 +320,12 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
#[inline] #[inline]
fn mem_needed_const<Gas: evm::CostType>(mem: &U256, add: usize) -> evm::Result<Gas> { fn mem_needed_const<Gas: evm::CostType>(mem: &U256, add: usize) -> vm::Result<Gas> {
Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add)))) Gas::from_u256(overflowing!(mem.overflowing_add(U256::from(add))))
} }
#[inline] #[inline]
fn mem_needed<Gas: evm::CostType>(offset: &U256, size: &U256) -> evm::Result<Gas> { fn mem_needed<Gas: evm::CostType>(offset: &U256, size: &U256) -> vm::Result<Gas> {
if size.is_zero() { if size.is_zero() {
return Ok(Gas::from(0)); return Ok(Gas::from(0));
} }

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::U256; use util::U256;
use {ReturnData}; use vm::ReturnData;
const MAX_RETURN_WASTE_BYTES: usize = 16384; const MAX_RETURN_WASTE_BYTES: usize = 16384;

View File

@ -23,17 +23,23 @@ mod stack;
mod memory; mod memory;
mod shared_cache; mod shared_cache;
use std::marker::PhantomData;
use std::{cmp, mem};
use std::sync::Arc;
use vm::{
self, ActionParams, ActionValue, CallType, MessageCallResult,
ContractCreateResult, CreateContractAddress, ReturnData, GasLeft
};
use evm::CostType;
use instructions::{self, Instruction, InstructionInfo};
use self::gasometer::Gasometer; use self::gasometer::Gasometer;
use self::stack::{Stack, VecStack}; use self::stack::{Stack, VecStack};
use self::memory::Memory; use self::memory::Memory;
pub use self::shared_cache::SharedCache; pub use self::shared_cache::SharedCache;
use std::marker::PhantomData;
use action_params::{ActionParams, ActionValue};
use call_type::CallType;
use instructions::{self, Instruction, InstructionInfo};
use evm::{self, GasLeft, CostType, ReturnData};
use ext::{self, MessageCallResult, ContractCreateResult, CreateContractAddress};
use bit_set::BitSet; use bit_set::BitSet;
use util::*; use util::*;
@ -107,8 +113,8 @@ pub struct Interpreter<Cost: CostType> {
_type: PhantomData<Cost>, _type: PhantomData<Cost>,
} }
impl<Cost: CostType> evm::Evm for Interpreter<Cost> { impl<Cost: CostType> vm::Vm for Interpreter<Cost> {
fn exec(&mut self, params: ActionParams, ext: &mut ext::Ext) -> evm::Result<GasLeft> { fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
self.mem.clear(); self.mem.clear();
let mut informant = informant::EvmInformant::new(ext.depth()); let mut informant = informant::EvmInformant::new(ext.depth());
@ -205,7 +211,7 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
} }
fn verify_instruction(&self, ext: &ext::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack<U256>) -> evm::Result<()> { fn verify_instruction(&self, ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack<U256>) -> vm::Result<()> {
let schedule = ext.schedule(); let schedule = ext.schedule();
if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) || if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) ||
@ -214,25 +220,25 @@ impl<Cost: CostType> Interpreter<Cost> {
((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) || ((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) ||
(instruction == instructions::REVERT && !schedule.have_revert) { (instruction == instructions::REVERT && !schedule.have_revert) {
return Err(evm::Error::BadInstruction { return Err(vm::Error::BadInstruction {
instruction: instruction instruction: instruction
}); });
} }
if info.tier == instructions::GasPriceTier::Invalid { if info.tier == instructions::GasPriceTier::Invalid {
return Err(evm::Error::BadInstruction { return Err(vm::Error::BadInstruction {
instruction: instruction instruction: instruction
}); });
} }
if !stack.has(info.args) { if !stack.has(info.args) {
Err(evm::Error::StackUnderflow { Err(vm::Error::StackUnderflow {
instruction: info.name, instruction: info.name,
wanted: info.args, wanted: info.args,
on_stack: stack.size() on_stack: stack.size()
}) })
} else if stack.size() - info.args + info.ret > schedule.stack_limit { } else if stack.size() - info.args + info.ret > schedule.stack_limit {
Err(evm::Error::OutOfStack { Err(vm::Error::OutOfStack {
instruction: info.name, instruction: info.name,
wanted: info.ret - info.args, wanted: info.ret - info.args,
limit: schedule.stack_limit limit: schedule.stack_limit
@ -272,12 +278,12 @@ impl<Cost: CostType> Interpreter<Cost> {
&mut self, &mut self,
gas: Cost, gas: Cost,
params: &ActionParams, params: &ActionParams,
ext: &mut ext::Ext, ext: &mut vm::Ext,
instruction: Instruction, instruction: Instruction,
code: &mut CodeReader, code: &mut CodeReader,
stack: &mut Stack<U256>, stack: &mut Stack<U256>,
provided: Option<Cost> provided: Option<Cost>
) -> evm::Result<InstructionResult<Cost>> { ) -> vm::Result<InstructionResult<Cost>> {
match instruction { match instruction {
instructions::JUMP => { instructions::JUMP => {
let jump = stack.pop_back(); let jump = stack.pop_back();
@ -593,13 +599,13 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
} }
fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> evm::Result<usize> { fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> vm::Result<usize> {
let jump = jump_u.low_u64() as usize; let jump = jump_u.low_u64() as usize;
if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u { if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u {
Ok(jump) Ok(jump)
} else { } else {
Err(evm::Error::BadJumpDestination { Err(vm::Error::BadJumpDestination {
destination: jump destination: jump
}) })
} }
@ -617,7 +623,7 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
} }
fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack<U256>) -> evm::Result<()> { fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack<U256>) -> vm::Result<()> {
match instruction { match instruction {
instructions::DUP1...instructions::DUP16 => { instructions::DUP1...instructions::DUP16 => {
let position = instructions::get_dup_position(instruction); let position = instructions::get_dup_position(instruction);
@ -822,7 +828,7 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
}, },
_ => { _ => {
return Err(evm::Error::BadInstruction { return Err(vm::Error::BadInstruction {
instruction: instruction instruction: instruction
}); });
} }

View File

@ -19,6 +19,7 @@ use util::*;
use evmjit; use evmjit;
use evm::{self, GasLeft}; use evm::{self, GasLeft};
use evm::CallType; use evm::CallType;
use vm::{self, Vm};
/// Should be used to convert jit types to ethcore /// Should be used to convert jit types to ethcore
trait FromJit<T>: Sized { trait FromJit<T>: Sized {
@ -318,7 +319,7 @@ pub struct JitEvm {
context: Option<evmjit::ContextHandle>, context: Option<evmjit::ContextHandle>,
} }
impl evm::Evm for JitEvm { impl vm::Vm for JitEvm {
fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result<GasLeft> { fn exec(&mut self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result<GasLeft> {
// Dirty hack. This is unsafe, but we interact with ffi, so it's justified. // Dirty hack. This is unsafe, but we interact with ffi, so it's justified.
let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext, params.address.clone())) }; let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext, params.address.clone())) };
@ -370,8 +371,8 @@ impl evm::Evm for JitEvm {
ext.suicide(&Address::from_jit(&context.suicide_refund_address())); ext.suicide(&Address::from_jit(&context.suicide_refund_address()));
Ok(GasLeft::Known(U256::from(context.gas_left()))) Ok(GasLeft::Known(U256::from(context.gas_left())))
}, },
evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas), evmjit::ReturnCode::OutOfGas => Err(vm::Error::OutOfGas),
_err => Err(evm::Error::Internal) _err => Err(vm::Error::Internal)
} }
} }
} }

View File

@ -24,11 +24,12 @@ extern crate ethjson;
extern crate rlp; extern crate rlp;
extern crate parity_wasm; extern crate parity_wasm;
extern crate wasm_utils; extern crate wasm_utils;
extern crate ethcore_logger;
extern crate vm;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[macro_use]
extern crate log; extern crate log;
#[cfg(feature = "jit")] #[cfg(feature = "jit")]
@ -37,14 +38,8 @@ extern crate evmjit;
#[cfg(test)] #[cfg(test)]
extern crate rustc_hex; extern crate rustc_hex;
pub mod action_params;
pub mod call_type;
pub mod env_info;
pub mod ext;
pub mod evm; pub mod evm;
pub mod interpreter; pub mod interpreter;
pub mod schedule;
pub mod wasm;
#[macro_use] #[macro_use]
pub mod factory; pub mod factory;
@ -59,12 +54,12 @@ mod tests;
#[cfg(all(feature="benches", test))] #[cfg(all(feature="benches", test))]
mod benches; mod benches;
pub use self::action_params::ActionParams; pub use vm::{
pub use self::call_type::CallType; Schedule, CleanDustMode, EnvInfo, CallType, ActionParams, Ext,
pub use self::env_info::EnvInfo; ContractCreateResult, MessageCallResult, CreateContractAddress,
pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData}; GasLeft, ReturnData
pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; };
pub use self::evm::{Finalize, FinalizationResult, CostType};
pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes};
pub use self::vmtype::VMType; pub use self::vmtype::VMType;
pub use self::factory::Factory; pub use self::factory::Factory;
pub use self::schedule::{Schedule, CleanDustMode};

View File

@ -15,212 +15,17 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::fmt::Debug; use std::fmt::Debug;
use std::str::FromStr;
use std::hash::Hash;
use std::sync::Arc;
use std::collections::{HashMap, HashSet};
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::*; use util::*;
use action_params::{ActionParams, ActionValue}; use vm::{self, ActionParams, ActionValue};
use env_info::EnvInfo; use vm::tests::{FakeExt, FakeCall, FakeCallType, test_finalize};
use call_type::CallType;
use schedule::Schedule;
use evm::{self, GasLeft, ReturnData};
use ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress};
use factory::Factory; use factory::Factory;
use vmtype::VMType; use vmtype::VMType;
pub struct FakeLogEntry {
topics: Vec<H256>,
data: Bytes
}
#[derive(PartialEq, Eq, Hash, Debug)]
pub enum FakeCallType {
Call, Create
}
#[derive(PartialEq, Eq, Hash, Debug)]
pub struct FakeCall {
pub call_type: FakeCallType,
pub gas: U256,
pub sender_address: Option<Address>,
pub receive_address: Option<Address>,
pub value: Option<U256>,
pub data: Bytes,
pub code_address: Option<Address>,
}
/// Fake externalities test structure.
///
/// Can't do recursive calls.
#[derive(Default)]
pub struct FakeExt {
pub store: HashMap<H256, H256>,
pub suicides: HashSet<Address>,
pub calls: HashSet<FakeCall>,
sstore_clears: usize,
depth: usize,
blockhashes: HashMap<U256, H256>,
codes: HashMap<Address, Arc<Bytes>>,
logs: Vec<FakeLogEntry>,
info: EnvInfo,
schedule: Schedule,
balances: HashMap<Address, U256>,
}
// similar to the normal `finalize` function, but ignoring NeedsReturn.
fn test_finalize(res: Result<GasLeft, evm::Error>) -> Result<U256, evm::Error> {
match res {
Ok(GasLeft::Known(gas)) => Ok(gas),
Ok(GasLeft::NeedsReturn{..}) => unimplemented!(), // since ret is unimplemented.
Err(e) => Err(e),
}
}
impl FakeExt {
pub fn new() -> Self {
FakeExt::default()
}
}
impl Default for Schedule {
fn default() -> Self {
Schedule::new_frontier()
}
}
impl Ext for FakeExt {
fn storage_at(&self, key: &H256) -> evm::Result<H256> {
Ok(self.store.get(key).unwrap_or(&H256::new()).clone())
}
fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> {
self.store.insert(key, value);
Ok(())
}
fn exists(&self, address: &Address) -> evm::Result<bool> {
Ok(self.balances.contains_key(address))
}
fn exists_and_not_null(&self, address: &Address) -> evm::Result<bool> {
Ok(self.balances.get(address).map_or(false, |b| !b.is_zero()))
}
fn origin_balance(&self) -> evm::Result<U256> {
unimplemented!()
}
fn balance(&self, address: &Address) -> evm::Result<U256> {
Ok(self.balances[address])
}
fn blockhash(&mut self, number: &U256) -> H256 {
self.blockhashes.get(number).unwrap_or(&H256::new()).clone()
}
fn create(&mut self, gas: &U256, value: &U256, code: &[u8], _address: CreateContractAddress) -> ContractCreateResult {
self.calls.insert(FakeCall {
call_type: FakeCallType::Create,
gas: *gas,
sender_address: None,
receive_address: None,
value: Some(*value),
data: code.to_vec(),
code_address: None
});
ContractCreateResult::Failed
}
fn call(&mut self,
gas: &U256,
sender_address: &Address,
receive_address: &Address,
value: Option<U256>,
data: &[u8],
code_address: &Address,
_output: &mut [u8],
_call_type: CallType
) -> MessageCallResult {
self.calls.insert(FakeCall {
call_type: FakeCallType::Call,
gas: *gas,
sender_address: Some(sender_address.clone()),
receive_address: Some(receive_address.clone()),
value: value,
data: data.to_vec(),
code_address: Some(code_address.clone())
});
MessageCallResult::Success(*gas, ReturnData::empty())
}
fn extcode(&self, address: &Address) -> evm::Result<Arc<Bytes>> {
Ok(self.codes.get(address).unwrap_or(&Arc::new(Bytes::new())).clone())
}
fn extcodesize(&self, address: &Address) -> evm::Result<usize> {
Ok(self.codes.get(address).map_or(0, |c| c.len()))
}
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> evm::Result<()> {
self.logs.push(FakeLogEntry {
topics: topics,
data: data.to_vec()
});
Ok(())
}
fn ret(self, _gas: &U256, _data: &ReturnData) -> evm::Result<U256> {
unimplemented!();
}
fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> {
self.suicides.insert(refund_address.clone());
Ok(())
}
fn schedule(&self) -> &Schedule {
&self.schedule
}
fn env_info(&self) -> &EnvInfo {
&self.info
}
fn depth(&self) -> usize {
self.depth
}
fn inc_sstore_clears(&mut self) {
self.sstore_clears += 1;
}
}
#[test]
fn test_stack_underflow() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "01600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let err = {
let mut vm : Box<evm::Evm> = Box::new(super::interpreter::Interpreter::<usize>::new(Arc::new(super::interpreter::SharedCache::default())));
test_finalize(vm.exec(params, &mut ext)).unwrap_err()
};
match err {
evm::Error::StackUnderflow {wanted, on_stack, ..} => {
assert_eq!(wanted, 2);
assert_eq!(on_stack, 0);
}
_ => {
assert!(false, "Expected StackUndeflow")
}
};
}
evm_test!{test_add: test_add_jit, test_add_int} evm_test!{test_add: test_add_jit, test_add_int}
fn test_add(factory: super::Factory) { fn test_add(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
@ -849,7 +654,7 @@ fn test_badinstruction_int() {
}; };
match err { match err {
evm::Error::BadInstruction { instruction: 0xaf } => (), vm::Error::BadInstruction { instruction: 0xaf } => (),
_ => assert!(false, "Expected bad instruction") _ => assert!(false, "Expected bad instruction")
} }
} }

View File

@ -19,7 +19,9 @@ ethcore-io = { path = "../../util/io" }
ethcore-ipc = { path = "../../ipc/rpc", optional = true } ethcore-ipc = { path = "../../ipc/rpc", optional = true }
ethcore-devtools = { path = "../../devtools" } ethcore-devtools = { path = "../../devtools" }
evm = { path = "../evm" } evm = { path = "../evm" }
vm = { path = "../vm" }
rlp = { path = "../../util/rlp" } rlp = { path = "../../util/rlp" }
rlp_derive = { path = "../../util/rlp_derive" }
time = "0.1" time = "0.1"
smallvec = "0.4" smallvec = "0.4"
futures = "0.1" futures = "0.1"

View File

@ -105,8 +105,8 @@ pub trait LightChainClient: Send + Sync {
/// Get an iterator over a block and its ancestry. /// Get an iterator over a block and its ancestry.
fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a>; fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a>;
/// Get the signing network ID. /// Get the signing chain ID.
fn signing_network_id(&self) -> Option<u64>; fn signing_chain_id(&self) -> Option<u64>;
/// Get environment info for execution at a given block. /// Get environment info for execution at a given block.
/// Fails if that block's header is not stored. /// Fails if that block's header is not stored.
@ -287,9 +287,9 @@ impl<T: ChainDataFetcher> Client<T> {
self.chain.ancestry_iter(start) self.chain.ancestry_iter(start)
} }
/// Get the signing network id. /// Get the signing chain id.
pub fn signing_network_id(&self) -> Option<u64> { pub fn signing_chain_id(&self) -> Option<u64> {
self.engine.signing_network_id(&self.latest_env_info()) self.engine.signing_chain_id(&self.latest_env_info())
} }
/// Flush the header queue. /// Flush the header queue.
@ -552,8 +552,8 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
Box::new(Client::ancestry_iter(self, start)) Box::new(Client::ancestry_iter(self, start))
} }
fn signing_network_id(&self) -> Option<BlockNumber> { fn signing_chain_id(&self) -> Option<u64> {
Client::signing_network_id(self) Client::signing_chain_id(self)
} }
fn env_info(&self, id: BlockId) -> Option<EnvInfo> { fn env_info(&self, id: BlockId) -> Option<EnvInfo> {

View File

@ -76,10 +76,13 @@ extern crate futures;
extern crate itertools; extern crate itertools;
extern crate rand; extern crate rand;
extern crate rlp; extern crate rlp;
#[macro_use]
extern crate rlp_derive;
extern crate serde; extern crate serde;
extern crate smallvec; extern crate smallvec;
extern crate stats; extern crate stats;
extern crate time; extern crate time;
extern crate vm;
#[cfg(feature = "ipc")] #[cfg(feature = "ipc")]
extern crate ethcore_ipc as ipc; extern crate ethcore_ipc as ipc;

View File

@ -24,7 +24,7 @@ use ethcore::engines::{Engine, StateDependentProof};
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use ethcore::state::{self, ProvedExecution}; use ethcore::state::{self, ProvedExecution};
use ethcore::transaction::SignedTransaction; use ethcore::transaction::SignedTransaction;
use evm::env_info::EnvInfo; use vm::EnvInfo;
use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field};

View File

@ -677,7 +677,7 @@ pub mod header {
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
/// Potentially incomplete headers request. /// Potentially incomplete headers request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// Start block. /// Start block.
pub start: Field<HashOrNumber>, pub start: Field<HashOrNumber>,
@ -689,27 +689,6 @@ pub mod header {
pub reverse: bool, pub reverse: bool,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
start: rlp.val_at(0)?,
skip: rlp.val_at(1)?,
max: rlp.val_at(2)?,
reverse: rlp.val_at(3)?
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(4)
.append(&self.start)
.append(&self.skip)
.append(&self.max)
.append(&self.reverse);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -811,26 +790,12 @@ pub mod header_proof {
use util::{Bytes, U256, H256}; use util::{Bytes, U256, H256};
/// Potentially incomplete header proof request. /// Potentially incomplete header proof request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// Block number. /// Block number.
pub num: Field<u64>, pub num: Field<u64>,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
num: rlp.val_at(0)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(1).append(&self.num);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -916,30 +881,15 @@ pub mod header_proof {
/// Request and response for transaction index. /// Request and response for transaction index.
pub mod transaction_index { pub mod transaction_index {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use util::H256; use util::H256;
/// Potentially incomplete transaction index request. /// Potentially incomplete transaction index request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// Transaction hash to get index for. /// Transaction hash to get index for.
pub hash: Field<H256>, pub hash: Field<H256>,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
hash: rlp.val_at(0)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(1).append(&self.hash);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -986,7 +936,7 @@ pub mod transaction_index {
} }
/// The output of a request for transaction index. /// The output of a request for transaction index.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Response { pub struct Response {
/// Block number. /// Block number.
pub num: u64, pub num: u64,
@ -1003,55 +953,21 @@ pub mod transaction_index {
f(1, Output::Hash(self.hash)); f(1, Output::Hash(self.hash));
} }
} }
impl Decodable for Response {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Response {
num: rlp.val_at(0)?,
hash: rlp.val_at(1)?,
index: rlp.val_at(2)?,
})
}
}
impl Encodable for Response {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(3)
.append(&self.num)
.append(&self.hash)
.append(&self.index);
}
}
} }
/// Request and response for block receipts /// Request and response for block receipts
pub mod block_receipts { pub mod block_receipts {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use ethcore::receipt::Receipt; use ethcore::receipt::Receipt;
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use util::H256; use util::H256;
/// Potentially incomplete block receipts request. /// Potentially incomplete block receipts request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// Block hash to get receipts for. /// Block hash to get receipts for.
pub hash: Field<H256>, pub hash: Field<H256>,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
hash: rlp.val_at(0)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(1).append(&self.hash);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -1095,7 +1011,7 @@ pub mod block_receipts {
} }
/// The output of a request for block receipts. /// The output of a request for block receipts.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct Response { pub struct Response {
/// The block receipts. /// The block receipts.
pub receipts: Vec<Receipt> pub receipts: Vec<Receipt>
@ -1105,20 +1021,6 @@ pub mod block_receipts {
/// Fill reusable outputs by providing them to the function. /// Fill reusable outputs by providing them to the function.
fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {} fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {}
} }
impl Decodable for Response {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Response {
receipts: rlp.as_list()?,
})
}
}
impl Encodable for Response {
fn rlp_append(&self, s: &mut RlpStream) {
s.append_list(&self.receipts);
}
}
} }
/// Request and response for a block body /// Request and response for a block body
@ -1129,26 +1031,12 @@ pub mod block_body {
use util::H256; use util::H256;
/// Potentially incomplete block body request. /// Potentially incomplete block body request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// Block hash to get receipts for. /// Block hash to get receipts for.
pub hash: Field<H256>, pub hash: Field<H256>,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
hash: rlp.val_at(0)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(1).append(&self.hash);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -1228,11 +1116,10 @@ pub mod block_body {
/// A request for an account proof. /// A request for an account proof.
pub mod account { pub mod account {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use util::{Bytes, U256, H256}; use util::{Bytes, U256, H256};
/// Potentially incomplete request for an account proof. /// Potentially incomplete request for an account proof.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// Block hash to request state proof for. /// Block hash to request state proof for.
pub block_hash: Field<H256>, pub block_hash: Field<H256>,
@ -1240,23 +1127,6 @@ pub mod account {
pub address_hash: Field<H256>, pub address_hash: Field<H256>,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
block_hash: rlp.val_at(0)?,
address_hash: rlp.val_at(1)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(2)
.append(&self.block_hash)
.append(&self.address_hash);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -1319,7 +1189,7 @@ pub mod account {
} }
/// The output of a request for an account state proof. /// The output of a request for an account state proof.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Response { pub struct Response {
/// Inclusion/exclusion proof /// Inclusion/exclusion proof
pub proof: Vec<Bytes>, pub proof: Vec<Bytes>,
@ -1340,39 +1210,15 @@ pub mod account {
f(1, Output::Hash(self.storage_root)); f(1, Output::Hash(self.storage_root));
} }
} }
impl Decodable for Response {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Response {
proof: rlp.list_at(0)?,
nonce: rlp.val_at(1)?,
balance: rlp.val_at(2)?,
code_hash: rlp.val_at(3)?,
storage_root: rlp.val_at(4)?
})
}
}
impl Encodable for Response {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(5)
.append_list::<Vec<u8>,_>(&self.proof[..])
.append(&self.nonce)
.append(&self.balance)
.append(&self.code_hash)
.append(&self.storage_root);
}
}
} }
/// A request for a storage proof. /// A request for a storage proof.
pub mod storage { pub mod storage {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use util::{Bytes, H256}; use util::{Bytes, H256};
/// Potentially incomplete request for an storage proof. /// Potentially incomplete request for an storage proof.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// Block hash to request state proof for. /// Block hash to request state proof for.
pub block_hash: Field<H256>, pub block_hash: Field<H256>,
@ -1382,25 +1228,6 @@ pub mod storage {
pub key_hash: Field<H256>, pub key_hash: Field<H256>,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
block_hash: rlp.val_at(0)?,
address_hash: rlp.val_at(1)?,
key_hash: rlp.val_at(2)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(3)
.append(&self.block_hash)
.append(&self.address_hash)
.append(&self.key_hash);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -1477,7 +1304,7 @@ pub mod storage {
} }
/// The output of a request for an account state proof. /// The output of a request for an account state proof.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Response { pub struct Response {
/// Inclusion/exclusion proof /// Inclusion/exclusion proof
pub proof: Vec<Bytes>, pub proof: Vec<Bytes>,
@ -1491,33 +1318,15 @@ pub mod storage {
f(0, Output::Hash(self.value)); f(0, Output::Hash(self.value));
} }
} }
impl Decodable for Response {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Response {
proof: rlp.list_at(0)?,
value: rlp.val_at(1)?,
})
}
}
impl Encodable for Response {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(2)
.append_list::<Vec<u8>,_>(&self.proof[..])
.append(&self.value);
}
}
} }
/// A request for contract code. /// A request for contract code.
pub mod contract_code { pub mod contract_code {
use super::{Field, NoSuchOutput, OutputKind, Output}; use super::{Field, NoSuchOutput, OutputKind, Output};
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use util::{Bytes, H256}; use util::{Bytes, H256};
/// Potentially incomplete contract code request. /// Potentially incomplete contract code request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// The block hash to request the state for. /// The block hash to request the state for.
pub block_hash: Field<H256>, pub block_hash: Field<H256>,
@ -1525,23 +1334,6 @@ pub mod contract_code {
pub code_hash: Field<H256>, pub code_hash: Field<H256>,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
block_hash: rlp.val_at(0)?,
code_hash: rlp.val_at(1)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(2)
.append(&self.block_hash)
.append(&self.code_hash);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;
@ -1600,7 +1392,7 @@ pub mod contract_code {
} }
/// The output of a request for /// The output of a request for
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct Response { pub struct Response {
/// The requested code. /// The requested code.
pub code: Bytes, pub code: Bytes,
@ -1610,21 +1402,6 @@ pub mod contract_code {
/// Fill reusable outputs by providing them to the function. /// Fill reusable outputs by providing them to the function.
fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {} fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {}
} }
impl Decodable for Response {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Response {
code: rlp.as_val()?,
})
}
}
impl Encodable for Response {
fn rlp_append(&self, s: &mut RlpStream) {
s.append(&self.code);
}
}
} }
/// A request for proof of execution. /// A request for proof of execution.
@ -1635,7 +1412,7 @@ pub mod execution {
use util::{Bytes, Address, U256, H256, DBValue}; use util::{Bytes, Address, U256, H256, DBValue};
/// Potentially incomplete execution proof request. /// Potentially incomplete execution proof request.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
pub struct Incomplete { pub struct Incomplete {
/// The block hash to request the state for. /// The block hash to request the state for.
pub block_hash: Field<H256>, pub block_hash: Field<H256>,
@ -1653,38 +1430,6 @@ pub mod execution {
pub data: Bytes, pub data: Bytes,
} }
impl Decodable for Incomplete {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Incomplete {
block_hash: rlp.val_at(0)?,
from: rlp.val_at(1)?,
action: rlp.val_at(2)?,
gas: rlp.val_at(3)?,
gas_price: rlp.val_at(4)?,
value: rlp.val_at(5)?,
data: rlp.val_at(6)?,
})
}
}
impl Encodable for Incomplete {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(7)
.append(&self.block_hash)
.append(&self.from);
match self.action {
Action::Create => s.append_empty_data(),
Action::Call(ref addr) => s.append(addr),
};
s.append(&self.gas)
.append(&self.gas_price)
.append(&self.value)
.append(&self.data);
}
}
impl super::IncompleteRequest for Incomplete { impl super::IncompleteRequest for Incomplete {
type Complete = Complete; type Complete = Complete;
type Response = Response; type Response = Response;

View File

@ -9,7 +9,7 @@ build = "build.rs"
ethabi = "2.0" ethabi = "2.0"
futures = "0.1" futures = "0.1"
byteorder = "1.0" byteorder = "1.0"
ethcore-util = { path = "../../util" } ethcore-bigint = { path = "../../util/bigint" }
[build-dependencies] [build-dependencies]
native-contract-generator = { path = "generator" } native-contract-generator = { path = "generator" }

View File

@ -21,6 +21,7 @@ use std::fs::File;
use std::io::Write; use std::io::Write;
// TODO: just walk the "res" directory and generate whole crate automatically. // TODO: just walk the "res" directory and generate whole crate automatically.
const KEY_SERVER_SET_ABI: &'static str = include_str!("res/key_server_set.json");
const REGISTRY_ABI: &'static str = include_str!("res/registrar.json"); const REGISTRY_ABI: &'static str = include_str!("res/registrar.json");
const URLHINT_ABI: &'static str = include_str!("res/urlhint.json"); const URLHINT_ABI: &'static str = include_str!("res/urlhint.json");
const SERVICE_TRANSACTION_ABI: &'static str = include_str!("res/service_transaction.json"); const SERVICE_TRANSACTION_ABI: &'static str = include_str!("res/service_transaction.json");
@ -45,6 +46,7 @@ fn build_test_contracts() {
} }
fn main() { fn main() {
build_file("KeyServerSet", KEY_SERVER_SET_ABI, "key_server_set.rs");
build_file("Registry", REGISTRY_ABI, "registry.rs"); build_file("Registry", REGISTRY_ABI, "registry.rs");
build_file("Urlhint", URLHINT_ABI, "urlhint.rs"); build_file("Urlhint", URLHINT_ABI, "urlhint.rs");
build_file("ServiceTransactionChecker", SERVICE_TRANSACTION_ABI, "service_transaction.rs"); build_file("ServiceTransactionChecker", SERVICE_TRANSACTION_ABI, "service_transaction.rs");

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Rust code contract generator. //! Rust code contract generator.
//! The code generated will require a dependence on the `ethcore-util`, //! The code generated will require a dependence on the `ethcore-bigint::prelude`,
//! `ethabi`, `byteorder`, and `futures` crates. //! `ethabi`, `byteorder`, and `futures` crates.
//! This currently isn't hygienic, so compilation of generated code may fail //! This currently isn't hygienic, so compilation of generated code may fail
//! due to missing crates or name collisions. This will change when //! due to missing crates or name collisions. This will change when
@ -48,14 +48,14 @@ pub fn generate_module(struct_name: &str, abi: &str) -> Result<String, Error> {
use byteorder::{{BigEndian, ByteOrder}}; use byteorder::{{BigEndian, ByteOrder}};
use futures::{{future, Future, IntoFuture, BoxFuture}}; use futures::{{future, Future, IntoFuture, BoxFuture}};
use ethabi::{{Contract, Interface, Token, Event}}; use ethabi::{{Contract, Interface, Token, Event}};
use util; use bigint;
/// Generated Rust bindings to an Ethereum contract. /// Generated Rust bindings to an Ethereum contract.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct {name} {{ pub struct {name} {{
contract: Contract, contract: Contract,
/// Address to make calls to. /// Address to make calls to.
pub address: util::Address, pub address: bigint::prelude::H160,
}} }}
const ABI: &'static str = r#"{abi_str}"#; const ABI: &'static str = r#"{abi_str}"#;
@ -63,7 +63,7 @@ const ABI: &'static str = r#"{abi_str}"#;
impl {name} {{ impl {name} {{
/// Create a new instance of `{name}` with an address. /// Create a new instance of `{name}` with an address.
/// Calls can be made, given a callback for dispatching calls asynchronously. /// Calls can be made, given a callback for dispatching calls asynchronously.
pub fn new(address: util::Address) -> Self {{ pub fn new(address: bigint::prelude::H160) -> Self {{
let contract = Contract::new(Interface::load(ABI.as_bytes()) let contract = Contract::new(Interface::load(ABI.as_bytes())
.expect("ABI checked at generation-time; qed")); .expect("ABI checked at generation-time; qed"));
{name} {{ {name} {{
@ -108,7 +108,7 @@ fn generate_functions(contract: &Contract) -> Result<String, Error> {
/// Outputs: {abi_outputs:?} /// Outputs: {abi_outputs:?}
pub fn {snake_name}<F, U>(&self, call: F, {params}) -> BoxFuture<{output_type}, String> pub fn {snake_name}<F, U>(&self, call: F, {params}) -> BoxFuture<{output_type}, String>
where where
F: FnOnce(util::Address, Vec<u8>) -> U, F: FnOnce(bigint::prelude::H160, Vec<u8>) -> U,
U: IntoFuture<Item=Vec<u8>, Error=String>, U: IntoFuture<Item=Vec<u8>, Error=String>,
U::Future: Send + 'static U::Future: Send + 'static
{{ {{
@ -217,8 +217,8 @@ fn output_params_codegen(outputs: &[ParamType]) -> Result<(String, String), Para
// create code for an argument type from param type. // create code for an argument type from param type.
fn rust_type(input: ParamType) -> Result<String, ParamType> { fn rust_type(input: ParamType) -> Result<String, ParamType> {
Ok(match input { Ok(match input {
ParamType::Address => "util::Address".into(), ParamType::Address => "bigint::prelude::H160".into(),
ParamType::FixedBytes(len) if len <= 32 => format!("util::H{}", len * 8), ParamType::FixedBytes(len) if len <= 32 => format!("bigint::prelude::H{}", len * 8),
ParamType::Bytes | ParamType::FixedBytes(_) => "Vec<u8>".into(), ParamType::Bytes | ParamType::FixedBytes(_) => "Vec<u8>".into(),
ParamType::Int(width) => match width { ParamType::Int(width) => match width {
8 | 16 | 32 | 64 => format!("i{}", width), 8 | 16 | 32 | 64 => format!("i{}", width),
@ -226,7 +226,7 @@ fn rust_type(input: ParamType) -> Result<String, ParamType> {
}, },
ParamType::Uint(width) => match width { ParamType::Uint(width) => match width {
8 | 16 | 32 | 64 => format!("u{}", width), 8 | 16 | 32 | 64 => format!("u{}", width),
128 | 160 | 256 => format!("util::U{}", width), 128 | 160 | 256 => format!("bigint::prelude::U{}", width),
_ => return Err(ParamType::Uint(width)), _ => return Err(ParamType::Uint(width)),
}, },
ParamType::Bool => "bool".into(), ParamType::Bool => "bool".into(),
@ -259,8 +259,8 @@ fn tokenize(name: &str, input: ParamType) -> (bool, String) {
}, },
ParamType::Uint(width) => format!( ParamType::Uint(width) => format!(
"let mut r = [0; 32]; {}.to_big_endian(&mut r); Token::Uint(r)", "let mut r = [0; 32]; {}.to_big_endian(&mut r); Token::Uint(r)",
if width <= 64 { format!("util::U256::from({} as u64)", name) } if width <= 64 { format!("bigint::prelude::U256::from({} as u64)", name) }
else { format!("util::U256::from({})", name) } else { format!("bigint::prelude::U256::from({})", name) }
), ),
ParamType::Bool => format!("Token::Bool({})", name), ParamType::Bool => format!("Token::Bool({})", name),
ParamType::String => format!("Token::String({})", name), ParamType::String => format!("Token::String({})", name),
@ -281,11 +281,11 @@ fn tokenize(name: &str, input: ParamType) -> (bool, String) {
// panics on unsupported types. // panics on unsupported types.
fn detokenize(name: &str, output_type: ParamType) -> String { fn detokenize(name: &str, output_type: ParamType) -> String {
match output_type { match output_type {
ParamType::Address => format!("{}.to_address().map(util::H160)", name), ParamType::Address => format!("{}.to_address().map(bigint::prelude::H160)", name),
ParamType::Bytes => format!("{}.to_bytes()", name), ParamType::Bytes => format!("{}.to_bytes()", name),
ParamType::FixedBytes(len) if len <= 32 => { ParamType::FixedBytes(len) if len <= 32 => {
// ensure no panic on slice too small. // ensure no panic on slice too small.
let read_hash = format!("b.resize({}, 0); util::H{}::from_slice(&b[..{}])", let read_hash = format!("b.resize({}, 0); bigint::prelude::H{}::from_slice(&b[..{}])",
len, len * 8, len); len, len * 8, len);
format!("{}.to_fixed_bytes().map(|mut b| {{ {} }})", format!("{}.to_fixed_bytes().map(|mut b| {{ {} }})",
@ -302,8 +302,8 @@ fn detokenize(name: &str, output_type: ParamType) -> String {
} }
ParamType::Uint(width) => { ParamType::Uint(width) => {
let read_uint = match width { let read_uint = match width {
8 | 16 | 32 | 64 => format!("util::U256(u).low_u64() as u{}", width), 8 | 16 | 32 | 64 => format!("bigint::prelude::U256(u).low_u64() as u{}", width),
_ => format!("util::U{}::from(&u[..])", width), _ => format!("bigint::prelude::U{}::from(&u[..])", width),
}; };
format!("{}.to_uint().map(|u| {})", name, read_uint) format!("{}.to_uint().map(|u| {})", name, read_uint)
@ -328,30 +328,30 @@ mod tests {
#[test] #[test]
fn input_types() { fn input_types() {
assert_eq!(::input_params_codegen(&[]).unwrap().0, ""); assert_eq!(::input_params_codegen(&[]).unwrap().0, "");
assert_eq!(::input_params_codegen(&[ParamType::Address]).unwrap().0, "param_0: util::Address, "); assert_eq!(::input_params_codegen(&[ParamType::Address]).unwrap().0, "param_0: bigint::prelude::H160, ");
assert_eq!(::input_params_codegen(&[ParamType::Address, ParamType::Bytes]).unwrap().0, assert_eq!(::input_params_codegen(&[ParamType::Address, ParamType::Bytes]).unwrap().0,
"param_0: util::Address, param_1: Vec<u8>, "); "param_0: bigint::prelude::H160, param_1: Vec<u8>, ");
} }
#[test] #[test]
fn output_types() { fn output_types() {
assert_eq!(::output_params_codegen(&[]).unwrap().0, "()"); assert_eq!(::output_params_codegen(&[]).unwrap().0, "()");
assert_eq!(::output_params_codegen(&[ParamType::Address]).unwrap().0, "(util::Address)"); assert_eq!(::output_params_codegen(&[ParamType::Address]).unwrap().0, "(bigint::prelude::H160)");
assert_eq!(::output_params_codegen(&[ParamType::Address, ParamType::Array(Box::new(ParamType::Bytes))]).unwrap().0, assert_eq!(::output_params_codegen(&[ParamType::Address, ParamType::Array(Box::new(ParamType::Bytes))]).unwrap().0,
"(util::Address, Vec<Vec<u8>>)"); "(bigint::prelude::H160, Vec<Vec<u8>>)");
} }
#[test] #[test]
fn rust_type() { fn rust_type() {
assert_eq!(::rust_type(ParamType::FixedBytes(32)).unwrap(), "util::H256"); assert_eq!(::rust_type(ParamType::FixedBytes(32)).unwrap(), "bigint::prelude::H256");
assert_eq!(::rust_type(ParamType::Array(Box::new(ParamType::FixedBytes(32)))).unwrap(), assert_eq!(::rust_type(ParamType::Array(Box::new(ParamType::FixedBytes(32)))).unwrap(),
"Vec<util::H256>"); "Vec<bigint::prelude::H256>");
assert_eq!(::rust_type(ParamType::Uint(64)).unwrap(), "u64"); assert_eq!(::rust_type(ParamType::Uint(64)).unwrap(), "u64");
assert!(::rust_type(ParamType::Uint(63)).is_err()); assert!(::rust_type(ParamType::Uint(63)).is_err());
assert_eq!(::rust_type(ParamType::Int(32)).unwrap(), "i32"); assert_eq!(::rust_type(ParamType::Int(32)).unwrap(), "i32");
assert_eq!(::rust_type(ParamType::Uint(256)).unwrap(), "util::U256"); assert_eq!(::rust_type(ParamType::Uint(256)).unwrap(), "bigint::prelude::U256");
} }
// codegen tests will need bootstrapping of some kind. // codegen tests will need bootstrapping of some kind.

View File

@ -0,0 +1 @@
[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"keyServersList","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"keyServer","type":"address"}],"name":"getKeyServerPublic","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getKeyServers","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"keyServer","type":"address"}],"name":"getKeyServerAddress","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"keyServer","type":"address"}],"name":"removeKeyServer","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"keyServerPublic","type":"bytes"},{"name":"keyServerIp","type":"string"}],"name":"addKeyServer","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keyServer","type":"address"}],"name":"KeyServerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keyServer","type":"address"}],"name":"KeyServerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]

View File

@ -14,32 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Std lib global reexports. #![allow(unused_mut, unused_variables, unused_imports)]
pub use std::io; //! Secret store Key Server set contract.
pub use std::fs;
pub use std::str;
pub use std::fmt;
pub use std::cmp;
pub use std::ptr;
pub use std::mem;
pub use std::ops;
pub use std::slice;
pub use std::result;
pub use std::option;
pub use std::path::Path; include!(concat!(env!("OUT_DIR"), "/key_server_set.rs"));
pub use std::str::{FromStr};
pub use std::io::{Read,Write};
pub use std::hash::{Hash, Hasher};
pub use std::error::Error as StdError;
pub use std::ops::*;
pub use std::cmp::*;
pub use std::sync::Arc;
pub use std::collections::*;
pub use heapsize::HeapSizeOf;
pub use itertools::Itertools;
pub use parking_lot::{Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};

View File

@ -21,8 +21,9 @@
extern crate futures; extern crate futures;
extern crate byteorder; extern crate byteorder;
extern crate ethabi; extern crate ethabi;
extern crate ethcore_util as util; extern crate ethcore_bigint as bigint;
mod key_server_set;
mod registry; mod registry;
mod urlhint; mod urlhint;
mod service_transaction; mod service_transaction;
@ -32,6 +33,7 @@ mod validator_report;
pub mod test_contracts; pub mod test_contracts;
pub use self::key_server_set::KeyServerSet;
pub use self::registry::Registry; pub use self::registry::Registry;
pub use self::urlhint::Urlhint; pub use self::urlhint::Urlhint;
pub use self::service_transaction::ServiceTransactionChecker; pub use self::service_transaction::ServiceTransactionChecker;

View File

@ -3,7 +3,6 @@
"engine": { "engine": {
"authorityRound": { "authorityRound": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"stepDuration": 1, "stepDuration": 1,
"startStep": 2, "startStep": 2,
"validators": { "validators": {
@ -17,6 +16,7 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -3,7 +3,6 @@
"engine": { "engine": {
"basicAuthority": { "basicAuthority": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"validators": { "validators": {
"list": ["0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6"] "list": ["0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6"]
@ -12,6 +11,7 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0100000", "accountStartNonce": "0x0100000",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -4,6 +4,7 @@
"null": null "null": null
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -4,15 +4,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": 1150000, "homesteadTransition": 1150000,
"eip150Transition": 2500000, "eip150Transition": 2500000,
"eip155Transition": 3000000,
"eip160Transition": 3000000, "eip160Transition": 3000000,
"ecip1010PauseTransition": 3000000, "ecip1010PauseTransition": 3000000,
"ecip1010ContinueTransition": 5000000, "ecip1010ContinueTransition": 5000000,
@ -24,6 +20,9 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
@ -31,6 +30,8 @@
"chainID": "0x3d", "chainID": "0x3d",
"forkBlock": "0x1d4c00", "forkBlock": "0x1d4c00",
"forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f",
"eip155Transition": 3000000,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff"
}, },

View File

@ -3,15 +3,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x0", "homesteadTransition": "0x0",
"eip150Transition": "0x0", "eip150Transition": "0x0",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
@ -20,12 +16,16 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff" "eip86Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -3,15 +3,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x0", "homesteadTransition": "0x0",
"eip150Transition": "0x0", "eip150Transition": "0x0",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x0", "eip160Transition": "0x0",
"eip161abcTransition": "0x0", "eip161abcTransition": "0x0",
"eip161dTransition": "0x0", "eip161dTransition": "0x0",
@ -20,12 +16,16 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff" "eip86Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -4,19 +4,15 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"difficultyIncrementDivisor": "60", "difficultyIncrementDivisor": "60",
"durationLimit": "0x3C", "durationLimit": "0x3C",
"blockReward": "0x6f05b59d3b200000",
"registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21",
"homesteadTransition": "0x30d40", "homesteadTransition": "0x30d40",
"difficultyHardforkTransition": "0x59d9", "difficultyHardforkTransition": "0x59d9",
"difficultyHardforkBoundDivisor": "0x0200", "difficultyHardforkBoundDivisor": "0x0200",
"bombDefuseTransition": "0x30d40", "bombDefuseTransition": "0x30d40",
"eip150Transition": "0x927C0", "eip150Transition": "0x927C0",
"eip155Transition": "0x927C0",
"eip160Transition": "0x927C0", "eip160Transition": "0x927C0",
"eip161abcTransition": "0x927C0", "eip161abcTransition": "0x927C0",
"eip161dTransition": "0x927C0" "eip161dTransition": "0x927C0"
@ -24,6 +20,9 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x6f05b59d3b200000",
"registrar" : "0x6c221ca53705f3497ec90ca7b84c59ae7382fc21",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
@ -31,7 +30,8 @@
"chainID": "0x2", "chainID": "0x2",
"subprotocolName": "exp", "subprotocolName": "exp",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x927C0"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -4,12 +4,9 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142",
"homesteadTransition": "0x118c30", "homesteadTransition": "0x118c30",
"daoHardforkTransition": "0x1d4c00", "daoHardforkTransition": "0x1d4c00",
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",
@ -132,7 +129,6 @@
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a" "0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
], ],
"eip150Transition": "0x259518", "eip150Transition": "0x259518",
"eip155Transition": 2675000,
"eip160Transition": 2675000, "eip160Transition": 2675000,
"eip161abcTransition": 2675000, "eip161abcTransition": 2675000,
"eip161dTransition": 2675000, "eip161dTransition": 2675000,
@ -141,12 +137,17 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"forkBlock": "0x1d4c00", "forkBlock": "0x1d4c00",
"forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb", "forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb",
"eip155Transition": 2675000,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff"
}, },

View File

@ -3,12 +3,9 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x118c30", "homesteadTransition": "0x118c30",
"daoHardforkTransition": "0x1d4c00", "daoHardforkTransition": "0x1d4c00",
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",
@ -131,7 +128,6 @@
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a" "0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
], ],
"eip150Transition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff" "eip161dTransition": "0x7fffffffffffffff"
@ -139,12 +135,16 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -3,15 +3,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x7fffffffffffffff", "homesteadTransition": "0x7fffffffffffffff",
"eip150Transition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff" "eip161dTransition": "0x7fffffffffffffff"
@ -19,12 +15,16 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -3,15 +3,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x0", "homesteadTransition": "0x0",
"eip150Transition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff" "eip161dTransition": "0x7fffffffffffffff"
@ -19,12 +15,16 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -4,10 +4,7 @@
"engine": { "engine": {
"authorityRound": { "authorityRound": {
"params": { "params": {
"gasLimitBoundDivisor": "0x400",
"registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3",
"stepDuration": "4", "stepDuration": "4",
"blockReward": "0x4563918244F40000",
"validators" : { "validators" : {
"list": [ "list": [
"0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED",
@ -25,16 +22,19 @@
] ]
}, },
"validateScoreTransition": 1000000, "validateScoreTransition": 1000000,
"eip155Transition": 1000000,
"validateStepTransition": 1500000 "validateStepTransition": 1500000
} }
} }
}, },
"params": { "params": {
"maximumExtraDataSize": "0x20", "gasLimitBoundDivisor": "0x400",
"registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3",
"blockReward": "0x4563918244F40000",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x2A", "networkID" : "0x2A",
"validateReceiptsTransition" : 1000000 "validateReceiptsTransition" : 1000000,
"eip155Transition": 1000000
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -3,15 +3,12 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x0", "homesteadTransition": "0x0",
"eip150Transition": "0x0", "eip150Transition": "0x0",
"eip155Transition": "0x0",
"eip160Transition": "0x0", "eip160Transition": "0x0",
"eip161abcTransition": "0x0", "eip161abcTransition": "0x0",
"eip161dTransition": "0x0", "eip161dTransition": "0x0",
@ -20,6 +17,9 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
@ -27,7 +27,8 @@
"eip98Transition": "0x0", "eip98Transition": "0x0",
"eip86Transition": "0x0", "eip86Transition": "0x0",
"eip140Transition": "0x0", "eip140Transition": "0x0",
"eip210Transition": "0x0" "eip210Transition": "0x0",
"eip155Transition": "0x0"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -4,15 +4,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d",
"homesteadTransition": 494000, "homesteadTransition": 494000,
"eip150Transition": 1783000, "eip150Transition": 1783000,
"eip155Transition": 1915000,
"eip160Transition": 1915000, "eip160Transition": 1915000,
"ecip1010PauseTransition": 1915000, "ecip1010PauseTransition": 1915000,
"ecip1010ContinueTransition": 3415000, "ecip1010ContinueTransition": 3415000,
@ -23,6 +19,9 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d",
"accountStartNonce": "0x0100000", "accountStartNonce": "0x0100000",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
@ -30,6 +29,8 @@
"chainID": "0x3e", "chainID": "0x3e",
"forkBlock": "0x1b34d8", "forkBlock": "0x1b34d8",
"forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145",
"eip155Transition": 1915000,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff"
}, },

View File

@ -3,15 +3,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x08", "durationLimit": "0x08",
"blockReward": "0x14D1120D7B160000",
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
"homesteadTransition": "0x7fffffffffffffff", "homesteadTransition": "0x7fffffffffffffff",
"eip150Transition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff" "eip161dTransition": "0x7fffffffffffffff"
@ -19,12 +15,16 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x14D1120D7B160000",
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x0400", "maximumExtraDataSize": "0x0400",
"minGasLimit": "125000", "minGasLimit": "125000",
"networkID" : "0x0", "networkID" : "0x0",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -4,15 +4,11 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2",
"homesteadTransition": 0, "homesteadTransition": 0,
"eip150Transition": 0, "eip150Transition": 0,
"eip155Transition": 10,
"eip160Transition": 10, "eip160Transition": 10,
"eip161abcTransition": 10, "eip161abcTransition": 10,
"eip161dTransition": 10, "eip161dTransition": 10,
@ -21,12 +17,17 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x3", "networkID" : "0x3",
"forkBlock": 641350, "forkBlock": 641350,
"forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb", "forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb",
"eip155Transition": 10,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff"
}, },

View File

@ -3,12 +3,9 @@
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x5", "homesteadTransition": "0x5",
"daoHardforkTransition": "0x8", "daoHardforkTransition": "0x8",
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754", "daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",
@ -131,7 +128,6 @@
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a" "0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
], ],
"eip150Transition": "0xa", "eip150Transition": "0xa",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff" "eip161dTransition": "0x7fffffffffffffff"
@ -139,12 +135,16 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00", "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff" "eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@ -1,13 +1,10 @@
{ {
"name": "DevelopmentChain", "name": "DevelopmentChain",
"engine": { "engine": {
"instantSeal": { "instantSeal": null
"params": {
"registrar": "0x0000000000000000000000000000000000000005"
}
}
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -4,6 +4,7 @@
"null": null "null": null
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -4,6 +4,7 @@
"null": null "null": null
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -3,7 +3,6 @@
"engine": { "engine": {
"tendermint": { "tendermint": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"validators" : { "validators" : {
"list": [ "list": [
"0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1", "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1",
@ -18,6 +17,7 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -3,7 +3,6 @@
"engine": { "engine": {
"authorityRound": { "authorityRound": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"stepDuration": 1, "stepDuration": 1,
"startStep": 2, "startStep": 2,
"validators": { "validators": {
@ -14,6 +13,7 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -3,7 +3,6 @@
"engine": { "engine": {
"basicAuthority": { "basicAuthority": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"validators": { "validators": {
"multi": { "multi": {
@ -15,6 +14,7 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

View File

@ -3,7 +3,6 @@
"engine": { "engine": {
"basicAuthority": { "basicAuthority": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"validators": { "validators": {
"safeContract": "0x0000000000000000000000000000000000000005" "safeContract": "0x0000000000000000000000000000000000000005"
@ -12,6 +11,7 @@
} }
}, },
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"accountStartNonce": "0x0", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",

@ -1 +1 @@
Subproject commit 9ed6304313fa949ed92aa0570fb2bc759fb6dc58 Subproject commit 85e76c5ea2a54c6c54e35014643b5080a50460c5

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! DB backend wrapper for Account trie //! DB backend wrapper for Account trie
use std::collections::HashMap;
use util::*; use util::*;
use rlp::NULL_RLP; use rlp::NULL_RLP;

View File

@ -519,6 +519,11 @@ impl AccountProvider {
} }
} }
/// Returns account public key.
pub fn account_public(&self, address: Address, password: &str) -> Result<Public, Error> {
self.sstore.public(&self.sstore.account_ref(&address)?, password)
}
/// Returns each account along with name and meta. /// Returns each account along with name and meta.
pub fn set_account_name(&self, address: Address, name: String) -> Result<(), Error> { pub fn set_account_name(&self, address: Address, name: String) -> Result<(), Error> {
self.sstore.set_name(&self.sstore.account_ref(&address)?, name)?; self.sstore.set_name(&self.sstore.account_ref(&address)?, name)?;
@ -697,6 +702,13 @@ impl AccountProvider {
Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?) Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?)
} }
/// Agree on shared key.
pub fn agree(&self, address: Address, password: Option<String>, other_public: &Public) -> Result<Secret, SignError> {
let account = self.sstore.account_ref(&address)?;
let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?;
Ok(self.sstore.agree(&account, &password, other_public)?)
}
/// Returns the underlying `SecretStore` reference if one exists. /// Returns the underlying `SecretStore` reference if one exists.
pub fn list_geth_accounts(&self, testnet: bool) -> Vec<Address> { pub fn list_geth_accounts(&self, testnet: bool) -> Vec<Address> {
self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect() self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect()

View File

@ -25,7 +25,7 @@ use util::{Bytes, Address, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RL
use util::error::{Mismatch, OutOfBounds}; use util::error::{Mismatch, OutOfBounds};
use basic_types::{LogBloom, Seal}; use basic_types::{LogBloom, Seal};
use evm::env_info::{EnvInfo, LastHashes}; use vm::{EnvInfo, LastHashes};
use engines::Engine; use engines::Engine;
use error::{Error, BlockError, TransactionError}; use error::{Error, BlockError, TransactionError};
use factory::Factories; use factory::Factories;
@ -667,7 +667,7 @@ mod tests {
use tests::helpers::*; use tests::helpers::*;
use super::*; use super::*;
use engines::Engine; use engines::Engine;
use evm::env_info::LastHashes; use vm::LastHashes;
use error::Error; use error::Error;
use header::Header; use header::Header;
use factory::Factories; use factory::Factories;

View File

@ -16,6 +16,10 @@
//! Blockchain database. //! Blockchain database.
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use std::mem;
use itertools::Itertools;
use bloomchain as bc; use bloomchain as bc;
use util::*; use util::*;
use rlp::*; use rlp::*;

View File

@ -16,6 +16,8 @@
//! Blockchain DB extras. //! Blockchain DB extras.
use std::ops;
use std::io::Write;
use bloomchain; use bloomchain;
use blooms::{GroupPosition, BloomGroup}; use blooms::{GroupPosition, BloomGroup};
use db::Key; use db::Key;
@ -23,11 +25,9 @@ use engines::epoch::{Transition as EpochTransition};
use header::BlockNumber; use header::BlockNumber;
use receipt::Receipt; use receipt::Receipt;
use rlp::*; use util::{HeapSizeOf, H256, H264, U256};
use util::*;
use util::kvdb::PREFIX_LEN as DB_PREFIX_LEN; use util::kvdb::PREFIX_LEN as DB_PREFIX_LEN;
/// Represents index of extra data in database /// Represents index of extra data in database
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)] #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
pub enum ExtrasIndex { pub enum ExtrasIndex {
@ -56,7 +56,7 @@ fn with_index(hash: &H256, i: ExtrasIndex) -> H264 {
pub struct BlockNumberKey([u8; 5]); pub struct BlockNumberKey([u8; 5]);
impl Deref for BlockNumberKey { impl ops::Deref for BlockNumberKey {
type Target = [u8]; type Target = [u8];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -88,7 +88,7 @@ impl Key<BlockDetails> for H256 {
pub struct LogGroupKey([u8; 6]); pub struct LogGroupKey([u8; 6]);
impl Deref for LogGroupKey { impl ops::Deref for LogGroupKey {
type Target = [u8]; type Target = [u8];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -160,7 +160,8 @@ pub const EPOCH_KEY_PREFIX: &'static [u8; DB_PREFIX_LEN] = &[
]; ];
pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]); pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]);
impl Deref for EpochTransitionsKey {
impl ops::Deref for EpochTransitionsKey {
type Target = [u8]; type Target = [u8];
fn deref(&self) -> &[u8] { &self.0[..] } fn deref(&self) -> &[u8] { &self.0[..] }
@ -181,7 +182,7 @@ impl Key<EpochTransitions> for u64 {
} }
/// Familial details concerning a block /// Familial details concerning a block
#[derive(Debug, Clone)] #[derive(Debug, Clone, RlpEncodable, RlpDecodable)]
pub struct BlockDetails { pub struct BlockDetails {
/// Block number /// Block number
pub number: BlockNumber, pub number: BlockNumber,
@ -199,30 +200,8 @@ impl HeapSizeOf for BlockDetails {
} }
} }
impl Decodable for BlockDetails {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
let details = BlockDetails {
number: rlp.val_at(0)?,
total_difficulty: rlp.val_at(1)?,
parent: rlp.val_at(2)?,
children: rlp.list_at(3)?,
};
Ok(details)
}
}
impl Encodable for BlockDetails {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(4);
s.append(&self.number);
s.append(&self.total_difficulty);
s.append(&self.parent);
s.append_list(&self.children);
}
}
/// Represents address of certain transaction within block /// Represents address of certain transaction within block
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone, RlpEncodable, RlpDecodable)]
pub struct TransactionAddress { pub struct TransactionAddress {
/// Block hash /// Block hash
pub block_hash: H256, pub block_hash: H256,
@ -234,27 +213,8 @@ impl HeapSizeOf for TransactionAddress {
fn heap_size_of_children(&self) -> usize { 0 } fn heap_size_of_children(&self) -> usize { 0 }
} }
impl Decodable for TransactionAddress {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
let tx_address = TransactionAddress {
block_hash: rlp.val_at(0)?,
index: rlp.val_at(1)?,
};
Ok(tx_address)
}
}
impl Encodable for TransactionAddress {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(2);
s.append(&self.block_hash);
s.append(&self.index);
}
}
/// Contains all block receipts. /// Contains all block receipts.
#[derive(Clone)] #[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct BlockReceipts { pub struct BlockReceipts {
pub receipts: Vec<Receipt>, pub receipts: Vec<Receipt>,
} }
@ -267,20 +227,6 @@ impl BlockReceipts {
} }
} }
impl Decodable for BlockReceipts {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(BlockReceipts {
receipts: rlp.as_list()?,
})
}
}
impl Encodable for BlockReceipts {
fn rlp_append(&self, s: &mut RlpStream) {
s.append_list(&self.receipts);
}
}
impl HeapSizeOf for BlockReceipts { impl HeapSizeOf for BlockReceipts {
fn heap_size_of_children(&self) -> usize { fn heap_size_of_children(&self) -> usize {
self.receipts.heap_size_of_children() self.receipts.heap_size_of_children()
@ -288,27 +234,12 @@ impl HeapSizeOf for BlockReceipts {
} }
/// Candidate transitions to an epoch with specific number. /// Candidate transitions to an epoch with specific number.
#[derive(Clone)] #[derive(Clone, RlpEncodable, RlpDecodable)]
pub struct EpochTransitions { pub struct EpochTransitions {
pub number: u64, pub number: u64,
pub candidates: Vec<EpochTransition>, pub candidates: Vec<EpochTransition>,
} }
impl Encodable for EpochTransitions {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(2).append(&self.number).append_list(&self.candidates);
}
}
impl Decodable for EpochTransitions {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(EpochTransitions {
number: rlp.val_at(0)?,
candidates: rlp.list_at(1)?,
})
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rlp::*; use rlp::*;

View File

@ -15,12 +15,11 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain as bc; use bloomchain as bc;
use rlp::*;
use util::HeapSizeOf; use util::HeapSizeOf;
use basic_types::LogBloom; use basic_types::LogBloom;
/// Helper structure representing bloom of the trace. /// Helper structure representing bloom of the trace.
#[derive(Debug, Clone)] #[derive(Debug, Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct Bloom(LogBloom); pub struct Bloom(LogBloom);
impl From<LogBloom> for Bloom { impl From<LogBloom> for Bloom {
@ -43,18 +42,6 @@ impl Into<bc::Bloom> for Bloom {
} }
} }
impl Decodable for Bloom {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
LogBloom::decode(rlp).map(Bloom)
}
}
impl Encodable for Bloom {
fn rlp_append(&self, s: &mut RlpStream) {
Encodable::rlp_append(&self.0, s)
}
}
impl HeapSizeOf for Bloom { impl HeapSizeOf for Bloom {
fn heap_size_of_children(&self) -> usize { fn heap_size_of_children(&self) -> usize {
0 0

View File

@ -36,9 +36,9 @@ impl From<&'static str> for Error {
} }
} }
impl Into<::evm::Error> for Error { impl Into<::vm::Error> for Error {
fn into(self) -> ::evm::Error { fn into(self) -> ::vm::Error {
::evm::Error::BuiltIn(self.0) ::vm::Error::BuiltIn(self.0)
} }
} }

View File

@ -20,9 +20,10 @@ use std::sync::{Arc, Weak};
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::time::{Instant}; use std::time::{Instant};
use time::precise_time_ns; use time::precise_time_ns;
use itertools::Itertools;
// util // util
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, MutexGuard, Hashable}; use util::{Bytes, PerfTimer, Mutex, RwLock, MutexGuard, Hashable};
use util::{journaldb, DBValue, TrieFactory, Trie}; use util::{journaldb, DBValue, TrieFactory, Trie};
use util::{U256, H256, Address, H2048}; use util::{U256, H256, Address, H2048};
use util::trie::TrieSpec; use util::trie::TrieSpec;
@ -42,9 +43,8 @@ use client::{
}; };
use encoded; use encoded;
use engines::{Engine, EpochTransition}; use engines::{Engine, EpochTransition};
use evm::env_info::EnvInfo;
use evm::env_info::LastHashes;
use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError};
use vm::{EnvInfo, LastHashes};
use evm::{Factory as EvmFactory, Schedule}; use evm::{Factory as EvmFactory, Schedule};
use executive::{Executive, Executed, TransactOptions, contract_address}; use executive::{Executive, Executed, TransactOptions, contract_address};
use factory::Factories; use factory::Factories;
@ -907,7 +907,7 @@ impl Client {
pub fn state_at(&self, id: BlockId) -> Option<State<StateDB>> { pub fn state_at(&self, id: BlockId) -> Option<State<StateDB>> {
// fast path for latest state. // fast path for latest state.
match id.clone() { match id.clone() {
BlockId::Pending => return self.miner.pending_state().or_else(|| Some(self.state())), BlockId::Pending => return self.miner.pending_state(self.chain.read().best_block_number()).or_else(|| Some(self.state())),
BlockId::Latest => return Some(self.state()), BlockId::Latest => return Some(self.state()),
_ => {}, _ => {},
} }
@ -1056,19 +1056,20 @@ impl Client {
self.history self.history
} }
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> { fn block_hash(chain: &BlockChain, miner: &Miner, id: BlockId) -> Option<H256> {
match id { match id {
BlockId::Hash(hash) => Some(hash), BlockId::Hash(hash) => Some(hash),
BlockId::Number(number) => chain.block_hash(number), BlockId::Number(number) => chain.block_hash(number),
BlockId::Earliest => chain.block_hash(0), BlockId::Earliest => chain.block_hash(0),
BlockId::Latest | BlockId::Pending => Some(chain.best_block_hash()), BlockId::Latest => Some(chain.best_block_hash()),
BlockId::Pending => miner.pending_block_header(chain.best_block_number()).map(|header| header.hash())
} }
} }
fn transaction_address(&self, id: TransactionId) -> Option<TransactionAddress> { fn transaction_address(&self, id: TransactionId) -> Option<TransactionAddress> {
match id { match id {
TransactionId::Hash(ref hash) => self.chain.read().transaction_address(hash), TransactionId::Hash(ref hash) => self.chain.read().transaction_address(hash),
TransactionId::Location(id, index) => Self::block_hash(&self.chain.read(), id).map(|hash| TransactionAddress { TransactionId::Location(id, index) => Self::block_hash(&self.chain.read(), &self.miner, id).map(|hash| TransactionAddress {
block_hash: hash, block_hash: hash,
index: index, index: index,
}) })
@ -1111,6 +1112,20 @@ impl Client {
data: data, data: data,
}.fake_sign(from) }.fake_sign(from)
} }
fn do_call(&self, env_info: &EnvInfo, state: &mut State<StateDB>, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, CallError> {
let original_state = if analytics.state_diffing { Some(state.clone()) } else { None };
let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false };
let mut ret = Executive::new(state, env_info, &*self.engine).transact_virtual(t, options)?;
// TODO gav move this into Executive.
if let Some(original) = original_state {
ret.state_diff = Some(state.diff_from(original).map_err(ExecutionError::from)?);
}
Ok(ret)
}
} }
impl snapshot::DatabaseRestore for Client { impl snapshot::DatabaseRestore for Client {
@ -1135,23 +1150,31 @@ impl snapshot::DatabaseRestore for Client {
} }
impl BlockChainClient for Client { impl BlockChainClient for Client {
fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result<Executed, CallError> { fn call(&self, transaction: &SignedTransaction, analytics: CallAnalytics, block: BlockId) -> Result<Executed, CallError> {
let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?; let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?;
env_info.gas_limit = U256::max_value(); env_info.gas_limit = U256::max_value();
// that's just a copy of the state. // that's just a copy of the state.
let mut state = self.state_at(block).ok_or(CallError::StatePruned)?; let mut state = self.state_at(block).ok_or(CallError::StatePruned)?;
let original_state = if analytics.state_diffing { Some(state.clone()) } else { None };
let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false }; self.do_call(&env_info, &mut state, transaction, analytics)
let mut ret = Executive::new(&mut state, &env_info, &*self.engine).transact_virtual(t, options)?; }
// TODO gav move this into Executive. fn call_many(&self, transactions: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result<Vec<Executed>, CallError> {
if let Some(original) = original_state { let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?;
ret.state_diff = Some(state.diff_from(original).map_err(ExecutionError::from)?); env_info.gas_limit = U256::max_value();
// that's just a copy of the state.
let mut state = self.state_at(block).ok_or(CallError::StatePruned)?;
let mut results = Vec::with_capacity(transactions.len());
for &(ref t, analytics) in transactions {
let ret = self.do_call(&env_info, &mut state, t, analytics)?;
env_info.gas_used = ret.cumulative_gas_used;
results.push(ret);
} }
Ok(ret) Ok(results)
} }
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> { fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
@ -1304,7 +1327,16 @@ impl BlockChainClient for Client {
fn block_header(&self, id: BlockId) -> Option<::encoded::Header> { fn block_header(&self, id: BlockId) -> Option<::encoded::Header> {
let chain = self.chain.read(); let chain = self.chain.read();
Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash))
if let BlockId::Pending = id {
if let Some(block) = self.miner.pending_block(chain.best_block_number()) {
return Some(encoded::Header::new(block.header.rlp(Seal::Without)));
}
// fall back to latest
return self.block_header(BlockId::Latest);
}
Self::block_hash(&chain, &self.miner, id).and_then(|hash| chain.block_header_data(&hash))
} }
fn block_number(&self, id: BlockId) -> Option<BlockNumber> { fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
@ -1312,30 +1344,48 @@ impl BlockChainClient for Client {
BlockId::Number(number) => Some(number), BlockId::Number(number) => Some(number),
BlockId::Hash(ref hash) => self.chain.read().block_number(hash), BlockId::Hash(ref hash) => self.chain.read().block_number(hash),
BlockId::Earliest => Some(0), BlockId::Earliest => Some(0),
BlockId::Latest | BlockId::Pending => Some(self.chain.read().best_block_number()), BlockId::Latest => Some(self.chain.read().best_block_number()),
BlockId::Pending => Some(self.chain.read().best_block_number() + 1),
} }
} }
fn block_body(&self, id: BlockId) -> Option<encoded::Body> { fn block_body(&self, id: BlockId) -> Option<encoded::Body> {
let chain = self.chain.read(); let chain = self.chain.read();
Self::block_hash(&chain, id).and_then(|hash| chain.block_body(&hash))
if let BlockId::Pending = id {
if let Some(block) = self.miner.pending_block(chain.best_block_number()) {
return Some(encoded::Body::new(BlockChain::block_to_body(&block.rlp_bytes(Seal::Without))));
}
// fall back to latest
return self.block_body(BlockId::Latest);
}
Self::block_hash(&chain, &self.miner, id).and_then(|hash| chain.block_body(&hash))
} }
fn block(&self, id: BlockId) -> Option<encoded::Block> { fn block(&self, id: BlockId) -> Option<encoded::Block> {
let chain = self.chain.read();
if let BlockId::Pending = id { if let BlockId::Pending = id {
if let Some(block) = self.miner.pending_block() { if let Some(block) = self.miner.pending_block(chain.best_block_number()) {
return Some(encoded::Block::new(block.rlp_bytes(Seal::Without))); return Some(encoded::Block::new(block.rlp_bytes(Seal::Without)));
} }
// fall back to latest
return self.block(BlockId::Latest);
} }
let chain = self.chain.read();
Self::block_hash(&chain, id).and_then(|hash| { Self::block_hash(&chain, &self.miner, id).and_then(|hash| {
chain.block(&hash) chain.block(&hash)
}) })
} }
fn block_status(&self, id: BlockId) -> BlockStatus { fn block_status(&self, id: BlockId) -> BlockStatus {
if let BlockId::Pending = id {
return BlockStatus::Pending;
}
let chain = self.chain.read(); let chain = self.chain.read();
match Self::block_hash(&chain, id) { match Self::block_hash(&chain, &self.miner, id) {
Some(ref hash) if chain.is_known(hash) => BlockStatus::InChain, Some(ref hash) if chain.is_known(hash) => BlockStatus::InChain,
Some(hash) => self.block_queue.status(&hash).into(), Some(hash) => self.block_queue.status(&hash).into(),
None => BlockStatus::Unknown None => BlockStatus::Unknown
@ -1343,13 +1393,18 @@ impl BlockChainClient for Client {
} }
fn block_total_difficulty(&self, id: BlockId) -> Option<U256> { fn block_total_difficulty(&self, id: BlockId) -> Option<U256> {
if let BlockId::Pending = id {
if let Some(block) = self.miner.pending_block() {
return Some(*block.header.difficulty() + self.block_total_difficulty(BlockId::Latest).expect("blocks in chain have details; qed"));
}
}
let chain = self.chain.read(); let chain = self.chain.read();
Self::block_hash(&chain, id).and_then(|hash| chain.block_details(&hash)).map(|d| d.total_difficulty) if let BlockId::Pending = id {
let latest_difficulty = self.block_total_difficulty(BlockId::Latest).expect("blocks in chain have details; qed");
let pending_difficulty = self.miner.pending_block_header(chain.best_block_number()).map(|header| *header.difficulty());
if let Some(difficulty) = pending_difficulty {
return Some(difficulty + latest_difficulty);
}
// fall back to latest
return Some(latest_difficulty);
}
Self::block_hash(&chain, &self.miner, id).and_then(|hash| chain.block_details(&hash)).map(|d| d.total_difficulty)
} }
fn nonce(&self, address: &Address, id: BlockId) -> Option<U256> { fn nonce(&self, address: &Address, id: BlockId) -> Option<U256> {
@ -1362,7 +1417,7 @@ impl BlockChainClient for Client {
fn block_hash(&self, id: BlockId) -> Option<H256> { fn block_hash(&self, id: BlockId) -> Option<H256> {
let chain = self.chain.read(); let chain = self.chain.read();
Self::block_hash(&chain, id) Self::block_hash(&chain, &self.miner, id)
} }
fn code(&self, address: &Address, id: BlockId) -> Option<Option<Bytes>> { fn code(&self, address: &Address, id: BlockId) -> Option<Option<Bytes>> {
@ -1527,7 +1582,8 @@ impl BlockChainClient for Client {
if self.chain.read().is_known(&unverified.hash()) { if self.chain.read().is_known(&unverified.hash()) {
return Err(BlockImportError::Import(ImportError::AlreadyInChain)); return Err(BlockImportError::Import(ImportError::AlreadyInChain));
} }
if self.block_status(BlockId::Hash(unverified.parent_hash())) == BlockStatus::Unknown { let status = self.block_status(BlockId::Hash(unverified.parent_hash()));
if status == BlockStatus::Unknown || status == BlockStatus::Pending {
return Err(BlockImportError::Block(BlockError::UnknownParent(unverified.parent_hash()))); return Err(BlockImportError::Block(BlockError::UnknownParent(unverified.parent_hash())));
} }
} }
@ -1541,7 +1597,8 @@ impl BlockChainClient for Client {
if self.chain.read().is_known(&header.hash()) { if self.chain.read().is_known(&header.hash()) {
return Err(BlockImportError::Import(ImportError::AlreadyInChain)); return Err(BlockImportError::Import(ImportError::AlreadyInChain));
} }
if self.block_status(BlockId::Hash(header.parent_hash())) == BlockStatus::Unknown { let status = self.block_status(BlockId::Hash(header.parent_hash()));
if status == BlockStatus::Unknown || status == BlockStatus::Pending {
return Err(BlockImportError::Block(BlockError::UnknownParent(header.parent_hash()))); return Err(BlockImportError::Block(BlockError::UnknownParent(header.parent_hash())));
} }
} }
@ -1663,8 +1720,8 @@ impl BlockChainClient for Client {
} }
} }
fn signing_network_id(&self) -> Option<u64> { fn signing_chain_id(&self) -> Option<u64> {
self.engine.signing_network_id(&self.latest_env_info()) self.engine.signing_chain_id(&self.latest_env_info())
} }
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>> { fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>> {
@ -1687,7 +1744,7 @@ impl BlockChainClient for Client {
fn call_contract(&self, block_id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String> { fn call_contract(&self, block_id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String> {
let transaction = self.contract_call_tx(block_id, address, data); let transaction = self.contract_call_tx(block_id, address, data);
self.call(&transaction, block_id, Default::default()) self.call(&transaction, Default::default(), block_id)
.map_err(|e| format!("{:?}", e)) .map_err(|e| format!("{:?}", e))
.map(|executed| { .map(|executed| {
executed.output executed.output
@ -1703,9 +1760,9 @@ impl BlockChainClient for Client {
value: U256::zero(), value: U256::zero(),
data: data, data: data,
}; };
let network_id = self.engine.signing_network_id(&self.latest_env_info()); let chain_id = self.engine.signing_chain_id(&self.latest_env_info());
let signature = self.engine.sign(transaction.hash(network_id))?; let signature = self.engine.sign(transaction.hash(chain_id))?;
let signed = SignedTransaction::new(transaction.with_signature(signature, network_id))?; let signed = SignedTransaction::new(transaction.with_signature(signature, chain_id))?;
self.miner.import_own_transaction(self, signed.into()) self.miner.import_own_transaction(self, signed.into())
} }

View File

@ -23,7 +23,7 @@ use util::kvdb::{self, KeyValueDB};
use {state, state_db, client, executive, trace, db, spec}; use {state, state_db, client, executive, trace, db, spec};
use factory::Factories; use factory::Factories;
use evm::{self, VMType}; use evm::{self, VMType};
use evm::action_params::ActionParams; use vm::{self, ActionParams};
/// EVM test Error. /// EVM test Error.
#[derive(Debug)] #[derive(Debug)]
@ -31,7 +31,7 @@ pub enum EvmTestError {
/// Trie integrity error. /// Trie integrity error.
Trie(util::TrieError), Trie(util::TrieError),
/// EVM error. /// EVM error.
Evm(evm::Error), Evm(vm::Error),
/// Initialization error. /// Initialization error.
Initialization(::error::Error), Initialization(::error::Error),
/// Low-level database error. /// Low-level database error.

View File

@ -40,7 +40,7 @@ pub use types::pruning_info::PruningInfo;
pub use types::call_analytics::CallAnalytics; pub use types::call_analytics::CallAnalytics;
pub use executive::{Executed, Executive, TransactOptions}; pub use executive::{Executed, Executive, TransactOptions};
pub use evm::env_info::{LastHashes, EnvInfo}; pub use vm::{LastHashes, EnvInfo};
pub use error::{BlockImportError, TransactionImportError, TransactionImportResult}; pub use error::{BlockImportError, TransactionImportError, TransactionImportResult};
pub use verification::VerifierType; pub use verification::VerifierType;

View File

@ -17,6 +17,10 @@
//! Test client. //! Test client.
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
use std::sync::Arc;
use std::collections::{HashMap, BTreeMap};
use std::mem;
use itertools::Itertools;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::*; use util::*;
use rlp::*; use rlp::*;
@ -36,7 +40,8 @@ use log_entry::LocalizedLogEntry;
use receipt::{Receipt, LocalizedReceipt}; use receipt::{Receipt, LocalizedReceipt};
use blockchain::extras::BlockReceipts; use blockchain::extras::BlockReceipts;
use error::{ImportResult, Error as EthcoreError}; use error::{ImportResult, Error as EthcoreError};
use evm::{Factory as EvmFactory, VMType, Schedule}; use evm::{Factory as EvmFactory, VMType};
use vm::Schedule;
use miner::{Miner, MinerService, TransactionImportResult}; use miner::{Miner, MinerService, TransactionImportResult};
use spec::Spec; use spec::Spec;
use types::basic_account::BasicAccount; use types::basic_account::BasicAccount;
@ -397,10 +402,18 @@ impl MiningBlockChainClient for TestBlockChainClient {
} }
impl BlockChainClient for TestBlockChainClient { impl BlockChainClient for TestBlockChainClient {
fn call(&self, _t: &SignedTransaction, _block: BlockId, _analytics: CallAnalytics) -> Result<Executed, CallError> { fn call(&self, _t: &SignedTransaction, _analytics: CallAnalytics, _block: BlockId) -> Result<Executed, CallError> {
self.execution_result.read().clone().unwrap() self.execution_result.read().clone().unwrap()
} }
fn call_many(&self, txs: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result<Vec<Executed>, CallError> {
let mut res = Vec::with_capacity(txs.len());
for &(ref tx, analytics) in txs {
res.push(self.call(tx, analytics, block)?);
}
Ok(res)
}
fn estimate_gas(&self, _t: &SignedTransaction, _block: BlockId) -> Result<U256, CallError> { fn estimate_gas(&self, _t: &SignedTransaction, _block: BlockId) -> Result<U256, CallError> {
Ok(21000.into()) Ok(21000.into())
} }
@ -419,7 +432,7 @@ impl BlockChainClient for TestBlockChainClient {
fn nonce(&self, address: &Address, id: BlockId) -> Option<U256> { fn nonce(&self, address: &Address, id: BlockId) -> Option<U256> {
match id { match id {
BlockId::Latest => Some(self.nonces.read().get(address).cloned().unwrap_or(self.spec.params().account_start_nonce)), BlockId::Latest | BlockId::Pending => Some(self.nonces.read().get(address).cloned().unwrap_or(self.spec.params().account_start_nonce)),
_ => None, _ => None,
} }
} }
@ -434,16 +447,15 @@ impl BlockChainClient for TestBlockChainClient {
fn code(&self, address: &Address, id: BlockId) -> Option<Option<Bytes>> { fn code(&self, address: &Address, id: BlockId) -> Option<Option<Bytes>> {
match id { match id {
BlockId::Latest => Some(self.code.read().get(address).cloned()), BlockId::Latest | BlockId::Pending => Some(self.code.read().get(address).cloned()),
_ => None, _ => None,
} }
} }
fn balance(&self, address: &Address, id: BlockId) -> Option<U256> { fn balance(&self, address: &Address, id: BlockId) -> Option<U256> {
if let BlockId::Latest = id { match id {
Some(self.balances.read().get(address).cloned().unwrap_or_else(U256::zero)) BlockId::Latest | BlockId::Pending => Some(self.balances.read().get(address).cloned().unwrap_or_else(U256::zero)),
} else { _ => None,
None
} }
} }
@ -452,10 +464,9 @@ impl BlockChainClient for TestBlockChainClient {
} }
fn storage_at(&self, address: &Address, position: &H256, id: BlockId) -> Option<H256> { fn storage_at(&self, address: &Address, position: &H256, id: BlockId) -> Option<H256> {
if let BlockId::Latest = id { match id {
Some(self.storage.read().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)) BlockId::Latest | BlockId::Pending => Some(self.storage.read().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)),
} else { _ => None,
None
} }
} }
@ -544,7 +555,8 @@ impl BlockChainClient for TestBlockChainClient {
match id { match id {
BlockId::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain, BlockId::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain,
BlockId::Hash(ref hash) if self.blocks.read().get(hash).is_some() => BlockStatus::InChain, BlockId::Hash(ref hash) if self.blocks.read().get(hash).is_some() => BlockStatus::InChain,
BlockId::Latest | BlockId::Pending | BlockId::Earliest => BlockStatus::InChain, BlockId::Latest | BlockId::Earliest => BlockStatus::InChain,
BlockId::Pending => BlockStatus::Pending,
_ => BlockStatus::Unknown, _ => BlockStatus::Unknown,
} }
} }
@ -722,7 +734,7 @@ impl BlockChainClient for TestBlockChainClient {
self.miner.ready_transactions(info.best_block_number, info.best_block_timestamp) self.miner.ready_transactions(info.best_block_number, info.best_block_timestamp)
} }
fn signing_network_id(&self) -> Option<u64> { None } fn signing_chain_id(&self) -> Option<u64> { None }
fn mode(&self) -> Mode { Mode::Active } fn mode(&self) -> Mode { Mode::Active }
@ -753,9 +765,9 @@ impl BlockChainClient for TestBlockChainClient {
value: U256::default(), value: U256::default(),
data: data, data: data,
}; };
let network_id = Some(self.spec.params().network_id); let chain_id = Some(self.spec.chain_id());
let sig = self.spec.engine.sign(transaction.hash(network_id)).unwrap(); let sig = self.spec.engine.sign(transaction.hash(chain_id)).unwrap();
let signed = SignedTransaction::new(transaction.with_signature(sig, network_id)).unwrap(); let signed = SignedTransaction::new(transaction.with_signature(sig, chain_id)).unwrap();
self.miner.import_own_transaction(self, signed.into()) self.miner.import_own_transaction(self, signed.into())
} }

View File

@ -15,11 +15,12 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap; use std::collections::BTreeMap;
use itertools::Itertools;
use block::{OpenBlock, SealedBlock, ClosedBlock}; use block::{OpenBlock, SealedBlock, ClosedBlock};
use blockchain::TreeRoute; use blockchain::TreeRoute;
use encoded; use encoded;
use evm::env_info::LastHashes; use vm::LastHashes;
use error::{ImportResult, CallError, Error as EthcoreError}; use error::{ImportResult, CallError, Error as EthcoreError};
use error::{TransactionImportResult, BlockImportError}; use error::{TransactionImportResult, BlockImportError};
use evm::{Factory as EvmFactory, Schedule}; use evm::{Factory as EvmFactory, Schedule};
@ -33,7 +34,7 @@ use trace::LocalizedTrace;
use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction}; use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction};
use verification::queue::QueueInfo as BlockQueueInfo; use verification::queue::QueueInfo as BlockQueueInfo;
use util::{U256, Address, H256, H2048, Bytes, Itertools}; use util::{U256, Address, H256, H2048, Bytes};
use util::hashdb::DBValue; use util::hashdb::DBValue;
use types::ids::*; use types::ids::*;
@ -182,7 +183,11 @@ pub trait BlockChainClient : Sync + Send {
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry>; fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry>;
/// Makes a non-persistent transaction call. /// Makes a non-persistent transaction call.
fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result<Executed, CallError>; fn call(&self, tx: &SignedTransaction, analytics: CallAnalytics, block: BlockId) -> Result<Executed, CallError>;
/// Makes multiple non-persistent but dependent transaction calls.
/// Returns a vector of successes or a failure if any of the transaction fails.
fn call_many(&self, txs: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result<Vec<Executed>, CallError>;
/// Estimates how much gas will be necessary for a call. /// Estimates how much gas will be necessary for a call.
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError>; fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError>;
@ -235,8 +240,8 @@ pub trait BlockChainClient : Sync + Send {
corpus.into() corpus.into()
} }
/// Get the preferred network ID to sign on /// Get the preferred chain ID to sign on
fn signing_network_id(&self) -> Option<u64>; fn signing_chain_id(&self) -> Option<u64>;
/// Get the mode. /// Get the mode.
fn mode(&self) -> Mode; fn mode(&self) -> Mode;

View File

@ -17,8 +17,10 @@
//! A blockchain engine that supports a non-instant BFT proof-of-authority. //! A blockchain engine that supports a non-instant BFT proof-of-authority.
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::sync::Weak; use std::sync::{Weak, Arc};
use std::time::{UNIX_EPOCH, Duration}; use std::time::{UNIX_EPOCH, Duration};
use std::collections::{BTreeMap, HashSet, HashMap};
use std::cmp;
use account_provider::AccountProvider; use account_provider::AccountProvider;
use block::*; use block::*;
@ -47,22 +49,14 @@ mod finality;
/// `AuthorityRound` params. /// `AuthorityRound` params.
pub struct AuthorityRoundParams { pub struct AuthorityRoundParams {
/// Gas limit divisor.
pub gas_limit_bound_divisor: U256,
/// Time to wait before next block or authority switching. /// Time to wait before next block or authority switching.
pub step_duration: Duration, pub step_duration: Duration,
/// Block reward.
pub block_reward: U256,
/// Namereg contract address.
pub registrar: Address,
/// Starting step, /// Starting step,
pub start_step: Option<u64>, pub start_step: Option<u64>,
/// Valid validators. /// Valid validators.
pub validators: Box<ValidatorSet>, pub validators: Box<ValidatorSet>,
/// Chain score validation transition block. /// Chain score validation transition block.
pub validate_score_transition: u64, pub validate_score_transition: u64,
/// Number of first block where EIP-155 rules are validated.
pub eip155_transition: u64,
/// Monotonic step validation transition block. /// Monotonic step validation transition block.
pub validate_step_transition: u64, pub validate_step_transition: u64,
/// Immediate transitions. /// Immediate transitions.
@ -72,14 +66,10 @@ pub struct AuthorityRoundParams {
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams { impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
fn from(p: ethjson::spec::AuthorityRoundParams) -> Self { fn from(p: ethjson::spec::AuthorityRoundParams) -> Self {
AuthorityRoundParams { AuthorityRoundParams {
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
step_duration: Duration::from_secs(p.step_duration.into()), step_duration: Duration::from_secs(p.step_duration.into()),
validators: new_validator_set(p.validators), validators: new_validator_set(p.validators),
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
registrar: p.registrar.map_or_else(Address::new, Into::into),
start_step: p.start_step.map(Into::into), start_step: p.start_step.map(Into::into),
validate_score_transition: p.validate_score_transition.map_or(0, Into::into), validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
eip155_transition: p.eip155_transition.map_or(0, Into::into),
validate_step_transition: p.validate_step_transition.map_or(0, Into::into), validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
immediate_transitions: p.immediate_transitions.unwrap_or(false), immediate_transitions: p.immediate_transitions.unwrap_or(false),
} }
@ -214,9 +204,6 @@ impl EpochManager {
/// Engine using `AuthorityRound` proof-of-authority BFT consensus. /// Engine using `AuthorityRound` proof-of-authority BFT consensus.
pub struct AuthorityRound { pub struct AuthorityRound {
params: CommonParams, params: CommonParams,
gas_limit_bound_divisor: U256,
block_reward: U256,
registrar: Address,
builtins: BTreeMap<Address, Builtin>, builtins: BTreeMap<Address, Builtin>,
transition_service: IoService<()>, transition_service: IoService<()>,
step: Arc<Step>, step: Arc<Step>,
@ -225,7 +212,6 @@ pub struct AuthorityRound {
signer: RwLock<EngineSigner>, signer: RwLock<EngineSigner>,
validators: Box<ValidatorSet>, validators: Box<ValidatorSet>,
validate_score_transition: u64, validate_score_transition: u64,
eip155_transition: u64,
validate_step_transition: u64, validate_step_transition: u64,
epoch_manager: Mutex<EpochManager>, epoch_manager: Mutex<EpochManager>,
immediate_transitions: bool, immediate_transitions: bool,
@ -362,9 +348,6 @@ impl AuthorityRound {
let engine = Arc::new( let engine = Arc::new(
AuthorityRound { AuthorityRound {
params: params, params: params,
gas_limit_bound_divisor: our_params.gas_limit_bound_divisor,
block_reward: our_params.block_reward,
registrar: our_params.registrar,
builtins: builtins, builtins: builtins,
transition_service: IoService::<()>::start()?, transition_service: IoService::<()>::start()?,
step: Arc::new(Step { step: Arc::new(Step {
@ -377,7 +360,6 @@ impl AuthorityRound {
signer: Default::default(), signer: Default::default(),
validators: our_params.validators, validators: our_params.validators,
validate_score_transition: our_params.validate_score_transition, validate_score_transition: our_params.validate_score_transition,
eip155_transition: our_params.eip155_transition,
validate_step_transition: our_params.validate_step_transition, validate_step_transition: our_params.validate_step_transition,
epoch_manager: Mutex::new(EpochManager::blank()), epoch_manager: Mutex::new(EpochManager::blank()),
immediate_transitions: our_params.immediate_transitions, immediate_transitions: our_params.immediate_transitions,
@ -433,7 +415,9 @@ impl Engine for AuthorityRound {
fn params(&self) -> &CommonParams { &self.params } fn params(&self) -> &CommonParams { &self.params }
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.registrar.hex()] } fn additional_params(&self) -> HashMap<String, String> {
hash_map!["registrar".to_owned() => self.params().registrar.hex()]
}
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins } fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
@ -461,11 +445,11 @@ impl Engine for AuthorityRound {
header.set_difficulty(new_difficulty); header.set_difficulty(new_difficulty);
header.set_gas_limit({ header.set_gas_limit({
let gas_limit = parent.gas_limit().clone(); let gas_limit = parent.gas_limit().clone();
let bound_divisor = self.gas_limit_bound_divisor; let bound_divisor = self.params().gas_limit_bound_divisor;
if gas_limit < gas_floor_target { if gas_limit < gas_floor_target {
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
} else { } else {
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into())
} }
}); });
} }
@ -532,7 +516,7 @@ impl Engine for AuthorityRound {
fn on_new_block( fn on_new_block(
&self, &self,
block: &mut ExecutedBlock, block: &mut ExecutedBlock,
last_hashes: Arc<::evm::env_info::LastHashes>, last_hashes: Arc<::vm::LastHashes>,
epoch_begin: bool, epoch_begin: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
let parent_hash = block.fields().header.parent_hash().clone(); let parent_hash = block.fields().header.parent_hash().clone();
@ -564,7 +548,8 @@ impl Engine for AuthorityRound {
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
let fields = block.fields_mut(); let fields = block.fields_mut();
// Bestow block reward // Bestow block reward
let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) let reward = self.params().block_reward;
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
.map_err(::error::Error::from) .map_err(::error::Error::from)
.and_then(|_| fields.state.commit()); .and_then(|_| fields.state.commit());
// Commit state so that we can actually figure out the state root. // Commit state so that we can actually figure out the state root.
@ -629,7 +614,7 @@ impl Engine for AuthorityRound {
} }
} }
let gas_limit_divisor = self.gas_limit_bound_divisor; let gas_limit_divisor = self.params().gas_limit_bound_divisor;
let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor;
let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor;
if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas {
@ -707,6 +692,7 @@ impl Engine for AuthorityRound {
// apply immediate transitions. // apply immediate transitions.
if let Some(change) = self.validators.is_epoch_end(first, chain_head) { if let Some(change) = self.validators.is_epoch_end(first, chain_head) {
let change = combine_proofs(chain_head.number(), &change, &[]);
return Some(change) return Some(change)
} }
@ -817,12 +803,12 @@ impl Engine for AuthorityRound {
} }
} }
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> {
t.check_low_s()?; t.check_low_s()?;
if let Some(n) = t.network_id() { if let Some(n) = t.chain_id() {
if header.number() >= self.eip155_transition && n != self.params().chain_id { if header.number() >= self.params().eip155_transition && n != self.params().chain_id {
return Err(TransactionError::InvalidNetworkId.into()); return Err(TransactionError::InvalidChainId.into());
} }
} }
@ -853,6 +839,7 @@ impl Engine for AuthorityRound {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use util::*; use util::*;
use header::Header; use header::Header;
@ -943,10 +930,10 @@ mod tests {
let addr = tap.insert_account("0".sha3().into(), "0").unwrap(); let addr = tap.insert_account("0".sha3().into(), "0").unwrap();
let mut parent_header: Header = Header::default(); let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&0usize).into_vec()]); parent_header.set_seal(vec![encode(&0usize).into_vec()]);
parent_header.set_gas_limit(U256::from_str("222222").unwrap()); parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
let mut header: Header = Header::default(); let mut header: Header = Header::default();
header.set_number(1); header.set_number(1);
header.set_gas_limit(U256::from_str("222222").unwrap()); header.set_gas_limit("222222".parse::<U256>().unwrap());
header.set_author(addr); header.set_author(addr);
let engine = Spec::new_test_round().engine; let engine = Spec::new_test_round().engine;
@ -969,10 +956,10 @@ mod tests {
let mut parent_header: Header = Header::default(); let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&0usize).into_vec()]); parent_header.set_seal(vec![encode(&0usize).into_vec()]);
parent_header.set_gas_limit(U256::from_str("222222").unwrap()); parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
let mut header: Header = Header::default(); let mut header: Header = Header::default();
header.set_number(1); header.set_number(1);
header.set_gas_limit(U256::from_str("222222").unwrap()); header.set_gas_limit("222222".parse::<U256>().unwrap());
header.set_author(addr); header.set_author(addr);
let engine = Spec::new_test_round().engine; let engine = Spec::new_test_round().engine;
@ -995,10 +982,10 @@ mod tests {
let mut parent_header: Header = Header::default(); let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&4usize).into_vec()]); parent_header.set_seal(vec![encode(&4usize).into_vec()]);
parent_header.set_gas_limit(U256::from_str("222222").unwrap()); parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
let mut header: Header = Header::default(); let mut header: Header = Header::default();
header.set_number(1); header.set_number(1);
header.set_gas_limit(U256::from_str("222222").unwrap()); header.set_gas_limit("222222".parse::<U256>().unwrap());
header.set_author(addr); header.set_author(addr);
let engine = Spec::new_test_round().engine; let engine = Spec::new_test_round().engine;
@ -1016,25 +1003,26 @@ mod tests {
fn reports_skipped() { fn reports_skipped() {
let last_benign = Arc::new(AtomicUsize::new(0)); let last_benign = Arc::new(AtomicUsize::new(0));
let params = AuthorityRoundParams { let params = AuthorityRoundParams {
gas_limit_bound_divisor: U256::from_str("400").unwrap(),
step_duration: Default::default(), step_duration: Default::default(),
block_reward: Default::default(),
registrar: Default::default(),
start_step: Some(1), start_step: Some(1),
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())), validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
validate_score_transition: 0, validate_score_transition: 0,
validate_step_transition: 0, validate_step_transition: 0,
eip155_transition: 0,
immediate_transitions: true, immediate_transitions: true,
}; };
let aura = AuthorityRound::new(Default::default(), params, Default::default()).unwrap();
let aura = {
let mut c_params = ::spec::CommonParams::default();
c_params.gas_limit_bound_divisor = 5.into();
AuthorityRound::new(c_params, params, Default::default()).unwrap()
};
let mut parent_header: Header = Header::default(); let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&1usize).into_vec()]); parent_header.set_seal(vec![encode(&1usize).into_vec()]);
parent_header.set_gas_limit(U256::from_str("222222").unwrap()); parent_header.set_gas_limit("222222".parse::<U256>().unwrap());
let mut header: Header = Header::default(); let mut header: Header = Header::default();
header.set_number(1); header.set_number(1);
header.set_gas_limit(U256::from_str("222222").unwrap()); header.set_gas_limit("222222".parse::<U256>().unwrap());
header.set_seal(vec![encode(&3usize).into_vec()]); header.set_seal(vec![encode(&3usize).into_vec()]);
// Do not report when signer not present. // Do not report when signer not present.

View File

@ -16,7 +16,9 @@
//! A blockchain engine that supports a basic, non-BFT proof-of-authority. //! A blockchain engine that supports a basic, non-BFT proof-of-authority.
use std::sync::Weak; use std::sync::{Weak, Arc};
use std::collections::BTreeMap;
use std::cmp;
use util::*; use util::*;
use ethkey::{recover, public_to_address, Signature}; use ethkey::{recover, public_to_address, Signature};
use account_provider::AccountProvider; use account_provider::AccountProvider;
@ -35,8 +37,6 @@ use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
/// `BasicAuthority` params. /// `BasicAuthority` params.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct BasicAuthorityParams { pub struct BasicAuthorityParams {
/// Gas limit divisor.
pub gas_limit_bound_divisor: U256,
/// Valid signatories. /// Valid signatories.
pub validators: ethjson::spec::ValidatorSet, pub validators: ethjson::spec::ValidatorSet,
} }
@ -44,7 +44,6 @@ pub struct BasicAuthorityParams {
impl From<ethjson::spec::BasicAuthorityParams> for BasicAuthorityParams { impl From<ethjson::spec::BasicAuthorityParams> for BasicAuthorityParams {
fn from(p: ethjson::spec::BasicAuthorityParams) -> Self { fn from(p: ethjson::spec::BasicAuthorityParams) -> Self {
BasicAuthorityParams { BasicAuthorityParams {
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
validators: p.validators, validators: p.validators,
} }
} }
@ -80,7 +79,6 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err
/// Engine using `BasicAuthority`, trivial proof-of-authority consensus. /// Engine using `BasicAuthority`, trivial proof-of-authority consensus.
pub struct BasicAuthority { pub struct BasicAuthority {
params: CommonParams, params: CommonParams,
gas_limit_bound_divisor: U256,
builtins: BTreeMap<Address, Builtin>, builtins: BTreeMap<Address, Builtin>,
signer: RwLock<EngineSigner>, signer: RwLock<EngineSigner>,
validators: Box<ValidatorSet>, validators: Box<ValidatorSet>,
@ -91,7 +89,6 @@ impl BasicAuthority {
pub fn new(params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap<Address, Builtin>) -> Self { pub fn new(params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap<Address, Builtin>) -> Self {
BasicAuthority { BasicAuthority {
params: params, params: params,
gas_limit_bound_divisor: our_params.gas_limit_bound_divisor,
builtins: builtins, builtins: builtins,
validators: new_validator_set(our_params.validators), validators: new_validator_set(our_params.validators),
signer: Default::default(), signer: Default::default(),
@ -119,11 +116,11 @@ impl Engine for BasicAuthority {
header.set_difficulty(parent.difficulty().clone()); header.set_difficulty(parent.difficulty().clone());
header.set_gas_limit({ header.set_gas_limit({
let gas_limit = parent.gas_limit().clone(); let gas_limit = parent.gas_limit().clone();
let bound_divisor = self.gas_limit_bound_divisor; let bound_divisor = self.params().gas_limit_bound_divisor;
if gas_limit < gas_floor_target { if gas_limit < gas_floor_target {
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
} else { } else {
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into())
} }
}); });
} }
@ -147,7 +144,7 @@ impl Engine for BasicAuthority {
Seal::None Seal::None
} }
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
// check the seal fields. // check the seal fields.
// TODO: pull this out into common code. // TODO: pull this out into common code.
if header.seal().len() != self.seal_fields() { if header.seal().len() != self.seal_fields() {
@ -158,11 +155,11 @@ impl Engine for BasicAuthority {
Ok(()) Ok(())
} }
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
// Do not calculate difficulty for genesis blocks. // Do not calculate difficulty for genesis blocks.
if header.number() == 0 { if header.number() == 0 {
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
@ -172,7 +169,7 @@ impl Engine for BasicAuthority {
if header.difficulty() != parent.difficulty() { if header.difficulty() != parent.difficulty() {
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() }))) return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() })))
} }
let gas_limit_divisor = self.gas_limit_bound_divisor; let gas_limit_divisor = self.params().gas_limit_bound_divisor;
let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor;
let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor;
if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas {
@ -254,6 +251,7 @@ impl Engine for BasicAuthority {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use util::*; use util::*;
use block::*; use block::*;
use error::{BlockError, Error}; use error::{BlockError, Error};

View File

@ -16,14 +16,12 @@
//! Epoch verifiers and transitions. //! Epoch verifiers and transitions.
use util::H256;
use error::Error; use error::Error;
use header::Header; use header::Header;
use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp};
use util::H256;
/// A full epoch transition. /// A full epoch transition.
#[derive(Debug, Clone)] #[derive(Debug, Clone, RlpEncodable, RlpDecodable)]
pub struct Transition { pub struct Transition {
/// Block hash at which the transition occurred. /// Block hash at which the transition occurred.
pub block_hash: H256, pub block_hash: H256,
@ -33,46 +31,14 @@ pub struct Transition {
pub proof: Vec<u8>, pub proof: Vec<u8>,
} }
impl Encodable for Transition {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(3)
.append(&self.block_hash)
.append(&self.block_number)
.append(&self.proof);
}
}
impl Decodable for Transition {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(Transition {
block_hash: rlp.val_at(0)?,
block_number: rlp.val_at(1)?,
proof: rlp.val_at(2)?,
})
}
}
/// An epoch transition pending a finality proof. /// An epoch transition pending a finality proof.
/// Not all transitions need one. /// Not all transitions need one.
#[derive(RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct PendingTransition { pub struct PendingTransition {
/// "transition/epoch" proof from the engine. /// "transition/epoch" proof from the engine.
pub proof: Vec<u8>, pub proof: Vec<u8>,
} }
impl Encodable for PendingTransition {
fn rlp_append(&self, s: &mut RlpStream) {
s.append(&self.proof);
}
}
impl Decodable for PendingTransition {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(PendingTransition {
proof: rlp.as_val()?,
})
}
}
/// Verifier for all blocks within an epoch with self-contained state. /// Verifier for all blocks within an epoch with self-contained state.
/// ///
/// See docs on `Engine` relating to proving functions for more details. /// See docs on `Engine` relating to proving functions for more details.

View File

@ -14,26 +14,24 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap; use std::collections::{BTreeMap, HashMap};
use util::{Address, HashMap}; use util::Address;
use builtin::Builtin; use builtin::Builtin;
use engines::{Engine, Seal}; use engines::{Engine, Seal};
use spec::CommonParams; use spec::CommonParams;
use block::ExecutedBlock; use block::{ExecutedBlock, IsBlock};
/// An engine which does not provide any consensus mechanism, just seals blocks internally. /// An engine which does not provide any consensus mechanism, just seals blocks internally.
pub struct InstantSeal { pub struct InstantSeal {
params: CommonParams, params: CommonParams,
registrar: Address,
builtins: BTreeMap<Address, Builtin>, builtins: BTreeMap<Address, Builtin>,
} }
impl InstantSeal { impl InstantSeal {
/// Returns new instance of InstantSeal with default VM Factory /// Returns new instance of InstantSeal with default VM Factory
pub fn new(params: CommonParams, registrar: Address, builtins: BTreeMap<Address, Builtin>) -> Self { pub fn new(params: CommonParams, builtins: BTreeMap<Address, Builtin>) -> Self {
InstantSeal { InstantSeal {
params: params, params: params,
registrar: registrar,
builtins: builtins, builtins: builtins,
} }
} }
@ -49,7 +47,7 @@ impl Engine for InstantSeal {
} }
fn additional_params(&self) -> HashMap<String, String> { fn additional_params(&self) -> HashMap<String, String> {
hash_map!["registrar".to_owned() => self.registrar.hex()] hash_map!["registrar".to_owned() => self.params().registrar.hex()]
} }
fn builtins(&self) -> &BTreeMap<Address, Builtin> { fn builtins(&self) -> &BTreeMap<Address, Builtin> {
@ -58,13 +56,14 @@ impl Engine for InstantSeal {
fn seals_internally(&self) -> Option<bool> { Some(true) } fn seals_internally(&self) -> Option<bool> { Some(true) }
fn generate_seal(&self, _block: &ExecutedBlock) -> Seal { fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
Seal::Regular(Vec::new()) if block.transactions().is_empty() { Seal::None } else { Seal::Regular(Vec::new()) }
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use util::*; use util::*;
use tests::helpers::*; use tests::helpers::*;
use spec::Spec; use spec::Spec;

View File

@ -35,7 +35,9 @@ pub use self::instant_seal::InstantSeal;
pub use self::null_engine::NullEngine; pub use self::null_engine::NullEngine;
pub use self::tendermint::Tendermint; pub use self::tendermint::Tendermint;
use std::sync::Weak; use std::sync::{Weak, Arc};
use std::collections::{BTreeMap, HashMap};
use std::fmt;
use self::epoch::PendingTransition; use self::epoch::PendingTransition;
@ -43,15 +45,13 @@ use account_provider::AccountProvider;
use block::ExecutedBlock; use block::ExecutedBlock;
use builtin::Builtin; use builtin::Builtin;
use client::EngineClient; use client::EngineClient;
use evm::env_info::{EnvInfo, LastHashes}; use vm::{EnvInfo, LastHashes, Schedule, CreateContractAddress};
use error::Error; use error::Error;
use evm::Schedule;
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};
use receipt::Receipt; use receipt::Receipt;
use snapshot::SnapshotComponents; use snapshot::SnapshotComponents;
use spec::CommonParams; use spec::CommonParams;
use transaction::{UnverifiedTransaction, SignedTransaction}; use transaction::{UnverifiedTransaction, SignedTransaction};
use evm::CreateContractAddress;
use ethkey::Signature; use ethkey::Signature;
use util::*; use util::*;
@ -273,7 +273,7 @@ pub trait Engine : Sync + Send {
// TODO: Add flags for which bits of the transaction to check. // TODO: Add flags for which bits of the transaction to check.
// TODO: consider including State in the params. // TODO: consider including State in the params.
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> { fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> {
t.verify_basic(true, Some(self.params().network_id), true)?; t.verify_basic(true, Some(self.params().chain_id), true)?;
Ok(()) Ok(())
} }
@ -283,7 +283,7 @@ pub trait Engine : Sync + Send {
} }
/// The network ID that transactions should be signed with. /// The network ID that transactions should be signed with.
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> { fn signing_chain_id(&self, _env_info: &EnvInfo) -> Option<u64> {
Some(self.params().chain_id) Some(self.params().chain_id)
} }
@ -403,13 +403,12 @@ pub trait Engine : Sync + Send {
/// Common engine utilities /// Common engine utilities
pub mod common { pub mod common {
use std::sync::Arc;
use block::ExecutedBlock; use block::ExecutedBlock;
use evm::env_info::{EnvInfo, LastHashes};
use error::Error; use error::Error;
use transaction::SYSTEM_ADDRESS; use transaction::SYSTEM_ADDRESS;
use executive::Executive; use executive::Executive;
use evm::CallType; use vm::{CallType, ActionParams, ActionValue, EnvInfo, LastHashes};
use evm::action_params::{ActionParams, ActionValue};
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
use state::Substate; use state::Substate;

View File

@ -62,6 +62,6 @@ impl Engine for NullEngine {
} }
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> { fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
Some(Box::new(::snapshot::PowSnapshot(10000))) Some(Box::new(::snapshot::PowSnapshot::new(10000, 10000)))
} }
} }

View File

@ -16,7 +16,8 @@
//! A signer used by Engines which need to sign messages. //! A signer used by Engines which need to sign messages.
use util::{Arc, H256, Address}; use std::sync::Arc;
use util::{H256, Address};
use ethkey::Signature; use ethkey::Signature;
use account_provider::{self, AccountProvider}; use account_provider::{self, AccountProvider};

View File

@ -16,6 +16,7 @@
//! Tendermint message handling. //! Tendermint message handling.
use std::cmp;
use util::*; use util::*;
use super::{Height, View, BlockHash, Step}; use super::{Height, View, BlockHash, Step};
use error::Error; use error::Error;
@ -110,13 +111,13 @@ impl Default for VoteStep {
} }
impl PartialOrd for VoteStep { impl PartialOrd for VoteStep {
fn partial_cmp(&self, m: &VoteStep) -> Option<Ordering> { fn partial_cmp(&self, m: &VoteStep) -> Option<cmp::Ordering> {
Some(self.cmp(m)) Some(self.cmp(m))
} }
} }
impl Ord for VoteStep { impl Ord for VoteStep {
fn cmp(&self, m: &VoteStep) -> Ordering { fn cmp(&self, m: &VoteStep) -> cmp::Ordering {
if self.height != m.height { if self.height != m.height {
self.height.cmp(&m.height) self.height.cmp(&m.height)
} else if self.view != m.view { } else if self.view != m.view {
@ -198,6 +199,7 @@ pub fn message_hash(vote_step: VoteStep, block_hash: H256) -> H256 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use util::*; use util::*;
use rlp::*; use rlp::*;
use account_provider::AccountProvider; use account_provider::AccountProvider;

View File

@ -25,8 +25,10 @@
mod message; mod message;
mod params; mod params;
use std::sync::Weak; use std::sync::{Weak, Arc};
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use std::collections::{HashSet, BTreeMap, HashMap};
use std::cmp;
use util::*; use util::*;
use client::EngineClient; use client::EngineClient;
use error::{Error, BlockError}; use error::{Error, BlockError};
@ -71,12 +73,9 @@ pub type BlockHash = H256;
/// Engine using `Tendermint` consensus algorithm, suitable for EVM chain. /// Engine using `Tendermint` consensus algorithm, suitable for EVM chain.
pub struct Tendermint { pub struct Tendermint {
params: CommonParams, params: CommonParams,
gas_limit_bound_divisor: U256,
builtins: BTreeMap<Address, Builtin>, builtins: BTreeMap<Address, Builtin>,
step_service: IoService<Step>, step_service: IoService<Step>,
client: RwLock<Option<Weak<EngineClient>>>, client: RwLock<Option<Weak<EngineClient>>>,
block_reward: U256,
registrar: Address,
/// Blockchain height. /// Blockchain height.
height: AtomicUsize, height: AtomicUsize,
/// Consensus view. /// Consensus view.
@ -166,12 +165,9 @@ impl Tendermint {
let engine = Arc::new( let engine = Arc::new(
Tendermint { Tendermint {
params: params, params: params,
gas_limit_bound_divisor: our_params.gas_limit_bound_divisor,
builtins: builtins, builtins: builtins,
client: RwLock::new(None), client: RwLock::new(None),
step_service: IoService::<Step>::start()?, step_service: IoService::<Step>::start()?,
block_reward: our_params.block_reward,
registrar: our_params.registrar,
height: AtomicUsize::new(1), height: AtomicUsize::new(1),
view: AtomicUsize::new(0), view: AtomicUsize::new(0),
step: RwLock::new(Step::Propose), step: RwLock::new(Step::Propose),
@ -446,7 +442,9 @@ impl Engine for Tendermint {
fn params(&self) -> &CommonParams { &self.params } fn params(&self) -> &CommonParams { &self.params }
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.registrar.hex()] } fn additional_params(&self) -> HashMap<String, String> {
hash_map!["registrar".to_owned() => self.params().registrar.hex()]
}
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins } fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
@ -471,11 +469,11 @@ impl Engine for Tendermint {
header.set_difficulty(new_difficulty); header.set_difficulty(new_difficulty);
header.set_gas_limit({ header.set_gas_limit({
let gas_limit = parent.gas_limit().clone(); let gas_limit = parent.gas_limit().clone();
let bound_divisor = self.gas_limit_bound_divisor; let bound_divisor = self.params().gas_limit_bound_divisor;
if gas_limit < gas_floor_target { if gas_limit < gas_floor_target {
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) cmp::min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
} else { } else {
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) cmp::max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into())
} }
}); });
} }
@ -545,7 +543,8 @@ impl Engine for Tendermint {
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{ fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{
let fields = block.fields_mut(); let fields = block.fields_mut();
// Bestow block reward // Bestow block reward
let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty) let reward = self.params().block_reward;
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
.map_err(::error::Error::from) .map_err(::error::Error::from)
.and_then(|_| fields.state.commit()); .and_then(|_| fields.state.commit());
// Commit state so that we can actually figure out the state root. // Commit state so that we can actually figure out the state root.
@ -583,7 +582,7 @@ impl Engine for Tendermint {
return Err(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }).into()); return Err(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }).into());
} }
let gas_limit_divisor = self.gas_limit_bound_divisor; let gas_limit_divisor = self.params().gas_limit_bound_divisor;
let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor;
let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor;
if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas {
@ -651,6 +650,7 @@ impl Engine for Tendermint {
let first = chain_head.number() == 0; let first = chain_head.number() == 0;
if let Some(change) = self.validators.is_epoch_end(first, chain_head) { if let Some(change) = self.validators.is_epoch_end(first, chain_head) {
let change = combine_proofs(chain_head.number(), &change, &[]);
return Some(change) return Some(change)
} else if let Some(pending) = transition_store(chain_head.hash()) { } else if let Some(pending) = transition_store(chain_head.hash()) {
let signal_number = chain_head.number(); let signal_number = chain_head.number();
@ -777,6 +777,7 @@ impl Engine for Tendermint {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::*; use util::*;
use block::*; use block::*;
@ -1055,7 +1056,7 @@ mod tests {
client.miner().import_own_transaction(client.as_ref(), transaction.into()).unwrap(); client.miner().import_own_transaction(client.as_ref(), transaction.into()).unwrap();
// Propose // Propose
let proposal = Some(client.miner().pending_block().unwrap().header.bare_hash()); let proposal = Some(client.miner().pending_block(0).unwrap().header.bare_hash());
// Propose timeout // Propose timeout
engine.step(); engine.step();

View File

@ -17,7 +17,6 @@
//! Tendermint specific parameters. //! Tendermint specific parameters.
use ethjson; use ethjson;
use util::{U256, Address};
use time::Duration; use time::Duration;
use super::super::validator_set::{ValidatorSet, new_validator_set}; use super::super::validator_set::{ValidatorSet, new_validator_set};
use super::super::transition::Timeouts; use super::super::transition::Timeouts;
@ -25,16 +24,10 @@ use super::Step;
/// `Tendermint` params. /// `Tendermint` params.
pub struct TendermintParams { pub struct TendermintParams {
/// Gas limit divisor.
pub gas_limit_bound_divisor: U256,
/// List of validators. /// List of validators.
pub validators: Box<ValidatorSet>, pub validators: Box<ValidatorSet>,
/// Timeout durations for different steps. /// Timeout durations for different steps.
pub timeouts: TendermintTimeouts, pub timeouts: TendermintTimeouts,
/// Block reward.
pub block_reward: U256,
/// Namereg contract address.
pub registrar: Address,
} }
/// Base timeout of each step in ms. /// Base timeout of each step in ms.
@ -81,7 +74,6 @@ impl From<ethjson::spec::TendermintParams> for TendermintParams {
fn from(p: ethjson::spec::TendermintParams) -> Self { fn from(p: ethjson::spec::TendermintParams) -> Self {
let dt = TendermintTimeouts::default(); let dt = TendermintTimeouts::default();
TendermintParams { TendermintParams {
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
validators: new_validator_set(p.validators), validators: new_validator_set(p.validators),
timeouts: TendermintTimeouts { timeouts: TendermintTimeouts {
propose: p.timeout_propose.map_or(dt.propose, to_duration), propose: p.timeout_propose.map_or(dt.propose, to_duration),
@ -89,8 +81,6 @@ impl From<ethjson::spec::TendermintParams> for TendermintParams {
precommit: p.timeout_precommit.map_or(dt.precommit, to_duration), precommit: p.timeout_precommit.map_or(dt.precommit, to_duration),
commit: p.timeout_commit.map_or(dt.commit, to_duration), commit: p.timeout_commit.map_or(dt.commit, to_duration),
}, },
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
registrar: p.registrar.map_or_else(Address::new, Into::into),
} }
} }
} }

View File

@ -126,6 +126,7 @@ impl ValidatorSet for ValidatorContract {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::*; use util::*;
use rlp::encode; use rlp::encode;
@ -142,11 +143,11 @@ mod tests {
#[test] #[test]
fn fetches_validators() { fn fetches_validators() {
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None);
let vc = Arc::new(ValidatorContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); let vc = Arc::new(ValidatorContract::new("0000000000000000000000000000000000000005".parse::<Address>().unwrap()));
vc.register_client(Arc::downgrade(&client) as _); vc.register_client(Arc::downgrade(&client) as _);
let last_hash = client.best_block_header().hash(); let last_hash = client.best_block_header().hash();
assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::<Address>().unwrap()));
assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::<Address>().unwrap()));
} }
#[test] #[test]
@ -155,7 +156,7 @@ mod tests {
let v1 = tap.insert_account("1".sha3().into(), "").unwrap(); let v1 = tap.insert_account("1".sha3().into(), "").unwrap();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone())); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone()));
client.engine().register_client(Arc::downgrade(&client) as _); client.engine().register_client(Arc::downgrade(&client) as _);
let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
// Make sure reporting can be done. // Make sure reporting can be done.
client.miner().set_gas_floor_target(1_000_000.into()); client.miner().set_gas_floor_target(1_000_000.into());

View File

@ -142,6 +142,8 @@ impl ValidatorSet for Multi {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use std::collections::BTreeMap;
use account_provider::AccountProvider; use account_provider::AccountProvider;
use client::BlockChainClient; use client::BlockChainClient;
use engines::EpochChange; use engines::EpochChange;

View File

@ -16,7 +16,7 @@
/// Validator set maintained in a contract, updated using `getValidators` method. /// Validator set maintained in a contract, updated using `getValidators` method.
use std::sync::Weak; use std::sync::{Weak, Arc};
use futures::Future; use futures::Future;
use native_contracts::ValidatorSet as Provider; use native_contracts::ValidatorSet as Provider;
@ -95,7 +95,7 @@ fn check_first_proof(engine: &Engine, provider: &Provider, old_header: Header, s
// TODO: match client contract_call_tx more cleanly without duplication. // TODO: match client contract_call_tx more cleanly without duplication.
const PROVIDED_GAS: u64 = 50_000_000; const PROVIDED_GAS: u64 = 50_000_000;
let env_info = ::evm::env_info::EnvInfo { let env_info = ::vm::EnvInfo {
number: old_header.number(), number: old_header.number(),
author: *old_header.author(), author: *old_header.author(),
difficulty: *old_header.difficulty(), difficulty: *old_header.difficulty(),
@ -454,6 +454,7 @@ impl ValidatorSet for ValidatorSafeContract {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use util::*; use util::*;
use types::ids::BlockId; use types::ids::BlockId;
@ -470,11 +471,11 @@ mod tests {
#[test] #[test]
fn fetches_validators() { fn fetches_validators() {
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let vc = Arc::new(ValidatorSafeContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); let vc = Arc::new(ValidatorSafeContract::new("0000000000000000000000000000000000000005".parse::<Address>().unwrap()));
vc.register_client(Arc::downgrade(&client) as _); vc.register_client(Arc::downgrade(&client) as _);
let last_hash = client.best_block_header().hash(); let last_hash = client.best_block_header().hash();
assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap())); assert!(vc.contains(&last_hash, &"7d577a597b2742b498cb5cf0c26cdcd726d39e6e".parse::<Address>().unwrap()));
assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap())); assert!(vc.contains(&last_hash, &"82a978b3f5962a5b0957d9ee9eef472ee55b42f1".parse::<Address>().unwrap()));
} }
#[test] #[test]
@ -483,10 +484,10 @@ mod tests {
let s0: Secret = "1".sha3().into(); let s0: Secret = "1".sha3().into();
let v0 = tap.insert_account(s0.clone(), "").unwrap(); let v0 = tap.insert_account(s0.clone(), "").unwrap();
let v1 = tap.insert_account("0".sha3().into(), "").unwrap(); let v1 = tap.insert_account("0".sha3().into(), "").unwrap();
let network_id = Spec::new_validator_safe_contract().network_id(); let chain_id = Spec::new_validator_safe_contract().chain_id();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap)); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
client.engine().register_client(Arc::downgrade(&client) as _); client.engine().register_client(Arc::downgrade(&client) as _);
let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
client.miner().set_engine_signer(v1, "".into()).unwrap(); client.miner().set_engine_signer(v1, "".into()).unwrap();
// Remove "1" validator. // Remove "1" validator.
@ -497,7 +498,7 @@ mod tests {
action: Action::Call(validator_contract), action: Action::Call(validator_contract),
value: 0.into(), value: 0.into(),
data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
}.sign(&s0, Some(network_id)); }.sign(&s0, Some(chain_id));
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
::client::EngineClient::update_sealing(&*client); ::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 1); assert_eq!(client.chain_info().best_block_number, 1);
@ -509,7 +510,7 @@ mod tests {
action: Action::Call(validator_contract), action: Action::Call(validator_contract),
value: 0.into(), value: 0.into(),
data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
}.sign(&s0, Some(network_id)); }.sign(&s0, Some(chain_id));
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
::client::EngineClient::update_sealing(&*client); ::client::EngineClient::update_sealing(&*client);
// The transaction is not yet included so still unable to seal. // The transaction is not yet included so still unable to seal.
@ -528,7 +529,7 @@ mod tests {
action: Action::Call(Address::default()), action: Action::Call(Address::default()),
value: 0.into(), value: 0.into(),
data: Vec::new(), data: Vec::new(),
}.sign(&s0, Some(network_id)); }.sign(&s0, Some(chain_id));
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
::client::EngineClient::update_sealing(&*client); ::client::EngineClient::update_sealing(&*client);
// Able to seal again. // Able to seal again.
@ -552,7 +553,7 @@ mod tests {
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let engine = client.engine().clone(); let engine = client.engine().clone();
let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
let last_hash = client.best_block_header().hash(); let last_hash = client.best_block_header().hash();
let mut new_header = Header::default(); let mut new_header = Header::default();

View File

@ -17,8 +17,9 @@
/// Used for Engine testing. /// Used for Engine testing.
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use util::{Arc, Bytes, H256, Address, HeapSizeOf}; use util::{Bytes, H256, Address, HeapSizeOf};
use engines::{Call, Engine}; use engines::{Call, Engine};
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};

View File

@ -17,6 +17,8 @@
//! Collects votes on hashes at each Message::Round. //! Collects votes on hashes at each Message::Round.
use std::fmt::Debug; use std::fmt::Debug;
use std::collections::{BTreeMap, HashSet, HashMap};
use std::hash::Hash;
use util::*; use util::*;
use rlp::{Encodable, RlpStream}; use rlp::{Encodable, RlpStream};

View File

@ -16,6 +16,7 @@
//! General error types for use in ethcore. //! General error types for use in ethcore.
use std::fmt;
use util::*; use util::*;
use io::*; use io::*;
use header::BlockNumber; use header::BlockNumber;
@ -77,8 +78,8 @@ pub enum TransactionError {
RecipientBanned, RecipientBanned,
/// Contract creation code is banned. /// Contract creation code is banned.
CodeBanned, CodeBanned,
/// Invalid network ID given. /// Invalid chain ID given.
InvalidNetworkId, InvalidChainId,
} }
impl fmt::Display for TransactionError { impl fmt::Display for TransactionError {
@ -102,7 +103,7 @@ impl fmt::Display for TransactionError {
SenderBanned => "Sender is temporarily banned.".into(), SenderBanned => "Sender is temporarily banned.".into(),
RecipientBanned => "Recipient is temporarily banned.".into(), RecipientBanned => "Recipient is temporarily banned.".into(),
CodeBanned => "Contract code is temporarily banned.".into(), CodeBanned => "Contract code is temporarily banned.".into(),
InvalidNetworkId => "Transaction of this network ID is not allowed on this chain.".into(), InvalidChainId => "Transaction of this chain ID is not allowed on this chain.".into(),
}; };
f.write_fmt(format_args!("Transaction error ({})", msg)) f.write_fmt(format_args!("Transaction error ({})", msg))

View File

@ -15,11 +15,14 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::path::Path; use std::path::Path;
use std::cmp;
use std::collections::{BTreeMap, HashMap};
use std::sync::Arc;
use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager};
use util::*; use util::*;
use block::*; use block::*;
use builtin::Builtin; use builtin::Builtin;
use evm::env_info::EnvInfo; use vm::EnvInfo;
use error::{BlockError, Error, TransactionError}; use error::{BlockError, Error, TransactionError};
use header::{Header, BlockNumber}; use header::{Header, BlockNumber};
use state::CleanupMode; use state::CleanupMode;
@ -29,20 +32,21 @@ use engines::{self, Engine};
use evm::Schedule; use evm::Schedule;
use ethjson; use ethjson;
use rlp::{self, UntrustedRlp}; use rlp::{self, UntrustedRlp};
use evm::env_info::LastHashes; use vm::LastHashes;
/// Parity tries to round block.gas_limit to multiple of this constant /// Parity tries to round block.gas_limit to multiple of this constant
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
/// Number of blocks in an ethash snapshot. /// Number of blocks in an ethash snapshot.
// make dependent on difficulty incrment divisor? // make dependent on difficulty incrment divisor?
const SNAPSHOT_BLOCKS: u64 = 30000; const SNAPSHOT_BLOCKS: u64 = 5000;
/// Maximum number of blocks allowed in an ethash snapshot.
const MAX_SNAPSHOT_BLOCKS: u64 = 30000;
/// Ethash params. /// Ethash params.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct EthashParams { pub struct EthashParams {
/// Gas limit divisor.
pub gas_limit_bound_divisor: U256,
/// Minimum difficulty. /// Minimum difficulty.
pub minimum_difficulty: U256, pub minimum_difficulty: U256,
/// Difficulty bound divisor. /// Difficulty bound divisor.
@ -53,10 +57,6 @@ pub struct EthashParams {
pub metropolis_difficulty_increment_divisor: u64, pub metropolis_difficulty_increment_divisor: u64,
/// Block duration. /// Block duration.
pub duration_limit: u64, pub duration_limit: u64,
/// Block reward.
pub block_reward: U256,
/// Namereg contract address.
pub registrar: Address,
/// Homestead transition block number. /// Homestead transition block number.
pub homestead_transition: u64, pub homestead_transition: u64,
/// DAO hard-fork transition block (X). /// DAO hard-fork transition block (X).
@ -75,8 +75,6 @@ pub struct EthashParams {
pub eip100b_transition: u64, pub eip100b_transition: u64,
/// Number of first block where EIP-150 rules begin. /// Number of first block where EIP-150 rules begin.
pub eip150_transition: u64, pub eip150_transition: u64,
/// Number of first block where EIP-155 rules begin.
pub eip155_transition: u64,
/// Number of first block where EIP-160 rules begin. /// Number of first block where EIP-160 rules begin.
pub eip160_transition: u64, pub eip160_transition: u64,
/// Number of first block where EIP-161.abc begin. /// Number of first block where EIP-161.abc begin.
@ -104,14 +102,11 @@ pub struct EthashParams {
impl From<ethjson::spec::EthashParams> for EthashParams { impl From<ethjson::spec::EthashParams> for EthashParams {
fn from(p: ethjson::spec::EthashParams) -> Self { fn from(p: ethjson::spec::EthashParams) -> Self {
EthashParams { EthashParams {
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
minimum_difficulty: p.minimum_difficulty.into(), minimum_difficulty: p.minimum_difficulty.into(),
difficulty_bound_divisor: p.difficulty_bound_divisor.into(), difficulty_bound_divisor: p.difficulty_bound_divisor.into(),
difficulty_increment_divisor: p.difficulty_increment_divisor.map_or(10, Into::into), difficulty_increment_divisor: p.difficulty_increment_divisor.map_or(10, Into::into),
metropolis_difficulty_increment_divisor: p.metropolis_difficulty_increment_divisor.map_or(9, Into::into), metropolis_difficulty_increment_divisor: p.metropolis_difficulty_increment_divisor.map_or(9, Into::into),
duration_limit: p.duration_limit.map_or(0, Into::into), duration_limit: p.duration_limit.map_or(0, Into::into),
block_reward: p.block_reward.into(),
registrar: p.registrar.map_or_else(Address::new, Into::into),
homestead_transition: p.homestead_transition.map_or(0, Into::into), homestead_transition: p.homestead_transition.map_or(0, Into::into),
dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into), dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into),
dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::new, Into::into), dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::new, Into::into),
@ -121,7 +116,6 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
bomb_defuse_transition: p.bomb_defuse_transition.map_or(u64::max_value(), Into::into), bomb_defuse_transition: p.bomb_defuse_transition.map_or(u64::max_value(), Into::into),
eip100b_transition: p.eip100b_transition.map_or(u64::max_value(), Into::into), eip100b_transition: p.eip100b_transition.map_or(u64::max_value(), Into::into),
eip150_transition: p.eip150_transition.map_or(0, Into::into), eip150_transition: p.eip150_transition.map_or(0, Into::into),
eip155_transition: p.eip155_transition.map_or(0, Into::into),
eip160_transition: p.eip160_transition.map_or(0, Into::into), eip160_transition: p.eip160_transition.map_or(0, Into::into),
eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into), eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into),
eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into), eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into),
@ -185,7 +179,7 @@ impl Engine for Arc<Ethash> {
fn seal_fields(&self) -> usize { 2 } fn seal_fields(&self) -> usize { 2 }
fn params(&self) -> &CommonParams { &self.params } fn params(&self) -> &CommonParams { &self.params }
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.ethash_params.registrar.hex()] } fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.params().registrar.hex()] }
fn builtins(&self) -> &BTreeMap<Address, Builtin> { fn builtins(&self) -> &BTreeMap<Address, Builtin> {
&self.builtins &self.builtins
@ -215,8 +209,8 @@ impl Engine for Arc<Ethash> {
} }
} }
fn signing_network_id(&self, env_info: &EnvInfo) -> Option<u64> { fn signing_chain_id(&self, env_info: &EnvInfo) -> Option<u64> {
if env_info.number >= self.ethash_params.eip155_transition { if env_info.number >= self.params().eip155_transition {
Some(self.params().chain_id) Some(self.params().chain_id)
} else { } else {
None None
@ -231,19 +225,19 @@ impl Engine for Arc<Ethash> {
} }
let gas_limit = { let gas_limit = {
let gas_limit = parent.gas_limit().clone(); let gas_limit = parent.gas_limit().clone();
let bound_divisor = self.ethash_params.gas_limit_bound_divisor; let bound_divisor = self.params().gas_limit_bound_divisor;
let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into(); let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into();
let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into(); let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into();
let gas_limit = if gas_limit < gas_floor_target { let gas_limit = if gas_limit < gas_floor_target {
let gas_limit = min(gas_floor_target, upper_limit); let gas_limit = cmp::min(gas_floor_target, upper_limit);
round_block_gas_limit(gas_limit, lower_limit, upper_limit) round_block_gas_limit(gas_limit, lower_limit, upper_limit)
} else if gas_limit > gas_ceil_target { } else if gas_limit > gas_ceil_target {
let gas_limit = max(gas_ceil_target, lower_limit); let gas_limit = cmp::max(gas_ceil_target, lower_limit);
round_block_gas_limit(gas_limit, lower_limit, upper_limit) round_block_gas_limit(gas_limit, lower_limit, upper_limit)
} else { } else {
let total_lower_limit = max(lower_limit, gas_floor_target); let total_lower_limit = cmp::max(lower_limit, gas_floor_target);
let total_upper_limit = min(upper_limit, gas_ceil_target); let total_upper_limit = cmp::min(upper_limit, gas_ceil_target);
let gas_limit = max(gas_floor_target, min(total_upper_limit, let gas_limit = cmp::max(gas_floor_target, cmp::min(total_upper_limit,
lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor)); lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor));
round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit) round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit)
}; };
@ -284,7 +278,7 @@ impl Engine for Arc<Ethash> {
/// Apply the block reward on finalisation of the block. /// Apply the block reward on finalisation of the block.
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
let reward = self.ethash_params.block_reward; let reward = self.params().block_reward;
let fields = block.fields_mut(); let fields = block.fields_mut();
let eras_rounds = self.ethash_params.ecip1017_era_rounds; let eras_rounds = self.ethash_params.ecip1017_era_rounds;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number()); let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number());
@ -319,7 +313,7 @@ impl Engine for Arc<Ethash> {
Ok(()) Ok(())
} }
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
// check the seal fields. // check the seal fields.
if header.seal().len() != self.seal_fields() { if header.seal().len() != self.seal_fields() {
return Err(From::from(BlockError::InvalidSealArity( return Err(From::from(BlockError::InvalidSealArity(
@ -357,7 +351,7 @@ impl Engine for Arc<Ethash> {
Ok(()) Ok(())
} }
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
if header.seal().len() != self.seal_fields() { if header.seal().len() != self.seal_fields() {
return Err(From::from(BlockError::InvalidSealArity( return Err(From::from(BlockError::InvalidSealArity(
Mismatch { expected: self.seal_fields(), found: header.seal().len() } Mismatch { expected: self.seal_fields(), found: header.seal().len() }
@ -376,7 +370,7 @@ impl Engine for Arc<Ethash> {
Ok(()) Ok(())
} }
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
// we should not calculate difficulty for genesis blocks // we should not calculate difficulty for genesis blocks
if header.number() == 0 { if header.number() == 0 {
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
@ -387,7 +381,7 @@ impl Engine for Arc<Ethash> {
if header.difficulty() != &expected_difficulty { if header.difficulty() != &expected_difficulty {
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() }))) return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() })))
} }
let gas_limit_divisor = self.ethash_params.gas_limit_bound_divisor; let gas_limit_divisor = self.params().gas_limit_bound_divisor;
let parent_gas_limit = *parent.gas_limit(); let parent_gas_limit = *parent.gas_limit();
let min_gas = parent_gas_limit - parent_gas_limit / gas_limit_divisor; let min_gas = parent_gas_limit - parent_gas_limit / gas_limit_divisor;
let max_gas = parent_gas_limit + parent_gas_limit / gas_limit_divisor; let max_gas = parent_gas_limit + parent_gas_limit / gas_limit_divisor;
@ -400,14 +394,14 @@ impl Engine for Arc<Ethash> {
Ok(()) Ok(())
} }
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> {
if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price { if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price {
return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into()); return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into());
} }
let check_low_s = header.number() >= self.ethash_params.homestead_transition; let check_low_s = header.number() >= self.ethash_params.homestead_transition;
let network_id = if header.number() >= self.ethash_params.eip155_transition { Some(self.params().chain_id) } else { None }; let chain_id = if header.number() >= self.params().eip155_transition { Some(self.params().chain_id) } else { None };
t.verify_basic(check_low_s, network_id, false)?; t.verify_basic(check_low_s, chain_id, false)?;
Ok(()) Ok(())
} }
@ -416,7 +410,7 @@ impl Engine for Arc<Ethash> {
} }
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> { fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
Some(Box::new(::snapshot::PowSnapshot(SNAPSHOT_BLOCKS))) Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS)))
} }
} }
@ -493,28 +487,28 @@ impl Ethash {
if diff_inc <= threshold { if diff_inc <= threshold {
*parent.difficulty() + *parent.difficulty() / difficulty_bound_divisor * (threshold - diff_inc).into() *parent.difficulty() + *parent.difficulty() / difficulty_bound_divisor * (threshold - diff_inc).into()
} else { } else {
let multiplier = min(diff_inc - threshold, 99).into(); let multiplier = cmp::min(diff_inc - threshold, 99).into();
parent.difficulty().saturating_sub( parent.difficulty().saturating_sub(
*parent.difficulty() / difficulty_bound_divisor * multiplier *parent.difficulty() / difficulty_bound_divisor * multiplier
) )
} }
}; };
target = max(min_difficulty, target); target = cmp::max(min_difficulty, target);
if header.number() < self.ethash_params.bomb_defuse_transition { if header.number() < self.ethash_params.bomb_defuse_transition {
if header.number() < self.ethash_params.ecip1010_pause_transition { if header.number() < self.ethash_params.ecip1010_pause_transition {
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
if period > 1 { if period > 1 {
target = max(min_difficulty, target + (U256::from(1) << (period - 2))); target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2)));
} }
} }
else if header.number() < self.ethash_params.ecip1010_continue_transition { else if header.number() < self.ethash_params.ecip1010_continue_transition {
let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize; let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize;
target = max(min_difficulty, target + (U256::from(1) << fixed_difficulty)); target = cmp::max(min_difficulty, target + (U256::from(1) << fixed_difficulty));
} }
else { else {
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize; let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize; let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize;
target = max(min_difficulty, target + (U256::from(1) << (period - delay - 2))); target = cmp::max(min_difficulty, target + (U256::from(1) << (period - delay - 2)));
} }
} }
target target
@ -559,6 +553,9 @@ impl Header {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr;
use std::collections::BTreeMap;
use std::sync::Arc;
use util::*; use util::*;
use block::*; use block::*;
use tests::helpers::*; use tests::helpers::*;
@ -809,36 +806,32 @@ mod tests {
#[test] #[test]
fn has_valid_ecip1017_eras_block_reward() { fn has_valid_ecip1017_eras_block_reward() {
let ethparams = EthashParams { let eras_rounds = 5000000;
// see ethcore/res/ethereum/classic.json
ecip1017_era_rounds: 5000000, let start_reward: U256 = "4563918244F40000".parse().unwrap();
block_reward: U256::from_str("4563918244F40000").unwrap(),
..get_default_ethash_params()
};
let eras_rounds = ethparams.ecip1017_era_rounds;
let reward = ethparams.block_reward;
let block_number = 0; let block_number = 0;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
assert_eq!(0, eras); assert_eq!(0, eras);
assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward);
let reward = ethparams.block_reward;
let block_number = 5000000; let block_number = 5000000;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
assert_eq!(0, eras); assert_eq!(0, eras);
assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward); assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward);
let reward = ethparams.block_reward;
let block_number = 10000000; let block_number = 10000000;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
assert_eq!(1, eras); assert_eq!(1, eras);
assert_eq!(U256::from_str("3782DACE9D900000").unwrap(), reward); assert_eq!(U256::from_str("3782DACE9D900000").unwrap(), reward);
let reward = ethparams.block_reward;
let block_number = 20000000; let block_number = 20000000;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
assert_eq!(3, eras); assert_eq!(3, eras);
assert_eq!(U256::from_str("2386F26FC1000000").unwrap(), reward); assert_eq!(U256::from_str("2386F26FC1000000").unwrap(), reward);
let reward = ethparams.block_reward;
let block_number = 80000000; let block_number = 80000000;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number); let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
assert_eq!(15, eras); assert_eq!(15, eras);
assert_eq!(U256::from_str("271000000000000").unwrap(), reward); assert_eq!(U256::from_str("271000000000000").unwrap(), reward);
} }

View File

@ -134,23 +134,4 @@ mod tests {
let _ = frontier.engine; let _ = frontier.engine;
} }
#[test]
fn all_spec_files_valid() {
let tmp = ::std::env::temp_dir();
new_olympic(&tmp);
new_foundation(&tmp);
new_classic(&tmp);
new_expanse(&tmp);
new_kovan(&tmp);
new_ropsten(&tmp);
new_morden(&tmp);
new_frontier_test();
new_homestead_test();
new_eip150_test();
new_eip161_test();
new_transition_test();
new_mainnet_like();
new_metropolis_test();
}
} }

View File

@ -17,7 +17,7 @@
//! Transaction execution format module. //! Transaction execution format module.
use util::{Bytes, U256, Address, U512, trie}; use util::{Bytes, U256, Address, U512, trie};
use evm; use vm;
use trace::{VMTrace, FlatTrace}; use trace::{VMTrace, FlatTrace};
use log_entry::LogEntry; use log_entry::LogEntry;
use state_diff::StateDiff; use state_diff::StateDiff;
@ -28,7 +28,7 @@ use std::fmt;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Executed { pub struct Executed {
/// True if the outer call/create resulted in an exceptional exit. /// True if the outer call/create resulted in an exceptional exit.
pub exception: Option<evm::Error>, pub exception: Option<vm::Error>,
/// Gas paid up front for execution of transaction. /// Gas paid up front for execution of transaction.
pub gas: U256, pub gas: U256,

View File

@ -15,14 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Transaction Execution environment. //! Transaction Execution environment.
use std::cmp;
use std::sync::Arc;
use util::*; use util::*;
use evm::action_params::{ActionParams, ActionValue};
use state::{Backend as StateBackend, State, Substate, CleanupMode}; use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine; use engines::Engine;
use evm::CallType; use vm::EnvInfo;
use evm::env_info::EnvInfo;
use error::ExecutionError; use error::ExecutionError;
use evm::{self, wasm, Factory, Ext, Finalize, CreateContractAddress, FinalizationResult, ReturnData, CleanDustMode}; use evm::{CallType, Factory, Finalize, FinalizationResult};
use vm::{self, Ext, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, ActionValue};
use wasm;
use externalities::*; use externalities::*;
use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer}; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer};
use transaction::{Action, SignedTransaction}; use transaction::{Action, SignedTransaction};
@ -74,8 +76,8 @@ pub struct TransactOptions {
pub check_nonce: bool, pub check_nonce: bool,
} }
pub fn executor<E>(engine: &E, vm_factory: &Factory, params: &ActionParams) pub fn executor<E>(engine: &E, vm_factory: &Factory, params: &ActionParams)
-> Box<evm::Evm> where E: Engine + ?Sized -> Box<vm::Vm> where E: Engine + ?Sized
{ {
if engine.supports_wasm() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) { if engine.supports_wasm() && params.code.as_ref().map_or(false, |code| code.len() > 4 && &code[0..4] == WASM_MAGIC_NUMBER) {
Box::new( Box::new(
@ -155,7 +157,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) -> Result<Executed, ExecutionError> { pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) -> Result<Executed, ExecutionError> {
let sender = t.sender(); let sender = t.sender();
let balance = self.state.balance(&sender)?; let balance = self.state.balance(&sender)?;
let needed_balance = t.value + t.gas * t.gas_price; let needed_balance = t.value.saturating_add(t.gas.saturating_mul(t.gas_price));
if balance < needed_balance { if balance < needed_balance {
// give the sender a sufficient balance // give the sender a sufficient balance
self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?; self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?;
@ -269,7 +271,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
output_policy: OutputPolicy, output_policy: OutputPolicy,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V vm_tracer: &mut V
) -> evm::Result<FinalizationResult> where T: Tracer, V: VMTracer { ) -> vm::Result<FinalizationResult> where T: Tracer, V: VMTracer {
let depth_threshold = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get() / STACK_SIZE_PER_DEPTH); let depth_threshold = ::io::LOCAL_STACK_SIZE.with(|sz| sz.get() / STACK_SIZE_PER_DEPTH);
let static_call = params.call_type == CallType::StaticCall; let static_call = params.call_type == CallType::StaticCall;
@ -299,7 +301,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
/// Calls contract function with given contract params. /// Calls contract function with given contract params.
/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
/// Modifies the substate and the output. /// Modifies the substate and the output.
/// Returns either gas_left or `evm::Error`. /// Returns either gas_left or `vm::Error`.
pub fn call<T, V>( pub fn call<T, V>(
&mut self, &mut self,
params: ActionParams, params: ActionParams,
@ -307,14 +309,14 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
mut output: BytesRef, mut output: BytesRef,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V vm_tracer: &mut V
) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { ) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer {
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info);
if (params.call_type == CallType::StaticCall || if (params.call_type == CallType::StaticCall ||
((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) && ((params.call_type == CallType::Call || params.call_type == CallType::DelegateCall) &&
self.static_flag)) self.static_flag))
&& params.value.value() > 0.into() { && params.value.value() > 0.into() {
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
// backup used in case of running out of gas // backup used in case of running out of gas
@ -344,7 +346,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
if cost <= params.gas { if cost <= params.gas {
if let Err(e) = builtin.execute(data, &mut output) { if let Err(e) = builtin.execute(data, &mut output) {
self.state.revert_to_checkpoint(); self.state.revert_to_checkpoint();
let evm_err: evm::evm::Error = e.into(); let evm_err: vm::Error = e.into();
tracer.trace_failed_call(trace_info, vec![], evm_err.clone().into()); tracer.trace_failed_call(trace_info, vec![], evm_err.clone().into());
Err(evm_err) Err(evm_err)
} else { } else {
@ -371,9 +373,9 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
// just drain the whole gas // just drain the whole gas
self.state.revert_to_checkpoint(); self.state.revert_to_checkpoint();
tracer.trace_failed_call(trace_info, vec![], evm::Error::OutOfGas.into()); tracer.trace_failed_call(trace_info, vec![], vm::Error::OutOfGas.into());
Err(evm::Error::OutOfGas) Err(vm::Error::OutOfGas)
} }
} else { } else {
let trace_info = tracer.prepare_trace_call(&params); let trace_info = tracer.prepare_trace_call(&params);
@ -432,17 +434,17 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
substate: &mut Substate, substate: &mut Substate,
tracer: &mut T, tracer: &mut T,
vm_tracer: &mut V, vm_tracer: &mut V,
) -> evm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer { ) -> vm::Result<(U256, ReturnData)> where T: Tracer, V: VMTracer {
let scheme = self.engine.create_address_scheme(self.info.number); let scheme = self.engine.create_address_scheme(self.info.number);
if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(&params.address)? { if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(&params.address)? {
return Err(evm::Error::OutOfGas); return Err(vm::Error::OutOfGas);
} }
if params.call_type == CallType::StaticCall || self.static_flag { if params.call_type == CallType::StaticCall || self.static_flag {
let trace_info = tracer.prepare_trace_create(&params); let trace_info = tracer.prepare_trace_create(&params);
tracer.trace_failed_create(trace_info, vec![], evm::Error::MutableCallInStaticContext.into()); tracer.trace_failed_create(trace_info, vec![], vm::Error::MutableCallInStaticContext.into());
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
// backup used in case of running out of gas // backup used in case of running out of gas
@ -496,7 +498,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
&mut self, &mut self,
t: &SignedTransaction, t: &SignedTransaction,
mut substate: Substate, mut substate: Substate,
result: evm::Result<(U256, ReturnData)>, result: vm::Result<(U256, ReturnData)>,
output: Bytes, output: Bytes,
trace: Vec<FlatTrace>, trace: Vec<FlatTrace>,
vm_trace: Option<VMTrace> vm_trace: Option<VMTrace>
@ -538,7 +540,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?; self.state.kill_garbage(&substate.touched, schedule.kill_empty, &min_balance, schedule.kill_dust == CleanDustMode::WithCodeAndStorage)?;
match result { match result {
Err(evm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)), Err(vm::Error::Internal(msg)) => Err(ExecutionError::Internal(msg)),
Err(exception) => { Err(exception) => {
Ok(Executed { Ok(Executed {
exception: Some(exception), exception: Some(exception),
@ -572,20 +574,20 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
} }
} }
fn enact_result(&mut self, result: &evm::Result<FinalizationResult>, substate: &mut Substate, un_substate: Substate) { fn enact_result(&mut self, result: &vm::Result<FinalizationResult>, substate: &mut Substate, un_substate: Substate) {
match *result { match *result {
Err(evm::Error::OutOfGas) Err(vm::Error::OutOfGas)
| Err(evm::Error::BadJumpDestination {..}) | Err(vm::Error::BadJumpDestination {..})
| Err(evm::Error::BadInstruction {.. }) | Err(vm::Error::BadInstruction {.. })
| Err(evm::Error::StackUnderflow {..}) | Err(vm::Error::StackUnderflow {..})
| Err(evm::Error::BuiltIn {..}) | Err(vm::Error::BuiltIn {..})
| Err(evm::Error::Wasm {..}) | Err(vm::Error::Wasm {..})
| Err(evm::Error::OutOfStack {..}) | Err(vm::Error::OutOfStack {..})
| Err(evm::Error::MutableCallInStaticContext) | Err(vm::Error::MutableCallInStaticContext)
| Ok(FinalizationResult { apply_state: false, .. }) => { | Ok(FinalizationResult { apply_state: false, .. }) => {
self.state.revert_to_checkpoint(); self.state.revert_to_checkpoint();
}, },
Ok(_) | Err(evm::Error::Internal(_)) => { Ok(_) | Err(vm::Error::Internal(_)) => {
self.state.discard_checkpoint(); self.state.discard_checkpoint();
substate.accrue(un_substate); substate.accrue(un_substate);
} }
@ -597,14 +599,14 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
#[allow(dead_code)] #[allow(dead_code)]
mod tests { mod tests {
use std::sync::Arc; use std::sync::Arc;
use std::str::FromStr;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use ethkey::{Generator, Random}; use ethkey::{Generator, Random};
use super::*; use super::*;
use util::{H256, U256, U512, Address, FromStr}; use util::{H256, U256, U512, Address};
use util::bytes::BytesRef; use util::bytes::BytesRef;
use evm::action_params::{ActionParams, ActionValue}; use vm::{ActionParams, ActionValue, CallType, EnvInfo, CreateContractAddress};
use evm::env_info::EnvInfo; use evm::{Factory, VMType};
use evm::{Factory, VMType, CreateContractAddress};
use error::ExecutionError; use error::ExecutionError;
use state::{Substate, CleanupMode}; use state::{Substate, CleanupMode};
use tests::helpers::*; use tests::helpers::*;
@ -613,8 +615,6 @@ mod tests {
use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer}; use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer};
use transaction::{Action, Transaction}; use transaction::{Action, Transaction};
use evm::CallType;
#[test] #[test]
fn test_contract_address() { fn test_contract_address() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();

View File

@ -15,14 +15,17 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Transaction Execution environment. //! Transaction Execution environment.
use std::cmp;
use std::sync::Arc;
use util::*; use util::*;
use evm::action_params::{ActionParams, ActionValue};
use state::{Backend as StateBackend, State, Substate, CleanupMode}; use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine; use engines::Engine;
use evm::env_info::EnvInfo;
use executive::*; use executive::*;
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, CreateContractAddress, ReturnData}; use vm::{
use evm::CallType; self, ActionParams, ActionValue, EnvInfo, CallType, Schedule,
Ext, ContractCreateResult, MessageCallResult, CreateContractAddress,
ReturnData
};
use transaction::UNSIGNED_SENDER; use transaction::UNSIGNED_SENDER;
use trace::{Tracer, VMTracer}; use trace::{Tracer, VMTracer};
@ -109,31 +112,31 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Externalities<'a, T, V, B, E>
impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized
{ {
fn storage_at(&self, key: &H256) -> evm::Result<H256> { fn storage_at(&self, key: &H256) -> vm::Result<H256> {
self.state.storage_at(&self.origin_info.address, key).map_err(Into::into) self.state.storage_at(&self.origin_info.address, key).map_err(Into::into)
} }
fn set_storage(&mut self, key: H256, value: H256) -> evm::Result<()> { fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> {
if self.static_flag { if self.static_flag {
Err(evm::Error::MutableCallInStaticContext) Err(vm::Error::MutableCallInStaticContext)
} else { } else {
self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into) self.state.set_storage(&self.origin_info.address, key, value).map_err(Into::into)
} }
} }
fn exists(&self, address: &Address) -> evm::Result<bool> { fn exists(&self, address: &Address) -> vm::Result<bool> {
self.state.exists(address).map_err(Into::into) self.state.exists(address).map_err(Into::into)
} }
fn exists_and_not_null(&self, address: &Address) -> evm::Result<bool> { fn exists_and_not_null(&self, address: &Address) -> vm::Result<bool> {
self.state.exists_and_not_null(address).map_err(Into::into) self.state.exists_and_not_null(address).map_err(Into::into)
} }
fn origin_balance(&self) -> evm::Result<U256> { fn origin_balance(&self) -> vm::Result<U256> {
self.balance(&self.origin_info.address).map_err(Into::into) self.balance(&self.origin_info.address).map_err(Into::into)
} }
fn balance(&self, address: &Address) -> evm::Result<U256> { fn balance(&self, address: &Address) -> vm::Result<U256> {
self.state.balance(address).map_err(Into::into) self.state.balance(address).map_err(Into::into)
} }
@ -274,16 +277,16 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
} }
} }
fn extcode(&self, address: &Address) -> evm::Result<Arc<Bytes>> { fn extcode(&self, address: &Address) -> vm::Result<Arc<Bytes>> {
Ok(self.state.code(address)?.unwrap_or_else(|| Arc::new(vec![]))) Ok(self.state.code(address)?.unwrap_or_else(|| Arc::new(vec![])))
} }
fn extcodesize(&self, address: &Address) -> evm::Result<usize> { fn extcodesize(&self, address: &Address) -> vm::Result<usize> {
Ok(self.state.code_size(address)?.unwrap_or(0)) Ok(self.state.code_size(address)?.unwrap_or(0))
} }
#[cfg_attr(feature="dev", allow(match_ref_pats))] #[cfg_attr(feature="dev", allow(match_ref_pats))]
fn ret(mut self, gas: &U256, data: &ReturnData) -> evm::Result<U256> fn ret(mut self, gas: &U256, data: &ReturnData) -> vm::Result<U256>
where Self: Sized { where Self: Sized {
let handle_copy = |to: &mut Option<&mut Bytes>| { let handle_copy = |to: &mut Option<&mut Bytes>| {
to.as_mut().map(|b| **b = data.to_vec()); to.as_mut().map(|b| **b = data.to_vec());
@ -307,7 +310,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas);
if return_cost > *gas || data.len() > self.schedule.create_data_limit { if return_cost > *gas || data.len() > self.schedule.create_data_limit {
return match self.schedule.exceptional_failed_code_deposit { return match self.schedule.exceptional_failed_code_deposit {
true => Err(evm::Error::OutOfGas), true => Err(vm::Error::OutOfGas),
false => Ok(*gas) false => Ok(*gas)
} }
} }
@ -320,11 +323,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
} }
} }
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> evm::Result<()> { fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> {
use log_entry::LogEntry; use log_entry::LogEntry;
if self.static_flag { if self.static_flag {
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
let address = self.origin_info.address.clone(); let address = self.origin_info.address.clone();
@ -337,9 +340,9 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
Ok(()) Ok(())
} }
fn suicide(&mut self, refund_address: &Address) -> evm::Result<()> { fn suicide(&mut self, refund_address: &Address) -> vm::Result<()> {
if self.static_flag { if self.static_flag {
return Err(evm::Error::MutableCallInStaticContext); return Err(vm::Error::MutableCallInStaticContext);
} }
let address = self.origin_info.address.clone(); let address = self.origin_info.address.clone();
@ -396,13 +399,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
mod tests { mod tests {
use util::*; use util::*;
use engines::Engine; use engines::Engine;
use evm::env_info::EnvInfo; use evm::{EnvInfo, Ext, CallType};
use evm::Ext;
use state::{State, Substate}; use state::{State, Substate};
use tests::helpers::*; use tests::helpers::*;
use super::*; use super::*;
use trace::{NoopTracer, NoopVMTracer}; use trace::{NoopTracer, NoopVMTracer};
use evm::CallType;
fn get_test_origin() -> OriginInfo { fn get_test_origin() -> OriginInfo {
OriginInfo { OriginInfo {
@ -470,7 +471,7 @@ mod tests {
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::<U256>().unwrap());
assert_eq!(hash, H256::zero()); assert_eq!(hash, H256::zero());
} }
@ -494,7 +495,7 @@ mod tests {
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false); let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::<U256>().unwrap());
assert_eq!(test_hash, hash); assert_eq!(test_hash, hash);
} }
@ -513,10 +514,10 @@ mod tests {
// this should panic because we have no balance on any account // this should panic because we have no balance on any account
ext.call( ext.call(
&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap(), &"0000000000000000000000000000000000000000000000000000000000120000".parse::<U256>().unwrap(),
&Address::new(), &Address::new(),
&Address::new(), &Address::new(),
Some(U256::from_str("0000000000000000000000000000000000000000000000000000000000150000").unwrap()), Some("0000000000000000000000000000000000000000000000000000000000150000".parse::<U256>().unwrap()),
&[], &[],
&Address::new(), &Address::new(),
&mut output, &mut output,

View File

@ -16,13 +16,13 @@
//! Block header. //! Block header.
use std::cmp;
use std::cell::RefCell;
use util::*; use util::*;
use basic_types::{LogBloom, ZERO_LOGBLOOM}; use basic_types::{LogBloom, ZERO_LOGBLOOM};
use time::get_time; use time::get_time;
use rlp::*; use rlp::*;
use std::cell::RefCell;
pub use basic_types::Seal; pub use basic_types::Seal;
pub use types::BlockNumber; pub use types::BlockNumber;
@ -175,7 +175,7 @@ impl Header {
/// Set the timestamp field of the header. /// Set the timestamp field of the header.
pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); } pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); }
/// Set the timestamp field of the header to the current time. /// Set the timestamp field of the header to the current time.
pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); } pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = cmp::max(get_time().sec as u64, but_later_than + 1); self.note_dirty(); }
/// Set the number field of the header. /// Set the number field of the header.
pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); } pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); }
/// Set the author field of the header. /// Set the author field of the header.
@ -275,7 +275,7 @@ impl Decodable for Header {
number: r.val_at(8)?, number: r.val_at(8)?,
gas_limit: r.val_at(9)?, gas_limit: r.val_at(9)?,
gas_used: r.val_at(10)?, gas_used: r.val_at(10)?,
timestamp: min(r.val_at::<U256>(11)?, u64::max_value().into()).as_u64(), timestamp: cmp::min(r.val_at::<U256>(11)?, u64::max_value().into()).as_u64(),
extra_data: r.val_at(12)?, extra_data: r.val_at(12)?,
seal: vec![], seal: vec![],
hash: RefCell::new(Some(r.as_raw().sha3())), hash: RefCell::new(Some(r.as_raw().sha3())),

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