v2.5.8-stable (#11041)

* add more tx tests (#11038)
* Fix parallel transactions race-condition (#10995)
* Add blake2_f precompile (#11017)
* [trace] introduce trace failed to Ext (#11019)
* Edit publish-onchain.sh to use https (#11016)
* Fix deadlock in network-devp2p (#11013)
* EIP 1108: Reduce alt_bn128 precompile gas costs (#11008)
* xDai chain support and nodes list update (#10989)
* EIP 2028: transaction gas lowered from 68 to 16 (#10987)
* EIP-1344 Add CHAINID op-code (#10983)
* manual publish jobs for releases, no changes for nightlies (#10977)
* [blooms-db] Fix benchmarks (#10974)
* Verify transaction against its block during import (#10954)
* Better error message for rpc gas price errors (#10931)
* tx-pool: accept local tx with higher gas price when pool full (#10901)
* Fix fork choice (#10837)
* Cleanup unused vm dependencies (#10787)
* Fix compilation on recent nightlies (#10991)
This commit is contained in:
s3krit 2019-09-12 18:43:53 +02:00 committed by GitHub
parent 6bd7db96fe
commit 45f27cec34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 2482 additions and 538 deletions

View File

@ -13,10 +13,6 @@ variables:
SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache"
CARGO_TARGET: x86_64-unknown-linux-gnu
.no_git: &no_git # disable git strategy
variables:
GIT_STRATEGY: none
GIT_SUBMODULE_STRATEGY: none
.releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries")
only: &releaseable_branches
@ -205,11 +201,10 @@ build-windows:
publish-docker:
stage: publish
<<: *no_git
only: *releaseable_branches
except:
variables:
- $SCHEDULE_TAG == "nightly"
- nightly
when: manual
dependencies:
- build-linux
environment:
@ -219,23 +214,24 @@ publish-docker:
services:
- docker:dind
variables:
GIT_STRATEGY: none
DOCKER_HOST: tcp://localhost:2375
DOCKER_DRIVER: overlay2
GIT_STRATEGY: none
# DOCKERFILE: tools/Dockerfile
# CONTAINER_IMAGE: parity/parity
script:
# we stopped pushing nightlies to dockerhub, will push to own registry prb.
- ./tools/publish-docker.sh
tags:
- kubernetes-parity-build
publish-snap: &publish-snap
publish-snap-nightly: &publish-snap
stage: publish
<<: *no_git
only: *releaseable_branches
only:
- nightly
image: snapcore/snapcraft
variables:
GIT_STRATEGY: none
BUILD_ARCH: amd64
cache: {}
dependencies:
@ -245,7 +241,12 @@ publish-snap: &publish-snap
script:
- ./tools/publish-snap.sh
publish-snap-i386:
publish-snap-manually:
<<: *publish-snap
only: *releaseable_branches
when: manual
publish-snap-i386-nightly: &publish-snap-i386
<<: *publish-snap
variables:
BUILD_ARCH: i386
@ -253,7 +254,12 @@ publish-snap-i386:
dependencies:
- build-linux-i386
publish-snap-arm64:
publish-snap-i386-manually:
<<: *publish-snap-i386
only: *releaseable_branches
when: manual
publish-snap-arm64-nightly: &publish-snap-arm64
<<: *publish-snap
variables:
BUILD_ARCH: arm64
@ -261,7 +267,12 @@ publish-snap-arm64:
dependencies:
- build-linux-arm64
publish-snap-armhf:
publish-snap-arm64-manually:
<<: *publish-snap-arm64
only: *releaseable_branches
when: manual
publish-snap-armhf-nightly: &publish-snap-armhf
<<: *publish-snap
variables:
BUILD_ARCH: armhf
@ -269,11 +280,18 @@ publish-snap-armhf:
dependencies:
- build-linux-armhf
publish-onchain:
stage: publish
<<: *no_git
publish-snap-armhf-manually:
<<: *publish-snap-armhf
only: *releaseable_branches
when: manual
publish-onchain-nightly: &publish-onchain
stage: publish
only:
- nightly
cache: {}
variables:
GIT_STRATEGY: none
dependencies:
- build-linux
- build-darwin
@ -283,11 +301,18 @@ publish-onchain:
tags:
- linux-docker
publish-awss3-release:
publish-onchain-manually:
<<: *publish-onchain
only: *releaseable_branches
when: manual
publish-release-awss3-nightly: &publish-release-awss3
image: parity/awscli:latest
stage: publish
only: *releaseable_branches
<<: *no_git
only:
- nightly
variables:
GIT_STRATEGY: none
cache: {}
dependencies:
- build-linux
@ -309,6 +334,11 @@ publish-awss3-release:
tags:
- linux-docker
publish-release-awss3-manually:
<<: *publish-release-awss3
only: *releaseable_branches
when: manual
publish-docs:
stage: publish
image: parity/parity-ci-docs:latest
@ -316,6 +346,7 @@ publish-docs:
- tags
except:
- nightly
when: manual
cache: {}
dependencies: []
script:
@ -326,11 +357,12 @@ publish-docs:
publish-av-whitelist:
stage: publish
<<: *no_git
variables:
GIT_STRATEGY: none
only: *releaseable_branches
except:
variables:
- $SCHEDULE_TAG == "nightly"
- nightly
when: manual
cache: {}
dependencies:
- build-windows

117
Cargo.lock generated
View File

@ -497,6 +497,13 @@ name = "edit-distance"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "eip-152"
version = "0.1.0"
dependencies = [
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "eip-712"
version = "0.1.0"
@ -643,6 +650,7 @@ dependencies = [
"common-types 0.1.0",
"criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"eip-152 0.1.0",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -664,6 +672,7 @@ dependencies = [
"fetch 0.1.0",
"hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"journaldb 0.2.0",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -729,7 +738,7 @@ dependencies = [
name = "ethcore-blockchain"
version = "0.1.0"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"blooms-db 0.1.0",
"common-types 0.1.0",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
@ -744,12 +753,14 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp_compress 0.1.0",
"rlp_derive 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"triehash-ethereum 0.2.0",
]
[[package]]
@ -884,7 +895,7 @@ dependencies = [
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -979,7 +990,7 @@ dependencies = [
"serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1135,7 +1146,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memzero 0.1.0",
"parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1152,7 +1163,7 @@ dependencies = [
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0",
"panic_hook 0.1.0",
"parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1172,7 +1183,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1210,6 +1221,7 @@ dependencies = [
"criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1511,6 +1523,23 @@ name = "hex"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hex-literal"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hex-literal-impl"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hidapi"
version = "0.3.1"
@ -2392,7 +2421,7 @@ dependencies = [
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0",
"parity-ethereum 2.5.7",
"parity-ethereum 2.5.8",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2422,7 +2451,7 @@ dependencies = [
[[package]]
name = "parity-ethereum"
version = "2.5.7"
version = "2.5.8"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2475,7 +2504,7 @@ dependencies = [
"parity-rpc 1.12.0",
"parity-runtime 0.1.0",
"parity-updater 1.12.0",
"parity-version 2.5.7",
"parity-version 2.5.8",
"parity-whisper 0.1.0",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2618,7 +2647,7 @@ dependencies = [
"parity-crypto 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-runtime 0.1.0",
"parity-updater 1.12.0",
"parity-version 2.5.7",
"parity-version 2.5.8",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2632,7 +2661,7 @@ dependencies = [
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0",
]
@ -2716,7 +2745,7 @@ dependencies = [
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-hash-fetch 1.12.0",
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-version 2.5.7",
"parity-version 2.5.8",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2726,7 +2755,7 @@ dependencies = [
[[package]]
name = "parity-version"
version = "2.5.7"
version = "2.5.8"
dependencies = [
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2775,12 +2804,11 @@ dependencies = [
[[package]]
name = "parity-wordlist"
version = "1.2.1"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2996,6 +3024,16 @@ dependencies = [
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.20"
@ -3004,6 +3042,14 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "protobuf"
version = "1.7.5"
@ -3061,6 +3107,14 @@ dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.22"
@ -3601,6 +3655,16 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synom"
version = "0.11.3"
@ -3996,7 +4060,7 @@ dependencies = [
[[package]]
name = "transaction-pool"
version = "2.0.0"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -4141,6 +4205,11 @@ name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unreachable"
version = "1.0.0"
@ -4224,15 +4293,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "vm"
version = "0.1.0"
dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethjson 0.1.0",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie-ethereum 0.1.0",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -4503,6 +4569,8 @@ dependencies = [
"checksum heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)" = "<none>"
"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
"checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0"
"checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d"
"checksum hidapi 0.3.1 (git+https://github.com/paritytech/hidapi-rs)" = "<none>"
"checksum home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff"
"checksum http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1a10e5b573b9a0146545010f50772b9e8b1dd0a256564cc4307694c68832a2f5"
@ -4597,7 +4665,7 @@ dependencies = [
"checksum parity-snappy-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1a413d51e5e1927320c9de992998e4a279dffb8c8a7363570198bd8383e66f1b"
"checksum parity-tokio-ipc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb002c2d3539ccd3b82bd915ec060028d4ab350ad203dbffa20028c1e483af5b"
"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
"checksum parity-wordlist 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf13102febd98f4ad416a526b42deb82daf482626ba6ab10d0ebf8f45327514c"
"checksum parity-wordlist 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "573d08f0d3bc8a6ffcdac1de2725b5daeed8db26345a9c12d91648e2d6457f3e"
"checksum parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fec5048fba72a2e01baeb0d08089db79aead4b57e2443df172fb1840075a233"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
@ -4618,13 +4686,16 @@ dependencies = [
"checksum primal-check 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e65f96c0a171f887198c274392c99a116ef65aa7f53f3b6d4902f493965c2d1"
"checksum primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56ea4531dde757b56906493c8604641da14607bf9cdaa80fb9c9cabd2429f8d5"
"checksum primal-sieve 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "da2d6ed369bb4b0273aeeb43f07c105c0117717cbae827b20719438eb2eb798c"
"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8"
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
"checksum protobuf 1.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e14ccd6b79ec748412d4f2dfde1a80fa363a67def4062969f8aed3d790a30f28"
"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07"
"checksum pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9135bed7b452e20dbb395a2d519abaf0c46d60e7ecc02daeeab447d29bada1"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
@ -4688,6 +4759,7 @@ dependencies = [
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe"
@ -4726,7 +4798,7 @@ dependencies = [
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum toolshed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "450441e131c7663af72e63a33c02a6a1fbaaa8601dc652ed6757813bb55aeec7"
"checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9"
"checksum transaction-pool 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d8bd3123931aa6e49dd03bc8a2400490e14701d779458d1f1fff1f04c6f666"
"checksum transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "454adc482e32785c3beab9415dd0f3c689f29cc2d16717eb62f6a784d53544b4"
"checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e"
"checksum trezor-sys 1.0.0 (git+https://github.com/paritytech/trezor-sys)" = "<none>"
"checksum trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7319e28ca295f27359d944a682f7f65b419158bf1590c92cadc0000258d788"
@ -4745,6 +4817,7 @@ dependencies = [
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f"
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"

View File

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

View File

@ -12,7 +12,7 @@ ethereum-types = "0.4"
lazy_static = "1.0"
log = "0.4"
memzero = { path = "../../util/memzero" }
parity-wordlist = "1.2"
parity-wordlist = "1.3"
quick-error = "1.2.2"
rand = "0.4"
rustc-hex = "1.0"

View File

@ -9,7 +9,7 @@ docopt = "1.0"
env_logger = "0.5"
ethkey = { path = "../" }
panic_hook = { path = "../../../util/panic-hook" }
parity-wordlist="1.2"
parity-wordlist="1.3"
rustc-hex = "1.0"
serde = "1.0"
serde_derive = "1.0"

View File

@ -21,7 +21,7 @@ parity-crypto = "0.3.0"
ethereum-types = "0.4"
dir = { path = "../../util/dir" }
smallvec = "0.6"
parity-wordlist = "1.0"
parity-wordlist = "1.3"
tempdir = "0.3"
lazy_static = "1.2.0"

View File

@ -13,6 +13,7 @@ bn = { git = "https://github.com/paritytech/bn", default-features = false }
byteorder = "1.0"
common-types = { path = "types" }
crossbeam-utils = "0.6"
eip-152 = { version = "0.1", path = "../util/EIP-152" }
env_logger = { version = "0.5", optional = true }
error-chain = { version = "0.12", default-features = false }
ethabi = "6.0"
@ -77,6 +78,7 @@ criterion = "0.2"
env_logger = "0.5"
ethcore-accounts = { path = "../accounts" }
fetch = { path = "../util/fetch" }
hex-literal = "0.2.1"
kvdb-rocksdb = "0.1.3"
parity-runtime = { path = "../util/runtime" }
rlp_compress = { path = "../util/rlp-compress" }

View File

@ -8,26 +8,28 @@ authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
ansi_term = "0.10"
ansi_term = "0.11"
blooms-db = { path = "../../util/blooms-db" }
common-types = { path = "../types" }
ethcore-db = { path = "../db" }
ethereum-types = "0.4"
heapsize = "0.4"
itertools = "0.5"
keccak-hash = "0.1"
kvdb = "0.1"
log = "0.4"
parity-bytes = "0.1"
parking_lot = "0.7"
rand = "0.6"
rayon = "1.1"
rlp = { version = "0.3.0", features = ["ethereum"] }
rlp_compress = { path = "../../util/rlp-compress" }
rlp_derive = { path = "../../util/rlp-derive" }
triehash-ethereum = { version = "0.2", path = "../../util/triehash-ethereum" }
[dev-dependencies]
env_logger = "0.5"
ethkey = { path = "../../accounts/ethkey" }
keccak-hash = "0.1"
rustc-hex = "1.0"
tempdir = "0.3"
kvdb-memorydb = "0.1"

View File

@ -713,6 +713,10 @@ impl BlockChain {
///
/// If the tree route verges into pruned or unknown blocks,
/// `None` is returned.
///
/// `is_from_route_finalized` returns whether the `from` part of the
/// route contains a finalized block. This only holds if the two parts (from
/// and to) are on different branches, ie. on 2 different forks.
pub fn tree_route(&self, from: H256, to: H256) -> Option<TreeRoute> {
let mut from_branch = vec![];
let mut is_from_route_finalized = false;
@ -726,9 +730,9 @@ impl BlockChain {
// reset from && to to the same level
while from_details.number > to_details.number {
from_branch.push(current_from);
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
current_from = from_details.parent.clone();
from_details = self.block_details(&from_details.parent)?;
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
}
while to_details.number > from_details.number {
@ -742,9 +746,9 @@ impl BlockChain {
// move to shared parent
while current_from != current_to {
from_branch.push(current_from);
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
current_from = from_details.parent.clone();
from_details = self.block_details(&from_details.parent)?;
is_from_route_finalized = is_from_route_finalized || from_details.is_finalized;
to_branch.push(current_to);
current_to = to_details.parent.clone();
@ -2491,4 +2495,74 @@ mod tests {
assert_eq!(bc.epoch_transition_for(fork_hash).unwrap().block_number, 0);
}
}
#[test]
fn tree_rout_with_finalization() {
let genesis = BlockBuilder::genesis();
let a = genesis.add_block();
// First branch
let a1 = a.add_block_with_random_transactions();
let a2 = a1.add_block_with_random_transactions();
let a3 = a2.add_block_with_random_transactions();
// Second branch
let b1 = a.add_block_with_random_transactions();
let b2 = b1.add_block_with_random_transactions();
let a_hash = a.last().hash();
let a1_hash = a1.last().hash();
let a2_hash = a2.last().hash();
let a3_hash = a3.last().hash();
let b2_hash = b2.last().hash();
let bootstrap_chain = |blocks: Vec<&BlockBuilder>| {
let db = new_db();
let bc = new_chain(genesis.last().encoded(), db.clone());
let mut batch = db.key_value().transaction();
for block in blocks {
insert_block_batch(&mut batch, &bc, block.last().encoded(), vec![]);
bc.commit();
}
db.key_value().write(batch).unwrap();
(db, bc)
};
let mark_finalized = |block_hash: H256, db: &Arc<dyn BlockChainDB>, bc: &BlockChain| {
let mut batch = db.key_value().transaction();
bc.mark_finalized(&mut batch, block_hash).unwrap();
bc.commit();
db.key_value().write(batch).unwrap();
};
// Case 1: fork, with finalized common ancestor
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]);
assert_eq!(bc.best_block_hash(), a3_hash);
assert_eq!(bc.block_hash(2).unwrap(), a1_hash);
mark_finalized(a_hash, &db, &bc);
assert!(!bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized);
}
// Case 2: fork with a finalized block on a branch
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2, &a3, &b1, &b2]);
assert_eq!(bc.best_block_hash(), a3_hash);
assert_eq!(bc.block_hash(2).unwrap(), a1_hash);
mark_finalized(a2_hash, &db, &bc);
assert!(bc.tree_route(a3_hash, b2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(b2_hash, a3_hash).unwrap().is_from_route_finalized);
}
// Case 3: no-fork, with a finalized block
{
let (db, bc) = bootstrap_chain(vec![&a, &a1, &a2]);
assert_eq!(bc.best_block_hash(), a2_hash);
mark_finalized(a1_hash, &db, &bc);
assert!(!bc.tree_route(a1_hash, a2_hash).unwrap().is_from_route_finalized);
assert!(!bc.tree_route(a2_hash, a1_hash).unwrap().is_from_route_finalized);
}
}
}

View File

@ -21,11 +21,13 @@ use ethereum_types::{U256, H256, Bloom};
use common_types::encoded;
use common_types::header::Header;
use common_types::transaction::SignedTransaction;
use common_types::transaction::{SignedTransaction, Transaction, Action};
use common_types::view;
use common_types::views::BlockView;
use keccak_hash::keccak;
use rlp::encode;
use rlp_derive::RlpEncodable;
use triehash_ethereum::ordered_trie_root;
/// Helper structure, used for encoding blocks.
#[derive(Default, Clone, RlpEncodable)]
@ -136,6 +138,29 @@ impl BlockBuilder {
})
}
/// Add a block with randomly generated transactions.
#[inline]
pub fn add_block_with_random_transactions(&self) -> Self {
// Maximum of ~50 transactions
let count = rand::random::<u8>() as usize / 5;
let transactions = std::iter::repeat_with(|| {
let data_len = rand::random::<u8>();
let data = std::iter::repeat_with(|| rand::random::<u8>())
.take(data_len as usize)
.collect::<Vec<_>>();
Transaction {
nonce: 0.into(),
gas_price: 0.into(),
gas: 100_000.into(),
action: Action::Create,
value: 100.into(),
data,
}.sign(&keccak("").into(), None)
}).take(count);
self.add_block_with_transactions(transactions)
}
/// Add a block with given transactions.
#[inline]
pub fn add_block_with_transactions<T>(&self, transactions: T) -> Self
@ -166,11 +191,15 @@ impl BlockBuilder {
let mut block = Block::default();
let metadata = get_metadata();
let block_number = parent_number + 1;
let transactions = metadata.transactions;
let transactions_root = ordered_trie_root(transactions.iter().map(rlp::encode));
block.header.set_parent_hash(parent_hash);
block.header.set_number(block_number);
block.header.set_log_bloom(metadata.bloom);
block.header.set_difficulty(metadata.difficulty);
block.transactions = metadata.transactions;
block.header.set_transactions_root(transactions_root);
block.transactions = transactions;
parent_hash = block.hash();
parent_number = block_number;

View File

@ -20,6 +20,7 @@ num-bigint = "0.2"
[dev-dependencies]
rustc-hex = "1.0"
criterion = "0.2"
hex-literal = "0.2.0"
[features]
evm-debug = []

View File

@ -47,7 +47,7 @@ impl Factory {
/// for caching jump destinations.
pub fn new(evm: VMType, cache_size: usize) -> Self {
Factory {
evm: evm,
evm,
evm_cache: Arc::new(SharedCache::new(cache_size)),
}
}

View File

@ -149,6 +149,8 @@ enum_with_from_u8! {
DIFFICULTY = 0x44,
#[doc = "get the block's gas limit"]
GASLIMIT = 0x45,
#[doc = "get chain ID"]
CHAINID = 0x46,
#[doc = "remove item from stack"]
POP = 0x50,
@ -442,12 +444,7 @@ pub struct InstructionInfo {
impl InstructionInfo {
/// Create new instruction info.
pub fn new(name: &'static str, args: usize, ret: usize, tier: GasPriceTier) -> Self {
InstructionInfo {
name: name,
args: args,
ret: ret,
tier: tier
}
InstructionInfo { name, args, ret, tier }
}
}
@ -504,6 +501,7 @@ lazy_static! {
arr[NUMBER as usize] = Some(InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base));
arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base));
arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base));
arr[CHAINID as usize] = Some(InstructionInfo::new("CHAINID", 0, 1, GasPriceTier::Base));
arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base));
arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow));
arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow));

View File

@ -119,8 +119,6 @@ enum InstructionResult<Gas> {
Trap(TrapKind),
}
enum Never {}
/// ActionParams without code, so that it can be feed into CodeReader.
#[derive(Debug)]
struct InterpreterParams {
@ -178,12 +176,6 @@ pub enum InterpreterResult {
Trap(TrapKind),
}
impl From<vm::Error> for InterpreterResult {
fn from(error: vm::Error) -> InterpreterResult {
InterpreterResult::Done(Err(error))
}
}
/// Intepreter EVM implementation
pub struct Interpreter<Cost: CostType> {
mem: Vec<u8>,
@ -294,6 +286,8 @@ impl<Cost: CostType> Interpreter<Cost> {
cache, params, reader, informant,
valid_jump_destinations, gasometer, stack,
done: false,
// Overridden in `step_inner` based on
// the result of `ext.trace_next_instruction`.
do_trace: true,
mem: Vec::new(),
return_data: ReturnData::empty(),
@ -316,7 +310,7 @@ impl<Cost: CostType> Interpreter<Cost> {
} else if self.reader.len() == 0 {
InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_ref().expect("Gasometer None case is checked above; qed").current_gas.as_u256())))
} else {
self.step_inner(ext).err().expect("step_inner never returns Ok(()); qed")
self.step_inner(ext)
};
if let &InterpreterResult::Done(_) = &result {
@ -328,7 +322,7 @@ impl<Cost: CostType> Interpreter<Cost> {
/// Inner helper function for step.
#[inline(always)]
fn step_inner(&mut self, ext: &mut vm::Ext) -> Result<Never, InterpreterResult> {
fn step_inner(&mut self, ext: &mut dyn vm::Ext) -> InterpreterResult {
let result = match self.resume_result.take() {
Some(result) => result,
None => {
@ -343,22 +337,31 @@ impl<Cost: CostType> Interpreter<Cost> {
let instruction = match instruction {
Some(i) => i,
None => return Err(InterpreterResult::Done(Err(vm::Error::BadInstruction {
None => return InterpreterResult::Done(Err(vm::Error::BadInstruction {
instruction: opcode
}))),
})),
};
let info = instruction.info();
self.last_stack_ret_len = info.ret;
self.verify_instruction(ext, instruction, info)?;
if let Err(e) = self.verify_instruction(ext, instruction, info) {
return InterpreterResult::Done(Err(e));
};
// Calculate gas cost
let requirements = self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size())?;
let requirements = match self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size()) {
Ok(t) => t,
Err(e) => return InterpreterResult::Done(Err(e)),
};
if self.do_trace {
ext.trace_prepare_execute(self.reader.position - 1, opcode, requirements.gas_cost.as_u256(), Self::mem_written(instruction, &self.stack), Self::store_written(instruction, &self.stack));
}
self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost)?;
if let Err(e) = self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost) {
if self.do_trace {
ext.trace_failed();
}
return InterpreterResult::Done(Err(e));
}
self.mem.expand(requirements.memory_required_size);
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_mem_gas = requirements.memory_total_gas;
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas - requirements.gas_cost;
@ -367,18 +370,24 @@ impl<Cost: CostType> Interpreter<Cost> {
// Execute instruction
let current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas;
let result = self.exec_instruction(
let result = match self.exec_instruction(
current_gas, ext, instruction, requirements.provide_gas
)?;
) {
Err(x) => {
if self.do_trace {
ext.trace_failed();
}
return InterpreterResult::Done(Err(x));
},
Ok(x) => x,
};
evm_debug!({ self.informant.after_instruction(instruction) });
result
},
};
if let InstructionResult::Trap(trap) = result {
return Err(InterpreterResult::Trap(trap));
return InterpreterResult::Trap(trap);
}
if let InstructionResult::UnusedGas(ref gas) = result {
@ -400,28 +409,31 @@ impl<Cost: CostType> Interpreter<Cost> {
self.valid_jump_destinations = Some(self.cache.jump_destinations(&self.params.code_hash, &self.reader.code));
}
let jump_destinations = self.valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed");
let pos = self.verify_jump(position, jump_destinations)?;
let pos = match self.verify_jump(position, jump_destinations) {
Ok(x) => x,
Err(e) => return InterpreterResult::Done(Err(e))
};
self.reader.position = pos;
},
InstructionResult::StopExecutionNeedsReturn {gas, init_off, init_size, apply} => {
let mem = mem::replace(&mut self.mem, Vec::new());
return Err(InterpreterResult::Done(Ok(GasLeft::NeedsReturn {
return InterpreterResult::Done(Ok(GasLeft::NeedsReturn {
gas_left: gas.as_u256(),
data: mem.into_return_data(init_off, init_size),
apply_state: apply
})));
}));
},
InstructionResult::StopExecution => {
return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))));
return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())));
},
_ => {},
}
if self.reader.position >= self.reader.len() {
return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))));
return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())));
}
Err(InterpreterResult::Continue)
InterpreterResult::Continue
}
fn verify_instruction(&self, ext: &vm::Ext, instruction: Instruction, info: &InstructionInfo) -> vm::Result<()> {
@ -433,7 +445,8 @@ impl<Cost: CostType> Interpreter<Cost> {
((instruction == instructions::RETURNDATACOPY || instruction == instructions::RETURNDATASIZE) && !schedule.have_return_data) ||
(instruction == instructions::REVERT && !schedule.have_revert) ||
((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) ||
(instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash)
(instruction == instructions::EXTCODEHASH && !schedule.have_extcodehash) ||
(instruction == instructions::CHAINID && !schedule.have_chain_id)
{
return Err(vm::Error::BadInstruction {
instruction: instruction as u8
@ -848,6 +861,9 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::GASLIMIT => {
self.stack.push(ext.env_info().gas_limit.clone());
},
instructions::CHAINID => {
self.stack.push(ext.chain_id().into())
},
// Stack instructions

View File

@ -34,6 +34,8 @@ extern crate log;
#[cfg(test)]
extern crate rustc_hex;
#[cfg(test)]
extern crate hex_literal;
pub mod evm;
pub mod interpreter;

View File

@ -25,6 +25,7 @@ use vm::{self, ActionParams, ActionValue, Ext};
use vm::tests::{FakeExt, FakeCall, FakeCallType, test_finalize};
use factory::Factory;
use vmtype::VMType;
use hex_literal::hex;
evm_test!{test_add: test_add_int}
fn test_add(factory: super::Factory) {
@ -130,6 +131,27 @@ fn test_sender(factory: super::Factory) {
assert_store(&ext, 0, "000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681");
}
evm_test!{test_chain_id: test_chain_id_int}
fn test_chain_id(factory: super::Factory) {
// 46 CHAINID
// 60 00 PUSH 0
// 55 SSTORE
let code = hex!("46 60 00 55").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_istanbul().with_chain_id(9);
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000009");
}
evm_test!{test_extcodecopy: test_extcodecopy_int}
fn test_extcodecopy(factory: super::Factory) {
// 33 - sender
@ -262,7 +284,6 @@ fn test_calldataload(factory: super::Factory) {
assert_eq!(gas_left, U256::from(79_991));
assert_store(&ext, 0, "23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23");
}
evm_test!{test_author: test_author_int}

View File

@ -36,7 +36,7 @@ serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
tiny-keccak = "1.4"
transaction-pool = "2.0"
transaction-pool = "2.0.1"
url = "1"
[dev-dependencies]

View File

@ -46,9 +46,50 @@
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"balance": "1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"balance": "1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"balance": "1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
}
}

View File

@ -49,9 +49,50 @@
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"balance": "1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"balance": "1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"balance": "1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" },
"0000000000000000000000000000000000000042": {
"balance": "1",

View File

@ -38,9 +38,50 @@
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"balance": "1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"balance": "1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"balance": "1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
}
}

View File

@ -34,9 +34,50 @@
"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": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"balance": "1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"balance": "1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"balance": "1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"0000000000000000000000000000000000001337": { "balance": "1", "constructor": "60606040526000805460ff19166001179055346000575b6075806100246000396000f300606060405263ffffffff60e060020a60003504166394b91deb81146022575b6000565b34600057602c6040565b604080519115158252519081900360200190f35b60005460ff16815600a165627a7a723058207882eb60ebce23178b3fa06d4cd8e5adc17711937ccddacb18a04abca2a2c9ee0029" }
}
}

View File

@ -54,8 +54,46 @@
"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": 20 } } } },
"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": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
}
}
}

View File

@ -72,9 +72,50 @@
"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": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 20, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 20, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 20, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 20, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"balance": "1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": 20,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"balance": "1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 20,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"balance": "1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 20,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"183394f52b2c8c034835edba3bcececa6f60b5a8": {
"balance": "100491852286952719463755404"
}

View File

@ -3917,10 +3917,11 @@
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x85d9a0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
@ -3929,10 +3930,11 @@
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x85d9a0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -3941,10 +3943,13 @@
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x85d9a0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -58,8 +58,46 @@
"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": 20 } } } },
"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": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
}
}
}

View File

@ -46,8 +46,46 @@
"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 } } } }
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
}
}
}

