Compare commits
101 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21522ff863 | ||
|
|
a02d7c68b3 | ||
|
|
2738c5cd74 | ||
|
|
a51e4d5d13 | ||
|
|
6c50f9007a | ||
|
|
78acefd35c | ||
|
|
c3a53e7545 | ||
|
|
b06fa73cff | ||
|
|
2caf71fdde | ||
|
|
4bfabb6752 | ||
|
|
9b54d3f2d3 | ||
|
|
db86dec404 | ||
|
|
d2fa3e3236 | ||
|
|
590362b23c | ||
|
|
5e2258c6de | ||
|
|
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
|
||||
|
||||
248
Cargo.lock
generated
248
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.11",
|
||||
"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.11",
|
||||
"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",
|
||||
@@ -621,7 +621,6 @@ dependencies = [
|
||||
"rlp_derive 0.1.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)",
|
||||
"semantic_version 0.1.0",
|
||||
"snappy 0.1.0",
|
||||
"stats 0.1.0",
|
||||
"table 0.1.0",
|
||||
@@ -682,7 +681,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.11",
|
||||
"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 +731,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.11",
|
||||
"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 +750,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.11",
|
||||
"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 +802,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.11",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"hash 0.1.0",
|
||||
@@ -810,12 +811,15 @@ dependencies = [
|
||||
"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)",
|
||||
"mio 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-version 1.8.11",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"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.11",
|
||||
"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.11",
|
||||
"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.11"
|
||||
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,10 +904,12 @@ 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)",
|
||||
"memorydb 0.1.0",
|
||||
"parity-version 1.8.11",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia_trie 0.1.0",
|
||||
"rlp 0.2.0",
|
||||
@@ -1018,12 +1025,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.11",
|
||||
"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 +1052,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.11",
|
||||
"ethjson 0.1.0",
|
||||
"evmjit 1.8.0",
|
||||
"hash 0.1.0",
|
||||
@@ -1066,7 +1074,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.11",
|
||||
"ethjson 0.1.0",
|
||||
"evm 0.1.0",
|
||||
"panic_hook 0.1.0",
|
||||
@@ -1142,7 +1150,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 +1285,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 +1372,8 @@ 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.11",
|
||||
"parity-version 1.8.11",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1496,7 +1505,7 @@ dependencies = [
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws 0.7.1 (git+https://github.com/tomusdrw/ws-rs)",
|
||||
"ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1514,11 +1523,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 +1696,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 +1836,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 +1845,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 +1884,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.11",
|
||||
"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 +2001,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 +2083,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity"
|
||||
version = "1.8.0"
|
||||
version = "1.8.11"
|
||||
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 +2107,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.11",
|
||||
"ethkey 0.2.0",
|
||||
"ethsync 1.8.0",
|
||||
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2090,12 +2117,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",
|
||||
@@ -2106,6 +2133,7 @@ dependencies = [
|
||||
"parity-rpc 1.8.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
"parity-updater 1.8.0",
|
||||
"parity-version 1.8.11",
|
||||
"parity-whisper 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
@@ -2120,6 +2148,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 +2166,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.11",
|
||||
"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)",
|
||||
@@ -2152,6 +2182,7 @@ dependencies = [
|
||||
"parity-hash-fetch 1.8.0",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-ui 1.8.0",
|
||||
"parity-version 1.8.11",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2195,10 +2226,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.11",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hash 0.1.0",
|
||||
@@ -2220,7 +2251,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.11",
|
||||
"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 +2265,10 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore 1.8.0",
|
||||
"ethcore-io 1.8.0",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.11",
|
||||
"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 +2281,7 @@ name = "parity-machine"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-util 1.8.0",
|
||||
"ethcore-util 1.8.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2277,13 +2309,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.11",
|
||||
"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 +2327,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)",
|
||||
@@ -2302,6 +2335,7 @@ dependencies = [
|
||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-updater 1.8.0",
|
||||
"parity-version 1.8.11",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2358,7 +2392,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 +2406,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#8bb56b99d68982128a7d97365ecfda548b0c4706"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2381,27 +2415,40 @@ 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.11",
|
||||
"ethsync 1.8.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-common-types 1.8.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.8.0",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-version 1.8.11",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-version"
|
||||
version = "1.8.11"
|
||||
dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"rlp 0.2.0",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[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 +2754,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 +2841,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 +2851,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 +2898,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.11",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc 1.8.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
@@ -2957,10 +3006,6 @@ dependencies = [
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semantic_version"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.1.20"
|
||||
@@ -3104,6 +3149,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 +3299,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 +3618,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.11",
|
||||
"ethjson 0.1.0",
|
||||
"evmjit 1.8.0",
|
||||
"hash 0.1.0",
|
||||
@@ -3581,17 +3634,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.11",
|
||||
"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]]
|
||||
@@ -3606,8 +3673,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ws"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/tomusdrw/ws-rs#f8306a798b7541d64624299a83a2c934f173beed"
|
||||
version = "0.7.5"
|
||||
source = "git+https://github.com/tomusdrw/ws-rs#368ce39e2aa8700d568ca29dbacaecdf1bf749d1"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3665,6 +3732,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 +3752,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 +3762,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 +3790,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 +3872,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 +3883,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 +3957,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 +3974,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"
|
||||
@@ -3943,7 +4013,7 @@ dependencies = [
|
||||
"checksum wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)" = "<none>"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum ws 0.7.1 (git+https://github.com/tomusdrw/ws-rs)" = "<none>"
|
||||
"checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "<none>"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
|
||||
"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
[package]
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity"
|
||||
version = "1.8.0"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "1.8.11"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
@@ -12,6 +13,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"
|
||||
@@ -58,12 +61,13 @@ parity-reactor = { path = "util/reactor" }
|
||||
parity-rpc = { path = "rpc" }
|
||||
parity-rpc-client = { path = "rpc_client" }
|
||||
parity-updater = { path = "updater" }
|
||||
parity-version = { path = "util/version" }
|
||||
parity-whisper = { path = "whisper" }
|
||||
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}
|
||||
|
||||
@@ -37,6 +37,7 @@ parity-hash-fetch = { path = "../hash-fetch" }
|
||||
parity-reactor = { path = "../util/reactor" }
|
||||
parity-ui = { path = "./ui" }
|
||||
hash = { path = "../util/hash" }
|
||||
parity-version = { path = "../util/version" }
|
||||
|
||||
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>;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use hyper::{self, mime, header};
|
||||
use hyper::StatusCode;
|
||||
|
||||
use util::version;
|
||||
use parity_version::version;
|
||||
|
||||
use handlers::add_security_headers;
|
||||
use Embeddable;
|
||||
|
||||
@@ -44,6 +44,7 @@ extern crate parity_dapps_glue as parity_dapps;
|
||||
extern crate parity_hash_fetch as hash_fetch;
|
||||
extern crate parity_ui;
|
||||
extern crate hash;
|
||||
extern crate parity_version;
|
||||
|
||||
#[macro_use]
|
||||
extern crate futures;
|
||||
|
||||
@@ -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" }
|
||||
@@ -72,7 +74,6 @@ vm = { path = "vm" }
|
||||
wasm = { path = "wasm" }
|
||||
hash = { path = "../util/hash" }
|
||||
triehash = { path = "../util/triehash" }
|
||||
semantic_version = { path = "../util/semantic_version" }
|
||||
unexpected = { path = "../util/unexpected" }
|
||||
|
||||
[dev-dependencies]
|
||||
@@ -81,7 +82,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;
|
||||
|
||||
@@ -90,7 +90,14 @@ impl Pending {
|
||||
match self.requests[idx].respond_local(cache) {
|
||||
Some(response) => {
|
||||
self.requests.supply_response_unchecked(&response);
|
||||
|
||||
// update header and back-references after each from-cache
|
||||
// response to ensure that the requests are left in a consistent
|
||||
// state and increase the likelihood of being able to answer
|
||||
// the next request from cache.
|
||||
self.update_header_refs(idx, &response);
|
||||
self.fill_unanswered();
|
||||
|
||||
self.responses.push(response);
|
||||
}
|
||||
None => break,
|
||||
|
||||
@@ -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"
|
||||
],
|
||||
|
||||
Submodule ethcore/res/wasm-tests updated: c8129ce2f3...d6185ea16e
@@ -257,9 +257,9 @@ impl AccountProvider {
|
||||
Ok(Address::from(account.address).into())
|
||||
}
|
||||
|
||||
/// Import a new presale wallet.
|
||||
pub fn import_wallet(&self, json: &[u8], password: &str) -> Result<Address, Error> {
|
||||
let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password)?;
|
||||
/// Import a new wallet.
|
||||
pub fn import_wallet(&self, json: &[u8], password: &str, gen_id: bool) -> Result<Address, Error> {
|
||||
let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password, gen_id)?;
|
||||
if self.blacklisted_accounts.contains(&account.address) {
|
||||
self.sstore.remove_account(&account, password)?;
|
||||
return Err(SSError::InvalidAccount.into());
|
||||
@@ -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};
|
||||
|
||||
@@ -41,18 +41,20 @@ use itertools::{self, Itertools};
|
||||
use rlp::{UntrustedRlp, encode};
|
||||
use bigint::prelude::{U256, U128};
|
||||
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 +67,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 +101,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 +276,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 +289,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 +317,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 +327,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 +345,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 +405,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 +428,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 +464,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))
|
||||
}
|
||||
}
|
||||
@@ -411,8 +482,6 @@ impl IoHandler<()> for TransitionHandler {
|
||||
impl Engine<EthereumMachine> for AuthorityRound {
|
||||
fn name(&self) -> &str { "AuthorityRound" }
|
||||
|
||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
||||
|
||||
fn machine(&self) -> &EthereumMachine { &self.machine }
|
||||
|
||||
/// Two fields - consensus step and the corresponding proposer signature.
|
||||
@@ -436,13 +505,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 +529,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 +579,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 +600,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
trace!(target: "engine", "generate_seal: {} not a proposer for step {}.",
|
||||
header.author(), step);
|
||||
}
|
||||
|
||||
Seal::None
|
||||
}
|
||||
|
||||
@@ -539,28 +642,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 +688,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 +703,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 +722,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> {
|
||||
@@ -811,7 +916,6 @@ mod tests {
|
||||
fn has_valid_metadata() {
|
||||
let engine = Spec::new_test_round().engine;
|
||||
assert!(!engine.name().is_empty());
|
||||
assert!(engine.version().major >= 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -850,17 +954,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 +1049,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 +1080,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 +1115,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ use ethjson;
|
||||
use header::Header;
|
||||
use client::EngineClient;
|
||||
use machine::{AuxiliaryData, Call, EthereumMachine};
|
||||
use semantic_version::SemanticVersion;
|
||||
use super::signer::EngineSigner;
|
||||
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
|
||||
|
||||
@@ -95,7 +94,6 @@ impl BasicAuthority {
|
||||
|
||||
impl Engine<EthereumMachine> for BasicAuthority {
|
||||
fn name(&self) -> &str { "BasicAuthority" }
|
||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
||||
|
||||
fn machine(&self) -> &EthereumMachine { &self.machine }
|
||||
|
||||
@@ -107,7 +105,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) {
|
||||
@@ -218,7 +216,6 @@ mod tests {
|
||||
fn has_valid_metadata() {
|
||||
let engine = new_test_authority().engine;
|
||||
assert!(!engine.name().is_empty());
|
||||
assert!(engine.version().major >= 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -251,7 +248,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ use ethkey::Signature;
|
||||
use parity_machine::{Machine, LocalizedMachine as Localized};
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use semantic_version::SemanticVersion;
|
||||
use util::*;
|
||||
use unexpected::{Mismatch, OutOfBounds};
|
||||
use bytes::Bytes;
|
||||
@@ -178,8 +177,6 @@ pub enum EpochChange<M: Machine> {
|
||||
pub trait Engine<M: Machine>: Sync + Send {
|
||||
/// The name of this engine.
|
||||
fn name(&self) -> &str;
|
||||
/// The version of this engine. Should be of the form
|
||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(0, 0, 0) }
|
||||
|
||||
/// Get access to the underlying state machine.
|
||||
// TODO: decouple.
|
||||
@@ -192,7 +189,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 +223,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 +361,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(())
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ use super::transition::TransitionHandler;
|
||||
use super::vote_collector::VoteCollector;
|
||||
use self::message::*;
|
||||
use self::params::TendermintParams;
|
||||
use semantic_version::SemanticVersion;
|
||||
use machine::{AuxiliaryData, EthereumMachine};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
@@ -443,14 +442,12 @@ impl Tendermint {
|
||||
impl Engine<EthereumMachine> for Tendermint {
|
||||
fn name(&self) -> &str { "Tendermint" }
|
||||
|
||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
||||
|
||||
/// (consensus view, proposal signature, authority signatures)
|
||||
fn seal_fields(&self) -> usize { 3 }
|
||||
|
||||
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 +480,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 +802,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!()
|
||||
@@ -857,7 +854,6 @@ mod tests {
|
||||
fn has_valid_metadata() {
|
||||
let engine = Spec::new_test_tendermint().engine;
|
||||
assert!(!engine.name().is_empty());
|
||||
assert!(engine.version().major >= 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -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,12 +26,11 @@ 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};
|
||||
use machine::EthereumMachine;
|
||||
use semantic_version::SemanticVersion;
|
||||
|
||||
/// Number of blocks in an ethash snapshot.
|
||||
// make dependent on difficulty incrment divisor?
|
||||
@@ -90,6 +89,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 +121,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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +168,6 @@ impl engines::EpochVerifier<EthereumMachine> for Arc<Ethash> {
|
||||
|
||||
impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
fn name(&self) -> &str { "Ethash" }
|
||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
||||
fn machine(&self) -> &EthereumMachine { &self.machine }
|
||||
|
||||
// Two fields - nonce and mix.
|
||||
@@ -181,6 +185,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 +359,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 +374,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 +458,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 +529,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]
|
||||
@@ -556,7 +575,6 @@ mod tests {
|
||||
fn has_valid_metadata() {
|
||||
let engine = test_spec().engine;
|
||||
assert!(!engine.name().is_empty());
|
||||
assert!(engine.version().major >= 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -30,15 +30,6 @@ pub use self::denominations::*;
|
||||
use machine::EthereumMachine;
|
||||
use super::spec::*;
|
||||
|
||||
/// Most recent fork block that we support on Mainnet.
|
||||
pub const FORK_SUPPORTED_FOUNDATION: u64 = 2675000;
|
||||
|
||||
/// Most recent fork block that we support on Ropsten.
|
||||
pub const FORK_SUPPORTED_ROPSTEN: u64 = 10;
|
||||
|
||||
/// Most recent fork block that we support on Kovan.
|
||||
pub const FORK_SUPPORTED_KOVAN: u64 = 0;
|
||||
|
||||
fn load<'a, T: Into<Option<SpecParams<'a>>>>(params: T, b: &[u8]) -> Spec {
|
||||
match params.into() {
|
||||
Some(params) => Spec::load(params, b),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -110,9 +110,10 @@ extern crate memorydb;
|
||||
extern crate patricia_trie as trie;
|
||||
extern crate triehash;
|
||||
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;
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ pub enum Error {
|
||||
VersionNotSupported(u64),
|
||||
/// Max chunk size is to small to fit basic account data.
|
||||
ChunkTooSmall,
|
||||
/// Oversized chunk
|
||||
ChunkTooLarge,
|
||||
/// Snapshots not supported by the consensus engine.
|
||||
SnapshotsUnsupported,
|
||||
/// Bad epoch transition.
|
||||
@@ -85,6 +87,7 @@ impl fmt::Display for Error {
|
||||
Error::Trie(ref err) => err.fmt(f),
|
||||
Error::VersionNotSupported(ref ver) => write!(f, "Snapshot version {} is not supprted.", ver),
|
||||
Error::ChunkTooSmall => write!(f, "Chunk size is too small."),
|
||||
Error::ChunkTooLarge => write!(f, "Chunk size is too large."),
|
||||
Error::SnapshotsUnsupported => write!(f, "Snapshots unsupported by consensus engine."),
|
||||
Error::BadEpochProof(i) => write!(f, "Bad epoch proof for transition to epoch {}", i),
|
||||
Error::WrongChunkFormat(ref msg) => write!(f, "Wrong chunk format: {}", msg),
|
||||
|
||||
@@ -86,6 +86,11 @@ mod traits {
|
||||
// Try to have chunks be around 4MB (before compression)
|
||||
const PREFERRED_CHUNK_SIZE: usize = 4 * 1024 * 1024;
|
||||
|
||||
// Maximal chunk size (decompressed)
|
||||
// Snappy::decompressed_len estimation may sometimes yield results greater
|
||||
// than PREFERRED_CHUNK_SIZE so allow some threshold here.
|
||||
const MAX_CHUNK_SIZE: usize = PREFERRED_CHUNK_SIZE / 4 * 5;
|
||||
|
||||
// Minimum supported state chunk version.
|
||||
const MIN_SUPPORTED_STATE_CHUNK_VERSION: u64 = 1;
|
||||
// current state chunk version.
|
||||
|
||||
@@ -23,7 +23,7 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
|
||||
use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService};
|
||||
use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService, MAX_CHUNK_SIZE};
|
||||
use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter};
|
||||
|
||||
use blockchain::BlockChain;
|
||||
@@ -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.
|
||||
@@ -130,6 +130,11 @@ impl Restoration {
|
||||
// feeds a state chunk, aborts early if `flag` becomes false.
|
||||
fn feed_state(&mut self, hash: H256, chunk: &[u8], flag: &AtomicBool) -> Result<(), Error> {
|
||||
if self.state_chunks_left.contains(&hash) {
|
||||
let expected_len = snappy::decompressed_len(chunk)?;
|
||||
if expected_len > MAX_CHUNK_SIZE {
|
||||
trace!(target: "snapshot", "Discarding large chunk: {} vs {}", expected_len, MAX_CHUNK_SIZE);
|
||||
return Err(::snapshot::Error::ChunkTooLarge.into());
|
||||
}
|
||||
let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?;
|
||||
|
||||
self.state.feed(&self.snappy_buffer[..len], flag)?;
|
||||
@@ -147,6 +152,11 @@ impl Restoration {
|
||||
// feeds a block chunk
|
||||
fn feed_blocks(&mut self, hash: H256, chunk: &[u8], engine: &EthEngine, flag: &AtomicBool) -> Result<(), Error> {
|
||||
if self.block_chunks_left.contains(&hash) {
|
||||
let expected_len = snappy::decompressed_len(chunk)?;
|
||||
if expected_len > MAX_CHUNK_SIZE {
|
||||
trace!(target: "snapshot", "Discarding large chunk: {} vs {}", expected_len, MAX_CHUNK_SIZE);
|
||||
return Err(::snapshot::Error::ChunkTooLarge.into());
|
||||
}
|
||||
let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?;
|
||||
|
||||
self.secondary.feed(&self.snappy_buffer[..len], engine, flag)?;
|
||||
@@ -682,7 +692,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,
|
||||
);
|
||||
|
||||
@@ -35,6 +35,15 @@ use std::cell::{RefCell, Cell};
|
||||
|
||||
const STORAGE_CACHE_ITEMS: usize = 8192;
|
||||
|
||||
/// Boolean type for clean/dirty status.
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub enum Filth {
|
||||
/// Data has not been changed.
|
||||
Clean,
|
||||
/// Data has been changed.
|
||||
Dirty,
|
||||
}
|
||||
|
||||
/// Single account in the system.
|
||||
/// Keeps track of changes to the code and storage.
|
||||
/// The changes are applied in `commit_storage` and `commit_code`
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::{fs, io};
|
||||
use std::io::Write;
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::collections::HashMap;
|
||||
use time;
|
||||
@@ -122,6 +123,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
|
||||
@@ -145,31 +153,39 @@ impl<T> DiskDirectory<T> where T: KeyFileManager {
|
||||
)
|
||||
}
|
||||
|
||||
/// insert account with given file name
|
||||
pub fn insert_with_filename(&self, account: SafeAccount, filename: String) -> Result<SafeAccount, Error> {
|
||||
|
||||
/// insert account with given filename. if the filename is a duplicate of any stored account and dedup is set to
|
||||
/// true, a random suffix is appended to the filename.
|
||||
pub fn insert_with_filename(&self, account: SafeAccount, mut filename: String, dedup: bool) -> Result<SafeAccount, Error> {
|
||||
// path to keyfile
|
||||
let mut keyfile_path = self.path.join(filename.as_str());
|
||||
|
||||
// check for duplicate filename and append random suffix
|
||||
if dedup && keyfile_path.exists() {
|
||||
let suffix = ::random::random_string(4);
|
||||
filename.push_str(&format!("-{}", suffix));
|
||||
keyfile_path.set_file_name(&filename);
|
||||
}
|
||||
|
||||
// update account filename
|
||||
let original_account = account.clone();
|
||||
let mut account = account;
|
||||
account.filename = Some(filename.clone());
|
||||
account.filename = Some(filename);
|
||||
|
||||
{
|
||||
// Path to keyfile
|
||||
let mut keyfile_path = self.path.clone();
|
||||
keyfile_path.push(filename.as_str());
|
||||
|
||||
// save the file
|
||||
let mut file = fs::File::create(&keyfile_path)?;
|
||||
if let Err(err) = self.key_manager.write(original_account, &mut file).map_err(|e| Error::Custom(format!("{:?}", e))) {
|
||||
drop(file);
|
||||
fs::remove_file(keyfile_path).expect("Expected to remove recently created file");
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
// write key content
|
||||
self.key_manager.write(original_account, &mut file).map_err(|e| Error::Custom(format!("{:?}", e)))?;
|
||||
|
||||
file.flush()?;
|
||||
|
||||
if let Err(_) = restrict_permissions_to_owner(keyfile_path.as_path()) {
|
||||
drop(file);
|
||||
fs::remove_file(keyfile_path).expect("Expected to remove recently created file");
|
||||
return Err(Error::Io(io::Error::last_os_error()));
|
||||
}
|
||||
|
||||
file.sync_all()?;
|
||||
}
|
||||
|
||||
Ok(account)
|
||||
@@ -192,17 +208,13 @@ impl<T> KeyDirectory for DiskDirectory<T> where T: KeyFileManager {
|
||||
|
||||
fn update(&self, account: SafeAccount) -> Result<SafeAccount, Error> {
|
||||
// Disk store handles updates correctly iff filename is the same
|
||||
self.insert(account)
|
||||
let filename = account_filename(&account);
|
||||
self.insert_with_filename(account, filename, false)
|
||||
}
|
||||
|
||||
fn insert(&self, account: SafeAccount) -> Result<SafeAccount, Error> {
|
||||
// build file path
|
||||
let filename = account.filename.as_ref().cloned().unwrap_or_else(|| {
|
||||
let timestamp = time::strftime("%Y-%m-%dT%H-%M-%S", &time::now_utc()).expect("Time-format string is valid.");
|
||||
format!("UTC--{}Z--{}", timestamp, Uuid::from(account.id))
|
||||
});
|
||||
|
||||
self.insert_with_filename(account, filename)
|
||||
let filename = account_filename(&account);
|
||||
self.insert_with_filename(account, filename, true)
|
||||
}
|
||||
|
||||
fn remove(&self, account: &SafeAccount) -> Result<(), Error> {
|
||||
@@ -226,7 +238,7 @@ impl<T> KeyDirectory for DiskDirectory<T> where T: KeyFileManager {
|
||||
}
|
||||
|
||||
fn unique_repr(&self) -> Result<u64, Error> {
|
||||
self.files_hash()
|
||||
self.last_modification_date()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +290,14 @@ impl KeyFileManager for DiskKeyFileManager {
|
||||
}
|
||||
}
|
||||
|
||||
fn account_filename(account: &SafeAccount) -> String {
|
||||
// build file path
|
||||
account.filename.clone().unwrap_or_else(|| {
|
||||
let timestamp = time::strftime("%Y-%m-%dT%H-%M-%S", &time::now_utc()).expect("Time-format string is valid.");
|
||||
format!("UTC--{}Z--{}", timestamp, Uuid::from(account.id))
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
extern crate tempdir;
|
||||
@@ -310,6 +330,38 @@ mod test {
|
||||
let _ = fs::remove_dir_all(dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_handle_duplicate_filenames() {
|
||||
// given
|
||||
let mut dir = env::temp_dir();
|
||||
dir.push("ethstore_should_handle_duplicate_filenames");
|
||||
let keypair = Random.generate().unwrap();
|
||||
let password = "hello world";
|
||||
let directory = RootDiskDirectory::create(dir.clone()).unwrap();
|
||||
|
||||
// when
|
||||
let account = SafeAccount::create(&keypair, [0u8; 16], password, 1024, "Test".to_owned(), "{}".to_owned());
|
||||
let filename = "test".to_string();
|
||||
let dedup = true;
|
||||
|
||||
directory.insert_with_filename(account.clone(), "foo".to_string(), dedup).unwrap();
|
||||
let file1 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap();
|
||||
let file2 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap();
|
||||
let file3 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap();
|
||||
|
||||
// then
|
||||
// the first file should have the original names
|
||||
assert_eq!(file1, filename);
|
||||
|
||||
// the following duplicate files should have a suffix appended
|
||||
assert!(file2 != file3);
|
||||
assert_eq!(file2.len(), filename.len() + 5);
|
||||
assert_eq!(file3.len(), filename.len() + 5);
|
||||
|
||||
// cleanup
|
||||
let _ = fs::remove_dir_all(dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_manage_vaults() {
|
||||
// given
|
||||
|
||||
@@ -106,7 +106,7 @@ impl VaultDiskDirectory {
|
||||
fn copy_to_vault(&self, vault: &VaultDiskDirectory) -> Result<(), Error> {
|
||||
for account in self.load()? {
|
||||
let filename = account.filename.clone().expect("self is instance of DiskDirectory; DiskDirectory fills filename in load; qed");
|
||||
vault.insert_with_filename(account, filename)?;
|
||||
vault.insert_with_filename(account, filename, true)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -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,
|
||||
@@ -155,9 +158,14 @@ impl SecretStore for EthStore {
|
||||
self.insert_account(vault, keypair.secret().clone(), password)
|
||||
}
|
||||
|
||||
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result<StoreAccountRef, Error> {
|
||||
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result<StoreAccountRef, Error> {
|
||||
let json_keyfile = json::KeyFile::load(json).map_err(|_| Error::InvalidKeyFile("Invalid JSON format".to_owned()))?;
|
||||
let mut safe_account = SafeAccount::from_file(json_keyfile, None);
|
||||
|
||||
if gen_id {
|
||||
safe_account.id = Random::random();
|
||||
}
|
||||
|
||||
let secret = safe_account.crypto.secret(password).map_err(|_| Error::InvalidPassword)?;
|
||||
safe_account.address = KeyPair::from_secret(secret)?.address();
|
||||
self.store.import(vault, safe_account)
|
||||
@@ -245,7 +253,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 +274,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 +475,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
|
||||
@@ -103,7 +116,7 @@ pub trait SecretStore: SimpleSecretStore {
|
||||
/// Imports presale wallet
|
||||
fn import_presale(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result<StoreAccountRef, Error>;
|
||||
/// Imports existing JSON wallet
|
||||
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result<StoreAccountRef, Error>;
|
||||
fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result<StoreAccountRef, Error>;
|
||||
/// Copies account between stores and vaults.
|
||||
fn copy_account(&self, new_store: &SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &str, new_password: &str) -> Result<(), Error>;
|
||||
/// Checks if password matches given account.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -14,3 +14,4 @@ semver = "0.6"
|
||||
ethcore-ipc = { path = "../ipc/rpc" }
|
||||
ethcore-util = { path = "../util" }
|
||||
ethcore-bigint = { path = "../util/bigint" }
|
||||
parity-version = { path = "../util/version" }
|
||||
|
||||
@@ -20,6 +20,7 @@ extern crate semver;
|
||||
extern crate ethcore_util as util;
|
||||
extern crate ethcore_bigint as bigint;
|
||||
extern crate ethcore_ipc as ipc;
|
||||
extern crate parity_version as version;
|
||||
|
||||
mod types;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use semver::{Version};
|
||||
use bigint::hash::H160;
|
||||
use util::misc::raw_package_info;
|
||||
use version::raw_package_info;
|
||||
use release_track::ReleaseTrack;
|
||||
|
||||
/// Version information of a particular release.
|
||||
|
||||
970
js/package-lock.json
generated
970
js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user