Compare commits
94 Commits
main
...
v1.8.10-ci
Author | SHA1 | Date | |
---|---|---|---|
|
e5b1bbe886 | ||
|
549192f1eb | ||
|
857d7daf37 | ||
|
5e3e50c420 | ||
|
a47623d3dc | ||
|
b8ec7d583f | ||
|
7fb752e6a7 | ||
|
71bf7f5ed5 | ||
|
f65003c630 | ||
|
ceb23638fc | ||
|
24ab53245b | ||
|
1952d05d9c | ||
|
98cccd5b26 | ||
|
fd07b608bd | ||
|
944ace3b61 | ||
|
c697e40e84 | ||
|
b322af35bc | ||
|
987d26ac46 | ||
|
143d4840c7 | ||
|
fae7cf6b41 | ||
|
d8c1372b7c | ||
|
28821142e6 | ||
|
791d944a53 | ||
|
9e2b3308d4 | ||
|
680cc9c0c3 | ||
|
346c80ef11 | ||
|
efb310f251 | ||
|
1ede2fbed2 | ||
|
31ef44d718 | ||
|
19fc9fcc58 | ||
|
835dcaec2a | ||
|
2c93b0fdf7 | ||
|
e322fd824b | ||
|
366320fb8d | ||
|
29dc3ca2dd | ||
|
5f590a0df5 | ||
|
e3d32a4abb | ||
|
9c7359e343 | ||
|
628f0878b1 | ||
|
a835c13e6b | ||
|
abcfcacf95 | ||
|
9abc6bd7d1 | ||
|
5e775f3e27 | ||
|
1eab85afc6 | ||
|
662416f05b | ||
|
00b5d30d33 | ||
|
2d051e4f79 | ||
|
a257827f27 | ||
|
c3727266e1 | ||
|
364bf48cef | ||
|
849e574c2c | ||
|
e93872e7bb | ||
|
61c3e1a2d6 | ||
|
54bae9a0f2 | ||
|
42dd3addea | ||
|
c74c8c1ac1 | ||
|
4e39c318aa | ||
|
03b1e9d8ba | ||
|
fdaedc8c00 | ||
|
d60fe51553 | ||
|
c7621b9bbf | ||
|
0ec35d9ac5 | ||
|
ef702b77dc | ||
|
a8cf4efc91 | ||
|
aeb43b6af0 | ||
|
dcdde49d91 | ||
|
b49c44a198 | ||
|
561e843207 | ||
|
6ad5d559ca | ||
|
91db3535f8 | ||
|
baa1223736 | ||
|
a2d5edb8f5 | ||
|
454b4518f2 | ||
|
303036cab0 | ||
|
b7e9152cc2 | ||
|
b1b5ffff95 | ||
|
067cbe78d2 | ||
|
1211c1f10c | ||
|
148ec3731c | ||
|
1b6588cb27 | ||
|
0e4a06d078 | ||
|
d470773fec | ||
|
8f0eb3e192 | ||
|
48c7e4ab8c | ||
|
8362bc7f2d | ||
|
284fc65c70 | ||
|
9882902f31 | ||
|
789c85561e | ||
|
18dff68278 | ||
|
d9a92c2bea | ||
|
2145388103 | ||
|
77d00e3dab | ||
|
aa6909ff99 | ||
|
0085d6a47b |
@ -9,7 +9,7 @@ trim_trailing_whitespace=true
|
||||
max_line_length=120
|
||||
insert_final_newline=true
|
||||
|
||||
[.travis.yml]
|
||||
[*.{yml,sh}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
tab_width=8
|
||||
|
548
.gitlab-ci.yml
548
.gitlab-ci.yml
@ -4,14 +4,15 @@ stages:
|
||||
- push-release
|
||||
- build
|
||||
variables:
|
||||
GIT_DEPTH: "3"
|
||||
SIMPLECOV: "true"
|
||||
RUST_BACKTRACE: "1"
|
||||
RUSTFLAGS: ""
|
||||
CARGOFLAGS: ""
|
||||
CI_SERVER_NAME: "GitLab CI"
|
||||
LIBSSL: "libssl1.0.0 (>=1.0.0)"
|
||||
cache:
|
||||
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
|
||||
key: "$CI_BUILD_STAGE-$CI_BUILD_REF_NAME"
|
||||
paths:
|
||||
- target
|
||||
untracked: true
|
||||
linux-stable:
|
||||
stage: build
|
||||
@ -23,77 +24,14 @@ linux-stable:
|
||||
- triggers
|
||||
script:
|
||||
- rustup default stable
|
||||
- cargo build -j $(nproc) --release --features final $CARGOFLAGS
|
||||
- cargo build -j $(nproc) --release -p evmbin
|
||||
- cargo build -j $(nproc) --release -p ethstore-cli
|
||||
- cargo build -j $(nproc) --release -p ethkey-cli
|
||||
- strip target/release/parity
|
||||
- strip target/release/parity-evm
|
||||
- strip target/release/ethstore
|
||||
- strip target/release/ethkey
|
||||
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||
- md5sum target/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh amd64
|
||||
- cp target/release/parity deb/usr/bin/parity
|
||||
- cp target/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- dpkg-deb -b deb "parity_"$VER"_amd64.deb"
|
||||
- md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity --body target/release/parity
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu
|
||||
# ARGUMENTS: 1. BUILD_PLATFORM (target for binaries) 2. PLATFORM (target for cargo) 3. ARC (architecture) 4. & 5. CC & CXX flags 6. binary identifier
|
||||
- scripts/gitlab-build.sh x86_64-unknown-linux-gnu x86_64-unknown-linux-gnu amd64 gcc g++ ubuntu
|
||||
tags:
|
||||
- rust
|
||||
- rust-stable
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
- target/release/parity-evm
|
||||
- target/release/ethstore
|
||||
- target/release/ethkey
|
||||
- parity.zip
|
||||
name: "stable-x86_64-unknown-linux-gnu_parity"
|
||||
linux-snap:
|
||||
stage: build
|
||||
image: parity/snapcraft:gitlab-ci
|
||||
only:
|
||||
- snap
|
||||
- beta
|
||||
- tags
|
||||
- triggers
|
||||
script:
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- cd snap
|
||||
- rm -rf *snap
|
||||
- sed -i 's/master/'"$VER"'/g' snapcraft.yaml
|
||||
- echo "Version:"$VER
|
||||
- snapcraft
|
||||
- ls
|
||||
- cp "parity_"$CI_BUILD"_REF_NAME_amd64.snap" "parity_"$VER"_amd64.snap"
|
||||
- md5sum "parity_"$VER"_amd64.snap" > "parity_"$VER"_amd64.snap.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.snap" --body "parity_"$VER"_amd64.snap"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.snap.md5" --body "parity_"$VER"_amd64.snap.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu
|
||||
tags:
|
||||
- rust
|
||||
- rust-stable
|
||||
artifacts:
|
||||
paths:
|
||||
- scripts/parity_*_amd64.snap
|
||||
name: "stable-x86_64-unknown-snap-gnu_parity"
|
||||
allow_failure: true
|
||||
linux-stable-debian:
|
||||
stage: build
|
||||
image: parity/rust-debian:gitlab-ci
|
||||
@ -103,81 +41,14 @@ linux-stable-debian:
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- cargo build -j $(nproc) --release --features final $CARGOFLAGS
|
||||
- cargo build -j $(nproc) --release -p evmbin
|
||||
- cargo build -j $(nproc) --release -p ethstore-cli
|
||||
- cargo build -j $(nproc) --release -p ethkey-cli
|
||||
- strip target/release/parity
|
||||
- strip target/release/parity-evm
|
||||
- strip target/release/ethstore
|
||||
- strip target/release/ethkey
|
||||
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||
- md5sum target/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh amd64
|
||||
- cp target/release/parity deb/usr/bin/parity
|
||||
- cp target/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- dpkg-deb -b deb "parity_"$VER"_amd64.deb"
|
||||
- md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/parity --body target/release/parity
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu
|
||||
- export LIBSSL="libssl1.1 (>=1.1.0)"
|
||||
- scripts/gitlab-build.sh x86_64-unknown-debian-gnu x86_64-unknown-linux-gnu amd64 gcc g++ debian
|
||||
tags:
|
||||
- rust
|
||||
- rust-debian
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
- parity.zip
|
||||
name: "stable-x86_64-unknown-debian-gnu_parity"
|
||||
linux-beta:
|
||||
stage: build
|
||||
image: parity/rust:gitlab-ci
|
||||
only:
|
||||
- beta
|
||||
- tags
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- rustup default beta
|
||||
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||
- strip target/release/parity
|
||||
tags:
|
||||
- rust
|
||||
- rust-beta
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
name: "beta-x86_64-unknown-linux-gnu_parity"
|
||||
allow_failure: true
|
||||
linux-nightly:
|
||||
stage: build
|
||||
image: parity/rust:gitlab-ci
|
||||
only:
|
||||
- beta
|
||||
- tags
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- rustup default nightly
|
||||
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||
- strip target/release/parity
|
||||
tags:
|
||||
- rust
|
||||
- rust-nightly
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
name: "nigthly-x86_64-unknown-linux-gnu_parity"
|
||||
allow_failure: true
|
||||
linux-centos:
|
||||
stage: build
|
||||
image: parity/rust-centos:gitlab-ci
|
||||
@ -187,42 +58,12 @@ linux-centos:
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- export CXX="g++"
|
||||
- export CC="gcc"
|
||||
- export PLATFORM=x86_64-unknown-centos-gnu
|
||||
- cargo build -j $(nproc) --release --features final $CARGOFLAGS
|
||||
- cargo build -j $(nproc) --release -p evmbin
|
||||
- cargo build -j $(nproc) --release -p ethstore-cli
|
||||
- cargo build -j $(nproc) --release -p ethkey-cli
|
||||
- strip target/release/parity
|
||||
- strip target/release/parity-evm
|
||||
- strip target/release/ethstore
|
||||
- strip target/release/ethkey
|
||||
- md5sum target/release/parity > parity.md5
|
||||
- md5sum target/release/parity-evm > parity-evm.md5
|
||||
- md5sum target/release/ethstore > ethstore.md5
|
||||
- md5sum target/release/ethkey > ethkey.md5
|
||||
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity --body target/release/parity
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity-evm --body target/release/parity-evm
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity-evm.md5 --body parity-evm.md5
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/ethstore --body target/release/ethstore
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/ethstore.md5 --body ethstore.md5
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/ethkey --body target/release/ethkey
|
||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/ethkey.md5 --body ethkey.md5
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- scripts/gitlab-build.sh x86_64-unknown-centos-gnu x86_64-unknown-linux-gnu x86_64 gcc g++ centos
|
||||
tags:
|
||||
- rust
|
||||
- rust-centos
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
- parity.zip
|
||||
name: "x86_64-unknown-centos-gnu_parity"
|
||||
linux-i686:
|
||||
stage: build
|
||||
@ -233,47 +74,13 @@ linux-i686:
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- export HOST_CC=gcc
|
||||
- export HOST_CXX=g++
|
||||
- export COMMIT=$(git rev-parse HEAD)
|
||||
- export PLATFORM=i686-unknown-linux-gnu
|
||||
- cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p evmbin
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethstore-cli
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethkey-cli
|
||||
- strip target/$PLATFORM/release/parity
|
||||
- strip target/$PLATFORM/release/parity-evm
|
||||
- strip target/$PLATFORM/release/ethstore
|
||||
- strip target/$PLATFORM/release/ethkey
|
||||
- strip target/$PLATFORM/release/parity
|
||||
- md5sum target/$PLATFORM/release/parity > parity.md5
|
||||
- export SHA3=$(target/$PLATFORM/release/parity tools hash target/$PLATFORM/release/parity)
|
||||
- sh scripts/deb-build.sh i386
|
||||
- cp target/$PLATFORM/release/parity deb/usr/bin/parity
|
||||
- cp target/$PLATFORM/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/$PLATFORM/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/$PLATFORM/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- dpkg-deb -b deb "parity_"$VER"_i386.deb"
|
||||
- md5sum "parity_"$VER"_i386.deb" > "parity_"$VER"_i386.deb.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/$PLATFORM/release/parity
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_i386.deb" --body "parity_"$VER"_i386.deb"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_i386.deb.md5" --body "parity_"$VER"_i386.deb.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- scripts/gitlab-build.sh i686-unknown-linux-gnu i686-unknown-linux-gnu i386 gcc g++ ubuntu
|
||||
tags:
|
||||
- rust
|
||||
- rust-i686
|
||||
artifacts:
|
||||
paths:
|
||||
- target/i686-unknown-linux-gnu/release/parity
|
||||
- parity.zip
|
||||
name: "i686-unknown-linux-gnu"
|
||||
allow_failure: true
|
||||
linux-armv7:
|
||||
stage: build
|
||||
image: parity/rust-armv7:gitlab-ci
|
||||
@ -283,55 +90,13 @@ linux-armv7:
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- export CC=arm-linux-gnueabihf-gcc
|
||||
- export CXX=arm-linux-gnueabihf-g++
|
||||
- export HOST_CC=gcc
|
||||
- export HOST_CXX=g++
|
||||
- export PLATFORM=armv7-unknown-linux-gnueabihf
|
||||
- rm -rf .cargo
|
||||
- mkdir -p .cargo
|
||||
- echo "[target.$PLATFORM]" >> .cargo/config
|
||||
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
||||
- cat .cargo/config
|
||||
- cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p evmbin
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethstore-cli
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethkey-cli
|
||||
- md5sum target/$PLATFORM/release/parity > parity.md5
|
||||
- export SHA3=$(target/$PLATFORM/release/parity tools hash target/$PLATFORM/release/parity)
|
||||
- sh scripts/deb-build.sh i386
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/parity
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/parity-evm
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/ethstore
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/ethkey
|
||||
- export SHA3=$(rhash --sha3-256 target/$PLATFORM/release/parity -p %h)
|
||||
- md5sum target/$PLATFORM/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh armhf
|
||||
- cp target/$PLATFORM/release/parity deb/usr/bin/parity
|
||||
- cp target/$PLATFORM/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/$PLATFORM/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/$PLATFORM/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- dpkg-deb -b deb "parity_"$VER"_armhf.deb"
|
||||
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/$PLATFORM/release/parity
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_armhf.deb" --body "parity_"$VER"_armhf.deb"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- scripts/gitlab-build.sh armv7-unknown-linux-gnueabihf armv7-unknown-linux-gnueabihf armhf arm-linux-gnueabihf-gcc arm-linux-gnueabihf-g++ ubuntu
|
||||
tags:
|
||||
- rust
|
||||
- rust-arm
|
||||
artifacts:
|
||||
paths:
|
||||
- target/armv7-unknown-linux-gnueabihf/release/parity
|
||||
- parity.zip
|
||||
name: "armv7_unknown_linux_gnueabihf_parity"
|
||||
allow_failure: true
|
||||
linux-arm:
|
||||
stage: build
|
||||
image: parity/rust-arm:gitlab-ci
|
||||
@ -341,52 +106,13 @@ linux-arm:
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- export CC=arm-linux-gnueabihf-gcc
|
||||
- export CXX=arm-linux-gnueabihf-g++
|
||||
- export HOST_CC=gcc
|
||||
- export HOST_CXX=g++
|
||||
- export PLATFORM=arm-unknown-linux-gnueabihf
|
||||
- rm -rf .cargo
|
||||
- mkdir -p .cargo
|
||||
- echo "[target.$PLATFORM]" >> .cargo/config
|
||||
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
||||
- cat .cargo/config
|
||||
- cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p evmbin
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethstore-cli
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethkey-cli
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/parity
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/parity-evm
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/ethstore
|
||||
- arm-linux-gnueabihf-strip target/$PLATFORM/release/ethkey
|
||||
- export SHA3=$(rhash --sha3-256 target/$PLATFORM/release/parity -p %h)
|
||||
- md5sum target/$PLATFORM/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh armhf
|
||||
- cp target/$PLATFORM/release/parity deb/usr/bin/parity
|
||||
- cp target/$PLATFORM/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/$PLATFORM/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/$PLATFORM/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- dpkg-deb -b deb "parity_"$VER"_armhf.deb"
|
||||
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/$PLATFORM/release/parity
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_armhf.deb" --body "parity_"$VER"_armhf.deb"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- scripts/gitlab-build.sh arm-unknown-linux-gnueabihf arm-unknown-linux-gnueabihf armhf arm-linux-gnueabihf-gcc arm-linux-gnueabihf-g++ ubuntu
|
||||
tags:
|
||||
- rust
|
||||
- rust-arm
|
||||
artifacts:
|
||||
paths:
|
||||
- target/arm-unknown-linux-gnueabihf/release/parity
|
||||
- parity.zip
|
||||
name: "arm-unknown-linux-gnueabihf_parity"
|
||||
allow_failure: true
|
||||
linux-aarch64:
|
||||
stage: build
|
||||
image: parity/rust-arm64:gitlab-ci
|
||||
@ -396,50 +122,29 @@ linux-aarch64:
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- export CC=aarch64-linux-gnu-gcc
|
||||
- export CXX=aarch64-linux-gnu-g++
|
||||
- export HOST_CC=gcc
|
||||
- export HOST_CXX=g++
|
||||
- export PLATFORM=aarch64-unknown-linux-gnu
|
||||
- rm -rf .cargo
|
||||
- mkdir -p .cargo
|
||||
- echo "[target.$PLATFORM]" >> .cargo/config
|
||||
- echo "linker= \"aarch64-linux-gnu-gcc\"" >> .cargo/config
|
||||
- cat .cargo/config
|
||||
- cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p evmbin
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethstore-cli
|
||||
- cargo build -j $(nproc) --target $PLATFORM --release -p ethkey-cli
|
||||
- aarch64-linux-gnu-strip target/$PLATFORM/release/parity
|
||||
- aarch64-linux-gnu-strip target/$PLATFORM/release/parity-evm
|
||||
- aarch64-linux-gnu-strip target/$PLATFORM/release/ethstore
|
||||
- aarch64-linux-gnu-strip target/$PLATFORM/release/ethkey
|
||||
- export SHA3=$(rhash --sha3-256 target/$PLATFORM/release/parity -p %h)
|
||||
- md5sum target/$PLATFORM/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh arm64
|
||||
- cp target/$PLATFORM/release/parity deb/usr/bin/parity
|
||||
- cp target/$PLATFORM/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/$PLATFORM/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/$PLATFORM/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- dpkg-deb -b deb "parity_"$VER"_arm64.deb"
|
||||
- md5sum "parity_"$VER"_arm64.deb" > "parity_"$VER"_arm64.deb.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_arm64.deb" --body "parity_"$VER"_arm64.deb"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_arm64.deb.md5" --body "parity_"$VER"_arm64.deb.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
- scripts/gitlab-build.sh aarch64-unknown-linux-gnu aarch64-unknown-linux-gnu arm64 aarch64-linux-gnu-gcc aarch64-linux-gnu-g++ ubuntu
|
||||
tags:
|
||||
- rust
|
||||
- rust-arm
|
||||
artifacts:
|
||||
paths:
|
||||
- target/aarch64-unknown-linux-gnu/release/parity
|
||||
- parity.zip
|
||||
name: "aarch64-unknown-linux-gnu_parity"
|
||||
linux-snap:
|
||||
stage: build
|
||||
image: snapcore/snapcraft:stable
|
||||
only:
|
||||
- stable
|
||||
- beta
|
||||
- tags
|
||||
- triggers
|
||||
script:
|
||||
- scripts/gitlab-build.sh x86_64-unknown-snap-gnu x86_64-unknown-linux-gnu amd64 gcc g++ snap
|
||||
tags:
|
||||
- rust-stable
|
||||
artifacts:
|
||||
paths:
|
||||
- parity.zip
|
||||
name: "stable-x86_64-unknown-snap-gnu_parity"
|
||||
allow_failure: true
|
||||
darwin:
|
||||
stage: build
|
||||
@ -448,45 +153,17 @@ darwin:
|
||||
- tags
|
||||
- stable
|
||||
- triggers
|
||||
script: |
|
||||
export COMMIT=$(git rev-parse HEAD)
|
||||
export PLATFORM=x86_64-apple-darwin
|
||||
rustup default stable
|
||||
cargo clean
|
||||
cargo build -j 8 --features final --release #$CARGOFLAGS
|
||||
cargo build -j 8 --release -p ethstore-cli #$CARGOFLAGS
|
||||
cargo build -j 8 --release -p ethkey-cli #$CARGOFLAGS
|
||||
cargo build -j 8 --release -p evmbin #$CARGOFLAGS
|
||||
rm -rf parity.md5
|
||||
md5sum target/release/parity > parity.md5
|
||||
export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||
cd mac
|
||||
xcodebuild -configuration Release
|
||||
cd ..
|
||||
packagesbuild -v mac/Parity.pkgproj
|
||||
productsign --sign 'Developer ID Installer: PARITY TECHNOLOGIES LIMITED (P2PX3JU8FT)' target/release/Parity\ Ethereum.pkg target/release/Parity\ Ethereum-signed.pkg
|
||||
export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
mv target/release/Parity\ Ethereum-signed.pkg "parity-"$VER"-macos-installer.pkg"
|
||||
md5sum "parity-"$VER"-macos-installer.pkg" >> "parity-"$VER"-macos-installer.pkg.md5"
|
||||
aws configure set aws_access_key_id $s3_key
|
||||
aws configure set aws_secret_access_key $s3_secret
|
||||
if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/release/parity
|
||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-macos-installer.pkg" --body "parity-"$VER"-macos-installer.pkg"
|
||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-macos-installer.pkg.md5" --body "parity-"$VER"-macos-installer.pkg.md5"
|
||||
curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||
script:
|
||||
- scripts/gitlab-build.sh x86_64-apple-darwin x86_64-apple-darwin macos gcc g++ macos
|
||||
tags:
|
||||
- osx
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
- parity.zip
|
||||
name: "x86_64-apple-darwin_parity"
|
||||
windows:
|
||||
cache:
|
||||
key: "%CI_BUILD_STAGE%/%CI_BUILD_REF_NAME%"
|
||||
key: "%CI_BUILD_STAGE%-%CI_BUILD_REF_NAME%"
|
||||
untracked: true
|
||||
stage: build
|
||||
only:
|
||||
@ -495,62 +172,12 @@ windows:
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- set PLATFORM=x86_64-pc-windows-msvc
|
||||
- set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt
|
||||
- set LIB=C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64
|
||||
- set RUST_BACKTRACE=1
|
||||
- set RUSTFLAGS=%RUSTFLAGS%
|
||||
- rustup default stable-x86_64-pc-windows-msvc
|
||||
- cargo clean
|
||||
- cargo build --features final --release #%CARGOFLAGS%
|
||||
- cargo build --release -p ethstore-cli #%CARGOFLAGS%
|
||||
- cargo build --release -p ethkey-cli #%CARGOFLAGS%
|
||||
- cargo build --release -p evmbin #%CARGOFLAGS%
|
||||
- signtool sign /f %keyfile% /p %certpass% target\release\parity.exe
|
||||
- target\release\parity.exe tools hash target\release\parity.exe > parity.sha3
|
||||
- set /P SHA3=<parity.sha3
|
||||
- curl -sL --url "https://github.com/paritytech/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll
|
||||
- curl -sL --url "https://github.com/paritytech/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe
|
||||
- msbuild windows\ptray\ptray.vcxproj /p:Platform=x64 /p:Configuration=Release
|
||||
- signtool sign /f %keyfile% /p %certpass% windows\ptray\x64\release\ptray.exe
|
||||
- cd nsis
|
||||
- makensis.exe installer.nsi
|
||||
- copy installer.exe InstallParity.exe
|
||||
- signtool sign /f %keyfile% /p %certpass% InstallParity.exe
|
||||
- md5sums InstallParity.exe > InstallParity.exe.md5
|
||||
- zip win-installer.zip InstallParity.exe InstallParity.exe.md5
|
||||
- md5sums win-installer.zip > win-installer.zip.md5
|
||||
- cd ..\target\release\
|
||||
- md5sums parity.exe > parity.exe.md5
|
||||
- zip parity.zip parity.exe parity.md5
|
||||
- md5sums parity.zip > parity.zip.md5
|
||||
- cd ..\..
|
||||
- aws configure set aws_access_key_id %s3_key%
|
||||
- aws configure set aws_secret_access_key %s3_secret%
|
||||
- echo %CI_BUILD_REF_NAME%
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "nightly" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
|
||||
- echo %S3_BUCKET%
|
||||
- aws s3 rm --recursive s3://%S3_BUCKET%/%CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe --body target\release\parity.exe
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe.md5 --body target\release\parity.exe.md5
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.zip --body target\release\parity.zip
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.zip.md5 --body target\release\parity.zip.md5
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe --body nsis\InstallParity.exe
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe.md5 --body nsis\InstallParity.exe.md5
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip --body nsis\win-installer.zip
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip.md5 --body nsis\win-installer.zip.md5
|
||||
- curl --data "commit=%CI_BUILD_REF%&sha3=%SHA3%&filename=parity.exe&secret=%RELEASES_SECRET%" http://update.parity.io:1337/push-build/%CI_BUILD_REF_NAME%/%PLATFORM%
|
||||
- curl --data "commit=%CI_BUILD_REF%&sha3=%SHA3%&filename=parity.exe&secret=%RELEASES_SECRET%" http://update.parity.io:1338/push-build/%CI_BUILD_REF_NAME%/%PLATFORM%
|
||||
- sh scripts/gitlab-build.sh x86_64-pc-windows-msvc x86_64-pc-windows-msvc installer "" "" windows
|
||||
tags:
|
||||
- rust-windows
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity.exe
|
||||
- target/release/parity.pdb
|
||||
- nsis/InstallParity.exe
|
||||
- parity.zip
|
||||
name: "x86_64-pc-windows-msvc_parity"
|
||||
docker-build:
|
||||
stage: build
|
||||
@ -563,7 +190,7 @@ docker-build:
|
||||
- if [ "$CI_BUILD_REF_NAME" == "beta-release" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi
|
||||
- echo "Tag:" $DOCKER_TAG
|
||||
- docker login -u $Docker_Hub_User_Parity -p $Docker_Hub_Pass_Parity
|
||||
- sh scripts/docker-build.sh $DOCKER_TAG
|
||||
- scripts/docker-build.sh $DOCKER_TAG
|
||||
- docker logout
|
||||
tags:
|
||||
- docker
|
||||
@ -572,65 +199,16 @@ test-coverage:
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- git submodule update --init --recursive
|
||||
- rm -rf target/*
|
||||
- rm -rf js/.coverage
|
||||
- scripts/cov.sh
|
||||
# - COVERAGE=$(grep -Po 'covered":.*?[^\\]"' target/cov/index.json | grep "[0-9]*\.[0-9]" -o)
|
||||
# - echo "Coverage:" $COVERAGE
|
||||
- scripts/gitlab-test.sh test-coverage
|
||||
tags:
|
||||
- kcov
|
||||
allow_failure: true
|
||||
test-darwin:
|
||||
stage: test
|
||||
only:
|
||||
- triggers
|
||||
before_script:
|
||||
- git submodule update --init --recursive
|
||||
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e "^js/" -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
|
||||
script:
|
||||
- export RUST_BACKTRACE=1
|
||||
- if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
|
||||
tags:
|
||||
- osx
|
||||
allow_failure: true
|
||||
test-windows:
|
||||
stage: test
|
||||
only:
|
||||
- triggers
|
||||
before_script:
|
||||
- git submodule update --init --recursive
|
||||
script:
|
||||
- set RUST_BACKTRACE=1
|
||||
- echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p parity-dapps -p parity-rpc -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity-rpc-client -p parity %CARGOFLAGS% --verbose --release
|
||||
tags:
|
||||
- rust-windows
|
||||
allow_failure: true
|
||||
test-rust-stable:
|
||||
stage: test
|
||||
image: parity/rust:gitlab-ci
|
||||
before_script:
|
||||
- git submodule update --init --recursive
|
||||
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
|
||||
script:
|
||||
- rustup show
|
||||
- export RUST_BACKTRACE=1
|
||||
- if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
|
||||
- if [ "$CI_BUILD_REF_NAME" == "nightly" ]; then sh scripts/aura-test.sh; fi
|
||||
- scripts/gitlab-test.sh stable
|
||||
tags:
|
||||
- rust
|
||||
- rust-stable
|
||||
js-test:
|
||||
stage: test
|
||||
image: parity/rust:gitlab-ci
|
||||
before_script:
|
||||
- git submodule update --init --recursive
|
||||
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
|
||||
script:
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS lint since no JS files modified."; else ./js/scripts/lint.sh && ./js/scripts/test.sh && ./js/scripts/build.sh; fi
|
||||
tags:
|
||||
- rust
|
||||
- rust-stable
|
||||
test-rust-beta:
|
||||
stage: test
|
||||
@ -638,15 +216,9 @@ test-rust-beta:
|
||||
- triggers
|
||||
- master
|
||||
image: parity/rust:gitlab-ci
|
||||
before_script:
|
||||
- git submodule update --init --recursive
|
||||
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
|
||||
script:
|
||||
- rustup default beta
|
||||
- export RUST_BACKTRACE=1
|
||||
- if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
|
||||
- scripts/gitlab-test.sh beta
|
||||
tags:
|
||||
- rust
|
||||
- rust-beta
|
||||
allow_failure: true
|
||||
test-rust-nightly:
|
||||
@ -655,34 +227,30 @@ test-rust-nightly:
|
||||
- triggers
|
||||
- master
|
||||
image: parity/rust:gitlab-ci
|
||||
before_script:
|
||||
- git submodule update --init --recursive
|
||||
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
|
||||
script:
|
||||
- rustup default nightly
|
||||
- export RUST_BACKTRACE=1
|
||||
- if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
|
||||
- scripts/gitlab-test.sh nightly
|
||||
tags:
|
||||
- rust
|
||||
- rust-nightly
|
||||
allow_failure: true
|
||||
js-test:
|
||||
stage: test
|
||||
image: parity/rust:gitlab-ci
|
||||
script:
|
||||
- scripts/gitlab-test.sh js-test
|
||||
tags:
|
||||
- rust-stable
|
||||
js-release:
|
||||
stage: js-build
|
||||
only:
|
||||
- master
|
||||
- beta
|
||||
- stable
|
||||
- beta
|
||||
- tags
|
||||
- triggers
|
||||
image: parity/rust:gitlab-ci
|
||||
before_script:
|
||||
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
|
||||
- echo $JS_FILES_MODIFIED
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
|
||||
script:
|
||||
- rustup default stable
|
||||
- echo $JS_FILES_MODIFIED
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi
|
||||
- scripts/gitlab-test.sh js-release
|
||||
tags:
|
||||
- javascript
|
||||
push-release:
|
||||
@ -692,8 +260,6 @@ push-release:
|
||||
- triggers
|
||||
image: parity/rust:gitlab-ci
|
||||
script:
|
||||
- rustup default stable
|
||||
- curl --data "secret=$RELEASES_SECRET" http://update.parity.io:1337/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF
|
||||
- curl --data "secret=$RELEASES_SECRET" http://update.parity.io:1338/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF
|
||||
- scripts/gitlab-push-release.sh
|
||||
tags:
|
||||
- curl
|
||||
|
216
Cargo.lock
generated
216
Cargo.lock
generated
@ -1,17 +1,3 @@
|
||||
[root]
|
||||
name = "wasm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.0.2"
|
||||
@ -39,6 +25,11 @@ name = "ansi_term"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "app_dirs"
|
||||
version = "1.1.1"
|
||||
@ -191,6 +182,11 @@ name = "bitflags"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bloomable"
|
||||
version = "0.1.0"
|
||||
@ -247,6 +243,9 @@ dependencies = [
|
||||
name = "cc"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -274,15 +273,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.26.2"
|
||||
version = "2.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -374,7 +372,7 @@ dependencies = [
|
||||
"bloomable 0.1.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethjson 0.1.0",
|
||||
"hash 0.1.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -542,7 +540,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethabi"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -588,7 +586,7 @@ dependencies = [
|
||||
"ethcore-ipc-nano 1.8.0",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-stratum 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"ethstore 0.1.0",
|
||||
@ -601,6 +599,8 @@ dependencies = [
|
||||
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -610,7 +610,7 @@ dependencies = [
|
||||
"migration 0.1.0",
|
||||
"native-contracts 0.1.0",
|
||||
"num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-machine 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia_trie 0.1.0",
|
||||
@ -682,7 +682,7 @@ version = "1.8.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-devtools 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -732,7 +732,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.8.0",
|
||||
"ethcore-ipc-codegen 1.8.0",
|
||||
"ethcore-ipc-nano 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -751,13 +751,15 @@ dependencies = [
|
||||
"ethcore-ipc 1.8.0",
|
||||
"ethcore-ipc-codegen 1.8.0",
|
||||
"ethcore-network 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"evm 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hash 0.1.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memorydb 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -801,7 +803,7 @@ dependencies = [
|
||||
"ethcore-devtools 1.8.0",
|
||||
"ethcore-io 1.8.0",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"hash 0.1.0",
|
||||
@ -816,6 +818,8 @@ dependencies = [
|
||||
"rlp 0.2.0",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -827,7 +831,7 @@ name = "ethcore-secretstore"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.8.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
@ -836,7 +840,7 @@ dependencies = [
|
||||
"ethcore-ipc-codegen 1.8.0",
|
||||
"ethcore-ipc-nano 1.8.0",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -844,6 +848,7 @@ dependencies = [
|
||||
"hash 0.1.0",
|
||||
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-contracts 0.1.0",
|
||||
@ -871,7 +876,7 @@ dependencies = [
|
||||
"ethcore-ipc-codegen 1.8.0",
|
||||
"ethcore-ipc-nano 1.8.0",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"hash 0.1.0",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
@ -884,7 +889,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-util"
|
||||
version = "1.8.0"
|
||||
version = "1.8.9"
|
||||
dependencies = [
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -899,6 +904,7 @@ dependencies = [
|
||||
"hashdb 0.1.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1018,12 +1024,13 @@ dependencies = [
|
||||
"ethcore-ipc-nano 1.8.0",
|
||||
"ethcore-light 1.8.0",
|
||||
"ethcore-network 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethkey 0.2.0",
|
||||
"hash 0.1.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1044,7 +1051,7 @@ dependencies = [
|
||||
"common-types 0.1.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethjson 0.1.0",
|
||||
"evmjit 1.8.0",
|
||||
"hash 0.1.0",
|
||||
@ -1066,7 +1073,7 @@ dependencies = [
|
||||
"ethcore 1.8.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethjson 0.1.0",
|
||||
"evm 0.1.0",
|
||||
"panic_hook 0.1.0",
|
||||
@ -1142,7 +1149,7 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1277,7 +1284,7 @@ dependencies = [
|
||||
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1364,7 +1371,7 @@ dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-ipc 1.8.0",
|
||||
"ethcore-ipc-codegen 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1514,11 +1521,28 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kvdb-memorydb"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"kvdb 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kvdb-rocksdb"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-devtools 1.8.0",
|
||||
"hashdb 0.1.0",
|
||||
"kvdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
@ -1670,6 +1694,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-devtools 1.8.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
]
|
||||
@ -1809,7 +1834,7 @@ dependencies = [
|
||||
name = "native-contract-generator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heck 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1818,7 +1843,7 @@ name = "native-contracts"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-contract-generator 0.1.0",
|
||||
@ -1857,9 +1882,9 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-io 1.8.0",
|
||||
"ethcore-network 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-contracts 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1974,7 +1999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.6.2"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2056,11 +2081,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity"
|
||||
version = "1.8.0"
|
||||
version = "1.8.9"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
|
||||
"daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2080,7 +2105,7 @@ dependencies = [
|
||||
"ethcore-network 1.8.0",
|
||||
"ethcore-secretstore 1.0.0",
|
||||
"ethcore-stratum 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethkey 0.2.0",
|
||||
"ethsync 1.8.0",
|
||||
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2090,12 +2115,12 @@ dependencies = [
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"migration 0.1.0",
|
||||
"node-filter 1.8.0",
|
||||
"node-health 0.1.0",
|
||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic_hook 0.1.0",
|
||||
"parity-dapps 1.8.0",
|
||||
@ -2120,6 +2145,8 @@ dependencies = [
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2136,7 +2163,7 @@ dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2195,10 +2222,10 @@ dependencies = [
|
||||
name = "parity-hash-fetch"
|
||||
version = "1.8.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hash 0.1.0",
|
||||
@ -2220,7 +2247,7 @@ dependencies = [
|
||||
"ethcore 1.8.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2234,9 +2261,10 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore 1.8.0",
|
||||
"ethcore-io 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethkey 0.2.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2249,7 +2277,7 @@ name = "parity-machine"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2277,13 +2305,14 @@ dependencies = [
|
||||
"ethcore-light 1.8.0",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-network 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"ethstore 0.1.0",
|
||||
"ethsync 1.8.0",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hardware-wallet 1.8.0",
|
||||
"hash 0.1.0",
|
||||
@ -2294,7 +2323,7 @@ dependencies = [
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2358,7 +2387,7 @@ name = "parity-ui"
|
||||
version = "1.8.0"
|
||||
dependencies = [
|
||||
"parity-ui-dev 1.8.0",
|
||||
"parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git)",
|
||||
"parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git?branch=stable)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2372,7 +2401,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git#7f18ddb380a06977d1028501d5930023b5cc9a26"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git?branch=stable#555710ae973da34051d2265adbbc7c6b2392d2ad"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2381,13 +2410,13 @@ dependencies = [
|
||||
name = "parity-updater"
|
||||
version = "1.8.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.8.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-ipc 1.8.0",
|
||||
"ethcore-ipc-codegen 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethsync 1.8.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-common-types 1.8.0",
|
||||
@ -2401,7 +2430,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-wasm"
|
||||
version = "0.14.5"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2707,7 +2736,7 @@ dependencies = [
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2794,7 +2823,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rocksdb"
|
||||
version = "0.4.5"
|
||||
source = "git+https://github.com/paritytech/rust-rocksdb#4364caec4dd5da1a1d78c39276774ee65bf55c7d"
|
||||
source = "git+https://github.com/paritytech/rust-rocksdb#ecf06adf3148ab10f6f7686b724498382ff4f36e"
|
||||
dependencies = [
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2804,10 +2833,12 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rocksdb-sys"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/paritytech/rust-rocksdb#4364caec4dd5da1a1d78c39276774ee65bf55c7d"
|
||||
source = "git+https://github.com/paritytech/rust-rocksdb#ecf06adf3148ab10f6f7686b724498382ff4f36e"
|
||||
dependencies = [
|
||||
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2849,7 +2880,7 @@ name = "rpc-cli"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc 1.8.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
@ -3104,6 +3135,15 @@ dependencies = [
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snappy-sys"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/rust-snappy#858eac97192ea25d18d3f3626a8cc13ca0b175bb"
|
||||
dependencies = [
|
||||
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spmc"
|
||||
version = "0.2.2"
|
||||
@ -3245,10 +3285,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -3565,7 +3604,7 @@ dependencies = [
|
||||
"common-types 0.1.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"ethjson 0.1.0",
|
||||
"evmjit 1.8.0",
|
||||
"hash 0.1.0",
|
||||
@ -3581,17 +3620,31 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-utils"
|
||||
name = "wasm"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/wasm-utils#6a39db802eb6b67a0c4e5cf50741f965e217335a"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-logger 1.8.0",
|
||||
"ethcore-util 1.8.9",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paritytech/wasm-utils#3d59f7ca0661317bc66894a26b2a5a319fa5d229"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3665,6 +3718,7 @@ dependencies = [
|
||||
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
|
||||
"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a"
|
||||
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
|
||||
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7d1c0d48a81bbb13043847f957971f4d87c81542d80ece5e84ba3cba4058fd4"
|
||||
"checksum arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "699e63a93b79d717e8c3b5eb1b28b7780d0d6d9e59a72eb769291c83b0c8dc67"
|
||||
@ -3684,6 +3738,7 @@ dependencies = [
|
||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d"
|
||||
"checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "<none>"
|
||||
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
|
||||
@ -3693,7 +3748,7 @@ dependencies = [
|
||||
"checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34aa7da06f10541fbca6850719cdaa8fa03060a5d2fb33840f149cf8133a00c7"
|
||||
"checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2"
|
||||
"checksum clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f4a2b3bb7ef3c672d7c13d15613211d5a6976b6892c598b0fcb5d40765f19c2"
|
||||
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
|
||||
"checksum clippy 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad3f3dc94d81a6505eb28bf545b501fc9d7525ee9864df5a4b2b6d82629f038"
|
||||
"checksum clippy 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "d19bda68c3db98e3a780342f6101b44312fef20a5f13ce756d1202a35922b01b"
|
||||
@ -3721,7 +3776,7 @@ dependencies = [
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143"
|
||||
"checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
|
||||
"checksum ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3d62319ee0f35abf20afe8859dd2668195912614346447bb2dee9fb8da7c62"
|
||||
"checksum ethabi 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6af84a622f9169efc6ead7f70043ca2058ef261c50e5e1e2ac60ccd381e386"
|
||||
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
|
||||
"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
@ -3803,7 +3858,7 @@ dependencies = [
|
||||
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
|
||||
"checksum num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "288629c76fac4b33556f4b7ab57ba21ae202da65ba8b77466e6d598e31990790"
|
||||
"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
|
||||
"checksum num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584"
|
||||
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
|
||||
"checksum number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "59a14be9c211cb9c602bad35ac99f41e9a84b44d71b8cbd3040e3bd02a214902"
|
||||
"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
|
||||
"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c"
|
||||
@ -3814,8 +3869,8 @@ dependencies = [
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddaeb8543c6823e93dae65a25eb8083ebfeee8f0000031119d7a0055b2e8fc63"
|
||||
"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
|
||||
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git)" = "<none>"
|
||||
"checksum parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4502e18417d96bd8e72fca9ea4cc18f4d80288ff565582d10aefe86f18b4fc3"
|
||||
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git?branch=stable)" = "<none>"
|
||||
"checksum parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8431a184ad88cfbcd71a792aaca319cc7203a94300c26b8dce2d0df0681ea87d"
|
||||
"checksum parity-wordlist 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81451bfab101d186f8fc4a0aa13cb5539b31b02c4ed96425a0842e2a413daba6"
|
||||
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
|
||||
"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595"
|
||||
@ -3888,6 +3943,7 @@ dependencies = [
|
||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
|
||||
"checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"
|
||||
"checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
|
||||
"checksum spmc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd1f11d1fb5fd41834e55ce0b85a186efbf2f2afd9fdb09e2c8d72f9bff1ad1a"
|
||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
@ -3904,7 +3960,7 @@ dependencies = [
|
||||
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
|
||||
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
|
||||
"checksum termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
|
||||
"checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd"
|
||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
||||
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
||||
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
|
||||
"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity"
|
||||
version = "1.8.0"
|
||||
version = "1.8.10"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
@ -12,6 +12,8 @@ env_logger = "0.4"
|
||||
rustc-hex = "1.0"
|
||||
docopt = "0.8"
|
||||
clap = "2"
|
||||
term_size = "0.3"
|
||||
textwrap = "0.9"
|
||||
time = "0.1"
|
||||
num_cpus = "1.2"
|
||||
number_prefix = "0.2"
|
||||
@ -63,7 +65,7 @@ path = { path = "util/path" }
|
||||
panic_hook = { path = "panic_hook" }
|
||||
hash = { path = "util/hash" }
|
||||
migration = { path = "util/migration" }
|
||||
kvdb = { path = "util/kvdb" }
|
||||
kvdb-rocksdb = { path = "util/kvdb-rocksdb" }
|
||||
|
||||
parity-dapps = { path = "dapps", optional = true }
|
||||
clippy = { version = "0.0.103", optional = true}
|
||||
|
@ -193,7 +193,7 @@ const UPDATE_TIMEOUT_ERR_SECS: u64 = 60;
|
||||
const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10;
|
||||
|
||||
/// Maximal valid time drift.
|
||||
pub const MAX_DRIFT: i64 = 500;
|
||||
pub const MAX_DRIFT: i64 = 10_000;
|
||||
|
||||
type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
||||
|
||||
|
@ -12,7 +12,7 @@ rustc_version = "0.1"
|
||||
[dependencies]
|
||||
parity-ui-dev = { path = "../../js", optional = true }
|
||||
# This is managed by the js/scripts/release.sh script on CI - keep it in a single line
|
||||
parity-ui-precompiled = { git = "https://github.com/paritytech/js-precompiled.git", optional = true, branch = "master" }
|
||||
parity-ui-precompiled = { git = "https://github.com/paritytech/js-precompiled.git", optional = true, branch = "stable" }
|
||||
|
||||
[features]
|
||||
no-precompiled-js = ["parity-ui-dev"]
|
||||
|
@ -56,6 +56,8 @@ rand = "0.3"
|
||||
rlp = { path = "../util/rlp" }
|
||||
rlp_derive = { path = "../util/rlp_derive" }
|
||||
kvdb = { path = "../util/kvdb" }
|
||||
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
|
||||
kvdb-memorydb = { path = "../util/kvdb-memorydb" }
|
||||
util-error = { path = "../util/error" }
|
||||
snappy = { path = "../util/snappy" }
|
||||
migration = { path = "../util/migration" }
|
||||
@ -81,7 +83,7 @@ native-contracts = { path = "native_contracts", features = ["test_contracts"] }
|
||||
[features]
|
||||
jit = ["evm/jit"]
|
||||
evm-debug = ["slow-blocks"]
|
||||
evm-debug-tests = ["evm-debug"]
|
||||
evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
|
||||
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
|
||||
json-tests = []
|
||||
test-heavy = []
|
||||
|
@ -26,3 +26,5 @@ rustc-hex = "1.0"
|
||||
|
||||
[features]
|
||||
jit = ["evmjit"]
|
||||
evm-debug = []
|
||||
evm-debug-tests = ["evm-debug"]
|
||||
|
@ -39,12 +39,12 @@ mod inner {
|
||||
use std::collections::HashMap;
|
||||
use std::time::{Instant, Duration};
|
||||
|
||||
use evm::interpreter::stack::Stack;
|
||||
use evm::instructions::{Instruction, InstructionInfo, INSTRUCTIONS};
|
||||
use evm::{CostType};
|
||||
|
||||
use bigint::prelude::U256;
|
||||
|
||||
use interpreter::stack::Stack;
|
||||
use instructions::{Instruction, InstructionInfo, INSTRUCTIONS};
|
||||
use CostType;
|
||||
|
||||
macro_rules! evm_debug {
|
||||
($x: expr) => {
|
||||
$x
|
||||
@ -110,7 +110,7 @@ mod inner {
|
||||
}
|
||||
|
||||
pub fn after_instruction(&mut self, instruction: Instruction) {
|
||||
let mut stats = self.stats.entry(instruction).or_insert_with(|| Stats::default());
|
||||
let stats = self.stats.entry(instruction).or_insert_with(|| Stats::default());
|
||||
let took = self.last_instruction.elapsed();
|
||||
stats.note(took);
|
||||
}
|
||||
|
@ -322,20 +322,24 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
let init_off = stack.pop_back();
|
||||
let init_size = stack.pop_back();
|
||||
|
||||
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
|
||||
let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed");
|
||||
|
||||
let contract_code = self.mem.read_slice(init_off, init_size);
|
||||
let can_create = ext.balance(¶ms.address)? >= endowment && ext.depth() < ext.schedule().max_depth;
|
||||
if ext.is_static() {
|
||||
return Err(vm::Error::MutableCallInStaticContext);
|
||||
}
|
||||
|
||||
// clear return data buffer before creating new call frame.
|
||||
self.return_data = ReturnData::empty();
|
||||
|
||||
let can_create = ext.balance(¶ms.address)? >= endowment && ext.depth() < ext.schedule().max_depth;
|
||||
if !can_create {
|
||||
stack.push(U256::zero());
|
||||
return Ok(InstructionResult::UnusedGas(create_gas));
|
||||
}
|
||||
|
||||
let contract_code = self.mem.read_slice(init_off, init_size);
|
||||
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
|
||||
|
||||
let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme);
|
||||
return match create_result {
|
||||
ContractCreateResult::Created(address, gas_left) => {
|
||||
@ -351,9 +355,6 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
stack.push(U256::zero());
|
||||
Ok(InstructionResult::Ok)
|
||||
},
|
||||
ContractCreateResult::FailedInStaticCall => {
|
||||
Err(vm::Error::MutableCallInStaticContext)
|
||||
},
|
||||
};
|
||||
},
|
||||
instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL | instructions::STATICCALL => {
|
||||
|
@ -33,6 +33,7 @@ extern crate hash;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
#[cfg_attr(feature = "evm-debug", macro_use)]
|
||||
extern crate log;
|
||||
|
||||
#[cfg(feature = "jit")]
|
||||
|
@ -724,7 +724,6 @@ fn test_jumps(factory: super::Factory) {
|
||||
assert_eq!(gas_left, U256::from(54_117));
|
||||
}
|
||||
|
||||
|
||||
evm_test!{test_calls: test_calls_jit, test_calls_int}
|
||||
fn test_calls(factory: super::Factory) {
|
||||
let code = "600054602d57600160005560006000600060006050610998610100f160006000600060006050610998610100f25b".from_hex().unwrap();
|
||||
@ -769,6 +768,27 @@ fn test_calls(factory: super::Factory) {
|
||||
assert_eq!(ext.calls.len(), 2);
|
||||
}
|
||||
|
||||
evm_test!{test_create_in_staticcall: test_create_in_staticcall_jit, test_create_in_staticcall_int}
|
||||
fn test_create_in_staticcall(factory: super::Factory) {
|
||||
let code = "600060006064f000".from_hex().unwrap();
|
||||
|
||||
let address = Address::from(0x155);
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.address = address.clone();
|
||||
let mut ext = FakeExt::new_byzantium();
|
||||
ext.is_static = true;
|
||||
|
||||
let err = {
|
||||
let mut vm = factory.create(params.gas);
|
||||
test_finalize(vm.exec(params, &mut ext)).unwrap_err()
|
||||
};
|
||||
|
||||
assert_eq!(err, vm::Error::MutableCallInStaticContext);
|
||||
assert_eq!(ext.calls.len(), 0);
|
||||
}
|
||||
|
||||
fn assert_set_contains<T : Debug + Eq + PartialEq + Hash>(set: &HashSet<T>, val: &T) {
|
||||
let contains = set.contains(val);
|
||||
if !contains {
|
||||
|
@ -40,6 +40,8 @@ stats = { path = "../../util/stats" }
|
||||
hash = { path = "../../util/hash" }
|
||||
triehash = { path = "../../util/triehash" }
|
||||
kvdb = { path = "../../util/kvdb" }
|
||||
kvdb-rocksdb = { path = "../../util/kvdb-rocksdb" }
|
||||
kvdb-memorydb = { path = "../../util/kvdb-memorydb" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -728,13 +728,14 @@ mod tests {
|
||||
use ethcore::header::Header;
|
||||
use ethcore::spec::Spec;
|
||||
use cache::Cache;
|
||||
use kvdb::{in_memory, KeyValueDB};
|
||||
use kvdb::KeyValueDB;
|
||||
use kvdb_memorydb;
|
||||
|
||||
use time::Duration;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
fn make_db() -> Arc<KeyValueDB> {
|
||||
Arc::new(in_memory(0))
|
||||
Arc::new(kvdb_memorydb::create(0))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -36,7 +36,8 @@ use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use futures::{IntoFuture, Future};
|
||||
|
||||
use kvdb::{KeyValueDB, CompactionProfile};
|
||||
use kvdb::KeyValueDB;
|
||||
use kvdb_rocksdb::CompactionProfile;
|
||||
|
||||
use self::fetch::ChainDataFetcher;
|
||||
use self::header_chain::{AncestryIter, HeaderChain};
|
||||
@ -214,7 +215,7 @@ impl<T: ChainDataFetcher> Client<T> {
|
||||
io_channel: IoChannel<ClientIoMessage>,
|
||||
cache: Arc<Mutex<Cache>>
|
||||
) -> Self {
|
||||
let db = ::kvdb::in_memory(0);
|
||||
let db = ::kvdb_memorydb::create(0);
|
||||
|
||||
Client::new(
|
||||
config,
|
||||
|
@ -25,7 +25,7 @@ use ethcore::db;
|
||||
use ethcore::service::ClientIoMessage;
|
||||
use ethcore::spec::Spec;
|
||||
use io::{IoContext, IoError, IoHandler, IoService};
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
use cache::Cache;
|
||||
use parking_lot::Mutex;
|
||||
@ -63,11 +63,7 @@ impl<T: ChainDataFetcher> Service<T> {
|
||||
// initialize database.
|
||||
let mut db_config = DatabaseConfig::with_columns(db::NUM_COLUMNS);
|
||||
|
||||
// give all rocksdb cache to the header chain column.
|
||||
if let Some(size) = config.db_cache_size {
|
||||
db_config.set_cache(db::COL_LIGHT_CHAIN, size);
|
||||
}
|
||||
|
||||
db_config.memory_budget = config.db_cache_size;
|
||||
db_config.compaction = config.db_compaction;
|
||||
db_config.wal = config.db_wal;
|
||||
|
||||
|
@ -92,6 +92,8 @@ extern crate vm;
|
||||
extern crate hash;
|
||||
extern crate triehash;
|
||||
extern crate kvdb;
|
||||
extern crate kvdb_memorydb;
|
||||
extern crate kvdb_rocksdb;
|
||||
|
||||
#[cfg(feature = "ipc")]
|
||||
extern crate ethcore_ipc as ipc;
|
||||
|
@ -11,10 +11,12 @@ ethcore = { path = ".."}
|
||||
ethcore-util = { path = "../../util" }
|
||||
ethcore-bigint = { path = "../../util/bigint" }
|
||||
ethcore-bytes = { path = "../../util/bytes" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
ethcore-network = { path = "../../util/network" }
|
||||
kvdb = { path = "../../util/kvdb" }
|
||||
native-contracts = { path = "../native_contracts" }
|
||||
futures = "0.1"
|
||||
log = "0.3"
|
||||
parking_lot = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
kvdb-memorydb = { path = "../../util/kvdb-memorydb" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
|
@ -24,9 +24,14 @@ extern crate ethcore_network as network;
|
||||
extern crate native_contracts;
|
||||
extern crate futures;
|
||||
extern crate parking_lot;
|
||||
extern crate kvdb;
|
||||
#[cfg(test)] extern crate ethcore_io as io;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate kvdb_memorydb;
|
||||
#[cfg(test)]
|
||||
extern crate ethcore_io as io;
|
||||
|
||||
use std::sync::Weak;
|
||||
use std::collections::HashMap;
|
||||
@ -135,7 +140,7 @@ mod test {
|
||||
let contract_addr = Address::from_str("0000000000000000000000000000000000000005").unwrap();
|
||||
let data = include_bytes!("../res/node_filter.json");
|
||||
let spec = Spec::load(&::std::env::temp_dir(), &data[..]).unwrap();
|
||||
let client_db = Arc::new(::kvdb::in_memory(::ethcore::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let client_db = Arc::new(::kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
|
||||
let client = Client::new(
|
||||
ClientConfig::default(),
|
||||
|
@ -6,7 +6,7 @@
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"difficultyIncrementDivisor": "60",
|
||||
"difficultyIncrementDivisor": "0x3C",
|
||||
"durationLimit": "0x3C",
|
||||
"blockReward": "0x6f05b59d3b200000",
|
||||
"homesteadTransition": "0x30d40",
|
||||
@ -16,7 +16,13 @@
|
||||
"eip150Transition": "0x927C0",
|
||||
"eip160Transition": "0x927C0",
|
||||
"eip161abcTransition": "0x927C0",
|
||||
"eip161dTransition": "0x927C0"
|
||||
"eip161dTransition": "0x927C0",
|
||||
"eip100bTransition": "0xC3500",
|
||||
"metropolisDifficultyIncrementDivisor": "0x1E",
|
||||
"eip649Transition": "0xC3500",
|
||||
"eip649Reward": "0x3782DACE9D900000",
|
||||
"expip2Transition": "0xC3500",
|
||||
"expip2DurationLimit": "0x1E"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -28,10 +34,16 @@
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID": "0x1",
|
||||
"chainID": "0x2",
|
||||
"forkBlock": "0xDBBA0",
|
||||
"forkCanonHash": "0x8e7bed51e24f5174090408664ac476b90b5e1199a947af7442f1ac88263fc8c7",
|
||||
"subprotocolName": "exp",
|
||||
"eip98Transition": "0x7fffffffffffff",
|
||||
"eip86Transition": "0x7fffffffffffff",
|
||||
"eip155Transition": "0x927C0"
|
||||
"eip155Transition": "0x927C0",
|
||||
"eip140Transition": "0xC3500",
|
||||
"eip211Transition": "0xC3500",
|
||||
"eip214Transition": "0xC3500",
|
||||
"eip658Transition": "0xC3500"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@ -53,7 +65,6 @@
|
||||
"enode://96d3919b903e7f5ad59ac2f73c43be9172d9d27e2771355db03fd194732b795829a31fe2ea6de109d0804786c39a807e155f065b4b94c6fce167becd0ac02383@45.55.22.34:42786",
|
||||
"enode://5f6c625bf287e3c08aad568de42d868781e961cbda805c8397cfb7be97e229419bef9a5a25a75f97632787106bba8a7caf9060fab3887ad2cfbeb182ab0f433f@46.101.182.53:42786",
|
||||
"enode://d33a8d4c2c38a08971ed975b750f21d54c927c0bf7415931e214465a8d01651ecffe4401e1db913f398383381413c78105656d665d83f385244ab302d6138414@128.199.183.48:42786",
|
||||
"enode://df872f81e25f72356152b44cab662caf1f2e57c3a156ecd20e9ac9246272af68a2031b4239a0bc831f2c6ab34733a041464d46b3ea36dce88d6c11714446e06b@178.62.208.109:42786",
|
||||
"enode://f6f0d6b9b7d02ec9e8e4a16e38675f3621ea5e69860c739a65c1597ca28aefb3cec7a6d84e471ac927d42a1b64c1cbdefad75e7ce8872d57548ddcece20afdd1@159.203.64.95:42786"
|
||||
],
|
||||
"accounts": {
|
||||
@ -61,6 +72,10 @@
|
||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"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 } } } },
|
||||
"bb94f0ceb32257275b2a7a9c094c13e469b4563e": {
|
||||
"balance": "10000000000000000000000000"
|
||||
},
|
||||
|
@ -173,24 +173,38 @@
|
||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://efe4f2493f4aff2d641b1db8366b96ddacfe13e7a6e9c8f8f8cf49f9cdba0fdf3258d8c8f8d0c5db529f8123c8f1d95f36d54d590ca1bb366a5818b9a4ba521c@163.172.187.252:30303",
|
||||
"enode://6a868ced2dec399c53f730261173638a93a40214cf299ccf4d42a76e3fa54701db410669e8006347a4b3a74fa090bb35af0320e4bc8d04cf5b7f582b1db285f5@163.172.131.191:30303",
|
||||
"enode://66a483383882a518fcc59db6c017f9cd13c71261f13c8d7e67ed43adbbc82a932d88d2291f59be577e9425181fc08828dc916fdd053af935a9491edf9d6006ba@212.47.247.103:30303",
|
||||
"enode://cd6611461840543d5b9c56fbf088736154c699c43973b3a1a32390cf27106f87e58a818a606ccb05f3866de95a4fe860786fea71bf891ea95f234480d3022aa3@163.172.157.114:30303",
|
||||
"enode://78b094cb27ceeecbe311bc278f4fde8b9a265db42d268c88484c94d7a2d19b82a1bd22dfd6c2bd4d90f9b05e6d42255e6eb85de15f73848ff82ed0be9cdf5202@52.233.198.218:30303",
|
||||
"enode://00526537cb7e1aa6cf49714f0635fd0f608904d8d0693b949eea2dcdfdb0abbe4c794003a5fe57aa662d0a9215e8dfa4d2deb6ef0101c5e185e2617721813d43@40.65.122.44:30303",
|
||||
"enode://4a456b4b6e6ee1f51389763e51b80fe04782c762445d96c32a96ebd34bd9178c1894924d5101123eacfd4f0fc4da25b5e1ee7f18832ac0bf4c6d6ac81442d698@40.71.6.49:3030",
|
||||
"enode://68f85e7403976aa92318eff804cbe9bc988e0f5230d9d07ae4def030cbae16603262638e272d19875b7e5c54e296ba88ab6ec6e98face9e2537346c4dce78882@52.243.47.211:30303",
|
||||
"enode://dc72806c3aa8fda207c8c018aba8d6cf143728b3628b6ded8d5e8cdeb8aa05cbd53f710ecd014c9a8f0d1e98f2874bff8afb15a229202f510a9c0258d1f6d109@159.203.210.80:30303",
|
||||
"enode://5a62f19d35c0da8b576c9414568c728d4744e6e9d436c0f9db27456400011414f515871f13a6b8e0468534b5116cfe765d7630f680f1707a38467940a9f62511@45.55.33.62:30303",
|
||||
"enode://605e04a43b1156966b3a3b66b980c87b7f18522f7f712035f84576016be909a2798a438b2b17b1a8c58db314d88539a77419ca4be36148c086900fba487c9d39@188.166.255.12:30303",
|
||||
"enode://1d1f7bcb159d308eb2f3d5e32dc5f8786d714ec696bb2f7e3d982f9bcd04c938c139432f13aadcaf5128304a8005e8606aebf5eebd9ec192a1471c13b5e31d49@138.201.223.35:30303",
|
||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
||||
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303",
|
||||
"enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303",
|
||||
"enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303",
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||
"enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303",
|
||||
"enode://0cc5f5ffb5d9098c8b8c62325f3797f56509bff942704687b6530992ac706e2cb946b90a34f1f19548cd3c7baccbcaea354531e5983c7d1bc0dee16ce4b6440b@40.118.3.223:30305",
|
||||
"enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30308",
|
||||
"enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30309",
|
||||
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303",
|
||||
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
|
||||
"enode://2c9059f05c352b29d559192fe6bca272d965c9f2290632a2cfda7f83da7d2634f3ec45ae3a72c54dd4204926fb8082dcf9686e0d7504257541c86fc8569bcf4b@163.172.171.38:30303",
|
||||
"enode://efe4f2493f4aff2d641b1db8366b96ddacfe13e7a6e9c8f8f8cf49f9cdba0fdf3258d8c8f8d0c5db529f8123c8f1d95f36d54d590ca1bb366a5818b9a4ba521c@163.172.187.252:30303",
|
||||
"enode://bcc7240543fe2cf86f5e9093d05753dd83343f8fda7bf0e833f65985c73afccf8f981301e13ef49c4804491eab043647374df1c4adf85766af88a624ecc3330e@136.243.154.244:30303",
|
||||
"enode://ed4227681ca8c70beb2277b9e870353a9693f12e7c548c35df6bca6a956934d6f659999c2decb31f75ce217822eefca149ace914f1cbe461ed5a2ebaf9501455@88.212.206.70:30303",
|
||||
"enode://cadc6e573b6bc2a9128f2f635ac0db3353e360b56deef239e9be7e7fce039502e0ec670b595f6288c0d2116812516ad6b6ff8d5728ff45eba176989e40dead1e@37.128.191.230:30303",
|
||||
"enode://595a9a06f8b9bc9835c8723b6a82105aea5d55c66b029b6d44f229d6d135ac3ecdd3e9309360a961ea39d7bee7bac5d03564077a4e08823acc723370aace65ec@46.20.235.22:30303",
|
||||
"enode://029178d6d6f9f8026fc0bc17d5d1401aac76ec9d86633bba2320b5eed7b312980c0a210b74b20c4f9a8b0b2bf884b111fa9ea5c5f916bb9bbc0e0c8640a0f56c@216.158.85.185:30303",
|
||||
"enode://fdd1b9bb613cfbc200bba17ce199a9490edc752a833f88d4134bf52bb0d858aa5524cb3ec9366c7a4ef4637754b8b15b5dc913e4ed9fdb6022f7512d7b63f181@212.47.247.103:30303",
|
||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
||||
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303",
|
||||
|
||||
"enode://89d5dc2a81e574c19d0465f497c1af96732d1b61a41de89c2a37f35707689ac416529fae1038809852b235c2d30fd325abdc57c122feeefbeaaf802cc7e9580d@45.55.33.62:30303",
|
||||
"enode://605e04a43b1156966b3a3b66b980c87b7f18522f7f712035f84576016be909a2798a438b2b17b1a8c58db314d88539a77419ca4be36148c086900fba487c9d39@188.166.255.12:30303",
|
||||
"enode://016b20125f447a3b203a3cae953b2ede8ffe51290c071e7599294be84317635730c397b8ff74404d6be412d539ee5bb5c3c700618723d3b53958c92bd33eaa82@159.203.210.80:30303",
|
||||
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
|
||||
"enode://8d91c8137890d29110b9463882f17ae4e279cd2c90cf56573187ed1c8546fca5f590a9f05e9f108eb1bd91767ed01ede4daad9e001b61727885eaa246ddb39c2@163.172.171.38:30303"
|
||||
"enode://fdd1b9bb613cfbc200bba17ce199a9490edc752a833f88d4134bf52bb0d858aa5524cb3ec9366c7a4ef4637754b8b15b5dc913e4ed9fdb6022f7512d7b63f181@212.47.247.103:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
@ -12,29 +12,35 @@
|
||||
"0x00427feae2419c15b89d1c21af10d1b6650a4d3d",
|
||||
"0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c",
|
||||
"0x0020ee4Be0e2027d76603cB751eE069519bA81A1",
|
||||
|
||||
"0x0010f94b296a852aaac52ea6c5ac72e03afd032d",
|
||||
|
||||
"0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A",
|
||||
"0x00E6d2b931F55a3f1701c7389d592a7778897879",
|
||||
"0x00e4a10650e5a6D6001C38ff8E64F97016a1645c",
|
||||
|
||||
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
|
||||
]
|
||||
},
|
||||
"validateScoreTransition": 1000000,
|
||||
"validateStepTransition": 1500000
|
||||
"validateStepTransition": 1500000,
|
||||
"maximumUncleCountTransition": 5067000,
|
||||
"maximumUncleCount": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x400",
|
||||
"registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x2A",
|
||||
"forkBlock": 4297256,
|
||||
"forkCanonHash": "0x0a66d93c2f727dca618fabaf70c39b37018c73d78b939d8b11efbbd09034778f",
|
||||
"validateReceiptsTransition" : 1000000,
|
||||
"eip155Transition": 1000000
|
||||
"eip155Transition": 1000000,
|
||||
"validateChainIdTransition": 1000000,
|
||||
"eip140Transition": 5067000,
|
||||
"eip211Transition": 5067000,
|
||||
"eip214Transition": 5067000,
|
||||
"eip658Transition": 5067000
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@ -51,13 +57,17 @@
|
||||
"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 } } } },
|
||||
"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 } } } },
|
||||
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
|
||||
},
|
||||
"nodes": [
|
||||
"enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303",
|
||||
"enode://dcf984764db421fa0cd8dc7fc02ae378545723abb94d179f55325514cc30185eaea3dcefde6e358b7cdbe970c50b7c49e841618713a9a72d6f3f59ad9949ec6b@52.165.239.18:30303",
|
||||
"enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303",
|
||||
"enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303",
|
||||
"enode://8fa162563a8e5a05eef3e1cd5abc5828c71344f7277bb788a395cce4a0e30baf2b34b92fe0b2dbbba2313ee40236bae2aab3c9811941b9f5a7e8e90aaa27ecba@52.165.239.18:30303",
|
||||
"enode://7e2e7f00784f516939f94e22bdc6cf96153603ca2b5df1c7cc0f90a38e7a2f218ffb1c05b156835e8b49086d11fdd1b3e2965be16baa55204167aa9bf536a4d9@52.243.47.56:30303",
|
||||
"enode://d51b3e98bf35addf2f1d0ea1ffc90483e24d7c60b0fb3be1701e818f3d6778c06e53fdec737a534fe222956296f9d6e909baa025916a94601897e5c7136a7d95@40.71.221.215:30303",
|
||||
"enode://419d42e300e8fd379ff6d045d93d7e66a091441e7b3c9f1d3d10088d8634ad37721e6bf86148f78c3f1b9f1360dc566ca8ee830b2d2079bc9f7171ea6152bb64@52.166.117.77:30303"
|
||||
"enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303"
|
||||
]
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
"eip160Transition": 1915000,
|
||||
"ecip1010PauseTransition": 1915000,
|
||||
"ecip1010ContinueTransition": 3415000,
|
||||
"ecip1017EraRounds": 2000000,
|
||||
|
||||
"eip161abcTransition": "0x7fffffffffffffff",
|
||||
"eip161dTransition": "0x7fffffffffffffff"
|
||||
@ -49,11 +50,13 @@
|
||||
"gasLimit": "0x2fefd8"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://e731347db0521f3476e6bbbb83375dcd7133a1601425ebd15fd10f3835fd4c304fba6282087ca5a0deeafadf0aa0d4fd56c3323331901c1f38bd181c283e3e35@128.199.55.137:30303",
|
||||
"enode://ceb5c0f85eb994dbe9693bf46d99b03f6b838d17cc74e68d5eb003171ff39e5f120b17f965b267c319303f94d80b9d994b77062fb1486d76ce95d9f3d8fe1cb4@46.101.122.141:30303",
|
||||
"enode://fb28713820e718066a2f5df6250ae9d07cff22f672dbf26be6c75d088f821a9ad230138ba492c533a80407d054b1436ef18e951bb65e6901553516c8dffe8ff0@104.155.176.151:30304",
|
||||
"enode://afdc6076b9bf3e7d3d01442d6841071e84c76c73a7016cb4f35c0437df219db38565766234448f1592a07ba5295a867f0ce87b359bf50311ed0b830a2361392d@104.154.136.117:30403",
|
||||
"enode://21101a9597b79e933e17bc94ef3506fe99a137808907aa8fefa67eea4b789792ad11fb391f38b00087f8800a2d3dff011572b62a31232133dd1591ac2d1502c8@104.198.71.200:30403"
|
||||
"enode://21101a9597b79e933e17bc94ef3506fe99a137808907aa8fefa67eea4b789792ad11fb391f38b00087f8800a2d3dff011572b62a31232133dd1591ac2d1502c8@104.198.71.200:30403",
|
||||
"enode://fd008499e9c4662f384b3cff23438879d31ced24e2d19504c6389bc6da6c882f9c2f8dbed972f7058d7650337f54e4ba17bb49c7d11882dd1731d26a6e62e3cb@35.187.57.94:30304",
|
||||
"enode://30a1fd71f28aa6f66fe662af9ecc75f0a6980f06b71598f2b19d3dda04223fc0e53b47e40c9171d5014e9f5b59d9954de125782da592f5d95ea39066e2591d5d@104.237.131.102:30304",
|
||||
"enode://7909d51011d8a153351169f21d3a7bbedb3be1e17d38c1f2fad06504dd5aa07a00f00845835d535fe702bf379c4d7209a51f4d1b723e0ca8b8732bd21fba3b30@139.162.133.42:30303",
|
||||
"enode://a088dfb2f5305be9232e8071c5535f13718a4017e247a0b35074b807d43d99e022880c27302cdb5b1e98ad34c083dbbb483f2b17bdc66149bad037154d6ace96@139.162.127.72:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
@ -52,6 +52,8 @@
|
||||
"gasLimit": "0x1000000"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303",
|
||||
"enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303",
|
||||
"enode://20c9ad97c081d63397d7b685a412227a40e23c8bdc6688c6f37e97cfbc22d2b4d1db1510d8f61e6a8866ad7f0e17c02b14182d37ea7c3c8b9c2683aeb6b733a1@52.169.14.227:30303",
|
||||
"enode://6ce05930c72abc632c58e2e4324f7c7ea478cec0ed4fa2528982cf34483094e9cbc9216e7aa349691242576d552a2a56aaeae426c5303ded677ce455ba1acd9d@13.84.180.240:30303"
|
||||
],
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c8129ce2f36c26ed634eda786960978a28e28d0e
|
||||
Subproject commit d6185ea16eaba7ff685c069c2064819f9549c4d7
|
@ -269,7 +269,7 @@ impl AccountProvider {
|
||||
|
||||
/// Checks whether an account with a given address is present.
|
||||
pub fn has_account(&self, address: Address) -> Result<bool, Error> {
|
||||
Ok(self.accounts()?.iter().any(|&a| a == address))
|
||||
Ok(self.sstore.account_ref(&address).is_ok() && !self.blacklisted_accounts.contains(&address))
|
||||
}
|
||||
|
||||
/// Returns addresses of all accounts.
|
||||
@ -516,8 +516,8 @@ impl AccountProvider {
|
||||
}
|
||||
|
||||
/// Returns each hardware account along with name and meta.
|
||||
pub fn is_hardware_address(&self, address: Address) -> bool {
|
||||
self.hardware_store.as_ref().and_then(|s| s.wallet_info(&address)).is_some()
|
||||
pub fn is_hardware_address(&self, address: &Address) -> bool {
|
||||
self.hardware_store.as_ref().and_then(|s| s.wallet_info(address)).is_some()
|
||||
}
|
||||
|
||||
/// Returns each account along with name and meta.
|
||||
@ -589,7 +589,7 @@ impl AccountProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if self.unlock_keep_secret && unlock != Unlock::OneTime {
|
||||
if self.unlock_keep_secret && unlock == Unlock::Perm {
|
||||
// verify password and get the secret
|
||||
let secret = self.sstore.raw_secret(&account, &password)?;
|
||||
self.unlocked_secrets.write().insert(account.clone(), secret);
|
||||
@ -639,14 +639,22 @@ impl AccountProvider {
|
||||
}
|
||||
|
||||
/// Checks if given account is unlocked
|
||||
pub fn is_unlocked(&self, address: Address) -> bool {
|
||||
pub fn is_unlocked(&self, address: &Address) -> bool {
|
||||
let unlocked = self.unlocked.read();
|
||||
let unlocked_secrets = self.unlocked_secrets.read();
|
||||
self.sstore.account_ref(&address)
|
||||
self.sstore.account_ref(address)
|
||||
.map(|r| unlocked.get(&r).is_some() || unlocked_secrets.get(&r).is_some())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Checks if given account is unlocked permanently
|
||||
pub fn is_unlocked_permanently(&self, address: &Address) -> bool {
|
||||
let unlocked = self.unlocked.read();
|
||||
self.sstore.account_ref(address)
|
||||
.map(|r| unlocked.get(&r).map_or(false, |account| account.unlock == Unlock::Perm))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Signs the message. If password is not provided the account must be unlocked.
|
||||
pub fn sign(&self, address: Address, password: Option<String>, message: Message) -> Result<Signature, SignError> {
|
||||
let account = self.sstore.account_ref(&address)?;
|
||||
|
@ -380,8 +380,13 @@ impl<'x> OpenBlock<'x> {
|
||||
/// NOTE Will check chain constraints and the uncle number but will NOT check
|
||||
/// that the header itself is actually valid.
|
||||
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
|
||||
if self.block.uncles.len() + 1 > self.engine.maximum_uncle_count() {
|
||||
return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.uncles.len() + 1}));
|
||||
let max_uncles = self.engine.maximum_uncle_count(self.block.header().number());
|
||||
if self.block.uncles.len() + 1 > max_uncles {
|
||||
return Err(BlockError::TooManyUncles(OutOfBounds{
|
||||
min: None,
|
||||
max: Some(max_uncles),
|
||||
found: self.block.uncles.len() + 1,
|
||||
}));
|
||||
}
|
||||
// TODO: check number
|
||||
// TODO: check not a direct ancestor (use last_hashes for that)
|
||||
|
@ -1479,7 +1479,8 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
use rustc_hex::FromHex;
|
||||
use hash::keccak;
|
||||
use kvdb::{in_memory, KeyValueDB};
|
||||
use kvdb::KeyValueDB;
|
||||
use kvdb_memorydb;
|
||||
use bigint::hash::*;
|
||||
use receipt::{Receipt, TransactionOutcome};
|
||||
use blockchain::{BlockProvider, BlockChain, Config, ImportRoute};
|
||||
@ -1493,7 +1494,7 @@ mod tests {
|
||||
use header::BlockNumber;
|
||||
|
||||
fn new_db() -> Arc<KeyValueDB> {
|
||||
Arc::new(in_memory(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
}
|
||||
|
||||
fn new_chain(genesis: &[u8], db: Arc<KeyValueDB>) -> BlockChain {
|
||||
|
@ -23,8 +23,6 @@ pub struct Config {
|
||||
pub pref_cache_size: usize,
|
||||
/// Maximum cache size in bytes.
|
||||
pub max_cache_size: usize,
|
||||
/// Backing db cache_size
|
||||
pub db_cache_size: Option<usize>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@ -32,8 +30,6 @@ impl Default for Config {
|
||||
Config {
|
||||
pref_cache_size: 1 << 14,
|
||||
max_cache_size: 1 << 20,
|
||||
db_cache_size: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,11 @@ impl Pricer for ModexpPricer {
|
||||
|
||||
let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low);
|
||||
|
||||
(Self::mult_complexity(m) * max(adjusted_exp_len, 1) / self.divisor as u64).into()
|
||||
let (gas, overflow) = Self::mult_complexity(m).overflowing_mul(max(adjusted_exp_len, 1));
|
||||
if overflow {
|
||||
return U256::max_value();
|
||||
}
|
||||
(gas / self.divisor as u64).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,6 +710,14 @@ mod tests {
|
||||
activate_at: 0,
|
||||
};
|
||||
|
||||
// test for potential gas cost multiplication overflow
|
||||
{
|
||||
let input = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3").unwrap();
|
||||
let expected_cost = U256::max_value();
|
||||
assert_eq!(f.cost(&input[..]), expected_cost.into());
|
||||
}
|
||||
|
||||
|
||||
// test for potential exp len overflow
|
||||
{
|
||||
let input = FromHex::from_hex("\
|
||||
|
@ -1230,18 +1230,18 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
|
||||
const UPPER_CEILING: u64 = 1_000_000_000_000u64;
|
||||
let (mut upper, env_info) = {
|
||||
let (mut upper, max_upper, env_info) = {
|
||||
let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?;
|
||||
let initial_upper = env_info.gas_limit;
|
||||
env_info.gas_limit = UPPER_CEILING.into();
|
||||
(initial_upper, env_info)
|
||||
let init = env_info.gas_limit;
|
||||
let max = init * U256::from(10);
|
||||
env_info.gas_limit = max;
|
||||
(init, max, env_info)
|
||||
};
|
||||
|
||||
// that's just a copy of the state.
|
||||
let original_state = self.state_at(block).ok_or(CallError::StatePruned)?;
|
||||
let sender = t.sender();
|
||||
let options = || TransactOptions::with_tracing();
|
||||
let options = || TransactOptions::with_tracing().dont_check_nonce();
|
||||
|
||||
let cond = |gas| {
|
||||
let mut tx = t.as_unsigned().clone();
|
||||
@ -1256,9 +1256,7 @@ impl BlockChainClient for Client {
|
||||
};
|
||||
|
||||
if !cond(upper)? {
|
||||
// impossible at block gas limit - try `UPPER_CEILING` instead.
|
||||
// TODO: consider raising limit by powers of two.
|
||||
upper = UPPER_CEILING.into();
|
||||
upper = max_upper;
|
||||
if !cond(upper)? {
|
||||
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
||||
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
|
||||
@ -1871,7 +1869,7 @@ impl MiningBlockChainClient for Client {
|
||||
.find_uncle_headers(&h, engine.maximum_uncle_age())
|
||||
.unwrap_or_else(Vec::new)
|
||||
.into_iter()
|
||||
.take(engine.maximum_uncle_count())
|
||||
.take(engine.maximum_uncle_count(open_block.header().number()))
|
||||
.foreach(|h| {
|
||||
open_block.push_uncle(h).expect("pushing maximum_uncle_count;
|
||||
open_block was just created;
|
||||
@ -1886,7 +1884,7 @@ impl MiningBlockChainClient for Client {
|
||||
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
|
||||
let engine = &*self.engine;
|
||||
let mut block = block.reopen(engine);
|
||||
let max_uncles = engine.maximum_uncle_count();
|
||||
let max_uncles = engine.maximum_uncle_count(block.header().number());
|
||||
if block.uncles().len() < max_uncles {
|
||||
let chain = self.chain.read();
|
||||
let h = chain.best_block_hash();
|
||||
|
@ -21,7 +21,7 @@ use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
use mode::Mode as IpcMode;
|
||||
use verification::{VerifierType, QueueConfig};
|
||||
use util::journaldb;
|
||||
use kvdb::CompactionProfile;
|
||||
use kvdb_rocksdb::CompactionProfile;
|
||||
|
||||
pub use std::time::Duration;
|
||||
pub use blockchain::Config as BlockChainConfig;
|
||||
@ -141,7 +141,7 @@ pub struct ClientConfig {
|
||||
pub pruning: journaldb::Algorithm,
|
||||
/// The name of the client instance.
|
||||
pub name: String,
|
||||
/// RocksDB state column cache-size if not default
|
||||
/// RocksDB column cache-size if not default
|
||||
pub db_cache_size: Option<usize>,
|
||||
/// State db compaction profile
|
||||
pub db_compaction: DatabaseCompactionProfile,
|
||||
|
@ -21,8 +21,7 @@ use std::sync::Arc;
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use util::journaldb;
|
||||
use trie;
|
||||
use bytes;
|
||||
use {trie, kvdb_memorydb, bytes};
|
||||
use kvdb::{self, KeyValueDB};
|
||||
use {state, state_db, client, executive, trace, transaction, db, spec, pod_state};
|
||||
use factory::Factories;
|
||||
@ -128,7 +127,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
}
|
||||
|
||||
fn state_from_spec(spec: &'a spec::Spec, factories: &Factories) -> Result<state::State<state_db::StateDB>, EvmTestError> {
|
||||
let db = Arc::new(kvdb::in_memory(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let db = Arc::new(kvdb_memorydb::create(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, db::COL_STATE);
|
||||
let mut state_db = state_db::StateDB::new(journal_db, 5 * 1024 * 1024);
|
||||
state_db = spec.ensure_db_good(state_db, factories)?;
|
||||
@ -150,7 +149,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
}
|
||||
|
||||
fn state_from_pod(spec: &'a spec::Spec, factories: &Factories, pod_state: pod_state::PodState) -> Result<state::State<state_db::StateDB>, EvmTestError> {
|
||||
let db = Arc::new(kvdb::in_memory(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let db = Arc::new(kvdb_memorydb::create(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, db::COL_STATE);
|
||||
let state_db = state_db::StateDB::new(journal_db, 5 * 1024 * 1024);
|
||||
let mut state = state::State::new(
|
||||
|
@ -27,7 +27,7 @@ use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use parking_lot::RwLock;
|
||||
use util::*;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use bytes::Bytes;
|
||||
use rlp::*;
|
||||
use ethkey::{Generator, Random};
|
||||
|
@ -44,15 +44,18 @@ use bigint::hash::{H256, H520};
|
||||
use semantic_version::SemanticVersion;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use unexpected::{Mismatch, OutOfBounds};
|
||||
use util::*;
|
||||
use bytes::Bytes;
|
||||
use util::Address;
|
||||
|
||||
mod finality;
|
||||
|
||||
/// `AuthorityRound` params.
|
||||
pub struct AuthorityRoundParams {
|
||||
/// Time to wait before next block or authority switching.
|
||||
pub step_duration: Duration,
|
||||
/// Time to wait before next block or authority switching,
|
||||
/// in seconds.
|
||||
///
|
||||
/// Deliberately typed as u16 as too high of a value leads
|
||||
/// to slow block issuance.
|
||||
pub step_duration: u16,
|
||||
/// Starting step,
|
||||
pub start_step: Option<u64>,
|
||||
/// Valid validators.
|
||||
@ -65,18 +68,31 @@ pub struct AuthorityRoundParams {
|
||||
pub immediate_transitions: bool,
|
||||
/// Block reward in base units.
|
||||
pub block_reward: U256,
|
||||
/// Number of accepted uncles transition block.
|
||||
pub maximum_uncle_count_transition: u64,
|
||||
/// Number of accepted uncles.
|
||||
pub maximum_uncle_count: usize,
|
||||
}
|
||||
|
||||
const U16_MAX: usize = ::std::u16::MAX as usize;
|
||||
|
||||
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
fn from(p: ethjson::spec::AuthorityRoundParams) -> Self {
|
||||
let mut step_duration_usize: usize = p.step_duration.into();
|
||||
if step_duration_usize > U16_MAX {
|
||||
step_duration_usize = U16_MAX;
|
||||
warn!(target: "engine", "step_duration is too high ({}), setting it to {}", step_duration_usize, U16_MAX);
|
||||
}
|
||||
AuthorityRoundParams {
|
||||
step_duration: Duration::from_secs(p.step_duration.into()),
|
||||
step_duration: step_duration_usize as u16,
|
||||
validators: new_validator_set(p.validators),
|
||||
start_step: p.start_step.map(Into::into),
|
||||
validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
|
||||
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
||||
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
||||
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
|
||||
maximum_uncle_count_transition: p.maximum_uncle_count_transition.map_or(0, Into::into),
|
||||
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,40 +102,83 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
struct Step {
|
||||
calibrate: bool, // whether calibration is enabled.
|
||||
inner: AtomicUsize,
|
||||
duration: Duration,
|
||||
duration: u16,
|
||||
}
|
||||
|
||||
impl Step {
|
||||
fn load(&self) -> usize { self.inner.load(AtomicOrdering::SeqCst) }
|
||||
fn duration_remaining(&self) -> Duration {
|
||||
let now = unix_now();
|
||||
let step_end = self.duration * (self.load() as u32 + 1);
|
||||
if step_end > now {
|
||||
step_end - now
|
||||
} else {
|
||||
Duration::from_secs(0)
|
||||
let expected_seconds = (self.load() as u64)
|
||||
.checked_add(1)
|
||||
.and_then(|ctr| ctr.checked_mul(self.duration as u64))
|
||||
.map(Duration::from_secs);
|
||||
|
||||
match expected_seconds {
|
||||
Some(step_end) if step_end > now => step_end - now,
|
||||
Some(_) => Duration::from_secs(0),
|
||||
None => {
|
||||
let ctr = self.load();
|
||||
error!(target: "engine", "Step counter is too high: {}, aborting", ctr);
|
||||
panic!("step counter is too high: {}", ctr)
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn increment(&self) {
|
||||
self.inner.fetch_add(1, AtomicOrdering::SeqCst);
|
||||
use std::usize;
|
||||
// fetch_add won't panic on overflow but will rather wrap
|
||||
// around, leading to zero as the step counter, which might
|
||||
// lead to unexpected situations, so it's better to shut down.
|
||||
if self.inner.fetch_add(1, AtomicOrdering::SeqCst) == usize::MAX {
|
||||
error!(target: "engine", "Step counter is too high: {}, aborting", usize::MAX);
|
||||
panic!("step counter is too high: {}", usize::MAX);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn calibrate(&self) {
|
||||
if self.calibrate {
|
||||
let new_step = unix_now().as_secs() / self.duration.as_secs();
|
||||
let new_step = unix_now().as_secs() / (self.duration as u64);
|
||||
self.inner.store(new_step as usize, AtomicOrdering::SeqCst);
|
||||
}
|
||||
}
|
||||
fn is_future(&self, given: usize) -> bool {
|
||||
if given > self.load() + 1 {
|
||||
// Make absolutely sure that the given step is correct.
|
||||
self.calibrate();
|
||||
given > self.load() + 1
|
||||
|
||||
fn check_future(&self, given: usize) -> Result<(), Option<OutOfBounds<u64>>> {
|
||||
const REJECTED_STEP_DRIFT: usize = 4;
|
||||
|
||||
// Verify if the step is correct.
|
||||
if given <= self.load() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Make absolutely sure that the given step is incorrect.
|
||||
self.calibrate();
|
||||
let current = self.load();
|
||||
|
||||
// reject blocks too far in the future
|
||||
if given > current + REJECTED_STEP_DRIFT {
|
||||
Err(None)
|
||||
// wait a bit for blocks in near future
|
||||
} else if given > current {
|
||||
let d = self.duration as u64;
|
||||
Err(Some(OutOfBounds {
|
||||
min: None,
|
||||
max: Some(d * current as u64),
|
||||
found: d * given as u64,
|
||||
}))
|
||||
} else {
|
||||
false
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||
fn calculate_score(parent_step: U256, current_step: U256) -> U256 {
|
||||
U256::from(U128::max_value()) + parent_step - current_step
|
||||
}
|
||||
|
||||
struct EpochManager {
|
||||
epoch_transition_hash: H256,
|
||||
epoch_transition_number: BlockNumber,
|
||||
@ -218,6 +277,8 @@ pub struct AuthorityRound {
|
||||
epoch_manager: Mutex<EpochManager>,
|
||||
immediate_transitions: bool,
|
||||
block_reward: U256,
|
||||
maximum_uncle_count_transition: u64,
|
||||
maximum_uncle_count: usize,
|
||||
machine: EthereumMachine,
|
||||
}
|
||||
|
||||
@ -229,9 +290,11 @@ struct EpochVerifier {
|
||||
|
||||
impl super::EpochVerifier<EthereumMachine> for EpochVerifier {
|
||||
fn verify_light(&self, header: &Header) -> Result<(), Error> {
|
||||
// Validate the timestamp
|
||||
verify_timestamp(&*self.step, header_step(header)?)?;
|
||||
// always check the seal since it's fast.
|
||||
// nothing heavier to do.
|
||||
verify_external(header, &self.subchain_validators, &*self.step, |_| {})
|
||||
verify_external(header, &self.subchain_validators)
|
||||
}
|
||||
|
||||
fn check_finality_proof(&self, proof: &[u8]) -> Option<Vec<H256>> {
|
||||
@ -255,7 +318,7 @@ impl super::EpochVerifier<EthereumMachine> for EpochVerifier {
|
||||
//
|
||||
// `verify_external` checks that signature is correct and author == signer.
|
||||
if header.seal().len() != 2 { return None }
|
||||
otry!(verify_external(header, &self.subchain_validators, &*self.step, |_| {}).ok());
|
||||
otry!(verify_external(header, &self.subchain_validators).ok());
|
||||
|
||||
let newly_finalized = otry!(finality_checker.push_hash(header.hash(), header.author().clone()).ok());
|
||||
finalized.extend(newly_finalized);
|
||||
@ -265,16 +328,6 @@ impl super::EpochVerifier<EthereumMachine> for EpochVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Report misbehavior
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
enum Report {
|
||||
// Malicious behavior
|
||||
Malicious(Address, BlockNumber, Bytes),
|
||||
// benign misbehavior
|
||||
Benign(Address, BlockNumber),
|
||||
}
|
||||
|
||||
fn header_step(header: &Header) -> Result<usize, ::rlp::DecoderError> {
|
||||
UntrustedRlp::new(&header.seal().get(0).expect("was either checked with verify_block_basic or is genesis; has 2 fields; qed (Make sure the spec file has a correct genesis seal)")).as_val()
|
||||
}
|
||||
@ -293,28 +346,35 @@ fn is_step_proposer(validators: &ValidatorSet, bh: &H256, step: usize, address:
|
||||
step_proposer(validators, bh, step) == *address
|
||||
}
|
||||
|
||||
fn verify_external<F: Fn(Report)>(header: &Header, validators: &ValidatorSet, step: &Step, report: F)
|
||||
-> Result<(), Error>
|
||||
{
|
||||
fn verify_timestamp(step: &Step, header_step: usize) -> Result<(), BlockError> {
|
||||
match step.check_future(header_step) {
|
||||
Err(None) => {
|
||||
trace!(target: "engine", "verify_timestamp: block from the future");
|
||||
Err(BlockError::InvalidSeal.into())
|
||||
},
|
||||
Err(Some(oob)) => {
|
||||
// NOTE This error might be returned only in early stage of verification (Stage 1).
|
||||
// Returning it further won't recover the sync process.
|
||||
trace!(target: "engine", "verify_timestamp: block too early");
|
||||
Err(BlockError::TemporarilyInvalid(oob).into())
|
||||
},
|
||||
Ok(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Error> {
|
||||
let header_step = header_step(header)?;
|
||||
|
||||
// Give one step slack if step is lagging, double vote is still not possible.
|
||||
if step.is_future(header_step) {
|
||||
trace!(target: "engine", "verify_block_external: block from the future");
|
||||
report(Report::Benign(*header.author(), header.number()));
|
||||
Err(BlockError::InvalidSeal)?
|
||||
} else {
|
||||
let proposer_signature = header_signature(header)?;
|
||||
let correct_proposer = validators.get(header.parent_hash(), header_step);
|
||||
let is_invalid_proposer = *header.author() != correct_proposer ||
|
||||
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
|
||||
let proposer_signature = header_signature(header)?;
|
||||
let correct_proposer = validators.get(header.parent_hash(), header_step);
|
||||
let is_invalid_proposer = *header.author() != correct_proposer ||
|
||||
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
|
||||
|
||||
if is_invalid_proposer {
|
||||
trace!(target: "engine", "verify_block_external: bad proposer for step: {}", header_step);
|
||||
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
if is_invalid_proposer {
|
||||
trace!(target: "engine", "verify_block_external: bad proposer for step: {}", header_step);
|
||||
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,8 +406,12 @@ impl AsMillis for Duration {
|
||||
impl AuthorityRound {
|
||||
/// Create a new instance of AuthorityRound engine.
|
||||
pub fn new(our_params: AuthorityRoundParams, machine: EthereumMachine) -> Result<Arc<Self>, Error> {
|
||||
if our_params.step_duration == 0 {
|
||||
error!(target: "engine", "Authority Round step duration can't be zero, aborting");
|
||||
panic!("authority_round: step duration can't be zero")
|
||||
}
|
||||
let should_timeout = our_params.start_step.is_none();
|
||||
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / our_params.step_duration.as_secs())) as usize;
|
||||
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / (our_params.step_duration as u64))) as usize;
|
||||
let engine = Arc::new(
|
||||
AuthorityRound {
|
||||
transition_service: IoService::<()>::start()?,
|
||||
@ -365,6 +429,8 @@ impl AuthorityRound {
|
||||
epoch_manager: Mutex::new(EpochManager::blank()),
|
||||
immediate_transitions: our_params.immediate_transitions,
|
||||
block_reward: our_params.block_reward,
|
||||
maximum_uncle_count_transition: our_params.maximum_uncle_count_transition,
|
||||
maximum_uncle_count: our_params.maximum_uncle_count,
|
||||
machine: machine,
|
||||
});
|
||||
|
||||
@ -399,9 +465,15 @@ impl IoHandler<()> for TransitionHandler {
|
||||
fn timeout(&self, io: &IoContext<()>, timer: TimerToken) {
|
||||
if timer == ENGINE_TIMEOUT_TOKEN {
|
||||
if let Some(engine) = self.engine.upgrade() {
|
||||
engine.step();
|
||||
let remaining = engine.step.duration_remaining();
|
||||
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining.as_millis())
|
||||
// NOTE we might be lagging by couple of steps in case the timeout
|
||||
// has not been called fast enough.
|
||||
// Make sure to advance up to the actual step.
|
||||
while engine.step.duration_remaining().as_millis() == 0 {
|
||||
engine.step();
|
||||
}
|
||||
|
||||
let next_run_at = engine.step.duration_remaining().as_millis() >> 2;
|
||||
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, next_run_at)
|
||||
.unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e))
|
||||
}
|
||||
}
|
||||
@ -436,13 +508,23 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
]
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, block: BlockNumber) -> usize {
|
||||
if block >= self.maximum_uncle_count_transition {
|
||||
self.maximum_uncle_count
|
||||
} else {
|
||||
// fallback to default value
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||
let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load().into();
|
||||
header.set_difficulty(new_difficulty);
|
||||
let parent_step = header_step(parent).expect("Header has been verified; qed");
|
||||
let score = calculate_score(parent_step.into(), self.step.load().into());
|
||||
header.set_difficulty(score);
|
||||
}
|
||||
|
||||
fn seals_internally(&self) -> Option<bool> {
|
||||
// TODO: accept a `&Call` here so we can query the validator set.
|
||||
Some(self.signer.read().is_some())
|
||||
}
|
||||
|
||||
@ -450,14 +532,30 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
///
|
||||
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
||||
/// `Seal::None` will be returned.
|
||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||
fn generate_seal(&self, block: &ExecutedBlock, parent: &Header) -> Seal {
|
||||
// first check to avoid generating signature most of the time
|
||||
// (but there's still a race to the `compare_and_swap`)
|
||||
if !self.can_propose.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
||||
|
||||
let header = block.header();
|
||||
let parent_step: U256 = header_step(parent)
|
||||
.expect("Header has been verified; qed").into();
|
||||
|
||||
let step = self.step.load();
|
||||
|
||||
let expected_diff = calculate_score(parent_step, step.into());
|
||||
|
||||
if header.difficulty() != &expected_diff {
|
||||
debug!(target: "engine", "Aborting seal generation. The step has changed in the meantime. {:?} != {:?}",
|
||||
header.difficulty(), expected_diff);
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
if parent_step > step.into() {
|
||||
warn!(target: "engine", "Aborting seal generation for invalid step: {} > {}", parent_step, step);
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
// fetch correct validator set for current epoch, taking into account
|
||||
// finality of previous transitions.
|
||||
let active_set;
|
||||
@ -484,6 +582,13 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
};
|
||||
|
||||
if is_step_proposer(validators, header.parent_hash(), step, header.author()) {
|
||||
// this is guarded against by `can_propose` unless the block was signed
|
||||
// on the same step (implies same key) and on a different node.
|
||||
if parent_step == step.into() {
|
||||
warn!("Attempted to seal block on the same step as parent. Is this authority sealing with more than one node?");
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
if let Ok(signature) = self.sign(header.bare_hash()) {
|
||||
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
|
||||
|
||||
@ -498,6 +603,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
trace!(target: "engine", "generate_seal: {} not a proposer for step {}.",
|
||||
header.author(), step);
|
||||
}
|
||||
|
||||
Seal::None
|
||||
}
|
||||
|
||||
@ -539,28 +645,40 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
}
|
||||
|
||||
/// Check the number of seal fields.
|
||||
fn verify_block_basic(&self, header: &Header,) -> Result<(), Error> {
|
||||
fn verify_block_basic(&self, header: &Header) -> Result<(), Error> {
|
||||
if header.number() >= self.validate_score_transition && *header.difficulty() >= U256::from(U128::max_value()) {
|
||||
Err(From::from(BlockError::DifficultyOutOfBounds(
|
||||
return Err(From::from(BlockError::DifficultyOutOfBounds(
|
||||
OutOfBounds { min: None, max: Some(U256::from(U128::max_value())), found: *header.difficulty() }
|
||||
)))
|
||||
} else {
|
||||
Ok(())
|
||||
)));
|
||||
}
|
||||
|
||||
// TODO [ToDr] Should this go from epoch manager?
|
||||
// If yes then probably benign reporting needs to be moved further in the verification.
|
||||
let set_number = header.number();
|
||||
|
||||
match verify_timestamp(&*self.step, header_step(header)?) {
|
||||
Err(BlockError::InvalidSeal) => {
|
||||
self.validators.report_benign(header.author(), set_number, header.number());
|
||||
Err(BlockError::InvalidSeal.into())
|
||||
}
|
||||
Err(e) => Err(e.into()),
|
||||
Ok(()) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Do the step and gas limit validation.
|
||||
fn verify_block_family(&self, header: &Header, parent: &Header) -> Result<(), Error> {
|
||||
let step = header_step(header)?;
|
||||
|
||||
let parent_step = header_step(parent)?;
|
||||
// TODO [ToDr] Should this go from epoch manager?
|
||||
let set_number = header.number();
|
||||
|
||||
// Ensure header is from the step after parent.
|
||||
if step == parent_step
|
||||
|| (header.number() >= self.validate_step_transition && step <= parent_step) {
|
||||
trace!(target: "engine", "Multiple blocks proposed for step {}.", parent_step);
|
||||
|
||||
self.validators.report_malicious(header.author(), header.number(), header.number(), Default::default());
|
||||
self.validators.report_malicious(header.author(), set_number, header.number(), Default::default());
|
||||
Err(EngineError::DoubleVote(header.author().clone()))?;
|
||||
}
|
||||
|
||||
@ -573,7 +691,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
let skipped_primary = step_proposer(&*self.validators, &parent.hash(), s);
|
||||
// Do not report this signer.
|
||||
if skipped_primary != me {
|
||||
self.validators.report_benign(&skipped_primary, header.number(), header.number());
|
||||
self.validators.report_benign(&skipped_primary, set_number, header.number());
|
||||
}
|
||||
// Stop reporting once validators start repeating.
|
||||
if !reported.insert(skipped_primary) { break; }
|
||||
@ -588,9 +706,8 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
// fetch correct validator set for current epoch, taking into account
|
||||
// finality of previous transitions.
|
||||
let active_set;
|
||||
|
||||
let (validators, set_number) = if self.immediate_transitions {
|
||||
(&*self.validators, header.number())
|
||||
let validators = if self.immediate_transitions {
|
||||
&*self.validators
|
||||
} else {
|
||||
// get correct validator set for epoch.
|
||||
let client = match self.client.read().as_ref().and_then(|weak| weak.upgrade()) {
|
||||
@ -608,21 +725,12 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
}
|
||||
|
||||
active_set = epoch_manager.validators().clone();
|
||||
(&active_set as &_, epoch_manager.epoch_transition_number)
|
||||
};
|
||||
|
||||
// always report with "self.validators" so that the report actually gets
|
||||
// to the contract.
|
||||
let report = |report| match report {
|
||||
Report::Benign(address, block_number) =>
|
||||
self.validators.report_benign(&address, set_number, block_number),
|
||||
Report::Malicious(address, block_number, proof) =>
|
||||
self.validators.report_malicious(&address, set_number, block_number, proof),
|
||||
&active_set as &_
|
||||
};
|
||||
|
||||
// verify signature against fixed list, but reports should go to the
|
||||
// contract itself.
|
||||
verify_external(header, validators, &*self.step, report)
|
||||
verify_external(header, validators)
|
||||
}
|
||||
|
||||
fn genesis_epoch_data(&self, header: &Header, call: &Call) -> Result<Vec<u8>, String> {
|
||||
@ -850,17 +958,51 @@ mod tests {
|
||||
let b2 = b2.close_and_lock();
|
||||
|
||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b1.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) {
|
||||
assert!(b1.clone().try_seal(engine, seal).is_ok());
|
||||
// Second proposal is forbidden.
|
||||
assert!(engine.generate_seal(b1.block()) == Seal::None);
|
||||
assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None);
|
||||
}
|
||||
|
||||
engine.set_signer(tap, addr2, "2".into());
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b2.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) {
|
||||
assert!(b2.clone().try_seal(engine, seal).is_ok());
|
||||
// Second proposal is forbidden.
|
||||
assert!(engine.generate_seal(b2.block()) == Seal::None);
|
||||
assert!(engine.generate_seal(b2.block(), &genesis_header) == Seal::None);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checks_difficulty_in_generate_seal() {
|
||||
let tap = Arc::new(AccountProvider::transient_provider());
|
||||
let addr1 = tap.insert_account(keccak("1").into(), "1").unwrap();
|
||||
let addr2 = tap.insert_account(keccak("0").into(), "0").unwrap();
|
||||
|
||||
let spec = Spec::new_test_round();
|
||||
let engine = &*spec.engine;
|
||||
|
||||
let genesis_header = spec.genesis_header();
|
||||
let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||
let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
|
||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||
let b1 = b1.close_and_lock();
|
||||
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||
let b2 = b2.close_and_lock();
|
||||
|
||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||
match engine.generate_seal(b1.block(), &genesis_header) {
|
||||
Seal::None | Seal::Proposal(_) => panic!("wrong seal"),
|
||||
Seal::Regular(_) => {
|
||||
engine.step();
|
||||
|
||||
engine.set_signer(tap.clone(), addr2, "0".into());
|
||||
match engine.generate_seal(b2.block(), &genesis_header) {
|
||||
Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"),
|
||||
Seal::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -911,8 +1053,7 @@ mod tests {
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||
assert!(engine.verify_block_external(&header).is_ok());
|
||||
header.set_seal(vec![encode(&5usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
|
||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||
assert!(engine.verify_block_external(&header).is_err());
|
||||
assert!(engine.verify_block_basic(&header).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -943,12 +1084,14 @@ mod tests {
|
||||
fn reports_skipped() {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
step_duration: Default::default(),
|
||||
step_duration: 1,
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 0,
|
||||
maximum_uncle_count: 0,
|
||||
block_reward: Default::default(),
|
||||
};
|
||||
|
||||
@ -976,4 +1119,78 @@ mod tests {
|
||||
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
||||
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uncles_transition() {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
step_duration: 1,
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 1,
|
||||
maximum_uncle_count: 0,
|
||||
block_reward: Default::default(),
|
||||
};
|
||||
|
||||
let aura = {
|
||||
let mut c_params = ::spec::CommonParams::default();
|
||||
c_params.gas_limit_bound_divisor = 5.into();
|
||||
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
||||
AuthorityRound::new(params, machine).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(aura.maximum_uncle_count(0), 2);
|
||||
assert_eq!(aura.maximum_uncle_count(1), 0);
|
||||
assert_eq!(aura.maximum_uncle_count(100), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="counter is too high")]
|
||||
fn test_counter_increment_too_high() {
|
||||
use super::Step;
|
||||
let step = Step {
|
||||
calibrate: false,
|
||||
inner: AtomicUsize::new(::std::usize::MAX),
|
||||
duration: 1,
|
||||
};
|
||||
step.increment();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="counter is too high")]
|
||||
fn test_counter_duration_remaining_too_high() {
|
||||
use super::Step;
|
||||
let step = Step {
|
||||
calibrate: false,
|
||||
inner: AtomicUsize::new(::std::usize::MAX),
|
||||
duration: 1,
|
||||
};
|
||||
step.duration_remaining();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="authority_round: step duration can't be zero")]
|
||||
fn test_step_duration_zero() {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
step_duration: 0,
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 0,
|
||||
maximum_uncle_count: 0,
|
||||
block_reward: Default::default(),
|
||||
};
|
||||
|
||||
let mut c_params = ::spec::CommonParams::default();
|
||||
c_params.gas_limit_bound_divisor = 5.into();
|
||||
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
||||
AuthorityRound::new(params, machine).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ impl Engine<EthereumMachine> for BasicAuthority {
|
||||
}
|
||||
|
||||
/// Attempt to seal the block internally.
|
||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||
let header = block.header();
|
||||
let author = header.author();
|
||||
if self.validators.contains(header.parent_hash(), author) {
|
||||
@ -251,7 +251,7 @@ mod tests {
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) {
|
||||
assert!(b.try_seal(engine, seal).is_ok());
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ impl<M: Machine> Engine<M> for InstantSeal<M>
|
||||
|
||||
fn seals_internally(&self) -> Option<bool> { Some(true) }
|
||||
|
||||
fn generate_seal(&self, block: &M::LiveBlock) -> Seal {
|
||||
fn generate_seal(&self, block: &M::LiveBlock, _parent: &M::Header) -> Seal {
|
||||
if block.transactions().is_empty() { Seal::None } else { Seal::Regular(Vec::new()) }
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ mod tests {
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block()) {
|
||||
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) {
|
||||
assert!(b.try_seal(engine, seal).is_ok());
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,8 @@ pub trait Engine<M: Machine>: Sync + Send {
|
||||
fn extra_info(&self, _header: &M::Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
||||
|
||||
/// Maximum number of uncles a block is allowed to declare.
|
||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||
|
||||
/// The number of generations back that uncles can be.
|
||||
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||
|
||||
@ -225,7 +226,7 @@ pub trait Engine<M: Machine>: Sync + Send {
|
||||
///
|
||||
/// It is fine to require access to state or a full client for this function, since
|
||||
/// light clients do not generate seals.
|
||||
fn generate_seal(&self, _block: &M::LiveBlock) -> Seal { Seal::None }
|
||||
fn generate_seal(&self, _block: &M::LiveBlock, _parent: &M::Header) -> Seal { Seal::None }
|
||||
|
||||
/// Verify a locally-generated seal of a header.
|
||||
///
|
||||
@ -363,7 +364,7 @@ pub trait EthEngine: Engine<::machine::EthereumMachine> {
|
||||
}
|
||||
|
||||
/// The nonce with which accounts begin at given block.
|
||||
fn account_start_nonce(&self, block: u64) -> U256 {
|
||||
fn account_start_nonce(&self, block: BlockNumber) -> U256 {
|
||||
self.machine().account_start_nonce(block)
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use bigint::prelude::U256;
|
||||
use engines::Engine;
|
||||
use header::BlockNumber;
|
||||
use parity_machine::{Header, LiveBlock, WithBalances};
|
||||
|
||||
/// Params for a null engine.
|
||||
@ -95,6 +96,8 @@ impl<M: WithBalances> Engine<M> for NullEngine<M> {
|
||||
self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards)
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||
|
||||
fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ impl Engine<EthereumMachine> for Tendermint {
|
||||
|
||||
fn machine(&self) -> &EthereumMachine { &self.machine }
|
||||
|
||||
fn maximum_uncle_count(&self) -> usize { 0 }
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||
|
||||
fn maximum_uncle_age(&self) -> usize { 0 }
|
||||
|
||||
@ -483,7 +483,7 @@ impl Engine<EthereumMachine> for Tendermint {
|
||||
///
|
||||
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
||||
/// `Seal::None` will be returned.
|
||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||
let header = block.header();
|
||||
let author = header.author();
|
||||
// Only proposer can generate seal if None was generated.
|
||||
@ -805,7 +805,7 @@ mod tests {
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||
let b = b.close();
|
||||
if let Seal::Proposal(seal) = spec.engine.generate_seal(b.block()) {
|
||||
if let Seal::Proposal(seal) = spec.engine.generate_seal(b.block(), &genesis_header) {
|
||||
(b, seal)
|
||||
} else {
|
||||
panic!()
|
||||
|
@ -171,22 +171,36 @@ mod tests {
|
||||
|
||||
// Make sure reporting can be done.
|
||||
client.miner().set_gas_floor_target(1_000_000.into());
|
||||
|
||||
client.miner().set_engine_signer(v1, "".into()).unwrap();
|
||||
|
||||
// Check a block that is a bit in future, reject it but don't report the validator.
|
||||
let mut header = Header::default();
|
||||
let seal = vec![encode(&5u8).into_vec(), encode(&(&H520::default() as &[u8])).into_vec()];
|
||||
header.set_seal(seal);
|
||||
header.set_author(v1);
|
||||
header.set_number(2);
|
||||
header.set_parent_hash(client.chain_info().best_block_hash);
|
||||
|
||||
// `reportBenign` when the designated proposer releases block from the future (bad clock).
|
||||
assert!(client.engine().verify_block_external(&header).is_err());
|
||||
client.engine().step();
|
||||
assert_eq!(client.chain_info().best_block_number, 0);
|
||||
|
||||
// Now create one that is more in future. That one should be rejected and validator should be reported.
|
||||
let mut header = Header::default();
|
||||
let seal = vec![encode(&8u8).into_vec(), encode(&(&H520::default() as &[u8])).into_vec()];
|
||||
header.set_seal(seal);
|
||||
header.set_author(v1);
|
||||
header.set_number(2);
|
||||
header.set_parent_hash(client.chain_info().best_block_hash);
|
||||
// `reportBenign` when the designated proposer releases block from the future (bad clock).
|
||||
assert!(client.engine().verify_block_basic(&header).is_err());
|
||||
// Seal a block.
|
||||
client.engine().step();
|
||||
assert_eq!(client.chain_info().best_block_number, 1);
|
||||
// Check if the unresponsive validator is `disliked`.
|
||||
assert_eq!(client.call_contract(BlockId::Latest, validator_contract, "d8f2e0bf".from_hex().unwrap()).unwrap().to_hex(), "0000000000000000000000007d577a597b2742b498cb5cf0c26cdcd726d39e6e");
|
||||
assert_eq!(
|
||||
client.call_contract(BlockId::Latest, validator_contract, "d8f2e0bf".from_hex().unwrap()).unwrap().to_hex(),
|
||||
"0000000000000000000000007d577a597b2742b498cb5cf0c26cdcd726d39e6e"
|
||||
);
|
||||
// Simulate a misbehaving validator by handling a double proposal.
|
||||
let header = client.best_block_header().decode();
|
||||
assert!(client.engine().verify_block_family(&header, &header).is_err());
|
||||
|
@ -168,6 +168,8 @@ pub enum BlockError {
|
||||
InvalidReceiptsRoot(Mismatch<H256>),
|
||||
/// Timestamp header field is invalid.
|
||||
InvalidTimestamp(OutOfBounds<u64>),
|
||||
/// Timestamp header field is too far in future.
|
||||
TemporarilyInvalid(OutOfBounds<u64>),
|
||||
/// Log bloom header field is invalid.
|
||||
InvalidLogBloom(Mismatch<LogBloom>),
|
||||
/// Parent hash field of header is invalid; this is an invalid error indicating a logic flaw in the codebase.
|
||||
@ -213,6 +215,7 @@ impl fmt::Display for BlockError {
|
||||
InvalidGasLimit(ref oob) => format!("Invalid gas limit: {}", oob),
|
||||
InvalidReceiptsRoot(ref mis) => format!("Invalid receipts trie root in header: {}", mis),
|
||||
InvalidTimestamp(ref oob) => format!("Invalid timestamp in header: {}", oob),
|
||||
TemporarilyInvalid(ref oob) => format!("Future timestamp in header: {}", oob),
|
||||
InvalidLogBloom(ref oob) => format!("Invalid log bloom in header: {}", oob),
|
||||
InvalidParentHash(ref mis) => format!("Invalid parent hash: {}", mis),
|
||||
InvalidNumber(ref mis) => format!("Invalid number in header: {}", mis),
|
||||
|
@ -26,7 +26,7 @@ use util::Address;
|
||||
use unexpected::{OutOfBounds, Mismatch};
|
||||
use block::*;
|
||||
use error::{BlockError, Error};
|
||||
use header::Header;
|
||||
use header::{Header, BlockNumber};
|
||||
use engines::{self, Engine};
|
||||
use ethjson;
|
||||
use rlp::{self, UntrustedRlp};
|
||||
@ -90,6 +90,10 @@ pub struct EthashParams {
|
||||
pub eip649_delay: u64,
|
||||
/// EIP-649 base reward.
|
||||
pub eip649_reward: Option<U256>,
|
||||
/// EXPIP-2 block height
|
||||
pub expip2_transition: u64,
|
||||
/// EXPIP-2 duration limit
|
||||
pub expip2_duration_limit: u64,
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
@ -118,6 +122,8 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into),
|
||||
eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into),
|
||||
eip649_reward: p.eip649_reward.map(Into::into),
|
||||
expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into),
|
||||
expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,6 +187,8 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
}
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||
let difficulty = self.calculate_difficulty(header, parent);
|
||||
header.set_difficulty(difficulty);
|
||||
@ -353,7 +361,13 @@ impl Ethash {
|
||||
self.ethash_params.difficulty_bound_divisor
|
||||
};
|
||||
|
||||
let duration_limit = self.ethash_params.duration_limit;
|
||||
let expip2_hardfork = header.number() >= self.ethash_params.expip2_transition;
|
||||
let duration_limit = if expip2_hardfork {
|
||||
self.ethash_params.expip2_duration_limit
|
||||
} else {
|
||||
self.ethash_params.duration_limit
|
||||
};
|
||||
|
||||
let frontier_limit = self.ethash_params.homestead_transition;
|
||||
|
||||
let mut target = if header.number() < frontier_limit {
|
||||
@ -362,8 +376,7 @@ impl Ethash {
|
||||
} else {
|
||||
*parent.difficulty() + (*parent.difficulty() / difficulty_bound_divisor)
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
trace!(target: "ethash", "Calculating difficulty parent.difficulty={}, header.timestamp={}, parent.timestamp={}", parent.difficulty(), header.timestamp(), parent.timestamp());
|
||||
//block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)
|
||||
let (increment_divisor, threshold) = if header.number() < self.ethash_params.eip100b_transition {
|
||||
@ -447,9 +460,12 @@ fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u6
|
||||
} else {
|
||||
block_number / era_rounds
|
||||
};
|
||||
let mut divi = U256::from(1);
|
||||
for _ in 0..eras {
|
||||
reward = reward / U256::from(5) * U256::from(4);
|
||||
reward = reward * U256::from(4);
|
||||
divi = divi * U256::from(5);
|
||||
}
|
||||
reward = reward / divi;
|
||||
(eras, reward)
|
||||
}
|
||||
|
||||
@ -515,6 +531,11 @@ mod tests {
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(15, eras);
|
||||
assert_eq!(U256::from_str("271000000000000").unwrap(), reward);
|
||||
|
||||
let block_number = 250000000;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(49, eras);
|
||||
assert_eq!(U256::from_str("51212FFBAF0A").unwrap(), reward);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -31,7 +31,7 @@ use machine::EthereumMachine;
|
||||
use super::spec::*;
|
||||
|
||||
/// Most recent fork block that we support on Mainnet.
|
||||
pub const FORK_SUPPORTED_FOUNDATION: u64 = 2675000;
|
||||
pub const FORK_SUPPORTED_FOUNDATION: u64 = 4370000;
|
||||
|
||||
/// Most recent fork block that we support on Ropsten.
|
||||
pub const FORK_SUPPORTED_ROPSTEN: u64 = 10;
|
||||
|
@ -309,6 +309,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
code: Some(Arc::new(t.data.clone())),
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
params_type: vm::ParamsType::Embedded,
|
||||
};
|
||||
let mut out = if output_from_create { Some(vec![]) } else { None };
|
||||
(self.create(params, &mut substate, &mut out, &mut tracer, &mut vm_tracer), out.unwrap_or_else(Vec::new))
|
||||
@ -326,6 +327,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
code_hash: Some(self.state.code_hash(address)?),
|
||||
data: Some(t.data.clone()),
|
||||
call_type: CallType::Call,
|
||||
params_type: vm::ParamsType::Separate,
|
||||
};
|
||||
let mut out = vec![];
|
||||
(self.call(params, &mut substate, BytesRef::Flexible(&mut out), &mut tracer, &mut vm_tracer), out)
|
||||
@ -484,12 +486,13 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
|
||||
let traces = subtracer.drain();
|
||||
match res {
|
||||
Ok(ref res) => tracer.trace_call(
|
||||
Ok(ref res) if res.apply_state => tracer.trace_call(
|
||||
trace_info,
|
||||
gas - res.gas_left,
|
||||
trace_output,
|
||||
traces
|
||||
),
|
||||
Ok(_) => tracer.trace_failed_call(trace_info, traces, vm::Error::Reverted.into()),
|
||||
Err(ref e) => tracer.trace_failed_call(trace_info, traces, e.into()),
|
||||
};
|
||||
|
||||
@ -572,13 +575,14 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
vm_tracer.done_subtrace(subvmtracer);
|
||||
|
||||
match res {
|
||||
Ok(ref res) => tracer.trace_create(
|
||||
Ok(ref res) if res.apply_state => tracer.trace_create(
|
||||
trace_info,
|
||||
gas - res.gas_left,
|
||||
trace_output.map(|data| output.as_ref().map(|out| out.to_vec()).unwrap_or(data)),
|
||||
created,
|
||||
subtracer.drain()
|
||||
),
|
||||
Ok(_) => tracer.trace_failed_create(trace_info, subtracer.drain(), vm::Error::Reverted.into()),
|
||||
Err(ref e) => tracer.trace_failed_create(trace_info, subtracer.drain(), e.into())
|
||||
};
|
||||
|
||||
@ -934,6 +938,85 @@ mod tests {
|
||||
assert_eq!(vm_tracer.drain().unwrap(), expected_vm_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trace_reverted_create() {
|
||||
// code:
|
||||
//
|
||||
// 65 60016000fd - push 5 bytes
|
||||
// 60 00 - push 0
|
||||
// 52 mstore
|
||||
// 60 05 - push 5
|
||||
// 60 1b - push 27
|
||||
// 60 17 - push 23
|
||||
// f0 - create
|
||||
// 60 00 - push 0
|
||||
// 55 sstore
|
||||
//
|
||||
// other code:
|
||||
//
|
||||
// 60 01
|
||||
// 60 00
|
||||
// fd - revert
|
||||
|
||||
let code = "6460016000fd6000526005601b6017f0600055".from_hex().unwrap();
|
||||
|
||||
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
|
||||
let mut params = ActionParams::default();
|
||||
params.address = address.clone();
|
||||
params.code_address = address.clone();
|
||||
params.sender = sender.clone();
|
||||
params.origin = sender.clone();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.value = ActionValue::Transfer(U256::from(100));
|
||||
params.call_type = CallType::Call;
|
||||
let mut state = get_temp_state();
|
||||
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
|
||||
let info = EnvInfo::default();
|
||||
let machine = ::ethereum::new_byzantium_test_machine();
|
||||
let mut substate = Substate::new();
|
||||
let mut tracer = ExecutiveTracer::default();
|
||||
let mut vm_tracer = ExecutiveVMTracer::toplevel();
|
||||
|
||||
let FinalizationResult { gas_left, .. } = {
|
||||
let mut ex = Executive::new(&mut state, &info, &machine);
|
||||
let output = BytesRef::Fixed(&mut[0u8;0]);
|
||||
ex.call(params, &mut substate, output, &mut tracer, &mut vm_tracer).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(62967));
|
||||
|
||||
let expected_trace = vec![FlatTrace {
|
||||
trace_address: Default::default(),
|
||||
subtraces: 1,
|
||||
action: trace::Action::Call(trace::Call {
|
||||
from: "cd1722f3947def4cf144679da39c4c32bdc35681".into(),
|
||||
to: "b010143a42d5980c7e5ef0e4a4416dc098a4fed3".into(),
|
||||
value: 100.into(),
|
||||
gas: 100_000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call,
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(37_033),
|
||||
output: vec![],
|
||||
}),
|
||||
}, FlatTrace {
|
||||
trace_address: vec![0].into_iter().collect(),
|
||||
subtraces: 0,
|
||||
action: trace::Action::Create(trace::Create {
|
||||
from: "b010143a42d5980c7e5ef0e4a4416dc098a4fed3".into(),
|
||||
value: 23.into(),
|
||||
gas: 66_917.into(),
|
||||
init: vec![0x60, 0x01, 0x60, 0x00, 0xfd]
|
||||
}),
|
||||
result: trace::Res::FailedCreate(vm::Error::Reverted.into()),
|
||||
}];
|
||||
|
||||
assert_eq!(tracer.drain(), expected_trace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_contract() {
|
||||
// Tracing is not supported in JIT
|
||||
|
@ -171,6 +171,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
||||
code_hash: Some(code_hash),
|
||||
data: Some(H256::from(number).to_vec()),
|
||||
call_type: CallType::Call,
|
||||
params_type: vm::ParamsType::Separate,
|
||||
};
|
||||
|
||||
let mut output = H256::new();
|
||||
@ -219,6 +220,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
||||
code_hash: code_hash,
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
params_type: vm::ParamsType::Embedded,
|
||||
};
|
||||
|
||||
if !self.static_flag {
|
||||
@ -240,7 +242,6 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
||||
Ok(FinalizationResult{ gas_left, apply_state: false, return_data }) => {
|
||||
ContractCreateResult::Reverted(gas_left, return_data)
|
||||
},
|
||||
Err(vm::Error::MutableCallInStaticContext) => ContractCreateResult::FailedInStaticCall,
|
||||
_ => ContractCreateResult::Failed,
|
||||
}
|
||||
}
|
||||
@ -277,6 +278,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
||||
code_hash: Some(code_hash),
|
||||
data: Some(data.to_vec()),
|
||||
call_type: call_type,
|
||||
params_type: vm::ParamsType::Separate,
|
||||
};
|
||||
|
||||
if let Some(value) = value {
|
||||
|
@ -162,6 +162,12 @@ impl Header {
|
||||
pub fn difficulty(&self) -> &U256 { &self.difficulty }
|
||||
/// Get the seal field of the header.
|
||||
pub fn seal(&self) -> &[Bytes] { &self.seal }
|
||||
/// Get the seal field with RLP-decoded values as bytes.
|
||||
pub fn decode_seal<'a, T: ::std::iter::FromIterator<&'a [u8]>>(&'a self) -> Result<T, DecoderError> {
|
||||
self.seal.iter().map(|rlp| {
|
||||
UntrustedRlp::new(rlp).data()
|
||||
}).collect()
|
||||
}
|
||||
|
||||
// TODO: seal_at, set_seal_at &c.
|
||||
|
||||
@ -340,13 +346,20 @@ mod tests {
|
||||
// that's rlp of block header created with ethash engine.
|
||||
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let mix_hash_decoded = "a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
|
||||
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap();
|
||||
|
||||
let header: Header = rlp::decode(&header_rlp);
|
||||
let seal_fields = header.seal;
|
||||
let seal_fields = header.seal.clone();
|
||||
assert_eq!(seal_fields.len(), 2);
|
||||
assert_eq!(seal_fields[0], mix_hash);
|
||||
assert_eq!(seal_fields[1], nonce);
|
||||
|
||||
let decoded_seal = header.decode_seal::<Vec<_>>().unwrap();
|
||||
assert_eq!(decoded_seal.len(), 2);
|
||||
assert_eq!(decoded_seal[0], &*mix_hash_decoded);
|
||||
assert_eq!(decoded_seal[1], &*nonce_decoded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -57,7 +57,7 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec<String> {
|
||||
};
|
||||
|
||||
{
|
||||
let db = Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let db = Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let mut config = ClientConfig::default();
|
||||
config.history = 8;
|
||||
let client = Client::new(
|
||||
|
@ -113,6 +113,8 @@ extern crate ansi_term;
|
||||
extern crate semantic_version;
|
||||
extern crate unexpected;
|
||||
extern crate kvdb;
|
||||
extern crate kvdb_rocksdb;
|
||||
extern crate kvdb_memorydb;
|
||||
extern crate util_error;
|
||||
extern crate snappy;
|
||||
extern crate migration;
|
||||
|
@ -35,7 +35,7 @@ use tx_filter::TransactionFilter;
|
||||
use bigint::prelude::U256;
|
||||
use bytes::BytesRef;
|
||||
use util::Address;
|
||||
use vm::{CallType, ActionParams, ActionValue};
|
||||
use vm::{CallType, ActionParams, ActionValue, ParamsType};
|
||||
use vm::{EnvInfo, Schedule, CreateContractAddress};
|
||||
|
||||
/// Parity tries to round block.gas_limit to multiple of this constant
|
||||
@ -149,6 +149,7 @@ impl EthereumMachine {
|
||||
code_hash: Some(state.code_hash(&contract_address)?),
|
||||
data: data,
|
||||
call_type: CallType::Call,
|
||||
params_type: ParamsType::Separate,
|
||||
};
|
||||
let mut ex = Executive::new(&mut state, &env_info, self);
|
||||
let mut substate = Substate::new();
|
||||
@ -351,7 +352,9 @@ impl EthereumMachine {
|
||||
None => true,
|
||||
};
|
||||
|
||||
let chain_id = if header.number() >= self.params().eip155_transition {
|
||||
let chain_id = if header.number() < self.params().validate_chain_id_transition {
|
||||
t.chain_id()
|
||||
} else if header.number() >= self.params().eip155_transition {
|
||||
Some(self.params().chain_id)
|
||||
} else {
|
||||
None
|
||||
|
@ -22,7 +22,7 @@ use std::collections::HashMap;
|
||||
use bigint::hash::H256;
|
||||
use util::Address;
|
||||
use bytes::Bytes;
|
||||
use kvdb::Database;
|
||||
use kvdb_rocksdb::Database;
|
||||
use migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
|
||||
use hash::keccak;
|
||||
use std::sync::Arc;
|
||||
|
@ -26,7 +26,8 @@ use migration::{Error, Migration, Progress, Batch, Config};
|
||||
use util::journaldb;
|
||||
use bigint::hash::H256;
|
||||
use trie::Trie;
|
||||
use kvdb::{Database, DBTransaction};
|
||||
use kvdb::DBTransaction;
|
||||
use kvdb_rocksdb::Database;
|
||||
|
||||
/// Account bloom upgrade routine. If bloom already present, does nothing.
|
||||
/// If database empty (no best block), does nothing.
|
||||
|
@ -18,7 +18,7 @@
|
||||
//! This migration consolidates all databases into single one using Column Families.
|
||||
|
||||
use rlp::{Rlp, RlpStream};
|
||||
use kvdb::Database;
|
||||
use kvdb_rocksdb::Database;
|
||||
use migration::{Batch, Config, Error, Migration, Progress};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -525,7 +525,13 @@ impl Miner {
|
||||
fn seal_and_import_block_internally(&self, chain: &MiningBlockChainClient, block: ClosedBlock) -> bool {
|
||||
if !block.transactions().is_empty() || self.forced_sealing() || Instant::now() > *self.next_mandatory_reseal.read() {
|
||||
trace!(target: "miner", "seal_block_internally: attempting internal seal.");
|
||||
match self.engine.generate_seal(block.block()) {
|
||||
|
||||
let parent_header = match chain.block_header(BlockId::Hash(*block.header().parent_hash())) {
|
||||
Some(hdr) => hdr.decode(),
|
||||
None => return false,
|
||||
};
|
||||
|
||||
match self.engine.generate_seal(block.block(), &parent_header) {
|
||||
// Save proposal for later seal submission and broadcast it.
|
||||
Seal::Proposal(seal) => {
|
||||
trace!(target: "miner", "Received a Proposal seal.");
|
||||
@ -647,10 +653,6 @@ impl Miner {
|
||||
condition: Option<TransactionCondition>,
|
||||
transaction_queue: &mut BanningTransactionQueue,
|
||||
) -> Vec<Result<TransactionImportResult, Error>> {
|
||||
let accounts = self.accounts.as_ref()
|
||||
.and_then(|provider| provider.accounts().ok())
|
||||
.map(|accounts| accounts.into_iter().collect::<HashSet<_>>());
|
||||
|
||||
let best_block_header = client.best_block_header().decode();
|
||||
let insertion_time = client.chain_info().best_block_number;
|
||||
|
||||
@ -669,8 +671,8 @@ impl Miner {
|
||||
Err(e)
|
||||
},
|
||||
Ok(transaction) => {
|
||||
let origin = accounts.as_ref().and_then(|accounts| {
|
||||
match accounts.contains(&transaction.sender()) {
|
||||
let origin = self.accounts.as_ref().and_then(|accounts| {
|
||||
match accounts.has_account(transaction.sender()).unwrap_or(false) {
|
||||
true => Some(TransactionOrigin::Local),
|
||||
false => None,
|
||||
}
|
||||
|
@ -19,7 +19,8 @@
|
||||
use std::sync::Arc;
|
||||
use std::path::Path;
|
||||
use bigint::hash::H256;
|
||||
use kvdb::{Database, DatabaseConfig, KeyValueDB};
|
||||
use kvdb::KeyValueDB;
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use bytes::Bytes;
|
||||
use io::*;
|
||||
use spec::Spec;
|
||||
@ -82,12 +83,7 @@ impl ClientService {
|
||||
|
||||
let mut db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS);
|
||||
|
||||
// give all rocksdb cache to state column; everything else has its
|
||||
// own caches.
|
||||
if let Some(size) = config.db_cache_size {
|
||||
db_config.set_cache(::db::COL_STATE, size);
|
||||
}
|
||||
|
||||
db_config.memory_budget = config.db_cache_size;
|
||||
db_config.compaction = config.db_compaction.compaction_profile(client_path);
|
||||
db_config.wal = config.db_wal;
|
||||
|
||||
|
@ -40,7 +40,7 @@ use parking_lot::{Mutex, RwLock, RwLockReadGuard};
|
||||
use util_error::UtilError;
|
||||
use bytes::Bytes;
|
||||
use util::journaldb::Algorithm;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use snappy;
|
||||
|
||||
/// Helper for removing directories in case of error.
|
||||
@ -682,7 +682,7 @@ mod tests {
|
||||
#[test]
|
||||
fn cannot_finish_with_invalid_chunks() {
|
||||
use bigint::hash::H256;
|
||||
use kvdb::DatabaseConfig;
|
||||
use kvdb_rocksdb::DatabaseConfig;
|
||||
|
||||
let spec = get_test_spec();
|
||||
let dir = RandomTempPath::new();
|
||||
|
@ -31,7 +31,7 @@ use tests::helpers;
|
||||
use transaction::{Transaction, Action, SignedTransaction};
|
||||
|
||||
use util::Address;
|
||||
use kvdb;
|
||||
use kvdb_memorydb;
|
||||
|
||||
const PASS: &'static str = "";
|
||||
const TRANSITION_BLOCK_1: usize = 2; // block at which the contract becomes activated.
|
||||
@ -238,7 +238,7 @@ fn fixed_to_contract_only() {
|
||||
assert_eq!(client.chain_info().best_block_number, 11);
|
||||
let reader = snapshot_helpers::snap(&*client);
|
||||
|
||||
let new_db = kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let new_db = kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let spec = spec_fixed_to_contract();
|
||||
|
||||
// ensure fresh engine's step matches.
|
||||
@ -270,7 +270,7 @@ fn fixed_to_contract_to_contract() {
|
||||
|
||||
assert_eq!(client.chain_info().best_block_number, 16);
|
||||
let reader = snapshot_helpers::snap(&*client);
|
||||
let new_db = kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let new_db = kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let spec = spec_fixed_to_contract();
|
||||
|
||||
for _ in 0..16 { spec.engine.step() }
|
||||
|
@ -26,7 +26,8 @@ use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use snappy;
|
||||
use kvdb::{self, KeyValueDB, DBTransaction};
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
use kvdb_memorydb;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
@ -43,7 +44,7 @@ fn chunk_and_restore(amount: u64) {
|
||||
let mut snapshot_path = new_path.as_path().to_owned();
|
||||
snapshot_path.push("SNAP");
|
||||
|
||||
let old_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let old_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());
|
||||
|
||||
// build the blockchain.
|
||||
@ -80,7 +81,7 @@ fn chunk_and_restore(amount: u64) {
|
||||
writer.into_inner().finish(manifest.clone()).unwrap();
|
||||
|
||||
// restore it.
|
||||
let new_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let new_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone());
|
||||
let mut rebuilder = SNAPSHOT_MODE.rebuilder(new_chain, new_db.clone(), &manifest).unwrap();
|
||||
|
||||
@ -127,7 +128,7 @@ fn checks_flag() {
|
||||
|
||||
let chunk = stream.out();
|
||||
|
||||
let db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let engine = ::spec::Spec::new_test().engine;
|
||||
let chain = BlockChain::new(Default::default(), &genesis, db.clone());
|
||||
|
||||
|
@ -27,7 +27,7 @@ use tests::helpers::generate_dummy_client_with_spec_and_data;
|
||||
|
||||
use devtools::RandomTempPath;
|
||||
use io::IoChannel;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
struct NoopDBRestore;
|
||||
|
||||
|
@ -27,7 +27,7 @@ use error::Error;
|
||||
use rand::{XorShiftRng, SeedableRng};
|
||||
use bigint::hash::H256;
|
||||
use util::journaldb::{self, Algorithm};
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use memorydb::MemoryDB;
|
||||
use parking_lot::Mutex;
|
||||
use devtools::RandomTempPath;
|
||||
|
@ -30,7 +30,7 @@ use parking_lot::RwLock;
|
||||
use rlp::{Rlp, RlpStream};
|
||||
use rustc_hex::FromHex;
|
||||
use util::*;
|
||||
use vm::{EnvInfo, CallType, ActionValue, ActionParams};
|
||||
use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType};
|
||||
|
||||
use super::genesis::Genesis;
|
||||
use super::seal::Generic as GenericSeal;
|
||||
@ -85,6 +85,8 @@ pub struct CommonParams {
|
||||
pub eip155_transition: BlockNumber,
|
||||
/// Validate block receipts root.
|
||||
pub validate_receipts_transition: BlockNumber,
|
||||
/// Validate transaction chain id.
|
||||
pub validate_chain_id_transition: BlockNumber,
|
||||
/// Number of first block where EIP-86 (Metropolis) rules begin.
|
||||
pub eip86_transition: BlockNumber,
|
||||
/// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin.
|
||||
@ -153,7 +155,7 @@ impl CommonParams {
|
||||
self.validate_receipts_transition != 0 && self.eip86_transition != 0 &&
|
||||
self.eip140_transition != 0 && self.eip210_transition != 0 &&
|
||||
self.eip211_transition != 0 && self.eip214_transition != 0 &&
|
||||
self.dust_protection_transition != 0
|
||||
self.validate_chain_id_transition != 0 && self.dust_protection_transition != 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,6 +180,7 @@ impl From<ethjson::spec::Params> for CommonParams {
|
||||
eip98_transition: p.eip98_transition.map_or(0, Into::into),
|
||||
eip155_transition: p.eip155_transition.map_or(0, Into::into),
|
||||
validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into),
|
||||
validate_chain_id_transition: p.validate_chain_id_transition.map_or(0, Into::into),
|
||||
eip86_transition: p.eip86_transition.map_or(
|
||||
BlockNumber::max_value(),
|
||||
Into::into,
|
||||
@ -501,6 +504,7 @@ impl Spec {
|
||||
code: Some(Arc::new(constructor.clone())),
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
params_type: ParamsType::Embedded,
|
||||
};
|
||||
|
||||
let mut substate = Substate::new();
|
||||
@ -668,13 +672,13 @@ impl Spec {
|
||||
pub fn genesis_epoch_data(&self) -> Result<Vec<u8>, String> {
|
||||
use transaction::{Action, Transaction};
|
||||
use util::journaldb;
|
||||
use kvdb;
|
||||
use kvdb_memorydb;
|
||||
|
||||
let genesis = self.genesis_header();
|
||||
|
||||
let factories = Default::default();
|
||||
let mut db = journaldb::new(
|
||||
Arc::new(kvdb::in_memory(0)),
|
||||
Arc::new(kvdb_memorydb::create(0)),
|
||||
journaldb::Algorithm::Archive,
|
||||
None,
|
||||
);
|
||||
|
@ -1409,7 +1409,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_trace_delegatecall() {
|
||||
fn should_trace_delegatecall_properly() {
|
||||
init_log();
|
||||
|
||||
let mut state = get_temp_state();
|
||||
@ -1429,7 +1429,7 @@ mod tests {
|
||||
}.sign(&secret(), None);
|
||||
|
||||
state.init_code(&0xa.into(), FromHex::from_hex("6000600060006000600b618000f4").unwrap()).unwrap();
|
||||
state.init_code(&0xb.into(), FromHex::from_hex("6000").unwrap()).unwrap();
|
||||
state.init_code(&0xb.into(), FromHex::from_hex("60056000526001601ff3").unwrap()).unwrap();
|
||||
let result = state.apply(&info, &machine, &t, true).unwrap();
|
||||
|
||||
let expected_trace = vec![FlatTrace {
|
||||
@ -1444,23 +1444,23 @@ mod tests {
|
||||
call_type: CallType::Call,
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: U256::from(721), // in post-eip150
|
||||
gas_used: U256::from(736), // in post-eip150
|
||||
output: vec![]
|
||||
}),
|
||||
}, FlatTrace {
|
||||
trace_address: vec![0].into_iter().collect(),
|
||||
subtraces: 0,
|
||||
action: trace::Action::Call(trace::Call {
|
||||
from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
|
||||
to: 0xa.into(),
|
||||
from: 0xa.into(),
|
||||
to: 0xb.into(),
|
||||
value: 0.into(),
|
||||
gas: 32768.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::DelegateCall,
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 3.into(),
|
||||
output: vec![],
|
||||
gas_used: 18.into(),
|
||||
output: vec![5],
|
||||
}),
|
||||
}];
|
||||
|
||||
|
@ -27,7 +27,7 @@ use tests::helpers::*;
|
||||
use types::filter::Filter;
|
||||
use bigint::prelude::U256;
|
||||
use util::*;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use devtools::*;
|
||||
use miner::Miner;
|
||||
use spec::Spec;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
use hash::keccak;
|
||||
use vm::{EnvInfo, ActionParams, ActionValue, CallType};
|
||||
use vm::{EnvInfo, ActionParams, ActionValue, CallType, ParamsType};
|
||||
use evm::{Factory, VMType};
|
||||
use executive::Executive;
|
||||
use state::Substate;
|
||||
@ -45,6 +45,7 @@ fn test_blockhash_eip210(factory: Factory) {
|
||||
code_hash: Some(blockhash_contract_code_hash),
|
||||
data: Some(H256::from(i - 1).to_vec()),
|
||||
call_type: CallType::Call,
|
||||
params_type: ParamsType::Separate,
|
||||
};
|
||||
let mut ex = Executive::new(&mut state, &env_info, &machine);
|
||||
let mut substate = Substate::new();
|
||||
@ -67,6 +68,7 @@ fn test_blockhash_eip210(factory: Factory) {
|
||||
code_hash: Some(get_prev_hash_code_hash),
|
||||
data: None,
|
||||
call_type: CallType::Call,
|
||||
params_type: ParamsType::Separate,
|
||||
};
|
||||
let mut ex = Executive::new(&mut state, &env_info, &machine);
|
||||
let mut substate = Substate::new();
|
||||
|
@ -232,7 +232,7 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> Arc<Client> {
|
||||
}
|
||||
|
||||
fn new_db() -> Arc<::kvdb::KeyValueDB> {
|
||||
Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
}
|
||||
|
||||
pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain {
|
||||
@ -386,5 +386,7 @@ pub fn get_default_ethash_params() -> EthashParams {
|
||||
eip649_transition: u64::max_value(),
|
||||
eip649_delay: 3_000_000,
|
||||
eip649_reward: None,
|
||||
expip2_transition: u64::max_value(),
|
||||
expip2_duration_limit: 30,
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use client::*;
|
||||
use tests::helpers::*;
|
||||
use devtools::RandomTempPath;
|
||||
use client::{BlockChainClient, Client, ClientConfig};
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use std::sync::Arc;
|
||||
use header::Header;
|
||||
use miner::Miner;
|
||||
|
@ -416,7 +416,8 @@ mod tests {
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use util::Address;
|
||||
use kvdb::{DBTransaction, in_memory, KeyValueDB};
|
||||
use kvdb::{DBTransaction, KeyValueDB};
|
||||
use kvdb_memorydb;
|
||||
use header::BlockNumber;
|
||||
use trace::{Config, TraceDB, Database as TraceDatabase, DatabaseExtras, ImportRequest};
|
||||
use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError};
|
||||
@ -467,7 +468,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn new_db() -> Arc<KeyValueDB> {
|
||||
Arc::new(in_memory(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -77,13 +77,23 @@ pub struct Call {
|
||||
|
||||
impl From<ActionParams> for Call {
|
||||
fn from(p: ActionParams) -> Self {
|
||||
Call {
|
||||
from: p.sender,
|
||||
to: p.address,
|
||||
value: p.value.value(),
|
||||
gas: p.gas,
|
||||
input: p.data.unwrap_or_else(Vec::new),
|
||||
call_type: p.call_type,
|
||||
match p.call_type {
|
||||
CallType::DelegateCall => Call {
|
||||
from: p.address,
|
||||
to: p.code_address,
|
||||
value: p.value.value(),
|
||||
gas: p.gas,
|
||||
input: p.data.unwrap_or_else(Vec::new),
|
||||
call_type: p.call_type,
|
||||
},
|
||||
_ => Call {
|
||||
from: p.sender,
|
||||
to: p.address,
|
||||
value: p.value.value(),
|
||||
gas: p.gas,
|
||||
input: p.data.unwrap_or_else(Vec::new),
|
||||
call_type: p.call_type,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,6 +469,11 @@ impl SignedTransaction {
|
||||
pub fn is_unsigned(&self) -> bool {
|
||||
self.transaction.is_unsigned()
|
||||
}
|
||||
|
||||
/// Deconstructs this transaction back into `UnverifiedTransaction`
|
||||
pub fn deconstruct(self) -> (UnverifiedTransaction, Address, Option<Public>) {
|
||||
(self.transaction, self.sender, self.public)
|
||||
}
|
||||
}
|
||||
|
||||
/// Signed Transaction that is a part of canon blockchain.
|
||||
|
@ -178,7 +178,7 @@ mod test {
|
||||
"#;
|
||||
|
||||
let spec = Spec::load(&::std::env::temp_dir(), spec_data.as_bytes()).unwrap();
|
||||
let client_db = Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let client_db = Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
|
||||
let client = Client::new(
|
||||
ClientConfig::default(),
|
||||
|
@ -505,7 +505,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
Err(err) => {
|
||||
match err {
|
||||
// Don't mark future blocks as bad.
|
||||
Error::Block(BlockError::InvalidTimestamp(ref e)) if e.max.is_some() => {},
|
||||
Error::Block(BlockError::TemporarilyInvalid(_)) => {},
|
||||
_ => {
|
||||
self.verification.bad.lock().insert(h.clone());
|
||||
}
|
||||
|
@ -137,9 +137,14 @@ pub fn verify_block_family(header: &Header, parent: &Header, engine: &EthEngine,
|
||||
|
||||
fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &EthEngine) -> Result<(), Error> {
|
||||
let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?;
|
||||
let max_uncles = engine.maximum_uncle_count(header.number());
|
||||
if num_uncles != 0 {
|
||||
if num_uncles > engine.maximum_uncle_count() {
|
||||
return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles })));
|
||||
if num_uncles > max_uncles {
|
||||
return Err(From::from(BlockError::TooManyUncles(OutOfBounds {
|
||||
min: None,
|
||||
max: Some(max_uncles),
|
||||
found: num_uncles,
|
||||
})));
|
||||
}
|
||||
|
||||
let mut excluded = HashSet::new();
|
||||
@ -268,11 +273,20 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool)
|
||||
}
|
||||
|
||||
if is_full {
|
||||
let max_time = get_time().sec as u64 + 30;
|
||||
if header.timestamp() > max_time {
|
||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
|
||||
const ACCEPTABLE_DRIFT_SECS: u64 = 15;
|
||||
let max_time = get_time().sec as u64 + ACCEPTABLE_DRIFT_SECS;
|
||||
let invalid_threshold = max_time + ACCEPTABLE_DRIFT_SECS * 9;
|
||||
let timestamp = header.timestamp();
|
||||
|
||||
if timestamp > invalid_threshold {
|
||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp })))
|
||||
}
|
||||
|
||||
if timestamp > max_time {
|
||||
return Err(From::from(BlockError::TemporarilyInvalid(OutOfBounds { max: Some(max_time), min: None, found: timestamp })))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -354,11 +368,13 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fail_timestamp(result: Result<(), Error>) {
|
||||
fn check_fail_timestamp(result: Result<(), Error>, temp: bool) {
|
||||
let name = if temp { "TemporarilyInvalid" } else { "InvalidTimestamp" };
|
||||
match result {
|
||||
Err(Error::Block(BlockError::InvalidTimestamp(_))) => (),
|
||||
Err(other) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: {:?}", other),
|
||||
Ok(_) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: Ok"),
|
||||
Err(Error::Block(BlockError::InvalidTimestamp(_))) if !temp => (),
|
||||
Err(Error::Block(BlockError::TemporarilyInvalid(_))) if temp => (),
|
||||
Err(other) => panic!("Block verification failed.\nExpected: {}\nGot: {:?}", name, other),
|
||||
Ok(_) => panic!("Block verification failed.\nExpected: {}\nGot: Ok", name),
|
||||
}
|
||||
}
|
||||
|
||||
@ -638,11 +654,17 @@ mod tests {
|
||||
|
||||
header = good.clone();
|
||||
header.set_timestamp(2450000000);
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), false);
|
||||
|
||||
header = good.clone();
|
||||
header.set_timestamp(get_time().sec as u64 + 40);
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||
header.set_timestamp(get_time().sec as u64 + 20);
|
||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), true);
|
||||
|
||||
header = good.clone();
|
||||
header.set_timestamp(get_time().sec as u64 + 10);
|
||||
header.set_uncles_hash(good_uncles_hash.clone());
|
||||
header.set_transactions_root(good_transactions_root.clone());
|
||||
check_ok(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||
|
||||
header = good.clone();
|
||||
header.set_number(9);
|
||||
@ -653,7 +675,7 @@ mod tests {
|
||||
let mut bad_uncles = good_uncles.clone();
|
||||
bad_uncles.push(good_uncle1.clone());
|
||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &bad_uncles), engine, &bc),
|
||||
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count()), min: None, found: bad_uncles.len() }));
|
||||
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count(header.number())), min: None, found: bad_uncles.len() }));
|
||||
|
||||
header = good.clone();
|
||||
bad_uncles = vec![ good_uncle1.clone(), good_uncle1.clone() ];
|
||||
|
@ -21,7 +21,7 @@ use bigint::prelude::U256;
|
||||
use bigint::hash::{H256, H2048};
|
||||
use util::Address;
|
||||
use bytes::Bytes;
|
||||
use rlp::Rlp;
|
||||
use rlp::{self, Rlp};
|
||||
use header::BlockNumber;
|
||||
|
||||
/// View onto block header rlp.
|
||||
@ -99,6 +99,14 @@ impl<'a> HeaderView<'a> {
|
||||
}
|
||||
seal
|
||||
}
|
||||
|
||||
/// Returns a vector of seal fields (RLP-decoded).
|
||||
pub fn decode_seal(&self) -> Result<Vec<Bytes>, rlp::DecoderError> {
|
||||
let seal = self.seal();
|
||||
seal.into_iter()
|
||||
.map(|s| rlp::UntrustedRlp::new(&s).data().map(|x| x.to_vec()))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -35,6 +35,15 @@ pub enum ActionValue {
|
||||
Apparent(U256)
|
||||
}
|
||||
|
||||
/// Type of the way parameters encoded
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ParamsType {
|
||||
/// Parameters are included in code
|
||||
Embedded,
|
||||
/// Parameters are passed in data section
|
||||
Separate,
|
||||
}
|
||||
|
||||
impl ActionValue {
|
||||
/// Returns action value as U256.
|
||||
pub fn value(&self) -> U256 {
|
||||
@ -81,7 +90,8 @@ pub struct ActionParams {
|
||||
pub data: Option<Bytes>,
|
||||
/// Type of call
|
||||
pub call_type: CallType,
|
||||
|
||||
/// Param types encoding
|
||||
pub params_type: ParamsType,
|
||||
}
|
||||
|
||||
impl Default for ActionParams {
|
||||
@ -99,6 +109,7 @@ impl Default for ActionParams {
|
||||
code: None,
|
||||
data: None,
|
||||
call_type: CallType::None,
|
||||
params_type: ParamsType::Separate,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,6 +129,7 @@ impl From<ethjson::vm::Transaction> for ActionParams {
|
||||
gas_price: t.gas_price.into(),
|
||||
value: ActionValue::Transfer(t.value.into()),
|
||||
call_type: match address.is_zero() { true => CallType::None, false => CallType::Call }, // TODO @debris is this correct?
|
||||
params_type: ParamsType::Separate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,6 @@ pub enum ContractCreateResult {
|
||||
/// Returned when contract creation failed.
|
||||
/// VM doesn't have to know the reason.
|
||||
Failed,
|
||||
/// Returned when contract creation failed.
|
||||
/// VM doesn't have to know the reason.
|
||||
FailedInStaticCall,
|
||||
/// Reverted with REVERT.
|
||||
Reverted(U256, ReturnData),
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ mod error;
|
||||
|
||||
pub mod tests;
|
||||
|
||||
pub use action_params::{ActionParams, ActionValue};
|
||||
pub use action_params::{ActionParams, ActionValue, ParamsType};
|
||||
pub use call_type::CallType;
|
||||
pub use env_info::{EnvInfo, LastHashes};
|
||||
pub use schedule::{Schedule, CleanDustMode};
|
||||
|
@ -127,12 +127,14 @@ pub struct WasmCosts {
|
||||
pub mul: u32,
|
||||
/// Memory (load/store) operations multiplier.
|
||||
pub mem: u32,
|
||||
/// Memory copy operation.
|
||||
/// Memory copy operation, per byte.
|
||||
pub mem_copy: u32,
|
||||
/// Memory move operation, per byte.
|
||||
pub mem_move: u32,
|
||||
/// Memory set operation, per byte.
|
||||
pub mem_set: u32,
|
||||
/// Static region charge, per byte.
|
||||
pub static_region: u32,
|
||||
/// General static query of u64 value from env-info
|
||||
pub static_u64: u32,
|
||||
/// General static query of U256 value from env-info
|
||||
pub static_u256: u32,
|
||||
/// General static query of Address value from env-info
|
||||
@ -147,11 +149,9 @@ impl Default for WasmCosts {
|
||||
mul: 4,
|
||||
mem: 2,
|
||||
mem_copy: 1,
|
||||
mem_move: 1,
|
||||
mem_set: 1,
|
||||
static_region: 1,
|
||||
|
||||
// due to runtime issues, this can be slow
|
||||
static_u64: 32,
|
||||
|
||||
static_u256: 64,
|
||||
static_address: 40,
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ pub struct FakeExt {
|
||||
pub schedule: Schedule,
|
||||
pub balances: HashMap<Address, U256>,
|
||||
pub tracing: bool,
|
||||
pub is_static: bool,
|
||||
}
|
||||
|
||||
// similar to the normal `finalize` function, but ignoring NeedsReturn.
|
||||
@ -192,7 +193,7 @@ impl Ext for FakeExt {
|
||||
}
|
||||
|
||||
fn is_static(&self) -> bool {
|
||||
false
|
||||
self.is_static
|
||||
}
|
||||
|
||||
fn inc_sstore_clears(&mut self) {
|
||||
|
@ -8,7 +8,7 @@ byteorder = "1.0"
|
||||
ethcore-util = { path = "../../util" }
|
||||
ethcore-bigint = { path = "../../util/bigint" }
|
||||
log = "0.3"
|
||||
parity-wasm = "0.14"
|
||||
parity-wasm = "0.15"
|
||||
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
|
||||
vm = { path = "../vm" }
|
||||
ethcore-logger = { path = "../../logger" }
|
||||
|
@ -25,12 +25,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
Static(
|
||||
"_storage_read",
|
||||
&[I32; 2],
|
||||
Some(I32),
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_storage_write",
|
||||
&[I32; 2],
|
||||
Some(I32),
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_balance",
|
||||
@ -38,12 +38,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_malloc",
|
||||
"_ext_malloc",
|
||||
&[I32],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_free",
|
||||
"_ext_free",
|
||||
&[I32],
|
||||
None,
|
||||
),
|
||||
@ -92,6 +92,21 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_ext_memcpy",
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_ext_memset",
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_ext_memmove",
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_panic",
|
||||
&[I32; 2],
|
||||
@ -99,8 +114,8 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
),
|
||||
Static(
|
||||
"_blockhash",
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
&[I64, I32],
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_coinbase",
|
||||
@ -130,12 +145,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
Static(
|
||||
"_timestamp",
|
||||
&[],
|
||||
Some(I32),
|
||||
Some(I64),
|
||||
),
|
||||
Static(
|
||||
"_blocknumber",
|
||||
&[],
|
||||
Some(I32),
|
||||
Some(I64),
|
||||
),
|
||||
Static(
|
||||
"_difficulty",
|
||||
@ -147,6 +162,11 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
&[I32],
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_elog",
|
||||
&[I32; 4],
|
||||
None,
|
||||
),
|
||||
|
||||
// TODO: Get rid of it also somehow?
|
||||
Static(
|
||||
@ -157,8 +177,8 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
|
||||
Static(
|
||||
"_llvm_bswap_i64",
|
||||
&[I32; 2],
|
||||
Some(I32)
|
||||
&[I64],
|
||||
Some(I64)
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -31,6 +31,7 @@ mod result;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod env;
|
||||
mod panic_payload;
|
||||
|
||||
const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024;
|
||||
|
||||
@ -115,7 +116,18 @@ impl vm::Vm for WasmInterpreter {
|
||||
&self.program,
|
||||
);
|
||||
|
||||
let mut cursor = ::std::io::Cursor::new(&*code);
|
||||
let (mut cursor, data_position) = match params.params_type {
|
||||
vm::ParamsType::Embedded => {
|
||||
let module_size = parity_wasm::peek_size(&*code);
|
||||
(
|
||||
::std::io::Cursor::new(&code[..module_size]),
|
||||
module_size
|
||||
)
|
||||
},
|
||||
vm::ParamsType::Separate => {
|
||||
(::std::io::Cursor::new(&code[..]), 0)
|
||||
},
|
||||
};
|
||||
|
||||
let contract_module = wasm_utils::inject_gas_counter(
|
||||
elements::Module::deserialize(
|
||||
@ -134,8 +146,19 @@ impl vm::Vm for WasmInterpreter {
|
||||
let static_segment_cost = data_section_length * runtime.ext().schedule().wasm.static_region as u64;
|
||||
runtime.charge(|_| static_segment_cost).map_err(Error)?;
|
||||
|
||||
let d_ptr = runtime.write_descriptor(¶ms.data.unwrap_or_default())
|
||||
.map_err(Error)?;
|
||||
let d_ptr = {
|
||||
match params.params_type {
|
||||
vm::ParamsType::Embedded => {
|
||||
runtime.write_descriptor(
|
||||
if data_position < code.len() { &code[data_position..] } else { &[] }
|
||||
).map_err(Error)?
|
||||
},
|
||||
vm::ParamsType::Separate => {
|
||||
runtime.write_descriptor(¶ms.data.unwrap_or_default())
|
||||
.map_err(Error)?
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
let execution_params = runtime.execution_params()
|
||||
|
168
ethcore/wasm/src/panic_payload.rs
Normal file
168
ethcore/wasm/src/panic_payload.rs
Normal file
@ -0,0 +1,168 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use std::io::{self, Read};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct PanicPayload {
|
||||
pub msg: Option<String>,
|
||||
pub file: Option<String>,
|
||||
pub line: Option<u32>,
|
||||
pub col: Option<u32>,
|
||||
}
|
||||
|
||||
fn read_string(rdr: &mut io::Cursor<&[u8]>) -> io::Result<Option<String>> {
|
||||
let string_len = rdr.read_u32::<LittleEndian>()?;
|
||||
let string = if string_len == 0 {
|
||||
None
|
||||
} else {
|
||||
let mut content = vec![0; string_len as usize];
|
||||
rdr.read_exact(&mut content)?;
|
||||
Some(String::from_utf8_lossy(&content).into_owned())
|
||||
};
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
pub fn decode(raw: &[u8]) -> PanicPayload {
|
||||
let mut rdr = io::Cursor::new(raw);
|
||||
let msg = read_string(&mut rdr).ok().and_then(|x| x);
|
||||
let file = read_string(&mut rdr).ok().and_then(|x| x);
|
||||
let line = rdr.read_u32::<LittleEndian>().ok();
|
||||
let col = rdr.read_u32::<LittleEndian>().ok();
|
||||
PanicPayload {
|
||||
msg: msg,
|
||||
file: file,
|
||||
line: line,
|
||||
col: col,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use byteorder::WriteBytesExt;
|
||||
|
||||
fn write_u32(payload: &mut Vec<u8>, val: u32) {
|
||||
payload.write_u32::<LittleEndian>(val).unwrap();
|
||||
}
|
||||
|
||||
fn write_bytes(payload: &mut Vec<u8>, bytes: &[u8]) {
|
||||
write_u32(payload, bytes.len() as u32);
|
||||
payload.extend(bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
write_bytes(&mut raw, b"file");
|
||||
write_u32(&mut raw, 1);
|
||||
write_u32(&mut raw, 2);
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: Some("file".to_string()),
|
||||
line: Some(1),
|
||||
col: Some(2),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_msg() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: None,
|
||||
line: None,
|
||||
col: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"\xF0\x90\x80msg");
|
||||
write_bytes(&mut raw, b"file");
|
||||
write_u32(&mut raw, 1);
|
||||
write_u32(&mut raw, 2);
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("<EFBFBD>msg".to_string()),
|
||||
file: Some("file".to_string()),
|
||||
line: Some(1),
|
||||
col: Some(2),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trailing_data() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
write_bytes(&mut raw, b"file");
|
||||
write_u32(&mut raw, 1);
|
||||
write_u32(&mut raw, 2);
|
||||
write_u32(&mut raw, 0xdeadbeef);
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: Some("file".to_string()),
|
||||
line: Some(1),
|
||||
col: Some(2),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_str_is_none() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
write_bytes(&mut raw, b"");
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: None,
|
||||
line: None,
|
||||
col: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ use std::sync::Arc;
|
||||
use byteorder::{LittleEndian, ByteOrder};
|
||||
|
||||
use vm;
|
||||
use panic_payload;
|
||||
use parity_wasm::interpreter;
|
||||
use wasm_utils::rules;
|
||||
use bigint::prelude::U256;
|
||||
@ -55,6 +56,8 @@ pub enum UserTrap {
|
||||
Unknown,
|
||||
/// Passed string had invalid utf-8 encoding
|
||||
BadUtf8,
|
||||
/// Log event error
|
||||
Log,
|
||||
/// Other error in native code
|
||||
Other,
|
||||
/// Panic with message
|
||||
@ -75,6 +78,7 @@ impl ::std::fmt::Display for UserTrap {
|
||||
UserTrap::AllocationFailed => write!(f, "Memory allocation failed (OOM)"),
|
||||
UserTrap::BadUtf8 => write!(f, "String encoding is bad utf-8 sequence"),
|
||||
UserTrap::GasLimit => write!(f, "Invocation resulted in gas limit violated"),
|
||||
UserTrap::Log => write!(f, "Error occured while logging an event"),
|
||||
UserTrap::Other => write!(f, "Other unspecified error"),
|
||||
UserTrap::Panic(ref msg) => write!(f, "Panic: {}", msg),
|
||||
}
|
||||
@ -164,7 +168,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
|
||||
self.ext.set_storage(key, val).map_err(|_| UserTrap::StorageUpdateError)?;
|
||||
|
||||
Ok(Some(0i32.into()))
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Read from the storage to wasm memory
|
||||
@ -180,7 +184,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
|
||||
self.memory.set(val_ptr as u32, &*val)?;
|
||||
|
||||
Ok(Some(0.into()))
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Fetches balance for address
|
||||
@ -221,8 +225,8 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
}
|
||||
|
||||
/// Charge gas according to closure
|
||||
pub fn charge<F>(&mut self, f: F) -> Result<(), InterpreterError>
|
||||
where F: FnOnce(&vm::Schedule) -> u64
|
||||
pub fn charge<F>(&mut self, f: F) -> Result<(), InterpreterError>
|
||||
where F: FnOnce(&vm::Schedule) -> u64
|
||||
{
|
||||
let amount = f(self.ext.schedule());
|
||||
if !self.charge_gas(amount as u64) {
|
||||
@ -232,6 +236,21 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn overflow_charge<F>(&mut self, f: F) -> Result<(), InterpreterError>
|
||||
where F: FnOnce(&vm::Schedule) -> Option<u64>
|
||||
{
|
||||
let amount = match f(self.ext.schedule()) {
|
||||
Some(amount) => amount,
|
||||
None => { return Err(UserTrap::GasLimit.into()); }
|
||||
};
|
||||
|
||||
if !self.charge_gas(amount as u64) {
|
||||
Err(UserTrap::GasLimit.into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Invoke create in the state runtime
|
||||
pub fn create(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
@ -277,10 +296,6 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
self.gas_counter = self.gas_limit - gas_left.low_u64();
|
||||
Ok(Some((-1i32).into()))
|
||||
},
|
||||
vm::ContractCreateResult::FailedInStaticCall => {
|
||||
trace!(target: "wasm", "runtime: create contract called in static context");
|
||||
Err(interpreter::Error::Trap("CREATE in static context".to_owned()))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,43 +561,92 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
fn mem_copy(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
//
|
||||
// method signature:
|
||||
// fn memcpy(dest: *const u8, src: *const u8, len: u32) -> *mut u8;
|
||||
//
|
||||
|
||||
let len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let src = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
self.charge(|schedule| schedule.wasm.mem_copy as u64 * len as u64)?;
|
||||
|
||||
let mem = self.memory().get(src, len as usize)?;
|
||||
self.memory().set(dst, &mem)?;
|
||||
self.memory().copy_nonoverlapping(src as usize, dst as usize, len as usize)?;
|
||||
|
||||
Ok(Some(0i32.into()))
|
||||
Ok(Some(Into::into(dst as i32)))
|
||||
}
|
||||
|
||||
fn bswap_32(x: u32) -> u32 {
|
||||
x >> 24 | x >> 8 & 0xff00 | x << 8 & 0xff0000 | x << 24
|
||||
fn mem_move(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
//
|
||||
// method signature:
|
||||
// fn memmove(dest: *const u8, src: *const u8, len: u32) -> *mut u8;
|
||||
//
|
||||
|
||||
let len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let src = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
self.charge(|schedule| schedule.wasm.mem_move as u64 * len as u64)?;
|
||||
|
||||
self.memory().copy(src as usize, dst as usize, len as usize)?;
|
||||
|
||||
Ok(Some(Into::into(dst as i32)))
|
||||
}
|
||||
|
||||
fn mem_set(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
//
|
||||
// method signature:
|
||||
// fn memset(dest: *const u8, c: u32, len: u32) -> *mut u8;
|
||||
//
|
||||
|
||||
let len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let c = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
self.charge(|schedule| schedule.wasm.mem_set as u64 * len as u64)?;
|
||||
|
||||
self.memory().clear(dst as usize, c as u8, len as usize)?;
|
||||
|
||||
Ok(Some(Into::into(dst as i32)))
|
||||
}
|
||||
|
||||
fn bitswap_i64(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let x1 = context.value_stack.pop_as::<i32>()?;
|
||||
let x2 = context.value_stack.pop_as::<i32>()?;
|
||||
let x = context.value_stack.pop_as::<i64>()?;
|
||||
let result = x.swap_bytes();
|
||||
|
||||
let result = ((Runtime::bswap_32(x2 as u32) as u64) << 32
|
||||
| Runtime::bswap_32(x1 as u32) as u64) as i64;
|
||||
|
||||
self.return_i64(result)
|
||||
Ok(Some(result.into()))
|
||||
}
|
||||
|
||||
fn user_panic(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let msg_len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let msg_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
let msg = String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
|
||||
.map_err(|_| UserTrap::BadUtf8)?;
|
||||
let payload_len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let payload_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
let raw_payload = self.memory.get(payload_ptr, payload_len as usize)?;
|
||||
let payload = panic_payload::decode(&raw_payload);
|
||||
let msg = format!(
|
||||
"{msg}, {file}:{line}:{col}",
|
||||
msg = payload
|
||||
.msg
|
||||
.as_ref()
|
||||
.map(String::as_ref)
|
||||
.unwrap_or("<msg was stripped>"),
|
||||
file = payload
|
||||
.file
|
||||
.as_ref()
|
||||
.map(String::as_ref)
|
||||
.unwrap_or("<unknown>"),
|
||||
line = payload.line.unwrap_or(0),
|
||||
col = payload.col.unwrap_or(0)
|
||||
);
|
||||
trace!(target: "wasm", "Contract custom panic message: {}", msg);
|
||||
|
||||
Err(UserTrap::Panic(msg).into())
|
||||
@ -592,19 +656,16 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let return_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let block_hi = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let block_lo = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let block_num = context.value_stack.pop_as::<i64>()? as u64;
|
||||
|
||||
self.charge(|schedule| schedule.blockhash_gas as u64)?;
|
||||
|
||||
let block_num = (block_hi as u64) << 32 | block_lo as u64;
|
||||
|
||||
trace!("Requesting block hash for block #{}", block_num);
|
||||
let hash = self.ext.blockhash(&U256::from(block_num));
|
||||
|
||||
self.memory.set(return_ptr, &*hash)?;
|
||||
|
||||
Ok(Some(0i32.into()))
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn return_address_ptr(&mut self, ptr: u32, val: Address) -> Result<(), InterpreterError>
|
||||
@ -615,11 +676,11 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
}
|
||||
|
||||
fn return_u256_ptr(&mut self, ptr: u32, val: U256) -> Result<(), InterpreterError> {
|
||||
let value: H256 = val.into();
|
||||
let value: H256 = val.into();
|
||||
self.charge(|schedule| schedule.wasm.static_u256 as u64)?;
|
||||
self.memory.set(ptr, &*value)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn coinbase(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
@ -640,7 +701,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
context.value_stack.pop_as::<i32>()? as u32,
|
||||
sender,
|
||||
)?;
|
||||
Ok(None)
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn address(&mut self, context: InterpreterCallerContext)
|
||||
@ -651,7 +712,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
context.value_stack.pop_as::<i32>()? as u32,
|
||||
addr,
|
||||
)?;
|
||||
Ok(None)
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn origin(&mut self, context: InterpreterCallerContext)
|
||||
@ -662,7 +723,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
context.value_stack.pop_as::<i32>()? as u32,
|
||||
origin,
|
||||
)?;
|
||||
Ok(None)
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn value(&mut self, context: InterpreterCallerContext)
|
||||
@ -680,14 +741,14 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let timestamp = self.ext.env_info().timestamp as i64;
|
||||
self.return_i64(timestamp)
|
||||
Ok(Some(timestamp.into()))
|
||||
}
|
||||
|
||||
fn block_number(&mut self, _context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let block_number: u64 = self.ext.env_info().number.into();
|
||||
self.return_i64(block_number as i64)
|
||||
let block_number = self.ext.env_info().number as i64;
|
||||
Ok(Some(block_number.into()))
|
||||
}
|
||||
|
||||
fn difficulty(&mut self, context: InterpreterCallerContext)
|
||||
@ -709,26 +770,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
context.value_stack.pop_as::<i32>()? as u32,
|
||||
gas_limit,
|
||||
)?;
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn return_i64(&mut self, val: i64) -> Result<Option<interpreter::RuntimeValue>, InterpreterError> {
|
||||
self.charge(|schedule| schedule.wasm.static_u64 as u64)?;
|
||||
|
||||
let uval = val as u64;
|
||||
let hi = (uval >> 32) as i32;
|
||||
let lo = (uval << 32 >> 32) as i32;
|
||||
|
||||
let target = self.instance.module("contract").ok_or(UserTrap::Other)?;
|
||||
target.execute_export(
|
||||
"setTempRet0",
|
||||
self.execution_params().add_argument(
|
||||
interpreter::RuntimeValue::I32(hi).into()
|
||||
),
|
||||
)?;
|
||||
Ok(Some(
|
||||
(lo).into()
|
||||
))
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn execution_params(&mut self) -> interpreter::ExecutionParams<UserTrap> {
|
||||
@ -753,6 +795,44 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
pub fn ext(&mut self) -> &mut vm::Ext {
|
||||
self.ext
|
||||
}
|
||||
|
||||
pub fn log(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
// signature is:
|
||||
// pub fn elog(topic_ptr: *const u8, topic_count: u32, data_ptr: *const u8, data_len: u32);
|
||||
let data_len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let data_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let topic_count = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let topic_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
if topic_count > 4 {
|
||||
return Err(UserTrap::Log.into());
|
||||
}
|
||||
|
||||
self.overflow_charge(|schedule|
|
||||
{
|
||||
let topics_gas = schedule.log_gas as u64 + schedule.log_topic_gas as u64 * topic_count as u64;
|
||||
(schedule.log_data_gas as u64)
|
||||
.checked_mul(schedule.log_data_gas as u64)
|
||||
.and_then(|data_gas| data_gas.checked_add(topics_gas))
|
||||
}
|
||||
)?;
|
||||
|
||||
let mut topics: Vec<H256> = Vec::with_capacity(topic_count as usize);
|
||||
topics.resize(topic_count as usize, H256::zero());
|
||||
for i in 0..topic_count {
|
||||
let offset = i.checked_mul(32).ok_or(UserTrap::MemoryAccessViolation)?
|
||||
.checked_add(topic_ptr).ok_or(UserTrap::MemoryAccessViolation)?;
|
||||
|
||||
*topics.get_mut(i as usize)
|
||||
.expect("topics is resized to `topic_count`, i is in 0..topic count iterator, get_mut uses i as an indexer, get_mut cannot fail; qed")
|
||||
= H256::from(&self.memory.get(offset, 32)?[..]);
|
||||
}
|
||||
self.ext.log(topics, &self.memory.get(data_ptr, data_len as usize)?).map_err(|_| UserTrap::Log)?;
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
|
||||
@ -760,10 +840,10 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
match name {
|
||||
"_malloc" => {
|
||||
"_ext_malloc" => {
|
||||
self.malloc(context)
|
||||
},
|
||||
"_free" => {
|
||||
"_ext_free" => {
|
||||
// Since it is arena allocator, free does nothing
|
||||
// todo: update if changed
|
||||
self.user_noop(context)
|
||||
@ -801,6 +881,15 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
|
||||
"_emscripten_memcpy_big" => {
|
||||
self.mem_copy(context)
|
||||
},
|
||||
"_ext_memcpy" => {
|
||||
self.mem_copy(context)
|
||||
},
|
||||
"_ext_memmove" => {
|
||||
self.mem_move(context)
|
||||
},
|
||||
"_ext_memset" => {
|
||||
self.mem_set(context)
|
||||
},
|
||||
"_llvm_bswap_i64" => {
|
||||
self.bitswap_i64(context)
|
||||
},
|
||||
@ -837,6 +926,9 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
|
||||
"_value" => {
|
||||
self.value(context)
|
||||
},
|
||||
"_elog" => {
|
||||
self.log(context)
|
||||
},
|
||||
_ => {
|
||||
trace!(target: "wasm", "Trapped due to unhandled function: '{}'", name);
|
||||
Ok(self.unknown_trap(context)?)
|
||||
|
@ -60,7 +60,7 @@ fn empty() {
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(99_976));
|
||||
assert_eq!(gas_left, U256::from(99_982));
|
||||
}
|
||||
|
||||
// This test checks if the contract deserializes payload header properly.
|
||||
@ -89,7 +89,6 @@ fn logger() {
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(15_177));
|
||||
let address_val: H256 = address.into();
|
||||
assert_eq!(
|
||||
ext.store.get(&"0100000000000000000000000000000000000000000000000000000000000000".parse().unwrap()).expect("storage key to exist"),
|
||||
@ -113,6 +112,7 @@ fn logger() {
|
||||
U256::from(1_000_000_000),
|
||||
"Logger sets 0x04 key to the trasferred value"
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(19_147));
|
||||
}
|
||||
|
||||
// This test checks if the contract can allocate memory and pass pointer to the result stream properly.
|
||||
@ -142,13 +142,12 @@ fn identity() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(99_695));
|
||||
|
||||
assert_eq!(
|
||||
Address::from_slice(&result),
|
||||
sender,
|
||||
"Idenity test contract does not return the sender passed"
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(99_844));
|
||||
}
|
||||
|
||||
// Dispersion test sends byte array and expect the contract to 'disperse' the original elements with
|
||||
@ -176,12 +175,12 @@ fn dispersion() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_543));
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(96_393));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -205,12 +204,11 @@ fn suicide_not() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_822));
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
vec![0u8]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(96_725));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -241,8 +239,8 @@ fn suicide() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_580));
|
||||
assert!(ext.suicides.contains(&refund));
|
||||
assert_eq!(gas_left, U256::from(96_687));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -272,7 +270,7 @@ fn create() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Create,
|
||||
gas: U256::from(62_324),
|
||||
gas: U256::from(65_899),
|
||||
sender_address: None,
|
||||
receive_address: None,
|
||||
value: Some(1_000_000_000.into()),
|
||||
@ -280,7 +278,7 @@ fn create() {
|
||||
code_address: None,
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(62_289));
|
||||
assert_eq!(gas_left, U256::from(65_892));
|
||||
}
|
||||
|
||||
|
||||
@ -314,7 +312,7 @@ fn call_code() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Call,
|
||||
gas: U256::from(95_585),
|
||||
gas: U256::from(98_713),
|
||||
sender_address: Some(sender),
|
||||
receive_address: Some(receiver),
|
||||
value: None,
|
||||
@ -322,11 +320,11 @@ fn call_code() {
|
||||
code_address: Some("0d13710000000000000000000000000000000000".parse().unwrap()),
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(90_665));
|
||||
|
||||
// siphash result
|
||||
let res = LittleEndian::read_u32(&result[..]);
|
||||
assert_eq!(res, 4198595614);
|
||||
assert_eq!(gas_left, U256::from(93_855));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -359,7 +357,7 @@ fn call_static() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Call,
|
||||
gas: U256::from(95_585),
|
||||
gas: U256::from(98_713),
|
||||
sender_address: Some(sender),
|
||||
receive_address: Some(receiver),
|
||||
value: None,
|
||||
@ -367,11 +365,12 @@ fn call_static() {
|
||||
code_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()),
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(90_665));
|
||||
|
||||
// siphash result
|
||||
let res = LittleEndian::read_u32(&result[..]);
|
||||
assert_eq!(res, 317632590);
|
||||
|
||||
assert_eq!(gas_left, U256::from(93_855));
|
||||
}
|
||||
|
||||
// Realloc test
|
||||
@ -393,8 +392,8 @@ fn realloc() {
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
assert_eq!(gas_left, U256::from(96_811));
|
||||
assert_eq!(result, vec![0u8; 2]);
|
||||
assert_eq!(gas_left, U256::from(96_723));
|
||||
}
|
||||
|
||||
// Tests that contract's ability to read from a storage
|
||||
@ -419,8 +418,8 @@ fn storage_read() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_645));
|
||||
assert_eq!(Address::from(&result[12..32]), address);
|
||||
assert_eq!(gas_left, U256::from(99_767));
|
||||
}
|
||||
|
||||
// Tests keccak calculation
|
||||
@ -446,9 +445,97 @@ fn keccak() {
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(80_452));
|
||||
assert_eq!(gas_left, U256::from(81_446));
|
||||
}
|
||||
|
||||
// memcpy test.
|
||||
#[test]
|
||||
fn memcpy() {
|
||||
::ethcore_logger::init_log();
|
||||
let code = load_sample!("mem.wasm");
|
||||
|
||||
let mut test_payload = Vec::with_capacity(8192);
|
||||
for i in 0..8192 {
|
||||
test_payload.push((i % 255) as u8);
|
||||
}
|
||||
let mut data = vec![0u8];
|
||||
data.extend(&test_payload);
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.data = Some(data);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("mem should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(result, test_payload);
|
||||
assert_eq!(gas_left, U256::from(72_216));
|
||||
}
|
||||
|
||||
// memmove test.
|
||||
#[test]
|
||||
fn memmove() {
|
||||
::ethcore_logger::init_log();
|
||||
let code = load_sample!("mem.wasm");
|
||||
|
||||
let mut test_payload = Vec::with_capacity(8192);
|
||||
for i in 0..8192 {
|
||||
test_payload.push((i % 255) as u8);
|
||||
}
|
||||
let mut data = vec![1u8];
|
||||
data.extend(&test_payload);
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.data = Some(data);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("mem should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(result, test_payload);
|
||||
assert_eq!(gas_left, U256::from(72_216));
|
||||
}
|
||||
|
||||
// memset test
|
||||
#[test]
|
||||
fn memset() {
|
||||
::ethcore_logger::init_log();
|
||||
let code = load_sample!("mem.wasm");
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.data = Some(vec![2u8, 228u8]);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("mem should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(result, vec![228u8; 8192]);
|
||||
assert_eq!(gas_left, U256::from(72_196));
|
||||
}
|
||||
|
||||
macro_rules! reqrep_test {
|
||||
($name: expr, $input: expr) => {
|
||||
@ -500,11 +587,11 @@ fn math_add() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(94_666));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("1888888888888888888888888888887").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(95_524));
|
||||
}
|
||||
|
||||
// multiplication
|
||||
@ -522,11 +609,11 @@ fn math_mul() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(93_719));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(94_674));
|
||||
}
|
||||
|
||||
// subtraction
|
||||
@ -544,11 +631,11 @@ fn math_sub() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(94_718));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("111111111111111111111111111111").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(95_516));
|
||||
}
|
||||
|
||||
// subtraction with overflow
|
||||
@ -566,7 +653,10 @@ fn math_sub_with_overflow() {
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(result, Err(vm::Error::Wasm("Wasm runtime error: User(Panic(\"arithmetic operation overflow\"))".into())));
|
||||
match result {
|
||||
Err(vm::Error::Wasm(_)) => {},
|
||||
_ => panic!("Unexpected result {:?}", result),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -583,11 +673,11 @@ fn math_div() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(86_996));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("1125000").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(88_514));
|
||||
}
|
||||
|
||||
// This test checks the ability of wasm contract to invoke
|
||||
@ -675,5 +765,66 @@ fn externs() {
|
||||
"Gas limit requested and returned does not match"
|
||||
);
|
||||
|
||||
assert_eq!(gas_left, U256::from(91_857));
|
||||
assert_eq!(gas_left, U256::from(94_858));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_keccak() {
|
||||
::ethcore_logger::init_log();
|
||||
let mut code = load_sample!("keccak.wasm");
|
||||
code.extend_from_slice(b"something");
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.params_type = vm::ParamsType::Embedded;
|
||||
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("keccak should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(81_446));
|
||||
}
|
||||
|
||||
/// This test checks the correctness of log extern
|
||||
/// Target test puts one event with two topic [keccak(input), reverse(keccak(input))]
|
||||
/// and reversed input as a data
|
||||
#[test]
|
||||
fn events() {
|
||||
::ethcore_logger::init_log();
|
||||
let code = load_sample!("events.wasm");
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.data = Some(b"something".to_vec());
|
||||
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("events should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(ext.logs.len(), 1);
|
||||
let log_entry = &ext.logs[0];
|
||||
assert_eq!(log_entry.topics.len(), 2);
|
||||
assert_eq!(&log_entry.topics[0], &H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(&log_entry.topics[1], &H256::from("871d5ea37430753faab7dff7a7187783517d83bd822c02e28a164c887e1d3768"));
|
||||
assert_eq!(&log_entry.data, b"gnihtemos");
|
||||
|
||||
assert_eq!(&result, b"gnihtemos");
|
||||
assert_eq!(gas_left, U256::from(79_637));
|
||||
}
|
||||
|
@ -122,6 +122,13 @@ impl<T> DiskDirectory<T> where T: KeyFileManager {
|
||||
Ok(hasher.finish())
|
||||
}
|
||||
|
||||
fn last_modification_date(&self) -> Result<u64, Error> {
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
let duration = fs::metadata(&self.path)?.modified()?.duration_since(UNIX_EPOCH).unwrap_or(Duration::default());
|
||||
let timestamp = duration.as_secs() ^ (duration.subsec_nanos() as u64);
|
||||
Ok(timestamp)
|
||||
}
|
||||
|
||||
/// all accounts found in keys directory
|
||||
fn files_content(&self) -> Result<HashMap<PathBuf, SafeAccount>, Error> {
|
||||
// it's not done using one iterator cause
|
||||
@ -226,7 +233,7 @@ impl<T> KeyDirectory for DiskDirectory<T> where T: KeyFileManager {
|
||||
}
|
||||
|
||||
fn unique_repr(&self) -> Result<u64, Error> {
|
||||
self.files_hash()
|
||||
self.last_modification_date()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ use std::collections::{BTreeMap, HashMap};
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use std::time::{Instant, Duration};
|
||||
|
||||
use crypto::KEY_ITERATIONS;
|
||||
use random::Random;
|
||||
@ -28,6 +29,8 @@ use presale::PresaleWallet;
|
||||
use json::{self, Uuid, OpaqueKeyFile};
|
||||
use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret};
|
||||
|
||||
const REFRESH_TIME_SEC: u64 = 5;
|
||||
|
||||
/// Accounts store.
|
||||
pub struct EthStore {
|
||||
store: EthMultiStore,
|
||||
@ -245,7 +248,12 @@ pub struct EthMultiStore {
|
||||
// order lock: cache, then vaults
|
||||
cache: RwLock<BTreeMap<StoreAccountRef, Vec<SafeAccount>>>,
|
||||
vaults: Mutex<HashMap<String, Box<VaultKeyDirectory>>>,
|
||||
dir_hash: Mutex<Option<u64>>,
|
||||
timestamp: Mutex<Timestamp>,
|
||||
}
|
||||
|
||||
struct Timestamp {
|
||||
dir_hash: Option<u64>,
|
||||
last_checked: Instant,
|
||||
}
|
||||
|
||||
impl EthMultiStore {
|
||||
@ -261,20 +269,27 @@ impl EthMultiStore {
|
||||
vaults: Mutex::new(HashMap::new()),
|
||||
iterations: iterations,
|
||||
cache: Default::default(),
|
||||
dir_hash: Default::default(),
|
||||
timestamp: Mutex::new(Timestamp {
|
||||
dir_hash: None,
|
||||
last_checked: Instant::now(),
|
||||
}),
|
||||
};
|
||||
store.reload_accounts()?;
|
||||
Ok(store)
|
||||
}
|
||||
|
||||
fn reload_if_changed(&self) -> Result<(), Error> {
|
||||
let mut last_dir_hash = self.dir_hash.lock();
|
||||
let dir_hash = Some(self.dir.unique_repr()?);
|
||||
if *last_dir_hash == dir_hash {
|
||||
return Ok(())
|
||||
let mut last_timestamp = self.timestamp.lock();
|
||||
let now = Instant::now();
|
||||
if (now - last_timestamp.last_checked) > Duration::from_secs(REFRESH_TIME_SEC) {
|
||||
let dir_hash = Some(self.dir.unique_repr()?);
|
||||
last_timestamp.last_checked = now;
|
||||
if last_timestamp.dir_hash == dir_hash {
|
||||
return Ok(())
|
||||
}
|
||||
self.reload_accounts()?;
|
||||
last_timestamp.dir_hash = dir_hash;
|
||||
}
|
||||
self.reload_accounts()?;
|
||||
*last_dir_hash = dir_hash;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -455,11 +470,11 @@ impl SimpleSecretStore for EthMultiStore {
|
||||
}
|
||||
|
||||
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error> {
|
||||
use std::collections::Bound;
|
||||
self.reload_if_changed()?;
|
||||
self.cache.read().keys()
|
||||
.find(|r| &r.address == address)
|
||||
.cloned()
|
||||
.ok_or(Error::InvalidAccount)
|
||||
let cache = self.cache.read();
|
||||
let mut r = cache.range((Bound::Included(*address), Bound::Included(*address)));
|
||||
r.next().ok_or(Error::InvalidAccount).map(|(k, _)| k.clone())
|
||||
}
|
||||
|
||||
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error> {
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::PathBuf;
|
||||
use std::cmp::Ordering;
|
||||
use ethkey::{Address, Message, Signature, Secret, Public};
|
||||
use Error;
|
||||
use json::{Uuid, OpaqueKeyFile};
|
||||
@ -32,12 +33,24 @@ pub enum SecretVaultRef {
|
||||
}
|
||||
|
||||
/// Stored account reference
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Ord)]
|
||||
pub struct StoreAccountRef {
|
||||
/// Vault reference
|
||||
pub vault: SecretVaultRef,
|
||||
/// Account address
|
||||
pub address: Address,
|
||||
/// Vault reference
|
||||
pub vault: SecretVaultRef,
|
||||
}
|
||||
|
||||
impl PartialOrd for StoreAccountRef {
|
||||
fn partial_cmp(&self, other: &StoreAccountRef) -> Option<Ordering> {
|
||||
Some(self.address.cmp(&other.address).then_with(|| self.vault.cmp(&other.vault)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::borrow::Borrow<Address> for StoreAccountRef {
|
||||
fn borrow(&self) -> &Address {
|
||||
&self.address
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple Secret Store API
|
||||
|
@ -37,8 +37,8 @@ use trezor_sys::messages::{EthereumAddress, PinMatrixAck, MessageType, EthereumT
|
||||
|
||||
const TREZOR_VID: u16 = 0x534c;
|
||||
const TREZOR_PIDS: [u16; 1] = [0x0001]; // Trezor v1, keeping this as an array to leave room for Trezor v2 which is in progress
|
||||
const ETH_DERIVATION_PATH: [u32; 4] = [0x8000002C, 0x8000003C, 0x80000000, 0]; // m/44'/60'/0'/0
|
||||
const ETC_DERIVATION_PATH: [u32; 4] = [0x8000002C, 0x8000003D, 0x80000000, 0]; // m/44'/61'/0'/0
|
||||
const ETH_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003C, 0x80000000, 0, 0]; // m/44'/60'/0'/0/0
|
||||
const ETC_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003D, 0x80000000, 0, 0]; // m/44'/61'/0'/0/0
|
||||
|
||||
|
||||
/// Hardware wallet error.
|
||||
|
@ -4,7 +4,7 @@ set -e
|
||||
# variables
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
PACKAGES=( "parity" "etherscan" "shapeshift" "jsonrpc" )
|
||||
BRANCH=$CI_BUILD_REF_NAME
|
||||
BRANCH="stable"
|
||||
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git"
|
||||
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"
|
||||
|
||||
|
@ -1 +1 @@
|
||||
// test script 11
|
||||
// test script 12
|
||||
|
@ -17,35 +17,35 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { walletSourceURL } from '~/contracts/code/wallet';
|
||||
// import { walletSourceURL } from '~/contracts/code/wallet';
|
||||
import { RadioButtons } from '~/ui';
|
||||
|
||||
const TYPES = [
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.label'
|
||||
defaultMessage='Multi-Sig wallet'
|
||||
/>
|
||||
),
|
||||
key: 'MULTISIG',
|
||||
description: (
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.description'
|
||||
defaultMessage='Create/Deploy a {link} Wallet'
|
||||
values={ {
|
||||
link: (
|
||||
<a href={ walletSourceURL } target='_blank'>
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.link'
|
||||
defaultMessage='standard multi-signature'
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
} }
|
||||
/>
|
||||
)
|
||||
},
|
||||
// {
|
||||
// label: (
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.label'
|
||||
// defaultMessage='Multi-Sig wallet'
|
||||
// />
|
||||
// ),
|
||||
// key: 'MULTISIG',
|
||||
// description: (
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.description'
|
||||
// defaultMessage='Create/Deploy a {link} Wallet'
|
||||
// values={ {
|
||||
// link: (
|
||||
// <a href={ walletSourceURL } target='_blank'>
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.link'
|
||||
// defaultMessage='standard multi-signature'
|
||||
// />
|
||||
// </a>
|
||||
// )
|
||||
// } }
|
||||
// />
|
||||
// )
|
||||
// },
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
|
@ -59,7 +59,7 @@ const STEPS = {
|
||||
export default class CreateWalletStore {
|
||||
@observable step = null;
|
||||
@observable txhash = null;
|
||||
@observable walletType = 'MULTISIG';
|
||||
@observable walletType = 'WATCH'; // 'MULTISIG';
|
||||
|
||||
@observable wallet = {
|
||||
account: '',
|
||||
|
@ -206,7 +206,7 @@ export default class CertifiersMonitor {
|
||||
// Fetch the address, name and owner in one batch
|
||||
return querier(this.api, { address: instance.address, from, limit }, instance.badge)
|
||||
.then((results) => {
|
||||
this.certifiers = results
|
||||
const certifiers = results
|
||||
.map(([ address, name, owner ], index) => ({
|
||||
address, owner,
|
||||
id: index + from,
|
||||
@ -225,7 +225,7 @@ export default class CertifiersMonitor {
|
||||
}, {});
|
||||
|
||||
// Fetch the meta-data in serie
|
||||
return Object.values(this.certifiers).reduce((promise, certifier) => {
|
||||
return Object.values(certifiers).reduce((promise, certifier) => {
|
||||
return promise.then(() => badgeReg.fetchMeta(certifier.id))
|
||||
.then((meta) => {
|
||||
this.certifiers[certifier.id] = { ...certifier, ...meta };
|
||||
@ -274,8 +274,6 @@ export default class CertifiersMonitor {
|
||||
.then((certified) => {
|
||||
const { id, title, icon, name } = certifier;
|
||||
|
||||
this.fetchedAccounts[address] = true;
|
||||
|
||||
if (!certified) {
|
||||
return this.store.dispatch(removeCertification(address, id));
|
||||
}
|
||||
@ -283,7 +281,10 @@ export default class CertifiersMonitor {
|
||||
log.debug('seen as certified', { address, id, name, icon });
|
||||
this.store.dispatch(addCertification(address, id, name, title, icon));
|
||||
});
|
||||
}, Promise.resolve());
|
||||
}, Promise.resolve())
|
||||
.then(() => {
|
||||
this.fetchedAccounts[address] = true;
|
||||
});
|
||||
}
|
||||
|
||||
setCertifiersFilter () {
|
||||
|
@ -71,7 +71,6 @@ function loadCachedTokens (tokenRegContract) {
|
||||
// Check if we have data from the right contract
|
||||
if (cached.tokenreg === tokenRegContract.address && cached.tokens) {
|
||||
log.debug('found cached tokens', cached.tokens);
|
||||
dispatch(_setTokens(cached.tokens));
|
||||
|
||||
// Fetch all the tokens images on load
|
||||
// (it's the only thing that might have changed)
|
||||
@ -105,22 +104,13 @@ export function loadTokens (options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
export function loadTokensBasics (_tokenIndexes, options) {
|
||||
const limit = 64;
|
||||
export function loadTokensBasics (tokenIndexes, options) {
|
||||
const limit = 128;
|
||||
|
||||
return (dispatch, getState) => {
|
||||
const { api, tokens } = getState();
|
||||
const { api } = getState();
|
||||
const { tokenReg } = Contracts.get();
|
||||
const nextTokens = {};
|
||||
const prevTokensIndexes = Object.values(tokens).map((t) => t.index);
|
||||
|
||||
// Only fetch tokens we don't have yet
|
||||
const tokenIndexes = _tokenIndexes
|
||||
.filter((tokenIndex) => {
|
||||
return !prevTokensIndexes.includes(tokenIndex);
|
||||
})
|
||||
.sort();
|
||||
|
||||
const count = tokenIndexes.length;
|
||||
|
||||
log.debug('loading basic tokens', tokenIndexes);
|
||||
@ -164,7 +154,7 @@ export function loadTokensBasics (_tokenIndexes, options) {
|
||||
|
||||
export function fetchTokens (_tokenIndexes) {
|
||||
const tokenIndexes = uniq(_tokenIndexes || []);
|
||||
const tokenChunks = chunk(tokenIndexes, 64);
|
||||
const tokenChunks = chunk(tokenIndexes, 128);
|
||||
|
||||
return (dispatch, getState) => {
|
||||
const { tokenReg } = Contracts.get();
|
||||
@ -240,6 +230,7 @@ function fetchTokensData (tokenRegContract, tokenIndexes) {
|
||||
log.debug('fetched', { fullResults, partialResults });
|
||||
|
||||
return [].concat(fullResults, partialResults)
|
||||
.filter(({ address }) => !/0x0*$/.test(address))
|
||||
.reduce((tokens, token) => {
|
||||
const { id, image, address } = token;
|
||||
|
||||
|
@ -32,14 +32,19 @@ class TokenImage extends Component {
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
state = {
|
||||
error: false
|
||||
};
|
||||
|
||||
render () {
|
||||
const { error } = this.state;
|
||||
const { api } = this.context;
|
||||
const { image, token } = this.props;
|
||||
|
||||
const imageurl = token.image || image;
|
||||
let imagesrc = unknownImage;
|
||||
|
||||
if (imageurl) {
|
||||
if (imageurl && !error) {
|
||||
const host = /^(\/)?api/.test(imageurl)
|
||||
? api.dappsUrl
|
||||
: '';
|
||||
@ -49,11 +54,16 @@ class TokenImage extends Component {
|
||||
|
||||
return (
|
||||
<img
|
||||
src={ imagesrc }
|
||||
alt={ token.name }
|
||||
onError={ this.handleError }
|
||||
src={ imagesrc }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
handleError = () => {
|
||||
this.setState({ error: true });
|
||||
};
|
||||
}
|
||||
|
||||
function mapStateToProps (iniState) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { range } from 'lodash';
|
||||
import { chunk, range } from 'lodash';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import { hashToImageUrl } from '~/redux/util';
|
||||
@ -55,19 +55,40 @@ export function fetchTokensBasics (api, tokenReg, start = 0, limit = 100) {
|
||||
return api.eth
|
||||
.call({ data: tokenAddressesBytcode + tokenAddressesCallData })
|
||||
.then((result) => {
|
||||
const tokenAddresses = decodeArray(api, 'address[]', result);
|
||||
|
||||
return tokenAddresses.map((tokenAddress, index) => {
|
||||
return decodeArray(api, 'address[]', result);
|
||||
})
|
||||
.then((tokenAddresses) => {
|
||||
return tokenAddresses.map((address, index) => {
|
||||
const tokenIndex = start + index;
|
||||
|
||||
return {
|
||||
address: tokenAddress,
|
||||
id: getTokenId(tokenAddress, tokenIndex),
|
||||
id: getTokenId(address, tokenIndex),
|
||||
address,
|
||||
index: tokenIndex,
|
||||
|
||||
fetched: false
|
||||
};
|
||||
});
|
||||
})
|
||||
.then((tokens) => {
|
||||
const randomAddress = sha3(`${Date.now()}`).substr(0, 42);
|
||||
|
||||
return fetchTokensBalances(api, tokens, [randomAddress])
|
||||
.then((_balances) => {
|
||||
const balances = _balances[randomAddress];
|
||||
|
||||
return tokens.map((token) => {
|
||||
if (balances[token.id] && balances[token.id].gt(0)) {
|
||||
token.address = null;
|
||||
}
|
||||
|
||||
return token;
|
||||
});
|
||||
});
|
||||
})
|
||||
.then((tokens) => {
|
||||
return tokens.filter(({ address }) => {
|
||||
return address && !/^0x0*$/.test(address);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -177,19 +198,22 @@ export function fetchAccountsBalances (api, tokens, updates) {
|
||||
});
|
||||
|
||||
const tokenPromise = Object.keys(tokenUpdates)
|
||||
.reduce((tokenPromise, accountAddress) => {
|
||||
.reduce((promises, accountAddress) => {
|
||||
const tokenIds = tokenUpdates[accountAddress];
|
||||
const updateTokens = tokens
|
||||
.filter((t) => tokenIds.includes(t.id));
|
||||
|
||||
return tokenPromise
|
||||
.then(() => fetchTokensBalances(api, updateTokens, [ accountAddress ]))
|
||||
.then((balances) => {
|
||||
tokensBalances[accountAddress] = balances[accountAddress];
|
||||
});
|
||||
}, Promise.resolve());
|
||||
promises.push(
|
||||
fetchTokensBalances(api, updateTokens, [ accountAddress ])
|
||||
.then((balances) => {
|
||||
tokensBalances[accountAddress] = balances[accountAddress];
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.all([ ethPromise, tokenPromise ])
|
||||
return promises;
|
||||
}, []);
|
||||
|
||||
return Promise.all([ ethPromise, Promise.all(tokenPromise) ])
|
||||
.then(() => {
|
||||
const balances = Object.assign({}, tokensBalances);
|
||||
|
||||
@ -225,29 +249,24 @@ function fetchEthBalances (api, accountAddresses) {
|
||||
});
|
||||
}
|
||||
|
||||
function fetchTokensBalances (api, tokens, accountAddresses) {
|
||||
const tokenAddresses = tokens.map((t) => t.address);
|
||||
const tokensBalancesCallData = encode(
|
||||
api,
|
||||
[ 'address[]', 'address[]' ],
|
||||
[ accountAddresses, tokenAddresses ]
|
||||
);
|
||||
function fetchTokensBalances (api, _tokens, accountAddresses) {
|
||||
const promises = chunk(_tokens, 128).map((tokens) => {
|
||||
const data = tokensBalancesBytecode + encode(
|
||||
api,
|
||||
[ 'address[]', 'address[]' ],
|
||||
[ accountAddresses, tokens.map(({ address }) => address) ]
|
||||
);
|
||||
|
||||
return api.eth
|
||||
.call({ data: tokensBalancesBytecode + tokensBalancesCallData })
|
||||
.then((result) => {
|
||||
const rawBalances = decodeArray(api, 'uint[]', result);
|
||||
return api.eth.call({ data }).then((result) => {
|
||||
const balances = {};
|
||||
const rawBalances = decodeArray(api, 'uint[]', result);
|
||||
|
||||
accountAddresses.forEach((accountAddress, accountIndex) => {
|
||||
const preIndex = accountIndex * tokens.length;
|
||||
const balance = {};
|
||||
const preIndex = accountIndex * tokenAddresses.length;
|
||||
|
||||
tokenAddresses.forEach((tokenAddress, tokenIndex) => {
|
||||
const index = preIndex + tokenIndex;
|
||||
const token = tokens[tokenIndex];
|
||||
|
||||
balance[token.id] = rawBalances[index];
|
||||
tokens.forEach((token, tokenIndex) => {
|
||||
balance[token.id] = rawBalances[preIndex + tokenIndex];
|
||||
});
|
||||
|
||||
balances[accountAddress] = balance;
|
||||
@ -255,6 +274,31 @@ function fetchTokensBalances (api, tokens, accountAddresses) {
|
||||
|
||||
return balances;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises).then((results) => {
|
||||
return results.reduce((combined, result) => {
|
||||
Object
|
||||
.keys(result)
|
||||
.forEach((address) => {
|
||||
if (!combined[address]) {
|
||||
combined[address] = {};
|
||||
}
|
||||
|
||||
Object
|
||||
.keys(result[address])
|
||||
.forEach((token) => {
|
||||
const value = result[address][token];
|
||||
|
||||
if (value && value.gt(0)) {
|
||||
combined[address][token] = result[address][token];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return combined;
|
||||
}, {});
|
||||
});
|
||||
}
|
||||
|
||||
function getTokenId (...args) {
|
||||
|
@ -22,7 +22,7 @@ use super::ValidatorSet;
|
||||
/// Authority params deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct AuthorityRoundParams {
|
||||
/// Block duration.
|
||||
/// Block duration, in seconds.
|
||||
#[serde(rename="stepDuration")]
|
||||
pub step_duration: Uint,
|
||||
/// Valid authorities
|
||||
@ -43,6 +43,12 @@ pub struct AuthorityRoundParams {
|
||||
/// Reward per block in wei.
|
||||
#[serde(rename="blockReward")]
|
||||
pub block_reward: Option<Uint>,
|
||||
/// Block at which maximum uncle count should be considered.
|
||||
#[serde(rename="maximumUncleCountTransition")]
|
||||
pub maximum_uncle_count_transition: Option<Uint>,
|
||||
/// Maximum number of accepted uncles.
|
||||
#[serde(rename="maximumUncleCount")]
|
||||
pub maximum_uncle_count: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Authority engine deserialization.
|
||||
@ -71,7 +77,9 @@ mod tests {
|
||||
},
|
||||
"startStep" : 24,
|
||||
"validateStepTransition": 150,
|
||||
"blockReward": 5000000
|
||||
"blockReward": 5000000,
|
||||
"maximumUncleCountTransition": 10000000,
|
||||
"maximumUncleCount": 5
|
||||
}
|
||||
}"#;
|
||||
|
||||
@ -80,6 +88,8 @@ mod tests {
|
||||
assert_eq!(deserialized.params.validators, ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]));
|
||||
assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24))));
|
||||
assert_eq!(deserialized.params.immediate_transitions, None);
|
||||
assert_eq!(deserialized.params.maximum_uncle_count_transition, Some(Uint(10_000_000.into())));
|
||||
assert_eq!(deserialized.params.maximum_uncle_count, Some(Uint(5.into())));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -125,6 +125,14 @@ pub struct EthashParams {
|
||||
/// EIP-649 base reward.
|
||||
#[serde(rename="eip649Reward")]
|
||||
pub eip649_reward: Option<Uint>,
|
||||
|
||||
/// EXPIP-2 block height
|
||||
#[serde(rename="expip2Transition")]
|
||||
pub expip2_transition: Option<Uint>,
|
||||
|
||||
/// EXPIP-2 duration limit
|
||||
#[serde(rename="expip2DurationLimit")]
|
||||
pub expip2_duration_limit: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Ethash engine deserialization.
|
||||
@ -241,6 +249,8 @@ mod tests {
|
||||
eip649_transition: None,
|
||||
eip649_delay: None,
|
||||
eip649_reward: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -287,6 +297,8 @@ mod tests {
|
||||
eip649_transition: None,
|
||||
eip649_delay: None,
|
||||
eip649_reward: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -58,6 +58,9 @@ pub struct Params {
|
||||
#[serde(rename="eip155Transition")]
|
||||
pub eip155_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="validateChainIdTransition")]
|
||||
pub validate_chain_id_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="validateReceiptsTransition")]
|
||||
pub validate_receipts_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
|
@ -14,4 +14,7 @@ serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
log = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
ethkey = { path = "../ethkey" }
|
||||
kvdb-memorydb = { path = "../util/kvdb-memorydb" }
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user