View File

@ -66,8 +66,46 @@
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 2000000, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 2000000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 2000000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 2000000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": 2000000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 2000000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 2000000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
}
}
}

View File

@ -109,11 +109,12 @@
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
}
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
@ -122,10 +123,11 @@
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -135,12 +137,15 @@
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
}
},
"0x1204700000000000000000000000000000000005": {

View File

@ -76,9 +76,47 @@
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0xC3500", "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0xC3500", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0xC3500", "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0xC3500", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0xC3500",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0xC3500",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0xC3500",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"bb94f0ceb32257275b2a7a9c094c13e469b4563e": {
"balance": "10000000000000000000000000"
},

View File

@ -3921,10 +3921,11 @@
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x42ae50",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
@ -3933,10 +3934,11 @@
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x42ae50",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -3945,10 +3947,13 @@
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x42ae50",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -125,11 +125,12 @@
"balance": "0x1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x0",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
@ -138,11 +139,12 @@
"balance": "0x1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x0",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -151,11 +153,14 @@
"balance": "0x1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x0",
"activate_at": "0x00",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -117,10 +117,11 @@
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0xaef49",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
@ -130,10 +131,11 @@
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0xaef49",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -143,10 +145,13 @@
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0xaef49",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -5344,10 +5344,11 @@
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x4d50f8",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
@ -5356,10 +5357,11 @@
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x4d50f8",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -5368,10 +5370,13 @@
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x4d50f8",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
@ -5382,6 +5387,8 @@
},
"nodes": [
"enode://f6e37b943bad3a78cb8589b1798d30d210ffd39cfcd2c8f2de4f098467fd49c667980100d919da7ca46cd50505d30989abda87f0b9339377de13d6592c22caf8@34.198.49.72:30303",
"enode://16898006ba2cd4fa8bf9a3dfe32684c178fa861df144bfc21fe800dc4838a03e342056951fa9fd533dcb0be1219e306106442ff2cf1f7e9f8faa5f2fc1a3aa45@116.203.116.241:30303",
"enode://2909846f78c37510cc0e306f185323b83bb2209e5ff4fdd279d93c60e3f365e3c6e62ad1d2133ff11f9fd6d23ad9c3dad73bb974d53a22f7d1ac5b7dea79d0b0@3.217.96.11:30303",
"enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303",
"enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303",
"enode://38e6e7fd416293ed120d567a2675fe078c0205ab0671abf16982ce969823bd1f3443d590c18b321dfae7dcbe1f6ba98ef8702f255c3c9822a188abb82c53adca@51.77.66.187:30303",

View File

@ -60,9 +60,47 @@
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 5067000, "pricing": { "modexp": { "divisor": 20 } } } },
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 5067000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 5067000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 5067000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0x0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": 5067000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0x0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 5067000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0x0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 5067000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
},
"nodes": [

View File

@ -120,38 +120,43 @@
}
}
},
"0000000000000000000000000000000000000006":{
"builtin":{
"name":"alt_bn128_add",
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at":"0x7fffffffffffff",
"pricing":{
"linear":{
"base":500,
"word":0
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007":{
"builtin":{
"name":"alt_bn128_mul",
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at":"0x7fffffffffffff",
"pricing":{
"linear":{
"base":40000,
"word":0
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008":{
"builtin":{
"name":"alt_bn128_pairing",
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at":"0x7fffffffffffff",
"pricing":{
"alt_bn128_pairing":{
"base":100000,
"pair":80000
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -62,9 +62,47 @@
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 3000000, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 3000000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 3000000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 3000000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": 3000000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 3000000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 3000000,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"97c7f4f8f0bbf384578a9f5754ae73f37ff49ec2": { "balance": "55000000000000000000000000" }
}
}

View File

@ -90,10 +90,11 @@
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x4829ba",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
@ -102,10 +103,11 @@
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x4829ba",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -114,10 +116,13 @@
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x4829ba",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -128,38 +128,43 @@
}
}
},
"0000000000000000000000000000000000000006":{
"builtin":{
"name":"alt_bn128_add",
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at":"0x21e88e",
"pricing":{
"linear":{
"base":500,
"word":0
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007":{
"builtin":{
"name":"alt_bn128_mul",
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at":"0x21e88e",
"pricing":{
"linear":{
"base":40000,
"word":0
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008":{
"builtin":{
"name":"alt_bn128_pairing",
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at":"0x21e88e",
"pricing":{
"alt_bn128_pairing":{
"base":100000,
"pair":80000
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -51,7 +51,6 @@
},
"nodes": [
"enode://6e3d1b39cbd2a9c4f053a27e68fd90d0bac83691dfdc4a13c59f2555078a71e63c5daaee5a82aa6db500512760a5456f86076bf8bbe8011c27c82ed7d6f5fb26@45.77.140.210:30303",
"enode://f4698ad485a027497e1cc992bb5f7cecee2b32a44c47202738d8d0eecfab719541988d0cbcbc5ea94c6c959e5cddeb85fc6ae75fb63dc3bf87cdbe9e6f615e9d@206.156.242.64:30303",
"enode://31dffed97f8fed1f34fe66453280a89cbeeda60cf28f6fbb212ebbefd7c7566a02c1c7d5c00bbbb49b9fa8a49f157e0f786f379ca9bcbf2fea24de70d70a22b6@206.156.242.61:30303",
"enode://6bdc7553ab2e4914cb47774c1e6d8c8f47ac7c3981891f85f65d06f208ea1bc4d3bf982b330950e0a0cd127efd7145c4df7113159a1d4a06ed722e6c16d0ac6c@45.32.215.190:30303",
"enode://872d82a24144bc007658fb6fac0dcdfb9b63aeb05ef563a06d0186f2d1e5ffbfc5c4f1244891a8a86ef70682b9d24382e654b305224883698862e2df647a4d23@45.76.236.247:30303",
@ -60,10 +59,47 @@
],
"accounts": {
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x0", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x0", "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"0x0000000000000000000000000000000000000001": {
"balance": "1",
"builtin": {

View File

@ -58,16 +58,54 @@
"enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303",
"enode://f1a5100a81cb73163ae450c584d06b1f644aa4fad4486c6aeb4c384b343c54bb66c744aa5f133af66ea1b25f0f4a454f04878f3e96ee4cd2390c047396d6357b@209.97.158.4:30303",
"enode://0d1e0372f63a3f0b82d66635ea101ecc0f6797788a078805cc933dd93e6a22f7c9fa51ab4e2d21da02d04480ef19f3bbb9a2b41dd1c262085d295a354bb8b0f9@18.217.47.209:30303",
"enode://ab083db73da15b3995ac9c68035cdb32901835a823cb848fccb672e43dd21f14428706118d6fe5b921d8e741f122f35aad0255bc86807b1d17bcfa1e86e40a14@165.227.37.104:30303",
"enode://875e1bd1b98019a5d6d588c23f68534b75462dd6ecbb3dd058221dbf7aa923f0ab782ab93bb82d42edc9996f7f0816a318bdc761e55c02b95e1169cef66f7edc@159.203.24.35:30303",
"enode://8e0af07c86ec36590bb6368e7ad0c45b6dc658f5fb66ec68889a614affddda5e021bd513bcf4fb2fae4a3bbe08cf0de84f037cd58478a89665dfce1ded2595c7@34.236.37.74:30303",
"enode://182ee200ca134dc4d6390f3d5aadbcd80df0f7f24335830335d142573eacce4eeb919d30e82c5df588034e167e6ba6dd11187502ac9264a71005127f6b146a99@159.203.95.241:30303",
"enode://b022ff70b5fcaf9596ae5efed99a8198b4ae0578ee9d17b733609d803a75cef95d3a2a18e50dca9a7c3b26139f158c59eaf8b5fb8d1d331c9a46934a78acabe8@206.189.76.128:30303"
],
"accounts": {
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x0", "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x0", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x0", "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"0x0000000000000000000000000000000000000001": {
"balance": "1",

View File

@ -117,40 +117,42 @@
}
},
"0x0000000000000000000000000000000000000006": {
"balance": "0x1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0xfcc25",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0x0000000000000000000000000000000000000007": {
"balance": "0x1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0xfcc25",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0x0000000000000000000000000000000000000008": {
"balance": "0x1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0xfcc25",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -2735,10 +2735,11 @@
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x19f0a0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 500,
"word": 0
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
@ -2749,10 +2750,11 @@
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x19f0a0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"linear": {
"base": 40000,
"word": 0
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
@ -2763,10 +2765,13 @@
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x19f0a0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}

View File

@ -58,8 +58,46 @@
"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": 20 } } } },
"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": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
}
}
}

View File

@ -57,9 +57,46 @@
"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": "5", "pricing": { "modexp": { "divisor": 100 } } } },
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "5", "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "5", "pricing": { "linear": { "base": 2000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "5", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "5",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "5",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "5",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,157 @@
{
"name": "xDai Chain",
"dataDir": "xdai",
"engine": {
"authorityRound": {
"params": {
"stepDuration": 5,
"blockReward": "0x0",
"maximumUncleCountTransition": 0,
"maximumUncleCount": 0,
"validators": {
"multi": {
"0": {
"list": ["0xcace5b3c29211740e595850e80478416ee77ca21"]
},
"1300": {
"safeContract": "0x22e1229a2c5b95a60983b5577f745a603284f535"
}
}
},
"blockRewardContractAddress": "0x867305d19606aadba405ce534e303d0e225f9556",
"blockRewardContractTransition": 1310
}
}
},
"params": {
"gasLimitBoundDivisor": "0x400",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID": "100",
"eip140Transition": "0x0",
"eip211Transition": "0x0",
"eip214Transition": "0x0",
"eip658Transition": "0x0",
"eip145Transition": 1604400,
"eip1014Transition": 1604400,
"eip1052Transition": 1604400,
"eip1283Transition": 1604400,
"eip1283DisableTransition": 2508800,
"registrar": "0x1ec97dc137f5168af053c24460a1200502e1a9d2"
},
"genesis": {
"seal": {
"authorityRound": {
"step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"gasLimit": "0x989680"
},
"accounts": {
"0000000000000000000000000000000000000005": {
"builtin": {
"name": "modexp",
"activate_at": "0x0",
"pricing": {
"modexp": {
"divisor": 20
}
}
}
},
"0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": "0x0",
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"0x0000000000000000000000000000000000000001": {
"balance": "1",
"builtin": {
"name": "ecrecover",
"pricing": {
"linear": {
"base": 3000,
"word": 0
}
}
}
},
"0x0000000000000000000000000000000000000002": {
"balance": "1",
"builtin": {
"name": "sha256",
"pricing": {
"linear": {
"base": 60,
"word": 12
}
}
}
},
"0x0000000000000000000000000000000000000003": {
"balance": "1",
"builtin": {
"name": "ripemd160",
"pricing": {
"linear": {
"base": 600,
"word": 120
}
}
}
},
"0x0000000000000000000000000000000000000004": {
"balance": "1",
"builtin": {
"name": "identity",
"pricing": {
"linear": {
"base": 15,
"word": 3
}
}
}
}
},
"nodes": [
"enode://66786c15390cb4fef3743571e12ec54ca343e7f119018136d68b670edd93604eedf74e5013dc5c2439f89e0e05593e29c409a97e155ea4165c6b832de131ef1e@3.214.113.185:30303"
]
}

File diff suppressed because one or more lines are too long

View File

@ -36,9 +36,50 @@
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "0", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "0", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } },
"0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } },
"0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
"0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0000000000000000000000000000000000000006": {
"balance": "1",
"builtin": {
"name": "alt_bn128_add",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 500,
"eip1108_transition_price": 150
}
}
}
},
"0000000000000000000000000000000000000007": {
"balance": "1",
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_const_operations": {
"price": 40000,
"eip1108_transition_price": 6000
}
}
}
},
"0000000000000000000000000000000000000008": {
"balance": "1",
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 0,
"eip1108_transition": "0x7fffffffffffff",
"pricing": {
"alt_bn128_pairing": {
"base": 100000,
"pair": 80000,
"eip1108_transition_base": 45000,
"eip1108_transition_pair": 34000
}
}
}
},
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "0" }
}
}

