Compare commits

...

9 Commits

Author SHA1 Message Date
André Silva
db3a98903b [stable] Backport constantinople changes (#9723)
* ethash: implement EIP-1234 (#9187)

* Implement EIP-1052 (EXTCODEHASH) and fix several issues in state account cache (#9234)

* Implement EIP-1052 and fix several issues related to account cache

* Fix jsontests

* Merge two matches together

* Avoid making unnecessary Arc<Vec>

* Address grumbles

* Comply EIP-86 with the new definition (#9140)

* Comply EIP-86 with the new CREATE2 opcode

* Fix rpc compile

* Fix interpreter CREATE/CREATE2 stack pop difference

* Add unreachable! to fix compile

* Fix instruction_info

* Fix gas check due to new stack item

* Add new tests in executive

* Fix have_create2 comment

* Remove all unused references of eip86_transition and block_number

* Implement KIP4: create2 for wasm (#9277)

* Basic implementation for kip4

* Add KIP-4 config flags

* typo: docs fix

* Fix args offset

* Add tests for create2

* tests: evm

* Update wasm-tests and fix all gas costs

* Update wasm-tests

* Update wasm-tests and fix gas costs

* `gasleft` extern implemented for WASM runtime (kip-6) (#9357)

* Wasm gasleft extern added

* wasm_gasleft_activation_transition -> kip4_transition

* use kip-6 switch

* gasleft_panic -> gasleft_fail rename

* call_msg_gasleft test added and gas_left agustments because this https://github.com/paritytech/wasm-tests/pull/52

* change .. to _

* fix comment for the have_gasleft param

* update tests (0edbf860ff)

* Add EIP-1014 transition config flag (#9268)

* Add EIP-1014 transition config flag

* Remove EIP-86 configs

* Change CREATE2 opcode index to 0xf5

* Move salt to the last item in the stack

* Change sendersaltandaddress scheme to comply with current EIP-1014

* Fix json configs

* Fix create2 test

* Fix deprecated comments

* EIP 1283: Net gas metering for SSTORE without dirty maps (#9319)

* Implement last_checkpoint_storage_at

* Add reverted_storage_at for externalities

* sstore_clears_count -> sstore_clears_refund

* Implement eip1283 for evm

* Add eip1283Transition params

* evm: fix tests

* jsontests: fix test

* Return checkpoint index when creating

* Comply with spec Version II

* Fix docs

* Fix jsontests feature compile

* Address grumbles

* Fix no-checkpoint-entry case

* Remove unnecessary expect

* Add test for State::checkpoint_storage_at

* Add executive level test for eip1283

* Hard-code transaction_checkpoint_index to 0

* Fix jsontests

* Add tests for checkpoint discard/revert

* Require checkpoint to be empty for kill_account and commit

* Get code coverage

* Use saturating_add/saturating_sub

* Fix issues in insert_cache

* Clear the state again

* Fix original_storage_at

* Early return for empty RLP trie storage

* Update comments

* Fix borrow_mut issue

* Simplify checkpoint_storage_at if branches

* Better commenting for gas handling code

* Address naming grumbles

* More tests

* Fix an issue in overwrite_with

* Add another test

* Fix comment

* Remove unnecessary bracket

* Move orig to inner if

* Remove test coverage for this PR

* Add tests for executive original value

* Add warn! for an unreachable cause

* Update state tests execution model (#9440)

* Update & fix JSON state tests.

* Update tests to be able to run ethtest at
021fe3d410773024cd5f0387e62db6e6ec800f32.

- Touch user in state
- Adjust transaction tests to new json format

* Switch to same commit for submodule ethereum/test as geth (next includes constantinople changes).
Added test `json_tests::trie::generic::TrieTests_trieanyorder` and a few
difficulty tests.

* Remove trietestnextprev as it would require to parse differently and
implement it.

* Support new (shitty) format of transaction tests.

* Ignore junk in ethereum/tests repo.

* Ignore incorrect test.

* Update to a later commit

* Move block number to a constant.

* Fix ZK2 test - touched account should also be cleared.

* Fix conflict resolution

* Fix checkpointing when creating contract failed (#9514)

* In create memory calculation is the same for create2 because the additional parameter was popped before. (#9522)

* Enable all Constantinople hard fork changes in constantinople_test.json (#9505)

* Enable all Constantinople hard fork changes in constantinople_test.json

* Address grumbles

* Remove EIP-210 activation

* 8m -> 5m

* Temporarily add back eip210 transition so we can get test passed

* Add eip210_test and remove eip210 transition from const_test

* Add constantinople conf to EvmTestClient. (#9570)

* Add constantinople conf to EvmTestClient.

* Skip some test to update submodule etheureum/tests submodule to latest.

* Put skipping 'under issue' test behind a feature.

* Change blockReward for const-test to pass ethereum/tests

* Update tests to new constantinple definition (change of reward at block
5).
Switch 'reference' to string, that way we can include issues from others
repo (more flexible)Update tests to new constantinple definition (change
of reward at block 5).
Switch 'reference' to string, that way we can include issues from others
repo (more flexible).

* Fix modexp and bn128_mul gas prices in chain config

* Changes `run_test_path` method to append its directory results (without
that it stop testing at the first file failure).
Add some missing tests.
Add skip for those (block create2 is one hundred percent false but on
hive we can see that geth and aleth got similar issue for this item).

* retab current.json

* Update reference to parity issue for failing tests.

* Hardfork the testnets (#9562)

* ethcore: propose hardfork block number 4230000 for ropsten

* ethcore: propose hardfork block number 9000000 for kovan

* ethcore: enable kip-4 and kip-6 on kovan

* etcore: bump kovan hardfork to block 9.2M

* ethcore: fix ropsten constantinople block number to 4.2M

* ethcore: disable difficulty_test_ropsten until ethereum/tests are updated upstream

* Don't hash the init_code of CREATE. (#9688)

* Implement CREATE2 gas changes and fix some potential overflowing (#9694)

* Implement CREATE2 gas changes and fix some potential overflowing

* Ignore create2 state tests

* Split CREATE and CREATE2 in gasometer

* Generalize rounding (x + 31) / 32 to to_word_size

* ethcore: delay ropsten hardfork (#9704)

* Add hardcoded headers (#9730)

* add foundation hardcoded header #6486017

* add ropsten hardcoded headers #4202497

* add kovan hardcoded headers #9023489

* gitlab ci: releasable_branches: change variables condition to schedule (#9729)

* HF in POA Core (2018-10-22) (#9724)

https://github.com/poanetwork/poa-chain-spec/pull/87
2018-10-10 18:55:52 +02:00
Afri Schoedon
93b25d5242 Backports for stable 2.0.7 (#9648)
* parity-version: bump stable to 2.0.7

* HF in POA Sokol (2018-09-19) (#9607)

https://github.com/poanetwork/poa-chain-spec/pull/86

* fix failing node-table tests on mac os, closes #9632 (#9633)

* fix(light_fetch): avoid race with BlockNumber::Latest (#9665)

* CI: Remove unnecessary pipes (#9681)

* ci: reduce gitlab pipelines significantly

* ci: build pipeline for PR

* ci: remove dead weight

* ci: remove github release script

* ci: remove forever broken aura tests

* ci: add random stuff to the end of the pipes

* ci: add wind and mac to the end of the pipe

* ci: remove snap artifacts

* ci: (re)move dockerfiles

* ci: clarify job names

* ci: add cargo audit job

* ci: make audit script executable

* ci: ignore snap and docker files for rust check

* ci: simplify audit script

* ci: rename misc to optional

* ci: add publish script to releaseable branches

* ci: more verbose cp command for windows build

* ci: fix weird binary checksum logic in push script

* ci: fix regex in push script for windows

* ci: simplify gitlab caching

* docs: align README with ci changes

* ci: specify default cargo target dir

* ci: print verbose environment

* ci: proper naming of scripts

* ci: restore docker files

* ci: use docker hub file

* ci: use cargo home instead of cargo target dir

* ci: touch random rust file to trigger real builds

* ci: set cargo target dir for audit script

* ci: remove temp file

* ci: don't export the cargo target dir in the audit script

* ci: fix windows unbound variable

* docs: fix gitlab badge path

* rename deprecated gitlab ci variables

https://docs.gitlab.com/ee/ci/variables/#9-0-renaming

* ci: fix git compare for nightly builds

* test: skip c++ example for all platforms but linux

* ci: add random rust file to trigger tests

* ci: remove random rust file

* disable cpp lib test for mac, win and beta (#9686)

* cleanup ci merge

* parity: bump clib

* ci: fix tests

* ci: disable c++ example

* Docker: run as parity user (#9689)

* CI: Skip docs job for nightly (#9693)

* ci: force-tag wiki changes

* ci: force-tag wiki changes

* ci: skip docs job for master and nightly

* ci: revert docs job checking for nightly tag

* ci: exclude docs job from nightly builds in gitlab script

* fix (light/provider) : Make `read_only executions` read-only (#9591)

* `ExecutionsRequest` from light-clients as read-only

This changes so all `ExecutionRequests` from light-clients are executed
as read-only which the `virtual``flag == true ensures.

This boost up the current transaction to always succeed

Note, this only affects `eth_estimateGas` and `eth_call` AFAIK.

* grumbles(revert renaming) : TransactionProof

* grumbles(trace) : remove incorrect trace

* grumbles(state/prove_tx) : explicit `virt`

Remove the boolean flag to determine that a `state::prove_transaction`
whether it should be executed in a virtual context or not.

Because of that also rename the function to
`state::prove_transction_virtual` to make more clear

* ethcore: fix detection of major import (#9552)

* sync: set state to idle after sync is completed

* sync: refactor sync reset

* parity: revert clib bump and fix tests

* Fix path to parity.h (#9274)

* Fix path to parity.h

* Fix other paths as well

* ethcore-io retries failed work steal (#9651)

* ethcore-io uses newer version of crossbeam && retries failed work steal

* ethcore-io non-mio service uses newer crossbeam
2018-10-10 17:33:03 +02:00
Andronik Ordian
7658d22f3a stable(rpc-docs): avoid recursive copy (#9613)
* stable: avoid recursive cp in rpc-docs

* rpc-docs: remove cd ..
2018-09-21 16:28:04 +02:00
gabriel klawitter
1b3b115e55 rpc-docs should push the branch (#9612) 2018-09-21 14:38:44 +02:00
Afri Schoedon
549e202fc1 Backports to 2.0.6 stable (#9600) 2018-09-19 20:28:36 +02:00
gabriel klawitter
de974fe954 ci: disable build cache for json-rpc-docs (#9587) 2018-09-19 10:07:35 +02:00
Afri Schoedon
7dc4d349a1 Backports for 2.0.5 stable (#9519)
* parity-version: mark 2.0.5 track stable

* deps: bump fs-swap to 0.2.4

* Remove initial token for WS. (#9545)

* version: mark release critical

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

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

+ Gas-cap increased to 10M by default

* Improve P2P discovery (#9526)

* Add `target` to Rust traces

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

* network-p2p: Refresh discovery more often

* Update Peer discovery protocol

* Run discovery more often when not enough nodes connected

* Start the first discovery early

* Update fast discovery rate

* Fix tests

* Fix `ping` tests

* Fixing remote Node address ; adding PingPong round

* Fix tests: update new +1 PingPong round

* Increase slow Discovery rate
Check in flight FindNode before pings

* Add `deprecated` to deprecated_echo_hash

* Refactor `discovery_round` branching

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

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

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

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

* Provide the actual `account` for eth_coinbase

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

* full client `eth_coinbase` return err

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

* Remove needless blocks on single import

* Remove needless `static` lifetime on const

* Fix `rpc_eth_author` test

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

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

* Only check warp syncing for eth_getWorks (#9484)

* Only check warp syncing for eth_getWorks

* Use SyncStatus::is_snapshot_syncing

* Fix Snapshot restoration failure on Windows (#9491)

* Close Blooms DB files before DB restoration

* PR Grumbles I

* PR Grumble

* Grumble
2018-09-10 22:52:45 +02:00
152 changed files with 4008 additions and 2037 deletions

View File

@@ -1,242 +1,181 @@
stages: stages:
- test - test
- push-release
- build - build
- docs - publish
- optional
image: parity/rust:gitlab-ci
variables: variables:
RUST_BACKTRACE: "1" CI_SERVER_NAME: "GitLab CI"
RUSTFLAGS: "" CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
CARGOFLAGS: "" BUILD_TARGET: ubuntu
CI_SERVER_NAME: "GitLab CI" BUILD_ARCH: amd64
CARGO_TARGET: x86_64-unknown-linux-gnu
cache: cache:
key: "$CI_BUILD_STAGE-$CI_BUILD_REF_NAME" key: "${CI_JOB_NAME}"
paths: paths:
- target/ - ./target
untracked: true - ./.cargo
linux-amd64:
stage: build .releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries")
image: parity/rust:gitlab-ci only: &releaseable_branches
only: - stable
- beta - beta
- tags - tags
- stable - schedules
- triggers
.collect_artifacts: &collect_artifacts
artifacts:
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}"
when: on_success
expire_in: 1 mos
paths:
- artifacts/
.determine_version: &determine_version
- VERSION="$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' Cargo.toml)"
- DATE_STR="$(date +%Y%m%d)"
- ID_SHORT="$(echo ${CI_COMMIT_SHA} | cut -c 1-7)"
- test "${CI_COMMIT_REF_NAME}" = "nightly" && VERSION="${VERSION}-${ID_SHORT}-${DATE_STR}"
- export VERSION
- echo "Version = ${VERSION}"
test-linux:
stage: test
variables:
RUN_TESTS: cargo
script: script:
- rustup default stable - scripts/gitlab/test-all.sh stable
# ARGUMENTS: 1. BUILD_PLATFORM (target for binaries) 2. PLATFORM (target for cargo) 3. ARC (architecture) 4. & 5. CC & CXX flags 6. binary identifier
- scripts/gitlab-build.sh x86_64-unknown-linux-gnu x86_64-unknown-linux-gnu amd64 gcc g++ linux
tags: tags:
- rust-stable - rust-stable
artifacts:
paths: build-linux:
- parity.zip stage: build
name: "stable-x86_64-unknown-linux-gnu_parity" only: *releaseable_branches
linux-i686: variables:
stage: build CARGO_TARGET: x86_64-unknown-linux-gnu
image: parity/rust-i686:gitlab-ci
only:
- beta
- tags
- stable
- triggers
script: script:
- scripts/gitlab-build.sh i686-unknown-linux-gnu i686-unknown-linux-gnu i386 gcc g++ linux - scripts/gitlab/build-unix.sh
tags: <<: *collect_artifacts
- rust-i686
artifacts:
paths:
- parity.zip
name: "i686-unknown-linux-gnu"
allow_failure: true
linux-armv7:
stage: build
image: parity/rust-armv7:gitlab-ci
only:
- beta
- tags
- stable
- triggers
script:
- scripts/gitlab-build.sh armv7-unknown-linux-gnueabihf armv7-unknown-linux-gnueabihf armhf arm-linux-gnueabihf-gcc arm-linux-gnueabihf-g++ linux
tags:
- rust-arm
artifacts:
paths:
- parity.zip
name: "armv7_unknown_linux_gnueabihf_parity"
allow_failure: true
linux-armhf:
stage: build
image: parity/rust-arm:gitlab-ci
only:
- beta
- tags
- stable
- triggers
script:
- scripts/gitlab-build.sh arm-unknown-linux-gnueabihf arm-unknown-linux-gnueabihf armhf arm-linux-gnueabihf-gcc arm-linux-gnueabihf-g++ linux
tags:
- rust-arm
artifacts:
paths:
- parity.zip
name: "arm-unknown-linux-gnueabihf_parity"
allow_failure: true
linux-aarch64:
stage: build
image: parity/rust-arm64:gitlab-ci
only:
- beta
- tags
- stable
- triggers
script:
- scripts/gitlab-build.sh aarch64-unknown-linux-gnu aarch64-unknown-linux-gnu arm64 aarch64-linux-gnu-gcc aarch64-linux-gnu-g++ linux
tags:
- rust-arm
artifacts:
paths:
- parity.zip
name: "aarch64-unknown-linux-gnu_parity"
linux-snap:
stage: build
image: parity/snapcraft:gitlab-ci
only:
- stable
- beta
- tags
- triggers
script:
- scripts/gitlab-build.sh x86_64-unknown-snap-gnu x86_64-unknown-linux-gnu amd64 gcc g++ snap
tags: tags:
- rust-stable - rust-stable
artifacts:
paths: build-darwin:
- parity.zip stage: build
name: "stable-x86_64-unknown-snap-gnu_parity" only: *releaseable_branches
darwin: variables:
stage: build CARGO_TARGET: x86_64-apple-darwin
only: CC: gcc
- beta CXX: g++
- tags
- stable
- triggers
script: script:
- scripts/gitlab-build.sh x86_64-apple-darwin x86_64-apple-darwin macos gcc g++ macos - scripts/gitlab/build-unix.sh
tags: tags:
- osx - rust-osx
artifacts: <<: *collect_artifacts
paths:
- parity.zip build-windows:
name: "x86_64-apple-darwin_parity" stage: build
windows: only: *releaseable_branches
cache: variables:
key: "%CI_BUILD_STAGE%-%CI_BUILD_REF_NAME%" CARGO_TARGET: x86_64-pc-windows-msvc
untracked: true
stage: build
only:
- beta
- tags
- stable
- triggers
script: script:
- sh scripts/gitlab-build.sh x86_64-pc-windows-msvc x86_64-pc-windows-msvc amd64 "" "" windows - sh scripts/gitlab/build-windows.sh
tags: tags:
- rust-windows - rust-windows
artifacts: <<: *collect_artifacts
paths:
- parity.zip publish-docker:
name: "x86_64-pc-windows-msvc_parity" stage: publish
android-armv7: only: *releaseable_branches
stage: build cache: {}
image: parity/parity-android:latest dependencies:
only: - build-linux
- beta
- tags
- stable
- triggers
script:
- cargo build --target=armv7-linux-androideabi
tags: tags:
- rust-arm - shell
allow_failure: true script:
artifacts: - scripts/gitlab/publish-docker.sh parity
paths:
- parity.zip publish-awss3:
name: "armv7-linux-androideabi_parity" stage: publish
docker-build: only: *releaseable_branches
stage: build cache: {}
dependencies:
- build-linux
- build-darwin
- build-windows
before_script: *determine_version
script:
- scripts/gitlab/publish-awss3.sh
tags:
- shell
docs-jsonrpc:
stage: optional
only: only:
- tags - tags
- master except:
- beta - nightly
- stable cache: {}
- triggers
before_script:
- docker info
script: script:
- if [ "$CI_BUILD_REF_NAME" == "master" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi - scripts/gitlab/docs-jsonrpc.sh
- echo "Tag:" $DOCKER_TAG
- docker login -u $Docker_Hub_User_Parity -p $Docker_Hub_Pass_Parity
- scripts/docker-build.sh $DOCKER_TAG
- docker logout
tags: tags:
- docker - shell
test-coverage:
stage: test cargo-audit:
only: stage: optional
- master
script: script:
- scripts/gitlab-test.sh test-coverage - scripts/gitlab/cargo-audit.sh
tags:
- kcov
allow_failure: true
test-rust-stable:
stage: test
image: parity/rust:gitlab-ci
script:
- scripts/gitlab-test.sh stable
tags: tags:
- rust-stable - rust-stable
test-rust-beta:
stage: test test-android:
only: stage: optional
- triggers image: parity/rust-android:gitlab-ci
- master variables:
image: parity/rust:gitlab-ci CARGO_TARGET: armv7-linux-androideabi
script: script:
- scripts/gitlab-test.sh beta - scripts/gitlab/test-all.sh stable
tags:
- rust-arm
test-darwin:
stage: optional
variables:
CARGO_TARGET: x86_64-apple-darwin
CC: gcc
CXX: g++
RUN_TESTS: cargo
script:
- scripts/gitlab/test-all.sh stable
tags:
- rust-osx
test-windows:
stage: optional
variables:
CARGO_TARGET: x86_64-pc-windows-msvc
RUN_TESTS: cargo
script:
- sh scripts/gitlab/test-all.sh stable
tags:
- rust-windows
test-beta:
stage: optional
variables:
RUN_TESTS: cargo
script:
- scripts/gitlab/test-all.sh beta
tags: tags:
- rust-beta - rust-beta
allow_failure: true
test-rust-nightly: test-nightly:
stage: test stage: optional
only: variables:
- triggers RUN_TESTS: all
- master
image: parity/rust:gitlab-ci
script: script:
- scripts/gitlab-test.sh nightly - scripts/gitlab/test-all.sh nightly
tags: tags:
- rust
- rust-nightly - rust-nightly
allow_failure: true
json-rpc-docs:
stage: docs
only:
- tags
image: parity/rust:gitlab-ci
script:
- scripts/gitlab-rpc-docs.sh
tags:
- docs
push-release:
stage: push-release
only:
- tags
- triggers
image: parity/rust:gitlab-ci
script:
- scripts/gitlab-push-release.sh
tags:
- curl

80
Cargo.lock generated
View File

@@ -271,6 +271,15 @@ dependencies = [
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "crossbeam-deque"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.3.1" version = "0.3.1"
@@ -298,6 +307,19 @@ dependencies = [
"scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "crossbeam-epoch"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.2.2" version = "0.2.2"
@@ -314,6 +336,11 @@ dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "crossbeam-utils"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "crunchy" name = "crunchy"
version = "0.1.6" version = "0.1.6"
@@ -472,7 +499,7 @@ dependencies = [
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (git+https://github.com/paritytech/parity-common)", "keccak-hash 0.1.2 (git+https://github.com/paritytech/parity-common)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -576,7 +603,7 @@ version = "1.12.0"
name = "ethcore-io" name = "ethcore-io"
version = "1.12.0" version = "1.12.0"
dependencies = [ dependencies = [
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1062,7 +1089,7 @@ dependencies = [
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1091,7 +1118,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "fs-swap" name = "fs-swap"
version = "0.2.3" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1227,7 +1254,7 @@ dependencies = [
"httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1488,7 +1515,7 @@ source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c9
dependencies = [ dependencies = [
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fs-swap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1585,12 +1612,12 @@ name = "log"
version = "0.3.9" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.1" version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1705,7 +1732,7 @@ dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1717,7 +1744,7 @@ name = "mio-named-pipes"
version = "0.1.5" version = "0.1.5"
source = "git+https://github.com/alexcrichton/mio-named-pipes#6ad80e67fe7993423b281bc13d307785ade05d37" source = "git+https://github.com/alexcrichton/mio-named-pipes#6ad80e67fe7993423b281bc13d307785ade05d37"
dependencies = [ dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1930,7 +1957,7 @@ source = "git+https://github.com/paritytech/parity-common#0045887fecd2fec39e56c9
name = "parity-clib" name = "parity-clib"
version = "1.12.0" version = "1.12.0"
dependencies = [ dependencies = [
"parity-ethereum 2.0.3", "parity-ethereum 2.0.7",
] ]
[[package]] [[package]]
@@ -1947,7 +1974,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-ethereum" name = "parity-ethereum"
version = "2.0.3" version = "2.0.7"
dependencies = [ dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1996,7 +2023,7 @@ dependencies = [
"parity-rpc 1.12.0", "parity-rpc 1.12.0",
"parity-rpc-client 1.4.0", "parity-rpc-client 1.4.0",
"parity-updater 1.12.0", "parity-updater 1.12.0",
"parity-version 2.0.3", "parity-version 2.0.7",
"parity-whisper 0.1.0", "parity-whisper 0.1.0",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"path 0.1.1 (git+https://github.com/paritytech/parity-common)", "path 0.1.1 (git+https://github.com/paritytech/parity-common)",
@@ -2135,7 +2162,7 @@ dependencies = [
"parity-crypto 0.1.0 (git+https://github.com/paritytech/parity-common)", "parity-crypto 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parity-reactor 0.1.0", "parity-reactor 0.1.0",
"parity-updater 1.12.0", "parity-updater 1.12.0",
"parity-version 2.0.3", "parity-version 2.0.7",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)", "patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
"plain_hasher 0.1.0 (git+https://github.com/paritytech/parity-common)", "plain_hasher 0.1.0 (git+https://github.com/paritytech/parity-common)",
@@ -2180,7 +2207,7 @@ source = "git+https://github.com/nikvolf/parity-tokio-ipc#2af3e5b6b746552d818106
dependencies = [ dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-named-pipes 0.1.5 (git+https://github.com/alexcrichton/mio-named-pipes)", "mio-named-pipes 0.1.5 (git+https://github.com/alexcrichton/mio-named-pipes)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2206,7 +2233,7 @@ dependencies = [
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)", "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"parity-hash-fetch 1.12.0", "parity-hash-fetch 1.12.0",
"parity-version 2.0.3", "parity-version 2.0.7",
"parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"path 0.1.1 (git+https://github.com/paritytech/parity-common)", "path 0.1.1 (git+https://github.com/paritytech/parity-common)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2217,7 +2244,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-version" name = "parity-version"
version = "2.0.3" version = "2.0.7"
dependencies = [ dependencies = [
"parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)", "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)", "rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
@@ -2494,7 +2521,7 @@ version = "0.2.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.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -3092,7 +3119,7 @@ dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3117,7 +3144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -3155,7 +3182,7 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3212,7 +3239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3243,7 +3270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3645,10 +3672,13 @@ dependencies = [
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" "checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2"
"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1"
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" "checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81"
"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
"checksum ct-logs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61cd11fb222fecf889f4531855c614548e92e8bd2eb178e35296885df5ee9a7c" "checksum ct-logs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61cd11fb222fecf889f4531855c614548e92e8bd2eb178e35296885df5ee9a7c"
@@ -3674,7 +3704,7 @@ dependencies = [
"checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576" "checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum fs-swap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67f816b2a5f8a6628764a4323d1a8d9ad5303266c4e4e4486ba680f477ba7e62" "checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
@@ -3725,7 +3755,7 @@ dependencies = [
"checksum local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1ceb20f39ff7ae42f3ff9795f3986b1daad821caaa1e1732a0944103a5a1a66" "checksum local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1ceb20f39ff7ae42f3ff9795f3986b1daad821caaa1e1732a0944103a5a1a66"
"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" "checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21"
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"

View File

@@ -2,7 +2,7 @@
description = "Parity Ethereum client" description = "Parity Ethereum client"
name = "parity-ethereum" name = "parity-ethereum"
# NOTE Make sure to update util/version/Cargo.toml as well # NOTE Make sure to update util/version/Cargo.toml as well
version = "2.0.3" version = "2.0.7"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
@@ -89,6 +89,7 @@ daemonize = { git = "https://github.com/paritytech/daemonize" }
[features] [features]
miner-debug = ["ethcore/miner-debug"] miner-debug = ["ethcore/miner-debug"]
json-tests = ["ethcore/json-tests"] json-tests = ["ethcore/json-tests"]
ci-skip-issue = ["ethcore/ci-skip-issue"]
test-heavy = ["ethcore/test-heavy"] test-heavy = ["ethcore/test-heavy"]
evm-debug = ["ethcore/evm-debug"] evm-debug = ["ethcore/evm-debug"]
evm-debug-tests = ["ethcore/evm-debug-tests"] evm-debug-tests = ["ethcore/evm-debug-tests"]

175
README.md
View File

@@ -1,111 +1,75 @@
# Parity - fast, light, and robust Ethereum client ![Parity Ethereum](docs/logo-parity-ethereum.svg)
## [» Download the latest release «](https://github.com/paritytech/parity/releases/latest) ## The fastest and most advanced Ethereum client.
[![build status](https://gitlab.parity.io/parity/parity/badges/master/build.svg)](https://gitlab.parity.io/parity/parity/commits/master) <p align="center"><strong><a href="https://github.com/paritytech/parity-ethereum/releases/latest">» Download the latest release «</a></strong></p>
[![codecov](https://codecov.io/gh/paritytech/parity/branch/master/graph/badge.svg)](https://codecov.io/gh/paritytech/parity)
[![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)
<p align="center"><a href="https://gitlab.parity.io/parity/parity-ethereum/commits/master" target="_blank"><img src="https://gitlab.parity.io/parity/parity-ethereum/badges/master/build.svg" /></a>
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"><img src="https://img.shields.io/badge/license-GPL%20v3-green.svg" /></a></p>
### Join the chat! **Built for mission-critical use**: Miners, service providers, and exchanges need fast synchronisation and maximum uptime. Parity Ethereum provides the core infrastructure essential for speedy and reliable services.
Get in touch with us on Gitter: - Clean, modular codebase for easy customisation
[![Gitter: Parity](https://img.shields.io/badge/gitter-parity-4AB495.svg)](https://gitter.im/paritytech/parity) - Advanced CLI-based client
[![Gitter: Parity.js](https://img.shields.io/badge/gitter-parity.js-4AB495.svg)](https://gitter.im/paritytech/parity.js) - Minimal memory and storage footprint
[![Gitter: Parity/Miners](https://img.shields.io/badge/gitter-parity/miners-4AB495.svg)](https://gitter.im/paritytech/parity/miners) - Synchronise in hours, not days with Warp Sync
[![Gitter: Parity-PoA](https://img.shields.io/badge/gitter-parity--poa-4AB495.svg)](https://gitter.im/paritytech/parity-poa) - Modular for light integration into your service or product
Or join our community on Matrix: ## Technical Overview
[![Riot: +Parity](https://img.shields.io/badge/riot-%2Bparity%3Amatrix.parity.io-orange.svg)](https://riot.im/app/#/group/+parity:matrix.parity.io)
Official website: https://parity.io | Be sure to check out [our wiki](https://wiki.parity.io) for more information. Parity Ethereum's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity Ethereum using the sophisticated and cutting-edge **Rust programming language**. Parity Ethereum is licensed under the GPLv3 and can be used for all your Ethereum needs.
---- By default, Parity Ethereum runs a JSON-RPC HTTP server on port `:8545` and a Web-Sockets server on port `:8546`. This is fully configurable and supports a number of APIs.
## About Parity If you run into problems while using Parity Ethereum, check out the [wiki for documentation](https://wiki.parity.io/), feel free to [file an issue in this repository](https://github.com/paritytech/parity-ethereum/issues/new), or hop on our [Gitter](https://gitter.im/paritytech/parity) or [Riot](https://riot.im/app/#/group/+parity:matrix.parity.io) chat room to ask a question. We are glad to help! **For security-critical issues**, please refer to the security policy outlined in [SECURITY.md](SECURITY.md).
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. Parity Ethereum's current beta-release is 2.1. You can download it at [the releases page](https://github.com/paritytech/parity-ethereum/releases) or follow the instructions below to build from source. Please, mind the [CHANGELOG.md](CHANGELOG.md) for a list of all changes between different versions.
From Parity Ethereum client version 1.10.0, the User Interface (UI) is accessible in a separate application called Parity UI. To keep using the UI in the browser (deprecated), [follow these steps](https://wiki.parity.io/FAQ-Basic-Operations,-Configuration,-and-Synchronization#the-parity-ui-application-isnt-working-the-way-i-want). ## Build Dependencies
By default, Parity will also run a JSONRPC server on `127.0.0.1:8545` and a websockets server on `127.0.0.1:8546`. This is fully configurable and supports a number of APIs. Parity Ethereum requires **Rust version 1.29.x** to build.
If you run into an issue while using Parity, feel free to file one in this repository or hop on our [Gitter](https://gitter.im/paritytech/parity) or [Riot](https://riot.im/app/#/group/+parity:matrix.parity.io) chat room to ask a question. We are glad to help! **For security-critical issues**, please refer to the security policy outlined in [SECURITY.MD](SECURITY.md). We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have `rustup`, you can install it like this:
Parity's current beta-release is 1.11. You can download it at https://github.com/paritytech/parity/releases or follow the instructions below to build from source.
----
## Build dependencies
**Parity requires Rust version 1.26.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:
- Linux: - Linux:
```bash
$ curl https://sh.rustup.rs -sSf | sh
```
Parity also requires `gcc`, `g++`, `libssl-dev`/`openssl`, `libudev-dev`, `pkg-config`, `file` and `make` packages to be installed.
- OSX:
```bash
$ curl https://sh.rustup.rs -sSf | sh
```
`clang` is required. It comes with Xcode command line tools or can be installed with homebrew.
- Windows
Make sure you have Visual Studio 2015 with C++ support installed. Next, download and run the rustup installer from
https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe, start "VS2015 x64 Native Tools Command Prompt", and use the following command to install and set up the msvc toolchain:
```bash ```bash
$ rustup default stable-x86_64-pc-windows-msvc $ curl https://sh.rustup.rs -sSf | sh
``` ```
Once you have rustup installed, then you need to install: Parity Ethereum also requires `gcc`, `g++`, `libudev-dev`, `pkg-config`, `file`, `make`, and `cmake` packages to be installed.
- OSX:
```bash
$ curl https://sh.rustup.rs -sSf | sh
```
`clang` is required. It comes with Xcode command line tools or can be installed with homebrew.
- Windows
Make sure you have Visual Studio 2015 with C++ support installed. Next, download and run the `rustup` installer from
https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe, start "VS2015 x64 Native Tools Command Prompt", and use the following command to install and set up the `msvc` toolchain:
```bash
$ rustup default stable-x86_64-pc-windows-msvc
```
Once you have `rustup` installed, then you need to install:
* [Perl](https://www.perl.org) * [Perl](https://www.perl.org)
* [Yasm](http://yasm.tortall.net) * [Yasm](https://yasm.tortall.net)
Make sure that these binaries are in your `PATH`. After that you should be able to build parity from source. Make sure that these binaries are in your `PATH`. After that, you should be able to build Parity Ethereum from source.
---- ## Build from Source Code
## Install from the snap store
In any of the [supported Linux distros](https://snapcraft.io/docs/core/install):
```bash ```bash
sudo snap install parity # download Parity Ethereum code
``` $ git clone https://github.com/paritytech/parity-ethereum
$ cd parity-ethereum
Or, if you want to contribute testing the upcoming release:
```bash
sudo snap install parity --beta
```
And to test the latest code landed into the master branch:
```bash
sudo snap install parity --edge
```
----
## Build from source
```bash
# download Parity code
$ git clone https://github.com/paritytech/parity
$ cd parity
# build in release mode # build in release mode
$ cargo build --release $ cargo build --release --features final
``` ```
This will produce an executable in the `./target/release` subdirectory. This produces an executable in the `./target/release` subdirectory.
Note: if cargo fails to parse manifest try: Note: if cargo fails to parse manifest try:
@@ -119,7 +83,7 @@ Note, when compiling a crate and you receive errors, it's in most cases your out
$ cargo clean $ cargo clean
``` ```
This will always compile the latest nightly builds. If you want to build stable or beta, do a This always compiles the latest nightly builds. If you want to build stable or beta, do a
```bash ```bash
$ git checkout stable $ git checkout stable
@@ -131,11 +95,7 @@ or
$ git checkout beta $ git checkout beta
``` ```
first. ## Simple One-Line Installer for Mac and Linux
----
## Simple one-line installer for Mac and Ubuntu
```bash ```bash
bash <(curl https://get.parity.io -L) bash <(curl https://get.parity.io -L)
@@ -147,22 +107,49 @@ The one-line installer always defaults to the latest beta release. To install a
bash <(curl https://get.parity.io -L) -r stable bash <(curl https://get.parity.io -L) -r stable
``` ```
## Start Parity ## Start Parity Ethereum
### Manually ### Manually
To start Parity manually, just run To start Parity Ethereum manually, just run
```bash ```bash
$ ./target/release/parity $ ./target/release/parity
``` ```
and Parity will begin syncing the Ethereum blockchain. so Parity Ethereum begins syncing the Ethereum blockchain.
### Using systemd service file ### Using `systemd` service file
To start Parity as a regular user using systemd init: To start Parity Ethereum as a regular user using `systemd` init:
1. Copy `./scripts/parity.service` to your 1. Copy `./scripts/parity.service` to your
systemd user directory (usually `~/.config/systemd/user`). `systemd` user directory (usually `~/.config/systemd/user`).
2. To configure Parity, write a `/etc/parity/config.toml` config file, see [Configuring Parity](https://paritytech.github.io/wiki/Configuring-Parity) for details. 2. To configure Parity Ethereum, write a `/etc/parity/config.toml` config file, see [Configuring Parity Ethereum](https://paritytech.github.io/wiki/Configuring-Parity) for details.
## Parity Ethereum toolchain
In addition to the Parity Ethereum client, there are additional tools in this repository available:
- [evmbin](https://github.com/paritytech/parity-ethereum/blob/master/evmbin/) - EVM implementation for Parity Ethereum.
- [ethabi](https://github.com/paritytech/ethabi) - Parity Ethereum function calls encoding.
- [ethstore](https://github.com/paritytech/parity-ethereum/blob/master/ethstore/) - Parity Ethereum key management.
- [ethkey](https://github.com/paritytech/parity-ethereum/blob/master/ethkey/) - Parity Ethereum keys generator.
- [whisper](https://github.com/paritytech/parity-ethereum/blob/master/whisper/) - Implementation of Whisper-v2 PoC.
## Join the chat!
Questions? Get in touch with us on Gitter:
[![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)
[![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)
Alternatively, join our community on Matrix:
[![Riot: +Parity](https://img.shields.io/badge/riot-%2Bparity%3Amatrix.parity.io-orange.svg)](https://riot.im/app/#/group/+parity:matrix.parity.io)
## Documentation
Official website: https://parity.io
Be sure to [check out our wiki](https://wiki.parity.io) for more information.

View File

@@ -1,3 +0,0 @@
Usage
```docker build -f docker/ubuntu/Dockerfile --tag ethcore/parity:branch_or_tag_name .```

View File

@@ -1,29 +0,0 @@
FROM alpine:edge
WORKDIR /build
# install tools and dependencies
RUN apk add --no-cache gcc musl-dev pkgconfig g++ make curl \
eudev-dev rust cargo git file binutils \
libusb-dev linux-headers perl cmake
# show backtraces
ENV RUST_BACKTRACE 1
# show tools
RUN rustc -vV && \
cargo -V && \
gcc -v &&\
g++ -v
# build parity
ADD . /build/parity
RUN cd parity && \
cargo build --release --verbose && \
ls /build/parity/target/release/parity && \
strip /build/parity/target/release/parity
RUN file /build/parity/target/release/parity
EXPOSE 8080 8545 8180
ENTRYPOINT ["/build/parity/target/release/parity"]

View File

@@ -1,61 +0,0 @@
FROM ubuntu:xenial
LABEL maintainer="Parity Technologies <devops@parity.io>"
RUN apt-get update && \
apt-get install -yq sudo curl file build-essential wget git g++ cmake pkg-config bison flex \
unzip lib32stdc++6 lib32z1 python autotools-dev automake autoconf libtool \
gperf xsltproc docbook-xsl
# Rust & Cargo
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
ENV PATH /root/.cargo/bin:$PATH
RUN rustup toolchain install stable
RUN rustup target add --toolchain stable arm-linux-androideabi
RUN rustup target add --toolchain stable armv7-linux-androideabi
# Android NDK and toolchain
RUN cd /usr/local && \
wget -q https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip && \
unzip -q android-ndk-r16b-linux-x86_64.zip && \
rm android-ndk-r16b-linux-x86_64.zip
ENV NDK_HOME /usr/local/android-ndk-r16b
RUN /usr/local/android-ndk-r16b/build/tools/make-standalone-toolchain.sh \
--arch=arm --install-dir=/opt/ndk-standalone --stl=libc++ --platform=android-26
ENV PATH $PATH:/opt/ndk-standalone/bin
# Compiling libudev for Android
# This is the most hacky part of the process, as we need to apply a patch and pass specific
# options that the compiler environment doesn't define.
RUN cd /root && \
git clone https://github.com/gentoo/eudev.git
ADD libudev.patch /root
RUN cd /root/eudev && \
git checkout 83d918449f22720d84a341a05e24b6d109e6d3ae && \
./autogen.sh && \
./configure --disable-introspection --disable-programs --disable-hwdb \
--host=arm-linux-androideabi --prefix=/opt/ndk-standalone/sysroot/usr/ \
--enable-shared=false CC=arm-linux-androideabi-clang \
CFLAGS="-D LINE_MAX=2048 -D RLIMIT_NLIMITS=15 -D IPTOS_LOWCOST=2 -std=gnu99" \
CXX=arm-linux-androideabi-clang++ && \
git apply - < /root/libudev.patch && \
make && \
make install
RUN rm -rf /root/eudev
RUN rm /root/libudev.patch
# Rust-related configuration
ADD cargo-config.toml /root/.cargo/config
ENV ARM_LINUX_ANDROIDEABI_OPENSSL_DIR /opt/ndk-standalone/sysroot/usr
ENV ARMV7_LINUX_ANDROIDEABI_OPENSSL_DIR /opt/ndk-standalone/sysroot/usr
ENV CC_arm_linux_androideabi arm-linux-androideabi-clang
ENV CC_armv7_linux_androideabi arm-linux-androideabi-clang
ENV CXX_arm_linux_androideabi arm-linux-androideabi-clang++
ENV CXX_armv7_linux_androideabi arm-linux-androideabi-clang++
ENV AR_arm_linux_androideabi arm-linux-androideabi-ar
ENV AR_armv7_linux_androideabi arm-linux-androideabi-ar
ENV CFLAGS_arm_linux_androideabi -std=gnu11 -fPIC -D OS_ANDROID
ENV CFLAGS_armv7_linux_androideabi -std=gnu11 -fPIC -D OS_ANDROID
ENV CXXFLAGS_arm_linux_androideabi -std=gnu++11 -fPIC -fexceptions -frtti -static-libstdc++ -D OS_ANDROID
ENV CXXFLAGS_armv7_linux_androideabi -std=gnu++11 -fPIC -fexceptions -frtti -static-libstdc++ -D OS_ANDROID
ENV CXXSTDLIB_arm_linux_androideabi ""
ENV CXXSTDLIB_armv7_linux_androideabi ""

View File

@@ -1,9 +0,0 @@
[target.armv7-linux-androideabi]
linker = "arm-linux-androideabi-clang"
ar = "arm-linux-androideabi-ar"
rustflags = ["-C", "link-arg=-lc++_static", "-C", "link-arg=-lc++abi", "-C", "link-arg=-landroid_support"]
[target.arm-linux-androideabi]
linker = "arm-linux-androideabi-clang"
ar = "arm-linux-androideabi-ar"
rustflags = ["-C", "link-arg=-lc++_static", "-C", "link-arg=-lc++abi", "-C", "link-arg=-landroid_support"]

View File

@@ -1,216 +0,0 @@
diff --git a/src/collect/collect.c b/src/collect/collect.c
index 2cf1f00..b24f26b 100644
--- a/src/collect/collect.c
+++ b/src/collect/collect.c
@@ -84,7 +84,7 @@ static void usage(void)
" invoked for each ID in <idlist>) collect returns 0, the\n"
" number of missing IDs otherwise.\n"
" On error a negative number is returned.\n\n"
- , program_invocation_short_name);
+ , "parity");
}
/*
diff --git a/src/scsi_id/scsi_id.c b/src/scsi_id/scsi_id.c
index 8b76d87..7bf3948 100644
--- a/src/scsi_id/scsi_id.c
+++ b/src/scsi_id/scsi_id.c
@@ -321,7 +321,7 @@ static void help(void) {
" -u --replace-whitespace Replace all whitespace by underscores\n"
" -v --verbose Verbose logging\n"
" -x --export Print values as environment keys\n"
- , program_invocation_short_name);
+ , "parity");
}
diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h
index a03ee58..a7c2005 100644
--- a/src/shared/hashmap.h
+++ b/src/shared/hashmap.h
@@ -98,10 +98,7 @@ extern const struct hash_ops uint64_hash_ops;
#if SIZEOF_DEV_T != 8
unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
int devt_compare_func(const void *a, const void *b) _pure_;
-extern const struct hash_ops devt_hash_ops = {
- .hash = devt_hash_func,
- .compare = devt_compare_func
-};
+extern const struct hash_ops devt_hash_ops;
#else
#define devt_hash_func uint64_hash_func
#define devt_compare_func uint64_compare_func
diff --git a/src/shared/log.c b/src/shared/log.c
index 4a40996..1496984 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -335,7 +335,7 @@ static int write_to_syslog(
IOVEC_SET_STRING(iovec[0], header_priority);
IOVEC_SET_STRING(iovec[1], header_time);
- IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
+ IOVEC_SET_STRING(iovec[2], "parity");
IOVEC_SET_STRING(iovec[3], header_pid);
IOVEC_SET_STRING(iovec[4], buffer);
@@ -383,7 +383,7 @@ static int write_to_kmsg(
char_array_0(header_pid);
IOVEC_SET_STRING(iovec[0], header_priority);
- IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
+ IOVEC_SET_STRING(iovec[1], "parity");
IOVEC_SET_STRING(iovec[2], header_pid);
IOVEC_SET_STRING(iovec[3], buffer);
IOVEC_SET_STRING(iovec[4], "\n");
diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c
index 6af7163..3271e56 100644
--- a/src/udev/udevadm-control.c
+++ b/src/udev/udevadm-control.c
@@ -41,7 +41,7 @@ static void print_help(void) {
" -p --property=KEY=VALUE Set a global property for all events\n"
" -m --children-max=N Maximum number of children\n"
" --timeout=SECONDS Maximum time to block for a reply\n"
- , program_invocation_short_name);
+ , "parity");
}
static int adm_control(struct udev *udev, int argc, char *argv[]) {
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index 0aec976..a31ac02 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -279,7 +279,7 @@ static void help(void) {
" -P --export-prefix Export the key name with a prefix\n"
" -e --export-db Export the content of the udev database\n"
" -c --cleanup-db Clean up the udev database\n"
- , program_invocation_short_name);
+ , "parity");
}
static int uinfo(struct udev *udev, int argc, char *argv[]) {
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
index 15ded09..b58dd08 100644
--- a/src/udev/udevadm-monitor.c
+++ b/src/udev/udevadm-monitor.c
@@ -73,7 +73,7 @@ static void help(void) {
" -u --udev Print udev events\n"
" -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem\n"
" -t --tag-match=TAG Filter events by tag\n"
- , program_invocation_short_name);
+ , "parity");
}
static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
index 33597bc..b36a504 100644
--- a/src/udev/udevadm-settle.c
+++ b/src/udev/udevadm-settle.c
@@ -43,7 +43,7 @@ static void help(void) {
" --version Show package version\n"
" -t --timeout=SECONDS Maximum time to wait for events\n"
" -E --exit-if-exists=FILE Stop waiting if file exists\n"
- , program_invocation_short_name);
+ , "parity");
}
static int adm_settle(struct udev *udev, int argc, char *argv[]) {
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
index baaeca9..50ed812 100644
--- a/src/udev/udevadm-test-builtin.c
+++ b/src/udev/udevadm-test-builtin.c
@@ -39,7 +39,7 @@ static void help(struct udev *udev) {
" -h --help Print this message\n"
" --version Print version of the program\n\n"
"Commands:\n"
- , program_invocation_short_name);
+ , "parity");
udev_builtin_list(udev);
}
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 47fd924..a855412 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -39,7 +39,7 @@ static void help(void) {
" --version Show package version\n"
" -a --action=ACTION Set action string\n"
" -N --resolve-names=early|late|never When to resolve names\n"
- , program_invocation_short_name);
+ , "parity");
}
static int adm_test(struct udev *udev, int argc, char *argv[]) {
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
index 4dc756a..67787d3 100644
--- a/src/udev/udevadm-trigger.c
+++ b/src/udev/udevadm-trigger.c
@@ -92,7 +92,7 @@ static void help(void) {
" -y --sysname-match=NAME Trigger devices with this /sys path\n"
" --name-match=NAME Trigger devices with this /dev name\n"
" -b --parent-match=NAME Trigger devices with that parent device\n"
- , program_invocation_short_name);
+ , "parity");
}
static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
index 3e57cf6..b03dfaa 100644
--- a/src/udev/udevadm.c
+++ b/src/udev/udevadm.c
@@ -62,7 +62,7 @@ static int adm_help(struct udev *udev, int argc, char *argv[]) {
printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n"
"Send control commands or test the device manager.\n\n"
"Commands:\n"
- , program_invocation_short_name);
+ , "parity");
for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
if (udevadm_cmds[i]->help != NULL)
@@ -128,7 +128,7 @@ int main(int argc, char *argv[]) {
goto out;
}
- fprintf(stderr, "%s: missing or unknown command\n", program_invocation_short_name);
+ fprintf(stderr, "%s: missing or unknown command\n", "parity");
rc = 2;
out:
mac_selinux_finish();
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index cf826c6..4eec0af 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1041,7 +1041,7 @@ static void help(void) {
" -t --event-timeout=SECONDS Seconds to wait before terminating an event\n"
" -N --resolve-names=early|late|never\n"
" When to resolve users and groups\n"
- , program_invocation_short_name);
+ , "parity");
}
static int parse_argv(int argc, char *argv[]) {
diff --git a/src/v4l_id/v4l_id.c b/src/v4l_id/v4l_id.c
index 1dce0d5..f65badf 100644
--- a/src/v4l_id/v4l_id.c
+++ b/src/v4l_id/v4l_id.c
@@ -49,7 +49,7 @@ int main(int argc, char *argv[]) {
printf("%s [-h,--help] <device file>\n\n"
"Video4Linux device identification.\n\n"
" -h Print this message\n"
- , program_invocation_short_name);
+ , "parity");
return 0;
case '?':
return -EINVAL;
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index 0744563..7151356 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -109,7 +109,7 @@ char *path_make_absolute_cwd(const char *p) {
if (path_is_absolute(p))
return strdup(p);
- cwd = get_current_dir_name();
+ cwd = getcwd(malloc(128), 128);
if (!cwd)
return NULL;

View File

@@ -1,36 +0,0 @@
FROM centos:latest
WORKDIR /build
# install tools and dependencies
RUN yum -y update&& \
yum install -y git make gcc-c++ gcc file binutils cmake
# install rustup
RUN curl -sSf https://static.rust-lang.org/rustup.sh -o rustup.sh &&\
ls&&\
sh rustup.sh --disable-sudo
# show backtraces
ENV RUST_BACKTRACE 1
# set compiler
ENV CXX g++
ENV CC gcc
# show tools
RUN rustc -vV && \
cargo -V && \
gcc -v &&\
g++ -v
# build parity
ADD . /build/parity
RUN cd parity&&\
cargo build --release --verbose && \
ls /build/parity/target/release/parity && \
strip /build/parity/target/release/parity
RUN file /build/parity/target/release/parity
EXPOSE 8080 8545 8180
ENTRYPOINT ["/build/parity/target/release/parity"]

View File

@@ -1,65 +0,0 @@
FROM ubuntu:xenial
MAINTAINER Parity Technologies <devops@parity.io>
WORKDIR /build
#ENV for build TAG
ARG BUILD_TAG
ENV BUILD_TAG ${BUILD_TAG:-master}
RUN echo "Build tag:" $BUILD_TAG
# install tools and dependencies
RUN apt-get update && \
apt-get install -y --force-yes --no-install-recommends \
# make
build-essential \
# add-apt-repository
software-properties-common \
make \
cmake \
curl \
wget \
git \
g++ \
gcc \
libc6 \
libc6-dev \
binutils \
file \
libudev-dev \
pkg-config \
dpkg-dev \
libudev-dev &&\
# install rustup
curl https://sh.rustup.rs -sSf | sh -s -- -y && \
# rustup directory
PATH=/root/.cargo/bin:$PATH && \
# show backtraces
RUST_BACKTRACE=1 && \
# build parity
cd /build&&git clone https://github.com/paritytech/parity-ethereum && \
cd parity-ethereum && \
git pull&& \
git checkout $BUILD_TAG && \
cargo build --verbose --release --features final && \
strip /build/parity-ethereum/target/release/parity && \
file /build/parity-ethereum/target/release/parity&&mkdir -p /parity&& cp /build/parity-ethereum/target/release/parity /parity&&\
#cleanup Docker image
rm -rf /root/.cargo&&rm -rf /root/.multirust&&rm -rf /root/.rustup&&rm -rf /build&&\
apt-get purge -y \
# make
build-essential \
# add-apt-repository
software-properties-common \
make \
cmake \
curl \
wget \
git \
g++ \
gcc \
binutils \
file \
pkg-config \
dpkg-dev &&\
rm -rf /var/lib/apt/lists/*
# setup ENTRYPOINT
EXPOSE 8080 8545 8180
ENTRYPOINT ["/parity/parity"]

View File

@@ -1,42 +0,0 @@
FROM ubuntu:14.04
WORKDIR /build
# install tools and dependencies
RUN apt-get update && \
apt-get install -y \
g++ \
build-essential \
cmake \
curl \
git \
file \
binutils \
pkg-config \
libudev-dev
# install rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
# rustup directory
ENV PATH /root/.cargo/bin:$PATH
# show backtraces
ENV RUST_BACKTRACE 1
# show tools
RUN rustc -vV && \
cargo -V && \
gcc -v &&\
g++ -v
# build parity
ADD . /build/parity
RUN cd parity && \
cargo build --release --verbose && \
ls /build/parity/target/release/parity && \
strip /build/parity/target/release/parity
RUN file /build/parity/target/release/parity
EXPOSE 8080 8545 8180
ENTRYPOINT ["/build/parity/target/release/parity"]

View File

@@ -102,6 +102,8 @@ evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
slow-blocks = [] slow-blocks = []
# Run JSON consensus tests. # Run JSON consensus tests.
json-tests = ["ethcore-transaction/json-tests", "test-helpers", "tempdir"] json-tests = ["ethcore-transaction/json-tests", "test-helpers", "tempdir"]
# Skip JSON consensus tests with pending issues.
ci-skip-issue = []
# Run memory/cpu heavy tests. # Run memory/cpu heavy tests.
test-heavy = [] test-heavy = []
# Compile benches # Compile benches

View File

@@ -57,7 +57,7 @@ impl Finalize for Result<GasLeft> {
/// Cost calculation type. For low-gas usage we calculate costs using usize instead of U256 /// Cost calculation type. For low-gas usage we calculate costs using usize instead of U256
pub trait CostType: Sized + From<usize> + Copy pub trait CostType: Sized + From<usize> + Copy
+ ops::Mul<Output=Self> + ops::Div<Output=Self> + ops::Add<Output=Self> +ops::Sub<Output=Self> + ops::Mul<Output=Self> + ops::Div<Output=Self> + ops::Add<Output=Self> + ops::Sub<Output=Self>
+ ops::Shr<usize, Output=Self> + ops::Shl<usize, Output=Self> + ops::Shr<usize, Output=Self> + ops::Shl<usize, Output=Self>
+ cmp::Ord + fmt::Debug { + cmp::Ord + fmt::Debug {
/// Converts this cost into `U256` /// Converts this cost into `U256`

View File

@@ -134,6 +134,8 @@ enum_with_from_u8! {
RETURNDATASIZE = 0x3d, RETURNDATASIZE = 0x3d,
#[doc = "copy return data buffer to memory"] #[doc = "copy return data buffer to memory"]
RETURNDATACOPY = 0x3e, RETURNDATACOPY = 0x3e,
#[doc = "return the keccak256 hash of contract code"]
EXTCODEHASH = 0x3f,
#[doc = "get hash of most recent complete block"] #[doc = "get hash of most recent complete block"]
BLOCKHASH = 0x40, BLOCKHASH = 0x40,
@@ -326,7 +328,7 @@ enum_with_from_u8! {
#[doc = "like CALLCODE but keeps caller's value and sender"] #[doc = "like CALLCODE but keeps caller's value and sender"]
DELEGATECALL = 0xf4, DELEGATECALL = 0xf4,
#[doc = "create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160"] #[doc = "create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160"]
CREATE2 = 0xfb, CREATE2 = 0xf5,
#[doc = "stop execution and revert state changes. Return output data."] #[doc = "stop execution and revert state changes. Return output data."]
REVERT = 0xfd, REVERT = 0xfd,
#[doc = "like CALL but it does not take value, nor modify the state"] #[doc = "like CALL but it does not take value, nor modify the state"]
@@ -492,6 +494,7 @@ lazy_static! {
arr[CALLDATALOAD as usize] = Some(InstructionInfo::new("CALLDATALOAD", 1, 1, GasPriceTier::VeryLow)); arr[CALLDATALOAD as usize] = Some(InstructionInfo::new("CALLDATALOAD", 1, 1, GasPriceTier::VeryLow));
arr[CALLDATASIZE as usize] = Some(InstructionInfo::new("CALLDATASIZE", 0, 1, GasPriceTier::Base)); arr[CALLDATASIZE as usize] = Some(InstructionInfo::new("CALLDATASIZE", 0, 1, GasPriceTier::Base));
arr[CALLDATACOPY as usize] = Some(InstructionInfo::new("CALLDATACOPY", 3, 0, GasPriceTier::VeryLow)); arr[CALLDATACOPY as usize] = Some(InstructionInfo::new("CALLDATACOPY", 3, 0, GasPriceTier::VeryLow));
arr[EXTCODEHASH as usize] = Some(InstructionInfo::new("EXTCODEHASH", 1, 1, GasPriceTier::Special));
arr[CODESIZE as usize] = Some(InstructionInfo::new("CODESIZE", 0, 1, GasPriceTier::Base)); arr[CODESIZE as usize] = Some(InstructionInfo::new("CODESIZE", 0, 1, GasPriceTier::Base));
arr[CODECOPY as usize] = Some(InstructionInfo::new("CODECOPY", 3, 0, GasPriceTier::VeryLow)); arr[CODECOPY as usize] = Some(InstructionInfo::new("CODECOPY", 3, 0, GasPriceTier::VeryLow));
arr[GASPRICE as usize] = Some(InstructionInfo::new("GASPRICE", 0, 1, GasPriceTier::Base)); arr[GASPRICE as usize] = Some(InstructionInfo::new("GASPRICE", 0, 1, GasPriceTier::Base));
@@ -591,7 +594,7 @@ lazy_static! {
arr[DELEGATECALL as usize] = Some(InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special)); arr[DELEGATECALL as usize] = Some(InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special));
arr[STATICCALL as usize] = Some(InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special)); arr[STATICCALL as usize] = Some(InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special));
arr[SUICIDE as usize] = Some(InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special)); arr[SUICIDE as usize] = Some(InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special));
arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 3, 1, GasPriceTier::Special)); arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 4, 1, GasPriceTier::Special));
arr[REVERT as usize] = Some(InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero)); arr[REVERT as usize] = Some(InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero));
arr arr
}; };

View File

@@ -125,12 +125,17 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
let newval = stack.peek(1); let newval = stack.peek(1);
let val = U256::from(&*ext.storage_at(&address)?); let val = U256::from(&*ext.storage_at(&address)?);
let gas = if val.is_zero() && !newval.is_zero() { let gas = if schedule.eip1283 {
schedule.sstore_set_gas let orig = U256::from(&*ext.initial_storage_at(&address)?);
calculate_eip1283_sstore_gas(schedule, &orig, &val, &newval)
} else { } else {
// Refund for below case is added when actually executing sstore if val.is_zero() && !newval.is_zero() {
// !is_zero(&val) && is_zero(newval) schedule.sstore_set_gas
schedule.sstore_reset_gas } else {
// Refund for below case is added when actually executing sstore
// !is_zero(&val) && is_zero(newval)
schedule.sstore_reset_gas
}
}; };
Request::Gas(Gas::from(gas)) Request::Gas(Gas::from(gas))
}, },
@@ -143,6 +148,9 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
instructions::EXTCODESIZE => { instructions::EXTCODESIZE => {
Request::Gas(Gas::from(schedule.extcodesize_gas)) Request::Gas(Gas::from(schedule.extcodesize_gas))
}, },
instructions::EXTCODEHASH => {
Request::Gas(Gas::from(schedule.extcodehash_gas))
},
instructions::SUICIDE => { instructions::SUICIDE => {
let mut gas = Gas::from(schedule.suicide_gas); let mut gas = Gas::from(schedule.suicide_gas);
@@ -168,9 +176,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
Request::GasMem(default_gas, mem_needed(stack.peek(0), stack.peek(1))?) Request::GasMem(default_gas, mem_needed(stack.peek(0), stack.peek(1))?)
}, },
instructions::SHA3 => { instructions::SHA3 => {
let w = overflowing!(add_gas_usize(Gas::from_u256(*stack.peek(1))?, 31)); let words = overflowing!(to_word_size(Gas::from_u256(*stack.peek(1))?));
let words = w >> 5; let gas = overflowing!(Gas::from(schedule.sha3_gas).overflow_add(overflowing!(Gas::from(schedule.sha3_word_gas).overflow_mul(words))));
let gas = Gas::from(schedule.sha3_gas) + (Gas::from(schedule.sha3_word_gas) * words);
Request::GasMem(gas, mem_needed(stack.peek(0), stack.peek(1))?) Request::GasMem(gas, mem_needed(stack.peek(0), stack.peek(1))?)
}, },
instructions::CALLDATACOPY | instructions::CODECOPY | instructions::RETURNDATACOPY => { instructions::CALLDATACOPY | instructions::CODECOPY | instructions::RETURNDATACOPY => {
@@ -223,9 +230,24 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
Request::GasMemProvide(gas, mem, Some(requested)) Request::GasMemProvide(gas, mem, Some(requested))
}, },
instructions::CREATE | instructions::CREATE2 => { instructions::CREATE => {
let start = stack.peek(1);
let len = stack.peek(2);
let gas = Gas::from(schedule.create_gas); let gas = Gas::from(schedule.create_gas);
let mem = mem_needed(stack.peek(1), stack.peek(2))?; let mem = mem_needed(start, len)?;
Request::GasMemProvide(gas, mem, None)
},
instructions::CREATE2 => {
let start = stack.peek(1);
let len = stack.peek(2);
let base = Gas::from(schedule.create_gas);
let word = overflowing!(to_word_size(Gas::from_u256(*len)?));
let word_gas = overflowing!(Gas::from(schedule.sha3_word_gas).overflow_mul(word));
let gas = overflowing!(base.overflow_add(word_gas));
let mem = mem_needed(start, len)?;
Request::GasMemProvide(gas, mem, None) Request::GasMemProvide(gas, mem, None)
}, },
@@ -275,8 +297,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
}, },
Request::GasMemCopy(gas, mem_size, copy) => { Request::GasMemCopy(gas, mem_size, copy) => {
let (mem_gas_cost, new_mem_gas, new_mem_size) = self.mem_gas_cost(schedule, current_mem_size, &mem_size)?; let (mem_gas_cost, new_mem_gas, new_mem_size) = self.mem_gas_cost(schedule, current_mem_size, &mem_size)?;
let copy = overflowing!(add_gas_usize(copy, 31)) >> 5; let copy = overflowing!(to_word_size(copy));
let copy_gas = Gas::from(schedule.copy_gas) * copy; let copy_gas = overflowing!(Gas::from(schedule.copy_gas).overflow_mul(copy));
let gas = overflowing!(gas.overflow_add(copy_gas)); let gas = overflowing!(gas.overflow_add(copy_gas));
let gas = overflowing!(gas.overflow_add(mem_gas_cost)); let gas = overflowing!(gas.overflow_add(mem_gas_cost));
@@ -303,7 +325,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
}; };
let current_mem_size = Gas::from(current_mem_size); let current_mem_size = Gas::from(current_mem_size);
let req_mem_size_rounded = (overflowing!(mem_size.overflow_add(Gas::from(31 as usize))) >> 5) << 5; let req_mem_size_rounded = overflowing!(to_word_size(*mem_size)) << 5;
let (mem_gas_cost, new_mem_gas) = if req_mem_size_rounded > current_mem_size { let (mem_gas_cost, new_mem_gas) = if req_mem_size_rounded > current_mem_size {
let new_mem_gas = gas_for_mem(req_mem_size_rounded)?; let new_mem_gas = gas_for_mem(req_mem_size_rounded)?;
@@ -335,6 +357,99 @@ fn add_gas_usize<Gas: evm::CostType>(value: Gas, num: usize) -> (Gas, bool) {
value.overflow_add(Gas::from(num)) value.overflow_add(Gas::from(num))
} }
#[inline]
fn to_word_size<Gas: evm::CostType>(value: Gas) -> (Gas, bool) {
let (gas, overflow) = add_gas_usize(value, 31);
if overflow {
return (gas, overflow);
}
(gas >> 5, false)
}
#[inline]
fn calculate_eip1283_sstore_gas<Gas: evm::CostType>(schedule: &Schedule, original: &U256, current: &U256, new: &U256) -> Gas {
Gas::from(
if current == new {
// 1. If current value equals new value (this is a no-op), 200 gas is deducted.
schedule.sload_gas
} else {
// 2. If current value does not equal new value
if original == current {
// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context)
if original.is_zero() {
// 2.1.1. If original value is 0, 20000 gas is deducted.
schedule.sstore_set_gas
} else {
// 2.1.2. Otherwise, 5000 gas is deducted.
schedule.sstore_reset_gas
// 2.1.2.1. If new value is 0, add 15000 gas to refund counter.
}
} else {
// 2.2. If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses.
schedule.sload_gas
// 2.2.1. If original value is not 0
// 2.2.1.1. If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0.
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter.
// 2.2.2. If original value equals new value (this storage slot is reset)
// 2.2.2.1. If original value is 0, add 19800 gas to refund counter.
// 2.2.2.2. Otherwise, add 4800 gas to refund counter.
}
}
)
}
pub fn handle_eip1283_sstore_clears_refund(ext: &mut vm::Ext, original: &U256, current: &U256, new: &U256) {
let sstore_clears_schedule = U256::from(ext.schedule().sstore_refund_gas);
if current == new {
// 1. If current value equals new value (this is a no-op), 200 gas is deducted.
} else {
// 2. If current value does not equal new value
if original == current {
// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context)
if original.is_zero() {
// 2.1.1. If original value is 0, 20000 gas is deducted.
} else {
// 2.1.2. Otherwise, 5000 gas is deducted.
if new.is_zero() {
// 2.1.2.1. If new value is 0, add 15000 gas to refund counter.
ext.add_sstore_refund(sstore_clears_schedule);
}
}
} else {
// 2.2. If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses.
if !original.is_zero() {
// 2.2.1. If original value is not 0
if current.is_zero() {
// 2.2.1.1. If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0.
ext.sub_sstore_refund(sstore_clears_schedule);
} else if new.is_zero() {
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter.
ext.add_sstore_refund(sstore_clears_schedule);
}
}
if original == new {
// 2.2.2. If original value equals new value (this storage slot is reset)
if original.is_zero() {
// 2.2.2.1. If original value is 0, add 19800 gas to refund counter.
let refund = U256::from(ext.schedule().sstore_set_gas - ext.schedule().sload_gas);
ext.add_sstore_refund(refund);
} else {
// 2.2.2.2. Otherwise, add 4800 gas to refund counter.
let refund = U256::from(ext.schedule().sstore_reset_gas - ext.schedule().sload_gas);
ext.add_sstore_refund(refund);
}
}
}
}
}
#[test] #[test]
fn test_mem_gas_cost() { fn test_mem_gas_cost() {
// given // given

View File

@@ -186,8 +186,7 @@ impl<Cost: CostType> vm::Vm for Interpreter<Cost> {
match result { match result {
InstructionResult::JumpToPosition(position) => { InstructionResult::JumpToPosition(position) => {
if valid_jump_destinations.is_none() { if valid_jump_destinations.is_none() {
let code_hash = params.code_hash.clone().unwrap_or_else(|| keccak(code.as_ref())); valid_jump_destinations = Some(self.cache.jump_destinations(&params.code_hash, code));
valid_jump_destinations = Some(self.cache.jump_destinations(&code_hash, code));
} }
let jump_destinations = valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed"); let jump_destinations = valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed");
let pos = self.verify_jump(position, jump_destinations)?; let pos = self.verify_jump(position, jump_destinations)?;
@@ -230,8 +229,9 @@ impl<Cost: CostType> Interpreter<Cost> {
(instruction == instructions::STATICCALL && !schedule.have_static_call) || (instruction == instructions::STATICCALL && !schedule.have_static_call) ||
((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) ||
((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) { ((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) ||
(instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash)
{
return Err(vm::Error::BadInstruction { return Err(vm::Error::BadInstruction {
instruction: instruction as u8 instruction: instruction as u8
}); });
@@ -318,6 +318,11 @@ impl<Cost: CostType> Interpreter<Cost> {
let endowment = stack.pop_back(); let endowment = stack.pop_back();
let init_off = stack.pop_back(); let init_off = stack.pop_back();
let init_size = stack.pop_back(); let init_size = stack.pop_back();
let address_scheme = match instruction {
instructions::CREATE => CreateContractAddress::FromSenderAndNonce,
instructions::CREATE2 => CreateContractAddress::FromSenderSaltAndCodeHash(stack.pop_back().into()),
_ => unreachable!("instruction can only be CREATE/CREATE2 checked above; qed"),
};
let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed"); let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed");
@@ -335,7 +340,6 @@ impl<Cost: CostType> Interpreter<Cost> {
} }
let contract_code = self.mem.read_slice(init_off, init_size); let contract_code = self.mem.read_slice(init_off, init_size);
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme); let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme);
return match create_result { return match create_result {
@@ -510,8 +514,14 @@ impl<Cost: CostType> Interpreter<Cost> {
let current_val = U256::from(&*ext.storage_at(&address)?); let current_val = U256::from(&*ext.storage_at(&address)?);
// Increase refund for clear // Increase refund for clear
if !self.is_zero(&current_val) && self.is_zero(&val) { if ext.schedule().eip1283 {
ext.inc_sstore_clears(); let original_val = U256::from(&*ext.initial_storage_at(&address)?);
gasometer::handle_eip1283_sstore_clears_refund(ext, &original_val, &current_val, &val);
} else {
if !current_val.is_zero() && val.is_zero() {
let sstore_clears_schedule = U256::from(ext.schedule().sstore_refund_gas);
ext.add_sstore_refund(sstore_clears_schedule);
}
} }
ext.set_storage(address, H256::from(&val))?; ext.set_storage(address, H256::from(&val))?;
}, },
@@ -568,9 +578,14 @@ impl<Cost: CostType> Interpreter<Cost> {
}, },
instructions::EXTCODESIZE => { instructions::EXTCODESIZE => {
let address = u256_to_address(&stack.pop_back()); let address = u256_to_address(&stack.pop_back());
let len = ext.extcodesize(&address)?; let len = ext.extcodesize(&address)?.unwrap_or(0);
stack.push(U256::from(len)); stack.push(U256::from(len));
}, },
instructions::EXTCODEHASH => {
let address = u256_to_address(&stack.pop_back());
let hash = ext.extcodehash(&address)?.unwrap_or_else(H256::zero);
stack.push(U256::from(hash));
},
instructions::CALLDATACOPY => { instructions::CALLDATACOPY => {
Self::copy_data_to_memory(&mut self.mem, stack, params.data.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8])); Self::copy_data_to_memory(&mut self.mem, stack, params.data.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8]));
}, },
@@ -591,7 +606,11 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::EXTCODECOPY => { instructions::EXTCODECOPY => {
let address = u256_to_address(&stack.pop_back()); let address = u256_to_address(&stack.pop_back());
let code = ext.extcode(&address)?; let code = ext.extcode(&address)?;
Self::copy_data_to_memory(&mut self.mem, stack, &code); Self::copy_data_to_memory(
&mut self.mem,
stack,
code.as_ref().map(|c| &(*c)[..]).unwrap_or(&[])
);
}, },
instructions::GASPRICE => { instructions::GASPRICE => {
stack.push(params.gas_price.clone()); stack.push(params.gas_price.clone());

View File

@@ -50,17 +50,22 @@ impl SharedCache {
} }
/// Get jump destinations bitmap for a contract. /// Get jump destinations bitmap for a contract.
pub fn jump_destinations(&self, code_hash: &H256, code: &[u8]) -> Arc<BitSet> { pub fn jump_destinations(&self, code_hash: &Option<H256>, code: &[u8]) -> Arc<BitSet> {
if code_hash == &KECCAK_EMPTY { if let Some(ref code_hash) = code_hash {
return Self::find_jump_destinations(code); if code_hash == &KECCAK_EMPTY {
} return Self::find_jump_destinations(code);
}
if let Some(d) = self.jump_destinations.lock().get_mut(code_hash) { if let Some(d) = self.jump_destinations.lock().get_mut(code_hash) {
return d.0.clone(); return d.0.clone();
}
} }
let d = Self::find_jump_destinations(code); let d = Self::find_jump_destinations(code);
self.jump_destinations.lock().insert(code_hash.clone(), Bits(d.clone()));
if let Some(ref code_hash) = code_hash {
self.jump_destinations.lock().insert(*code_hash, Bits(d.clone()));
}
d d
} }

View File

@@ -716,7 +716,7 @@ fn test_jumps(factory: super::Factory) {
test_finalize(vm.exec(params, &mut ext)).unwrap() test_finalize(vm.exec(params, &mut ext)).unwrap()
}; };
assert_eq!(ext.sstore_clears, 1); assert_eq!(ext.sstore_clears, U256::from(ext.schedule.sstore_refund_gas));
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000"); // 5! assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000"); // 5!
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000078"); // 5! assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000078"); // 5!
assert_eq!(gas_left, U256::from(54_117)); assert_eq!(gas_left, U256::from(54_117));
@@ -746,6 +746,7 @@ fn test_calls(factory: super::Factory) {
assert_set_contains(&ext.calls, &FakeCall { assert_set_contains(&ext.calls, &FakeCall {
call_type: FakeCallType::Call, call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(2556), gas: U256::from(2556),
sender_address: Some(address.clone()), sender_address: Some(address.clone()),
receive_address: Some(code_address.clone()), receive_address: Some(code_address.clone()),
@@ -755,6 +756,7 @@ fn test_calls(factory: super::Factory) {
}); });
assert_set_contains(&ext.calls, &FakeCall { assert_set_contains(&ext.calls, &FakeCall {
call_type: FakeCallType::Call, call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(2556), gas: U256::from(2556),
sender_address: Some(address.clone()), sender_address: Some(address.clone()),
receive_address: Some(address.clone()), receive_address: Some(address.clone()),

View File

@@ -127,9 +127,6 @@ pub trait LightChainClient: Send + Sync {
/// Get the `i`th CHT root. /// Get the `i`th CHT root.
fn cht_root(&self, i: usize) -> Option<H256>; fn cht_root(&self, i: usize) -> Option<H256>;
/// Get the EIP-86 transition block number.
fn eip86_transition(&self) -> BlockNumber;
/// Get a report of import activity since the last call. /// Get a report of import activity since the last call.
fn report(&self) -> ClientReport; fn report(&self) -> ClientReport;
} }
@@ -585,10 +582,6 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
Client::cht_root(self, i) Client::cht_root(self, i)
} }
fn eip86_transition(&self) -> BlockNumber {
self.engine().params().eip86_transition
}
fn report(&self) -> ClientReport { fn report(&self) -> ClientReport {
Client::report(self) Client::report(self)
} }

View File

@@ -6,10 +6,10 @@
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000", "blockReward": "0x29A2241AF62C0000",
"homesteadTransition": "0x0", "homesteadTransition": "0x0",
"eip649Reward": "0x29A2241AF62C0000",
"eip100bTransition": "0x0", "eip100bTransition": "0x0",
"eip649Reward": "0x29A2241AF62C0000",
"eip649Transition": "0x0" "eip649Transition": "0x0"
} }
} }

View File

@@ -31,8 +31,7 @@
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip155Transition": 3000000, "eip155Transition": 3000000,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff"
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@@ -1,16 +1,18 @@
{ {
"name": "Byzantium (Test)", "name": "Constantinople (test)",
"engine": { "engine": {
"Ethash": { "Ethash": {
"params": { "params": {
"minimumDifficulty": "0x020000", "minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800", "difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000", "blockReward": "0x29A2241AF62C0000",
"homesteadTransition": "0x0", "homesteadTransition": "0x0",
"eip649Reward": "0x29A2241AF62C0000",
"eip100bTransition": "0x0", "eip100bTransition": "0x0",
"eip649Transition": "0x0" "eip649Transition": "0x5",
"eip649Reward": "0x1BC16D674EC80000",
"eip1234Transition": "0x5",
"eip1234Reward": "0x1BC16D674EC80000"
} }
} }
}, },
@@ -29,11 +31,14 @@
"eip161abcTransition": "0x0", "eip161abcTransition": "0x0",
"eip161dTransition": "0x0", "eip161dTransition": "0x0",
"eip140Transition": "0x0", "eip140Transition": "0x0",
"eip210Transition": "0x0",
"eip211Transition": "0x0", "eip211Transition": "0x0",
"eip214Transition": "0x0", "eip214Transition": "0x0",
"eip155Transition": "0x0", "eip155Transition": "0x0",
"eip658Transition": "0x0" "eip658Transition": "0x0",
"eip145Transition": "0x0",
"eip1014Transition": "0x0",
"eip1052Transition": "0x0",
"eip1283Transition": "0x0"
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@@ -54,9 +59,9 @@
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 100 } } } }, "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } }, "0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 2000, "word": 0 } } } }, "0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } } "0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
} }
} }

View File

@@ -27,8 +27,7 @@
"eip155Transition": "0x0", "eip155Transition": "0x0",
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff"
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@@ -23,7 +23,6 @@
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip98Transition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff",
"eip155Transition": "0x7fffffffffffffff", "eip155Transition": "0x7fffffffffffffff",
"maxCodeSize": 24576, "maxCodeSize": 24576,
"maxCodeSizeTransition": "0x7fffffffffffffff" "maxCodeSizeTransition": "0x7fffffffffffffff"

View File

@@ -23,8 +23,7 @@
"eip161abcTransition": "0x0", "eip161abcTransition": "0x0",
"eip161dTransition": "0x0", "eip161dTransition": "0x0",
"eip98Transition": "0x7fffffffffffffff", "eip98Transition": "0x7fffffffffffffff",
"eip86Transition": "0x7fffffffffffffff", "eip155Transition": "0x0",
"eip155Transition": "0x7fffffffffffffff",
"maxCodeSize": 24576, "maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0" "maxCodeSizeTransition": "0x0"
}, },

View File

@@ -0,0 +1,54 @@
{
"name": "EIP210 (test)",
"engine": {
"Ethash": {
"params": {
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"homesteadTransition": "0x0"
}
}
},
"params": {
"gasLimitBoundDivisor": "0x0400",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x1",
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0",
"eip98Transition": "0xffffffffffffffff",
"eip150Transition": "0x0",
"eip160Transition": "0x0",
"eip161abcTransition": "0x0",
"eip161dTransition": "0x0",
"eip210Transition": "0x0"
},
"genesis": {
"seal": {
"ethereum": {
"nonce": "0x0000000000000042",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x400000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 100 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 2000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
}
}

View File

@@ -29,7 +29,6 @@
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip155Transition": "0x0", "eip155Transition": "0x0",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"wasmActivationTransition": 2000000, "wasmActivationTransition": 2000000,
"eip140Transition": 2000000, "eip140Transition": 2000000,
"eip211Transition": 2000000, "eip211Transition": 2000000,

View File

@@ -38,7 +38,6 @@
"eip161abcTransition": "0x927C0", "eip161abcTransition": "0x927C0",
"eip161dTransition": "0x927C0", "eip161dTransition": "0x927C0",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x927C0", "eip155Transition": "0x927C0",
"eip140Transition": "0xC3500", "eip140Transition": "0xC3500",
"eip211Transition": "0xC3500", "eip211Transition": "0xC3500",

View File

@@ -150,7 +150,6 @@
"eip161dTransition": 2675000, "eip161dTransition": 2675000,
"eip155Transition": 2675000, "eip155Transition": 2675000,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"maxCodeSize": 24576, "maxCodeSize": 24576,
"maxCodeSizeTransition": 2675000, "maxCodeSizeTransition": 2675000,
"eip140Transition": 4370000, "eip140Transition": 4370000,
@@ -174,8 +173,8 @@
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
}, },
"hardcodedSync": { "hardcodedSync": {
"header": "f9020ba0c7139a7f4b14c2e12dbe34aeb92711b37747bf8698ecdd6f2c3b1f5f3840e288a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452e44f279f4203dcf680395379e5f9990a69f13ca06e817f8a9b206f93a393da76a3ece2a74b98eaecc4dae0cfa8f409455e88ccb4a0d739197170d2bc6bbb24fac0ce695982090702082fe1541bb7634f018dfe87b3a038503b7299fb1c113a78b4a3a5dfd997ef32e7fbf722fc178dfcb21e1af1f7f5b9010000020000000000000008000000000010000000000000000000000000000200000002000000000008000000000000000000000000000000000000000000000000000000000000000001004008000000000000000000000000000080000000000008000000080000000000008000000000000000000000000000040210004000000010000000400000000001040000000200000000000000440008000000040000000000000000000000000010000000000000000000000000000000800000000000100002000000000000000000002000000000000000000000000000000000000080000000100000000000000000040400000000000000004000000000000000870c90e059b181c6835ee8018379fb9583065150845b833d198a7777772e62772e636f6da0171fc2d066507ea10c8c2d7bedd5ccc3f0dfb4d590a3998a614013326c0b213a88b4fd884826187393", "header": "f90206a0391c42ff4f047145a6b9a14179c3cc404b31d92f30693e28cf2bba41f47f6329a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2930b35844a230f00e51431acae96fe543a0347a0fb280d4457e60a0b96577e1dde9e00905102cfd36def5c5b31dcc2284636136ea077f739c324e35c7448b14aa02186973d3c74cc1ab081498cd0c487a604873723a0e462d76b5204d14b13d1f1b39ea048a3b637f91d42c729c367d5bbdbd0a72d70b90100008003410402005000200009400030c40490500208480008414000a40048806408000080802008204400010001800c0020080c0a00400105a9080820400900240000084012030a1504030508000200005c4404a0c3490820000010400811040004708a1006910211444040c28001a800e920d00000940c200119111a10401001008044214002002080c21081801e008a320848a204400042400898004004010028840181106210080254a081112480031000410202440092c880be3894000120050500860880000108000c0080009e0000204007212840808cb80200601024020000210280100c018540b28a1041a62400000108204084000008808040000004870bc009a1914d7f8362f801837a121d8379ee5a845bbd53ca8573696e6731a0abce0f90ce69f740080eeb94d1cb13981fafe3bc6d020a44815acd86cbd3fc0a889501b04c0614e053",
"totalDifficulty": "6255555800944520547241", "totalDifficulty": "7128515864594819065361",
"CHTs": [ "CHTs": [
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11", "0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
@@ -3213,7 +3212,137 @@
"0xf344c0cf6516f0fa6617e48076726aefbdaaf5a31f67ad8199bc3f6e426bf904", "0xf344c0cf6516f0fa6617e48076726aefbdaaf5a31f67ad8199bc3f6e426bf904",
"0x3f3d2d33f36ba9009e9a72f3f5bbcb5df5392a19fc7afc8d37823aaf52b03477", "0x3f3d2d33f36ba9009e9a72f3f5bbcb5df5392a19fc7afc8d37823aaf52b03477",
"0x346a89411f090d559ff90e670bf0a385b1b09f117fc9ffa18b09d3b6d5d8e45c", "0x346a89411f090d559ff90e670bf0a385b1b09f117fc9ffa18b09d3b6d5d8e45c",
"0x5bc5689e2b4572b8ceea472cc7827e22cbfd018920beebf5c5b25f65f5cd5357" "0x5bc5689e2b4572b8ceea472cc7827e22cbfd018920beebf5c5b25f65f5cd5357",
"0xda418efcaa0076f77e4d2f0c57fc32fa67179a5631d9df52d56497113d0e87af",
"0x5a8050832e835202695129f6f384652827e61ea5f1be7ff300183201d8bd6b4d",
"0xd9f444c382da42c310bd2f05955187163ae7b224e5efd44ab95af332e197d374",
"0x9ef2c5bad361117eedbc2adcb72a2ef5eba4caf3a99a0cbb2a65a94d185e48ae",
"0x7e3e089bc46b00a4174d90003379c382ab5bd84d092b9c4db3189d2bdc24f00b",
"0x94f50fb12eed909d251fe69adb1a1f214776cb029d487360b55c3a2abb663d7e",
"0xd3e1f4244dea40d0741255db2dae72103e263390e0ccfdefcbb2da59ecc5ec9f",
"0x6808bf0cb7d4b677527de762b6db8ddf74a1b272349f34f44505912bd95d62f3",
"0xbf7672ac474b5b849bc086ff8455216f015c8fc7660436dee153522ef6991c04",
"0xe79d27a369cdd5455ddbc6bd9158cd1870aa895b3c3971d07f1555b95ed02ac3",
"0xfa9e20a36c11b0dfbf7e9c62872a6423f5460dfd18e447481461a41176678262",
"0xaafb6c407910341bedc82c0f260cdef75ce5653f644b93a465cb990247a32986",
"0x5058e655e0c179e6c20f48fbd08c2f34f9341f6c07972ff40f55bfabbc783b12",
"0x28d2e7c852de8602a764ff693b6881af18ddadd67fc7eff481f48ac20ebf32f6",
"0xf82e09e7916f61b5cfdc3dcf193bf9d535f2b33f93a06c90fbdc78b3aac6b7ef",
"0x626f3cca9e1a9e5e123e34485c8697c758ffc32213a727665065dd6abd2babe5",
"0xb7f1c07f673d903daa61dec649eb12286a7a0568ee36ecfb1023ec41427c8dd0",
"0x8d1d42bfe88dbe4c621cf68d380dc57e7768121a815546bb4aab29b7486da9ee",
"0x79835acd7266bce85978f481aa3c58f3bab9106d72892df8579e472dc95c6899",
"0x0911c9c804bbe9be0aebab6c92f5b71a893f72a9d0cd35a51b0e8cd19ab0c02a",
"0x7fd2eff10936d8d12fd9a1c6d27e77cbec4e48253465eb7e65876134ff60c8ec",
"0xc739ad4255415e2831c6996673f3d02dc79f6e6d6822f7dee23bff5b94833c3a",
"0x2559faafbae0852fe5a1c924f0e4f6ccdf4fd22f483148b3672a3e7b3692b669",
"0xca37f0aa3d375dbddc0b426c9564fe68f10b0a4cbbf1ab87f97b27b44878f2fb",
"0x00ba40205d1bd46ad5b5e73cd5b1f3418bd892586d5a4647ac9a6d158f15bd93",
"0xfa6d25c829299535e6b80af81a2416d10ed6903117e73c656b979a5f5abe3ee0",
"0xfd82d8944315cfb228a8fa416c18ff82cbd8869c3babbd3389dca6dd66797785",
"0xd8834cc29788cb40ec901725419df8c031a13e190756a6352696de870eaf4671",
"0xdf6843a52bf55e0f4404e7bdf144bb17d5c47a72ef9482e712090ac9730a7f52",
"0x4c2c562f835966c72985f7cca89a3b1a7b0d4cb04623dc96e337daa35a2f5925",
"0x49d2afd87e83a04059dbf3ef4e2598b8d0c495ab1cf91ed3004e16a608e910c2",
"0x5be64774739c001c239efae1ce9f2a5706cc6e3054ddf24b03c09358f2f4852f",
"0x678f789dc8c409653b36f4d2015338165d3bc6a73f2a77ebfe438676b8412d7a",
"0xf87c8fbf02d8e84cf72680e6b9a8b8be39fbae9f1eb1047c536d77535494a301",
"0xe2428b952d2c6d60d4925f56b3d8227cd6bc608da2c1b20264befd8b1ad89454",
"0x561a95eb50c663462bb8af3aab336bd745b0571746b10fefa791bc11be777763",
"0x6945f40e3499d2769ceecf499c701015d93fddb607720b18dbbd5a6a2aa46639",
"0x9c35b0367a2b82270d64f11c5299336b21b9f454077dcf7af3b2e434677a31b6",
"0x454dc6bb2443509381e478f1836cb36808e2ecd1a9944072056c292b710072f4",
"0x0c80566f34a46477592560a883a9c01fa393f7a2c9dbb28a54e46a5c017e8596",
"0xeff6a1255090509eccfdea2e591516886c91191f1f02eaae4808ac95009086fc",
"0x37cf60888e5ec75841e7f0533feef7200185a1c9f3253073216d83923c864829",
"0xb169ebb9e418809a96529835bc293782e4fc6310dba450afe3e95a7abdf7cc01",
"0xa3c8d5c71ce0477a247f56bfe95272ea07f0b7f10a8526b6e3ff9a8de8faa9ab",
"0x2bf18db4ee84bafbbabaf05d1d4d383c0d5fc91be6ae902334496996eb3a8e48",
"0x6c116f0d5809a2c28351a737ef3dbd1808685e1fd656e37df6b6e524aa82c918",
"0x21e2c8e019c687fdb360c9bdd4e3a5133488cd2e0365aee3b823120734aa6f27",
"0x20c9a1db9de894ab4f576265da25f391b32c0805c3da76fbfdd0aaf300f88a39",
"0x23ef1f43af87be7396449fc1f89d9766c59e8adf2660812293c65a27482ddb8e",
"0x04a82d3a4a5e7f2507688ecdcdc300d7fb97aa8be92a671d7d42c0b60fa4532b",
"0x99e204c42afd6d4040faad384517d99bd0e077b03310d32223234d2251d6a07c",
"0xe342c0c4295665b9e25773fc9998e18c460e723d0a14efdb59c19b27b9c7011b",
"0xb654b1b8ede0d54a605cda54b4635d2b3c2bb8efd01ebd416e52cc87b590d4f3",
"0x5daabc41eeb6de98336411a03ec0323995e81549941cf32b7e15c765d1b7b39e",
"0x5103fc7f0fc6df43fb081b580bb01476f2b1cbde73e4d0f9d1fa6d8427fae789",
"0xe2ecf5daba51d2f7b22106033fc43f956bd1db0c5ad02bd941bd3d2b96ca21c5",
"0xf152bce5c6d1efb7e22cde72d6b8ca37f556ffb686a13770c5fab46e04837c92",
"0x306007d8091caa5baaa78643307f5abf9a5f03996fc072a9016ba6b487b2017c",
"0xf57308d0c02c6b8e2416c070554c7e29911fa84ef4cf2d934e2322ca262e987c",
"0xb234fe7433d7fd71fe0c6dfc834e4bcbf84a261b95760a6c4eb67d222b9ff392",
"0x753059f3405f60da3aa7cd1aa0cbcfa4d5ef4f2a6ed34b853b2c5ab2181fd383",
"0x096c6630e821816d9f4bd83fbe0ccfd223282f34aae5a49f969ba30b98c324c3",
"0xd3eec9dedb057fbc839c474fc99cb54d89f3f47d896e06e758c98f1cd194b61f",
"0x0d44cb2a83b9a3fa18daac280cf08b46cc637d705488fd9400cd7300475d0a1c",
"0x2e37a3036db99c4cb1c135f5ca6b527fa13b2e80ee421805b7be5d8b16983602",
"0x381e0ca505308b7d3a083e60b0f9cb44c89f84942430ec9e4c5571796ab6a8eb",
"0x90b04d35906c6f5a59c266c3bce7c2b63cea1486f714e272592ef9ecab25b0ee",
"0x9cbea70e760f2ee97537d058d57f395886a2c3a6e769ccd3433b797b8716517b",
"0x4e2167846e8d6f0f6495b5f1443f59bea143b63f242e40186fc6429434d1136e",
"0xcaa0512739d000bb9783fceb46d0427098886e2b7f2e1140855f1a91f843d5b3",
"0xc14df4e379e84591f618e60b5953aa6764146c7822aa1f0e3c2287e20753985a",
"0xf4443154c04fd378b2c3812fee84b774b37d6e12778674403fb5c995379df866",
"0x1a501c2733cc138fb6ff3716899e08dbcd4d75edc18af8972e8a749e45eaf67a",
"0xfc8cb80bb0d0fb490f29aae3067641eef72e9225c558e7e299e0796a2086969d",
"0x2b7895550febf03070485c02d521e7ddd80b94b7fe33a60b7d7ea3545b13e7dd",
"0xfc4137c3cccd45050b5770a40b2f38c43c62b70b07d17bb6d762b405f3d753dc",
"0x86ed22bbbb9fc6600112b91601af4fff56d0ecbe9b3099f91d4477cab8e300f5",
"0x2273a60405ffb04bd024d880c79010f18d58e3c8ca0dc82795a0125364679fa6",
"0x00dfbfe7be3bb2116d9a603a01ac428c0088a2c1477810cd5d3be0d1bd86beab",
"0x7acfb03315585c79e2a47dbe847d24cab0785791f6af7f179fea4f9d6ecb0e0f",
"0xbf6a2e20ee1da5eec12b792bbaec2531e20766ba54bac423011c1057215851db",
"0xb5e94d1e3ba7363d1d79fb62dedd0b6c26b0485052dd64a7093d41ad2d41b890",
"0x9b0cc26f08708814960de8f280ac26d8ed5089a19bcbd2d765059306da22c196",
"0x22d8af121d3e395d3cb4f6ee43c06e6292f1b5ffda672d2e40dba69a2885f5ac",
"0x04bc174272a57189d76aa17de0f76806e8481f4903575ed8c4df12b042637e0e",
"0x06ebd2b6ec4b80280969a92726df5f9cb12d4288b60af617b7040876116656d3",
"0x0e9430513e63b5173271c89b1c91af0b4818d5d14a3034e1228c56c94186a109",
"0x8dc5422ba98d9e58112b052a00d4b82b1db32e22dd7ff2d845619899bd47f277",
"0xde513d40bdbb1e4956b468cece598d77134626a900066b92fb2ecd6fcb5f81c2",
"0x90746299ec75af1eb444ad14ac666ee444aa020fac3fb57796516d8772ec8f45",
"0xaa91c30c62b24f943ee1eec7586b682289541c0355c2726e44424da8686ca24d",
"0x76eb68baae9fb7ed126097f93842dcadfe6e7188d61549d9c0922a9b3ef8e80a",
"0x5aa5b4045e7fe71559a6e93f4a89b135eaef38b9a7f3a84e383ab1ff902ceca9",
"0x504b78f8fc3646e9722e96a5e97d99f2560d4fa3337fa5faf1cc8c8a05f3520d",
"0xffd7a5d7c3b21e8144f7678a9ddc039cf85eb32b09000a600c9f12aa7d6083ed",
"0xcbb4010000e96ff0b50b9627dae032bd50782ccbd51af8af7cfcd6cd184675f7",
"0xb96fabbdd02371bf4a6a0dc00e3874cf43d47246e27163c910c141b6759a4249",
"0x7358419f4e994ff296a37f2e88b238b3de6ba73062073c9467dec52a2df64422",
"0xca90be9f190a1fd0548becfa719a6e4763e92de0e4da4283a33b5f7d2886b425",
"0xa629364f7d6329b008d9c6a0262327bcc12953aa515cdb7b8817e7fe1d746d46",
"0xc5167bd8cac1ea6d14f305c9d4fe075e1875d96353e5236473b6daca5ae9b4fe",
"0xaf4ce2490e9504172a4393cf14e691e947c86a0ec7b53416384a5832b213d6c5",
"0xbfa4853ef2eecc5d99a90e1abfef37ca10c1f823c1d0ad59a1bb19339861241f",
"0xbb5a6584cdc7e4d06ec5fc1514233cc42970f6c332c3a9590978dc9908e58c0a",
"0xe69d7a0766db411e504f09a8f39f0583b2869016bbe95f21dba432bbe8b88442",
"0x89cf4caaaf200881779f5fa6da8ae91ff1c962045dd0622b5ca65c830d3a9d4f",
"0x82d66c631f4c4167e5301d896dbdfe24d8245b1de041fc85eaeb6e35117ed9a0",
"0x957907bc93879681d8682a188622f9bf2c7d2595dbe3e2e34bb01711cc4124d1",
"0xccb3a3380550586696abd3ac267e85c7516b2b682b3c48f66aca94d57500f3b3",
"0xaf56d4650406e70748dc860a7879d8d522599081f8e7011056c976b860703e43",
"0x5d96ac1d2dff8a054d880a44f5d45a1bd18aba29085fcd633b0608351ff1876c",
"0xe051736dad8b9f93a8f1c13031c2b63249925e152685a2e7ec188ee089861b20",
"0x0db8987339e1fae41af5f08e6fa15da5fd80de3431b54e82cf8edbdc792f870e",
"0xcc99097678110af2be8dc07da8d642dce928b7d9e2728fe6fef1fe2eaa81a72a",
"0x2428c1f94ca57c7913b011a68281eee9ee4855e4ed2c97e34a370e649b21acb1",
"0x501ee9580c89b1f67c5b3b69ae5fd1f83852a2f9330f53565bcd04d8a7c0b776",
"0x16ae47cfa19e8046f93a579fa2557b17aeca7892fc7a82b6d539930c8b7c95c9",
"0xda62590043ca70c1cdfc7969cdfa853bddbcef0ef62aabb9f372805322511014",
"0x481b4aeaaa60504c94dcfea966840b381db85183c34cd25b4857300b5c189003",
"0x035dcc47f8670a9f648bcb0232e42fd4876243a7a3bf737b88d723ba187929a7",
"0xebe9bf09e3577865aeb341a06f67bb6e607f10b04ed9f9d733492a9d0e9ceb1a",
"0xad5d85b58af6aef7f81bd6b2407c6e4884ec82b2ae2aeaa24e379a3d35902375",
"0x0f0dd63d7c6c284659283825624140b31a3adaf7cdbb2255faca443e52ebfe84",
"0x40079be1c9394e95b4823895ed380d79333ca2085aed2abd0d766f84d21b7b42",
"0x7cc40ed01b436ce225a3f9c5c2bc7f6f81aee40bb83a54bca2fe899b15f3e2b6",
"0x1b6356e1a83ca5b0eefda1fd62fa959b118d2a19a6a90f182a53414b3fc7f9f0",
"0xae4a71712cc96a5b30b45e3b92c339c2e975e4ed683f4d1fcadcdc121ff7c6bf",
"0x226f6d8c71ec32c5eaab6b01c0fc1d00ae95e60b383d09560e90549b79eb1447",
"0xf3dec779841c9384df93bcefbba8700a292b570b29d286a7c9c5a442b4788a20",
"0x63ef48e80efa45383857adcb0f31076393260cbad058d1938345ad13faae50b4"
] ]
}, },
"nodes": [ "nodes": [

View File

@@ -143,7 +143,6 @@
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff" "eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {

View File

@@ -23,7 +23,6 @@
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff" "eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {

View File

@@ -19,7 +19,6 @@
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x1", "networkID" : "0x1",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff", "eip155Transition": "0x7fffffffffffffff",
"eip150Transition": "0x7fffffffffffffff", "eip150Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": "0x7fffffffffffffff",

View File

@@ -43,7 +43,13 @@
"eip211Transition": 5067000, "eip211Transition": 5067000,
"eip214Transition": 5067000, "eip214Transition": 5067000,
"eip658Transition": 5067000, "eip658Transition": 5067000,
"wasmActivationTransition": 6600000 "wasmActivationTransition": 6600000,
"eip145Transition": 9200000,
"eip1014Transition": 9200000,
"eip1052Transition": 9200000,
"eip1283Transition": 9200000,
"kip4Transition": 9200000,
"kip6Transition": 9200000
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@@ -56,8 +62,8 @@
"gasLimit": "0x5B8D80" "gasLimit": "0x5B8D80"
}, },
"hardcodedSync": { "hardcodedSync": {
"header": "f9023ea00861b3771ffb84fce48b8ba3c54a09f81e91ccb38c401261f06d370098889a43a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e6d2b931f55a3f1701c7389d592a7778897879a071cc81d58cdd21d1e17f7389e55c530cd9f94cc15bb32af6477320682327dcffa06090021a7c09ae5e75e443410ebdb76de04f1eafb0ab910daae96ee6eec560eaa032510bf257dd03b11f3b4761b94b495a5b5a18cd6eb17c77785e0f46e2ffc882b901000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd8381e001837a12008306697a845b83bd6096d583010b068650617269747986312e32372e30826c698416e0ef58b841117e2088e2835bf2afcd5d48f42b3bf2a1f33435f21f089ead2a6bae7d01c1486e645b460bb3c726a827ff1eb50e0579f3410563bae090fc256cf1d8d594b82100", "header": "f90247a01865856fb6e4118598117560df31734c74cf725c8edae4db941055ac0afeb207a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e6d2b931f55a3f1701c7389d592a7778897879a054563efd593e9682943065880710af9187131127148575efc8bb51d80dfed41aa0a568a1653a6c7d559711be0b91a8e75db76c678dbdd286c75b88e4f0c0d31171a0dab32c5cbe9b9244a7af00afa7f6042a4ac923573e8f2f025b107abe1e3da999b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000004000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd8389b001837a120083046540845bbd803c9fde830200048f5061726974792d457468657265756d86312e32382e30826c698416ef600fb841387b51dae8bc8daa6cde190d3f44797690b4da1ce5fcfcd54bdbb2a6ee6d8c1f7649081ca28b5cd70067ee9f61e27d8184db83705102d5e1a269f2b631b4d5db01",
"totalDifficulty": "2845866505151538604560067685603735513869853136", "totalDifficulty": "3020091077015059097853315484608800838133866777",
"CHTs": [ "CHTs": [
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac", "0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02", "0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
@@ -4214,7 +4220,257 @@
"0x3ef50c81169af169c100f58f3afcb8e2f926d957b2adbaca8787be5d4e8d7233", "0x3ef50c81169af169c100f58f3afcb8e2f926d957b2adbaca8787be5d4e8d7233",
"0x8783eaeb56ca2d7fec84e0e272b77271fdfd6c14452a2e1dd83de770c5d99a1a", "0x8783eaeb56ca2d7fec84e0e272b77271fdfd6c14452a2e1dd83de770c5d99a1a",
"0x861024460895378ba100c5d0c05e62bb6cac8b21ae529ab5cab39eb6c6cabd90", "0x861024460895378ba100c5d0c05e62bb6cac8b21ae529ab5cab39eb6c6cabd90",
"0x1c741ed9eda60e5ac585e2f48f06fb988367c2c40a0d8111bb04b260fe44ec6b" "0x1c741ed9eda60e5ac585e2f48f06fb988367c2c40a0d8111bb04b260fe44ec6b",
"0x6051d77e0596a911bce132c4bc12be2ae5cf29d113dd52a41b3bc166861149ce",
"0x92c049df5ddb238644015d4e039e169614ed1d926de070952f2407912906cb4b",
"0xa897567fc1ee9437f2876deb3de2b11b8fc00aa07340564031573f0351ec556d",
"0x3e54a8e15218db168960d28369003cdb1a76f8db19384e9e2696ae66a6693d6e",
"0xc5db7ade97cf28f8b61f2c63a0773201ba64f37dadc19c03943b6772aa7a1a50",
"0xda784d1bf64b7efd06558b90cd2436f3e61dc0f7a8370ff92516ed062f461091",
"0xa1d10b0a36ec5169d2df740878d051bf4d38ebc5dc04ae5558daaabc2bfa1471",
"0xcc89a8be2ff74a7bb9e967cfea3cac067aa84cc455a2fdd5449577b52a2b4ff3",
"0xbd23a3e6d3198d81d798c2851c36b954fa6f359bc8fc6e04a0b757e3d0ba053a",
"0x74640f825b9d9f95be69763845aaa0269d3a6ed5aaec88bfd9b5c4139ba7ef41",
"0xc01a29e41af3cc0d0a13ea83f131f3e4828ec3e83dd2fdf9739c139938dfc2b3",
"0x832509e705972acc7efe91475e8d76ac00a12750e194847093825e6c4db9e83b",
"0x63139d1224766ada1318613b9ec5894308efa2473e809d9e37c8305c6965f2cc",
"0x76547e54dc59473093c3fcca1166307cc7d0f4f0e8a35d850507bec216b76476",
"0x3a6a14785272391982cfa690762f5b2aeccc1dc0bb13eab6b9fcfd056f40703a",
"0x603e32b52795c04416d800b6a936343aaaa09898fa97cadc2b157eeaaf3bd6f7",
"0xf241102a3d3f3a9fdc5a1a586b16fdce4280c6c6da04290541eb3cb9c28c7325",
"0x6db6de041bcc7c00104a21bbd487a1e1ddd5e4953f7a503aa992d68a8a7bbc43",
"0x8377d795c55eac07c0acca674e775ed7d8eea35867990c8a776f40965c9ddc68",
"0x48d62d562279641043e405f4d7fbd76050d773103871c5de2c8acc25992db502",
"0xa9ef42d314e15c419537e022753ab46d41318f1fa8784e4363494f395eb6d236",
"0x99572f567eb602a1d9839bd23b41562bb3782eccf9a8893e54b002e685ab378c",
"0xd8cf2fa2291efed46c1a36e1b8837be62e86caacc380aa6397792ae8baf8f3a1",
"0xed2e800df1acb7bba5ee6251592c397a604debd7b0bfc28c8b0002dc40faa8bf",
"0x9ccece195d9e67e318f6d2952bca9486d09f4207c6d8be266cc0eebe41290920",
"0xb20580a5c96c25bb59e1bae6ced3ea5cb69d903f64e648bcb38b799141b3cd5b",
"0x1488647e697452306d2744ca6c709007cf75e2e37da3c7c05006211ba0720824",
"0x009c3dfc5494962c77900fb8da67d7bf2a2f4b855c521b9d50c4aafb1e0735bb",
"0x482428835dfff3ee1da335b36ba3aa1969fa35e89150e5b3c1991f28272d14f5",
"0x6a972044f2076e98833b243c9ed18162d96b46823170ef7c20b1a02d8bbd48c5",
"0x676242effe0fae84110c4933beecfe5ff549b439e54ff5a588add229329e5365",
"0x2441bce77589ebf8019fa8ae870a8529479c6eaa0fed7e0fbd3cc7439dbd4a09",
"0x0b20c25d2c6897c1a8dc9ea1364d3c72d33c97b4d70b9176c3f0a1e3b6ce08a7",
"0x685aa4e279118f8326a90c78e9896e40d9baa62144e2425887dcc704106979c3",
"0xabcab60973f6bc9ec3b596452e7434c4dc89c55c8eea925fc0092d1103c6f86b",
"0xcbf44f106f3f2c0050906b5e344ad22f0e0034067d35402d447311d254516dd0",
"0xcaa67796a8ac69283d7b6304181a988992130ad8441d47b4fdaf236686dc1caa",
"0xad06e6db230bd0bfaa0df59d1ae517ced29d5f11b34f76ef9bb6a73407128b59",
"0x93ef56a4951e4e5c19230918b1219c1f07e9356363503c1410e71486ed338f87",
"0xc6fef02b5bdd4909906c40cf5b999fe9e08e4c0d8bfe59d3c9aa99011136f780",
"0xfed633749700ffdeb0921a537a215ae31c25b85e4f80727376e50c247b4c5a38",
"0xc39d8cc15f4331fb7db2c24ee1163bd164e81ad2ebc43271f841fb25d03835c6",
"0xb13962dcb364ee49e2d0a34dd1a555fa8df363041504ef1e987ce78646d64146",
"0x97e0d3047e2151d53cbd1358da627453558362c6a830910b33f241848b20cffc",
"0x587ea98cbd1da50c0af1986f6ee5e676658c06442e893304708db831fec8e804",
"0x0a1d21212d9bd85a1a39e046c897d1dafb496bfd80762beda2fd3eb1cdc72eb9",
"0x46aad83612f04e7a51fd642de742f713601992e58de4daf24148a3e6f3318aa2",
"0xa65a8a9ed4fb28fcab6ee3af5df4647083c2e735fc652568759fe0426e9a294e",
"0xacd7ed5525cad187f053ba98487cc4abf24f76c8c0e97e71a696d553a3a41b7f",
"0xdcbdcfbaee764bb404bfa5261b5037b9c7ce567a3c1aa9f7280071990320da18",
"0xf195aae79a232b2170a98602efaa2efbdebb3c40d2438e63bf0954e4dc779cb0",
"0xfbb2675a62e2e67baf85e56fcd4cdf2bf89ff7905952155d3cfd4e625fb674d9",
"0x5b955473a35f6b0d24fa8be8009734ecee62f6c4bcf0cafc2335f07c51752fb1",
"0x66f37b268338f4ba1e21eef6884aef245bc36935be1f5eb14ee1d23618f00f5b",
"0xaab809ee86773263043201b83bd445d98a634d8a6da4c389b2336f68381dd481",
"0x509fc38118491458e45c7e8ab1d60c687f50d85fc1c0bf104b531a3b352198ea",
"0x20d1e4f38e83b27b77d55281af40e9f96be098fdbb90730170638c88ab7e435a",
"0xb33711864d62709a98f81d9c5f0a301bd5808d0e8ecef1063c97347af754c8c2",
"0xd69fd6c0fea478bb380b948f5b054f91831cf26d304991d40ebdf0b00a97503c",
"0x87157d452bf57e617ac1dd2372438b0777b83f6087d8223008d823652c634882",
"0x9c54b0172ae0223e6b23f7e000cb6887144e615efb02c74596002dc26d43eb5c",
"0x5b0f87baa8e40f0a2bbc1a76afbe0b21b5e8aae1443f0d38c3ac55c5f942db42",
"0xeb68d93e19860fb9fb76847080edc345972e29ab1ffd417ae5727d3cec79c0eb",
"0xd27026033bba2557c79c4babaf669a399fbc72a2a5cc06c707e24eaacee83bce",
"0x420d887bd82cccac29711c52f4d362b6a7d854e694f8d597d208d0a094fbad8e",
"0x02ff085c6c3c47879a91f511ea4c54a214af8160e07dce8e82a6be9e8299e237",
"0x1f0384e0afaf47ba59aff9f224905950768674c48de0fb0312749b16edb0a347",
"0x55cefaac814e132ff335882a366ea6173bc21fa713e93d8ad92260c84cfd2d85",
"0x58a8dd6e036a05a937a7053be916c0e7f719f2a1905186e7586a9d2dafd5a1a4",
"0x8714d03549461e32a467cefdad60a96788c97172db05c18eb9debf6e6a4d39e8",
"0xd141656c1f57c12feed31dbff3817e1d2af4e1b5cf6aa75d1bb29ea2c0a3ae69",
"0x5ec365177e19fca3c1063e65a9342008aff04ba9d03d53837b598b143504b97a",
"0xc620e23ae73d423bf2628a3de70b1a1f915d80173e0c8d1443a44b91400c5a8a",
"0xc72c2356ed53eae5a4a56bc248d9d2f4e9154f1404780b84781f357cbc7ad2d2",
"0xe60bfe30e5a1a9457ccca65810675e129948b474f391ce64d270200be7ea6beb",
"0xf679887baad8f8e497d60b015156f194b94fc30c6cb1f83fbc4575e99b95a8d5",
"0x654463146799fcfa18a74ffe4f2423fa04c8747c16b789dd24da26d0338d381c",
"0xe8b5406278d9e4622d088976af8b5e6b14cc146a9530c862a42fa5566a247355",
"0x8ecb4735132f769663781f96fb531115190e68390c54e33b250db874e90aebaa",
"0xef13bf38c2ba993c9dea5777e5db348339273d0e6dd1f41867d3b258f24ac4d4",
"0xbbbbeedf7276a857c513f4ebce88e3b531c99cf206eacd1c6c29d3cabab45df4",
"0x89cd50cde2de3ef40de7502241b78e664de53dd4a5e2ed85db62c55be0a4d8a4",
"0x0da2cae061e7dff539c7e39b0b9f63af3217f1a51bc597db957b6a3972cf7186",
"0x57aa87a6daab3c65519de7c1c1360ab33b830d46f169d4e0d3c38e7dadef289b",
"0x85fb1241c4110b4f3a6c197450af8ac47bb24d531219f6cefcc079717b208c84",
"0x52194cfba6bd7d5eb8b438054fbaf5fef387cdb8b1a7ebafe44cdcf4da47b1dd",
"0x7d24eb47a1310f7f4244e825847f634fd4a4224f695a3609c5250dc6052de6d4",
"0x38edeacb93b10653624f77dc05063499daa770b74d6b63ebe656be5a3630b7b8",
"0x4e050f7b9d73c1aea3ce60c8eae8e46b55b6d4c1cd1eae22faf982895871dcd1",
"0xf22b284ed4d97b7d3553600388748721a328052daaf92a58ed5403fd4020a496",
"0xc5fcf858d9a9748045fa0ca1271ba5af780a788c51d693815e0490671be3885b",
"0x2342efdb88226e68173ef84060a0d4dc6c8aa9c9431883beef4a5588f3157fae",
"0xe1599bf452eaacb8dcd51ff835a9ef5761dbce83cfc719813d6a10772ca5fdb3",
"0xb754797393b3216778ea6389361ca5951f365ae4e7ed99ed4cd4c9c76ff442d3",
"0x3fb5f9f3754764155296c6ff4c469109512264c603ece7c78c1231942bb8ac35",
"0xbb347d23c7d703cd2801e2763f1a6c375b5cb2a666ba137c4d6442c3f94688dc",
"0xed3806645b55fd7027dfb7f5f796933049ae558d26ca695a01e1b11333f5e453",
"0xeadb7740432ede4f90c0bc490c15fb377b68de0fc1ee3a56e87e21e7771211fe",
"0xa8c0e907e0b544e7fc3116d47e4cdfc8e8688f5cc4a67cdf600f74be6b79775a",
"0xc6f6b94f2fb4c56066e3c722123b8e85f80ce8baa0427b62c5a2ff937702c481",
"0xfff0b94553a7daaee58a7e15daf9845d1a3ad4917d81d4f23dad27d0262b48ec",
"0xb9084676613e1a063c2b491bef1b984acfbd2dce60a8ed970688239524e31962",
"0x196af717eab2cf09b47db13605ca4864cb0c4189d40c9b618d8a7d3f92831d78",
"0x4fac369653dcfe74d86b7422354d68f7580b1ae0ab359a8b8f8be8582590ea7a",
"0x035ff04f84478354706945480266321d31790f5445028f3e964801fd9a16c78c",
"0x63df70a24370a408bffabbe1c7a4c9b9e40be1cb326ab10d63fe54bb9de50d34",
"0x37b5c558d31128595425ca68deddf5ae7539abc6da838837eb1e0457e092d9ea",
"0x41a9ce82ab27afbc84669368c2e75a15e6386b77034ec316795a896ef9de577d",
"0x08bc6cc18842df4130280823f7676f418f4797d3ddfc544e54267e6456cfac68",
"0xeabc09ffceeb35cc4ec18518d4920bea2f43bf746f23b5524fa405bd874e9d34",
"0x40336744dcfe6f312e17eea83f53538f9999864c41bec43576cfcbef68d12e7d",
"0x3e780dc9c8f2b708527f1eebca75d18507e00e226a00e1b1ddd0b715aa8dd561",
"0xfd6a3c50c4a4d6e1a6fe27fa96f6aa2654573cbb9b839ce8e09a75993e2bf8e5",
"0x166c03d381d6ab94666099024adc95de0ecc9818e5ceb49965767682ca0c73fe",
"0x9805810b802a51a3ae18ce44f6b2c68abfccef2119df2430e4693e291059e222",
"0x353ecd1a0922e819ffdcd634385ebbdb674d247c4fe75e2d5437b659c98424a4",
"0xe75fb8682b706ed6596699d6151db4dcb19f6e71a3b6e34aabc3508c919f5c17",
"0x6e9bab64b10a2341f49e81d862ef3322d3117842e3f1aabc8b774c68484a2a31",
"0x82b5e79ee8d72c3613458c975530bcbba359734a4e9f07015686dfc521230329",
"0x86d48d57ccbe1f1986a4043748b1a0d8d76fd56bc74e7c48c6fd742affa0ee11",
"0x46ee65b9c2fa3e69aa1cd6ba5aaafa7f7aef59224098b60e22994996c927c9c4",
"0xb6983761b177e21899799410dc018f1acd3d417fe35943fbe57207f9f799a100",
"0x594057a8386db6e159d43d136c464c5e3980eae75a73900f7a84ba94803fc6c4",
"0x53c78073c4a4c44d17db85be06f38ab47ecbb7f36ffa87b9db707fd2bc87f391",
"0x4a976673044732e3e8a0987fc8f3c36375e3c4fb3722fcde5259af492ec458c7",
"0x1e2fc8db341a4d9e123ae4ff4f4d8096d8afef47c5d2915c665922bd1de3b00c",
"0x565cd8eb410c6e0b4d67b54d37ff42f6189095965896b0f81566ca502bea34e3",
"0x32d030e4ff6b2f5a560cb7525b5e66ab1f34a1e06531f9b81c48b8a257bd5637",
"0x25a91d756023bb9ae538034bd39b6e698d05fb1393d1328c4fc7e5c14209cce1",
"0x8036f74c4cbaff3bd98820ddd84bc093c95e88d357b341154a3189715225d068",
"0x8bc6bc61f7a57a145b8d728f583e027c8630f0c07e003b189f390ffd11d6f150",
"0xfbeb53fa167d067c9b0a2c0710f7f5931484f7dd90b9456c52c578a15f402d9b",
"0x8d355b208a16b8aa3f7bc5d8864dc7d6a1c4917a97c523274b86e82998d60b63",
"0xc94e45da800d7b56456d55a9aa36ddf9df45e9cfeeacb1116b8c51a0cea34ebd",
"0x81761ec04a8d219aedb2f58aee529e876043b0a476e771957bc03fef9f0780de",
"0x29264094c720151f7448cae053a403aa86fc20649bcf383517e214d1677e893e",
"0x9ac97c7eef9b69dcd73ec7144a0cddfbf0973791beed405202fb4c2d932ec59e",
"0x89611f8e2f9e2e1629f83ec14aaec1656876718c05088e5087887c87b8414c39",
"0x67244fcdba97905472631378fa3a228b649880c2efdd57e5a6c95e9b70ad8456",
"0x0d554cfc4df02560c3e76159d1964c69c39f5df9489bba5516f28a32a4be202e",
"0xce9274a36a0f25a13edef679a5b286bf91a9dc5274354bb6f1ce0ac52557e650",
"0x6017e68689d9f6dca78f42b93a224b445c18b70288a6e4c0d6cc295627dbb1b9",
"0x76791c90f887355878d0a4d8c84ec3990a3159933ecc8d868d196b363153bd5f",
"0xacb6a6c9ec937b3d5cedba26ab6d581fc41cf9a58b0867232e2c8c73d9978cc3",
"0x89f17989ef556a0562c2aa5a2a1d71e5132b89d656bead1ef88ad31073b80cd1",
"0x06efcf8dbadaf28ee719a5b9c017a093fde84a7f4b9966fe3052c0b2fe410ea6",
"0xce16909616f1d97e5853818938b4798030259ddd41e3468f35b940ca901d6817",
"0xd3ff9e9ad14a605a94bdf05dd2639b6fbda28ccf7b2b228f064b0de52410df5b",
"0xb3e8ca9ee88d4c3ce347d82e8f22793ba22b7adc350fd694b1b00b0764c584f9",
"0xe690268a4ec089aced00f9654aa95acb7a8d7270d9428205b103c30a08d142eb",
"0xd685e1460799c51f14273361e31b9739e5212fa538fb8dfbb8e81e8b1d329bbe",
"0x664c293680fb7c5a89ff3c31e81ec8d0c30a6274ef44e4e76bdb9bba83f3c0b3",
"0x44027fd23526685d920d37b032f912159e308286eaac018244006690b4191d4e",
"0x7ea934c3d75a9ecb6a2055dcd5feaf2d4c851eaf360a648d5d87ef40fba2fbd0",
"0xfd97fc801315e5be630ccb3dc983c409a58fc1fc307adc1e4a48fc60c89ea40f",
"0x15aa0c3c732a2c6684d521729dfeb93f62e22e155d85d20e5488e2c86b043142",
"0xba235420ac54100da28cd6f30ff64b8594e73c42f45ca8494fb3d3c4d66651a9",
"0x9948e8489cd94bed4b8e90a8bd35e01ffe38e7c077f587c6c1949caa99cc98e0",
"0xcf66ccdfa85655d7d4c94cffd41f499afdfa2bbddcdaac547223e6ac4d1f9cf1",
"0x7e5382881f710530720b420a3f3ac08211565ecc8fead8ec649cea11f9385c3d",
"0x104576fbb1760c16ce85c3e5757832d53bda83d618500ef677a6a192ff14a5fb",
"0x9e4689bb1ee34635e1106e38ca41833d2dbc1cfacb7635ede5761048a8637c7c",
"0xc8c7f7ac271015da443320f4af650fc71ea0914f4c41252a5b7ec76f329d5268",
"0x46a93ae992001a54119c8d27788e3ef8927dee0a9949b22ece0196a90932c1da",
"0xa69467f9944f1a5e3a46718a99d3cb14930cab6d971baa37bb774cc757e55c2b",
"0x33f7272fdbfb91428a1344df5867300e256fc3cc2e439c777c3feae1cb27b781",
"0x0aaa367f4c7f399edc64ac1754f47aa5c28b0fa208238276de6bd9e424021ce3",
"0xf5f363c3bfa4a23bf221951f4b53a77b27613938babe40f0832d05fdfd252233",
"0xec315af99bdfdcb3cab1f1dcaa5b42ef53f4e3fcf4d921578892a5896fa20e9c",
"0xb580a8e51e875446d7096a20801dded1f7e5b5fac9f47e9361dfc9dd80214013",
"0xb877df38d8f4cebdfb89f26868bdb97ef945da187b44e1cbeafc1d4b7059d713",
"0x78613b9d2d6b639a54ecf1d50a56af80560b436fa632ae636cf354d4a6dd4af8",
"0x80a9d0a5e43558f1d24256baa6940c0074fa84d4b8e7e236054943f9ad5fbe2b",
"0x60f79f699ba1a740c9784f2a8f1b652d4e695ad2d230b110472b95914fd35c8d",
"0xae20de288eb7362a36a1ff236faaed6ddaacf58783d098118bc9fe66b8780651",
"0xcd08003531d6094cabdbe4d971a01b41552784c246bd2a2f749ee9947d1394d6",
"0x676720accf739c380f64748390c1acd2f88d454539866f7326a517c9b629b545",
"0x086b71ac681c0ea369c16b22ca49753b2083ec25b46ba659206433eb060d98c3",
"0x78910ab7d67e67da722ad53b669d8c3a312de3cf362c6254c09581088e920acb",
"0x5bc6e98a830c114cb432091679ac5b3efd25c362d6f99585ce3a027dff95e524",
"0x8d0daff5a97327b615d1535fea44fa33610fd645d93035e1e5e2bb49d4dcef24",
"0xbb46662b884bc6676d98ebf3f2a35ff9190339b72d68520fe40100b4eafaa2a2",
"0x9aa8faaf935c95a60ffae0487844860084a963792ae0bb90a831f825339810ac",
"0xfd77b5d6b6b87bfb0ddcad7b0ed3992e5fe897b16db06b118230b2d292e317e9",
"0xc465a3384c694bc50cbe97ce9f3bc364884651a97a491f7f64e65dc319d1c9f0",
"0xc4634431867d7a302be79e83fb50d01df7f3b950aeede21fcb59b883399b06e4",
"0xfd524c29525cb97a89026ff68048ca6e2a9f522791eadd74447a6c278151d7df",
"0xc7df516c295a58cf4cd5614eee3d2f773a412dcd4926eadad7e935ecae6d8907",
"0xfb915abde0108d6e84354e21a513fa564f5201277e060bb916a9153537fba1f7",
"0x1d3c6a780f1b259e096f4a141ab83cb6bd035407421e2468e743daec211e536f",
"0xb2f47534f060c70f61a7c16f920d0e11b957bb3ef912ed9292f35b8ceda2acea",
"0x03e0ebe6e9992f6921362d463b68f91518d91079c001c6bea7b3452879fdc29c",
"0xd9a7de173a1617ad813a554a56d7c7d2f010ac78d7782e524b35b5c676cb72dc",
"0x90d05d99167e53d34a02c5b66ed6920190370656905465f20efe56499aa0ba6b",
"0x17702606dc895aae35aef034fddf8f7235efcc66e5c9d252347063209c2177b0",
"0x3c416492193d81fc03b5c1964989a314e5ee6d689c638c996f6761b4d7acd6be",
"0x3c6c1162ea9b277f831989ea26e14bb23ce4d72bb9c865e354992559266ceb16",
"0x96de93f849613bb2ffc117bf111d4798b9252649f94f21187da324a3fe363833",
"0x91e50fc6e564cb9d6b7aab3a6e93f6b32944d5a781196a9a8b12ac7f6f527565",
"0xdbefa2bb2ee620d75295d0f3103e06b428f955dba1a792421e435051c46f7933",
"0x78f29df98ef7dce9fe7b4414da90fb4df5d99231ab0a3b7a3e70659986580fe4",
"0x56cf56899c2388d55eb1496ccbe62041d14cf655c9dbc53984d86c22ed281acd",
"0x099f52c675171088550a9e93e1ab17f003190fa3388d956724d422e5925c4813",
"0x9913e4ad8405b8a60fa512fb616c544c6cdc415cb1023aad0669d58cc3810161",
"0xbf5d51369b2510bb57f8fc8e9342890e8bb37049079dc79ab97afc0bcbf3cbf2",
"0x3a012d45d250c818b641fb18b71b622f5bdf0b7a541e0d8de54f61e516ee3ce7",
"0x0233833414d2cff3da0326f7baccf1bd522db5fee290ab4fc0a976934a20358e",
"0x38a0978c955f20cdc32e2013a5373efbfc50924e45e9c4c756291a903f4162b4",
"0x4107f33a14052662a0469ddd646ab6659006df131c4b0f6b0e6cfd331b46fea2",
"0x8074fb5054c755c912bc68b1dc22ae40ba13c06912c8af1c12652eb4d84c6503",
"0xf6d151b8f9c26c3a31366d967dd7338e80e8107b9b81da0a98faf16df9cbc91a",
"0xcebb0256d0a8a4b22d2341ec7c48292c3226caf4aeaa2003ee36dde25cff833b",
"0x5fa9ac499a2642b0cb7ca365062c02588f9c555bcdf584f533ee8e8544b9928d",
"0x800c7f04db30247318b8d4c11d575dca66bf615674fbeb9e8c20f387d907c8e2",
"0xb0a43de06c9d48afefd5411d759e3c6293cbea4a7c6d862b119182ea02af81b7",
"0xb6e7ca0075d28959cf87d716fea885e9e3a0062fc7da1b6e06089c808a632b8a",
"0x734c1b19f0b5972b5215f675cf60c68c12cf6d6bda7b5a95ee9a781482e68365",
"0x1995b08fffb20dedbef592ac23a81d87129ceb396e065265dd4a6cb876beaf09",
"0x051082047a6b579684b5444ce5b75bc630277ec06b0087779387b9d7fcd18fec",
"0x4aabfe145c368e6878e2ccbdfbecf2f1db5c9078650696bb3a584c14fe17177f",
"0x42811ab68b304ce30fe896c52b53d861abc3c8b5e4e740fa97b1695db9a6691f",
"0xd90cdb12ad64f86b2aa7afb781c00301f50206b05f1543b111c2b971ed209c94",
"0x385435507c2ef42b5f1760b97497e8a02a4b5ec4926c3cce8569fc0f4be59ce8",
"0x2d7a4908350c9cf022920cc51e0cad9c3c05d1d14a92d72310b52f984c857101",
"0xceea9c58106f4f806a256f64dc04e1c4b53e6cc5eb048f3df7a14f8de3506e96",
"0x7032f864eb3eae8d198c3f8edd9cc2dfe88b9971cd01b33318dcba004f9b044b",
"0x71bfeb4c183b20fba60e225524c809b0864fa14f5c0137accc36649ed0712e5c",
"0xef0ec5a2761c46827110c20e14fc4aecadc2407541ea046de09a58cda3b2e839",
"0x5e6debf328055c9413fc3eeca28583f917b361a5b5bda9af4306929931a4116a",
"0x1aab81df07eab969189333e5b2930fcc1b88a525ec5bc6af6626fdcb202b8f34",
"0xbdbf97e1558711d4872821b9400e03a811c61096bb838d3126b1c2154f8fb776",
"0x7d8aaee482933ffaa97777af3e4bf69ce7d99afb24e546d2e365d445d3d0190d",
"0x9da421621b14164582b2b877090c9a956f3a7c917031bf743a9ce457b6292369",
"0x050d717f0433a72b17a0e9a1340f26aed5bf17f90c08a5b73e675860ac9c24de",
"0x80551d3ff835aaf987b9ec056a73a3890985ef551431daa9d4aca10c81cac7fd",
"0x625a5b5aed2660d32d2fd8c4d1bfc248365a5cddaf9b5695e3f131629739ec60",
"0x7d86bc2dc5914d16b3d0d882a5db0230b4b688cbd8c81098d2efc5080e589646",
"0xfe42cd832cdffe56426031ba7d837c56d86be72b89ca9f5474bd08db80cfe903",
"0x0ca30e1fd3bf3e16a0e295ecbb442757248b2ad47baf88fc37d6c55901e709f6",
"0x2a83ed111b99844e17fb7aa69854525958255ffea04e0bfdc365264e72b349db",
"0x709779de19590b69864f5b9228b3a1c334724e20be006ef5ae38f8c05eb6f37e",
"0xf09c664d0e2e88ad5418d14481fefdc9e9c46158bc5439ffe0bf6d6d5ecb2eda",
"0xf350785dd3617ef73b0a5bf439ce5c49adca0c041b6b5047a664e5e33967ddf7",
"0x8fcf87571154dc4eb0a73c6ee31cc0db5f4e064cf23a255a408b2f2c7cc9c0e9",
"0x75801fc8867ce7c75b3148c6c022d7702143b93d93c1fc2349e3e969d0179cae",
"0xf14c18bf68ae881d3fb07f631340b00557a83860d0ba0efbfe55fe199176aff6",
"0xbe48c727fb6a32242229eaa09146c76522dcf6bed6d1c6fc1bebf86b5e4ccdb4",
"0x8487b971e383272df82cd812a0bf3a2026b85bc3897b4ce9ce48afa00849fe00",
"0x60d18b465172f59c0d71594b5273a90cb41db24a5d4c9fc37020f9d8c467a4a2",
"0xab4e36d9f17c748c87d89c23b667e3f4e3265e77b62dbd9c92659026f8a53d12"
] ]
}, },
"accounts": { "accounts": {

View File

@@ -33,7 +33,6 @@
"eip160Transition":"0x7fffffffffffff", "eip160Transition":"0x7fffffffffffff",
"eip161abcTransition":"0x7fffffffffffff", "eip161abcTransition":"0x7fffffffffffff",
"eip161dTransition":"0x7fffffffffffff", "eip161dTransition":"0x7fffffffffffff",
"eip86Transition":"0x7fffffffffffff",
"eip98Transition":"0x7fffffffffffff", "eip98Transition":"0x7fffffffffffff",
"eip140Transition":"0x7fffffffffffff", "eip140Transition":"0x7fffffffffffff",
"eip155Transition":"0x7fffffffffffff", "eip155Transition":"0x7fffffffffffff",

View File

@@ -33,7 +33,6 @@
"eip160Transition":"0x7fffffffffffff", "eip160Transition":"0x7fffffffffffff",
"eip161abcTransition":"0x7fffffffffffff", "eip161abcTransition":"0x7fffffffffffff",
"eip161dTransition":"0x7fffffffffffff", "eip161dTransition":"0x7fffffffffffff",
"eip86Transition":"0x7fffffffffffff",
"eip98Transition":"0x7fffffffffffff", "eip98Transition":"0x7fffffffffffff",
"eip140Transition":"0x2a", "eip140Transition":"0x2a",
"eip155Transition":"0x2a", "eip155Transition":"0x2a",

View File

@@ -31,8 +31,7 @@
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip155Transition": 1915000, "eip155Transition": 1915000,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff"
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@@ -33,7 +33,6 @@
"eip160Transition":"0x21e88e", "eip160Transition":"0x21e88e",
"eip161abcTransition":"0x21e88e", "eip161abcTransition":"0x21e88e",
"eip161dTransition":"0x21e88e", "eip161dTransition":"0x21e88e",
"eip86Transition":"0x7fffffffffffff",
"eip98Transition":"0x7fffffffffffff", "eip98Transition":"0x7fffffffffffff",
"eip140Transition":"0x21e88e", "eip140Transition":"0x21e88e",
"eip155Transition":"0x21e88e", "eip155Transition":"0x21e88e",

View File

@@ -23,7 +23,6 @@
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"eip155Transition": "0x7fffffffffffffff" "eip155Transition": "0x7fffffffffffffff"
}, },
"genesis": { "genesis": {

View File

@@ -15,9 +15,14 @@
}, },
"772000": { "772000": {
"safeContract": "0x83451c8bc04d4ee9745ccc58edfab88037bc48cc" "safeContract": "0x83451c8bc04d4ee9745ccc58edfab88037bc48cc"
},
"5329160": {
"safeContract": "0xa105Db0e6671C7B5f4f350ff1Af6460E6C696e71"
} }
} }
} },
"blockRewardContractAddress": "0x4d0153D434384128D17243409e02fca1B3EE21D6",
"blockRewardContractTransition": 5761140
} }
} }
}, },

View File

@@ -18,9 +18,14 @@
}, },
"509355": { "509355": {
"safeContract": "0x03048F666359CFD3C74a1A5b9a97848BF71d5038" "safeContract": "0x03048F666359CFD3C74a1A5b9a97848BF71d5038"
},
"4622420": {
"safeContract": "0x4c6a159659CCcb033F4b2e2Be0C16ACC62b89DDB"
} }
} }
} },
"blockRewardContractAddress": "0x3145197AD50D7083D0222DE4fCCf67d9BD05C30D",
"blockRewardContractTransition": 4639000
} }
} }
}, },

View File

@@ -9,9 +9,11 @@
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000", "blockReward": "0x4563918244F40000",
"homesteadTransition": 0, "homesteadTransition": 0,
"eip649Reward": "0x29A2241AF62C0000",
"eip100bTransition": 1700000, "eip100bTransition": 1700000,
"eip649Transition": 1700000 "eip649Transition": 1700000,
"eip649Reward": "0x29A2241AF62C0000",
"eip1234Transition": 4230000,
"eip1234Reward": "0x1BC16D674EC80000"
} }
} }
}, },
@@ -32,11 +34,14 @@
"eip161dTransition": 10, "eip161dTransition": 10,
"eip155Transition": 10, "eip155Transition": 10,
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"eip140Transition": 1700000, "eip140Transition": 1700000,
"eip211Transition": 1700000, "eip211Transition": 1700000,
"eip214Transition": 1700000, "eip214Transition": 1700000,
"eip658Transition": 1700000 "eip658Transition": 1700000,
"eip145Transition": 4230000,
"eip1014Transition": 4230000,
"eip1052Transition": 4230000,
"eip1283Transition": 4230000
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@@ -53,8 +58,8 @@
"gasLimit": "0x1000000" "gasLimit": "0x1000000"
}, },
"hardcodedSync":{ "hardcodedSync":{
"header": "f9020fa0a415a8dcd55fe9c93372da415ff6897036e48cd3c1a5ff8ffe119eea1096ecd6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479443d58f2096e015db88e44346e73d8c59cb1753bda0100f05d66d36782b7c061c724d8d07619cc61053eda41badc8d2cb9292898ebaa00a60317b490365f40f0528e1f559b0f49facb6638c82a9490d368e963647c704a0118b536c3bdabf90273d527dfc26914c7878176fff16cee8fbb150e00ffcdd29b9010000000000000000040000002040000000000000000000000000000000000000000040020000000000010800000000000010000000000200000800000000600400000000080100c000004002080000000045000000008000080000000020000200404010010200010004000000000008020000008000000000000000108010440000800080000400010000080010820008000410800000100000000000000000000240244000000010000000000010010000000000002000000000000000000004000000020000001000002000000000000000013000000100000800008000200000104000000000000080000080200402010000000000000000001020000008008501602a8414833bc8018347b7a983476d40845b838083904d696e656420627920416e74506f6f6ca0f540bc9cfa258b97576bfb9a79518b2c07ed73a98bc6baa61cf7af4b40ad5b6988965658a406315a8a", "header": "f90217a00f0e017311206b97b47403eba05a16ada760a691a36f844ab8bc9082a4efedc9a067baeee20ae4f4216ab4b0c41198efd376aca23e44b1d6575c5949955547b72a946a9ecfa04e99726ec105517ac7ae1aba550bea6ca0e64d4fe9bee34d98e127f7f94f17535582d5bc6eeb6219f323b046b9a98c72b5a02d33ce5daab0436707c6d958dcf0bcd311ec7a72d7b33c20784178d5d95bc6e9a0a5b9cd4802fafaa9381ec0aa745cdb7ac953675e9df89474e5fe14fee134cf87b90100000008018000100000000000800000010000000050004000800000800014200010000001000000000001009001000000000000000000000000000000006004020600000000200001000108088002260441000020204000000000000000000280000000000200010001000000041008002000000004004c000000001000000000008000000000000800000400000201000000044001145000000000000001000a0200c04000a00010080100000020000000400002040000000000040000000040200001020000401000000800080080000400010000000200000008020020200000101000000000100400000000004400010020000200000000000001000000008453461c8683402001837a1200832c5216845bbd359199d88301080f846765746888676f312e31302e31856c696e7578a0c1da176f6642888b4369e14349ca7dc125ef7d4f5f7abad61bd7f6b95bfd46bf887d1a171a9f55dd67",
"totalDifficulty": "9811143388018700", "totalDifficulty": "12027449412394243",
"CHTs": [ "CHTs": [
"0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a", "0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a",
"0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc", "0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc",
@@ -1968,7 +1973,146 @@
"0xb652952de1bf9e1174e5f6a37b069b437792672a37a9e0159c4f36b6e64306b4", "0xb652952de1bf9e1174e5f6a37b069b437792672a37a9e0159c4f36b6e64306b4",
"0xb72dd6cb5df1b00dbbd84e097e2da79af2ce60559697ab4c93b0a8b85b2ee406", "0xb72dd6cb5df1b00dbbd84e097e2da79af2ce60559697ab4c93b0a8b85b2ee406",
"0xb96fd4a94ac30c10f757691f7f06f25a4900fe424f4eb7ccf322e2f95249b914", "0xb96fd4a94ac30c10f757691f7f06f25a4900fe424f4eb7ccf322e2f95249b914",
"0x99fd442599036f161ccef1ae8088c5ef694c1819f5b76d9d2fa8f979935f69f8" "0x99fd442599036f161ccef1ae8088c5ef694c1819f5b76d9d2fa8f979935f69f8",
"0x3e53574f6ae31a45ef928f9c37bea6c61e6d728a5ade9851567d3167f5ca3314",
"0xd7e3d08c5b71a7ad8338e8b51ec54cb11ad4d643d129a371af07376f8c47c1d4",
"0x1033c8aed4ec46377f75cc9a6b3297e1da0a7d1e74df20bae9fdf6d037afdc28",
"0x924d621544f3301f9e212fbb95872fce9eb4a4172a11693674de733bfc2b0018",
"0x7f61884149ea4def1444a70c022da1c23f31ecc51bb175905b492236a57c7fde",
"0x40c50785bc0665ab4eb3cec95405e17510c571570a5859ead804530dbcbd1387",
"0xf806491cf778f4796c0f73428e6eaf237da8488af99e9b61d72c56fa03e7051c",
"0x7a9670842dcb12c66f11e357a84849cee227ea5a7351e7c6c9370e9ef2560129",
"0x1c974da4e1073157c10deac8b256c8ced77a030e0500b2b8a90b6ca1d32ab4fa",
"0x97ebcc81ba9c1e04865ee4617daa967dec39f65501be21fbbe929db869d57dd8",
"0xa36e4506065d8b9c662697b18ffe50ed2f6ccfe6d07a065bdad048778cc53668",
"0xb9d5566eb0d40bbb03114d333d1d1dc85b0e780ec63229f3b93b2c84af5f9509",
"0xcd16693573724880c3c83834d516be65c35a861b76b43878e28aa7fcbc961361",
"0x4f60ecd7811acc087fc4557fdfaa1a0b522fe30da1cbae5e7740eec3cff04c00",
"0x9e58573b152bf5008e0ea3fc0d64573211916521a62fb08ba0f1b44c5da12e7d",
"0x2c6693cfd7e5bf9a3d8cef9e186b3da25d07af983564ced6238f9191b020f105",
"0x8cc6149caeafef85ec7b2456f33530459c52b30a5365a2a0022b1c308357f7b4",
"0x6f66863bd9909f687523128569cd0894c4cf41e2eddd5cd9c20d30c446b1711b",
"0x402317752053e7b6d7e2d5512d6397112d80ace0873f5f9d32c023a402ec03b3",
"0x2fcd50a79495057908bd34875e3531e6298488f0d06d043fb6fb0b140895d379",
"0x533ba9669dcee2c6e35713c7eca3bca168a326a36b0e39fcde76cbd35ab3d99d",
"0xdc2e86503e8066bc5fac91fe63544e33568a3c744967b9360458101c3d9df096",
"0xf994b38ba312d8bfb00d428b13a088738d93965b525eae81b45b9be344f99fd2",
"0x0721f3f772958d6a58dba638453b8d004e0c76dc8b4cf6d595b712edddcf002f",
"0x3c650c2c7ebbe7879a15882c3157552e8ae1adebea8f0c65a2dda272cc4ed838",
"0x649fe38e87546703245a7adf5925e8c7a07942750e14d39553a56ca3fcbd8c65",
"0xad204bf42d2a444faa864df8e9d023483a6b6daaa8001e00bb5373a45ed064a3",
"0x2c5cdc73d8ddef2e5c0d47358ac180043e7e246e590a7e8ad2b0a3f9b4e9375d",
"0xf38f6c364bbbbe626e849ca9bb9324c54cf0ba8dfc0b2741a3ff87ce7734adbc",
"0x317efc1cea774849d6219d31c8464a15956da4f3810bf15d4353443f79d98e75",
"0xb6796dccdf4d3cab16b5ec9567237cb988ee94131f3262c2a581180b775e76de",
"0x1fde3fdf2303d080d400c43345a424f50f6551a6a06ad50c6e277d49e8034df3",
"0x4d7bc44a3b56f5e69fd3e5e8c0cd8f5f839a775c4ee381b4b1d0a36656cf91cc",
"0x6051b60fdced0c51aa6a1cab2418c8f21c5d174109d514a4c6de758b2056611b",
"0x3c2f7be830078af3c2c6d1557b3da74d1d5bbfd8094f98886a959aa71ce70b15",
"0x8f296b90a0ece0a3dbec19a801072497c5840f9c0491062cd402db00c2b69f2a",
"0x6c14c4697f8291dbdfdbfea5522798e3f8b17204f80d8370e6d379e6ee659e77",
"0x4e98f63afaa50f8a30b0d352eb5fcb5403c635cf54b41545aa8b48465d23fb1d",
"0xad3059433e981ff12cd0d7dbc11a8d92a65cb39c6e936e9c7db5934d45806492",
"0x1cbb21f28ad2d191d6850c97487e5a733306f2f6ba370723fd5ed37cf6c880a0",
"0x82a0010a1b20d383bff0e5d7ba3751bc0d9161a4817554432558c5c2825babb3",
"0x33e54e93443e87c003d582dc51d0b9981ddcaeac4df0993877739651cbf52a58",
"0x1de8bc150f4142cd45b5d0784e5952abd8de7cba9654af959498c0fd0bcac404",
"0x3ee852f48a1a930d671e53c9c8d8c3c38353ee1737c093960c3f841e6c682e94",
"0xa9c6e05ec91e2a2f2f003419063fe033e37e5353c6e233706e29c08693e35eb8",
"0x649f7328064c55c03249d527dadaedcdbb4cb0e939d94c866844192d99469e05",
"0x3a407d00efcd5fe7bb765347b1a3f231b744349269b3aeb44099f4bdd068eb9e",
"0xa1a20af2f7e61082810ce7e7afe6118bc0ad95e9641e6129027f46af28048107",
"0x0d68fc5e58cacb2d16d99a0e9e612d674754ea51cbee2c68a21f4b0aa926688c",
"0x9b3e58144c014343271c9dc90daa8d2f642954b3eda223d64bbb0ac41380e512",
"0xd3de08b676d4f06bbf4322ed4340caab76e6ab7144c97af91c2bc9c749e65b38",
"0x21d626c9c38087aac6262b64f09398be6e4cbf246100d8c2416cab57e9ac1b68",
"0x563a450e35f40279f5946641a823f596ef3ad22a45b8ec280128546aeb0faf14",
"0xadd9c7128e14e670c7d21d6dfa5c09a11dfd237e90709b087e3329d3cd89b5fd",
"0x258cc0f845d8e7438a707f590f55203c6c51302cef4cfbf788b1c7054688da14",
"0x4309676aa14fa8244e0a089c7013b89c9adf57fa952295b8ddb23fc6545c9870",
"0x5db769765dfb41aefc0f40f06f3d005b30ce1f14f04f653e0c5500f651cd61cb",
"0xbef131c9f19572b05d295d7122fd1a09fe4a8afd4e20c5a0f3cd2785b7eb9882",
"0x3f235228ea537332a041ec75cc6cb5663edaa1c2ed1c1700273af73a5d49bf1c",
"0xc081811bb077c6ebe224b560eb6b81f3f813b26789cb06d96110071ffc25fcb4",
"0x912444c19a5e458b79c89969ed5336f2873267baf2fe729b6f218b74d269b797",
"0x5846fc726eb9627e9d070041b92d76191c4b32e315d33ad18121b8acd01634fd",
"0xc899f45494660034d343670856c13a32b230d047434a4d54a772132ddfe3e182",
"0x11a699c18b04e8cdcd96a43b7465f7bd81f8f64d7ebe79dcaf9201cc897f2746",
"0x8e09b134dc8a1735c060175e9688fd001974bf2e3baa5a8e88dc4c87365e0e07",
"0xa086797ebca0a1d446a9289b7eda920b926e1b595c288a9dea31ad225e6de86f",
"0x0cc04369b6036dff78a9856a5173bb2dde380359a8dbe0126e06d6e763a01c36",
"0x4b5efcac86e03d1f67774769b8bcc5d131c181cd4fa297eaa6cea5ec0cdfaa6f",
"0x47272a21a07ad5e14e3f97b237dab7e33344da4db5b2d31bc7cd0cc2d2c9f1db",
"0x9540755fd321d125b73cb6f1884c2f0b2a821d29362194f5029a5e7ba2d3ed44",
"0x229b88922fe52a78090673775f264cd665fe222002d6add2ed29b7ffd98de717",
"0x8fa2d755d5cc0efb01d9fd6f5ae1f7864404ae111d8ba17e23686ea9b6566336",
"0x33a8f2e0775fd19b1302b985bd6c29d4ab5fc63060bcf3df2c3685ab1b19ce67",
"0xf6d6bebb541ef9b84d779c62adb76774bb38a8eba3823e74e0790dc7401bebbc",
"0xa1f421108d49ed23996e55012613fc05e0f86e00f17251b1ff1e0824d35befc7",
"0x2cc572ed83dc6c604bb455ab050c550184a923f4b13815f06d10ef19dffb3c7a",
"0x28220e7d1a9583d68656f03ef4d6fa3e249c71d1b42698f87ba1fc582493e194",
"0xe8aa37b3214abb1bc167fdb6f10119a4019541f31c76b3b3f8c363bb138bd09e",
"0x825189c2c836dda454b457a03ff83d422bf78df1f368434768690fa7f51c57e0",
"0x5dad65d275e69478c81ecaec5b872660205735d9649ac020f65f5ea6ae972dda",
"0x84a1184d8f94fab280e0593479179348f9184d6fe5a2b2ea9697894c42574473",
"0xbef5a05bc7e1fb94465570144499672d95f31fa241b4c510011f6677e2bf72fb",
"0xd08235ebe6d79a8549bcd3d2414cd8afd2a3e2ca22ced226c60aacad1361ff89",
"0xbab5204ad45ec52860023e7474579e7c95397f3c4ac01db7e446e92c19dceef0",
"0x6c81acf2ff161d423a904c457166ff454ef41571d01e73d56bf9ab892790248d",
"0xaf4a603b808e3ddece42e3e123ea02defb9f8ef2546a95c5a617b6ecdb89c306",
"0xeecdbda25b04eb764e322d9a1e5eefad399c9ced8c77b1e4ecfbefcc90bb403d",
"0x9463f4677a2039ca372b61b16d5bcb7c043b26af04aea4d3f0dcdec7bd222070",
"0x27bfd92799b4cf9699d2bfcb158f6727bb986fc0dee780fc1052366ebc4e6364",
"0x63c3faa1a8fc0d531261cd241b1299d4fc13629abb4cd357eeb130505fbddf94",
"0x9a4535b07ff68862f3396b14b88fa07cff7abdd5744775aeeec6868606eb4712",
"0xae59e7c3e0a1df32f6e027da2983d3c55b4ba4d99e85329361561bd7f13ac629",
"0xcc5dc26b9be8fd8432537d967afe12fc668949e4fcf72d97a40f9214975fa57a",
"0x8f11634c83c7a43be8b98335ba617a64c6379f5f92664055c5e1620791134ddb",
"0x14ce2a69d844e6a46aa244c5aca9fb74c127f2151c7c16f4611ca030df365d8b",
"0xb06f220566a5e62570b9e9e49a8b9d5663501ba145b12260fbf9d4a18a4b19e3",
"0x6274f3cf553c45e6ba7ef644d75bf208e08a8c6325e336aefd35dda9cca3c4d2",
"0xd0d685497c2f2b923d0b9f1590a748da8c684a915a470db58c3105c83d8304e7",
"0xf37fab515f96e655f182f0b6e6aa3602f2cd74773329094772151e8c33d1f9a4",
"0xf6efd731481e8553f1d18b5735166499e787009b484b0dfbe4d35e7930f0d837",
"0xc96132b510863e553e08c54e98b5e9c0067f26e421980a6a3bfd4f07480c4396",
"0xdca9d8182c573871b6d6a184cb9819256398080bcb7fd765e6c69cd972a28d8d",
"0xd632ca6f5d45646726ecd2977ffea5c71a867890633f571b359657c0d096f840",
"0xfe3884dbca6bd3b0087466b04e6a5857ad59d7a25021e1d994d059d20005185b",
"0x7f40eb6fb94b05bb43873a98e9d4eb5f7ac90fb8913240bc0909c6be42922b30",
"0x5113a0808666815cfc52b8ed63c649d96f35c365def36ae623f536241b163c3f",
"0x8e6dbacfb5c593d7d7c2650d3d0115c3702cbb55f73011823a202e69ca33cc70",
"0x8f069ac7caa48bce09fe93f4aaef6784d8a6f7a3a09edb82c7512ec18acc3ab9",
"0xa5525e51fd789c59d3b208efffe09abca47cfd6981d36ab44084b86706c69888",
"0xcb4a7e60d5e8b9d22887ef1e8ce339cfcea0ae1fcbfa9adb766ad05d84182de7",
"0x0a14f23f9066ebdb67df31e66f6b8ab1c089025c0ba56ea56d15f73749f47cb7",
"0x0963e3eba12e41d21af7625b8dc487b637b1789a6ac05fb23062e0166942df68",
"0xcb7ec271b2f42cae0027d22b688b19b9288f2b5d9c43bc5b1ea23b35f5542828",
"0x9b97e6f4b2eeee29ecccf9584dc020c8caa3cae51c82f5b58d279eaf0c6ab4e3",
"0xad7f1963ce9993e6172c2ae90c6e1d4d3d3c52e14284fcc1b1e9a56776afb97e",
"0x52ef2ad7bc2921742dcbac9772f13d5c31be938eb1ad6aceb2fa8a163389cefa",
"0x369ead6d900e64ae0b5028df8574e59b67c61dca418c87ce6461eb4c8535fd30",
"0x7e1a18f6199f05f21f9eb5463e9ffd87637d2fd24a23047fe095895c533cb6a5",
"0xe1b8813a95e511aaec9b358d515e624fbc20e551c56328f843ae90b3c895d3a2",
"0xc2ea59f3d1e7bbe115390a4c210142fe9f9dcb1959764450f5b5292ad90e0fcf",
"0x97d235c3f18e6819c08dab4efe66d0f11f0d06f8ffc9686e3f28400e057e6f4a",
"0xea64f817770252b77b08ca2f579b440ec02e833fc88af7c9c96a8e1e07b2cb2c",
"0x185f5fd1f7001b533dc01783c83b7ab0828a4e2f188cc4e26768c515b4c421f6",
"0x0c9de9844e856a1e4340bf54dcaf9dc66b489304765b5c3c6ca20284f5a0dca6",
"0x4dd1d52da1d260d1f0f63bafc4c816b30cea8ec3434e7d4b63a0eff86997254c",
"0x0b3eb94aa246f7c8c871535ae2d3abe5c1b951e76b77510140ef52d5ea2457ee",
"0x27102708eea5d715799642f213049d8ac9abc3b12c76d147ce443dab28af96d8",
"0x81fb3c4e8dc6c658af2901b7aebf7467b9ae045dd0f58fe8d77f8770ac517fb6",
"0xf68dba4eee635d7494bae6fb9f0c44e739b3121d4bc6f6f21b495a716af3cf52",
"0xcf87b723dc473d313bf9ddfa233056036c5658777e831796f1f56647cd040c8d",
"0x49927c2100039ac496d9c16dd12f0a05c9441b8616c69c726fd2e79ae65e130c",
"0x088195c7251f6b9fa2105e77df5620211b8ca783a77f1a98de6752fc442c26c7",
"0x604de480bcb88e908b90451c4142b99b9cbb479167473befca7bea9b4ca427a3",
"0x642fdaf6bc1abbf261a9480fcf9bb48cf03fb80bdd434c6ab63401856c74fa39",
"0xe6b596393fce7a3023a316ac34a1fac18e18779ca5983791866f857f257592e1",
"0x40384a52564fae5df8c3e41827cdf584e38f3f555a54ca749b7b516619071d85",
"0xe52f7c17a4106594563ae7b724e5613e87d8442177f39a36b946b0e335be0e5b",
"0x7726202a7c255a9d7be47af6f3b44c1e379cda61237866554396fb6ec043482c",
"0x665da353f296cde80e3cbcb9c7f93b107d5676e5cd694b0bd33334d74789beb9"
] ]
}, },
"nodes": [ "nodes": [

View File

@@ -27,8 +27,7 @@
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff",
"eip155Transition": "0x0", "eip155Transition": "0x0",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff"
"eip86Transition": "0x7fffffffffffff"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

View File

@@ -0,0 +1,468 @@
{ "block":
[
{
"reference": "9590",
"failing": "stCreateTest",
"subtests": [
"CreateOOGafterInitCodeReturndata2_d0g1v0_Constantinople"
]
},
{
"reference": "9590",
"failing": "stCreate2",
"subtests": [
"RevertDepthCreateAddressCollision_d0g1v0_Constantinople",
"RevertDepthCreateAddressCollision_d1g1v1_Constantinople",
"CREATE2_Suicide_d5g0v0_Constantinople",
"CREATE2_Suicide_d7g0v0_Constantinople",
"create2collisionSelfdestructedOOG_d2g0v0_Byzantium",
"create2collisionSelfdestructedOOG_d2g0v0_Constantinople",
"create2collisionNonce_d1g0v0_Byzantium",
"create2collisionNonce_d1g0v0_Constantinople",
"CreateMessageRevertedOOGInInit_d0g1v0_Constantinople",
"create2callPrecompiles_d3g0v0_Constantinople",
"create2collisionCode_d1g0v0_Byzantium",
"create2collisionCode_d1g0v0_Constantinople",
"create2collisionStorage_d0g0v0_Byzantium",
"create2collisionStorage_d0g0v0_Constantinople",
"create2callPrecompiles_d4g0v0_Constantinople",
"create2collisionSelfdestructedRevert_d0g0v0_Byzantium",
"create2collisionSelfdestructedRevert_d0g0v0_Constantinople",
"CreateMessageReverted_d0g1v0_Constantinople",
"RevertOpcodeCreate_d0g1v0_Constantinople",
"CREATE2_Suicide_d11g0v0_Constantinople",
"create2checkFieldsInInitcode_d5g0v0_Constantinople",
"create2collisionSelfdestructedOOG_d1g0v0_Byzantium",
"create2collisionSelfdestructedOOG_d1g0v0_Constantinople",
"returndatacopy_following_create_d1g0v0_Constantinople",
"RevertDepthCreate2OOG_d1g1v1_Constantinople",
"create2collisionSelfdestructed_d2g0v0_Byzantium",
"create2collisionSelfdestructed_d2g0v0_Constantinople",
"create2callPrecompiles_d2g0v0_Constantinople",
"create2InitCodes_d2g0v0_Constantinople",
"create2collisionNonce_d2g0v0_Byzantium",
"create2collisionNonce_d2g0v0_Constantinople",
"create2collisionCode_d0g0v0_Byzantium",
"create2collisionCode_d0g0v0_Constantinople",
"CREATE2_Bounds_d0g0v0_Constantinople",
"RevertDepthCreate2OOG_d0g0v0_Constantinople",
"CREATE2_Suicide_d1g0v0_Constantinople",
"CREATE2_Bounds3_d0g1v0_Constantinople",
"create2collisionStorage_d2g0v0_Byzantium",
"create2collisionStorage_d2g0v0_Constantinople",
"RevertDepthCreateAddressCollision_d0g0v1_Constantinople",
"create2callPrecompiles_d5g0v0_Constantinople",
"create2collisionCode2_d0g0v0_Byzantium",
"create2collisionCode2_d0g0v0_Constantinople",
"create2noCash_d0g0v0_Byzantium",
"create2noCash_d0g0v0_Constantinople",
"create2checkFieldsInInitcode_d7g0v0_Constantinople",
"create2SmartInitCode_d1g0v0_Constantinople",
"create2InitCodes_d6g0v0_Constantinople",
"create2noCash_d1g0v0_Byzantium",
"create2noCash_d1g0v0_Constantinople",
"CREATE2_ContractSuicideDuringInit_ThenStoreThenReturn_d0g0v0_Constantinople",
"RevertOpcodeInCreateReturns_d0g0v0_Constantinople",
"create2collisionStorage_d1g0v0_Byzantium",
"create2collisionStorage_d1g0v0_Constantinople",
"create2checkFieldsInInitcode_d3g0v0_Constantinople",
"create2collisionBalance_d0g0v0_Byzantium",
"create2collisionBalance_d0g0v0_Constantinople",
"create2collisionSelfdestructed2_d0g0v0_Constantinople",
"create2InitCodes_d3g0v0_Constantinople",
"create2collisionCode2_d1g0v0_Byzantium",
"create2collisionCode2_d1g0v0_Constantinople",
"create2checkFieldsInInitcode_d1g0v0_Constantinople",
"create2collisionBalance_d1g0v0_Byzantium",
"create2collisionBalance_d1g0v0_Constantinople",
"CREATE2_Bounds3_d0g2v0_Constantinople",
"create2callPrecompiles_d6g0v0_Constantinople",
"Create2Recursive_d0g0v0_Constantinople",
"create2collisionSelfdestructedOOG_d0g0v0_Byzantium",
"create2collisionSelfdestructedOOG_d0g0v0_Constantinople",
"CREATE2_Suicide_d3g0v0_Constantinople",
"returndatacopy_following_create_d0g0v0_Constantinople",
"create2InitCodes_d8g0v0_Constantinople",
"RevertDepthCreate2OOG_d0g0v1_Constantinople",
"create2checkFieldsInInitcode_d2g0v0_Constantinople",
"RevertDepthCreate2OOG_d1g0v1_Constantinople",
"Create2OnDepth1024_d0g0v0_Constantinople",
"create2collisionSelfdestructed2_d1g0v0_Constantinople",
"create2collisionSelfdestructedRevert_d2g0v0_Byzantium",
"create2collisionSelfdestructedRevert_d2g0v0_Constantinople",
"create2callPrecompiles_d0g0v0_Constantinople",
"RevertDepthCreateAddressCollision_d0g1v1_Constantinople",
"create2collisionSelfdestructed_d1g0v0_Byzantium",
"create2collisionSelfdestructed_d1g0v0_Constantinople",
"call_outsize_then_create2_successful_then_returndatasize_d0g0v0_Byzantium",
"call_outsize_then_create2_successful_then_returndatasize_d0g0v0_Constantinople",
"Create2OOGafterInitCodeRevert_d0g0v0_Constantinople",
"Create2OOGafterInitCodeReturndata3_d0g0v0_Constantinople",
"Create2OOGafterInitCodeReturndataSize_d0g0v0_Constantinople",
"create2InitCodes_d7g0v0_Constantinople",
"CREATE2_Suicide_d10g0v0_Constantinople",
"RevertDepthCreate2OOG_d0g1v0_Constantinople",
"create2InitCodes_d5g0v0_Constantinople",
"create2collisionSelfdestructedRevert_d1g0v0_Byzantium",
"create2collisionSelfdestructedRevert_d1g0v0_Constantinople",
"RevertDepthCreate2OOG_d1g1v0_Constantinople",
"create2collisionSelfdestructed_d0g0v0_Byzantium",
"create2collisionSelfdestructed_d0g0v0_Constantinople",
"create2noCash_d2g0v0_Byzantium",
"create2noCash_d2g0v0_Constantinople",
"CREATE2_Bounds3_d0g0v0_Constantinople",
"create2collisionNonce_d0g0v0_Byzantium",
"create2collisionNonce_d0g0v0_Constantinople",
"CREATE2_Suicide_d2g0v0_Constantinople",
"Create2OOGafterInitCode_d0g0v0_Constantinople",
"call_then_create2_successful_then_returndatasize_d0g0v0_Byzantium",
"call_then_create2_successful_then_returndatasize_d0g0v0_Constantinople",
"create2collisionBalance_d2g0v0_Byzantium",
"create2collisionBalance_d2g0v0_Constantinople",
"create2checkFieldsInInitcode_d6g0v0_Constantinople",
"RevertDepthCreate2OOG_d0g1v1_Constantinople",
"returndatacopy_afterFailing_create_d0g0v0_Constantinople",
"returndatacopy_following_revert_in_create_d0g0v0_Constantinople",
"CREATE2_Suicide_d9g0v0_Constantinople",
"create2callPrecompiles_d7g0v0_Constantinople",
"RevertDepthCreateAddressCollision_d1g0v1_Constantinople",
"create2InitCodes_d1g0v0_Constantinople",
"CREATE2_Bounds_d0g1v0_Constantinople",
"Create2OOGafterInitCodeReturndata_d0g0v0_Constantinople",
"create2checkFieldsInInitcode_d4g0v0_Constantinople",
"CreateMessageRevertedOOGInInit_d0g0v0_Constantinople",
"RevertDepthCreateAddressCollision_d1g1v0_Constantinople",
"returndatacopy_following_successful_create_d0g0v0_Constantinople",
"create2checkFieldsInInitcode_d0g0v0_Constantinople",
"CreateMessageReverted_d0g0v0_Constantinople",
"create2SmartInitCode_d0g0v0_Constantinople",
"CREATE2_Bounds2_d0g0v0_Constantinople",
"returndatasize_following_successful_create_d0g0v0_Constantinople",
"CREATE2_Bounds2_d0g1v0_Constantinople",
"returndatacopy_0_0_following_successful_create_d0g0v0_Constantinople",
"RevertDepthCreateAddressCollision_d0g0v0_Constantinople",
"CREATE2_Suicide_d0g0v0_Constantinople",
"create2InitCodes_d0g0v0_Constantinople",
"Create2OnDepth1023_d0g0v0_Constantinople",
"create2InitCodes_d4g0v0_Constantinople",
"Create2OOGafterInitCodeReturndata2_d0g0v0_Constantinople",
"create2collisionBalance_d3g0v0_Byzantium",
"create2collisionBalance_d3g0v0_Constantinople",
"CREATE2_Suicide_d4g0v0_Constantinople",
"Create2OOGafterInitCode_d0g1v0_Constantinople",
"RevertDepthCreateAddressCollision_d1g0v0_Constantinople",
"Create2OOGafterInitCodeRevert2_d0g0v0_Constantinople",
"Create2OOGafterInitCodeReturndata_d0g1v0_Constantinople",
"Create2Recursive_d0g1v0_Constantinople",
"create2collisionCode_d2g0v0_Byzantium",
"create2collisionCode_d2g0v0_Constantinople",
"CREATE2_Suicide_d6g0v0_Constantinople",
"CREATE2_Suicide_d8g0v0_Constantinople",
"RevertOpcodeCreate_d0g0v0_Constantinople",
"Create2OOGafterInitCodeReturndata2_d0g1v0_Constantinople",
"create2callPrecompiles_d1g0v0_Constantinople",
"RevertInCreateInInit_d0g0v0_Constantinople",
"RevertDepthCreate2OOG_d1g0v0_Constantinople"
]
},
{
"reference": "9590",
"failing": "bcStateTest",
"subtests": [
"suicideStorageCheck_Byzantium",
"suicideStorageCheck_Constantinople",
"suicideStorageCheckVCreate2_Byzantium",
"suicideStorageCheckVCreate2_Constantinople",
"create2collisionwithSelfdestructSameBlock_Constantinople",
"blockhashNonConstArg_Constantinople",
"suicideThenCheckBalance_Constantinople",
"suicideThenCheckBalance_Homestead",
"suicideStorageCheckVCreate_Byzantium",
"suicideStorageCheckVCreate_Constantinople"
]
},
{
"reference": "9590",
"failing": "stEIP158Specific",
"subtests": [
"callToEmptyThenCallError_d0g0v0_Byzantium",
"callToEmptyThenCallError_d0g0v0_Constantinople",
"callToEmptyThenCallError_d0g0v0_EIP158"
]
},
{
"reference": "9590",
"failing": "stPreCompiledContracts",
"subtests": [
"identity_to_smaller_d0g0v0_Constantinople",
"identity_to_bigger_d0g0v0_Constantinople"
]
},
{
"reference": "9590",
"failing": "stReturnDataTest",
"subtests": [
"modexp_modsize0_returndatasize_d0g1v0_Constantinople",
"modexp_modsize0_returndatasize_d0g2v0_Constantinople",
"modexp_modsize0_returndatasize_d0g3v0_Constantinople"
]
},
{
"reference": "9590",
"failing": "stSpecialTest",
"subtests": [
"push32withoutByte_d0g0v0_Constantinople"
]
}
],
"state":
[
{
"reference": "9590",
"failing": "stCreateTest",
"subtests": {
"CreateOOGafterInitCodeReturndata2": {
"subnumbers": ["2"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "9590",
"failing": "stCreate2Test",
"subtests": {
"RevertInCreateInInit": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "9590",
"failing": "stEIP150Specific",
"subtests": {
"NewGasPriceForCodes": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "9590",
"failing": "stInitCodeTest",
"subtests": {
"OutOfGasContractCreation": {
"subnumbers": ["4"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "9590",
"failing": "stPreCompiledContracts",
"subtests": {
"modexp": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "9590",
"failing": "stRevertTest",
"subtests": {
"LoopCallsDepthThenRevert3": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
},
"RevertOpcodeCreate": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
},
"RevertSubCallStorageOOG2": {
"subnumbers": ["1","3"],
"chain": "Constantinople (test)"
},
"RevertDepthCreateOOG": {
"subnumbers": ["3","4"],
"chain": "Constantinople (test)"
},
"RevertOpcodeMultipleSubCalls": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"RevertOpcodeDirectCall": {
"subnumbers": ["1","2"],
"chain": "Constantinople (test)"
},
"LoopCallsDepthThenRevert2": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
},
"RevertDepth2": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
},
"RevertRemoteSubCallStorageOOG2": {
"subnumbers": ["1","2"],
"chain": "Constantinople (test)"
},
"RevertDepthCreateAddressCollision": {
"subnumbers": ["3","4"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "9590",
"failing": "stStaticCall",
"subtests": {
"static_RevertDepth2": {
"subnumbers": ["1","3"],
"chain": "Constantinople (test)"
},
"static_CheckOpcodes4": {
"subnumbers": ["3"],
"chain": "Constantinople (test)"
},
"static_CheckOpcodes3": {
"subnumbers": ["5","6","7","8"],
"chain": "Constantinople (test)"
},
"static_callBasic": {
"subnumbers": ["1","2"],
"chain": "Constantinople (test)"
},
"static_CheckOpcodes2": {
"subnumbers": ["5","6","7","8"],
"chain": "Constantinople (test)"
},
"static_callCreate": {
"subnumbers": ["2"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "https://github.com/ethereum/tests/issues/512",
"failing": "stZeroKnowledge",
"subtests": {
"pointAddTrunc": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"pointAdd": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"pointMulAdd": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"pointMulAdd2": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "9590",
"failing": "stCreate2Test",
"subtests": {
"call_then_create2_successful_then_returndatasize": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
},
"returndatacopy_afterFailing_create": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
},
"create2checkFieldsInInitcode": {
"subnumbers": ["1","2","3","5","6","7"],
"chain": "Constantinople (test)"
},
"Create2Recursive": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"create2collisionBalance": {
"subnumbers": ["2","3"],
"chain": "Constantinople (test)"
},
"create2InitCodes": {
"subnumbers": ["1","5","6","7","8","9"],
"chain": "Constantinople (test)"
},
"Create2OOGafterInitCode": {
"subnumbers": ["2"],
"chain": "Constantinople (test)"
},
"CreateMessageRevertedOOGInInit": {
"subnumbers": ["2"],
"chain": "Constantinople (test)"
},
"returndatacopy_following_revert_in_create": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"create2collisionSelfdestructed": {
"subnumbers": ["2"],
"chain": "Constantinople (test)"
},
"returndatacopy_0_0_following_successful_create": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"Create2OnDepth1023": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"Create2OOGafterInitCodeReturndata2": {
"subnumbers": ["2"],
"chain": "Constantinople (test)"
},
"RevertOpcodeInCreateReturns": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"CREATE2_ContractSuicideDuringInit_ThenStoreThenReturn": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"returndatasize_following_successful_create": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"call_outsize_then_create2_successful_then_returndatasize": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"CreateMessageReverted": {
"subnumbers": ["2"],
"chain": "Constantinople (test)"
},
"CREATE2_Suicide": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"Create2OOGafterInitCodeRevert": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"Create2OnDepth1024": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
},
"create2collisionStorage": {
"subnumbers": ["2","3"],
"chain": "Constantinople (test)"
},
"create2callPrecompiles": {
"subnumbers": ["*"],
"chain": "Constantinople (test)"
}
}
}
]
}

View File

@@ -16,7 +16,6 @@
"eip161dTransition": "0x0", "eip161dTransition": "0x0",
"eip155Transition": "0x0", "eip155Transition": "0x0",
"eip98Transition": "0x7fffffffffffff", "eip98Transition": "0x7fffffffffffff",
"eip86Transition": "0x7fffffffffffff",
"maxCodeSize": 24576, "maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0", "maxCodeSizeTransition": "0x0",
"eip140Transition": "0x0", "eip140Transition": "0x0",

View File

@@ -11,7 +11,6 @@
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x2", "networkID" : "0x2",
"eip86Transition": "0x7fffffffffffff",
"eip140Transition": "0x0", "eip140Transition": "0x0",
"eip211Transition": "0x0", "eip211Transition": "0x0",
"eip214Transition": "0x0", "eip214Transition": "0x0",

View File

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

View File

@@ -1296,9 +1296,7 @@ impl snapshot::DatabaseRestore for Client {
let mut tracedb = self.tracedb.write(); let mut tracedb = self.tracedb.write();
self.importer.miner.clear(); self.importer.miner.clear();
let db = self.db.write(); let db = self.db.write();
db.key_value().restore(new_db)?; db.restore(new_db)?;
db.blooms().reopen()?;
db.trace_blooms().reopen()?;
let cache_size = state_db.cache_size(); let cache_size = state_db.cache_size();
*state_db = StateDB::new(journaldb::new(db.key_value().clone(), self.pruning, ::db::COL_STATE), cache_size); *state_db = StateDB::new(journaldb::new(db.key_value().clone(), self.pruning, ::db::COL_STATE), cache_size);
@@ -1351,7 +1349,7 @@ impl BlockInfo for Client {
} }
fn code_hash(&self, address: &Address, id: BlockId) -> Option<H256> { fn code_hash(&self, address: &Address, id: BlockId) -> Option<H256> {
self.state_at(id).and_then(|s| s.code_hash(address).ok()) self.state_at(id).and_then(|s| s.code_hash(address).unwrap_or(None))
} }
} }
@@ -2022,10 +2020,6 @@ impl BlockChainClient for Client {
fn registrar_address(&self) -> Option<Address> { fn registrar_address(&self) -> Option<Address> {
self.registrar_address.clone() self.registrar_address.clone()
} }
fn eip86_transition(&self) -> u64 {
self.engine().params().eip86_transition
}
} }
impl IoClient for Client { impl IoClient for Client {
@@ -2317,14 +2311,13 @@ impl ProvingBlockChainClient for Client {
env_info.gas_limit = transaction.gas.clone(); env_info.gas_limit = transaction.gas.clone();
let mut jdb = self.state_db.read().journal_db().boxed_clone(); let mut jdb = self.state_db.read().journal_db().boxed_clone();
state::prove_transaction( state::prove_transaction_virtual(
jdb.as_hashdb_mut(), jdb.as_hashdb_mut(),
header.state_root().clone(), header.state_root().clone(),
&transaction, &transaction,
self.engine.machine(), self.engine.machine(),
&env_info, &env_info,
self.factories.clone(), self.factories.clone(),
false,
) )
} }

View File

@@ -60,7 +60,7 @@ impl fmt::Display for EvmTestError {
} }
use ethereum; use ethereum;
use ethjson::state::test::ForkSpec; use ethjson::spec::ForkSpec;
/// Simplified, single-block EVM test client. /// Simplified, single-block EVM test client.
pub struct EvmTestClient<'a> { pub struct EvmTestClient<'a> {
@@ -69,12 +69,12 @@ pub struct EvmTestClient<'a> {
} }
impl<'a> fmt::Debug for EvmTestClient<'a> { impl<'a> fmt::Debug for EvmTestClient<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("EvmTestClient") fmt.debug_struct("EvmTestClient")
.field("state", &self.state) .field("state", &self.state)
.field("spec", &self.spec.name) .field("spec", &self.spec.name)
.finish() .finish()
} }
} }
impl<'a> EvmTestClient<'a> { impl<'a> EvmTestClient<'a> {
@@ -86,9 +86,9 @@ impl<'a> EvmTestClient<'a> {
ForkSpec::EIP150 => Some(ethereum::new_eip150_test()), ForkSpec::EIP150 => Some(ethereum::new_eip150_test()),
ForkSpec::EIP158 => Some(ethereum::new_eip161_test()), ForkSpec::EIP158 => Some(ethereum::new_eip161_test()),
ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()), ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()),
ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()),
ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()), ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()),
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None, ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
_ => None,
} }
} }
@@ -205,7 +205,7 @@ impl<'a> EvmTestClient<'a> {
) -> TransactResult<T::Output, V::Output> { ) -> TransactResult<T::Output, V::Output> {
let initial_gas = transaction.gas; let initial_gas = transaction.gas;
// Verify transaction // Verify transaction
let is_ok = transaction.verify_basic(true, None, env_info.number >= self.spec.engine.params().eip86_transition); let is_ok = transaction.verify_basic(true, None, false);
if let Err(error) = is_ok { if let Err(error) = is_ok {
return TransactResult::Err { return TransactResult::Err {
state_root: *self.state.root(), state_root: *self.state.root(),
@@ -217,9 +217,27 @@ impl<'a> EvmTestClient<'a> {
let result = self.state.apply_with_tracing(&env_info, self.spec.engine.machine(), &transaction, tracer, vm_tracer); let result = self.state.apply_with_tracing(&env_info, self.spec.engine.machine(), &transaction, tracer, vm_tracer);
let scheme = self.spec.engine.machine().create_address_scheme(env_info.number); let scheme = self.spec.engine.machine().create_address_scheme(env_info.number);
// Touch the coinbase at the end of the test to simulate
// miner reward.
// Details: https://github.com/paritytech/parity-ethereum/issues/9431
let schedule = self.spec.engine.machine().schedule(env_info.number);
self.state.add_balance(&env_info.author, &0.into(), if schedule.no_empty {
state::CleanupMode::NoEmpty
} else {
state::CleanupMode::ForceCreate
}).ok();
// Touching also means that we should remove the account if it's within eip161
// conditions.
self.state.kill_garbage(
&vec![env_info.author].into_iter().collect(),
schedule.kill_empty,
&None,
false
).ok();
self.state.commit().ok();
match result { match result {
Ok(result) => { Ok(result) => {
self.state.commit().ok();
TransactResult::Ok { TransactResult::Ok {
state_root: *self.state.root(), state_root: *self.state.root(),
gas_left: initial_gas - result.receipt.gas_used, gas_left: initial_gas - result.receipt.gas_used,

View File

@@ -845,8 +845,6 @@ impl BlockChainClient for TestBlockChainClient {
} }
fn registrar_address(&self) -> Option<Address> { None } fn registrar_address(&self) -> Option<Address> { None }
fn eip86_transition(&self) -> u64 { u64::max_value() }
} }
impl IoClient for TestBlockChainClient { impl IoClient for TestBlockChainClient {

View File

@@ -377,9 +377,6 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra
/// Get the address of the registry itself. /// Get the address of the registry itself.
fn registrar_address(&self) -> Option<Address>; fn registrar_address(&self) -> Option<Address>;
/// Get the EIP-86 transition block number.
fn eip86_transition(&self) -> u64;
} }
/// Provides `reopen_block` method /// Provides `reopen_block` method

View File

@@ -984,8 +984,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
self.clear_empty_steps(parent_step); self.clear_empty_steps(parent_step);
// report any skipped primaries between the parent block and // report any skipped primaries between the parent block and
// the block we're sealing // the block we're sealing, unless we have empty steps enabled
self.report_skipped(header, step, u64::from(parent_step) as usize, &*validators, set_number); if header.number() < self.empty_steps_transition {
self.report_skipped(header, step, u64::from(parent_step) as usize, &*validators, set_number);
}
let mut fields = vec![ let mut fields = vec![
encode(&step).into_vec(), encode(&step).into_vec(),

View File

@@ -693,7 +693,6 @@ impl Engine<EthereumMachine> for Tendermint {
} }
fn stop(&self) { fn stop(&self) {
self.step_service.stop()
} }
fn is_proposal(&self, header: &Header) -> bool { fn is_proposal(&self, header: &Header) -> bool {

View File

@@ -36,8 +36,9 @@ use machine::EthereumMachine;
const SNAPSHOT_BLOCKS: u64 = 5000; const SNAPSHOT_BLOCKS: u64 = 5000;
/// Maximum number of blocks allowed in an ethash snapshot. /// Maximum number of blocks allowed in an ethash snapshot.
const MAX_SNAPSHOT_BLOCKS: u64 = 30000; const MAX_SNAPSHOT_BLOCKS: u64 = 30000;
/// Default number of blocks the difficulty bomb is delayed in EIP-{649,1234}
const DEFAULT_EIP649_DELAY: u64 = 3_000_000; const DEFAULT_EIP649_DELAY: u64 = 3_000_000;
const DEFAULT_EIP1234_DELAY: u64 = 2_000_000;
/// Ethash specific seal /// Ethash specific seal
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@@ -120,6 +121,12 @@ pub struct EthashParams {
pub eip649_delay: u64, pub eip649_delay: u64,
/// EIP-649 base reward. /// EIP-649 base reward.
pub eip649_reward: Option<U256>, pub eip649_reward: Option<U256>,
/// EIP-1234 transition block.
pub eip1234_transition: u64,
/// EIP-1234 bomb delay.
pub eip1234_delay: u64,
/// EIP-1234 base reward.
pub eip1234_reward: Option<U256>,
/// EXPIP-2 block height /// EXPIP-2 block height
pub expip2_transition: u64, pub expip2_transition: u64,
/// EXPIP-2 duration limit /// EXPIP-2 duration limit
@@ -152,6 +159,9 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into), eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into),
eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into), eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into),
eip649_reward: p.eip649_reward.map(Into::into), eip649_reward: p.eip649_reward.map(Into::into),
eip1234_transition: p.eip1234_transition.map_or(u64::max_value(), Into::into),
eip1234_delay: p.eip1234_delay.map_or(DEFAULT_EIP1234_DELAY, Into::into),
eip1234_reward: p.eip1234_reward.map(Into::into),
expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into), expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into),
expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into), expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into),
} }
@@ -233,8 +243,10 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
let mut rewards = Vec::new(); let mut rewards = Vec::new();
// Applies EIP-649 reward. // Applies EIP-{649,1234} reward, defaults to block_reward.
let reward = if number >= self.ethash_params.eip649_transition { let reward = if number >= self.ethash_params.eip1234_transition {
self.ethash_params.eip1234_reward.unwrap_or(self.ethash_params.block_reward)
} else if number >= self.ethash_params.eip649_transition {
self.ethash_params.eip649_reward.unwrap_or(self.ethash_params.block_reward) self.ethash_params.eip649_reward.unwrap_or(self.ethash_params.block_reward)
} else { } else {
self.ethash_params.block_reward self.ethash_params.block_reward
@@ -427,6 +439,9 @@ impl Ethash {
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 mut number = header.number(); let mut number = header.number();
if number >= self.ethash_params.eip1234_transition {
number = number.saturating_sub(self.ethash_params.eip1234_delay);
}
if number >= self.ethash_params.eip649_transition { if number >= self.ethash_params.eip649_transition {
number = number.saturating_sub(self.ethash_params.eip649_delay); number = number.saturating_sub(self.ethash_params.eip649_delay);
} }
@@ -510,6 +525,9 @@ mod tests {
eip649_transition: u64::max_value(), eip649_transition: u64::max_value(),
eip649_delay: 3_000_000, eip649_delay: 3_000_000,
eip649_reward: None, eip649_reward: None,
eip1234_transition: u64::max_value(),
eip1234_delay: 2_000_000,
eip1234_reward: None,
expip2_transition: u64::max_value(), expip2_transition: u64::max_value(),
expip2_duration_limit: 30, expip2_duration_limit: 30,
} }

View File

@@ -151,6 +151,9 @@ pub fn new_frontier_test_machine() -> EthereumMachine { load_machine(include_byt
/// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier. /// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier.
pub fn new_homestead_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/homestead_test.json")) } pub fn new_homestead_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/homestead_test.json")) }
/// Create a new Foundation Homestead-EIP210-era chain spec as though it never changed from Homestead/Frontier.
pub fn new_eip210_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/eip210_test.json")) }
/// Create a new Foundation Byzantium era spec. /// Create a new Foundation Byzantium era spec.
pub fn new_byzantium_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/byzantium_test.json")) } pub fn new_byzantium_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/byzantium_test.json")) }

View File

@@ -61,10 +61,13 @@ pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address,
stream.append(nonce); stream.append(nonce);
(From::from(keccak(stream.as_raw())), None) (From::from(keccak(stream.as_raw())), None)
}, },
CreateContractAddress::FromCodeHash => { CreateContractAddress::FromSenderSaltAndCodeHash(salt) => {
let code_hash = keccak(code); let code_hash = keccak(code);
let mut buffer = [0xffu8; 20 + 32]; let mut buffer = [0u8; 1 + 20 + 32 + 32];
&mut buffer[20..].copy_from_slice(&code_hash[..]); buffer[0] = 0xff;
&mut buffer[1..(1+20)].copy_from_slice(&sender[..]);
&mut buffer[(1+20)..(1+20+32)].copy_from_slice(&salt[..]);
&mut buffer[(1+20+32)..].copy_from_slice(&code_hash[..]);
(From::from(keccak(&buffer[..])), Some(code_hash)) (From::from(keccak(&buffer[..])), Some(code_hash))
}, },
CreateContractAddress::FromSenderAndCodeHash => { CreateContractAddress::FromSenderAndCodeHash => {
@@ -285,7 +288,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
let mut substate = Substate::new(); let mut substate = Substate::new();
// NOTE: there can be no invalid transactions from this point. // NOTE: there can be no invalid transactions from this point.
if !schedule.eip86 || !t.is_unsigned() { if !schedule.keep_unsigned_nonce || !t.is_unsigned() {
self.state.inc_nonce(&sender)?; self.state.inc_nonce(&sender)?;
} }
self.state.sub_balance(&sender, &U256::from(gas_cost), &mut substate.to_cleanup_mode(&schedule))?; self.state.sub_balance(&sender, &U256::from(gas_cost), &mut substate.to_cleanup_mode(&schedule))?;
@@ -320,7 +323,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
gas_price: t.gas_price, gas_price: t.gas_price,
value: ActionValue::Transfer(t.value), value: ActionValue::Transfer(t.value),
code: self.state.code(address)?, code: self.state.code(address)?,
code_hash: Some(self.state.code_hash(address)?), code_hash: self.state.code_hash(address)?,
data: Some(t.data.clone()), data: Some(t.data.clone()),
call_type: CallType::Call, call_type: CallType::Call,
params_type: vm::ParamsType::Separate, params_type: vm::ParamsType::Separate,
@@ -557,9 +560,9 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
let prev_bal = self.state.balance(&params.address)?; let prev_bal = self.state.balance(&params.address)?;
if let ActionValue::Transfer(val) = params.value { if let ActionValue::Transfer(val) = params.value {
self.state.sub_balance(&params.sender, &val, &mut substate.to_cleanup_mode(&schedule))?; self.state.sub_balance(&params.sender, &val, &mut substate.to_cleanup_mode(&schedule))?;
self.state.new_contract(&params.address, val + prev_bal, nonce_offset); self.state.new_contract(&params.address, val + prev_bal, nonce_offset)?;
} else { } else {
self.state.new_contract(&params.address, prev_bal, nonce_offset); self.state.new_contract(&params.address, prev_bal, nonce_offset)?;
} }
let trace_info = tracer.prepare_trace_create(&params); let trace_info = tracer.prepare_trace_create(&params);
@@ -610,7 +613,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
let schedule = self.machine.schedule(self.info.number); let schedule = self.machine.schedule(self.info.number);
// refunds from SSTORE nonzero -> zero // refunds from SSTORE nonzero -> zero
let sstore_refunds = U256::from(schedule.sstore_refund_gas) * substate.sstore_clears_count; let sstore_refunds = substate.sstore_clears_refund;
// refunds from contract suicides // refunds from contract suicides
let suicide_refunds = U256::from(schedule.suicide_refund_gas) * U256::from(substate.suicides.len()); let suicide_refunds = U256::from(schedule.suicide_refund_gas) * U256::from(substate.suicides.len());
let refunds_bound = sstore_refunds + suicide_refunds; let refunds_bound = sstore_refunds + suicide_refunds;
@@ -1584,6 +1587,65 @@ mod tests {
assert_eq!(state.storage_at(&contract_address, &H256::from(&U256::zero())).unwrap(), H256::from(&U256::from(0))); assert_eq!(state.storage_at(&contract_address, &H256::from(&U256::zero())).unwrap(), H256::from(&U256::from(0)));
} }
evm_test!{test_eip1283: test_eip1283_int}
fn test_eip1283(factory: Factory) {
let x1 = Address::from(0x1000);
let x2 = Address::from(0x1001);
let y1 = Address::from(0x2001);
let y2 = Address::from(0x2002);
let operating_address = Address::from(0);
let k = H256::new();
let mut state = get_temp_state_with_factory(factory.clone());
state.new_contract(&x1, U256::zero(), U256::from(1)).unwrap();
state.init_code(&x1, "600160005560006000556001600055".from_hex().unwrap()).unwrap();
state.new_contract(&x2, U256::zero(), U256::from(1)).unwrap();
state.init_code(&x2, "600060005560016000556000600055".from_hex().unwrap()).unwrap();
state.new_contract(&y1, U256::zero(), U256::from(1)).unwrap();
state.init_code(&y1, "600060006000600061100062fffffff4".from_hex().unwrap()).unwrap();
state.new_contract(&y2, U256::zero(), U256::from(1)).unwrap();
state.init_code(&y2, "600060006000600061100162fffffff4".from_hex().unwrap()).unwrap();
let info = EnvInfo::default();
let machine = ::ethereum::new_constantinople_test_machine();
assert_eq!(state.storage_at(&operating_address, &k).unwrap(), H256::from(U256::from(0)));
// Test a call via top-level -> y1 -> x1
let (FinalizationResult { gas_left, .. }, refund, gas) = {
let gas = U256::from(0xffffffffffu64);
let mut params = ActionParams::default();
params.code = Some(Arc::new("6001600055600060006000600061200163fffffffff4".from_hex().unwrap()));
params.gas = gas;
let mut substate = Substate::new();
let mut ex = Executive::new(&mut state, &info, &machine);
let res = ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer, &mut NoopVMTracer).unwrap();
(res, substate.sstore_clears_refund, gas)
};
let gas_used = gas - gas_left;
// sstore: 0 -> (1) -> () -> (1 -> 0 -> 1)
assert_eq!(gas_used, U256::from(41860));
assert_eq!(refund, U256::from(19800));
assert_eq!(state.storage_at(&operating_address, &k).unwrap(), H256::from(U256::from(1)));
// Test a call via top-level -> y2 -> x2
let (FinalizationResult { gas_left, .. }, refund, gas) = {
let gas = U256::from(0xffffffffffu64);
let mut params = ActionParams::default();
params.code = Some(Arc::new("6001600055600060006000600061200263fffffffff4".from_hex().unwrap()));
params.gas = gas;
let mut substate = Substate::new();
let mut ex = Executive::new(&mut state, &info, &machine);
let res = ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer, &mut NoopVMTracer).unwrap();
(res, substate.sstore_clears_refund, gas)
};
let gas_used = gas - gas_left;
// sstore: 1 -> (1) -> () -> (0 -> 1 -> 0)
assert_eq!(gas_used, U256::from(11860));
assert_eq!(refund, U256::from(19800));
}
fn wasm_sample_code() -> Arc<Vec<u8>> { fn wasm_sample_code() -> Arc<Vec<u8>> {
Arc::new( Arc::new(
"0061736d01000000010d0360027f7f0060017f0060000002270303656e7603726574000003656e760673656e646572000103656e76066d656d6f727902010110030201020404017000000501000708010463616c6c00020901000ac10101be0102057f017e4100410028020441c0006b22043602042004412c6a41106a220041003602002004412c6a41086a22014200370200200441186a41106a22024100360200200441186a41086a220342003703002004420037022c2004410036021c20044100360218200441186a1001200020022802002202360200200120032903002205370200200441106a2002360200200441086a200537030020042004290318220537022c200420053703002004411410004100200441c0006a3602040b0b0a010041040b0410c00000" "0061736d01000000010d0360027f7f0060017f0060000002270303656e7603726574000003656e760673656e646572000103656e76066d656d6f727902010110030201020404017000000501000708010463616c6c00020901000ac10101be0102057f017e4100410028020441c0006b22043602042004412c6a41106a220041003602002004412c6a41086a22014200370200200441186a41106a22024100360200200441186a41086a220342003703002004420037022c2004410036021c20044100360218200441186a1001200020022802002202360200200120032903002205370200200441106a2002360200200441086a200537030020042004290318220537022c200420053703002004411410004100200441c0006a3602040b0b0a010041040b0410c00000"

View File

@@ -111,6 +111,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B>
impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend where T: Tracer, V: VMTracer, B: StateBackend
{ {
fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> {
self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into)
}
fn storage_at(&self, key: &H256) -> vm::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)
} }
@@ -163,7 +167,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
gas: self.machine.params().eip210_contract_gas, gas: self.machine.params().eip210_contract_gas,
gas_price: 0.into(), gas_price: 0.into(),
code: code, code: code,
code_hash: Some(code_hash), code_hash: code_hash,
data: Some(H256::from(number).to_vec()), data: Some(H256::from(number).to_vec()),
call_type: CallType::Call, call_type: CallType::Call,
params_type: vm::ParamsType::Separate, params_type: vm::ParamsType::Separate,
@@ -219,7 +223,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
}; };
if !self.static_flag { if !self.static_flag {
if !self.schedule.eip86 || params.sender != UNSIGNED_SENDER { if !self.schedule.keep_unsigned_nonce || params.sender != UNSIGNED_SENDER {
if let Err(e) = self.state.inc_nonce(&self.origin_info.address) { if let Err(e) = self.state.inc_nonce(&self.origin_info.address) {
debug!(target: "ext", "Database corruption encountered: {:?}", e); debug!(target: "ext", "Database corruption encountered: {:?}", e);
return ContractCreateResult::Failed return ContractCreateResult::Failed
@@ -270,7 +274,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
gas: *gas, gas: *gas,
gas_price: self.origin_info.gas_price, gas_price: self.origin_info.gas_price,
code: code, code: code,
code_hash: Some(code_hash), code_hash: code_hash,
data: Some(data.to_vec()), data: Some(data.to_vec()),
call_type: call_type, call_type: call_type,
params_type: vm::ParamsType::Separate, params_type: vm::ParamsType::Separate,
@@ -289,12 +293,16 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
} }
} }
fn extcode(&self, address: &Address) -> vm::Result<Arc<Bytes>> { fn extcode(&self, address: &Address) -> vm::Result<Option<Arc<Bytes>>> {
Ok(self.state.code(address)?.unwrap_or_else(|| Arc::new(vec![]))) Ok(self.state.code(address)?)
} }
fn extcodesize(&self, address: &Address) -> vm::Result<usize> { fn extcodehash(&self, address: &Address) -> vm::Result<Option<H256>> {
Ok(self.state.code_size(address)?.unwrap_or(0)) Ok(self.state.code_hash(address)?)
}
fn extcodesize(&self, address: &Address) -> vm::Result<Option<usize>> {
Ok(self.state.code_size(address)?)
} }
fn ret(mut self, gas: &U256, data: &ReturnData, apply_state: bool) -> vm::Result<U256> fn ret(mut self, gas: &U256, data: &ReturnData, apply_state: bool) -> vm::Result<U256>
@@ -390,8 +398,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
self.depth self.depth
} }
fn inc_sstore_clears(&mut self) { fn add_sstore_refund(&mut self, value: U256) {
self.substate.sstore_clears_count = self.substate.sstore_clears_count + U256::one(); self.substate.sstore_clears_refund = self.substate.sstore_clears_refund.saturating_add(value);
}
fn sub_sstore_refund(&mut self, value: U256) {
self.substate.sstore_clears_refund = self.substate.sstore_clears_refund.saturating_sub(value);
} }
fn trace_next_instruction(&mut self, pc: usize, instruction: u8, current_gas: U256) -> bool { fn trace_next_instruction(&mut self, pc: usize, instruction: u8, current_gas: U256) -> bool {
@@ -570,4 +582,44 @@ mod tests {
assert_eq!(setup.sub_state.suicides.len(), 1); assert_eq!(setup.sub_state.suicides.len(), 1);
} }
#[test]
fn can_create() {
use std::str::FromStr;
let mut setup = TestSetup::new();
let state = &mut setup.state;
let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer;
let address = {
let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
match ext.create(&U256::max_value(), &U256::zero(), &[], CreateContractAddress::FromSenderAndNonce) {
ContractCreateResult::Created(address, _) => address,
_ => panic!("Test create failed; expected Created, got Failed/Reverted."),
}
};
assert_eq!(address, Address::from_str("bd770416a3345f91e4b34576cb804a576fa48eb1").unwrap());
}
#[test]
fn can_create2() {
use std::str::FromStr;
let mut setup = TestSetup::new();
let state = &mut setup.state;
let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer;
let address = {
let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
match ext.create(&U256::max_value(), &U256::zero(), &[], CreateContractAddress::FromSenderSaltAndCodeHash(H256::default())) {
ContractCreateResult::Created(address, _) => address,
_ => panic!("Test create failed; expected Created, got Failed/Reverted."),
}
};
assert_eq!(address, Address::from_str("e33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0").unwrap());
}
} }

View File

@@ -23,6 +23,7 @@ use ethjson;
use miner::Miner; use miner::Miner;
use io::IoChannel; use io::IoChannel;
use test_helpers; use test_helpers;
use super::SKIP_TEST_STATE;
use super::HookType; use super::HookType;
@@ -36,12 +37,20 @@ pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
::json_tests::test_common::run_test_file(p, json_chain_test, h) ::json_tests::test_common::run_test_file(p, json_chain_test, h)
} }
fn skip_test(name: &String) -> bool {
SKIP_TEST_STATE.block.iter().any(|block_test|block_test.subtests.contains(name))
}
pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> { pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
::ethcore_logger::init_log(); ::ethcore_logger::init_log();
let tests = ethjson::blockchain::Test::load(json_data).unwrap(); let tests = ethjson::blockchain::Test::load(json_data).unwrap();
let mut failed = Vec::new(); let mut failed = Vec::new();
for (name, blockchain) in tests.into_iter() { for (name, blockchain) in tests.into_iter() {
if skip_test(&name) {
println!(" - {} | {:?} Ignoring tests because in skip list", name, blockchain.network);
continue;
}
start_stop_hook(&name, HookType::OnStart); start_stop_hook(&name, HookType::OnStart);
let mut fail = false; let mut fail = false;
@@ -122,19 +131,24 @@ mod block_tests {
declare_test!{BlockchainTests_bcInvalidHeaderTest, "BlockchainTests/bcInvalidHeaderTest"} declare_test!{BlockchainTests_bcInvalidHeaderTest, "BlockchainTests/bcInvalidHeaderTest"}
declare_test!{BlockchainTests_bcMultiChainTest, "BlockchainTests/bcMultiChainTest"} declare_test!{BlockchainTests_bcMultiChainTest, "BlockchainTests/bcMultiChainTest"}
declare_test!{BlockchainTests_bcRandomBlockhashTest, "BlockchainTests/bcRandomBlockhashTest"} declare_test!{BlockchainTests_bcRandomBlockhashTest, "BlockchainTests/bcRandomBlockhashTest"}
declare_test!{BlockchainTests_bcStateTest, "BlockchainTests/bcStateTests"}
declare_test!{BlockchainTests_bcTotalDifficultyTest, "BlockchainTests/bcTotalDifficultyTest"} declare_test!{BlockchainTests_bcTotalDifficultyTest, "BlockchainTests/bcTotalDifficultyTest"}
declare_test!{BlockchainTests_bcUncleHeaderValidity, "BlockchainTests/bcUncleHeaderValidity"} declare_test!{BlockchainTests_bcUncleHeaderValidity, "BlockchainTests/bcUncleHeaderValidity"}
declare_test!{BlockchainTests_bcUncleTest, "BlockchainTests/bcUncleTest"} declare_test!{BlockchainTests_bcUncleTest, "BlockchainTests/bcUncleTest"}
declare_test!{BlockchainTests_bcValidBlockTest, "BlockchainTests/bcValidBlockTest"} declare_test!{BlockchainTests_bcValidBlockTest, "BlockchainTests/bcValidBlockTest"}
declare_test!{BlockchainTests_bcWalletTest, "BlockchainTests/bcWalletTest"} declare_test!{BlockchainTests_bcWalletTest, "BlockchainTests/bcWalletTest"}
declare_test!{BlockchainTests_GeneralStateTest_stArgsZeroOneBalance, "BlockchainTests/GeneralStateTests/stArgsZeroOneBalance/"}
declare_test!{BlockchainTests_GeneralStateTest_stAttackTest, "BlockchainTests/GeneralStateTests/stAttackTest/"} declare_test!{BlockchainTests_GeneralStateTest_stAttackTest, "BlockchainTests/GeneralStateTests/stAttackTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stBadOpcodeTest, "BlockchainTests/GeneralStateTests/stBadOpcode/"} declare_test!{BlockchainTests_GeneralStateTest_stBadOpcodeTest, "BlockchainTests/GeneralStateTests/stBadOpcode/"}
declare_test!{BlockchainTests_GeneralStateTest_stBugsTest, "BlockchainTests/GeneralStateTests/stBugs/"}
declare_test!{BlockchainTests_GeneralStateTest_stCallCodes, "BlockchainTests/GeneralStateTests/stCallCodes/"} declare_test!{BlockchainTests_GeneralStateTest_stCallCodes, "BlockchainTests/GeneralStateTests/stCallCodes/"}
declare_test!{BlockchainTests_GeneralStateTest_stCallCreateCallCodeTest, "BlockchainTests/GeneralStateTests/stCallCreateCallCodeTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "BlockchainTests/GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"} declare_test!{BlockchainTests_GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "BlockchainTests/GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"}
declare_test!{BlockchainTests_GeneralStateTest_stCallDelegateCodesHomestead, "BlockchainTests/GeneralStateTests/stCallDelegateCodesHomestead/"} declare_test!{BlockchainTests_GeneralStateTest_stCallDelegateCodesHomestead, "BlockchainTests/GeneralStateTests/stCallDelegateCodesHomestead/"}
declare_test!{BlockchainTests_GeneralStateTest_stChangedEIP150, "BlockchainTests/GeneralStateTests/stChangedEIP150/"} declare_test!{BlockchainTests_GeneralStateTest_stChangedEIP150, "BlockchainTests/GeneralStateTests/stChangedEIP150/"}
declare_test!{BlockchainTests_GeneralStateTest_stCodeSizeLimit, "BlockchainTests/GeneralStateTests/stCodeSizeLimit/"} declare_test!{BlockchainTests_GeneralStateTest_stCodeSizeLimit, "BlockchainTests/GeneralStateTests/stCodeSizeLimit/"}
declare_test!{BlockchainTests_GeneralStateTest_stCreate2, "BlockchainTests/GeneralStateTests/stCreate2/"}
declare_test!{BlockchainTests_GeneralStateTest_stCreateTest, "BlockchainTests/GeneralStateTests/stCreateTest/"} declare_test!{BlockchainTests_GeneralStateTest_stCreateTest, "BlockchainTests/GeneralStateTests/stCreateTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stDelegatecallTestHomestead, "BlockchainTests/GeneralStateTests/stDelegatecallTestHomestead/"} declare_test!{BlockchainTests_GeneralStateTest_stDelegatecallTestHomestead, "BlockchainTests/GeneralStateTests/stDelegatecallTestHomestead/"}
declare_test!{BlockchainTests_GeneralStateTest_stEIP150singleCodeGasPrices, "BlockchainTests/GeneralStateTests/stEIP150singleCodeGasPrices/"} declare_test!{BlockchainTests_GeneralStateTest_stEIP150singleCodeGasPrices, "BlockchainTests/GeneralStateTests/stEIP150singleCodeGasPrices/"}
@@ -149,12 +163,15 @@ mod block_tests {
declare_test!{BlockchainTests_GeneralStateTest_stMemoryTest, "BlockchainTests/GeneralStateTests/stMemoryTest/"} declare_test!{BlockchainTests_GeneralStateTest_stMemoryTest, "BlockchainTests/GeneralStateTests/stMemoryTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stNonZeroCallsTest, "BlockchainTests/GeneralStateTests/stNonZeroCallsTest/"} declare_test!{BlockchainTests_GeneralStateTest_stNonZeroCallsTest, "BlockchainTests/GeneralStateTests/stNonZeroCallsTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stPreCompiledContracts, "BlockchainTests/GeneralStateTests/stPreCompiledContracts/"} declare_test!{BlockchainTests_GeneralStateTest_stPreCompiledContracts, "BlockchainTests/GeneralStateTests/stPreCompiledContracts/"}
declare_test!{BlockchainTests_GeneralStateTest_stPreCompiledContracts2, "BlockchainTests/GeneralStateTests/stPreCompiledContracts2/"}
declare_test!{heavy => BlockchainTests_GeneralStateTest_stQuadraticComplexityTest, "BlockchainTests/GeneralStateTests/stQuadraticComplexityTest/"} declare_test!{heavy => BlockchainTests_GeneralStateTest_stQuadraticComplexityTest, "BlockchainTests/GeneralStateTests/stQuadraticComplexityTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stRandom, "BlockchainTests/GeneralStateTests/stRandom/"} declare_test!{BlockchainTests_GeneralStateTest_stRandom, "BlockchainTests/GeneralStateTests/stRandom/"}
declare_test!{BlockchainTests_GeneralStateTest_stRandom2, "BlockchainTests/GeneralStateTests/stRandom2/"}
declare_test!{BlockchainTests_GeneralStateTest_stRecursiveCreate, "BlockchainTests/GeneralStateTests/stRecursiveCreate/"} declare_test!{BlockchainTests_GeneralStateTest_stRecursiveCreate, "BlockchainTests/GeneralStateTests/stRecursiveCreate/"}
declare_test!{BlockchainTests_GeneralStateTest_stRefundTest, "BlockchainTests/GeneralStateTests/stRefundTest/"} declare_test!{BlockchainTests_GeneralStateTest_stRefundTest, "BlockchainTests/GeneralStateTests/stRefundTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stReturnDataTest, "BlockchainTests/GeneralStateTests/stReturnDataTest/"} declare_test!{BlockchainTests_GeneralStateTest_stReturnDataTest, "BlockchainTests/GeneralStateTests/stReturnDataTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stRevertTest, "BlockchainTests/GeneralStateTests/stRevertTest/"} declare_test!{BlockchainTests_GeneralStateTest_stRevertTest, "BlockchainTests/GeneralStateTests/stRevertTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stShift, "BlockchainTests/GeneralStateTests/stShift/"}
declare_test!{BlockchainTests_GeneralStateTest_stSolidityTest, "BlockchainTests/GeneralStateTests/stSolidityTest/"} declare_test!{BlockchainTests_GeneralStateTest_stSolidityTest, "BlockchainTests/GeneralStateTests/stSolidityTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stSpecialTest, "BlockchainTests/GeneralStateTests/stSpecialTest/"} declare_test!{BlockchainTests_GeneralStateTest_stSpecialTest, "BlockchainTests/GeneralStateTests/stSpecialTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stStackTests, "BlockchainTests/GeneralStateTests/stStackTests/"} declare_test!{BlockchainTests_GeneralStateTest_stStackTests, "BlockchainTests/GeneralStateTests/stStackTests/"}
@@ -166,6 +183,7 @@ mod block_tests {
declare_test!{BlockchainTests_GeneralStateTest_stZeroCallsRevert, "BlockchainTests/GeneralStateTests/stZeroCallsRevert/"} declare_test!{BlockchainTests_GeneralStateTest_stZeroCallsRevert, "BlockchainTests/GeneralStateTests/stZeroCallsRevert/"}
declare_test!{BlockchainTests_GeneralStateTest_stZeroCallsTest, "BlockchainTests/GeneralStateTests/stZeroCallsTest/"} declare_test!{BlockchainTests_GeneralStateTest_stZeroCallsTest, "BlockchainTests/GeneralStateTests/stZeroCallsTest/"}
declare_test!{BlockchainTests_GeneralStateTest_stZeroKnowledge, "BlockchainTests/GeneralStateTests/stZeroKnowledge/"} declare_test!{BlockchainTests_GeneralStateTest_stZeroKnowledge, "BlockchainTests/GeneralStateTests/stZeroKnowledge/"}
declare_test!{BlockchainTests_GeneralStateTest_stZeroKnowledge2, "BlockchainTests/GeneralStateTests/stZeroKnowledge2/"}
declare_test!{BlockchainTests_TransitionTests_bcEIP158ToByzantium, "BlockchainTests/TransitionTests/bcEIP158ToByzantium/"} declare_test!{BlockchainTests_TransitionTests_bcEIP158ToByzantium, "BlockchainTests/TransitionTests/bcEIP158ToByzantium/"}
declare_test!{BlockchainTests_TransitionTests_bcFrontierToHomestead, "BlockchainTests/TransitionTests/bcFrontierToHomestead/"} declare_test!{BlockchainTests_TransitionTests_bcFrontierToHomestead, "BlockchainTests/TransitionTests/bcFrontierToHomestead/"}

View File

@@ -52,26 +52,62 @@ pub fn json_difficulty_test<H: FnMut(&str, HookType)>(json_data: &[u8], spec: Sp
vec![] vec![]
} }
mod difficulty_test_byzantium { macro_rules! difficulty_json_test {
use super::json_difficulty_test; ( $spec:ident ) => {
use json_tests::HookType;
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
json_difficulty_test(json_data, ::ethereum::new_byzantium_test(), h)
}
declare_test!{DifficultyTests_difficultyByzantium, "BasicTests/difficultyByzantium.json"}
}
mod difficulty_test_foundation {
use super::json_difficulty_test; use super::json_difficulty_test;
use tempdir::TempDir; use tempdir::TempDir;
use json_tests::HookType; use json_tests::HookType;
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> { fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
let tempdir = TempDir::new("").unwrap(); let tempdir = TempDir::new("").unwrap();
json_difficulty_test(json_data, ::ethereum::new_foundation(&tempdir.path()), h) json_difficulty_test(json_data, ::ethereum::$spec(&tempdir.path()), h)
} }
}
}
macro_rules! difficulty_json_test_nopath {
( $spec:ident ) => {
use super::json_difficulty_test;
use json_tests::HookType;
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], h: &mut H) -> Vec<String> {
json_difficulty_test(json_data, ::ethereum::$spec(), h)
}
}
}
mod difficulty_test {
difficulty_json_test!(new_foundation);
declare_test!{DifficultyTests_difficulty, "BasicTests/difficulty.json"}
}
mod difficulty_test_byzantium {
difficulty_json_test_nopath!(new_byzantium_test);
declare_test!{DifficultyTests_difficultyByzantium, "BasicTests/difficultyByzantium.json"}
}
mod difficulty_test_foundation {
difficulty_json_test!(new_foundation);
declare_test!{DifficultyTests_difficultyMainNetwork, "BasicTests/difficultyMainNetwork.json"} declare_test!{DifficultyTests_difficultyMainNetwork, "BasicTests/difficultyMainNetwork.json"}
} }
// Disabling Ropsten diff tests; waiting for upstream ethereum/tests Constantinople update
//mod difficulty_test_ropsten {
// difficulty_json_test_nopath!(new_ropsten_test);
// declare_test!{DifficultyTests_difficultyRopsten, "BasicTests/difficultyRopsten.json"}
//}
mod difficulty_test_frontier {
difficulty_json_test_nopath!(new_frontier_test);
declare_test!{DifficultyTests_difficultyFrontier, "BasicTests/difficultyFrontier.json"}
}
mod difficulty_test_homestead {
difficulty_json_test_nopath!(new_homestead_test);
declare_test!{DifficultyTests_difficultyHomestead, "BasicTests/difficultyHomestead.json"}
}

View File

@@ -111,6 +111,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
self.ext.storage_at(key) self.ext.storage_at(key)
} }
fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> {
self.ext.initial_storage_at(key)
}
fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> { fn set_storage(&mut self, key: H256, value: H256) -> vm::Result<()> {
self.ext.set_storage(key, value) self.ext.set_storage(key, value)
} }
@@ -165,14 +169,18 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
MessageCallResult::Success(*gas, ReturnData::empty()) MessageCallResult::Success(*gas, ReturnData::empty())
} }
fn extcode(&self, address: &Address) -> vm::Result<Arc<Bytes>> { fn extcode(&self, address: &Address) -> vm::Result<Option<Arc<Bytes>>> {
self.ext.extcode(address) self.ext.extcode(address)
} }
fn extcodesize(&self, address: &Address) -> vm::Result<usize> { fn extcodesize(&self, address: &Address) -> vm::Result<Option<usize>> {
self.ext.extcodesize(address) self.ext.extcodesize(address)
} }
fn extcodehash(&self, address: &Address) -> vm::Result<Option<H256>> {
self.ext.extcodehash(address)
}
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> { fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> {
self.ext.log(topics, data) self.ext.log(topics, data)
} }
@@ -201,8 +209,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
false false
} }
fn inc_sstore_clears(&mut self) { fn add_sstore_refund(&mut self, value: U256) {
self.ext.inc_sstore_clears() self.ext.add_sstore_refund(value)
}
fn sub_sstore_refund(&mut self, value: U256) {
self.ext.sub_sstore_refund(value)
} }
} }

View File

@@ -24,10 +24,12 @@ mod executive;
mod state; mod state;
mod chain; mod chain;
mod trie; mod trie;
mod skip;
#[cfg(test)] #[cfg(test)]
mod difficulty; mod difficulty;
pub use self::test_common::HookType; pub use self::test_common::HookType;
pub use self::transaction::run_test_path as run_transaction_test_path; pub use self::transaction::run_test_path as run_transaction_test_path;
@@ -42,3 +44,4 @@ pub use self::trie::run_generic_test_path as run_generic_trie_test_path;
pub use self::trie::run_generic_test_file as run_generic_trie_test_file; pub use self::trie::run_generic_test_file as run_generic_trie_test_file;
pub use self::trie::run_secure_test_path as run_secure_trie_test_path; pub use self::trie::run_secure_test_path as run_secure_trie_test_path;
pub use self::trie::run_secure_test_file as run_secure_trie_test_file; pub use self::trie::run_secure_test_file as run_secure_trie_test_file;
use self::skip::SKIP_TEST_STATE;

View File

@@ -0,0 +1,37 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! State tests to skip.
use ethjson;
#[cfg(all(not(test), feature = "ci-skip-tests"))]
compile_error!("ci-skip-tests can only be enabled for testing builds.");
#[cfg(feature="ci-skip-issue")]
lazy_static!{
pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = {
let skip_data = include_bytes!("../../res/ethereum/tests-issues/currents.json");
ethjson::test::SkipStates::load(&skip_data[..]).expect("No invalid json allowed")
};
}
#[cfg(not(feature="ci-skip-issue"))]
lazy_static!{
pub static ref SKIP_TEST_STATE: ethjson::test::SkipStates = {
ethjson::test::SkipStates::empty()
};
}

View File

@@ -22,7 +22,7 @@ use client::{EvmTestClient, EvmTestError, TransactResult};
use ethjson; use ethjson;
use transaction::SignedTransaction; use transaction::SignedTransaction;
use vm::EnvInfo; use vm::EnvInfo;
use super::SKIP_TEST_STATE;
use super::HookType; use super::HookType;
/// Run state jsontests on a given folder. /// Run state jsontests on a given folder.
@@ -35,6 +35,18 @@ pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
::json_tests::test_common::run_test_file(p, json_chain_test, h) ::json_tests::test_common::run_test_file(p, json_chain_test, h)
} }
fn skip_test(subname: &str, chain: &String, number: usize) -> bool {
SKIP_TEST_STATE.state.iter().any(|state_test|{
if let Some(subtest) = state_test.subtests.get(subname) {
chain == &subtest.chain &&
(subtest.subnumbers[0] == "*"
|| subtest.subnumbers.contains(&number.to_string()))
} else {
false
}
})
}
pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> { pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
::ethcore_logger::init_log(); ::ethcore_logger::init_log();
let tests = ethjson::state::test::Test::load(json_data).unwrap(); let tests = ethjson::state::test::Test::load(json_data).unwrap();
@@ -60,6 +72,10 @@ pub fn json_chain_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_ho
for (i, state) in states.into_iter().enumerate() { for (i, state) in states.into_iter().enumerate() {
let info = format!(" - {} | {:?} ({}/{}) ...", name, spec_name, i + 1, total); let info = format!(" - {} | {:?} ({}/{}) ...", name, spec_name, i + 1, total);
if skip_test(&name, &spec.name, i + 1) {
println!("{} in skip list : SKIPPED", info);
continue;
}
let post_root: H256 = state.hash.into(); let post_root: H256 = state.hash.into();
let transaction: SignedTransaction = multitransaction.select(&state.indexes).into(); let transaction: SignedTransaction = multitransaction.select(&state.indexes).into();
@@ -114,18 +130,24 @@ mod state_tests {
json_chain_test(json_data, h) json_chain_test(json_data, h)
} }
declare_test!{GeneralStateTest_stArgsZeroOneBalance, "GeneralStateTests/stArgsZeroOneBalance/"}
declare_test!{GeneralStateTest_stAttackTest, "GeneralStateTests/stAttackTest/"} declare_test!{GeneralStateTest_stAttackTest, "GeneralStateTests/stAttackTest/"}
declare_test!{GeneralStateTest_stBadOpcodeTest, "GeneralStateTests/stBadOpcode/"} declare_test!{GeneralStateTest_stBadOpcodeTest, "GeneralStateTests/stBadOpcode/"}
declare_test!{GeneralStateTest_stBugs, "GeneralStateTests/stBugs/"}
declare_test!{GeneralStateTest_stCallCodes, "GeneralStateTests/stCallCodes/"} declare_test!{GeneralStateTest_stCallCodes, "GeneralStateTests/stCallCodes/"}
declare_test!{GeneralStateTest_stCallCreateCallCodeTest, "GeneralStateTests/stCallCreateCallCodeTest/"}
declare_test!{GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"} declare_test!{GeneralStateTest_stCallDelegateCodesCallCodeHomestead, "GeneralStateTests/stCallDelegateCodesCallCodeHomestead/"}
declare_test!{GeneralStateTest_stCallDelegateCodesHomestead, "GeneralStateTests/stCallDelegateCodesHomestead/"} declare_test!{GeneralStateTest_stCallDelegateCodesHomestead, "GeneralStateTests/stCallDelegateCodesHomestead/"}
declare_test!{GeneralStateTest_stChangedEIP150, "GeneralStateTests/stChangedEIP150/"} declare_test!{GeneralStateTest_stChangedEIP150, "GeneralStateTests/stChangedEIP150/"}
declare_test!{GeneralStateTest_stCodeCopyTest, "GeneralStateTests/stCodeCopyTest/"}
declare_test!{GeneralStateTest_stCodeSizeLimit, "GeneralStateTests/stCodeSizeLimit/"} declare_test!{GeneralStateTest_stCodeSizeLimit, "GeneralStateTests/stCodeSizeLimit/"}
declare_test!{GeneralStateTest_stCreate2Test, "GeneralStateTests/stCreate2/"}
declare_test!{GeneralStateTest_stCreateTest, "GeneralStateTests/stCreateTest/"} declare_test!{GeneralStateTest_stCreateTest, "GeneralStateTests/stCreateTest/"}
declare_test!{GeneralStateTest_stDelegatecallTestHomestead, "GeneralStateTests/stDelegatecallTestHomestead/"} declare_test!{GeneralStateTest_stDelegatecallTestHomestead, "GeneralStateTests/stDelegatecallTestHomestead/"}
declare_test!{GeneralStateTest_stEIP150singleCodeGasPrices, "GeneralStateTests/stEIP150singleCodeGasPrices/"} declare_test!{GeneralStateTest_stEIP150singleCodeGasPrices, "GeneralStateTests/stEIP150singleCodeGasPrices/"}
declare_test!{GeneralStateTest_stEIP150Specific, "GeneralStateTests/stEIP150Specific/"} declare_test!{GeneralStateTest_stEIP150Specific, "GeneralStateTests/stEIP150Specific/"}
declare_test!{GeneralStateTest_stEIP158Specific, "GeneralStateTests/stEIP158Specific/"} declare_test!{GeneralStateTest_stEIP158Specific, "GeneralStateTests/stEIP158Specific/"}
declare_test!{GeneralStateTest_stEWASMTests, "GeneralStateTests/stEWASMTests/"}
declare_test!{GeneralStateTest_stExample, "GeneralStateTests/stExample/"} declare_test!{GeneralStateTest_stExample, "GeneralStateTests/stExample/"}
declare_test!{GeneralStateTest_stHomesteadSpecific, "GeneralStateTests/stHomesteadSpecific/"} declare_test!{GeneralStateTest_stHomesteadSpecific, "GeneralStateTests/stHomesteadSpecific/"}
declare_test!{GeneralStateTest_stInitCodeTest, "GeneralStateTests/stInitCodeTest/"} declare_test!{GeneralStateTest_stInitCodeTest, "GeneralStateTests/stInitCodeTest/"}
@@ -135,12 +157,15 @@ mod state_tests {
declare_test!{GeneralStateTest_stMemoryTest, "GeneralStateTests/stMemoryTest/"} declare_test!{GeneralStateTest_stMemoryTest, "GeneralStateTests/stMemoryTest/"}
declare_test!{GeneralStateTest_stNonZeroCallsTest, "GeneralStateTests/stNonZeroCallsTest/"} declare_test!{GeneralStateTest_stNonZeroCallsTest, "GeneralStateTests/stNonZeroCallsTest/"}
declare_test!{GeneralStateTest_stPreCompiledContracts, "GeneralStateTests/stPreCompiledContracts/"} declare_test!{GeneralStateTest_stPreCompiledContracts, "GeneralStateTests/stPreCompiledContracts/"}
declare_test!{GeneralStateTest_stPreCompiledContracts2, "GeneralStateTests/stPreCompiledContracts2/"}
declare_test!{heavy => GeneralStateTest_stQuadraticComplexityTest, "GeneralStateTests/stQuadraticComplexityTest/"} declare_test!{heavy => GeneralStateTest_stQuadraticComplexityTest, "GeneralStateTests/stQuadraticComplexityTest/"}
declare_test!{GeneralStateTest_stRandom, "GeneralStateTests/stRandom/"} declare_test!{GeneralStateTest_stRandom, "GeneralStateTests/stRandom/"}
declare_test!{GeneralStateTest_stRandom2, "GeneralStateTests/stRandom2/"}
declare_test!{GeneralStateTest_stRecursiveCreate, "GeneralStateTests/stRecursiveCreate/"} declare_test!{GeneralStateTest_stRecursiveCreate, "GeneralStateTests/stRecursiveCreate/"}
declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"} declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"}
declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"} declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"}
declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"} declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"}
declare_test!{GeneralStateTest_stShift, "GeneralStateTests/stShift/"}
declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"} declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"}
declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"} declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"}
declare_test!{GeneralStateTest_stStackTests, "GeneralStateTests/stStackTests/"} declare_test!{GeneralStateTest_stStackTests, "GeneralStateTests/stStackTests/"}
@@ -152,4 +177,11 @@ mod state_tests {
declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"} declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"}
declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"} declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"}
declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"} declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"}
// Attempts to send a transaction that requires more than current balance:
// Tx:
// https://github.com/ethereum/tests/blob/726b161ba8a739691006cc1ba080672bb50a9d49/GeneralStateTests/stZeroKnowledge2/ecmul_0-3_5616_28000_96.json#L170
// Balance:
// https://github.com/ethereum/tests/blob/726b161ba8a739691006cc1ba080672bb50a9d49/GeneralStateTests/stZeroKnowledge2/ecmul_0-3_5616_28000_96.json#L126
declare_test!{GeneralStateTest_stZeroKnowledge2, "GeneralStateTests/stZeroKnowledge2/"}
} }

View File

@@ -34,6 +34,18 @@ pub fn run_test_path<H: FnMut(&str, HookType)>(
p: &Path, skip: &[&'static str], p: &Path, skip: &[&'static str],
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>, runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
start_stop_hook: &mut H start_stop_hook: &mut H
) {
let mut errors = Vec::new();
run_test_path_inner(p, skip, runner, start_stop_hook, &mut errors);
let empty: [String; 0] = [];
assert_eq!(errors, empty);
}
fn run_test_path_inner<H: FnMut(&str, HookType)>(
p: &Path, skip: &[&'static str],
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
start_stop_hook: &mut H,
errors: &mut Vec<String>
) { ) {
let path = Path::new(p); let path = Path::new(p);
let s: HashSet<OsString> = skip.iter().map(|s| { let s: HashSet<OsString> = skip.iter().map(|s| {
@@ -41,6 +53,7 @@ pub fn run_test_path<H: FnMut(&str, HookType)>(
os.push(".json"); os.push(".json");
os os
}).collect(); }).collect();
let extension = path.extension().and_then(|s| s.to_str());
if path.is_dir() { if path.is_dir() {
for p in read_dir(path).unwrap().filter_map(|e| { for p in read_dir(path).unwrap().filter_map(|e| {
let e = e.unwrap(); let e = e.unwrap();
@@ -49,22 +62,42 @@ pub fn run_test_path<H: FnMut(&str, HookType)>(
} else { } else {
Some(e.path()) Some(e.path())
}}) { }}) {
run_test_path(&p, skip, runner, start_stop_hook) run_test_path_inner(&p, skip, runner, start_stop_hook, errors);
} }
} else if extension == Some("swp") || extension == None {
// Ignore junk
} else { } else {
let mut path = p.to_path_buf(); let mut path = p.to_path_buf();
path.set_extension("json"); path.set_extension("json");
run_test_file(&path, runner, start_stop_hook) run_test_file_append(&path, runner, start_stop_hook, errors)
} }
} }
fn run_test_file_append<H: FnMut(&str, HookType)>(
path: &Path,
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
start_stop_hook: &mut H,
errors: &mut Vec<String>
) {
let mut data = Vec::new();
let mut file = match File::open(&path) {
Ok(file) => file,
Err(_) => panic!("Error opening test file at: {:?}", path),
};
file.read_to_end(&mut data).expect("Error reading test file");
errors.append(&mut runner(&data, start_stop_hook));
}
pub fn run_test_file<H: FnMut(&str, HookType)>( pub fn run_test_file<H: FnMut(&str, HookType)>(
path: &Path, path: &Path,
runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>, runner: fn(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String>,
start_stop_hook: &mut H start_stop_hook: &mut H
) { ) {
let mut data = Vec::new(); let mut data = Vec::new();
let mut file = File::open(&path).expect("Error opening test file"); let mut file = match File::open(&path) {
Ok(file) => file,
Err(_) => panic!("Error opening test file at: {:?}", path),
};
file.read_to_end(&mut data).expect("Error reading test file"); file.read_to_end(&mut data).expect("Error reading test file");
let results = runner(&data, start_stop_hook); let results = runner(&data, start_stop_hook);
let empty: [String; 0] = []; let empty: [String; 0] = [];

View File

@@ -16,10 +16,11 @@
use std::path::Path; use std::path::Path;
use super::test_common::*; use super::test_common::*;
use evm; use client::EvmTestClient;
use header::Header;
use ethjson; use ethjson;
use rlp::Rlp; use rlp::Rlp;
use transaction::{Action, UnverifiedTransaction, SignedTransaction}; use transaction::UnverifiedTransaction;
/// Run transaction jsontests on a given folder. /// Run transaction jsontests on a given folder.
pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) { pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) {
@@ -31,55 +32,61 @@ pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
::json_tests::test_common::run_test_file(p, do_json_test, h) ::json_tests::test_common::run_test_file(p, do_json_test, h)
} }
// Block number used to run the tests.
// Make sure that all the specified features are activated.
const BLOCK_NUMBER: u64 = 0x6ffffffffffffe;
fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> { fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mut H) -> Vec<String> {
let tests = ethjson::transaction::Test::load(json_data).unwrap(); let tests = ethjson::transaction::Test::load(json_data).unwrap();
let mut failed = Vec::new(); let mut failed = Vec::new();
let frontier_schedule = evm::Schedule::new_frontier();
let homestead_schedule = evm::Schedule::new_homestead();
let byzantium_schedule = evm::Schedule::new_byzantium();
for (name, test) in tests.into_iter() { for (name, test) in tests.into_iter() {
start_stop_hook(&name, HookType::OnStart); start_stop_hook(&name, HookType::OnStart);
let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); }; for (spec_name, result) in test.post_state {
let spec = match EvmTestClient::spec_from_json(&spec_name) {
let number: Option<u64> = test.block_number.map(Into::into); Some(spec) => spec,
let schedule = match number { None => {
None => &frontier_schedule, println!(" - {} | {:?} Ignoring tests because of missing spec", name, spec_name);
Some(x) if x < 1_150_000 => &frontier_schedule, continue;
Some(x) if x < 3_000_000 => &homestead_schedule, }
Some(_) => &byzantium_schedule
};
let allow_chain_id_of_one = number.map_or(false, |n| n >= 2_675_000);
let allow_unsigned = number.map_or(false, |n| n >= 3_000_000);
let rlp: Vec<u8> = test.rlp.into();
let res = Rlp::new(&rlp)
.as_val()
.map_err(::error::Error::from)
.and_then(|t: UnverifiedTransaction| {
t.validate(schedule, schedule.have_delegate_call, allow_chain_id_of_one, allow_unsigned).map_err(Into::into)
});
fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
let t = res.unwrap();
fail_unless(SignedTransaction::new(t.clone()).unwrap().sender() == sender.into(), "sender mismatch");
let is_acceptable_chain_id = match t.chain_id() {
None => true,
Some(1) if allow_chain_id_of_one => true,
_ => false,
}; };
fail_unless(is_acceptable_chain_id, "Network ID unacceptable");
let data: Vec<u8> = tx.data.into(); let mut fail_unless = |cond: bool, title: &str| if !cond {
fail_unless(t.data == data, "data mismatch"); failed.push(format!("{}-{:?}", name, spec_name));
fail_unless(t.gas_price == tx.gas_price.into(), "gas_price mismatch"); println!("Transaction failed: {:?}-{:?}: {:?}", name, spec_name, title);
fail_unless(t.nonce == tx.nonce.into(), "nonce mismatch"); };
fail_unless(t.value == tx.value.into(), "value mismatch");
let to: Option<ethjson::hash::Address> = tx.to.into(); let rlp: Vec<u8> = test.rlp.clone().into();
let to: Option<Address> = to.map(Into::into); let res = Rlp::new(&rlp)
match t.action { .as_val()
Action::Call(dest) => fail_unless(Some(dest) == to, "call/destination mismatch"), .map_err(::error::Error::from)
Action::Create => fail_unless(None == to, "create mismatch"), .and_then(|t: UnverifiedTransaction| {
let mut header: Header = Default::default();
// Use high enough number to activate all required features.
header.set_number(BLOCK_NUMBER);
let minimal = t.gas_required(&spec.engine.schedule(header.number())).into();
if t.gas < minimal {
return Err(::transaction::Error::InsufficientGas {
minimal, got: t.gas,
}.into());
}
spec.engine.verify_transaction_basic(&t, &header)?;
Ok(spec.engine.verify_transaction_unordered(t, &header)?)
});
match (res, result.hash, result.sender) {
(Ok(t), Some(hash), Some(sender)) => {
fail_unless(t.sender() == sender.into(), "sender mismatch");
fail_unless(t.hash() == hash.into(), "hash mismatch");
},
(Err(_), None, None) => {},
data => {
fail_unless(
false,
&format!("Validity different: {:?}", data)
);
}
} }
} }
@@ -92,13 +99,14 @@ fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mu
failed failed
} }
declare_test!{TransactionTests_ttEip155VitaliksHomesead, "TransactionTests/ttEip155VitaliksHomesead"} declare_test!{TransactionTests_ttAddress, "TransactionTests/ttAddress"}
declare_test!{TransactionTests_ttEip155VitaliksEip158, "TransactionTests/ttEip155VitaliksEip158"} declare_test!{TransactionTests_ttData, "TransactionTests/ttData"}
declare_test!{TransactionTests_ttEip158, "TransactionTests/ttEip158"} declare_test!{TransactionTests_ttGasLimit, "TransactionTests/ttGasLimit"}
declare_test!{TransactionTests_ttFrontier, "TransactionTests/ttFrontier"} declare_test!{TransactionTests_ttGasPrice, "TransactionTests/ttGasPrice"}
declare_test!{TransactionTests_ttHomestead, "TransactionTests/ttHomestead"} declare_test!{TransactionTests_ttNonce, "TransactionTests/ttNonce"}
declare_test!{TransactionTests_ttVRuleEip158, "TransactionTests/ttVRuleEip158"} declare_test!{TransactionTests_ttRSValue, "TransactionTests/ttRSValue"}
declare_test!{TransactionTests_ttWrongRLPFrontier, "TransactionTests/ttWrongRLPFrontier"} declare_test!{TransactionTests_ttSignature, "TransactionTests/ttSignature"}
declare_test!{TransactionTests_ttWrongRLPHomestead, "TransactionTests/ttWrongRLPHomestead"} declare_test!{TransactionTests_ttValue, "TransactionTests/ttValue"}
declare_test!{TransactionTests_ttConstantinople, "TransactionTests/ttConstantinople"} declare_test!{TransactionTests_ttVValue, "TransactionTests/ttVValue"}
declare_test!{TransactionTests_ttSpecConstantinople, "TransactionTests/ttSpecConstantinople"} declare_test!{TransactionTests_ttWrongRLP, "TransactionTests/ttWrongRLP"}

View File

@@ -140,7 +140,7 @@ impl EthereumMachine {
gas_price: 0.into(), gas_price: 0.into(),
value: ActionValue::Transfer(0.into()), value: ActionValue::Transfer(0.into()),
code: state.code(&contract_address)?, code: state.code(&contract_address)?,
code_hash: Some(state.code_hash(&contract_address)?), code_hash: state.code_hash(&contract_address)?,
data: data, data: data,
call_type: CallType::Call, call_type: CallType::Call,
params_type: ParamsType::Separate, params_type: ParamsType::Separate,
@@ -309,12 +309,8 @@ impl EthereumMachine {
} }
/// Returns new contract address generation scheme at given block number. /// Returns new contract address generation scheme at given block number.
pub fn create_address_scheme(&self, number: BlockNumber) -> CreateContractAddress { pub fn create_address_scheme(&self, _number: BlockNumber) -> CreateContractAddress {
if number >= self.params().eip86_transition { CreateContractAddress::FromSenderAndNonce
CreateContractAddress::FromCodeHash
} else {
CreateContractAddress::FromSenderAndNonce
}
} }
/// Verify a particular transaction is valid, regardless of order. /// Verify a particular transaction is valid, regardless of order.

View File

@@ -96,8 +96,6 @@ pub struct CommonParams {
pub validate_receipts_transition: BlockNumber, pub validate_receipts_transition: BlockNumber,
/// Validate transaction chain id. /// Validate transaction chain id.
pub validate_chain_id_transition: BlockNumber, pub validate_chain_id_transition: BlockNumber,
/// Number of first block where EIP-86 (Metropolis) rules begin.
pub eip86_transition: BlockNumber,
/// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin. /// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin.
pub eip140_transition: BlockNumber, pub eip140_transition: BlockNumber,
/// Number of first block where EIP-210 (Metropolis: BLOCKHASH changes) rules begin. /// Number of first block where EIP-210 (Metropolis: BLOCKHASH changes) rules begin.
@@ -115,6 +113,12 @@ pub struct CommonParams {
pub eip214_transition: BlockNumber, pub eip214_transition: BlockNumber,
/// Number of first block where EIP-145 rules begin. /// Number of first block where EIP-145 rules begin.
pub eip145_transition: BlockNumber, pub eip145_transition: BlockNumber,
/// Number of first block where EIP-1052 rules begin.
pub eip1052_transition: BlockNumber,
/// Number of first block where EIP-1283 rules begin.
pub eip1283_transition: BlockNumber,
/// Number of first block where EIP-1014 rules begin.
pub eip1014_transition: BlockNumber,
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
pub dust_protection_transition: BlockNumber, pub dust_protection_transition: BlockNumber,
/// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled. /// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled.
@@ -123,6 +127,10 @@ pub struct CommonParams {
pub remove_dust_contracts: bool, pub remove_dust_contracts: bool,
/// Wasm activation blocknumber, if any disabled initially. /// Wasm activation blocknumber, if any disabled initially.
pub wasm_activation_transition: BlockNumber, pub wasm_activation_transition: BlockNumber,
/// Number of first block where KIP-4 rules begin. Only has effect if Wasm is activated.
pub kip4_transition: BlockNumber,
/// Number of first block where KIP-6 rules begin. Only has effect if Wasm is activated.
pub kip6_transition: BlockNumber,
/// Gas limit bound divisor (how much gas limit can change per block) /// Gas limit bound divisor (how much gas limit can change per block)
pub gas_limit_bound_divisor: U256, pub gas_limit_bound_divisor: U256,
/// Registrar contract address. /// Registrar contract address.
@@ -169,11 +177,13 @@ impl CommonParams {
/// Apply common spec config parameters to the schedule. /// Apply common spec config parameters to the schedule.
pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) { pub fn update_schedule(&self, block_number: u64, schedule: &mut ::vm::Schedule) {
schedule.have_create2 = block_number >= self.eip86_transition; schedule.have_create2 = block_number >= self.eip1014_transition;
schedule.have_revert = block_number >= self.eip140_transition; schedule.have_revert = block_number >= self.eip140_transition;
schedule.have_static_call = block_number >= self.eip214_transition; schedule.have_static_call = block_number >= self.eip214_transition;
schedule.have_return_data = block_number >= self.eip211_transition; schedule.have_return_data = block_number >= self.eip211_transition;
schedule.have_bitwise_shifting = block_number >= self.eip145_transition; schedule.have_bitwise_shifting = block_number >= self.eip145_transition;
schedule.have_extcodehash = block_number >= self.eip1052_transition;
schedule.eip1283 = block_number >= self.eip1283_transition;
if block_number >= self.eip210_transition { if block_number >= self.eip210_transition {
schedule.blockhash_gas = 800; schedule.blockhash_gas = 800;
} }
@@ -184,7 +194,14 @@ impl CommonParams {
}; };
} }
if block_number >= self.wasm_activation_transition { if block_number >= self.wasm_activation_transition {
schedule.wasm = Some(Default::default()); let mut wasm = ::vm::WasmCosts::default();
if block_number >= self.kip4_transition {
wasm.have_create2 = true;
}
if block_number >= self.kip6_transition {
wasm.have_gasleft = true;
}
schedule.wasm = Some(wasm);
} }
} }
@@ -232,10 +249,6 @@ impl From<ethjson::spec::Params> for CommonParams {
eip155_transition: p.eip155_transition.map_or(0, Into::into), eip155_transition: p.eip155_transition.map_or(0, Into::into),
validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into),
validate_chain_id_transition: p.validate_chain_id_transition.map_or(0, Into::into), validate_chain_id_transition: p.validate_chain_id_transition.map_or(0, Into::into),
eip86_transition: p.eip86_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip140_transition: p.eip140_transition.map_or_else( eip140_transition: p.eip140_transition.map_or_else(
BlockNumber::max_value, BlockNumber::max_value,
Into::into, Into::into,
@@ -270,6 +283,18 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value, BlockNumber::max_value,
Into::into, Into::into,
), ),
eip1052_transition: p.eip1052_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip1283_transition: p.eip1283_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip1014_transition: p.eip1014_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
dust_protection_transition: p.dust_protection_transition.map_or_else( dust_protection_transition: p.dust_protection_transition.map_or_else(
BlockNumber::max_value, BlockNumber::max_value,
Into::into, Into::into,
@@ -287,6 +312,14 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value, BlockNumber::max_value,
Into::into Into::into
), ),
kip4_transition: p.kip4_transition.map_or_else(
BlockNumber::max_value,
Into::into
),
kip6_transition: p.kip6_transition.map_or_else(
BlockNumber::max_value,
Into::into
),
} }
} }
} }
@@ -829,14 +862,13 @@ impl Spec {
data: d, data: d,
}.fake_sign(from); }.fake_sign(from);
let res = ::state::prove_transaction( let res = ::state::prove_transaction_virtual(
db.as_hashdb_mut(), db.as_hashdb_mut(),
*genesis.state_root(), *genesis.state_root(),
&tx, &tx,
self.engine.machine(), self.engine.machine(),
&env_info, &env_info,
factories.clone(), factories.clone(),
true,
); );
res.map(|(out, proof)| { res.map(|(out, proof)| {

View File

@@ -59,6 +59,10 @@ pub struct Account {
// LRU Cache of the trie-backed storage. // LRU Cache of the trie-backed storage.
// This is limited to `STORAGE_CACHE_ITEMS` recent queries // This is limited to `STORAGE_CACHE_ITEMS` recent queries
storage_cache: RefCell<LruCache<H256, H256>>, storage_cache: RefCell<LruCache<H256, H256>>,
// LRU Cache of the trie-backed storage for original value.
// This is only used when the initial storage root is different compared to
// what is in the database. That is, it is only used for new contracts.
original_storage_cache: Option<(H256, RefCell<LruCache<H256, H256>>)>,
// Modified storage. Accumulates changes to storage made in `set_storage` // Modified storage. Accumulates changes to storage made in `set_storage`
// Takes precedence over `storage_cache`. // Takes precedence over `storage_cache`.
storage_changes: HashMap<H256, H256>, storage_changes: HashMap<H256, H256>,
@@ -81,6 +85,7 @@ impl From<BasicAccount> for Account {
nonce: basic.nonce, nonce: basic.nonce,
storage_root: basic.storage_root, storage_root: basic.storage_root,
storage_cache: Self::empty_storage_cache(), storage_cache: Self::empty_storage_cache(),
original_storage_cache: None,
storage_changes: HashMap::new(), storage_changes: HashMap::new(),
code_hash: basic.code_hash, code_hash: basic.code_hash,
code_size: None, code_size: None,
@@ -100,6 +105,7 @@ impl Account {
nonce: nonce, nonce: nonce,
storage_root: KECCAK_NULL_RLP, storage_root: KECCAK_NULL_RLP,
storage_cache: Self::empty_storage_cache(), storage_cache: Self::empty_storage_cache(),
original_storage_cache: None,
storage_changes: storage, storage_changes: storage,
code_hash: keccak(&code), code_hash: keccak(&code),
code_size: Some(code.len()), code_size: Some(code.len()),
@@ -120,6 +126,7 @@ impl Account {
nonce: pod.nonce, nonce: pod.nonce,
storage_root: KECCAK_NULL_RLP, storage_root: KECCAK_NULL_RLP,
storage_cache: Self::empty_storage_cache(), storage_cache: Self::empty_storage_cache(),
original_storage_cache: None,
storage_changes: pod.storage.into_iter().collect(), storage_changes: pod.storage.into_iter().collect(),
code_hash: pod.code.as_ref().map_or(KECCAK_EMPTY, |c| keccak(c)), code_hash: pod.code.as_ref().map_or(KECCAK_EMPTY, |c| keccak(c)),
code_filth: Filth::Dirty, code_filth: Filth::Dirty,
@@ -136,6 +143,7 @@ impl Account {
nonce: nonce, nonce: nonce,
storage_root: KECCAK_NULL_RLP, storage_root: KECCAK_NULL_RLP,
storage_cache: Self::empty_storage_cache(), storage_cache: Self::empty_storage_cache(),
original_storage_cache: None,
storage_changes: HashMap::new(), storage_changes: HashMap::new(),
code_hash: KECCAK_EMPTY, code_hash: KECCAK_EMPTY,
code_cache: Arc::new(vec![]), code_cache: Arc::new(vec![]),
@@ -154,12 +162,17 @@ impl Account {
/// Create a new contract account. /// Create a new contract account.
/// NOTE: make sure you use `init_code` on this before `commit`ing. /// NOTE: make sure you use `init_code` on this before `commit`ing.
pub fn new_contract(balance: U256, nonce: U256) -> Account { pub fn new_contract(balance: U256, nonce: U256, original_storage_root: H256) -> Account {
Account { Account {
balance: balance, balance: balance,
nonce: nonce, nonce: nonce,
storage_root: KECCAK_NULL_RLP, storage_root: KECCAK_NULL_RLP,
storage_cache: Self::empty_storage_cache(), storage_cache: Self::empty_storage_cache(),
original_storage_cache: if original_storage_root == KECCAK_NULL_RLP {
None
} else {
Some((original_storage_root, Self::empty_storage_cache()))
},
storage_changes: HashMap::new(), storage_changes: HashMap::new(),
code_hash: KECCAK_EMPTY, code_hash: KECCAK_EMPTY,
code_cache: Arc::new(vec![]), code_cache: Arc::new(vec![]),
@@ -204,11 +217,43 @@ impl Account {
if let Some(value) = self.cached_storage_at(key) { if let Some(value) = self.cached_storage_at(key) {
return Ok(value); return Ok(value);
} }
let db = SecTrieDB::new(db, &self.storage_root)?; Self::get_and_cache_storage(
&self.storage_root,
&mut self.storage_cache.borrow_mut(),
db,
key)
}
/// Get (and cache) the contents of the trie's storage at `key`.
/// Does not take modified storage into account.
pub fn original_storage_at(&self, db: &HashDB<KeccakHasher>, key: &H256) -> TrieResult<H256> {
if let Some(value) = self.cached_original_storage_at(key) {
return Ok(value);
}
match &self.original_storage_cache {
Some((ref original_storage_root, ref original_storage_cache)) =>
Self::get_and_cache_storage(
original_storage_root,
&mut original_storage_cache.borrow_mut(),
db,
key
),
None =>
Self::get_and_cache_storage(
&self.storage_root,
&mut self.storage_cache.borrow_mut(),
db,
key
),
}
}
fn get_and_cache_storage(storage_root: &H256, storage_cache: &mut LruCache<H256, H256>, db: &HashDB<KeccakHasher>, key: &H256) -> TrieResult<H256> {
let db = SecTrieDB::new(db, storage_root)?;
let panicky_decoder = |bytes:&[u8]| ::rlp::decode(&bytes).expect("decoding db value failed"); let panicky_decoder = |bytes:&[u8]| ::rlp::decode(&bytes).expect("decoding db value failed");
let item: U256 = db.get_with(key, panicky_decoder)?.unwrap_or_else(U256::zero); let item: U256 = db.get_with(key, panicky_decoder)?.unwrap_or_else(U256::zero);
let value: H256 = item.into(); let value: H256 = item.into();
self.storage_cache.borrow_mut().insert(key.clone(), value.clone()); storage_cache.insert(key.clone(), value.clone());
Ok(value) Ok(value)
} }
@@ -218,10 +263,38 @@ impl Account {
if let Some(value) = self.storage_changes.get(key) { if let Some(value) = self.storage_changes.get(key) {
return Some(value.clone()) return Some(value.clone())
} }
if let Some(value) = self.storage_cache.borrow_mut().get_mut(key) { self.cached_moved_original_storage_at(key)
return Some(value.clone()) }
/// Get cached original storage value after last state commitment. Returns `None` if the key is not in the cache.
pub fn cached_original_storage_at(&self, key: &H256) -> Option<H256> {
match &self.original_storage_cache {
Some((_, ref original_storage_cache)) => {
if let Some(value) = original_storage_cache.borrow_mut().get_mut(key) {
Some(value.clone())
} else {
None
}
},
None => {
self.cached_moved_original_storage_at(key)
},
}
}
/// Get cached original storage value since last contract creation on this address. Returns `None` if the key is not in the cache.
fn cached_moved_original_storage_at(&self, key: &H256) -> Option<H256> {
// If storage root is empty RLP, then early return zero value. Practically, this makes it so that if
// `original_storage_cache` is used, then `storage_cache` will always remain empty.
if self.storage_root == KECCAK_NULL_RLP {
return Some(H256::new());
}
if let Some(value) = self.storage_cache.borrow_mut().get_mut(key) {
Some(value.clone())
} else {
None
} }
None
} }
/// return the balance associated with this account. /// return the balance associated with this account.
@@ -278,12 +351,13 @@ impl Account {
!self.code_cache.is_empty() || (self.code_cache.is_empty() && self.code_hash == KECCAK_EMPTY) !self.code_cache.is_empty() || (self.code_cache.is_empty() && self.code_hash == KECCAK_EMPTY)
} }
/// Provide a database to get `code_hash`. Should not be called if it is a contract without code. /// Provide a database to get `code_hash`. Should not be called if it is a contract without code. Returns the cached code, if successful.
#[must_use]
pub fn cache_code(&mut self, db: &HashDB<KeccakHasher>) -> Option<Arc<Bytes>> { pub fn cache_code(&mut self, db: &HashDB<KeccakHasher>) -> Option<Arc<Bytes>> {
// TODO: fill out self.code_cache; // TODO: fill out self.code_cache;
trace!("Account::cache_code: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty()); trace!("Account::cache_code: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty());
if self.is_cached() { return Some(self.code_cache.clone()) } if self.is_cached() { return Some(self.code_cache.clone()); }
match db.get(&self.code_hash) { match db.get(&self.code_hash) {
Some(x) => { Some(x) => {
@@ -298,8 +372,7 @@ impl Account {
} }
} }
/// Provide code to cache. For correctness, should be the correct code for the /// Provide code to cache. For correctness, should be the correct code for the account.
/// account.
pub fn cache_given_code(&mut self, code: Arc<Bytes>) { pub fn cache_given_code(&mut self, code: Arc<Bytes>) {
trace!("Account::cache_given_code: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty()); trace!("Account::cache_given_code: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty());
@@ -307,7 +380,9 @@ impl Account {
self.code_cache = code; self.code_cache = code;
} }
/// Provide a database to get `code_size`. Should not be called if it is a contract without code. /// Provide a database to get `code_size`. Should not be called if it is a contract without code. Returns whether
/// the cache succeeds.
#[must_use]
pub fn cache_code_size(&mut self, db: &HashDB<KeccakHasher>) -> bool { pub fn cache_code_size(&mut self, db: &HashDB<KeccakHasher>) -> bool {
// TODO: fill out self.code_cache; // TODO: fill out self.code_cache;
trace!("Account::cache_code_size: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty()); trace!("Account::cache_code_size: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty());
@@ -324,7 +399,9 @@ impl Account {
}, },
} }
} else { } else {
false // If the code hash is empty hash, then the code size is zero.
self.code_size = Some(0);
true
} }
} }
@@ -352,7 +429,27 @@ impl Account {
} }
/// Return the storage root associated with this account or None if it has been altered via the overlay. /// Return the storage root associated with this account or None if it has been altered via the overlay.
pub fn storage_root(&self) -> Option<&H256> { if self.storage_is_clean() {Some(&self.storage_root)} else {None} } pub fn storage_root(&self) -> Option<H256> {
if self.storage_is_clean() {
Some(self.storage_root)
} else {
None
}
}
/// Return the original storage root of this account.
pub fn original_storage_root(&self) -> H256 {
if let Some((original_storage_root, _)) = self.original_storage_cache {
original_storage_root
} else {
self.storage_root
}
}
/// Storage root where the account changes are based upon.
pub fn base_storage_root(&self) -> H256 {
self.storage_root
}
/// Return the storage overlay. /// Return the storage overlay.
pub fn storage_changes(&self) -> &HashMap<H256, H256> { &self.storage_changes } pub fn storage_changes(&self) -> &HashMap<H256, H256> { &self.storage_changes }
@@ -387,6 +484,7 @@ impl Account {
self.storage_cache.borrow_mut().insert(k, v); self.storage_cache.borrow_mut().insert(k, v);
} }
self.original_storage_cache = None;
Ok(()) Ok(())
} }
@@ -424,6 +522,7 @@ impl Account {
nonce: self.nonce.clone(), nonce: self.nonce.clone(),
storage_root: self.storage_root.clone(), storage_root: self.storage_root.clone(),
storage_cache: Self::empty_storage_cache(), storage_cache: Self::empty_storage_cache(),
original_storage_cache: self.original_storage_cache.as_ref().map(|(r, _)| (*r, Self::empty_storage_cache())),
storage_changes: HashMap::new(), storage_changes: HashMap::new(),
code_hash: self.code_hash.clone(), code_hash: self.code_hash.clone(),
code_size: self.code_size.clone(), code_size: self.code_size.clone(),
@@ -444,6 +543,7 @@ impl Account {
pub fn clone_all(&self) -> Account { pub fn clone_all(&self) -> Account {
let mut account = self.clone_dirty(); let mut account = self.clone_dirty();
account.storage_cache = self.storage_cache.clone(); account.storage_cache = self.storage_cache.clone();
account.original_storage_cache = self.original_storage_cache.clone();
account account
} }
@@ -453,16 +553,21 @@ impl Account {
pub fn overwrite_with(&mut self, other: Account) { pub fn overwrite_with(&mut self, other: Account) {
self.balance = other.balance; self.balance = other.balance;
self.nonce = other.nonce; self.nonce = other.nonce;
self.storage_root = other.storage_root;
self.code_hash = other.code_hash; self.code_hash = other.code_hash;
self.code_filth = other.code_filth; self.code_filth = other.code_filth;
self.code_cache = other.code_cache; self.code_cache = other.code_cache;
self.code_size = other.code_size; self.code_size = other.code_size;
self.address_hash = other.address_hash; self.address_hash = other.address_hash;
let mut cache = self.storage_cache.borrow_mut(); if self.storage_root == other.storage_root {
for (k, v) in other.storage_cache.into_inner() { let mut cache = self.storage_cache.borrow_mut();
cache.insert(k, v); for (k, v) in other.storage_cache.into_inner() {
cache.insert(k, v);
}
} else {
self.storage_cache = other.storage_cache;
} }
self.original_storage_cache = other.original_storage_cache;
self.storage_root = other.storage_root;
self.storage_changes = other.storage_changes; self.storage_changes = other.storage_changes;
} }
} }
@@ -521,7 +626,7 @@ mod tests {
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = { let rlp = {
let mut a = Account::new_contract(69.into(), 0.into()); let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP);
a.set_storage(0x00u64.into(), 0x1234u64.into()); a.set_storage(0x00u64.into(), 0x1234u64.into());
a.commit_storage(&Default::default(), &mut db).unwrap(); a.commit_storage(&Default::default(), &mut db).unwrap();
a.init_code(vec![]); a.init_code(vec![]);
@@ -530,7 +635,7 @@ mod tests {
}; };
let a = Account::from_rlp(&rlp).expect("decoding db value failed"); let a = Account::from_rlp(&rlp).expect("decoding db value failed");
assert_eq!(*a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()); assert_eq!(a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into());
assert_eq!(a.storage_at(&db.immutable(), &0x00u64.into()).unwrap(), 0x1234u64.into()); assert_eq!(a.storage_at(&db.immutable(), &0x00u64.into()).unwrap(), 0x1234u64.into());
assert_eq!(a.storage_at(&db.immutable(), &0x01u64.into()).unwrap(), H256::default()); assert_eq!(a.storage_at(&db.immutable(), &0x01u64.into()).unwrap(), H256::default());
} }
@@ -541,7 +646,7 @@ mod tests {
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = { let rlp = {
let mut a = Account::new_contract(69.into(), 0.into()); let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP);
a.init_code(vec![0x55, 0x44, 0xffu8]); a.init_code(vec![0x55, 0x44, 0xffu8]);
a.commit_code(&mut db); a.commit_code(&mut db);
a.rlp() a.rlp()
@@ -556,18 +661,18 @@ mod tests {
#[test] #[test]
fn commit_storage() { fn commit_storage() {
let mut a = Account::new_contract(69.into(), 0.into()); let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP);
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(0.into(), 0x1234.into()); a.set_storage(0.into(), 0x1234.into());
assert_eq!(a.storage_root(), None); assert_eq!(a.storage_root(), None);
a.commit_storage(&Default::default(), &mut db).unwrap(); a.commit_storage(&Default::default(), &mut db).unwrap();
assert_eq!(*a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()); assert_eq!(a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into());
} }
#[test] #[test]
fn commit_remove_commit_storage() { fn commit_remove_commit_storage() {
let mut a = Account::new_contract(69.into(), 0.into()); let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP);
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(0.into(), 0x1234.into()); a.set_storage(0.into(), 0x1234.into());
@@ -576,12 +681,12 @@ mod tests {
a.commit_storage(&Default::default(), &mut db).unwrap(); a.commit_storage(&Default::default(), &mut db).unwrap();
a.set_storage(1.into(), 0.into()); a.set_storage(1.into(), 0.into());
a.commit_storage(&Default::default(), &mut db).unwrap(); a.commit_storage(&Default::default(), &mut db).unwrap();
assert_eq!(*a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()); assert_eq!(a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into());
} }
#[test] #[test]
fn commit_code() { fn commit_code() {
let mut a = Account::new_contract(69.into(), 0.into()); let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP);
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
a.init_code(vec![0x55, 0x44, 0xffu8]); a.init_code(vec![0x55, 0x44, 0xffu8]);
@@ -593,7 +698,7 @@ mod tests {
#[test] #[test]
fn reset_code() { fn reset_code() {
let mut a = Account::new_contract(69.into(), 0.into()); let mut a = Account::new_contract(69.into(), 0.into(), KECCAK_NULL_RLP);
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
a.init_code(vec![0x55, 0x44, 0xffu8]); a.init_code(vec![0x55, 0x44, 0xffu8]);
@@ -624,7 +729,7 @@ mod tests {
assert_eq!(*a.balance(), 69u8.into()); assert_eq!(*a.balance(), 69u8.into());
assert_eq!(*a.nonce(), 0u8.into()); assert_eq!(*a.nonce(), 0u8.into());
assert_eq!(a.code_hash(), KECCAK_EMPTY); assert_eq!(a.code_hash(), KECCAK_EMPTY);
assert_eq!(a.storage_root().unwrap(), &KECCAK_NULL_RLP); assert_eq!(a.storage_root().unwrap(), KECCAK_NULL_RLP);
} }
#[test] #[test]

View File

@@ -181,6 +181,8 @@ impl AccountEntry {
Some(acc) => { Some(acc) => {
if let Some(ref mut ours) = self.account { if let Some(ref mut ours) = self.account {
ours.overwrite_with(acc); ours.overwrite_with(acc);
} else {
self.account = Some(acc);
} }
}, },
None => self.account = None, None => self.account = None,
@@ -222,17 +224,16 @@ pub fn check_proof(
} }
} }
/// Prove a transaction on the given state. /// Prove a `virtual` transaction on the given state.
/// Returns `None` when the transacion could not be proved, /// Returns `None` when the transacion could not be proved,
/// and a proof otherwise. /// and a proof otherwise.
pub fn prove_transaction<H: AsHashDB<KeccakHasher> + Send + Sync>( pub fn prove_transaction_virtual<H: AsHashDB<KeccakHasher> + Send + Sync>(
db: H, db: H,
root: H256, root: H256,
transaction: &SignedTransaction, transaction: &SignedTransaction,
machine: &Machine, machine: &Machine,
env_info: &EnvInfo, env_info: &EnvInfo,
factories: Factories, factories: Factories,
virt: bool,
) -> Option<(Bytes, Vec<DBValue>)> { ) -> Option<(Bytes, Vec<DBValue>)> {
use self::backend::Proving; use self::backend::Proving;
@@ -250,7 +251,7 @@ pub fn prove_transaction<H: AsHashDB<KeccakHasher> + Send + Sync>(
}; };
let options = TransactOptions::with_no_tracing().dont_check_nonce().save_output_from_contract(); let options = TransactOptions::with_no_tracing().dont_check_nonce().save_output_from_contract();
match state.execute(env_info, machine, transaction, options, virt) { match state.execute(env_info, machine, transaction, options, true) {
Err(ExecutionError::Internal(_)) => None, Err(ExecutionError::Internal(_)) => None,
Err(e) => { Err(e) => {
trace!(target: "state", "Proved call failed: {}", e); trace!(target: "state", "Proved call failed: {}", e);
@@ -401,9 +402,12 @@ impl<B: Backend> State<B> {
self.factories.vm.clone() self.factories.vm.clone()
} }
/// Create a recoverable checkpoint of this state. /// Create a recoverable checkpoint of this state. Return the checkpoint index.
pub fn checkpoint(&mut self) { pub fn checkpoint(&mut self) -> usize {
self.checkpoints.get_mut().push(HashMap::new()); let checkpoints = self.checkpoints.get_mut();
let index = checkpoints.len();
checkpoints.push(HashMap::new());
index
} }
/// Merge last checkpoint with previous. /// Merge last checkpoint with previous.
@@ -494,8 +498,10 @@ impl<B: Backend> State<B> {
/// Create a new contract at address `contract`. If there is already an account at the address /// Create a new contract at address `contract`. If there is already an account at the address
/// it will have its code reset, ready for `init_code()`. /// it will have its code reset, ready for `init_code()`.
pub fn new_contract(&mut self, contract: &Address, balance: U256, nonce_offset: U256) { pub fn new_contract(&mut self, contract: &Address, balance: U256, nonce_offset: U256) -> TrieResult<()> {
self.insert_cache(contract, AccountEntry::new_dirty(Some(Account::new_contract(balance, self.account_start_nonce + nonce_offset)))); let original_storage_root = self.original_storage_root(contract)?;
self.insert_cache(contract, AccountEntry::new_dirty(Some(Account::new_contract(balance, self.account_start_nonce + nonce_offset, original_storage_root))));
Ok(())
} }
/// Remove an existing account. /// Remove an existing account.
@@ -536,11 +542,84 @@ impl<B: Backend> State<B> {
/// Get the storage root of account `a`. /// Get the storage root of account `a`.
pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> { pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true, self.ensure_cached(a, RequireCache::None, true,
|a| a.as_ref().and_then(|account| account.storage_root().cloned())) |a| a.as_ref().and_then(|account| account.storage_root()))
} }
/// Mutate storage of account `address` so that it is `value` for `key`. /// Get the original storage root since last commit of account `a`.
pub fn storage_at(&self, address: &Address, key: &H256) -> TrieResult<H256> { pub fn original_storage_root(&self, a: &Address) -> TrieResult<H256> {
Ok(self.ensure_cached(a, RequireCache::None, true,
|a| a.as_ref().map(|account| account.original_storage_root()))?
.unwrap_or(KECCAK_NULL_RLP))
}
/// Get the value of storage at a specific checkpoint.
pub fn checkpoint_storage_at(&self, checkpoint_index: usize, address: &Address, key: &H256) -> TrieResult<Option<H256>> {
enum ReturnKind {
/// Use original storage at value at this address.
OriginalAt,
/// Use the downward checkpoint value.
Downward,
}
let (checkpoints_len, kind) = {
let checkpoints = self.checkpoints.borrow();
let checkpoints_len = checkpoints.len();
let checkpoint = match checkpoints.get(checkpoint_index) {
Some(checkpoint) => checkpoint,
// The checkpoint was not found. Return None.
None => return Ok(None),
};
let kind = match checkpoint.get(address) {
// The account exists at this checkpoint.
Some(Some(AccountEntry { account: Some(ref account), .. })) => {
if let Some(value) = account.cached_storage_at(key) {
return Ok(Some(value));
} else {
// This account has checkpoint entry, but the key is not in the entry's cache. We can use
// original_storage_at if current account's original storage root is the same as checkpoint
// account's original storage root. Otherwise, the account must be a newly created contract.
if account.base_storage_root() == self.original_storage_root(address)? {
ReturnKind::OriginalAt
} else {
// If account base storage root is different from the original storage root since last
// commit, then it can only be created from a new contract, where the base storage root
// would always be empty. Note that this branch is actually never called, because
// `cached_storage_at` handled this case.
warn!("Trying to get an account's cached storage value, but base storage root does not equal to original storage root! Assuming the value is empty.");
return Ok(Some(H256::new()));
}
}
},
// The account didn't exist at that point. Return empty value.
Some(Some(AccountEntry { account: None, .. })) => return Ok(Some(H256::new())),
// The value was not cached at that checkpoint, meaning it was not modified at all.
Some(None) => ReturnKind::OriginalAt,
// This key does not have a checkpoint entry.
None => ReturnKind::Downward,
};
(checkpoints_len, kind)
};
match kind {
ReturnKind::Downward => {
if checkpoint_index >= checkpoints_len - 1 {
Ok(Some(self.storage_at(address, key)?))
} else {
self.checkpoint_storage_at(checkpoint_index + 1, address, key)
}
},
ReturnKind::OriginalAt => Ok(Some(self.original_storage_at(address, key)?)),
}
}
fn storage_at_inner<FCachedStorageAt, FStorageAt>(
&self, address: &Address, key: &H256, f_cached_at: FCachedStorageAt, f_at: FStorageAt,
) -> TrieResult<H256> where
FCachedStorageAt: Fn(&Account, &H256) -> Option<H256>,
FStorageAt: Fn(&Account, &HashDB<KeccakHasher>, &H256) -> TrieResult<H256>
{
// Storage key search and update works like this: // Storage key search and update works like this:
// 1. If there's an entry for the account in the local cache check for the key and return it if found. // 1. If there's an entry for the account in the local cache check for the key and return it if found.
// 2. If there's an entry for the account in the global cache check for the key or load it into that account. // 2. If there's an entry for the account in the global cache check for the key or load it into that account.
@@ -553,7 +632,7 @@ impl<B: Backend> State<B> {
if let Some(maybe_acc) = local_cache.get(address) { if let Some(maybe_acc) = local_cache.get(address) {
match maybe_acc.account { match maybe_acc.account {
Some(ref account) => { Some(ref account) => {
if let Some(value) = account.cached_storage_at(key) { if let Some(value) = f_cached_at(account, key) {
return Ok(value); return Ok(value);
} else { } else {
local_account = Some(maybe_acc); local_account = Some(maybe_acc);
@@ -567,7 +646,7 @@ impl<B: Backend> State<B> {
None => Ok(H256::new()), None => Ok(H256::new()),
Some(a) => { Some(a) => {
let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address)); let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address));
a.storage_at(account_db.as_hashdb(), key) f_at(a, account_db.as_hashdb(), key)
} }
}); });
@@ -579,7 +658,7 @@ impl<B: Backend> State<B> {
if let Some(ref mut acc) = local_account { if let Some(ref mut acc) = local_account {
if let Some(ref account) = acc.account { if let Some(ref account) = acc.account {
let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(address)); let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(address));
return account.storage_at(account_db.as_hashdb(), key) return f_at(account, account_db.as_hashdb(), key)
} else { } else {
return Ok(H256::new()) return Ok(H256::new())
} }
@@ -595,12 +674,32 @@ impl<B: Backend> State<B> {
let maybe_acc = db.get_with(address, from_rlp)?; let maybe_acc = db.get_with(address, from_rlp)?;
let r = maybe_acc.as_ref().map_or(Ok(H256::new()), |a| { let r = maybe_acc.as_ref().map_or(Ok(H256::new()), |a| {
let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address)); let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address));
a.storage_at(account_db.as_hashdb(), key) f_at(a, account_db.as_hashdb(), key)
}); });
self.insert_cache(address, AccountEntry::new_clean(maybe_acc)); self.insert_cache(address, AccountEntry::new_clean(maybe_acc));
r r
} }
/// Mutate storage of account `address` so that it is `value` for `key`.
pub fn storage_at(&self, address: &Address, key: &H256) -> TrieResult<H256> {
self.storage_at_inner(
address,
key,
|account, key| { account.cached_storage_at(key) },
|account, db, key| { account.storage_at(db, key) },
)
}
/// Get the value of storage after last state commitment.
pub fn original_storage_at(&self, address: &Address, key: &H256) -> TrieResult<H256> {
self.storage_at_inner(
address,
key,
|account, key| { account.cached_original_storage_at(key) },
|account, db, key| { account.original_storage_at(db, key) },
)
}
/// Get accounts' code. /// Get accounts' code.
pub fn code(&self, a: &Address) -> TrieResult<Option<Arc<Bytes>>> { pub fn code(&self, a: &Address) -> TrieResult<Option<Arc<Bytes>>> {
self.ensure_cached(a, RequireCache::Code, true, self.ensure_cached(a, RequireCache::Code, true,
@@ -608,9 +707,9 @@ impl<B: Backend> State<B> {
} }
/// Get an account's code hash. /// Get an account's code hash.
pub fn code_hash(&self, a: &Address) -> TrieResult<H256> { pub fn code_hash(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true, self.ensure_cached(a, RequireCache::None, true,
|a| a.as_ref().map_or(KECCAK_EMPTY, |a| a.code_hash())) |a| a.as_ref().map(|a| a.code_hash()))
} }
/// Get accounts' code size. /// Get accounts' code size.
@@ -671,13 +770,13 @@ impl<B: Backend> State<B> {
/// Initialise the code of account `a` so that it is `code`. /// Initialise the code of account `a` so that it is `code`.
/// NOTE: Account should have been created with `new_contract`. /// NOTE: Account should have been created with `new_contract`.
pub fn init_code(&mut self, a: &Address, code: Bytes) -> TrieResult<()> { pub fn init_code(&mut self, a: &Address, code: Bytes) -> TrieResult<()> {
self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce), |_|{})?.init_code(code); self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce, KECCAK_NULL_RLP), |_| {})?.init_code(code);
Ok(()) Ok(())
} }
/// Reset the code of account `a` so that it is `code`. /// Reset the code of account `a` so that it is `code`.
pub fn reset_code(&mut self, a: &Address, code: Bytes) -> TrieResult<()> { pub fn reset_code(&mut self, a: &Address, code: Bytes) -> TrieResult<()> {
self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce), |_|{})?.reset_code(code); self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce, KECCAK_NULL_RLP), |_| {})?.reset_code(code);
Ok(()) Ok(())
} }
@@ -760,6 +859,7 @@ impl<B: Backend> State<B> {
/// Commits our cached account changes into the trie. /// Commits our cached account changes into the trie.
pub fn commit(&mut self) -> Result<(), Error> { pub fn commit(&mut self) -> Result<(), Error> {
assert!(self.checkpoints.borrow().is_empty());
// first, commit the sub trees. // first, commit the sub trees.
let mut accounts = self.cache.borrow_mut(); let mut accounts = self.cache.borrow_mut();
for (address, ref mut a) in accounts.iter_mut().filter(|&(_, ref a)| a.is_dirty()) { for (address, ref mut a) in accounts.iter_mut().filter(|&(_, ref a)| a.is_dirty()) {
@@ -805,6 +905,7 @@ impl<B: Backend> State<B> {
/// Clear state cache /// Clear state cache
pub fn clear(&mut self) { pub fn clear(&mut self) {
assert!(self.checkpoints.borrow().is_empty());
self.cache.borrow_mut().clear(); self.cache.borrow_mut().clear();
} }
@@ -910,31 +1011,38 @@ impl<B: Backend> State<B> {
Ok(pod_state::diff_pod(&pod_state_pre, &pod_state_post)) Ok(pod_state::diff_pod(&pod_state_pre, &pod_state_post))
} }
// load required account data from the databases. /// Load required account data from the databases. Returns whether the cache succeeds.
fn update_account_cache(require: RequireCache, account: &mut Account, state_db: &B, db: &HashDB<KeccakHasher>) { #[must_use]
fn update_account_cache(require: RequireCache, account: &mut Account, state_db: &B, db: &HashDB<KeccakHasher>) -> bool {
if let RequireCache::None = require { if let RequireCache::None = require {
return; return true;
} }
if account.is_cached() { if account.is_cached() {
return; return true;
} }
// if there's already code in the global cache, always cache it localy // if there's already code in the global cache, always cache it localy
let hash = account.code_hash(); let hash = account.code_hash();
match state_db.get_cached_code(&hash) { match state_db.get_cached_code(&hash) {
Some(code) => account.cache_given_code(code), Some(code) => {
account.cache_given_code(code);
true
},
None => match require { None => match require {
RequireCache::None => {}, RequireCache::None => true,
RequireCache::Code => { RequireCache::Code => {
if let Some(code) = account.cache_code(db) { if let Some(code) = account.cache_code(db) {
// propagate code loaded from the database to // propagate code loaded from the database to
// the global code cache. // the global code cache.
state_db.cache_code(hash, code) state_db.cache_code(hash, code);
true
} else {
false
} }
}, },
RequireCache::CodeSize => { RequireCache::CodeSize => {
account.cache_code_size(db); account.cache_code_size(db)
} }
} }
} }
@@ -949,8 +1057,11 @@ impl<B: Backend> State<B> {
if let Some(ref mut maybe_acc) = self.cache.borrow_mut().get_mut(a) { if let Some(ref mut maybe_acc) = self.cache.borrow_mut().get_mut(a) {
if let Some(ref mut account) = maybe_acc.account { if let Some(ref mut account) = maybe_acc.account {
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a)); let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a));
Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()); if Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()) {
return Ok(f(Some(account))); return Ok(f(Some(account)));
} else {
return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a))));
}
} }
return Ok(f(None)); return Ok(f(None));
} }
@@ -958,12 +1069,14 @@ impl<B: Backend> State<B> {
let result = self.db.get_cached(a, |mut acc| { let result = self.db.get_cached(a, |mut acc| {
if let Some(ref mut account) = acc { if let Some(ref mut account) = acc {
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a)); let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a));
Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()); if !Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()) {
return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a))));
}
} }
f(acc.map(|a| &*a)) Ok(f(acc.map(|a| &*a)))
}); });
match result { match result {
Some(r) => Ok(r), Some(r) => Ok(r?),
None => { None => {
// first check if it is not in database for sure // first check if it is not in database for sure
if check_null && self.db.is_known_null(a) { return Ok(f(None)); } if check_null && self.db.is_known_null(a) { return Ok(f(None)); }
@@ -974,7 +1087,9 @@ impl<B: Backend> State<B> {
let mut maybe_acc = db.get_with(a, from_rlp)?; let mut maybe_acc = db.get_with(a, from_rlp)?;
if let Some(ref mut account) = maybe_acc.as_mut() { if let Some(ref mut account) = maybe_acc.as_mut() {
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a)); let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a));
Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()); if !Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb()) {
return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a))));
}
} }
let r = f(maybe_acc.as_ref()); let r = f(maybe_acc.as_ref());
self.insert_cache(a, AccountEntry::new_clean(maybe_acc)); self.insert_cache(a, AccountEntry::new_clean(maybe_acc));
@@ -985,7 +1100,7 @@ impl<B: Backend> State<B> {
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too. /// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
fn require<'a>(&'a self, a: &Address, require_code: bool) -> TrieResult<RefMut<'a, Account>> { fn require<'a>(&'a self, a: &Address, require_code: bool) -> TrieResult<RefMut<'a, Account>> {
self.require_or_from(a, require_code, || Account::new_basic(0u8.into(), self.account_start_nonce), |_|{}) self.require_or_from(a, require_code, || Account::new_basic(0u8.into(), self.account_start_nonce), |_| {})
} }
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too. /// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
@@ -1125,7 +1240,7 @@ mod tests {
use std::sync::Arc; use std::sync::Arc;
use std::str::FromStr; use std::str::FromStr;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use hash::keccak; use hash::{keccak, KECCAK_NULL_RLP};
use super::*; use super::*;
use ethkey::Secret; use ethkey::Secret;
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
@@ -1977,7 +2092,7 @@ mod tests {
let a = Address::zero(); let a = Address::zero();
let (root, db) = { let (root, db) = {
let mut state = get_temp_state(); let mut state = get_temp_state();
state.require_or_from(&a, false, ||Account::new_contract(42.into(), 0.into()), |_|{}).unwrap(); state.require_or_from(&a, false, || Account::new_contract(42.into(), 0.into(), KECCAK_NULL_RLP), |_|{}).unwrap();
state.init_code(&a, vec![1, 2, 3]).unwrap(); state.init_code(&a, vec![1, 2, 3]).unwrap();
assert_eq!(state.code(&a).unwrap(), Some(Arc::new(vec![1u8, 2, 3]))); assert_eq!(state.code(&a).unwrap(), Some(Arc::new(vec![1u8, 2, 3])));
state.commit().unwrap(); state.commit().unwrap();
@@ -2181,6 +2296,180 @@ mod tests {
assert_eq!(state.balance(&a).unwrap(), U256::from(0)); assert_eq!(state.balance(&a).unwrap(), U256::from(0));
} }
#[test]
fn checkpoint_revert_to_get_storage_at() {
let mut state = get_temp_state();
let a = Address::zero();
let k = H256::from(U256::from(0));
let c0 = state.checkpoint();
let c1 = state.checkpoint();
state.set_storage(&a, k, H256::from(U256::from(1))).unwrap();
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.storage_at(&a, &k).unwrap(), H256::from(U256::from(1)));
state.revert_to_checkpoint(); // Revert to c1.
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.storage_at(&a, &k).unwrap(), H256::from(U256::from(0)));
}
#[test]
fn checkpoint_from_empty_get_storage_at() {
let mut state = get_temp_state();
let a = Address::zero();
let k = H256::from(U256::from(0));
let k2 = H256::from(U256::from(1));
assert_eq!(state.storage_at(&a, &k).unwrap(), H256::from(U256::from(0)));
state.clear();
let c0 = state.checkpoint();
state.new_contract(&a, U256::zero(), U256::zero()).unwrap();
let c1 = state.checkpoint();
state.set_storage(&a, k, H256::from(U256::from(1))).unwrap();
let c2 = state.checkpoint();
let c3 = state.checkpoint();
state.set_storage(&a, k2, H256::from(U256::from(3))).unwrap();
state.set_storage(&a, k, H256::from(U256::from(3))).unwrap();
let c4 = state.checkpoint();
state.set_storage(&a, k, H256::from(U256::from(4))).unwrap();
let c5 = state.checkpoint();
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c3, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c4, &a, &k).unwrap(), Some(H256::from(U256::from(3))));
assert_eq!(state.checkpoint_storage_at(c5, &a, &k).unwrap(), Some(H256::from(U256::from(4))));
state.discard_checkpoint(); // Commit/discard c5.
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c3, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c4, &a, &k).unwrap(), Some(H256::from(U256::from(3))));
state.revert_to_checkpoint(); // Revert to c4.
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c3, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
state.discard_checkpoint(); // Commit/discard c3.
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
state.revert_to_checkpoint(); // Revert to c2.
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
state.discard_checkpoint(); // Commit/discard c1.
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
}
#[test]
fn checkpoint_get_storage_at() {
let mut state = get_temp_state();
let a = Address::zero();
let k = H256::from(U256::from(0));
let k2 = H256::from(U256::from(1));
state.set_storage(&a, k, H256::from(U256::from(0xffff))).unwrap();
state.commit().unwrap();
state.clear();
assert_eq!(state.storage_at(&a, &k).unwrap(), H256::from(U256::from(0xffff)));
state.clear();
let cm1 = state.checkpoint();
let c0 = state.checkpoint();
state.new_contract(&a, U256::zero(), U256::zero()).unwrap();
let c1 = state.checkpoint();
state.set_storage(&a, k, H256::from(U256::from(1))).unwrap();
let c2 = state.checkpoint();
let c3 = state.checkpoint();
state.set_storage(&a, k2, H256::from(U256::from(3))).unwrap();
state.set_storage(&a, k, H256::from(U256::from(3))).unwrap();
let c4 = state.checkpoint();
state.set_storage(&a, k, H256::from(U256::from(4))).unwrap();
let c5 = state.checkpoint();
assert_eq!(state.checkpoint_storage_at(cm1, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c3, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c4, &a, &k).unwrap(), Some(H256::from(U256::from(3))));
assert_eq!(state.checkpoint_storage_at(c5, &a, &k).unwrap(), Some(H256::from(U256::from(4))));
state.discard_checkpoint(); // Commit/discard c5.
assert_eq!(state.checkpoint_storage_at(cm1, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c3, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c4, &a, &k).unwrap(), Some(H256::from(U256::from(3))));
state.revert_to_checkpoint(); // Revert to c4.
assert_eq!(state.checkpoint_storage_at(cm1, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
assert_eq!(state.checkpoint_storage_at(c3, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
state.discard_checkpoint(); // Commit/discard c3.
assert_eq!(state.checkpoint_storage_at(cm1, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
assert_eq!(state.checkpoint_storage_at(c2, &a, &k).unwrap(), Some(H256::from(U256::from(1))));
state.revert_to_checkpoint(); // Revert to c2.
assert_eq!(state.checkpoint_storage_at(cm1, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c1, &a, &k).unwrap(), Some(H256::from(U256::from(0))));
state.discard_checkpoint(); // Commit/discard c1.
assert_eq!(state.checkpoint_storage_at(cm1, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
assert_eq!(state.checkpoint_storage_at(c0, &a, &k).unwrap(), Some(H256::from(U256::from(0xffff))));
}
#[test]
fn kill_account_with_checkpoints() {
let mut state = get_temp_state();
let a = Address::zero();
let k = H256::from(U256::from(0));
state.checkpoint();
state.set_storage(&a, k, H256::from(U256::from(1))).unwrap();
state.checkpoint();
state.kill_account(&a);
assert_eq!(state.storage_at(&a, &k).unwrap(), H256::from(U256::from(0)));
state.revert_to_checkpoint();
assert_eq!(state.storage_at(&a, &k).unwrap(), H256::from(U256::from(1)));
}
#[test]
fn create_contract_fail() {
let mut state = get_temp_state();
let orig_root = state.root().clone();
let a: Address = 1000.into();
state.checkpoint(); // c1
state.new_contract(&a, U256::zero(), U256::zero()).unwrap();
state.add_balance(&a, &U256::from(1), CleanupMode::ForceCreate).unwrap();
state.checkpoint(); // c2
state.add_balance(&a, &U256::from(1), CleanupMode::ForceCreate).unwrap();
state.discard_checkpoint(); // discard c2
state.revert_to_checkpoint(); // revert to c1
assert_eq!(state.exists(&a).unwrap(), false);
state.commit().unwrap();
assert_eq!(orig_root, state.root().clone());
}
#[test] #[test]
fn create_empty() { fn create_empty() {
let mut state = get_temp_state(); let mut state = get_temp_state();
@@ -2218,7 +2507,7 @@ mod tests {
state.add_balance(&b, &100.into(), CleanupMode::ForceCreate).unwrap(); // create a dust account state.add_balance(&b, &100.into(), CleanupMode::ForceCreate).unwrap(); // create a dust account
state.add_balance(&c, &101.into(), CleanupMode::ForceCreate).unwrap(); // create a normal account state.add_balance(&c, &101.into(), CleanupMode::ForceCreate).unwrap(); // create a normal account
state.add_balance(&d, &99.into(), CleanupMode::ForceCreate).unwrap(); // create another dust account state.add_balance(&d, &99.into(), CleanupMode::ForceCreate).unwrap(); // create another dust account
state.new_contract(&e, 100.into(), 1.into()); // create a contract account state.new_contract(&e, 100.into(), 1.into()).unwrap(); // create a contract account
state.init_code(&e, vec![0x00]).unwrap(); state.init_code(&e, vec![0x00]).unwrap();
state.commit().unwrap(); state.commit().unwrap();
state.drop() state.drop()

View File

@@ -34,8 +34,8 @@ pub struct Substate {
/// Any logs. /// Any logs.
pub logs: Vec<LogEntry>, pub logs: Vec<LogEntry>,
/// Refund counter of SSTORE nonzero -> zero. /// Refund counter of SSTORE.
pub sstore_clears_count: U256, pub sstore_clears_refund: U256,
/// Created contracts. /// Created contracts.
pub contracts_created: Vec<Address>, pub contracts_created: Vec<Address>,
@@ -52,7 +52,7 @@ impl Substate {
self.suicides.extend(s.suicides); self.suicides.extend(s.suicides);
self.touched.extend(s.touched); self.touched.extend(s.touched);
self.logs.extend(s.logs); self.logs.extend(s.logs);
self.sstore_clears_count = self.sstore_clears_count + s.sstore_clears_count; self.sstore_clears_refund = self.sstore_clears_refund + s.sstore_clears_refund;
self.contracts_created.extend(s.contracts_created); self.contracts_created.extend(s.contracts_created);
} }
@@ -86,7 +86,7 @@ mod tests {
topics: vec![], topics: vec![],
data: vec![] data: vec![]
}); });
sub_state.sstore_clears_count = 5.into(); sub_state.sstore_clears_refund = (15000 * 5).into();
sub_state.suicides.insert(10u64.into()); sub_state.suicides.insert(10u64.into());
let mut sub_state_2 = Substate::new(); let mut sub_state_2 = Substate::new();
@@ -96,11 +96,11 @@ mod tests {
topics: vec![], topics: vec![],
data: vec![] data: vec![]
}); });
sub_state_2.sstore_clears_count = 7.into(); sub_state_2.sstore_clears_refund = (15000 * 7).into();
sub_state.accrue(sub_state_2); sub_state.accrue(sub_state_2);
assert_eq!(sub_state.contracts_created.len(), 2); assert_eq!(sub_state.contracts_created.len(), 2);
assert_eq!(sub_state.sstore_clears_count, 12.into()); assert_eq!(sub_state.sstore_clears_refund, (15000 * 12).into());
assert_eq!(sub_state.suicides.len(), 1); assert_eq!(sub_state.suicides.len(), 1);
} }
} }

View File

@@ -39,7 +39,7 @@ fn test_blockhash_eip210(factory: Factory) {
let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b"; let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b";
let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap()); let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap());
let blockhash_contract_code_hash = keccak(blockhash_contract_code.as_ref()); let blockhash_contract_code_hash = keccak(blockhash_contract_code.as_ref());
let machine = ::ethereum::new_constantinople_test_machine(); let machine = ::ethereum::new_eip210_test_machine();
let mut env_info = EnvInfo::default(); let mut env_info = EnvInfo::default();
// populate state with 256 last hashes // populate state with 256 last hashes

View File

@@ -500,8 +500,9 @@ impl ChainSync {
self.peers.clear(); self.peers.clear();
} }
/// Reset sync. Clear all downloaded data but keep the queue /// Reset sync. Clear all downloaded data but keep the queue.
fn reset(&mut self, io: &mut SyncIo) { /// Set sync state to the given state or to the initial state if `None` is provided.
fn reset(&mut self, io: &mut SyncIo, state: Option<SyncState>) {
self.new_blocks.reset(); self.new_blocks.reset();
let chain_info = io.chain().chain_info(); let chain_info = io.chain().chain_info();
for (_, ref mut p) in &mut self.peers { for (_, ref mut p) in &mut self.peers {
@@ -513,7 +514,7 @@ impl ChainSync {
} }
} }
} }
self.state = ChainSync::get_init_state(self.warp_sync, io.chain()); self.state = state.unwrap_or_else(|| ChainSync::get_init_state(self.warp_sync, io.chain()));
// Reactivate peers only if some progress has been made // Reactivate peers only if some progress has been made
// since the last sync round of if starting fresh. // since the last sync round of if starting fresh.
self.active_peers = self.peers.keys().cloned().collect(); self.active_peers = self.peers.keys().cloned().collect();
@@ -527,7 +528,7 @@ impl ChainSync {
io.snapshot_service().abort_restore(); io.snapshot_service().abort_restore();
} }
self.snapshot.clear(); self.snapshot.clear();
self.reset(io); self.reset(io, None);
self.continue_sync(io); self.continue_sync(io);
} }
@@ -692,7 +693,7 @@ impl ChainSync {
/// Called after all blocks have been downloaded /// Called after all blocks have been downloaded
fn complete_sync(&mut self, io: &mut SyncIo) { fn complete_sync(&mut self, io: &mut SyncIo) {
trace!(target: "sync", "Sync complete"); trace!(target: "sync", "Sync complete");
self.reset(io); self.reset(io, Some(SyncState::Idle));
} }
/// Enter waiting state /// Enter waiting state

View File

@@ -202,7 +202,7 @@ impl SyncPropagator {
let appended = packet.append_raw_checked(&transaction.drain(), 1, MAX_TRANSACTION_PACKET_SIZE); let appended = packet.append_raw_checked(&transaction.drain(), 1, MAX_TRANSACTION_PACKET_SIZE);
if !appended { if !appended {
// Maximal packet size reached just proceed with sending // Maximal packet size reached just proceed with sending
debug!("Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len()); debug!(target: "sync", "Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len());
to_send = to_send.into_iter().take(pushed).collect(); to_send = to_send.into_iter().take(pushed).collect();
break; break;
} }

View File

@@ -387,23 +387,6 @@ impl UnverifiedTransaction {
Ok(recover(&self.signature(), &self.unsigned.hash(self.chain_id()))?) Ok(recover(&self.signature(), &self.unsigned.hash(self.chain_id()))?)
} }
/// Do basic validation, checking for valid signature and minimum gas,
// TODO: consider use in block validation.
#[cfg(feature = "json-tests")]
pub fn validate(self, schedule: &Schedule, require_low: bool, allow_chain_id_of_one: bool, allow_empty_signature: bool)
-> Result<UnverifiedTransaction, error::Error>
{
let chain_id = if allow_chain_id_of_one { Some(1) } else { None };
self.verify_basic(require_low, chain_id, allow_empty_signature)?;
if !allow_empty_signature || !self.is_unsigned() {
self.recover_public()?;
}
if self.gas < U256::from(self.gas_required(&schedule)) {
return Err(error::Error::InvalidGasLimit(::unexpected::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
}
Ok(self)
}
/// Verify basic signature params. Does not attempt sender recovery. /// Verify basic signature params. Does not attempt sender recovery.
pub fn verify_basic(&self, check_low_s: bool, chain_id: Option<u64>, allow_empty_signature: bool) -> Result<(), error::Error> { pub fn verify_basic(&self, check_low_s: bool, chain_id: Option<u64>, allow_empty_signature: bool) -> Result<(), error::Error> {
if check_low_s && !(allow_empty_signature && self.is_unsigned()) { if check_low_s && !(allow_empty_signature && self.is_unsigned()) {

View File

@@ -51,18 +51,21 @@ pub enum MessageCallResult {
} }
/// Specifies how an address is calculated for a new contract. /// Specifies how an address is calculated for a new contract.
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum CreateContractAddress { pub enum CreateContractAddress {
/// Address is calculated from nonce and sender. Pre EIP-86 (Metropolis) /// Address is calculated from sender and nonce. pWASM `create` scheme.
FromSenderAndNonce, FromSenderAndNonce,
/// Address is calculated from code hash. Default since EIP-86 /// Address is calculated from sender, salt and code hash. pWASM `create2` scheme and EIP-1014 CREATE2 scheme.
FromCodeHash, FromSenderSaltAndCodeHash(H256),
/// Address is calculated from code hash and sender. Used by CREATE_P2SH instruction. /// Address is calculated from code hash and sender. Used by pwasm create ext.
FromSenderAndCodeHash, FromSenderAndCodeHash,
} }
/// Externalities interface for EVMs /// Externalities interface for EVMs
pub trait Ext { pub trait Ext {
/// Returns the storage value for a given key if reversion happens on the current transaction.
fn initial_storage_at(&self, key: &H256) -> Result<H256>;
/// Returns a value for given key. /// Returns a value for given key.
fn storage_at(&self, key: &H256) -> Result<H256>; fn storage_at(&self, key: &H256) -> Result<H256>;
@@ -106,10 +109,13 @@ pub trait Ext {
) -> MessageCallResult; ) -> MessageCallResult;
/// Returns code at given address /// Returns code at given address
fn extcode(&self, address: &Address) -> Result<Arc<Bytes>>; fn extcode(&self, address: &Address) -> Result<Option<Arc<Bytes>>>;
/// Returns code hash at given address
fn extcodehash(&self, address: &Address) -> Result<Option<H256>>;
/// Returns code size at given address /// Returns code size at given address
fn extcodesize(&self, address: &Address) -> Result<usize>; fn extcodesize(&self, address: &Address) -> Result<Option<usize>>;
/// Creates log entry with given topics and data /// Creates log entry with given topics and data
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>; fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>;
@@ -134,8 +140,11 @@ pub trait Ext {
/// then A depth is 0, B is 1, C is 2 and so on. /// then A depth is 0, B is 1, C is 2 and so on.
fn depth(&self) -> usize; fn depth(&self) -> usize;
/// Increments sstore refunds count by 1. /// Increments sstore refunds counter.
fn inc_sstore_clears(&mut self); fn add_sstore_refund(&mut self, value: U256);
/// Decrements sstore refunds counter.
fn sub_sstore_refund(&mut self, value: U256);
/// Decide if any more operations should be traced. Passthrough for the VM trace. /// Decide if any more operations should be traced. Passthrough for the VM trace.
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false } fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false }

View File

@@ -22,10 +22,12 @@ pub struct Schedule {
pub exceptional_failed_code_deposit: bool, pub exceptional_failed_code_deposit: bool,
/// Does it have a delegate cal /// Does it have a delegate cal
pub have_delegate_call: bool, pub have_delegate_call: bool,
/// Does it have a CREATE_P2SH instruction /// Does it have a CREATE2 instruction
pub have_create2: bool, pub have_create2: bool,
/// Does it have a REVERT instruction /// Does it have a REVERT instruction
pub have_revert: bool, pub have_revert: bool,
/// Does it have a EXTCODEHASH instruction
pub have_extcodehash: bool,
/// VM stack limit /// VM stack limit
pub stack_limit: usize, pub stack_limit: usize,
/// Max number of nested calls/creates /// Max number of nested calls/creates
@@ -92,6 +94,8 @@ pub struct Schedule {
pub extcodecopy_base_gas: usize, pub extcodecopy_base_gas: usize,
/// Price of BALANCE /// Price of BALANCE
pub balance_gas: usize, pub balance_gas: usize,
/// Price of EXTCODEHASH
pub extcodehash_gas: usize,
/// Price of SUICIDE /// Price of SUICIDE
pub suicide_gas: usize, pub suicide_gas: usize,
/// Amount of additional gas to pay when SUICIDE credits a non-existant account /// Amount of additional gas to pay when SUICIDE credits a non-existant account
@@ -113,8 +117,10 @@ pub struct Schedule {
pub have_bitwise_shifting: bool, pub have_bitwise_shifting: bool,
/// Kill basic accounts below this balance if touched. /// Kill basic accounts below this balance if touched.
pub kill_dust: CleanDustMode, pub kill_dust: CleanDustMode,
/// Enable EIP-86 rules /// Enable EIP-1283 rules
pub eip86: bool, pub eip1283: bool,
/// VM execution does not increase null signed address nonce if this field is true.
pub keep_unsigned_nonce: bool,
/// Wasm extra schedule settings, if wasm activated /// Wasm extra schedule settings, if wasm activated
pub wasm: Option<WasmCosts>, pub wasm: Option<WasmCosts>,
} }
@@ -145,6 +151,10 @@ pub struct WasmCosts {
pub opcodes_mul: u32, pub opcodes_mul: u32,
/// Cost of wasm opcode is calculated as TABLE_ENTRY_COST * `opcodes_mul` / `opcodes_div` /// Cost of wasm opcode is calculated as TABLE_ENTRY_COST * `opcodes_mul` / `opcodes_div`
pub opcodes_div: u32, pub opcodes_div: u32,
/// Whether create2 extern function is activated.
pub have_create2: bool,
/// Whether gasleft extern function is activated.
pub have_gasleft: bool,
} }
impl Default for WasmCosts { impl Default for WasmCosts {
@@ -162,6 +172,8 @@ impl Default for WasmCosts {
max_stack_height: 64*1024, max_stack_height: 64*1024,
opcodes_mul: 3, opcodes_mul: 3,
opcodes_div: 8, opcodes_div: 8,
have_create2: false,
have_gasleft: false,
} }
} }
} }
@@ -197,6 +209,7 @@ impl Schedule {
have_revert: false, have_revert: false,
have_return_data: false, have_return_data: false,
have_bitwise_shifting: false, have_bitwise_shifting: false,
have_extcodehash: false,
stack_limit: 1024, stack_limit: 1024,
max_depth: 1024, max_depth: 1024,
tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0],
@@ -229,6 +242,7 @@ impl Schedule {
copy_gas: 3, copy_gas: 3,
extcodesize_gas: 700, extcodesize_gas: 700,
extcodecopy_base_gas: 700, extcodecopy_base_gas: 700,
extcodehash_gas: 400,
balance_gas: 400, balance_gas: 400,
suicide_gas: 5000, suicide_gas: 5000,
suicide_to_new_account_cost: 25000, suicide_to_new_account_cost: 25000,
@@ -238,7 +252,8 @@ impl Schedule {
blockhash_gas: 20, blockhash_gas: 20,
have_static_call: false, have_static_call: false,
kill_dust: CleanDustMode::Off, kill_dust: CleanDustMode::Off,
eip86: false, eip1283: false,
keep_unsigned_nonce: false,
wasm: None, wasm: None,
} }
} }
@@ -268,6 +283,7 @@ impl Schedule {
have_revert: false, have_revert: false,
have_return_data: false, have_return_data: false,
have_bitwise_shifting: false, have_bitwise_shifting: false,
have_extcodehash: false,
stack_limit: 1024, stack_limit: 1024,
max_depth: 1024, max_depth: 1024,
tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0],
@@ -300,6 +316,7 @@ impl Schedule {
copy_gas: 3, copy_gas: 3,
extcodesize_gas: 20, extcodesize_gas: 20,
extcodecopy_base_gas: 20, extcodecopy_base_gas: 20,
extcodehash_gas: 400,
balance_gas: 20, balance_gas: 20,
suicide_gas: 0, suicide_gas: 0,
suicide_to_new_account_cost: 0, suicide_to_new_account_cost: 0,
@@ -309,7 +326,8 @@ impl Schedule {
blockhash_gas: 20, blockhash_gas: 20,
have_static_call: false, have_static_call: false,
kill_dust: CleanDustMode::Off, kill_dust: CleanDustMode::Off,
eip86: false, eip1283: false,
keep_unsigned_nonce: false,
wasm: None, wasm: None,
} }
} }

View File

@@ -24,6 +24,7 @@ use {
ReturnData, Ext, ContractCreateResult, MessageCallResult, ReturnData, Ext, ContractCreateResult, MessageCallResult,
CreateContractAddress, Result, GasLeft, CreateContractAddress, Result, GasLeft,
}; };
use hash::keccak;
pub struct FakeLogEntry { pub struct FakeLogEntry {
pub topics: Vec<H256>, pub topics: Vec<H256>,
@@ -38,6 +39,7 @@ pub enum FakeCallType {
#[derive(PartialEq, Eq, Hash, Debug)] #[derive(PartialEq, Eq, Hash, Debug)]
pub struct FakeCall { pub struct FakeCall {
pub call_type: FakeCallType, pub call_type: FakeCallType,
pub create_scheme: Option<CreateContractAddress>,
pub gas: U256, pub gas: U256,
pub sender_address: Option<Address>, pub sender_address: Option<Address>,
pub receive_address: Option<Address>, pub receive_address: Option<Address>,
@@ -54,7 +56,7 @@ pub struct FakeExt {
pub store: HashMap<H256, H256>, pub store: HashMap<H256, H256>,
pub suicides: HashSet<Address>, pub suicides: HashSet<Address>,
pub calls: HashSet<FakeCall>, pub calls: HashSet<FakeCall>,
pub sstore_clears: usize, pub sstore_clears: U256,
pub depth: usize, pub depth: usize,
pub blockhashes: HashMap<U256, H256>, pub blockhashes: HashMap<U256, H256>,
pub codes: HashMap<Address, Arc<Bytes>>, pub codes: HashMap<Address, Arc<Bytes>>,
@@ -103,6 +105,10 @@ impl FakeExt {
} }
impl Ext for FakeExt { impl Ext for FakeExt {
fn initial_storage_at(&self, _key: &H256) -> Result<H256> {
Ok(H256::new())
}
fn storage_at(&self, key: &H256) -> Result<H256> { fn storage_at(&self, key: &H256) -> Result<H256> {
Ok(self.store.get(key).unwrap_or(&H256::new()).clone()) Ok(self.store.get(key).unwrap_or(&H256::new()).clone())
} }
@@ -132,9 +138,10 @@ impl Ext for FakeExt {
self.blockhashes.get(number).unwrap_or(&H256::new()).clone() self.blockhashes.get(number).unwrap_or(&H256::new()).clone()
} }
fn create(&mut self, gas: &U256, value: &U256, code: &[u8], _address: CreateContractAddress) -> ContractCreateResult { fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult {
self.calls.insert(FakeCall { self.calls.insert(FakeCall {
call_type: FakeCallType::Create, call_type: FakeCallType::Create,
create_scheme: Some(address),
gas: *gas, gas: *gas,
sender_address: None, sender_address: None,
receive_address: None, receive_address: None,
@@ -158,6 +165,7 @@ impl Ext for FakeExt {
self.calls.insert(FakeCall { self.calls.insert(FakeCall {
call_type: FakeCallType::Call, call_type: FakeCallType::Call,
create_scheme: None,
gas: *gas, gas: *gas,
sender_address: Some(sender_address.clone()), sender_address: Some(sender_address.clone()),
receive_address: Some(receive_address.clone()), receive_address: Some(receive_address.clone()),
@@ -168,12 +176,16 @@ impl Ext for FakeExt {
MessageCallResult::Success(*gas, ReturnData::empty()) MessageCallResult::Success(*gas, ReturnData::empty())
} }
fn extcode(&self, address: &Address) -> Result<Arc<Bytes>> { fn extcode(&self, address: &Address) -> Result<Option<Arc<Bytes>>> {
Ok(self.codes.get(address).unwrap_or(&Arc::new(Bytes::new())).clone()) Ok(self.codes.get(address).cloned())
} }
fn extcodesize(&self, address: &Address) -> Result<usize> { fn extcodesize(&self, address: &Address) -> Result<Option<usize>> {
Ok(self.codes.get(address).map_or(0, |c| c.len())) Ok(self.codes.get(address).map(|c| c.len()))
}
fn extcodehash(&self, address: &Address) -> Result<Option<H256>> {
Ok(self.codes.get(address).map(|c| keccak(c.as_ref())))
} }
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()> { fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()> {
@@ -209,8 +221,12 @@ impl Ext for FakeExt {
self.is_static self.is_static
} }
fn inc_sstore_clears(&mut self) { fn add_sstore_refund(&mut self, value: U256) {
self.sstore_clears += 1; self.sstore_clears = self.sstore_clears + value;
}
fn sub_sstore_refund(&mut self, value: U256) {
self.sstore_clears = self.sstore_clears - value;
} }
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _gas: U256) -> bool { fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _gas: U256) -> bool {

View File

@@ -17,6 +17,7 @@
//! Env module glue for wasmi interpreter //! Env module glue for wasmi interpreter
use std::cell::RefCell; use std::cell::RefCell;
use vm::WasmCosts;
use wasmi::{ use wasmi::{
self, Signature, Error, FuncRef, FuncInstance, MemoryDescriptor, self, Signature, Error, FuncRef, FuncInstance, MemoryDescriptor,
MemoryRef, MemoryInstance, memory_units, MemoryRef, MemoryInstance, memory_units,
@@ -47,6 +48,8 @@ pub mod ids {
pub const SENDER_FUNC: usize = 190; pub const SENDER_FUNC: usize = 190;
pub const ORIGIN_FUNC: usize = 200; pub const ORIGIN_FUNC: usize = 200;
pub const ELOG_FUNC: usize = 210; pub const ELOG_FUNC: usize = 210;
pub const CREATE2_FUNC: usize = 220;
pub const GASLEFT_FUNC: usize = 230;
pub const PANIC_FUNC: usize = 1000; pub const PANIC_FUNC: usize = 1000;
pub const DEBUG_FUNC: usize = 1010; pub const DEBUG_FUNC: usize = 1010;
@@ -125,6 +128,11 @@ pub mod signatures {
Some(I32), Some(I32),
); );
pub const CREATE2: StaticSignature = StaticSignature(
&[I32, I32, I32, I32, I32],
Some(I32),
);
pub const SUICIDE: StaticSignature = StaticSignature( pub const SUICIDE: StaticSignature = StaticSignature(
&[I32], &[I32],
None, None,
@@ -150,6 +158,11 @@ pub mod signatures {
None, None,
); );
pub const GASLEFT: StaticSignature = StaticSignature(
&[],
Some(I64),
);
pub const GASLIMIT: StaticSignature = StaticSignature( pub const GASLIMIT: StaticSignature = StaticSignature(
&[I32], &[I32],
None, None,
@@ -195,18 +208,23 @@ fn host(signature: signatures::StaticSignature, idx: usize) -> FuncRef {
/// Maps all functions that runtime support to the corresponding contract import /// Maps all functions that runtime support to the corresponding contract import
/// entries. /// entries.
/// Also manages initial memory request from the runtime. /// Also manages initial memory request from the runtime.
#[derive(Default)]
pub struct ImportResolver { pub struct ImportResolver {
max_memory: u32, max_memory: u32,
memory: RefCell<Option<MemoryRef>>, memory: RefCell<Option<MemoryRef>>,
have_create2: bool,
have_gasleft: bool,
} }
impl ImportResolver { impl ImportResolver {
/// New import resolver with specifed maximum amount of inital memory (in wasm pages = 64kb) /// New import resolver with specifed maximum amount of inital memory (in wasm pages = 64kb)
pub fn with_limit(max_memory: u32) -> ImportResolver { pub fn with_limit(max_memory: u32, schedule: &WasmCosts) -> ImportResolver {
ImportResolver { ImportResolver {
max_memory: max_memory, max_memory: max_memory,
memory: RefCell::new(None), memory: RefCell::new(None),
have_create2: schedule.have_create2,
have_gasleft: schedule.have_gasleft,
} }
} }
@@ -263,6 +281,8 @@ impl wasmi::ModuleImportResolver for ImportResolver {
"sender" => host(signatures::SENDER, ids::SENDER_FUNC), "sender" => host(signatures::SENDER, ids::SENDER_FUNC),
"origin" => host(signatures::ORIGIN, ids::ORIGIN_FUNC), "origin" => host(signatures::ORIGIN, ids::ORIGIN_FUNC),
"elog" => host(signatures::ELOG, ids::ELOG_FUNC), "elog" => host(signatures::ELOG, ids::ELOG_FUNC),
"create2" if self.have_create2 => host(signatures::CREATE2, ids::CREATE2_FUNC),
"gasleft" if self.have_gasleft => host(signatures::GASLEFT, ids::GASLEFT_FUNC),
_ => { _ => {
return Err(wasmi::Error::Instantiation( return Err(wasmi::Error::Instantiation(
format!("Export {} not found", field_name), format!("Export {} not found", field_name),

View File

@@ -90,7 +90,7 @@ impl vm::Vm for WasmInterpreter {
let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error::Interpreter)?; let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error::Interpreter)?;
let instantiation_resolver = env::ImportResolver::with_limit(16); let instantiation_resolver = env::ImportResolver::with_limit(16, ext.schedule().wasm());
let module_instance = wasmi::ModuleInstance::new( let module_instance = wasmi::ModuleInstance::new(
&loaded_module, &loaded_module,

View File

@@ -284,7 +284,8 @@ impl<'a> Runtime<'a> {
self.ext.set_storage(key, val).map_err(|_| Error::StorageUpdateError)?; self.ext.set_storage(key, val).map_err(|_| Error::StorageUpdateError)?;
if former_val != H256::zero() && val == H256::zero() { if former_val != H256::zero() && val == H256::zero() {
self.ext.inc_sstore_clears(); let sstore_clears_schedule = U256::from(self.schedule().sstore_refund_gas);
self.ext.add_sstore_refund(sstore_clears_schedule);
} }
Ok(()) Ok(())
@@ -321,7 +322,7 @@ impl<'a> Runtime<'a> {
if self.gas_counter > self.gas_limit { return Err(Error::InvalidGasState); } if self.gas_counter > self.gas_limit { return Err(Error::InvalidGasState); }
Ok(self.gas_limit - self.gas_counter) Ok(self.gas_limit - self.gas_counter)
} }
/// General gas charging extern. /// General gas charging extern.
fn gas(&mut self, args: RuntimeArgs) -> Result<()> { fn gas(&mut self, args: RuntimeArgs) -> Result<()> {
let amount: u32 = args.nth_checked(0)?; let amount: u32 = args.nth_checked(0)?;
@@ -511,29 +512,7 @@ impl<'a> Runtime<'a> {
self.return_u256_ptr(args.nth_checked(0)?, val) self.return_u256_ptr(args.nth_checked(0)?, val)
} }
/// Creates a new contract fn do_create(&mut self, endowment: U256, code_ptr: u32, code_len: u32, result_ptr: u32, scheme: vm::CreateContractAddress) -> Result<RuntimeValue> {
///
/// Arguments:
/// * endowment - how much value (in Wei) transfer to the newly created contract
/// * code_ptr - pointer to the code data
/// * code_len - lenght of the code data
/// * result_ptr - pointer to write an address of the newly created contract
pub fn create(&mut self, args: RuntimeArgs) -> Result<RuntimeValue>
{
//
// method signature:
// fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
//
trace!(target: "wasm", "runtime: CREATE");
let endowment = self.u256_at(args.nth_checked(0)?)?;
trace!(target: "wasm", " val: {:?}", endowment);
let code_ptr: u32 = args.nth_checked(1)?;
trace!(target: "wasm", " code_ptr: {:?}", code_ptr);
let code_len: u32 = args.nth_checked(2)?;
trace!(target: "wasm", " code_len: {:?}", code_len);
let result_ptr: u32 = args.nth_checked(3)?;
trace!(target: "wasm", "result_ptr: {:?}", result_ptr);
let code = self.memory.get(code_ptr, code_len as usize)?; let code = self.memory.get(code_ptr, code_len as usize)?;
self.adjusted_charge(|schedule| schedule.create_gas as u64)?; self.adjusted_charge(|schedule| schedule.create_gas as u64)?;
@@ -543,7 +522,7 @@ impl<'a> Runtime<'a> {
* U256::from(self.ext.schedule().wasm().opcodes_mul) * U256::from(self.ext.schedule().wasm().opcodes_mul)
/ U256::from(self.ext.schedule().wasm().opcodes_div); / U256::from(self.ext.schedule().wasm().opcodes_div);
match self.ext.create(&gas_left, &endowment, &code, vm::CreateContractAddress::FromSenderAndCodeHash) { match self.ext.create(&gas_left, &endowment, &code, scheme) {
vm::ContractCreateResult::Created(address, gas_left) => { vm::ContractCreateResult::Created(address, gas_left) => {
self.memory.set(result_ptr, &*address)?; self.memory.set(result_ptr, &*address)?;
self.gas_counter = self.gas_limit - self.gas_counter = self.gas_limit -
@@ -571,6 +550,59 @@ impl<'a> Runtime<'a> {
} }
} }
/// Creates a new contract
///
/// Arguments:
/// * endowment - how much value (in Wei) transfer to the newly created contract
/// * code_ptr - pointer to the code data
/// * code_len - lenght of the code data
/// * result_ptr - pointer to write an address of the newly created contract
pub fn create(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> {
//
// method signature:
// fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
//
trace!(target: "wasm", "runtime: CREATE");
let endowment = self.u256_at(args.nth_checked(0)?)?;
trace!(target: "wasm", " val: {:?}", endowment);
let code_ptr: u32 = args.nth_checked(1)?;
trace!(target: "wasm", " code_ptr: {:?}", code_ptr);
let code_len: u32 = args.nth_checked(2)?;
trace!(target: "wasm", " code_len: {:?}", code_len);
let result_ptr: u32 = args.nth_checked(3)?;
trace!(target: "wasm", "result_ptr: {:?}", result_ptr);
self.do_create(endowment, code_ptr, code_len, result_ptr, vm::CreateContractAddress::FromSenderAndCodeHash)
}
/// Creates a new contract using FromSenderSaltAndCodeHash scheme
///
/// Arguments:
/// * endowment - how much value (in Wei) transfer to the newly created contract
/// * salt - salt to be used in contract creation address
/// * code_ptr - pointer to the code data
/// * code_len - lenght of the code data
/// * result_ptr - pointer to write an address of the newly created contract
pub fn create2(&mut self, args: RuntimeArgs) -> Result<RuntimeValue> {
//
// method signature:
// fn create2(endowment: *const u8, salt: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
//
trace!(target: "wasm", "runtime: CREATE2");
let endowment = self.u256_at(args.nth_checked(0)?)?;
trace!(target: "wasm", " val: {:?}", endowment);
let salt: H256 = self.u256_at(args.nth_checked(1)?)?.into();
trace!(target: "wasm", " salt: {:?}", salt);
let code_ptr: u32 = args.nth_checked(2)?;
trace!(target: "wasm", " code_ptr: {:?}", code_ptr);
let code_len: u32 = args.nth_checked(3)?;
trace!(target: "wasm", " code_len: {:?}", code_len);
let result_ptr: u32 = args.nth_checked(4)?;
trace!(target: "wasm", "result_ptr: {:?}", result_ptr);
self.do_create(endowment, code_ptr, code_len, result_ptr, vm::CreateContractAddress::FromSenderSaltAndCodeHash(salt))
}
fn debug(&mut self, args: RuntimeArgs) -> Result<()> fn debug(&mut self, args: RuntimeArgs) -> Result<()>
{ {
trace!(target: "wasm", "Contract debug message: {}", { trace!(target: "wasm", "Contract debug message: {}", {
@@ -629,6 +661,15 @@ impl<'a> Runtime<'a> {
self.return_u256_ptr(args.nth_checked(0)?, difficulty) self.return_u256_ptr(args.nth_checked(0)?, difficulty)
} }
/// Signature: `fn gasleft() -> i64`
pub fn gasleft(&mut self) -> Result<RuntimeValue> {
Ok(RuntimeValue::from(
self.gas_left()? * self.ext.schedule().wasm().opcodes_mul as u64
/ self.ext.schedule().wasm().opcodes_div as u64
)
)
}
/// Signature: `fn gaslimit(dest: *mut u8)` /// Signature: `fn gaslimit(dest: *mut u8)`
pub fn gaslimit(&mut self, args: RuntimeArgs) -> Result<()> { pub fn gaslimit(&mut self, args: RuntimeArgs) -> Result<()> {
let gas_limit = self.ext.env_info().gas_limit; let gas_limit = self.ext.env_info().gas_limit;
@@ -744,6 +785,8 @@ mod ext_impl {
SENDER_FUNC => void!(self.sender(args)), SENDER_FUNC => void!(self.sender(args)),
ORIGIN_FUNC => void!(self.origin(args)), ORIGIN_FUNC => void!(self.origin(args)),
ELOG_FUNC => void!(self.elog(args)), ELOG_FUNC => void!(self.elog(args)),
CREATE2_FUNC => some!(self.create2(args)),
GASLEFT_FUNC => some!(self.gasleft()),
_ => panic!("env module doesn't provide function at index {}", index), _ => panic!("env module doesn't provide function at index {}", index),
} }
} }

View File

@@ -20,7 +20,7 @@ use byteorder::{LittleEndian, ByteOrder};
use ethereum_types::{H256, U256, Address}; use ethereum_types::{H256, U256, Address};
use super::WasmInterpreter; use super::WasmInterpreter;
use vm::{self, Vm, GasLeft, ActionParams, ActionValue}; use vm::{self, Vm, GasLeft, ActionParams, ActionValue, CreateContractAddress};
use vm::tests::{FakeCall, FakeExt, FakeCallType}; use vm::tests::{FakeCall, FakeExt, FakeCallType};
macro_rules! load_sample { macro_rules! load_sample {
@@ -138,7 +138,7 @@ fn logger() {
U256::from(1_000_000_000), U256::from(1_000_000_000),
"Logger sets 0x04 key to the trasferred value" "Logger sets 0x04 key to the trasferred value"
); );
assert_eq!(gas_left, U256::from(16_181)); assert_eq!(gas_left, U256::from(17_716));
} }
// This test checks if the contract can allocate memory and pass pointer to the result stream properly. // This test checks if the contract can allocate memory and pass pointer to the result stream properly.
@@ -173,7 +173,7 @@ fn identity() {
sender, sender,
"Idenity test contract does not return the sender passed" "Idenity test contract does not return the sender passed"
); );
assert_eq!(gas_left, U256::from(96_883)); assert_eq!(gas_left, U256::from(98_419));
} }
// Dispersion test sends byte array and expect the contract to 'disperse' the original elements with // Dispersion test sends byte array and expect the contract to 'disperse' the original elements with
@@ -207,7 +207,7 @@ fn dispersion() {
result, result,
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0] vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
); );
assert_eq!(gas_left, U256::from(92_371)); assert_eq!(gas_left, U256::from(92_377));
} }
#[test] #[test]
@@ -267,7 +267,7 @@ fn suicide() {
}; };
assert!(ext.suicides.contains(&refund)); assert!(ext.suicides.contains(&refund));
assert_eq!(gas_left, U256::from(93_348)); assert_eq!(gas_left, U256::from(93_346));
} }
#[test] #[test]
@@ -281,14 +281,19 @@ fn create() {
params.value = ActionValue::transfer(1_000_000_000); params.value = ActionValue::transfer(1_000_000_000);
let mut ext = FakeExt::new().with_wasm(); let mut ext = FakeExt::new().with_wasm();
ext.schedule.wasm.as_mut().unwrap().have_create2 = true;
let gas_left = { let gas_left = {
let mut interpreter = wasm_interpreter(); let mut interpreter = wasm_interpreter();
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors"); let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
match result { match result {
GasLeft::Known(gas) => gas, GasLeft::Known(_) => {
GasLeft::NeedsReturn { .. } => { panic!("Create contract always return 40 bytes of the creation address, or in the case where it fails, return 40 bytes of zero.");
panic!("Create contract should not return anthing because ext always fails on creation"); },
GasLeft::NeedsReturn { gas_left, data, apply_state } => {
assert!(apply_state);
assert_eq!(data.as_ref(), [0u8; 40].as_ref()); // FakeExt never succeeds in create.
gas_left
}, },
} }
}; };
@@ -297,15 +302,28 @@ fn create() {
assert!(ext.calls.contains( assert!(ext.calls.contains(
&FakeCall { &FakeCall {
call_type: FakeCallType::Create, call_type: FakeCallType::Create,
gas: U256::from(59_269), create_scheme: Some(CreateContractAddress::FromSenderAndCodeHash),
gas: U256::from(49_674),
sender_address: None, sender_address: None,
receive_address: None, receive_address: None,
value: Some(1_000_000_000.into()), value: Some((1_000_000_000 / 2).into()),
data: vec![0u8, 2, 4, 8, 16, 32, 64, 128], data: vec![0u8, 2, 4, 8, 16, 32, 64, 128],
code_address: None, code_address: None,
} }
)); ));
assert_eq!(gas_left, U256::from(59_212)); assert!(ext.calls.contains(
&FakeCall {
call_type: FakeCallType::Create,
create_scheme: Some(CreateContractAddress::FromSenderSaltAndCodeHash(H256::from([5u8].as_ref()))),
gas: U256::from(6039),
sender_address: None,
receive_address: None,
value: Some((1_000_000_000 / 2).into()),
data: vec![0u8, 2, 4, 8, 16, 32, 64, 128],
code_address: None,
}
));
assert_eq!(gas_left, U256::from(5974));
} }
#[test] #[test]
@@ -340,6 +358,7 @@ fn call_msg() {
assert!(ext.calls.contains( assert!(ext.calls.contains(
&FakeCall { &FakeCall {
call_type: FakeCallType::Call, call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(33_000), gas: U256::from(33_000),
sender_address: Some(receiver), sender_address: Some(receiver),
receive_address: Some(Address::from([99, 88, 77, 66, 55, 44, 33, 22, 11, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0])), receive_address: Some(Address::from([99, 88, 77, 66, 55, 44, 33, 22, 11, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0])),
@@ -352,6 +371,54 @@ fn call_msg() {
assert_eq!(gas_left, U256::from(91_672)); assert_eq!(gas_left, U256::from(91_672));
} }
// The same as `call_msg`, but send a `pwasm_ethereum::gasleft`
// value as `gas` argument to the inner pwasm_ethereum::call
#[test]
fn call_msg_gasleft() {
::ethcore_logger::init_log();
let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
let receiver: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
let contract_address: Address = "0d461d4174b4ae35775c4a342f1e5e1e4e6c4db5".parse().unwrap();
let mut params = ActionParams::default();
params.sender = sender.clone();
params.address = receiver.clone();
params.code_address = contract_address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(load_sample!("call_gasleft.wasm")));
params.data = Some(Vec::new());
let mut ext = FakeExt::new().with_wasm();
ext.schedule.wasm.as_mut().unwrap().have_gasleft = true;
ext.balances.insert(receiver.clone(), U256::from(10000000000u64));
let gas_left = {
let mut interpreter = wasm_interpreter();
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
match result {
GasLeft::Known(gas_left) => gas_left,
GasLeft::NeedsReturn { .. } => { panic!("Call test should not return payload"); },
}
};
trace!(target: "wasm", "fake_calls: {:?}", &ext.calls);
assert!(ext.calls.contains(
&FakeCall {
call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(91_165),
sender_address: Some(receiver),
receive_address: Some(Address::from([99, 88, 77, 66, 55, 44, 33, 22, 11, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0])),
value: Some(1000000000.into()),
data: vec![129u8, 123, 113, 107, 101, 97],
code_address: Some(Address::from([99, 88, 77, 66, 55, 44, 33, 22, 11, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0])),
}
));
assert_eq!(gas_left, U256::from(91_671));
}
#[test] #[test]
fn call_code() { fn call_code() {
::ethcore_logger::init_log(); ::ethcore_logger::init_log();
@@ -382,6 +449,7 @@ fn call_code() {
assert!(ext.calls.contains( assert!(ext.calls.contains(
&FakeCall { &FakeCall {
call_type: FakeCallType::Call, call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(20_000), gas: U256::from(20_000),
sender_address: Some(sender), sender_address: Some(sender),
receive_address: Some(receiver), receive_address: Some(receiver),
@@ -394,7 +462,7 @@ fn call_code() {
// siphash result // siphash result
let res = LittleEndian::read_u32(&result[..]); let res = LittleEndian::read_u32(&result[..]);
assert_eq!(res, 4198595614); assert_eq!(res, 4198595614);
assert_eq!(gas_left, U256::from(90_038)); assert_eq!(gas_left, U256::from(90_037));
} }
#[test] #[test]
@@ -429,6 +497,7 @@ fn call_static() {
assert!(ext.calls.contains( assert!(ext.calls.contains(
&FakeCall { &FakeCall {
call_type: FakeCallType::Call, call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(20_000), gas: U256::from(20_000),
sender_address: Some(receiver), sender_address: Some(receiver),
receive_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()), receive_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()),
@@ -442,7 +511,7 @@ fn call_static() {
let res = LittleEndian::read_u32(&result[..]); let res = LittleEndian::read_u32(&result[..]);
assert_eq!(res, 317632590); assert_eq!(res, 317632590);
assert_eq!(gas_left, U256::from(90_043)); assert_eq!(gas_left, U256::from(90_042));
} }
// Realloc test // Realloc test
@@ -465,7 +534,7 @@ fn realloc() {
} }
}; };
assert_eq!(result, vec![0u8; 2]); assert_eq!(result, vec![0u8; 2]);
assert_eq!(gas_left, U256::from(92_842)); assert_eq!(gas_left, U256::from(92_848));
} }
#[test] #[test]
@@ -487,7 +556,7 @@ fn alloc() {
} }
}; };
assert_eq!(result, vec![5u8; 1024*400]); assert_eq!(result, vec![5u8; 1024*400]);
assert_eq!(gas_left, U256::from(6_893_883)); assert_eq!(gas_left, U256::from(6_893_881));
} }
// Tests that contract's ability to read from a storage // Tests that contract's ability to read from a storage
@@ -515,7 +584,7 @@ fn storage_read() {
}; };
assert_eq!(Address::from(&result[12..32]), address); assert_eq!(Address::from(&result[12..32]), address);
assert_eq!(gas_left, U256::from(96_833)); assert_eq!(gas_left, U256::from(98_369));
} }
// Tests keccak calculation // Tests keccak calculation
@@ -541,7 +610,7 @@ fn keccak() {
}; };
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87")); assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
assert_eq!(gas_left, U256::from(84_134)); assert_eq!(gas_left, U256::from(85_949));
} }
// math_* tests check the ability of wasm contract to perform big integer operations // math_* tests check the ability of wasm contract to perform big integer operations
@@ -570,7 +639,7 @@ fn math_add() {
U256::from_dec_str("1888888888888888888888888888887").unwrap(), U256::from_dec_str("1888888888888888888888888888887").unwrap(),
(&result[..]).into() (&result[..]).into()
); );
assert_eq!(gas_left, U256::from(92_086)); assert_eq!(gas_left, U256::from(92_072));
} }
// multiplication // multiplication
@@ -592,7 +661,7 @@ fn math_mul() {
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(), U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
(&result[..]).into() (&result[..]).into()
); );
assert_eq!(gas_left, U256::from(91_414)); assert_eq!(gas_left, U256::from(91_400));
} }
// subtraction // subtraction
@@ -614,7 +683,7 @@ fn math_sub() {
U256::from_dec_str("111111111111111111111111111111").unwrap(), U256::from_dec_str("111111111111111111111111111111").unwrap(),
(&result[..]).into() (&result[..]).into()
); );
assert_eq!(gas_left, U256::from(92_086)); assert_eq!(gas_left, U256::from(92_072));
} }
// subtraction with overflow // subtraction with overflow
@@ -656,7 +725,7 @@ fn math_div() {
U256::from_dec_str("1125000").unwrap(), U256::from_dec_str("1125000").unwrap(),
(&result[..]).into() (&result[..]).into()
); );
assert_eq!(gas_left, U256::from(87_376)); assert_eq!(gas_left, U256::from(85_700));
} }
#[test] #[test]
@@ -684,7 +753,7 @@ fn storage_metering() {
}; };
// 0 -> not 0 // 0 -> not 0
assert_eq!(gas_left, U256::from(72_399)); assert_eq!(gas_left, U256::from(72_164));
// #2 // #2
@@ -703,7 +772,7 @@ fn storage_metering() {
}; };
// not 0 -> not 0 // not 0 -> not 0
assert_eq!(gas_left, U256::from(87_399)); assert_eq!(gas_left, U256::from(87_164));
} }
// This test checks the ability of wasm contract to invoke // This test checks the ability of wasm contract to invoke
@@ -791,7 +860,48 @@ fn externs() {
"Gas limit requested and returned does not match" "Gas limit requested and returned does not match"
); );
assert_eq!(gas_left, U256::from(90_435)); assert_eq!(gas_left, U256::from(90_428));
}
// This test checks the ability of wasm contract to invoke gasleft
#[test]
fn gasleft() {
::ethcore_logger::init_log();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(load_sample!("gasleft.wasm")));
let mut ext = FakeExt::new().with_wasm();
ext.schedule.wasm.as_mut().unwrap().have_gasleft = true;
let mut interpreter = wasm_interpreter();
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
match result {
GasLeft::Known(_) => {},
GasLeft::NeedsReturn { gas_left, data, .. } => {
let gas = LittleEndian::read_u64(data.as_ref());
assert_eq!(gas, 93_423);
assert_eq!(gas_left, U256::from(93_349));
},
}
}
// This test should fail because
// ext.schedule.wasm.as_mut().unwrap().have_gasleft = false;
#[test]
fn gasleft_fail() {
::ethcore_logger::init_log();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(load_sample!("gasleft.wasm")));
let mut ext = FakeExt::new().with_wasm();
let mut interpreter = wasm_interpreter();
match interpreter.exec(params, &mut ext) {
Err(_) => {},
Ok(_) => panic!("interpreter.exec should return Err if ext.schedule.wasm.have_gasleft = false")
}
} }
#[test] #[test]
@@ -817,7 +927,7 @@ fn embedded_keccak() {
}; };
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87")); assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
assert_eq!(gas_left, U256::from(84_134)); assert_eq!(gas_left, U256::from(85_949));
} }
/// This test checks the correctness of log extern /// This test checks the correctness of log extern
@@ -852,7 +962,7 @@ fn events() {
assert_eq!(&log_entry.data, b"gnihtemos"); assert_eq!(&log_entry.data, b"gnihtemos");
assert_eq!(&result, b"gnihtemos"); assert_eq!(&result, b"gnihtemos");
assert_eq!(gas_left, U256::from(81_351)); assert_eq!(gas_left, U256::from(83_161));
} }
#[test] #[test]

View File

@@ -84,7 +84,7 @@ pub fn run_action<T: Informant>(
pub fn run_transaction<T: Informant>( pub fn run_transaction<T: Informant>(
name: &str, name: &str,
idx: usize, idx: usize,
spec: &ethjson::state::test::ForkSpec, spec: &ethjson::spec::ForkSpec,
pre_state: &pod_state::PodState, pre_state: &pod_state::PodState,
post_root: H256, post_root: H256,
env_info: &client::EnvInfo, env_info: &client::EnvInfo,

View File

@@ -21,8 +21,7 @@ use hash::H256;
use blockchain::state::State; use blockchain::state::State;
use blockchain::header::Header; use blockchain::header::Header;
use blockchain::block::Block; use blockchain::block::Block;
use state::test::ForkSpec; use spec::{ForkSpec, Genesis, Seal, Ethereum};
use spec::{Genesis, Seal, Ethereum};
/// Blockchain deserialization. /// Blockchain deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]

View File

@@ -116,6 +116,18 @@ pub struct EthashParams {
#[serde(rename="eip649Reward")] #[serde(rename="eip649Reward")]
pub eip649_reward: Option<Uint>, pub eip649_reward: Option<Uint>,
/// EIP-1234 transition block.
#[serde(rename="eip1234Transition")]
pub eip1234_transition: Option<Uint>,
/// EIP-1234 bomb delay.
#[serde(rename="eip1234Delay")]
pub eip1234_delay: Option<Uint>,
/// EIP-1234 base reward.
#[serde(rename="eip1234Reward")]
pub eip1234_reward: Option<Uint>,
/// EXPIP-2 block height /// EXPIP-2 block height
#[serde(rename="expip2Transition")] #[serde(rename="expip2Transition")]
pub expip2_transition: Option<Uint>, pub expip2_transition: Option<Uint>,
@@ -231,6 +243,9 @@ mod tests {
eip649_transition: None, eip649_transition: None,
eip649_delay: None, eip649_delay: None,
eip649_reward: None, eip649_reward: None,
eip1234_transition: None,
eip1234_delay: None,
eip1234_reward: None,
expip2_transition: None, expip2_transition: None,
expip2_duration_limit: None, expip2_duration_limit: None,
} }
@@ -275,6 +290,9 @@ mod tests {
eip649_transition: None, eip649_transition: None,
eip649_delay: None, eip649_delay: None,
eip649_reward: None, eip649_reward: None,
eip1234_transition: None,
eip1234_delay: None,
eip1234_reward: None,
expip2_transition: None, expip2_transition: None,
expip2_duration_limit: None, expip2_duration_limit: None,
} }

View File

@@ -36,7 +36,7 @@ pub use self::account::Account;
pub use self::builtin::{Builtin, Pricing, Linear}; pub use self::builtin::{Builtin, Pricing, Linear};
pub use self::genesis::Genesis; pub use self::genesis::Genesis;
pub use self::params::Params; pub use self::params::Params;
pub use self::spec::Spec; pub use self::spec::{Spec, ForkSpec};
pub use self::seal::{Seal, Ethereum, AuthorityRoundSeal, TendermintSeal}; pub use self::seal::{Seal, Ethereum, AuthorityRoundSeal, TendermintSeal};
pub use self::engine::Engine; pub use self::engine::Engine;
pub use self::state::State; pub use self::state::State;

View File

@@ -79,9 +79,6 @@ pub struct Params {
#[serde(rename="validateReceiptsTransition")] #[serde(rename="validateReceiptsTransition")]
pub validate_receipts_transition: Option<Uint>, pub validate_receipts_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
#[serde(rename="eip86Transition")]
pub eip86_transition: Option<Uint>,
/// See `CommonParams` docs.
#[serde(rename="eip140Transition")] #[serde(rename="eip140Transition")]
pub eip140_transition: Option<Uint>, pub eip140_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
@@ -109,6 +106,14 @@ pub struct Params {
#[serde(rename="eip658Transition")] #[serde(rename="eip658Transition")]
pub eip658_transition: Option<Uint>, pub eip658_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
#[serde(rename="eip1052Transition")]
pub eip1052_transition: Option<Uint>,
/// See `CommonParams` docs.
#[serde(rename="eip1283Transition")]
pub eip1283_transition: Option<Uint>,
#[serde(rename="eip1014Transition")]
pub eip1014_transition: Option<Uint>,
/// See `CommonParams` docs.
#[serde(rename="dustProtectionTransition")] #[serde(rename="dustProtectionTransition")]
pub dust_protection_transition: Option<Uint>, pub dust_protection_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
@@ -143,6 +148,12 @@ pub struct Params {
/// Wasm activation block height, if not activated from start /// Wasm activation block height, if not activated from start
#[serde(rename="wasmActivationTransition")] #[serde(rename="wasmActivationTransition")]
pub wasm_activation_transition: Option<Uint>, pub wasm_activation_transition: Option<Uint>,
/// KIP4 activiation block height.
#[serde(rename="kip4Transition")]
pub kip4_transition: Option<Uint>,
/// KIP6 activiation block height.
#[serde(rename="kip6Transition")]
pub kip6_transition: Option<Uint>,
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -21,6 +21,21 @@ use serde_json;
use serde_json::Error; use serde_json::Error;
use spec::{Params, Genesis, Engine, State, HardcodedSync}; use spec::{Params, Genesis, Engine, State, HardcodedSync};
/// Fork spec definition
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)]
pub enum ForkSpec {
EIP150,
EIP158,
Frontier,
Homestead,
Byzantium,
Constantinople,
EIP158ToByzantiumAt5,
FrontierToHomesteadAt5,
HomesteadToDaoAt5,
HomesteadToEIP150At5,
}
/// Spec deserialization. /// Spec deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
pub struct Spec { pub struct Spec {

View File

@@ -21,6 +21,7 @@ use std::collections::BTreeMap;
use uint::Uint; use uint::Uint;
use bytes::Bytes; use bytes::Bytes;
use hash::{Address, H256}; use hash::{Address, H256};
use spec::ForkSpec;
use state::{Env, AccountState, Transaction}; use state::{Env, AccountState, Transaction};
use maybe::MaybeEmpty; use maybe::MaybeEmpty;
use serde_json::{self, Error}; use serde_json::{self, Error};
@@ -97,21 +98,6 @@ impl MultiTransaction {
} }
} }
/// State test transaction deserialization.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)]
pub enum ForkSpec {
EIP150,
EIP158,
Frontier,
Homestead,
Byzantium,
Constantinople,
EIP158ToByzantiumAt5,
FrontierToHomesteadAt5,
HomesteadToDaoAt5,
HomesteadToEIP150At5,
}
/// State test indexes deserialization. /// State test indexes deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
pub struct PostStateIndexes { pub struct PostStateIndexes {

View File

@@ -45,6 +45,7 @@ pub struct DifficultyTestCase {
#[serde(rename="currentBlockNumber")] #[serde(rename="currentBlockNumber")]
pub current_block_number: Uint, pub current_block_number: Uint,
} }
/// Blockchain test deserializer. /// Blockchain test deserializer.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
pub struct DifficultyTest(BTreeMap<String, DifficultyTestCase>); pub struct DifficultyTest(BTreeMap<String, DifficultyTestCase>);
@@ -64,3 +65,59 @@ impl DifficultyTest {
serde_json::from_reader(reader) serde_json::from_reader(reader)
} }
} }
/// Test to skip (only if issue ongoing)
#[derive(Debug, PartialEq, Deserialize)]
pub struct SkipStates {
/// Block tests
pub block: Vec<BlockSkipStates>,
/// State tests
pub state: Vec<StateSkipStates>,
}
/// Block test to skip.
#[derive(Debug, PartialEq, Deserialize)]
pub struct BlockSkipStates {
/// Issue reference.
pub reference: String,
/// Test failing name.
pub failing: String,
/// Items failing for the test.
pub subtests: Vec<String>,
}
/// State test to skip.
#[derive(Debug, PartialEq, Deserialize)]
pub struct StateSkipStates {
/// Issue reference.
pub reference: String,
/// Test failing name.
pub failing: String,
/// Items failing for the test.
pub subtests: BTreeMap<String, StateSkipSubStates>
}
/// State subtest to skip.
#[derive(Debug, PartialEq, Deserialize)]
pub struct StateSkipSubStates {
/// State test number of this item. Or '*' for all state.
pub subnumbers: Vec<String>,
/// Chain for this items.
pub chain: String,
}
impl SkipStates {
/// Loads skip states from json.
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
serde_json::from_reader(reader)
}
/// Empty skip states.
pub fn empty() -> Self {
SkipStates {
block: Vec::new(),
state: Vec::new(),
}
}
}

View File

@@ -23,7 +23,7 @@ use serde_json::Error;
use transaction::TransactionTest; use transaction::TransactionTest;
/// TransactionTest test deserializer. /// TransactionTest test deserializer.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Test(BTreeMap<String, TransactionTest>); pub struct Test(BTreeMap<String, TransactionTest>);
impl IntoIterator for Test { impl IntoIterator for Test {

View File

@@ -16,23 +16,29 @@
//! Transaction test deserialization. //! Transaction test deserialization.
use uint::Uint; use std::collections::BTreeMap;
use bytes::Bytes; use bytes::Bytes;
use hash::Address; use hash::Address;
use transaction::Transaction; use hash::H256;
use spec::ForkSpec;
/// Transaction test deserialization. /// Transaction test deserialization.
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, Deserialize)]
pub struct TransactionTest { pub struct TransactionTest {
/// Block number.
#[serde(rename="blocknumber")]
pub block_number: Option<Uint>,
/// Transaction rlp.
pub rlp: Bytes, pub rlp: Bytes,
pub _info: ::serde::de::IgnoredAny,
#[serde(flatten)]
pub post_state: BTreeMap<ForkSpec, PostState>,
}
/// TransactionTest post state.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PostState {
/// Transaction sender. /// Transaction sender.
pub sender: Option<Address>, pub sender: Option<Address>,
/// Transaction /// Transaction hash.
pub transaction: Option<Transaction>, pub hash: Option<H256>,
} }
#[cfg(test)] #[cfg(test)]
@@ -43,21 +49,34 @@ mod tests {
#[test] #[test]
fn transaction_deserialization() { fn transaction_deserialization() {
let s = r#"{ let s = r#"{
"blocknumber" : "0", "Byzantium" : {
"rlp" : "0xf83f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870b801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a3664935301", "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5",
"sender" : "e115cf6bb5656786569dd273705242ca72d84bc0", "sender" : "2ea991808ba979ba103147edfd72304ebd95c028"
"transaction" : { },
"data" : "", "Constantinople" : {
"gasLimit" : "0x5208", "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5",
"gasPrice" : "0x01", "sender" : "2ea991808ba979ba103147edfd72304ebd95c028"
"nonce" : "0x00", },
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", "EIP150" : {
"s" : "0x01", },
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "EIP158" : {
"v" : "0x1b", "hash" : "4782cb5edcaeda1f0aef204b161214f124cefade9e146245183abbb9ca01bca5",
"value" : "0x0b" "sender" : "2ea991808ba979ba103147edfd72304ebd95c028"
} },
"Frontier" : {
},
"Homestead" : {
},
"_info" : {
"comment" : "",
"filledwith" : "cpp-1.3.0+commit.1829957d.Linux.g++",
"lllcversion" : "Version: 0.4.18-develop.2017.10.11+commit.81f9f86c.Linux.g++",
"source" : "src/TransactionTestsFiller/ttVValue/V_equals37Filler.json",
"sourceHash" : "89ef69312d4c0b4e3742da501263d23d2a64f180258ac93940997ac6a17b9b19"
},
"rlp" : "0xf865808698852840a46f82d6d894095e7baea6a6c7c4c2dfeb977efac326af552d87808025a098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa01887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3"
}"#; }"#;
let _deserialized: TransactionTest = serde_json::from_str(s).unwrap(); let _deserialized: TransactionTest = serde_json::from_str(s).unwrap();
// TODO: validate all fields // TODO: validate all fields
} }

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
include(ExternalProject) include(ExternalProject)
include_directories("${CMAKE_SOURCE_DIR}/../parity-clib") include_directories("${CMAKE_SOURCE_DIR}/../../parity-clib")
add_executable(parity-example main.cpp) add_executable(parity-example main.cpp)
@@ -11,9 +11,9 @@ ExternalProject_Add(
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
COMMAND cargo build -p parity-clib # Note: use --release in a real project COMMAND cargo build -p parity-clib # Note: use --release in a real project
BINARY_DIR "${CMAKE_SOURCE_DIR}/../target" BINARY_DIR "${CMAKE_SOURCE_DIR}/../../target"
INSTALL_COMMAND "" INSTALL_COMMAND ""
LOG_BUILD ON) LOG_BUILD ON)
add_dependencies(parity-example libparity) add_dependencies(parity-example libparity)
target_link_libraries(parity-example "${CMAKE_SOURCE_DIR}/../target/debug/libparity.so") target_link_libraries(parity-example "${CMAKE_SOURCE_DIR}/../../target/debug/libparity.so")

View File

@@ -700,11 +700,11 @@ usage! {
"--price-update-period=[T]", "--price-update-period=[T]",
"T will be allowed to pass between each gas price update. T may be daily, hourly, a number of seconds, or a time string of the form \"2 days\", \"30 minutes\" etc..", "T will be allowed to pass between each gas price update. T may be daily, hourly, a number of seconds, or a time string of the form \"2 days\", \"30 minutes\" etc..",
ARG arg_gas_floor_target: (String) = "4700000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(), ARG arg_gas_floor_target: (String) = "8000000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(),
"--gas-floor-target=[GAS]", "--gas-floor-target=[GAS]",
"Amount of gas per block to target when sealing a new block.", "Amount of gas per block to target when sealing a new block.",
ARG arg_gas_cap: (String) = "6283184", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(), ARG arg_gas_cap: (String) = "10000000", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(),
"--gas-cap=[GAS]", "--gas-cap=[GAS]",
"A cap on how large we will raise the gas limit per block due to transaction volume.", "A cap on how large we will raise the gas limit per block due to transaction volume.",
@@ -1712,7 +1712,7 @@ mod tests {
arg_reseal_max_period: 60000u64, arg_reseal_max_period: 60000u64,
flag_reseal_on_uncle: false, flag_reseal_on_uncle: false,
arg_work_queue_size: 20usize, arg_work_queue_size: 20usize,
arg_tx_gas_limit: Some("6283184".into()), arg_tx_gas_limit: Some("10000000".into()),
arg_tx_time_limit: Some(100u64), arg_tx_time_limit: Some(100u64),
arg_relay_set: "cheap".into(), arg_relay_set: "cheap".into(),
arg_min_gas_price: Some(0u64), arg_min_gas_price: Some(0u64),
@@ -1721,8 +1721,8 @@ mod tests {
arg_poll_lifetime: 60u32, arg_poll_lifetime: 60u32,
arg_usd_per_eth: "auto".into(), arg_usd_per_eth: "auto".into(),
arg_price_update_period: "hourly".into(), arg_price_update_period: "hourly".into(),
arg_gas_floor_target: "4700000".into(), arg_gas_floor_target: "8000000".into(),
arg_gas_cap: "6283184".into(), arg_gas_cap: "10000000".into(),
arg_extra_data: Some("Parity".into()), arg_extra_data: Some("Parity".into()),
flag_tx_queue_no_unfamiliar_locals: false, flag_tx_queue_no_unfamiliar_locals: false,
arg_tx_queue_size: 8192usize, arg_tx_queue_size: 8192usize,

View File

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

View File

@@ -286,7 +286,7 @@ impl Default for MinerExtras {
author: Default::default(), author: Default::default(),
engine_signer: Default::default(), engine_signer: Default::default(),
extra_data: version_data(), extra_data: version_data(),
gas_range_target: (4_700_000.into(), 6_283_184.into()), gas_range_target: (8_000_000.into(), 10_000_000.into()),
work_notify: Default::default(), work_notify: Default::default(),
} }
} }

View File

@@ -185,7 +185,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?; cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
//print out running parity environment //print out running parity environment
print_running_environment(&spec.name, &cmd.dirs, &db_dirs); print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
info!("Running in experimental {} mode.", Colour::Blue.bold().paint("Light Client")); info!("Running in experimental {} mode.", Colour::Blue.bold().paint("Light Client"));
@@ -402,7 +402,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
} }
//print out running parity environment //print out running parity environment
print_running_environment(&spec.name, &cmd.dirs, &db_dirs); print_running_environment(&spec.data_dir, &cmd.dirs, &db_dirs);
// display info about used pruning algorithm // display info about used pruning algorithm
info!("State DB configuration: {}{}{}", info!("State DB configuration: {}{}{}",
@@ -926,9 +926,9 @@ fn daemonize(_pid_file: String) -> Result<(), String> {
Err("daemon is no supported on windows".into()) Err("daemon is no supported on windows".into())
} }
fn print_running_environment(spec_name: &String, dirs: &Directories, db_dirs: &DatabaseDirectories) { fn print_running_environment(data_dir: &str, dirs: &Directories, db_dirs: &DatabaseDirectories) {
info!("Starting {}", Colour::White.bold().paint(version())); info!("Starting {}", Colour::White.bold().paint(version()));
info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(spec_name).to_string_lossy().into_owned())); info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(data_dir).to_string_lossy().into_owned()));
info!("DB path {}", Colour::White.bold().paint(db_dirs.db_root_path().to_string_lossy().into_owned())); info!("DB path {}", Colour::White.bold().paint(db_dirs.db_root_path().to_string_lossy().into_owned()));
} }

View File

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

View File

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

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