View File

@ -16,21 +16,26 @@
//! Standard built-in contracts.
use std::cmp::{max, min};
use std::io::{self, Read};
use std::{
cmp::{max, min},
io::{self, Read, Cursor},
mem::size_of,
};
use byteorder::{ByteOrder, BigEndian};
use parity_crypto::digest;
use num::{BigUint, Zero, One};
use hash::keccak;
use bn;
use byteorder::{BigEndian, LittleEndian, ByteOrder, ReadBytesExt};
use ethereum_types::{H256, U256};
use bytes::BytesRef;
use ethkey::{Signature, recover as ec_recover};
use ethjson;
use ethkey::{Signature, recover as ec_recover};
use hash::keccak;
use log::{warn, trace};
use num::{BigUint, Zero, One};
use bytes::BytesRef;
use parity_crypto::digest;
use eip_152::compress;
/// Execution error.
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct Error(pub &'static str);
impl From<&'static str> for Error {
@ -52,9 +57,27 @@ pub trait Impl: Send + Sync {
}
/// A gas pricing scheme for built-in contracts.
pub trait Pricer: Send + Sync {
/// The gas cost of running this built-in for the given input data.
fn cost(&self, input: &[u8]) -> U256;
// TODO: refactor this trait, see https://github.com/paritytech/parity-ethereum/issues/11014
trait Pricer: Send + Sync {
/// The gas cost of running this built-in for the given input data at block number `at`
fn cost(&self, input: &[u8], at: u64) -> U256;
}
/// Pricing for the Blake2 compression function (aka "F").
/// Computes the price as a fixed cost per round where the number of rounds is part of the input
/// byte slice.
pub type Blake2FPricer = u64;
impl Pricer for Blake2FPricer {
fn cost(&self, input: &[u8], _at: u64) -> U256 {
use std::convert::TryInto;
let (rounds_bytes, _) = input.split_at(std::mem::size_of::<u32>());
// Returning zero if the conversion fails is fine because `execute()` will check the length
// and bail with the appropriate error.
let rounds = u32::from_be_bytes(rounds_bytes.try_into().unwrap_or([0u8; 4]));
// U256::from(*self as u128 * rounds as u128)
U256::from(*self as u64 * rounds as u64)
}
}
/// A linear pricing model. This computes a price using a base cost and a cost per-word.
@ -69,26 +92,56 @@ struct ModexpPricer {
}
impl Pricer for Linear {
fn cost(&self, input: &[u8]) -> U256 {
fn cost(&self, input: &[u8], _at: u64) -> U256 {
U256::from(self.base) + U256::from(self.word) * U256::from((input.len() + 31) / 32)
}
}
/// A alt_bn128_parinig pricing model. This computes a price using a base cost and a cost per pair.
struct AltBn128PairingPricer {
/// alt_bn128 constant operations (add and mul) pricing model.
struct AltBn128ConstOperations {
price: usize,
eip1108_transition_at: u64,
eip1108_transition_price: usize,
}
impl Pricer for AltBn128ConstOperations {
fn cost(&self, _input: &[u8], at: u64) -> U256 {
if at >= self.eip1108_transition_at {
self.eip1108_transition_price.into()
} else {
self.price.into()
}
}
}
/// alt_bn128 pairing price
#[derive(Debug, Copy, Clone)]
struct AltBn128PairingPrice {
base: usize,
pair: usize,
}
/// alt_bn128_pairing pricing model. This computes a price using a base cost and a cost per pair.
struct AltBn128PairingPricer {
price: AltBn128PairingPrice,
eip1108_transition_at: u64,
eip1108_transition_price: AltBn128PairingPrice,
}
impl Pricer for AltBn128PairingPricer {
fn cost(&self, input: &[u8]) -> U256 {
let cost = U256::from(self.base) + U256::from(self.pair) * U256::from(input.len() / 192);
cost
fn cost(&self, input: &[u8], at: u64) -> U256 {
let price = if at >= self.eip1108_transition_at {
self.eip1108_transition_price
} else {
self.price
};
U256::from(price.base) + U256::from(price.pair) * U256::from(input.len() / 192)
}
}
impl Pricer for ModexpPricer {
fn cost(&self, input: &[u8]) -> U256 {
fn cost(&self, input: &[u8], _at: u64) -> U256 {
let mut reader = input.chain(io::repeat(0));
let mut buf = [0; 32];
@ -157,14 +210,16 @@ impl ModexpPricer {
///
/// Unless `is_active` is true,
pub struct Builtin {
pricer: Box<Pricer>,
native: Box<Impl>,
pricer: Box<dyn Pricer>,
native: Box<dyn Impl>,
activate_at: u64,
}
impl Builtin {
/// Simple forwarder for cost.
pub fn cost(&self, input: &[u8]) -> U256 { self.pricer.cost(input) }
pub fn cost(&self, input: &[u8], at: u64) -> U256 {
self.pricer.cost(input, at)
}
/// Simple forwarder for execute.
pub fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
@ -172,12 +227,17 @@ impl Builtin {
}
/// Whether the builtin is activated at the given block number.
pub fn is_active(&self, at: u64) -> bool { at >= self.activate_at }
pub fn is_active(&self, at: u64) -> bool {
at >= self.activate_at
}
}
impl From<ethjson::spec::Builtin> for Builtin {
fn from(b: ethjson::spec::Builtin) -> Self {
let pricer: Box<Pricer> = match b.pricing {
let pricer: Box<dyn Pricer> = match b.pricing {
ethjson::spec::Pricing::Blake2F(cost_per_round) => {
Box::new(cost_per_round)
},
ethjson::spec::Pricing::Linear(linear) => {
Box::new(Linear {
base: linear.base,
@ -187,7 +247,7 @@ impl From<ethjson::spec::Builtin> for Builtin {
ethjson::spec::Pricing::Modexp(exp) => {
Box::new(ModexpPricer {
divisor: if exp.divisor == 0 {
warn!("Zero modexp divisor specified. Falling back to default.");
warn!(target: "builtin", "Zero modexp divisor specified. Falling back to default.");
10
} else {
exp.divisor
@ -196,31 +256,46 @@ impl From<ethjson::spec::Builtin> for Builtin {
}
ethjson::spec::Pricing::AltBn128Pairing(pricer) => {
Box::new(AltBn128PairingPricer {
base: pricer.base,
pair: pricer.pair,
price: AltBn128PairingPrice {
base: pricer.base,
pair: pricer.pair,
},
eip1108_transition_at: b.eip1108_transition.map_or(u64::max_value(), Into::into),
eip1108_transition_price: AltBn128PairingPrice {
base: pricer.eip1108_transition_base,
pair: pricer.eip1108_transition_pair,
},
})
}
ethjson::spec::Pricing::AltBn128ConstOperations(pricer) => {
Box::new(AltBn128ConstOperations {
price: pricer.price,
eip1108_transition_price: pricer.eip1108_transition_price,
eip1108_transition_at: b.eip1108_transition.map_or(u64::max_value(), Into::into)
})
}
};
Builtin {
pricer: pricer,
pricer,
native: ethereum_builtin(&b.name),
activate_at: b.activate_at.map(Into::into).unwrap_or(0),
activate_at: b.activate_at.map_or(0, Into::into),
}
}
}
/// Ethereum built-in factory.
pub fn ethereum_builtin(name: &str) -> Box<Impl> {
pub fn ethereum_builtin(name: &str) -> Box<dyn Impl> {
match name {
"identity" => Box::new(Identity) as Box<Impl>,
"ecrecover" => Box::new(EcRecover) as Box<Impl>,
"sha256" => Box::new(Sha256) as Box<Impl>,
"ripemd160" => Box::new(Ripemd160) as Box<Impl>,
"modexp" => Box::new(ModexpImpl) as Box<Impl>,
"alt_bn128_add" => Box::new(Bn128AddImpl) as Box<Impl>,
"alt_bn128_mul" => Box::new(Bn128MulImpl) as Box<Impl>,
"alt_bn128_pairing" => Box::new(Bn128PairingImpl) as Box<Impl>,
"identity" => Box::new(Identity) as Box<dyn Impl>,
"ecrecover" => Box::new(EcRecover) as Box<dyn Impl>,
"sha256" => Box::new(Sha256) as Box<dyn Impl>,
"ripemd160" => Box::new(Ripemd160) as Box<dyn Impl>,
"modexp" => Box::new(ModexpImpl) as Box<dyn Impl>,
"alt_bn128_add" => Box::new(Bn128AddImpl) as Box<dyn Impl>,
"alt_bn128_mul" => Box::new(Bn128MulImpl) as Box<dyn Impl>,
"alt_bn128_pairing" => Box::new(Bn128PairingImpl) as Box<dyn Impl>,
"blake2_f" => Box::new(Blake2F) as Box<dyn Impl>,
_ => panic!("invalid builtin name: {}", name),
}
}
@ -232,6 +307,10 @@ pub fn ethereum_builtin(name: &str) -> Box<Impl> {
// - sha256
// - ripemd160
// - modexp (EIP198)
// - alt_bn128_add
// - alt_bn128_mul
// - alt_bn128_pairing
// - blake2_f (The Blake2 compression function F, EIP-152)
#[derive(Debug)]
struct Identity;
@ -257,8 +336,11 @@ struct Bn128MulImpl;
#[derive(Debug)]
struct Bn128PairingImpl;
#[derive(Debug)]
struct Blake2F;
impl Impl for Identity {
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
output.write(0, input);
Ok(())
}
@ -302,6 +384,60 @@ impl Impl for Sha256 {
}
}
impl Impl for Blake2F {
/// Format of `input`:
/// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f]
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
const BLAKE2_F_ARG_LEN: usize = 213;
const PROOF: &str = "Checked the length of the input above; qed";
if input.len() != BLAKE2_F_ARG_LEN {
trace!(target: "builtin", "input length for Blake2 F precompile should be exactly 213 bytes, was {}", input.len());
return Err("input length for Blake2 F precompile should be exactly 213 bytes".into())
}
let mut cursor = Cursor::new(input);
let rounds = cursor.read_u32::<BigEndian>().expect(PROOF);
// state vector, h
let mut h = [0u64; 8];
for state_word in h.iter_mut() {
*state_word = cursor.read_u64::<LittleEndian>().expect(PROOF);
}
// message block vector, m
let mut m = [0u64; 16];
for msg_word in m.iter_mut() {
*msg_word = cursor.read_u64::<LittleEndian>().expect(PROOF);
}
// 2w-bit offset counter, t
let t = [
cursor.read_u64::<LittleEndian>().expect(PROOF),
cursor.read_u64::<LittleEndian>().expect(PROOF),
];
// final block indicator flag, "f"
let f = match input.last() {
Some(1) => true,
Some(0) => false,
_ => {
trace!(target: "builtin", "incorrect final block indicator flag, was: {:?}", input.last());
return Err("incorrect final block indicator flag".into())
}
};
compress(&mut h, m, t, f, rounds as usize);
let mut output_buf = [0u8; 8 * size_of::<u64>()];
for (i, state_word) in h.iter().enumerate() {
output_buf[i*8..(i+1)*8].copy_from_slice(&state_word.to_le_bytes());
}
output.write(0, &output_buf[..]);
Ok(())
}
}
impl Impl for Ripemd160 {
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
let hash = digest::ripemd160(input);
@ -450,7 +586,7 @@ impl Impl for Bn128AddImpl {
if let Some(sum) = AffineG1::from_jacobian(p1 + p2) {
// point not at infinity
sum.x().to_big_endian(&mut write_buf[0..32]).expect("Cannot fail since 0..32 is 32-byte length");
sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length");;
sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length");
}
output.write(0, &write_buf);
@ -471,7 +607,7 @@ impl Impl for Bn128MulImpl {
if let Some(sum) = AffineG1::from_jacobian(p * fr) {
// point not at infinity
sum.x().to_big_endian(&mut write_buf[0..32]).expect("Cannot fail since 0..32 is 32-byte length");
sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length");;
sum.y().to_big_endian(&mut write_buf[32..64]).expect("Cannot fail since 32..64 is 32-byte length");
}
output.write(0, &write_buf);
Ok(())
@ -489,7 +625,7 @@ impl Impl for Bn128PairingImpl {
}
if let Err(err) = self.execute_with_error(input, output) {
trace!("Pairining error: {:?}", err);
trace!(target: "builtin", "Pairing error: {:?}", err);
return Err(err)
}
Ok(())
@ -558,12 +694,120 @@ impl Bn128PairingImpl {
#[cfg(test)]
mod tests {
use super::{Builtin, Linear, ethereum_builtin, Pricer, ModexpPricer, modexp as me};
use ethjson;
use ethereum_types::U256;
use bytes::BytesRef;
use rustc_hex::FromHex;
use ethjson::uint::Uint;
use num::{BigUint, Zero, One};
use bytes::BytesRef;
use hex_literal::hex;
use super::{Builtin, Linear, ethereum_builtin, Pricer, ModexpPricer, modexp as me};
#[test]
fn blake2f_cost() {
let f = Builtin {
pricer: Box::new(123),
native: ethereum_builtin("blake2_f"),
activate_at: 0,
};
// 5 rounds
let input = hex!("0000000548c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let mut output = [0u8; 64];
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).unwrap();
assert_eq!(f.cost(&input[..], 0), U256::from(123*5));
}
#[test]
fn blake2_f_is_err_on_invalid_length() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 1 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-1
let input = hex!("00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let mut out = [0u8; 64];
let result = blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..]));
assert!(result.is_err());
assert_eq!(result.unwrap_err(), "input length for Blake2 F precompile should be exactly 213 bytes".into());
}
#[test]
fn blake2_f_is_err_on_invalid_length_2() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 2 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-2
let input = hex!("000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let mut out = [0u8; 64];
let result = blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..]));
assert!(result.is_err());
assert_eq!(result.unwrap_err(), "input length for Blake2 F precompile should be exactly 213 bytes".into());
}
#[test]
fn blake2_f_is_err_on_bad_finalization_flag() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 3 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-3
let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002");
let mut out = [0u8; 64];
let result = blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..]));
assert!(result.is_err());
assert_eq!(result.unwrap_err(), "incorrect final block indicator flag".into());
}
#[test]
fn blake2_f_zero_rounds_is_ok_test_vector_4() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 4 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-4
let input = hex!("0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let expected = hex!("08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b");
let mut output = [0u8; 64];
blake2.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).unwrap();
assert_eq!(&output[..], &expected[..]);
}
#[test]
fn blake2_f_test_vector_5() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 5 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-5
let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let expected = hex!("ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923");
let mut out = [0u8; 64];
blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap();
assert_eq!(&out[..], &expected[..]);
}
#[test]
fn blake2_f_test_vector_6() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 6 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-6
let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000");
let expected = hex!("75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735");
let mut out = [0u8; 64];
blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap();
assert_eq!(&out[..], &expected[..]);
}
#[test]
fn blake2_f_test_vector_7() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 7 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-7
let input = hex!("0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let expected = hex!("b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421");
let mut out = [0u8; 64];
blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap();
assert_eq!(&out[..], &expected[..]);
}
#[ignore]
#[test]
fn blake2_f_test_vector_8() {
let blake2 = ethereum_builtin("blake2_f");
// Test vector 8 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-8
// Note this test is slow, 4294967295/0xffffffff rounds take a while.
let input = hex!("ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let expected = hex!("fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615");
let mut out = [0u8; 64];
blake2.execute(&input[..], &mut BytesRef::Fixed(&mut out[..])).unwrap();
assert_eq!(&out[..], &expected[..]);
}
#[test]
fn modexp_func() {
@ -626,19 +870,19 @@ mod tests {
let mut o = [255u8; 32];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").unwrap())[..]);
assert_eq!(&o[..], hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
let mut o8 = [255u8; 8];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o8[..])).expect("Builtin should not fail");
assert_eq!(&o8[..], &(FromHex::from_hex("e3b0c44298fc1c14").unwrap())[..]);
assert_eq!(&o8[..], hex!("e3b0c44298fc1c14"));
let mut o34 = [255u8; 34];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o34[..])).expect("Builtin should not fail");
assert_eq!(&o34[..], &(FromHex::from_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855ffff").unwrap())[..]);
assert_eq!(&o34[..], &hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855ffff")[..]);
let mut ov = vec![];
f.execute(&i[..], &mut BytesRef::Flexible(&mut ov)).expect("Builtin should not fail");
assert_eq!(&ov[..], &(FromHex::from_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").unwrap())[..]);
assert_eq!(&ov[..], &hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")[..]);
}
#[test]
@ -649,59 +893,59 @@ mod tests {
let mut o = [255u8; 32];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31").unwrap())[..]);
assert_eq!(&o[..], &hex!("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31")[..]);
let mut o8 = [255u8; 8];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o8[..])).expect("Builtin should not fail");
assert_eq!(&o8[..], &(FromHex::from_hex("0000000000000000").unwrap())[..]);
assert_eq!(&o8[..], &hex!("0000000000000000")[..]);
let mut o34 = [255u8; 34];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o34[..])).expect("Builtin should not fail");
assert_eq!(&o34[..], &(FromHex::from_hex("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31ffff").unwrap())[..]);
assert_eq!(&o34[..], &hex!("0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31ffff")[..]);
}
#[test]
fn ecrecover() {
let f = ethereum_builtin("ecrecover");
let i = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
let i = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03");
let mut o = [255u8; 32];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("000000000000000000000000c08b5542d177ac6686946920409741463a15dddb").unwrap())[..]);
assert_eq!(&o[..], &hex!("000000000000000000000000c08b5542d177ac6686946920409741463a15dddb")[..]);
let mut o8 = [255u8; 8];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o8[..])).expect("Builtin should not fail");
assert_eq!(&o8[..], &(FromHex::from_hex("0000000000000000").unwrap())[..]);
assert_eq!(&o8[..], &hex!("0000000000000000")[..]);
let mut o34 = [255u8; 34];
f.execute(&i[..], &mut BytesRef::Fixed(&mut o34[..])).expect("Builtin should not fail");
assert_eq!(&o34[..], &(FromHex::from_hex("000000000000000000000000c08b5542d177ac6686946920409741463a15dddbffff").unwrap())[..]);
assert_eq!(&o34[..], &hex!("000000000000000000000000c08b5542d177ac6686946920409741463a15dddbffff")[..]);
let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001a650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001a650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03");
let mut o = [255u8; 32];
f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);
assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]);
let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000").unwrap();
let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000");
let mut o = [255u8; 32];
f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);
assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]);
let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b").unwrap();
let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b");
let mut o = [255u8; 32];
f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);
assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]);
let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000001b").unwrap();
let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000001b");
let mut o = [255u8; 32];
f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);
assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]);
let i_bad = FromHex::from_hex("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
let i_bad = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
let mut o = [255u8; 32];
f.execute(&i_bad[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);
assert_eq!(&o[..], &hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[..]);
// TODO: Should this (corrupted version of the above) fail rather than returning some address?
/* let i_bad = FromHex::from_hex("48173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03").unwrap();
@ -721,103 +965,103 @@ mod tests {
// test for potential gas cost multiplication overflow
{
let input = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3").unwrap();
let input = hex!("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3");
let expected_cost = U256::max_value();
assert_eq!(f.cost(&input[..]), expected_cost.into());
assert_eq!(f.cost(&input[..], 0), expected_cost.into());
}
// test for potential exp len overflow
{
let input = FromHex::from_hex("\
00000000000000000000000000000000000000000000000000000000000000ff\
2a1e530000000000000000000000000000000000000000000000000000000000\
let input = hex!("
00000000000000000000000000000000000000000000000000000000000000ff
2a1e530000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000"
).unwrap();
);
let mut output = vec![0u8; 32];
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap();
let expected = hex!("0000000000000000000000000000000000000000000000000000000000000000");
let expected_cost = U256::max_value();
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should fail");
assert_eq!(output, expected);
assert_eq!(f.cost(&input[..]), expected_cost.into());
assert_eq!(f.cost(&input[..], 0), expected_cost.into());
}
// fermat's little theorem example.
{
let input = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000001\
0000000000000000000000000000000000000000000000000000000000000020\
0000000000000000000000000000000000000000000000000000000000000020\
03\
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\
let input = hex!("
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000020
03
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
).unwrap();
);
let mut output = vec![0u8; 32];
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap();
let expected = hex!("0000000000000000000000000000000000000000000000000000000000000001");
let expected_cost = 13056;
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected);
assert_eq!(f.cost(&input[..]), expected_cost.into());
assert_eq!(f.cost(&input[..], 0), expected_cost.into());
}
// second example from EIP: zero base.
{
let input = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000020\
0000000000000000000000000000000000000000000000000000000000000020\
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\
let input = hex!("
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000020
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
).unwrap();
);
let mut output = vec![0u8; 32];
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap();
let expected = hex!("0000000000000000000000000000000000000000000000000000000000000000");
let expected_cost = 13056;
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected);
assert_eq!(f.cost(&input[..]), expected_cost.into());
assert_eq!(f.cost(&input[..], 0), expected_cost.into());
}
// another example from EIP: zero-padding
{
let input = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000001\
0000000000000000000000000000000000000000000000000000000000000002\
0000000000000000000000000000000000000000000000000000000000000020\
03\
ffff\
let input = hex!("
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000020
03
ffff
80"
).unwrap();
);
let mut output = vec![0u8; 32];
let expected = FromHex::from_hex("3b01b01ac41f2d6e917c6d6a221ce793802469026d9ab7578fa2e79e4da6aaab").unwrap();
let expected = hex!("3b01b01ac41f2d6e917c6d6a221ce793802469026d9ab7578fa2e79e4da6aaab");
let expected_cost = 768;
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected);
assert_eq!(f.cost(&input[..]), expected_cost.into());
assert_eq!(f.cost(&input[..], 0), expected_cost.into());
}
// zero-length modulus.
{
let input = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000001\
0000000000000000000000000000000000000000000000000000000000000002\
0000000000000000000000000000000000000000000000000000000000000000\
03\
let input = hex!("
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000000
03
ffff"
).unwrap();
);
let mut output = vec![];
let expected_cost = 0;
f.execute(&input[..], &mut BytesRef::Flexible(&mut output)).expect("Builtin should not fail");
assert_eq!(output.len(), 0); // shouldn't have written any output.
assert_eq!(f.cost(&input[..]), expected_cost.into());
assert_eq!(f.cost(&input[..], 0), expected_cost.into());
}
}
@ -832,21 +1076,21 @@ mod tests {
// zero-points additions
{
let input = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000\
let input = hex!("
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000"
).unwrap();
);
let mut output = vec![0u8; 64];
let expected = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000000\
let expected = hex!("
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000"
).unwrap();
);
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected);
assert_eq!(output, &expected[..]);
}
// no input, should not fail
@ -855,23 +1099,23 @@ mod tests {
let input = BytesRef::Fixed(&mut empty);
let mut output = vec![0u8; 64];
let expected = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000000\
let expected = hex!("
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000"
).unwrap();
);
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected);
assert_eq!(output, &expected[..]);
}
// should fail - point not on curve
{
let input = FromHex::from_hex("\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
let input = hex!("
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111"
).unwrap();
);
let mut output = vec![0u8; 64];
@ -891,29 +1135,29 @@ mod tests {
// zero-point multiplication
{
let input = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000\
let input = hex!("
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0200000000000000000000000000000000000000000000000000000000000000"
).unwrap();
);
let mut output = vec![0u8; 64];
let expected = FromHex::from_hex("\
0000000000000000000000000000000000000000000000000000000000000000\
let expected = hex!("
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000"
).unwrap();
);
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail");
assert_eq!(output, expected);
assert_eq!(output, &expected[..]);
}
// should fail - point not on curve
{
let input = FromHex::from_hex("\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
let input = hex!("
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
0f00000000000000000000000000000000000000000000000000000000000000"
).unwrap();
);
let mut output = vec![0u8; 64];
@ -954,16 +1198,12 @@ mod tests {
}
}
fn bytes(s: &'static str) -> Vec<u8> {
FromHex::from_hex(s).expect("static str should contain valid hex bytes")
}
#[test]
fn bn128_pairing_empty() {
// should not fail, because empty input is a valid input of 0 elements
empty_test(
builtin_pairing(),
bytes("0000000000000000000000000000000000000000000000000000000000000001"),
hex!("0000000000000000000000000000000000000000000000000000000000000001").to_vec(),
);
}
@ -972,12 +1212,12 @@ mod tests {
// should fail - point not on curve
error_test(
builtin_pairing(),
&bytes("\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
&hex!("
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111"
),
Some("not on curve"),
@ -989,9 +1229,9 @@ mod tests {
// should fail - input length is invalid
error_test(
builtin_pairing(),
&bytes("\
1111111111111111111111111111111111111111111111111111111111111111\
1111111111111111111111111111111111111111111111111111111111111111\
&hex!("
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111"
),
Some("Invalid input length"),
@ -1008,7 +1248,7 @@ mod tests {
fn is_active() {
let pricer = Box::new(Linear { base: 10, word: 20} );
let b = Builtin {
pricer: pricer as Box<Pricer>,
pricer: pricer as Box<dyn Pricer>,
native: ethereum_builtin("identity"),
activate_at: 100_000,
};
@ -1022,15 +1262,15 @@ mod tests {
fn from_named_linear() {
let pricer = Box::new(Linear { base: 10, word: 20 });
let b = Builtin {
pricer: pricer as Box<Pricer>,
pricer: pricer as Box<dyn Pricer>,
native: ethereum_builtin("identity"),
activate_at: 1,
};
assert_eq!(b.cost(&[0; 0]), U256::from(10));
assert_eq!(b.cost(&[0; 1]), U256::from(30));
assert_eq!(b.cost(&[0; 32]), U256::from(30));
assert_eq!(b.cost(&[0; 33]), U256::from(50));
assert_eq!(b.cost(&[0; 0], 0), U256::from(10));
assert_eq!(b.cost(&[0; 1], 0), U256::from(30));
assert_eq!(b.cost(&[0; 32], 0), U256::from(30));
assert_eq!(b.cost(&[0; 33], 0), U256::from(50));
let i = [0u8, 1, 2, 3];
let mut o = [255u8; 4];
@ -1047,16 +1287,67 @@ mod tests {
word: 20,
}),
activate_at: None,
eip1108_transition: None,
});
assert_eq!(b.cost(&[0; 0]), U256::from(10));
assert_eq!(b.cost(&[0; 1]), U256::from(30));
assert_eq!(b.cost(&[0; 32]), U256::from(30));
assert_eq!(b.cost(&[0; 33]), U256::from(50));
assert_eq!(b.cost(&[0; 0], 0), U256::from(10));
assert_eq!(b.cost(&[0; 1], 0), U256::from(30));
assert_eq!(b.cost(&[0; 32], 0), U256::from(30));
assert_eq!(b.cost(&[0; 33], 0), U256::from(50));
let i = [0u8, 1, 2, 3];
let mut o = [255u8; 4];
b.execute(&i[..], &mut BytesRef::Fixed(&mut o[..])).expect("Builtin should not fail");
assert_eq!(i, o);
}
#[test]
fn bn128_pairing_eip1108_transition() {
let b = Builtin::from(ethjson::spec::Builtin {
name: "alt_bn128_pairing".to_owned(),
pricing: ethjson::spec::Pricing::AltBn128Pairing(ethjson::spec::builtin::AltBn128Pairing {
base: 100_000,
pair: 80_000,
eip1108_transition_base: 45_000,
eip1108_transition_pair: 34_000,
}),
activate_at: Some(Uint(U256::from(10))),
eip1108_transition: Some(Uint(U256::from(20))),
});
assert_eq!(b.cost(&[0; 192 * 3], 10), U256::from(340_000), "80 000 * 3 + 100 000 == 340 000");
assert_eq!(b.cost(&[0; 192 * 7], 20), U256::from(283_000), "34 000 * 7 + 45 000 == 283 000");
}
#[test]
fn bn128_add_eip1108_transition() {
let b = Builtin::from(ethjson::spec::Builtin {
name: "alt_bn128_add".to_owned(),
pricing: ethjson::spec::Pricing::AltBn128ConstOperations(ethjson::spec::builtin::AltBn128ConstOperations {
price: 500,
eip1108_transition_price: 150,
}),
activate_at: Some(Uint(U256::from(10))),
eip1108_transition: Some(Uint(U256::from(20))),
});
assert_eq!(b.cost(&[0; 192], 10), U256::from(500));
assert_eq!(b.cost(&[0; 10], 20), U256::from(150), "after istanbul hardfork gas cost for add should be 150");
}
#[test]
fn bn128_mul_eip1108_transition() {
let b = Builtin::from(ethjson::spec::Builtin {
name: "alt_bn128_mul".to_owned(),
pricing: ethjson::spec::Pricing::AltBn128ConstOperations(ethjson::spec::builtin::AltBn128ConstOperations {
price: 40_000,
eip1108_transition_price: 6000,
}),
activate_at: Some(Uint(U256::from(10))),
eip1108_transition: Some(Uint(U256::from(20))),
});
assert_eq!(b.cost(&[0; 192], 10), U256::from(40_000));
assert_eq!(b.cost(&[0; 10], 20), U256::from(6_000), "after istanbul hardfork gas cost for mul should be 6 000");
}
}

View File

@ -54,7 +54,7 @@ pub use vm::{LastHashes, EnvInfo};
pub use error::TransactionImportError;
pub use verification::VerifierType;
mod traits;
pub mod traits;
mod chain_notify;
mod private_notify;

View File

@ -18,6 +18,7 @@ use engines::{Engine, Seal};
use machine::Machine;
use types::header::{Header, ExtendedHeader};
use block::ExecutedBlock;
use std::sync::atomic::{AtomicU64, Ordering};
/// `InstantSeal` params.
#[derive(Default, Debug, PartialEq)]
@ -39,13 +40,16 @@ impl From<::ethjson::spec::InstantSealParams> for InstantSealParams {
pub struct InstantSeal<M> {
params: InstantSealParams,
machine: M,
last_sealed_block: AtomicU64,
}
impl<M> InstantSeal<M> {
/// Returns new instance of InstantSeal over the given state machine.
pub fn new(params: InstantSealParams, machine: M) -> Self {
InstantSeal {
params, machine,
params,
machine,
last_sealed_block: AtomicU64::new(0),
}
}
}
@ -60,11 +64,19 @@ impl<M: Machine> Engine<M> for InstantSeal<M> {
fn seals_internally(&self) -> Option<bool> { Some(true) }
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
if block.transactions.is_empty() {
Seal::None
} else {
Seal::Regular(Vec::new())
if !block.transactions.is_empty() {
let block_number = block.header.number();
let last_sealed_block = self.last_sealed_block.load(Ordering::SeqCst);
// Return a regular seal if the given block is _higher_ than
// the last sealed one
if block_number > last_sealed_block {
let prev_last_sealed_block = self.last_sealed_block.compare_and_swap(last_sealed_block, block_number, Ordering::SeqCst);
if prev_last_sealed_block == last_sealed_block {
return Seal::Regular(Vec::new())
}
}
}
Seal::None
}
fn verify_local_seal(&self, _header: &Header) -> Result<(), M::Error> {

View File

@ -57,6 +57,11 @@ pub fn new_poanet<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/poacore.json"))
}
/// Create a new xDai chain spec.
pub fn new_xdai<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/xdai.json"))
}
/// Create a new Volta mainnet chain spec.
pub fn new_volta<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
load(params.into(), include_bytes!("../../res/ethereum/volta.json"))

View File

@ -395,7 +395,8 @@ impl<'a> CallCreateExecutive<'a> {
let default = [];
let data = if let Some(ref d) = params.data { d as &[u8] } else { &default as &[u8] };
let cost = builtin.cost(data);
// NOTE(niklasad1): block number is used by `builtin alt_bn128 ops` to enable eip1108
let cost = builtin.cost(data, self.info.number);
if cost <= params.gas {
let mut builtin_out_buffer = Vec::new();
let result = {

View File

@ -399,6 +399,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
self.env_info
}
fn chain_id(&self) -> u64 {
self.machine.params().chain_id
}
fn depth(&self) -> usize {
self.depth
}
@ -419,6 +423,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
self.vm_tracer.trace_prepare_execute(pc, instruction, gas_cost, mem_written, store_written)
}
fn trace_failed(&mut self) {
self.vm_tracer.trace_failed();
}
fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) {
self.vm_tracer.trace_executed(gas_used, stack_push, mem)
}

View File

@ -210,6 +210,8 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
self.ext.env_info()
}
fn chain_id(&self) -> u64 { 0 }
fn depth(&self) -> usize {
0
}

View File

@ -62,6 +62,7 @@ extern crate bn;
extern crate byteorder;
extern crate common_types as types;
extern crate crossbeam_utils;
extern crate eip_152;
extern crate ethabi;
extern crate ethash;
extern crate ethcore_blockchain as blockchain;
@ -120,6 +121,9 @@ extern crate blooms_db;
extern crate env_logger;
#[cfg(test)]
extern crate rlp_compress;
#[cfg(test)]
#[macro_use]
extern crate hex_literal;
#[macro_use]
extern crate ethabi_derive;

View File

@ -474,7 +474,7 @@ mod tests {
#[test]
fn should_disallow_unsigned_transactions() {
let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080".into();
let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080";
let transaction: UnverifiedTransaction = ::rlp::decode(&::rustc_hex::FromHex::from_hex(rlp).unwrap()).unwrap();
let spec = ::ethereum::new_ropsten_test();
let ethparams = get_default_ethash_extensions();

View File

@ -31,7 +31,7 @@ use ethcore_miner::work_notify::NotifyWork;
use ethereum_types::{H256, U256, Address};
use io::IoChannel;
use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache};
use miner;
use miner::{self, MinerService};
use parking_lot::{Mutex, RwLock};
use rayon::prelude::*;
use types::transaction::{
@ -52,6 +52,7 @@ use client::{
BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
};
use client::{BlockId, ClientIoMessage};
use client::traits::EngineClient;
use engines::{EthEngine, Seal, EngineSigner};
use error::{Error, ErrorKind};
use executed::ExecutionError;
@ -494,7 +495,7 @@ impl Miner {
let sender = transaction.sender();
// Re-verify transaction again vs current state.
let result = client.verify_signed(&transaction)
let result = client.verify_for_pending_block(&transaction, &open_block.header)
.map_err(|e| e.into())
.and_then(|_| {
open_block.push_transaction(transaction, None)
@ -830,7 +831,6 @@ impl Miner {
/// Prepare pending block, check whether sealing is needed, and then update sealing.
fn prepare_and_update_sealing<C: miner::BlockChainClient>(&self, chain: &C) {
use miner::MinerService;
// Make sure to do it after transaction is imported and lock is dropped.
// We need to create pending block and enable sealing.
@ -1307,6 +1307,9 @@ impl miner::MinerService for Miner {
service_transaction_checker.as_ref(),
);
queue.cull(client);
if is_internal_import {
chain.update_sealing();
}
};
if let Err(e) = channel.send(ClientIoMessage::execute(cull)) {
@ -1314,6 +1317,9 @@ impl miner::MinerService for Miner {
}
} else {
self.transaction_queue.cull(client);
if is_internal_import {
self.update_sealing(chain);
}
}
}
if let Some(ref service_transaction_checker) = self.service_transaction_checker {

View File

@ -113,11 +113,13 @@ impl<'a, C: 'a> PoolClient<'a, C> where
}
}
/// Verifies if signed transaction is executable.
/// Verifies transaction against its block (before its import into this block)
/// Also Verifies if signed transaction is executable.
///
/// This should perform any verifications that rely on chain status.
pub fn verify_signed(&self, tx: &SignedTransaction) -> Result<(), transaction::Error> {
self.engine.machine().verify_transaction(&tx, &self.best_block_header, self.chain)
pub fn verify_for_pending_block(&self, tx: &SignedTransaction, header: &Header) -> Result<(), transaction::Error> {
self.engine.machine().verify_transaction_basic(tx, header)?;
self.engine.machine().verify_transaction(tx, &self.best_block_header, self.chain)
}
}
@ -138,8 +140,7 @@ impl<'a, C: 'a> pool::client::Client for PoolClient<'a, C> where
self.engine.verify_transaction_basic(&tx, &self.best_block_header)?;
let tx = self.engine.verify_transaction_unordered(tx, &self.best_block_header)?;
self.verify_signed(&tx)?;
self.engine.machine().verify_transaction(&tx, &self.best_block_header, self.chain)?;
Ok(tx)
}

View File

@ -65,7 +65,7 @@ fn fmt_err<F: ::std::fmt::Display>(f: F) -> String {
/// we define a "bugfix" hard fork as any hard fork which
/// you would put on-by-default in a new chain.
#[derive(Debug, PartialEq, Default)]
#[cfg_attr(test, derive(Clone))]
#[cfg_attr(any(test, feature = "test-helpers"), derive(Clone))]
pub struct CommonParams {
/// Account start nonce.
pub account_start_nonce: U256,
@ -123,6 +123,10 @@ pub struct CommonParams {
pub eip1283_disable_transition: BlockNumber,
/// Number of first block where EIP-1014 rules begin.
pub eip1014_transition: BlockNumber,
/// Number of first block where EIP-1344 rules begin: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md
pub eip1344_transition: BlockNumber,
/// Number of first block where EIP-2028 rules begin.
pub eip2028_transition: BlockNumber,
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
pub dust_protection_transition: BlockNumber,
/// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled.
@ -189,7 +193,11 @@ impl CommonParams {
schedule.have_return_data = block_number >= self.eip211_transition;
schedule.have_bitwise_shifting = block_number >= self.eip145_transition;
schedule.have_extcodehash = block_number >= self.eip1052_transition;
schedule.have_chain_id = block_number >= self.eip1344_transition;
schedule.eip1283 = block_number >= self.eip1283_transition && !(block_number >= self.eip1283_disable_transition);
if block_number >= self.eip2028_transition {
schedule.tx_data_non_zero_gas = 16;
}
if block_number >= self.eip210_transition {
schedule.blockhash_gas = 800;
}
@ -308,6 +316,14 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value,
Into::into,
),
eip1344_transition: p.eip1344_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
eip2028_transition: p.eip2028_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
dust_protection_transition: p.dust_protection_transition.map_or_else(
BlockNumber::max_value,
Into::into,

View File

@ -16,6 +16,7 @@
//! Simple executive tracer.
use std::cmp::min;
use ethereum_types::{U256, Address};
use vm::{Error as VmError, ActionParams};
use log::{debug, warn};
@ -194,12 +195,16 @@ impl Tracer for ExecutiveTracer {
}
}
struct TraceData {
mem_written: Option<(usize, usize)>,
store_written: Option<(U256, U256)>,
}
/// Simple VM tracer. Traces all operations.
pub struct ExecutiveVMTracer {
data: VMTrace,
depth: usize,
last_mem_written: Option<(usize, usize)>,
last_store_written: Option<(U256, U256)>,
trace_stack: Vec<TraceData>,
}
impl ExecutiveVMTracer {
@ -213,8 +218,7 @@ impl ExecutiveVMTracer {
subs: vec![],
},
depth: 0,
last_mem_written: None,
last_store_written: None,
trace_stack: vec![],
}
}
@ -241,30 +245,27 @@ impl VMTracer for ExecutiveVMTracer {
executed: None,
});
});
self.last_mem_written = mem_written;
self.last_store_written = store_written;
self.trace_stack.push(TraceData { mem_written, store_written });
}
fn trace_failed(&mut self) {
let _ = self.trace_stack.pop().expect("pushed in trace_prepare_execute; qed");
}
fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem: &[u8]) {
let mem_diff = self.last_mem_written.take().map(|(o, s)| {
let TraceData { mem_written, store_written } = self.trace_stack.pop().expect("pushed in trace_prepare_execute; qed");
let mem_diff = mem_written.map(|(o, s)| {
if o + s > mem.len() {
warn!(
target: "trace",
"Last mem written is out of bounds {} (mem is {})",
o + s,
mem.len(),
);
(o, &[][..])
} else {
(o, &(mem[o..o+s]))
warn!(target: "trace", "mem_written is out of bounds");
}
(o, &mem[min(mem.len(), o)..min(o + s, mem.len())])
});
let store_diff = self.last_store_written.take();
let store_diff = store_written;
Self::with_trace_in_depth(&mut self.data, self.depth, move |trace| {
let ex = VMExecutedOperation {
gas_used: gas_used,
stack_push: stack_push.iter().cloned().collect(),
mem_diff: mem_diff.map(|(s, r)| MemoryDiff { offset: s, data: r.iter().cloned().collect() }),
stack_push: stack_push.to_vec(),
mem_diff: mem_diff.map(|(s, r)| MemoryDiff { offset: s, data: r.to_vec() }),
store_diff: store_diff.map(|(l, v)| StorageDiff { location: l, value: v }),
};
trace.operations.last_mut().expect("trace_executed is always called after a trace_prepare_execute; trace.operations cannot be empty; qed").executed = Some(ex);

View File

@ -85,6 +85,9 @@ pub trait VMTracer: Send {
/// Trace the preparation to execute a single valid instruction.
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256, _mem_written: Option<(usize, usize)>, _store_written: Option<(U256, U256)>) {}
/// Trace the execution failure of a single instruction.
fn trace_failed(&mut self) {}
/// Trace the finalised execution of a single valid instruction.
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {}

View File

@ -16,4 +16,7 @@ rlp_derive = { path = "../../util/rlp-derive" }
unexpected = { path = "../../util/unexpected" }
[dev-dependencies]
rustc-hex= "1.0"
rustc-hex = "1.0"
[features]
test-helpers = []

View File

@ -28,9 +28,6 @@ pub enum Error {
AlreadyImported,
/// Transaction is not valid anymore (state already has higher nonce)
Old,
/// Transaction has too low fee
/// (there is already a transaction with the same sender-nonce but higher gas price)
TooCheapToReplace,
/// Transaction was not imported to the queue because limit has been reached.
LimitReached,
/// Transaction's gas price is below threshold.
@ -40,6 +37,14 @@ pub enum Error {
/// Transaction gas price
got: U256,
},
/// Transaction has too low fee
/// (there is already a transaction with the same sender-nonce but higher gas price)
TooCheapToReplace {
/// previous transaction's gas price
prev: Option<U256>,
/// new transaction's gas price
new: Option<U256>,
},
/// Transaction's gas is below currently set minimal gas requirement.
InsufficientGas {
/// Minimal expected gas
@ -99,7 +104,10 @@ impl fmt::Display for Error {
let msg = match *self {
AlreadyImported => "Already imported".into(),
Old => "No longer valid".into(),
TooCheapToReplace => "Gas price too low to replace".into(),
TooCheapToReplace { prev, new } =>
format!("Gas price too low to replace, previous tx gas: {:?}, new tx gas: {:?}",
prev, new
),
LimitReached => "Transaction limit reached".into(),
InsufficientGasPrice { minimal, got } =>
format!("Insufficient gas price. Min={}, Given={}", minimal, got),

View File

@ -53,7 +53,11 @@ impl Default for Action {
impl rlp::Decodable for Action {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
if rlp.is_empty() {
Ok(Action::Create)
if rlp.is_data() {
Ok(Action::Create)
} else {
Err(DecoderError::RlpExpectedToBeData)
}
} else {
Ok(Action::Call(rlp.as_val()?))
}
@ -572,6 +576,20 @@ mod tests {
assert_eq!(t.chain_id(), None);
}
#[test]
fn empty_atom_as_create_action() {
let empty_atom = [0x80];
let action: Action = rlp::decode(&empty_atom).unwrap();
assert_eq!(action, Action::Create);
}
#[test]
fn empty_list_as_create_action_rejected() {
let empty_list = [0xc0];
let action: Result<Action, DecoderError> = rlp::decode(&empty_list);
assert_eq!(action, Err(DecoderError::RlpExpectedToBeData));
}
#[test]
fn signing_eip155_zero_chainid() {
use ethkey::{Random, Generator};

View File

@ -5,12 +5,9 @@ version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
byteorder = "1.0"
parity-bytes = "0.1"
ethereum-types = "0.4"
trie-db = "0.11.0"
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
log = "0.4"
ethjson = { path = "../../json" }
rlp = { version = "0.3.0", features = ["ethereum"] }
keccak-hash = "0.1"

View File

@ -65,7 +65,7 @@ impl From<ethjson::vm::Env> for EnvInfo {
fn from(e: ethjson::vm::Env) -> Self {
let number = e.number.into();
EnvInfo {
number: number,
number,
author: e.author.into(),
difficulty: e.difficulty.into(),
gas_limit: e.gas_limit.into(),

View File

@ -144,6 +144,9 @@ pub trait Ext {
/// Returns environment info.
fn env_info(&self) -> &EnvInfo;
/// Returns the chain ID of the blockchain
fn chain_id(&self) -> u64;
/// Returns current depth of execution.
///
/// If contract A calls contract B, and contract B calls C,
@ -160,8 +163,12 @@ pub trait Ext {
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false }
/// Prepare to trace an operation. Passthrough for the VM trace.
/// For each call of `trace_prepare_execute` either `trace_failed` or `trace_executed` MUST be called.
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256, _mem_written: Option<(usize, usize)>, _store_written: Option<(U256, U256)>) {}
/// Trace the execution failure of a single instruction.
fn trace_failed(&mut self) {}
/// Trace the finalised execution of a single instruction.
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {}

View File

@ -22,7 +22,6 @@ extern crate ethjson;
extern crate rlp;
extern crate keccak_hash as hash;
extern crate patricia_trie_ethereum as ethtrie;
extern crate trie_db as trie;
mod action_params;
mod call_type;

View File

@ -84,7 +84,7 @@ pub struct Schedule {
pub tx_create_gas: usize,
/// Additional cost for empty data transaction
pub tx_data_zero_gas: usize,
/// Aditional cost for non-empty data transaction
/// Additional cost for non-empty data transaction
pub tx_data_non_zero_gas: usize,
/// Gas price for copying memory
pub copy_gas: usize,
@ -115,6 +115,8 @@ pub struct Schedule {
pub have_return_data: bool,
/// SHL, SHR, SAR opcodes enabled.
pub have_bitwise_shifting: bool,
/// CHAINID opcode enabled.
pub have_chain_id: bool,
/// Kill basic accounts below this balance if touched.
pub kill_dust: CleanDustMode,
/// Enable EIP-1283 rules
@ -209,6 +211,7 @@ impl Schedule {
have_revert: false,
have_return_data: false,
have_bitwise_shifting: false,
have_chain_id: false,
have_extcodehash: false,
stack_limit: 1024,
max_depth: 1024,
@ -275,6 +278,14 @@ impl Schedule {
schedule
}
/// Schedule for the Istanbul fork of the Ethereum main net.
pub fn new_istanbul() -> Schedule {
let mut schedule = Self::new_constantinople();
schedule.have_chain_id = true;
schedule.tx_data_non_zero_gas = 16;
schedule
}
fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule {
Schedule {
exceptional_failed_code_deposit: efcd,
@ -283,6 +294,7 @@ impl Schedule {
have_revert: false,
have_return_data: false,
have_bitwise_shifting: false,
have_chain_id: false,
have_extcodehash: false,
stack_limit: 1024,
max_depth: 1024,

View File

@ -67,6 +67,8 @@ pub struct FakeExt {
pub balances: HashMap<Address, U256>,
pub tracing: bool,
pub is_static: bool,
chain_id: u64,
}
// similar to the normal `finalize` function, but ignoring NeedsReturn.
@ -98,11 +100,24 @@ impl FakeExt {
ext
}
/// New fake externalities with Istanbul schedule rules
pub fn new_istanbul() -> Self {
let mut ext = FakeExt::default();
ext.schedule = Schedule::new_istanbul();
ext
}
/// Alter fake externalities to allow wasm
pub fn with_wasm(mut self) -> Self {
self.schedule.wasm = Some(Default::default());
self
}
/// Set chain ID
pub fn with_chain_id(mut self, chain_id: u64) -> Self {
self.chain_id = chain_id;
self
}
}
impl Ext for FakeExt {
@ -200,7 +215,7 @@ impl Ext for FakeExt {
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()> {
self.logs.push(FakeLogEntry {
topics: topics,
topics,
data: data.to_vec()
});
Ok(())
@ -223,6 +238,10 @@ impl Ext for FakeExt {
&self.info
}
fn chain_id(&self) -> u64 {
self.chain_id
}
fn depth(&self) -> usize {
self.depth
}

View File

@ -22,7 +22,7 @@ extern crate rlp;
extern crate ethcore;
extern crate parity_bytes as bytes;
extern crate ethereum_types;
extern crate jsonrpc_core as core;
extern crate jsonrpc_core;
extern crate jsonrpc_http_server as http;
pub mod error;
@ -32,8 +32,8 @@ use std::thread;
use std::sync::{mpsc, Arc};
use std::net::{SocketAddr, IpAddr};
use core::futures::future::{self, FutureResult};
use core::futures::{self, Future};
use jsonrpc_core::futures::future::{self, FutureResult};
use jsonrpc_core::futures::{self, Future};
use ethcore::client::BlockChainClient;
use http::hyper::{self, server, Method, StatusCode, Body,
header::{self, HeaderValue},
@ -51,19 +51,19 @@ pub struct IpfsHandler {
/// Hostnames allowed in the `Host` request header
allowed_hosts: Option<Vec<Host>>,
/// Reference to the Blockchain Client
client: Arc<BlockChainClient>,
client: Arc<dyn BlockChainClient>,
}
impl IpfsHandler {
pub fn client(&self) -> &BlockChainClient {
pub fn client(&self) -> &dyn BlockChainClient {
&*self.client
}
pub fn new(cors: DomainsValidation<AccessControlAllowOrigin>, hosts: DomainsValidation<Host>, client: Arc<BlockChainClient>) -> Self {
pub fn new(cors: DomainsValidation<AccessControlAllowOrigin>, hosts: DomainsValidation<Host>, client: Arc<dyn BlockChainClient>) -> Self {
IpfsHandler {
cors_domains: cors.into(),
allowed_hosts: hosts.into(),
client: client,
client,
}
}
pub fn on_request(&self, req: hyper::Request<Body>) -> (Option<HeaderValue>, Out) {
@ -154,7 +154,7 @@ pub fn start_server(
interface: String,
cors: DomainsValidation<AccessControlAllowOrigin>,
hosts: DomainsValidation<Host>,
client: Arc<BlockChainClient>
client: Arc<dyn BlockChainClient>
) -> Result<Listening, ServerError> {
let ip: IpAddr = interface.parse().map_err(|_| ServerError::InvalidInterface)?;
@ -182,12 +182,12 @@ pub fn start_server(
};
let server = server_bldr
.serve(new_service)
.map_err(|_| ())
.select(shutdown_signal.map_err(|_| ()))
.then(|_| Ok(()));
.serve(new_service)
.map_err(|_| ())
.select(shutdown_signal.map_err(|_| ()))
.then(|_| Ok(()));
hyper::rt::run(server);
hyper::rt::run(server);
send(Ok(()));
});

View File

@ -18,6 +18,9 @@
use uint::Uint;
/// Price per round of Blake2 compression.
pub type Blake2F = u64;
/// Linear pricing.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
@ -36,6 +39,16 @@ pub struct Modexp {
pub divisor: usize,
}
/// Pricing for constant alt_bn128 operations (ECADD and ECMUL)
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct AltBn128ConstOperations {
/// price
pub price: usize,
/// EIP 1108 transition price
pub eip1108_transition_price: usize,
}
/// Pricing for alt_bn128_pairing.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
@ -44,6 +57,10 @@ pub struct AltBn128Pairing {
pub base: usize,
/// Price per point pair.
pub pair: usize,
/// EIP 1108 transition base price
pub eip1108_transition_base: usize,
/// EIP 1108 transition price per point pair
pub eip1108_transition_pair: usize,
}
/// Pricing variants.
@ -51,12 +68,16 @@ pub struct AltBn128Pairing {
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")]
pub enum Pricing {
/// Pricing for Blake2 compression function: each call costs the same amount per round.
Blake2F(Blake2F),
/// Linear pricing.
Linear(Linear),
/// Pricing for modular exponentiation.
Modexp(Modexp),
/// Pricing for alt_bn128_pairing exponentiation.
AltBn128Pairing(AltBn128Pairing),
/// Pricing for constant alt_bn128 operations
AltBn128ConstOperations(AltBn128ConstOperations),
}
/// Spec builtin.
@ -69,6 +90,8 @@ pub struct Builtin {
pub pricing: Pricing,
/// Activation block.
pub activate_at: Option<Uint>,
/// EIP 1108
pub eip1108_transition: Option<Uint>,
}
#[cfg(test)]
@ -89,6 +112,19 @@ mod tests {
assert!(deserialized.activate_at.is_none());
}
#[test]
fn deserialization_blake2_f_builtin() {
let s = r#"{
"name": "blake2_f",
"activate_at": "0xffffff",
"pricing": { "blake2_f": 123 }
}"#;
let deserialized: Builtin = serde_json::from_str(s).unwrap();
assert_eq!(deserialized.name, "blake2_f");
assert_eq!(deserialized.pricing, Pricing::Blake2F(123));
assert!(deserialized.activate_at.is_some());
}
#[test]
fn activate_at() {
let s = r#"{

View File

@ -94,6 +94,10 @@ pub struct Params {
/// See `CommonParams` docs.
pub eip1014_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip1344_transition: Option<Uint>,
/// See `CommonParams` docs.
pub eip2028_transition: Option<Uint>,
/// See `CommonParams` docs.
pub dust_protection_transition: Option<Uint>,
/// See `CommonParams` docs.
pub nonce_cap_increment: Option<Uint>,

View File

@ -32,7 +32,7 @@ parking_lot = "0.7"
price-info = { path = "./price-info", optional = true }
rlp = { version = "0.3.0", features = ["ethereum"] }
trace-time = "0.1"
transaction-pool = "2.0"
transaction-pool = "2.0.1"
[dev-dependencies]
env_logger = "0.5"

View File

@ -587,7 +587,7 @@ fn convert_error<H: fmt::Debug + fmt::LowerHex>(err: txpool::Error<H>) -> transa
match err {
Error::AlreadyImported(..) => transaction::Error::AlreadyImported,
Error::TooCheapToEnter(..) => transaction::Error::LimitReached,
Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace
Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace { prev: None, new: None }
}
}

View File

@ -71,6 +71,20 @@ where
let old_score = (old.priority(), old.gas_price());
let new_score = (new.priority(), new.gas_price());
if new_score > old_score {
// Check if this is a replacement transaction.
//
// With replacement transactions we can safely return `InsertNew` here, because
// we don't need to remove `old` (worst transaction in the pool) since `new` will replace
// some other transaction in the pool so we will never go above limit anyway.
if let Some(txs) = new.pooled_by_sender {
if let Ok(index) = txs.binary_search_by(|old| self.scoring.compare(old, new)) {
return match self.scoring.choose(&txs[index], new) {
Choice::ReplaceOld => Choice::InsertNew,
choice => choice,
}
}
}
let state = &self.client;
// calculate readiness based on state nonce + pooled txs from same sender
let is_ready = |replace: &ReplaceTransaction<T>| {
@ -412,4 +426,88 @@ mod tests {
assert_eq!(replace.should_replace(&old, &new), ReplaceOld);
}
#[test]
fn should_accept_local_tx_with_same_sender_and_nonce_with_better_gas_price() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(1);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
// current transaction is ready
let old_tx = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.signed().verified()
};
let new_sender = Random.generate().unwrap();
let tx_new_ready_1 = local_tx_verified(Tx {
nonce: 1,
gas_price: 1,
..Default::default()
}, &new_sender);
let tx_new_ready_2 = local_tx_verified(Tx {
nonce: 1,
gas_price: 2, // same nonce, higher gas price
..Default::default()
}, &new_sender);
let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old_tx) };
let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_2) };
let pooled_txs = [
txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_1) },
];
let old = ReplaceTransaction::new(&old_tx, None);
let new = ReplaceTransaction::new(&new_tx, Some(&pooled_txs));
assert_eq!(replace.should_replace(&old, &new), InsertNew);
}
#[test]
fn should_reject_local_tx_with_same_sender_and_nonce_with_worse_gas_price() {
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
let client = TestClient::new().with_nonce(1);
let replace = ReplaceByScoreAndReadiness::new(scoring, client);
// current transaction is ready
let old_tx = {
let tx = Tx {
nonce: 1,
gas_price: 1,
..Default::default()
};
tx.signed().verified()
};
let new_sender = Random.generate().unwrap();
let tx_new_ready_1 = local_tx_verified(Tx {
nonce: 1,
gas_price: 2,
..Default::default()
}, &new_sender);
let tx_new_ready_2 = local_tx_verified(Tx {
nonce: 1,
gas_price: 1, // same nonce, lower gas price
..Default::default()
}, &new_sender);
let old_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(old_tx) };
let new_tx = txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_2) };
let pooled_txs = [
txpool::Transaction { insertion_id: 0, transaction: Arc::new(tx_new_ready_1) },
];
let old = ReplaceTransaction::new(&old_tx, None);
let new = ReplaceTransaction::new(&new_tx, Some(&pooled_txs));
assert_eq!(replace.should_replace(&old, &new), RejectNew);
}
}

View File

@ -91,10 +91,10 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() {
// then
assert_eq!(res, vec![Ok(()), Ok(())]);
assert_eq!(res2, vec![
// The error here indicates reaching the limit
// and minimal effective gas price taken into account.
Err(transaction::Error::InsufficientGasPrice { minimal: 2.into(), got: 1.into() }),
Ok(())
// The error here indicates reaching the limit
// and minimal effective gas price taken into account.
Err(transaction::Error::TooCheapToReplace { prev: Some(2.into()), new: Some(1.into()) }),
Ok(())
]);
assert_eq!(txq.status().status.transaction_count, 3);
// tx2 transaction got dropped because of limit
@ -585,7 +585,7 @@ fn should_not_replace_same_transaction_if_the_fee_is_less_than_minimal_bump() {
let res = txq.import(client.clone(), vec![tx2, tx4].local());
// then
assert_eq!(res, vec![Err(transaction::Error::TooCheapToReplace), Ok(())]);
assert_eq!(res, vec![Err(transaction::Error::TooCheapToReplace { prev: None, new: None }), Ok(())]);
assert_eq!(txq.status().status.transaction_count, 2);
assert_eq!(txq.pending(client.clone(), PendingSettings::all_prioritized(0, 0))[0].signed().gas_price, U256::from(20));
assert_eq!(txq.pending(client.clone(), PendingSettings::all_prioritized(0, 0))[1].signed().gas_price, U256::from(2));
@ -1027,9 +1027,9 @@ fn should_reject_early_in_case_gas_price_is_less_than_min_effective() {
let client = TestClient::new();
let tx1 = Tx::default().signed().unverified();
let res = txq.import(client.clone(), vec![tx1]);
assert_eq!(res, vec![Err(transaction::Error::InsufficientGasPrice {
minimal: 2.into(),
got: 1.into(),
assert_eq!(res, vec![Err(transaction::Error::TooCheapToReplace {
prev: Some(2.into()),
new: Some(1.into()),
})]);
assert!(!client.was_verification_triggered());

View File

@ -231,9 +231,9 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
tx.gas_price(),
vtx.transaction.gas_price,
);
bail!(transaction::Error::InsufficientGasPrice {
minimal: vtx.transaction.gas_price,
got: *tx.gas_price(),
return Err(transaction::Error::TooCheapToReplace {
prev: Some(vtx.transaction.gas_price),
new: Some(*tx.gas_price()),
});
}
}

View File

@ -300,7 +300,7 @@ usage! {
ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(),
"--chain=[CHAIN]",
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, volta, ewc, expanse, musicoin, ellaism, mix, callisto, morden, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, or dev.",
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, xdai, volta, ewc, expanse, musicoin, ellaism, mix, callisto, morden, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, or dev.",
ARG arg_keys_path: (String) = "$BASE/keys", or |c: &Config| c.parity.as_ref()?.keys_path.clone(),
"--keys-path=[PATH]",

View File

@ -1,3 +1,6 @@
Parity Ethereum Client.
By Wood/Paronyan/Kotewicz/Drwięga/Volf et al.
Copyright 2015-2019 Parity Technologies (UK) Ltd.
By Wood/Paronyan/Kotewicz/Drwięga/Volf/Greeff
Habermeier/Czaban/Gotchac/Redman/Nikolsky
Schoedon/Tang/Adolfsson/Silva/Palm/Hirsz et al.
Copyright 2015-2019 Parity Technologies (UK) Ltd.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.

View File

@ -1,9 +1,10 @@
Parity Ethereum
Parity Ethereum Client.
version {}
Copyright 2015-2019 Parity Technologies (UK) Ltd.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
By Wood/Paronyan/Kotewicz/Drwięga/Volf
Habermeier/Czaban/Greeff/Gotchac/Redmann
By Wood/Paronyan/Kotewicz/Drwięga/Volf/Greeff
Habermeier/Czaban/Gotchac/Redman/Nikolsky
Schoedon/Tang/Adolfsson/Silva/Palm/Hirsz et al.

View File

@ -36,6 +36,7 @@ pub enum SpecType {
Foundation,
Classic,
Poanet,
Xdai,
Volta,
Ewc,
Expanse,
@ -68,6 +69,7 @@ impl str::FromStr for SpecType {
"ethereum" | "frontier" | "homestead" | "byzantium" | "foundation" | "mainnet" => SpecType::Foundation,
"classic" | "frontier-dogmatic" | "homestead-dogmatic" => SpecType::Classic,
"poanet" | "poacore" => SpecType::Poanet,
"xdai" => SpecType::Xdai,
"volta" => SpecType::Volta,
"ewc" | "energyweb" => SpecType::Ewc,
"expanse" => SpecType::Expanse,
@ -95,6 +97,7 @@ impl fmt::Display for SpecType {
SpecType::Foundation => "foundation",
SpecType::Classic => "classic",
SpecType::Poanet => "poanet",
SpecType::Xdai => "xdai",
SpecType::Volta => "volta",
SpecType::Ewc => "energyweb",
SpecType::Expanse => "expanse",
@ -122,6 +125,7 @@ impl SpecType {
SpecType::Foundation => Ok(ethereum::new_foundation(params)),
SpecType::Classic => Ok(ethereum::new_classic(params)),
SpecType::Poanet => Ok(ethereum::new_poanet(params)),
SpecType::Xdai => Ok(ethereum::new_xdai(params)),
SpecType::Volta => Ok(ethereum::new_volta(params)),
SpecType::Ewc => Ok(ethereum::new_ewc(params)),
SpecType::Expanse => Ok(ethereum::new_expanse(params)),
@ -380,6 +384,7 @@ mod tests {
assert_eq!(SpecType::Classic, "homestead-dogmatic".parse().unwrap());
assert_eq!(SpecType::Poanet, "poanet".parse().unwrap());
assert_eq!(SpecType::Poanet, "poacore".parse().unwrap());
assert_eq!(SpecType::Xdai, "xdai".parse().unwrap());
assert_eq!(SpecType::Volta, "volta".parse().unwrap());
assert_eq!(SpecType::Ewc, "ewc".parse().unwrap());
assert_eq!(SpecType::Ewc, "energyweb".parse().unwrap());
@ -411,6 +416,7 @@ mod tests {
assert_eq!(format!("{}", SpecType::Foundation), "foundation");
assert_eq!(format!("{}", SpecType::Classic), "classic");
assert_eq!(format!("{}", SpecType::Poanet), "poanet");
assert_eq!(format!("{}", SpecType::Xdai), "xdai");
assert_eq!(format!("{}", SpecType::Volta), "volta");
assert_eq!(format!("{}", SpecType::Ewc), "energyweb");
assert_eq!(format!("{}", SpecType::Expanse), "expanse");

View File

@ -70,7 +70,7 @@ ethcore-network = { path = "../util/network" }
fake-fetch = { path = "../util/fake-fetch" }
macros = { path = "../util/macros" }
pretty_assertions = "0.1"
transaction-pool = "2.0"
transaction-pool = "2.0.1"
[features]
accounts = ["ethcore-accounts"]

View File

@ -408,8 +408,11 @@ pub fn transaction_message(error: &TransactionError) -> String {
match *error {
AlreadyImported => "Transaction with the same hash was already imported.".into(),
Old => "Transaction nonce is too low. Try incrementing the nonce.".into(),
TooCheapToReplace => {
"Transaction gas price is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce.".into()
TooCheapToReplace { prev, new } => {
format!("Transaction gas price {} is too low. There is another transaction with same nonce in the queue{}. Try increasing the gas price or incrementing the nonce.",
new.map(|gas| format!("{}wei", gas)).unwrap_or("supplied".into()),
prev.map(|gas| format!(" with gas price: {}wei", gas)).unwrap_or("".into())
)
}
LimitReached => {
"There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into()

View File

@ -7,7 +7,7 @@ echo "__________Register Release__________"
DATA="secret=$RELEASES_SECRET"
echo "Pushing release to Mainnet"
./tools/safe-curl.sh $DATA "http://update.parity.io:1337/push-release/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$CI_COMMIT_SHA"
./tools/safe-curl.sh $DATA "https://update.parity.io/push-release/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$CI_COMMIT_SHA"
cd artifacts
ls -l | sort -k9
@ -26,7 +26,7 @@ do
case $DIR in
x86_64* )
DATA="commit=$CI_COMMIT_SHA&sha3=$sha3&filename=parity$WIN&secret=$RELEASES_SECRET"
../../tools/safe-curl.sh $DATA "http://update.parity.io:1337/push-build/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$DIR"
../../tools/safe-curl.sh $DATA "https://update.parity.io/push-build/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}/$DIR"
;;
esac
cd ..

14
util/EIP-152/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "eip-152"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
repository = "https://github.com/paritytech/parity-ethereum"
documentation = "https://docs.rs/eip-152"
readme = "README.md"
description = "eip-512 blake2 F compression function"
keywords = ["eip-152", "eip152", "eip"]
license = "GPL-3.0"
edition = "2018"
[dependencies]
rustc-hex = "2.0.1"

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

@ -0,0 +1,192 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
/// The precomputed values for BLAKE2b [from the spec](https://tools.ietf.org/html/rfc7693#section-2.7)
/// There are 10 16-byte arrays - one for each round
/// the entries are calculated from the sigma constants.
const SIGMA: [[usize; 16]; 10] = [
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
[11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
[ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
[ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
[ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
[12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
[13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],
[ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],
[10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],
];
/// IV is the initialization vector for BLAKE2b. See https://tools.ietf.org/html/rfc7693#section-2.6
/// for details.
const IV: [u64; 8] = [
0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
];
#[inline(always)]
/// The G mixing function. See https://tools.ietf.org/html/rfc7693#section-3.1
fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) {
v[a] = v[a].wrapping_add(v[b]).wrapping_add(x);
v[d] = (v[d] ^ v[a]).rotate_right(32);
v[c] = v[c].wrapping_add(v[d]);
v[b] = (v[b] ^ v[c]).rotate_right(24);
v[a] = v[a].wrapping_add(v[b]).wrapping_add(y);
v[d] = (v[d] ^ v[a]).rotate_right(16);
v[c] = v[c].wrapping_add(v[d]);
v[b] = (v[b] ^ v[c]).rotate_right(63);
}
/// The Blake2 compression function F. See https://tools.ietf.org/html/rfc7693#section-3.2
/// Takes as an argument the state vector `h`, message block vector `m`, offset counter `t`, final
/// block indicator flag `f`, and number of rounds `rounds`. The state vector provided as the first
/// parameter is modified by the function.
pub fn compress(h: &mut [u64; 8], m: [u64; 16], t: [u64; 2], f: bool, rounds: usize) {
let mut v = [0u64; 16];
v[..h.len()].copy_from_slice(h); // First half from state.
v[h.len()..].copy_from_slice(&IV); // Second half from IV.
v[12] ^= t[0];
v[13] ^= t[1];
if f {
v[14] = !v[14] // Invert all bits if the last-block-flag is set.
}
for i in 0..rounds {
// Message word selection permutation for this round.
let s = &SIGMA[i % 10];
g(&mut v, 0, 4, 8, 12, m[s[0]], m[s[1]]);
g(&mut v, 1, 5, 9, 13, m[s[2]], m[s[3]]);
g(&mut v, 2, 6, 10, 14, m[s[4]], m[s[5]]);
g(&mut v, 3, 7, 11, 15, m[s[6]], m[s[7]]);
g(&mut v, 0, 5, 10, 15, m[s[8]], m[s[9]]);
g(&mut v, 1, 6, 11, 12, m[s[10]], m[s[11]]);
g(&mut v, 2, 7, 8, 13, m[s[12]], m[s[13]]);
g(&mut v, 3, 4, 9, 14, m[s[14]], m[s[15]]);
}
for i in 0..8 {
h[i] ^= v[i] ^ v[i + 8];
}
}
#[cfg(test)]
mod tests {
use crate::compress;
use rustc_hex::FromHex;
#[test]
fn test_blake2_f() {
// test from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#example-usage-in-solidity
let mut h_in = [
0x6a09e667f2bdc948_u64, 0xbb67ae8584caa73b_u64,
0x3c6ef372fe94f82b_u64, 0xa54ff53a5f1d36f1_u64,
0x510e527fade682d1_u64, 0x9b05688c2b3e6c1f_u64,
0x1f83d9abfb41bd6b_u64, 0x5be0cd19137e2179_u64,
];
let m = [
0x0000000000636261_u64, 0x0000000000000000_u64, 0x0000000000000000_u64,
0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64,
0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64,
0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64,
0x0000000000000000_u64, 0x0000000000000000_u64, 0x0000000000000000_u64,
0x0000000000000000_u64,
];
let c = [3, 0];
let f = true;
let rounds = 12;
let h_out: [u64; 8] = [
0x0D4D1C983FA580BA_u64, 0xE9F6129FB697276A_u64, 0xB7C45A68142F214C_u64,
0xD1A2FFDB6FBB124B_u64, 0x2D79AB2A39C5877D_u64, 0x95CC3345DED552C2_u64,
0x5A92F1DBA88AD318_u64, 0x239900D4ED8623B9_u64,
];
compress(&mut h_in, m, c, f, rounds);
assert_eq!(h_in, h_out);
}
fn to_u64_slice(vec: &[u8], slice: &mut [u64]) {
vec.chunks(8).enumerate().for_each(|(index, val)| {
slice[index] = u64::from_le_bytes([val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]])
})
}
#[test]
fn test_vectors_from_eip() {
let vec = vec![
(
// Test vector 4
"0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b",
),
( // test vector 5
"0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923",
),
(
// Test vector 6
"0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000",
"75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735",
),
(
// Test vector 7
"0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421",
),
// Test vector 8 u32::MAX rounds too slow to run
// (
// "ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
// "fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615",
// ),
];
for (hex, output) in vec {
let hex = hex;
let bytes: Vec<u8> = hex.from_hex().unwrap();
assert_eq!(bytes.len(), 213);
let mut h = [0u64; 8];
let mut m = [0u64; 16];
let mut t = [0u64; 2];
let rounds = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
let f = match bytes[212] {
1 => true,
0 => false,
_ => unreachable!()
};
to_u64_slice(&bytes[4..68], &mut h);
to_u64_slice(&bytes[68..196], &mut m);
to_u64_slice(&bytes[196..212], &mut t);
compress(&mut h, m, t, f, rounds as usize);
let output: Vec<u8> = output.from_hex().unwrap();
let mut out = [0u64; 8];
to_u64_slice(&output[..], &mut out);
assert_eq!(out, h);
}
}
}

View File

@ -31,8 +31,8 @@ use ethbloom::Bloom;
fn blooms_filter_1_million_ok(b: &mut Bencher) {
let tempdir = TempDir::new("").unwrap();
let database = Database::open(tempdir.path()).unwrap();
database.insert_blooms(999_999, iter::once(&Bloom::from(0))).unwrap();
let bloom = Bloom::from(0x001);
database.insert_blooms(999_999, iter::once(&Bloom::zero())).unwrap();
let bloom = Bloom::from_low_u64_be(0x001);
database.insert_blooms(200_000, iter::once(&bloom)).unwrap();
database.insert_blooms(400_000, iter::once(&bloom)).unwrap();
database.insert_blooms(600_000, iter::once(&bloom)).unwrap();
@ -48,9 +48,9 @@ fn blooms_filter_1_million_ok(b: &mut Bencher) {
fn blooms_filter_1_million_miss(b: &mut Bencher) {
let tempdir = TempDir::new("").unwrap();
let database = Database::open(tempdir.path()).unwrap();
database.insert_blooms(999_999, iter::once(&Bloom::from(0))).unwrap();
let bloom = Bloom::from(0x001);
let bad_bloom = Bloom::from(0x0001);
database.insert_blooms(999_999, iter::once(&Bloom::zero())).unwrap();
let bloom = Bloom::from_low_u64_be(0x001);
let bad_bloom = Bloom::from_low_u64_be(0x0001);
database.insert_blooms(200_000, iter::once(&bloom)).unwrap();
database.insert_blooms(400_000, iter::once(&bloom)).unwrap();
database.insert_blooms(600_000, iter::once(&bloom)).unwrap();
@ -66,9 +66,9 @@ fn blooms_filter_1_million_miss(b: &mut Bencher) {
fn blooms_filter_1_million_miss_and_ok(b: &mut Bencher) {
let tempdir = TempDir::new("").unwrap();
let database = Database::open(tempdir.path()).unwrap();
database.insert_blooms(999_999, iter::once(&Bloom::from(0))).unwrap();
let bloom = Bloom::from(0x001);
let bad_bloom = Bloom::from(0x0001);
database.insert_blooms(999_999, iter::once(&Bloom::zero())).unwrap();
let bloom = Bloom::from_low_u64_be(0x001);
let bad_bloom = Bloom::from_low_u64_be(0x0001);
database.insert_blooms(200_000, iter::once(&bloom)).unwrap();
database.insert_blooms(400_000, iter::once(&bloom)).unwrap();
database.insert_blooms(600_000, iter::once(&bloom)).unwrap();

View File

@ -21,7 +21,7 @@ use ethbloom;
use file::{File, FileIterator};
fn other_io_err<E>(e: E) -> io::Error where E: Into<Box<error::Error + Send + Sync>> {
fn other_io_err<E>(e: E) -> io::Error where E: Into<Box<dyn error::Error + Send + Sync>> {
io::Error::new(io::ErrorKind::Other, e)
}

View File

@ -254,6 +254,8 @@ struct ProtocolTimer {
}
/// Root IO handler. Manages protocol handlers, IO timers and network connections.
///
/// NOTE: must keep the lock in order of: reserved_nodes (rwlock) -> session (mutex, from sessions)
pub struct Host {
pub info: RwLock<HostInfo>,
udp_socket: Mutex<Option<UdpSocket>>,
@ -715,12 +717,13 @@ impl Host {
let session_result = session.lock().readable(io, &self.info.read());
match session_result {
Err(e) => {
let reserved_nodes = self.reserved_nodes.read();
let s = session.lock();
trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e);
match *e.kind() {
ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => {
if let Some(id) = s.id() {
if !self.reserved_nodes.read().contains(id) {
if !reserved_nodes.contains(id) {
let mut nodes = self.nodes.write();
nodes.note_failure(&id);
nodes.mark_as_useless(id);
@ -734,6 +737,7 @@ impl Host {
},
Ok(SessionData::Ready) => {
let (_, egress_count, ingress_count) = self.session_count();
let reserved_nodes = self.reserved_nodes.read();
let mut s = session.lock();
let (min_peers, mut max_peers, reserved_only, self_id) = {
let info = self.info.read();
@ -758,7 +762,7 @@ impl Host {
if reserved_only ||
(s.info.originated && egress_count > min_peers) ||
(!s.info.originated && ingress_count > max_ingress) {
if !self.reserved_nodes.read().contains(&id) {
if !reserved_nodes.contains(&id) {
// only proceed if the connecting peer is reserved.
trace!(target: "network", "Disconnecting non-reserved peer {:?}", id);
s.disconnect(io, DisconnectReason::TooManyPeers);
@ -973,7 +977,8 @@ impl Host {
for i in to_remove {
trace!(target: "network", "Removed from node table: {}", i);
}
self.nodes.write().update(node_changes, &*self.reserved_nodes.read());
let reserved_nodes = self.reserved_nodes.read();
self.nodes.write().update(node_changes, &*reserved_nodes);
}
pub fn with_context<F>(&self, protocol: ProtocolId, io: &IoContext<NetworkIoMessage>, action: F) where F: FnOnce(&NetworkContextTrait) {
@ -1059,8 +1064,9 @@ impl IoHandler<NetworkIoMessage> for Host {
},
NODE_TABLE => {
trace!(target: "network", "Refreshing node table");
self.nodes.write().clear_useless();
self.nodes.write().save();
let mut nodes = self.nodes.write();
nodes.clear_useless();
nodes.save();
},
_ => match self.timers.read().get(&token).cloned() {
Some(timer) => match self.handlers.read().get(&timer.protocol).cloned() {

View File

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