Compare commits

..

26 Commits

Author SHA1 Message Date
Denis S. Soldatov aka General-Beck
1ede2fbed2 fix snapcraft build (stable) (#7763)
* fix snapcraft build for stable

* fix snapcraft build (stable)
2018-01-31 18:35:13 +03:00
GitLab Build Bot
31ef44d718 [ci skip] js-precompiled 20180131-144450 2018-01-31 14:55:11 +00:00
André Silva
19fc9fcc58 [Stable] Backports (#7758)
* Filter-out nodes.json (#7716)

* Filter-out nodes.json

* network: sort node table nodes by failure ratio

* network: fix node table tests

* network: fit node failure percentage into buckets of 5%

* network: consider number of attempts in sorting of node table

* network: fix node table grumbles

* Fix client not being dropped on shutdown (#7695)

* parity: wait for client to drop on shutdown

* parity: fix grumbles in shutdown wait

* parity: increase shutdown timeouts

* Wrap --help output to 120 characters (#7626)

* Update Clap dependency and remove workarounds

* WIP

* Remove line breaks in help messages for now

* Multiple values can only be separated by commas (closes #7428)

* Grumbles; refactor repeating code; add constant

* Use a single Wrapper rather than allocate a new one for each call

* Wrap --help to 120 characters rather than 100 characters
2018-01-31 15:00:15 +01:00
Jaco Greeff
835dcaec2a [stable] Use explicit branch name in push (#7757) 2018-01-31 14:30:27 +01:00
Afri Schoedon
2c93b0fdf7 Bump stable to 1.8.8 (#7752) 2018-01-31 11:33:12 +01:00
Denis S. Soldatov aka General-Beck
e322fd824b fix js-release in stable (#7682)
we use an old assembly system < 1.9.0
2018-01-24 13:26:21 +03:00
Afri Schoedon
366320fb8d Update Info.plist 2018-01-23 22:36:16 +01:00
Denis S. Soldatov aka General-Beck
29dc3ca2dd fix conditions in gitlab-test (#7675) 2018-01-23 14:53:51 +03:00
Denis S. Soldatov aka General-Beck
5f590a0df5 remove cargo cache 2018-01-23 14:42:48 +03:00
5chdn
e3d32a4abb Merge branch 'stable' of github.com:paritytech/parity into stable 2018-01-23 11:01:41 +01:00
Afri Schoedon
9c7359e343 Bump stable version (#7665)
* Update .gitlab-ci.yml

fix cache:key

* Bump stable to 1.8.7
2018-01-23 11:01:09 +01:00
Marek Kotewicz
628f0878b1 Backports to stable (#7661)
* Update .gitlab-ci.yml

fix cache:key

* Fixed delegatecall's from/to (#7568)

* Fixed delegatecall's from/to, closes #7166

* added tests for delegatecall traces, #7167

* Fix Temporarily Invalid blocks handling (#7613)

* Handle temporarily invalid blocks in sync.

* Fix tests.

* Improve handling of RocksDB corruption (#7630)

* kvdb-rocksdb: update rust-rocksdb version

* kvdb-rocksdb: mark corruptions and attempt repair on db open

* kvdb-rocksdb: better corruption detection on open

* kvdb-rocksdb: add corruption_file_name const

* kvdb-rocksdb: rename mark_corruption to check_for_corruption
2018-01-23 10:58:08 +01:00
Denis S. Soldatov aka General-Beck
a835c13e6b add docker build for stable and cargo cache (#7672) 2018-01-23 06:20:22 +03:00
Denis S. Soldatov aka General-Beck
abcfcacf95 fix snapcraft build for stable (#7669) 2018-01-23 04:12:36 +03:00
Denis S. Soldatov aka General-Beck
9abc6bd7d1 Gitlab stable
update gitlab build script from master

Signed-off-by: Denis S. Soldatov aka General-Beck <general.beck@gmail.com>
2018-01-23 03:01:42 +03:00
5chdn
5e775f3e27 Merge branch 'stable' of github.com:paritytech/parity into stable 2018-01-22 13:00:47 +01:00
Afri Schoedon
1eab85afc6 Update .gitlab-ci.yml (#7599)
fix cache:key
2018-01-17 19:45:39 +03:00
Denis S. Soldatov aka General-Beck
662416f05b Update .gitlab-ci.yml
fix cache:key
2018-01-17 17:27:58 +01:00
Afri Schoedon
00b5d30d33 Make 1.8 stable (#7532)
* Bump 1.8 to stable

* Make js-precompiled stable
2018-01-17 12:28:38 +01:00
André Silva
2d051e4f79 kvdb: update rust-rocksdb version (#7508) 2018-01-09 19:13:29 +01:00
Marek Kotewicz
a257827f27 backports to beta (#7434)
* Merge pull request #7368 from paritytech/td-future-blocks

Wait for future blocks in AuRa

* Fix tracing failed calls.

* Problem: sending any Whisper message fails

The error is "PoW too low to compete with other messages"

This has been previously reported in #7144

Solution: prevent the move semantics

The source of the error is in PoolHandle.relay
implementation for NetPoolHandle.

Because of the move semantics, `res` variable is in fact
copied (as it implements Copy) into the closure and for
that reason, the returned result is always `false.

* Merge pull request #7433 from paritytech/td-strict-config

Strict config parsing

* Problem: AuRa's unsafeties around step duration (#7282)

Firstly, `Step.duration_remaining` casts it to u32, unnecesarily
limiting it to 2^32. While theoretically this is "good enough" (at 3
seconds steps it provides room for a little over 400 years), it is
still a lossy way to calculate the remaining time until the next step.

Secondly, step duration might be zero, triggering division by zero
in `Step.calibrate`

Solution: rework the code around the fact that duration is
typically in single digits and never grows, hence, it can be represented
by a much narrower range (u16) and this highlights the fact that
multiplying u64 by u16 will only result in an overflow in even further
future, at which point we should panic informatively (if anybody's
still around)

Similarly, panic when it is detected that incrementing the step
counter wrapped around on the overflow of usize.

As for the division by zero, prevent it by making zero an invalid
value for step duration. This will make AuRa log the constraint
mismatch and panic (after all, what purpose would zero step duration
serve? it makes no sense within the definition of the protocol,
as finality can only be achieved as per the specification
if messages are received within the step duration, which would violate
the speed of light and other physical laws in this case).

* Merge pull request #7437 from paritytech/a5-chains-expanse

Remove expanse chain

* Expanse Byzantium update w/ correct metropolis difficulty increment divisor (#7463)

* Byzantium Update for Expanse

Here the changes go. Hope I didnt miss anything.

* expip2 changes - update duration limit

* Fix missing EXPIP-2 fields

* Format numbers as hex

* Fix compilation errors

* Group expanse chain spec fields together

* Set metropolisDifficultyIncrementDivisor for Expanse

* Revert #7437

* Add Expanse block 900_000 hash checkpoint

* Advance AuRa step as far as we can and prevent invalid blocks. (#7451)

* Advance AuRa step as far as we can.

* Wait for future blocks.

* fixed panic when io is not available for export block, closes #7486 (#7495)

* Update Parity Mainnet Bootnodes (#7476)

* Update Parity Mainnet Bootnodes

* Replace the Azure HDD bootnodes with the new ones :)

* Use https connection (#7503)

Use https when connecting to etherscan.io API for price-info

* Expose default gas price percentile configuration in CLI (#7497)

* Expose gas price percentile.

* Fix light eth_call.

* fix gas_price in light client
2018-01-09 13:55:10 +01:00
Tomasz Drwięga
c3727266e1 [beta] Backport nonces reservations (#7439)
* Reserve nonces for signing (#6834)

* Nonce future - reserve and dispatch

* Single thread nonce tests

* Track status of reserved nonces.

* Initialization of nonce reservations.

* Prospective Signer

* Fix cli tests.

* Merge pull request #7025 from paritytech/fix-nonce-reservation

Fix nonce reservation

* Fix build.
2018-01-09 11:13:27 +01:00
Afri Schoedon
364bf48cef Bump beta to 1.8.6 (#7442)
* Bump beta to 1.8.6

* Fix Cargo.lock
2018-01-04 09:32:38 +01:00
Marek Kotewicz
849e574c2c Merge pull request #7438 from paritytech/beta-backports-kvdb
[beta] kvdb backports
2018-01-03 16:08:56 +01:00
André Silva
e93872e7bb Upgrade to RocksDB 5.8.8 and tune settings to reduce space amplification (#7348)
* kvdb-rocksdb: update to RocksDB 5.8.8

* kvdb-rocksdb: tune RocksDB options

* Switch to level-style compaction
* Increase default block size (16K), and use bigger blocks for HDDs (64K)
* Increase default file size base (64MB SSDs, 256MB HDDs)
* Create a single block cache shared across all column families
* Tune compaction settings using RocksDB helper functions, taking into account
  memory budget spread across all columns
* Configure backgrounds jobs based on the number of CPUs
* Set some default recommended settings

* ethcore: remove unused config blockchain.db_cache_size

* parity: increase default value for db_cache_size

* kvdb-rocksdb: enable compression on all levels

* kvdb-rocksdb: set global db_write_bufer_size

* kvdb-rocksdb: reduce db_write_bufer_size to force earlier flushing

* kvdb-rocksdb: use master branch for rust-rocksdb dependency
2018-01-03 13:40:58 +00:00
Marek Kotewicz
61c3e1a2d6 Merge pull request #6720 from paritytech/kvdb_split
separated kvdb into 3 crates: kvdb, kvdb-memorydb && kvdb-rocksdb
2018-01-03 13:22:31 +00:00
140 changed files with 3401 additions and 2289 deletions

View File

@@ -4,566 +4,195 @@ 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
image: parity/rust:gitlab-ci
only:
- stable
- beta
- tags
- 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
- scripts/gitlab-build.sh x86_64-unknown-linux-gnu x86_64-unknown-linux-gnu amd64 gcc g++
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
only:
- stable
- beta
- tags
- 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++
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
only:
- stable
- beta
- tags
- 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++
tags:
- rust
- rust-centos
artifacts:
paths:
- target/release/parity
- parity.zip
name: "x86_64-unknown-centos-gnu_parity"
linux-i686:
stage: build
image: parity/rust-i686:gitlab-ci
only:
- stable
- beta
- tags
- 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++
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
only:
- stable
- beta
- tags
- 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++
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
only:
- stable
- beta
- tags
- 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++
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
only:
- stable
- beta
- tags
- 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++
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: parity/snapcraft:gitlab-ci
only:
- stable
- beta
- tags
- triggers
script:
- scripts/gitlab-build.sh x86_64-unknown-snap-gnu x86_64-unknown-linux-gnu amd64 gcc g++
tags:
- rust-stable
artifacts:
paths:
- scripts/parity_*_amd64.snap
name: "stable-x86_64-unknown-snap-gnu_parity"
allow_failure: true
darwin:
stage: build
only:
- stable
- beta
- 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++
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:
- stable
- beta
- tags
- 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 "" "" ""
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
only:
- stable
- beta
- tags
- triggers
before_script:
- docker info
script:
- if [ "$CI_BUILD_REF_NAME" == "beta-release" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi
- DOCKER_TAG=$CI_BUILD_REF_NAME
- 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 +201,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 +218,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 +229,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:

166
Cargo.lock generated
View File

@@ -25,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"
@@ -177,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"
@@ -233,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"
@@ -260,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)",
]
@@ -360,7 +372,7 @@ dependencies = [
"bloomable 0.1.0",
"ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethjson 0.1.0",
"hash 0.1.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -574,7 +586,7 @@ dependencies = [
"ethcore-ipc-nano 1.8.0",
"ethcore-logger 1.8.0",
"ethcore-stratum 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
@@ -587,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)",
@@ -596,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",
@@ -668,7 +682,7 @@ version = "1.8.0"
dependencies = [
"ethcore-bigint 0.1.3",
"ethcore-devtools 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
]
@@ -718,7 +732,7 @@ dependencies = [
"ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0",
"ethcore-ipc-nano 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
@@ -737,13 +751,15 @@ dependencies = [
"ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0",
"ethcore-network 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
@@ -787,7 +803,7 @@ dependencies = [
"ethcore-devtools 1.8.0",
"ethcore-io 1.8.0",
"ethcore-logger 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethcrypto 0.1.0",
"ethkey 0.2.0",
"hash 0.1.0",
@@ -802,6 +818,8 @@ dependencies = [
"rlp 0.2.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -822,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.5",
"ethcore-util 1.8.8",
"ethcrypto 0.1.0",
"ethkey 0.2.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -830,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",
@@ -857,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.5",
"ethcore-util 1.8.8",
"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)",
@@ -870,7 +889,7 @@ dependencies = [
[[package]]
name = "ethcore-util"
version = "1.8.5"
version = "1.8.8"
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)",
@@ -885,6 +904,7 @@ dependencies = [
"hashdb 0.1.0",
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb 0.1.0",
"kvdb-memorydb 0.1.0",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1004,12 +1024,13 @@ dependencies = [
"ethcore-ipc-nano 1.8.0",
"ethcore-light 1.8.0",
"ethcore-network 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
@@ -1030,7 +1051,7 @@ dependencies = [
"common-types 0.1.0",
"ethcore-bigint 0.1.3",
"ethcore-logger 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethjson 0.1.0",
"evmjit 1.8.0",
"hash 0.1.0",
@@ -1052,7 +1073,7 @@ dependencies = [
"ethcore 1.8.0",
"ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethjson 0.1.0",
"evm 0.1.0",
"panic_hook 0.1.0",
@@ -1128,7 +1149,7 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1263,7 +1284,7 @@ dependencies = [
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1350,7 +1371,7 @@ dependencies = [
"ethcore-bigint 0.1.3",
"ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1500,11 +1521,28 @@ version = "0.1.0"
dependencies = [
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0",
]
[[package]]
name = "kvdb-memorydb"
version = "0.1.0"
dependencies = [
"kvdb 0.1.0",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0",
]
[[package]]
name = "kvdb-rocksdb"
version = "0.1.0"
dependencies = [
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.1.3",
"ethcore-devtools 1.8.0",
"hashdb 0.1.0",
"kvdb 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.0",
@@ -1656,6 +1694,7 @@ version = "0.1.0"
dependencies = [
"ethcore-devtools 1.8.0",
"kvdb 0.1.0",
"kvdb-rocksdb 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"macros 0.1.0",
]
@@ -1843,9 +1882,9 @@ dependencies = [
"ethcore-bytes 0.1.0",
"ethcore-io 1.8.0",
"ethcore-network 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
@@ -1960,7 +1999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num_cpus"
version = "1.6.2"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2042,11 +2081,11 @@ dependencies = [
[[package]]
name = "parity"
version = "1.8.5"
version = "1.8.8"
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)",
@@ -2066,7 +2105,7 @@ dependencies = [
"ethcore-network 1.8.0",
"ethcore-secretstore 1.0.0",
"ethcore-stratum 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethkey 0.2.0",
"ethsync 1.8.0",
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2076,12 +2115,12 @@ dependencies = [
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
"kvdb 0.1.0",
"kvdb-rocksdb 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"migration 0.1.0",
"node-filter 1.8.0",
"node-health 0.1.0",
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0",
"parity-dapps 1.8.0",
@@ -2106,6 +2145,8 @@ dependencies = [
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2122,7 +2163,7 @@ dependencies = [
"ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0",
"ethcore-devtools 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
@@ -2184,7 +2225,7 @@ dependencies = [
"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.5",
"ethcore-util 1.8.8",
"fetch 0.1.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"hash 0.1.0",
@@ -2206,7 +2247,7 @@ dependencies = [
"ethcore 1.8.0",
"ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
@@ -2220,9 +2261,10 @@ version = "0.1.0"
dependencies = [
"ethcore 1.8.0",
"ethcore-io 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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)",
@@ -2235,7 +2277,7 @@ name = "parity-machine"
version = "0.1.0"
dependencies = [
"ethcore-bigint 0.1.3",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
]
[[package]]
@@ -2263,13 +2305,14 @@ dependencies = [
"ethcore-light 1.8.0",
"ethcore-logger 1.8.0",
"ethcore-network 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"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",
@@ -2280,7 +2323,7 @@ dependencies = [
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
"kvdb 0.1.0",
"kvdb-memorydb 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"macros 0.1.0",
"multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2344,7 +2387,7 @@ name = "parity-ui"
version = "1.8.0"
dependencies = [
"parity-ui-dev 1.8.0",
"parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git?branch=beta)",
"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)",
]
@@ -2358,7 +2401,7 @@ dependencies = [
[[package]]
name = "parity-ui-precompiled"
version = "1.4.0"
source = "git+https://github.com/paritytech/js-precompiled.git?branch=beta#26c6b48bfc83bb26445f6d72646773b6d5838fe4"
source = "git+https://github.com/paritytech/js-precompiled.git?branch=stable#f6c7d8b9d8b0fe979484a2e8d7591215c21e67b2"
dependencies = [
"parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2373,7 +2416,7 @@ dependencies = [
"ethcore-bytes 0.1.0",
"ethcore-ipc 1.8.0",
"ethcore-ipc-codegen 1.8.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethsync 1.8.0",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-common-types 1.8.0",
@@ -2693,7 +2736,7 @@ dependencies = [
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2780,7 +2823,7 @@ dependencies = [
[[package]]
name = "rocksdb"
version = "0.4.5"
source = "git+https://github.com/paritytech/rust-rocksdb#4364caec4dd5da1a1d78c39276774ee65bf55c7d"
source = "git+https://github.com/paritytech/rust-rocksdb#ecf06adf3148ab10f6f7686b724498382ff4f36e"
dependencies = [
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2790,10 +2833,12 @@ dependencies = [
[[package]]
name = "rocksdb-sys"
version = "0.3.0"
source = "git+https://github.com/paritytech/rust-rocksdb#4364caec4dd5da1a1d78c39276774ee65bf55c7d"
source = "git+https://github.com/paritytech/rust-rocksdb#ecf06adf3148ab10f6f7686b724498382ff4f36e"
dependencies = [
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)",
]
[[package]]
@@ -2835,7 +2880,7 @@ name = "rpc-cli"
version = "1.4.0"
dependencies = [
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-rpc 1.8.0",
"parity-rpc-client 1.4.0",
@@ -3090,6 +3135,15 @@ dependencies = [
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "snappy-sys"
version = "0.1.0"
source = "git+https://github.com/paritytech/rust-snappy#858eac97192ea25d18d3f3626a8cc13ca0b175bb"
dependencies = [
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "spmc"
version = "0.2.2"
@@ -3231,10 +3285,9 @@ dependencies = [
[[package]]
name = "textwrap"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3551,7 +3604,7 @@ dependencies = [
"common-types 0.1.0",
"ethcore-bigint 0.1.3",
"ethcore-bytes 0.1.0",
"ethcore-util 1.8.5",
"ethcore-util 1.8.8",
"ethjson 0.1.0",
"evmjit 1.8.0",
"hash 0.1.0",
@@ -3573,7 +3626,7 @@ 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.5",
"ethcore-util 1.8.8",
"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",
@@ -3586,7 +3639,7 @@ 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.26.2 (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)",
@@ -3665,6 +3718,7 @@ dependencies = [
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7d1c0d48a81bbb13043847f957971f4d87c81542d80ece5e84ba3cba4058fd4"
"checksum arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "699e63a93b79d717e8c3b5eb1b28b7780d0d6d9e59a72eb769291c83b0c8dc67"
@@ -3684,6 +3738,7 @@ dependencies = [
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d"
"checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "<none>"
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
@@ -3693,7 +3748,7 @@ dependencies = [
"checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34aa7da06f10541fbca6850719cdaa8fa03060a5d2fb33840f149cf8133a00c7"
"checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2"
"checksum clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f4a2b3bb7ef3c672d7c13d15613211d5a6976b6892c598b0fcb5d40765f19c2"
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
"checksum clippy 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad3f3dc94d81a6505eb28bf545b501fc9d7525ee9864df5a4b2b6d82629f038"
"checksum clippy 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "d19bda68c3db98e3a780342f6101b44312fef20a5f13ce756d1202a35922b01b"
@@ -3803,7 +3858,7 @@ dependencies = [
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
"checksum num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "288629c76fac4b33556f4b7ab57ba21ae202da65ba8b77466e6d598e31990790"
"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
"checksum num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584"
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
"checksum number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "59a14be9c211cb9c602bad35ac99f41e9a84b44d71b8cbd3040e3bd02a214902"
"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c"
@@ -3814,7 +3869,7 @@ 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?branch=beta)" = "<none>"
"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"
@@ -3888,6 +3943,7 @@ dependencies = [
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
"checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"
"checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
"checksum spmc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd1f11d1fb5fd41834e55ce0b85a186efbf2f2afd9fdb09e2c8d72f9bff1ad1a"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
@@ -3904,7 +3960,7 @@ dependencies = [
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
"checksum termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
"checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292"

View File

@@ -1,7 +1,7 @@
[package]
description = "Parity Ethereum client"
name = "parity"
version = "1.8.5"
version = "1.8.8"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"
@@ -12,6 +12,8 @@ env_logger = "0.4"
rustc-hex = "1.0"
docopt = "0.8"
clap = "2"
term_size = "0.3"
textwrap = "0.9"
time = "0.1"
num_cpus = "1.2"
number_prefix = "0.2"
@@ -63,7 +65,7 @@ path = { path = "util/path" }
panic_hook = { path = "panic_hook" }
hash = { path = "util/hash" }
migration = { path = "util/migration" }
kvdb = { path = "util/kvdb" }
kvdb-rocksdb = { path = "util/kvdb-rocksdb" }
parity-dapps = { path = "dapps", optional = true }
clippy = { version = "0.0.103", optional = true}

View File

@@ -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 = "beta" }
parity-ui-precompiled = { git = "https://github.com/paritytech/js-precompiled.git", optional = true, branch = "stable" }
[features]
no-precompiled-js = ["parity-ui-dev"]

View File

@@ -56,6 +56,8 @@ rand = "0.3"
rlp = { path = "../util/rlp" }
rlp_derive = { path = "../util/rlp_derive" }
kvdb = { path = "../util/kvdb" }
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
kvdb-memorydb = { path = "../util/kvdb-memorydb" }
util-error = { path = "../util/error" }
snappy = { path = "../util/snappy" }
migration = { path = "../util/migration" }
@@ -81,7 +83,7 @@ native-contracts = { path = "native_contracts", features = ["test_contracts"] }
[features]
jit = ["evm/jit"]
evm-debug = ["slow-blocks"]
evm-debug-tests = ["evm-debug"]
evm-debug-tests = ["evm-debug", "evm/evm-debug-tests"]
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
json-tests = []
test-heavy = []

View File

@@ -26,3 +26,5 @@ rustc-hex = "1.0"
[features]
jit = ["evmjit"]
evm-debug = []
evm-debug-tests = ["evm-debug"]

View File

@@ -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);
}

View File

@@ -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")]

View File

@@ -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 = []

View File

@@ -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]

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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" }

View File

@@ -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(),

View File

@@ -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"
},

View File

@@ -176,12 +176,14 @@
"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://dc72806c3aa8fda207c8c018aba8d6cf143728b3628b6ded8d5e8cdeb8aa05cbd53f710ecd014c9a8f0d1e98f2874bff8afb15a229202f510a9c0258d1f6d109@159.203.210.80:30303",
"enode://aafde2e81e035f417019a80f5342d1cd0e5bce97f83230fc57e1abbb3a9a5d6fb751446040c67261ed422324ffb69214567e181bb4ac0cc6e817451be0eaad1e@52.178.74.216:30303",
"enode://460e54d7e9a361d326a9e503b3879c6a1075e1bfb7ea919b512ea1fe841e65f82c5f87af028f14a7825be1c1260825d5326b93b43a5bc72e3214a99e0c4c7bd4@52.230.6.166:30303",
"enode://28faaf6b2e86694d8978b8e6986e7813951d7bd25201116fa77de893aabedd2a4a8d5832776905b4c3e616320506516d08239d82aeef4355f6878c3a701a6059@40.71.19.172: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",

View File

@@ -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)?;

View File

@@ -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 {

View File

@@ -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,
}
}
}

View File

@@ -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,

View File

@@ -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(

View File

@@ -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};

View File

@@ -44,15 +44,18 @@ use bigint::hash::{H256, H520};
use semantic_version::SemanticVersion;
use parking_lot::{Mutex, RwLock};
use unexpected::{Mismatch, OutOfBounds};
use util::*;
use bytes::Bytes;
use util::Address;
mod finality;
/// `AuthorityRound` params.
pub struct AuthorityRoundParams {
/// Time to wait before next block or authority switching.
pub step_duration: Duration,
/// Time to wait before next block or authority switching,
/// in seconds.
///
/// Deliberately typed as u16 as too high of a value leads
/// to slow block issuance.
pub step_duration: u16,
/// Starting step,
pub start_step: Option<u64>,
/// Valid validators.
@@ -71,10 +74,17 @@ pub struct AuthorityRoundParams {
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),
@@ -92,36 +102,74 @@ 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(())
}
}
}
@@ -242,9 +290,11 @@ struct EpochVerifier {
impl super::EpochVerifier<EthereumMachine> for EpochVerifier {
fn verify_light(&self, header: &Header) -> Result<(), Error> {
// Validate the timestamp
verify_timestamp(&*self.step, header_step(header)?)?;
// always check the seal since it's fast.
// nothing heavier to do.
verify_external(header, &self.subchain_validators, &*self.step, |_| {})
verify_external(header, &self.subchain_validators)
}
fn check_finality_proof(&self, proof: &[u8]) -> Option<Vec<H256>> {
@@ -268,7 +318,7 @@ impl super::EpochVerifier<EthereumMachine> for EpochVerifier {
//
// `verify_external` checks that signature is correct and author == signer.
if header.seal().len() != 2 { return None }
otry!(verify_external(header, &self.subchain_validators, &*self.step, |_| {}).ok());
otry!(verify_external(header, &self.subchain_validators).ok());
let newly_finalized = otry!(finality_checker.push_hash(header.hash(), header.author().clone()).ok());
finalized.extend(newly_finalized);
@@ -278,16 +328,6 @@ impl super::EpochVerifier<EthereumMachine> for EpochVerifier {
}
}
// Report misbehavior
#[derive(Debug)]
#[allow(dead_code)]
enum Report {
// Malicious behavior
Malicious(Address, BlockNumber, Bytes),
// benign misbehavior
Benign(Address, BlockNumber),
}
fn header_step(header: &Header) -> Result<usize, ::rlp::DecoderError> {
UntrustedRlp::new(&header.seal().get(0).expect("was either checked with verify_block_basic or is genesis; has 2 fields; qed (Make sure the spec file has a correct genesis seal)")).as_val()
}
@@ -306,28 +346,35 @@ fn is_step_proposer(validators: &ValidatorSet, bh: &H256, step: usize, address:
step_proposer(validators, bh, step) == *address
}
fn verify_external<F: Fn(Report)>(header: &Header, validators: &ValidatorSet, step: &Step, report: F)
-> Result<(), Error>
{
fn verify_timestamp(step: &Step, header_step: usize) -> Result<(), BlockError> {
match step.check_future(header_step) {
Err(None) => {
trace!(target: "engine", "verify_timestamp: block from the future");
Err(BlockError::InvalidSeal.into())
},
Err(Some(oob)) => {
// NOTE This error might be returned only in early stage of verification (Stage 1).
// Returning it further won't recover the sync process.
trace!(target: "engine", "verify_timestamp: block too early");
Err(BlockError::TemporarilyInvalid(oob).into())
},
Ok(_) => Ok(()),
}
}
fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Error> {
let header_step = header_step(header)?;
// Give one step slack if step is lagging, double vote is still not possible.
if step.is_future(header_step) {
trace!(target: "engine", "verify_block_external: block from the future");
report(Report::Benign(*header.author(), header.number()));
Err(BlockError::InvalidSeal)?
} else {
let proposer_signature = header_signature(header)?;
let correct_proposer = validators.get(header.parent_hash(), header_step);
let is_invalid_proposer = *header.author() != correct_proposer ||
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
let proposer_signature = header_signature(header)?;
let correct_proposer = validators.get(header.parent_hash(), header_step);
let is_invalid_proposer = *header.author() != correct_proposer ||
!verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?;
if is_invalid_proposer {
trace!(target: "engine", "verify_block_external: bad proposer for step: {}", header_step);
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
} else {
Ok(())
}
if is_invalid_proposer {
trace!(target: "engine", "verify_block_external: bad proposer for step: {}", header_step);
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
} else {
Ok(())
}
}
@@ -359,8 +406,12 @@ impl AsMillis for Duration {
impl AuthorityRound {
/// Create a new instance of AuthorityRound engine.
pub fn new(our_params: AuthorityRoundParams, machine: EthereumMachine) -> Result<Arc<Self>, Error> {
if our_params.step_duration == 0 {
error!(target: "engine", "Authority Round step duration can't be zero, aborting");
panic!("authority_round: step duration can't be zero")
}
let should_timeout = our_params.start_step.is_none();
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / our_params.step_duration.as_secs())) as usize;
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / (our_params.step_duration as u64))) as usize;
let engine = Arc::new(
AuthorityRound {
transition_service: IoService::<()>::start()?,
@@ -414,9 +465,15 @@ impl IoHandler<()> for TransitionHandler {
fn timeout(&self, io: &IoContext<()>, timer: TimerToken) {
if timer == ENGINE_TIMEOUT_TOKEN {
if let Some(engine) = self.engine.upgrade() {
engine.step();
let remaining = engine.step.duration_remaining();
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining.as_millis())
// NOTE we might be lagging by couple of steps in case the timeout
// has not been called fast enough.
// Make sure to advance up to the actual step.
while engine.step.duration_remaining().as_millis() == 0 {
engine.step();
}
let next_run_at = engine.step.duration_remaining().as_millis() >> 2;
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, next_run_at)
.unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e))
}
}
@@ -489,6 +546,13 @@ impl Engine<EthereumMachine> for AuthorityRound {
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;
}
@@ -583,26 +647,38 @@ impl Engine<EthereumMachine> for AuthorityRound {
/// Check the number of seal fields.
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()))?;
}
@@ -615,7 +691,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
let skipped_primary = step_proposer(&*self.validators, &parent.hash(), s);
// Do not report this signer.
if skipped_primary != me {
self.validators.report_benign(&skipped_primary, header.number(), header.number());
self.validators.report_benign(&skipped_primary, set_number, header.number());
}
// Stop reporting once validators start repeating.
if !reported.insert(skipped_primary) { break; }
@@ -630,9 +706,8 @@ impl Engine<EthereumMachine> for AuthorityRound {
// fetch correct validator set for current epoch, taking into account
// finality of previous transitions.
let active_set;
let (validators, set_number) = if self.immediate_transitions {
(&*self.validators, header.number())
let validators = if self.immediate_transitions {
&*self.validators
} else {
// get correct validator set for epoch.
let client = match self.client.read().as_ref().and_then(|weak| weak.upgrade()) {
@@ -650,21 +725,12 @@ impl Engine<EthereumMachine> for AuthorityRound {
}
active_set = epoch_manager.validators().clone();
(&active_set as &_, epoch_manager.epoch_transition_number)
};
// always report with "self.validators" so that the report actually gets
// to the contract.
let report = |report| match report {
Report::Benign(address, block_number) =>
self.validators.report_benign(&address, set_number, block_number),
Report::Malicious(address, block_number, proof) =>
self.validators.report_malicious(&address, set_number, block_number, proof),
&active_set as &_
};
// verify signature against fixed list, but reports should go to the
// contract itself.
verify_external(header, validators, &*self.step, report)
verify_external(header, validators)
}
fn genesis_epoch_data(&self, header: &Header, call: &Call) -> Result<Vec<u8>, String> {
@@ -987,8 +1053,7 @@ mod tests {
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
assert!(engine.verify_block_external(&header).is_ok());
header.set_seal(vec![encode(&5usize).into_vec(), encode(&(&*signature as &[u8])).into_vec()]);
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
assert!(engine.verify_block_external(&header).is_err());
assert!(engine.verify_block_basic(&header).is_err());
}
#[test]
@@ -1019,7 +1084,7 @@ 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,
@@ -1059,7 +1124,7 @@ mod tests {
fn test_uncles_transition() {
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,
@@ -1081,4 +1146,51 @@ mod tests {
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();
}
}

View File

@@ -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());

View File

@@ -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),

View File

@@ -90,6 +90,10 @@ pub struct EthashParams {
pub eip649_delay: u64,
/// EIP-649 base reward.
pub eip649_reward: Option<U256>,
/// EXPIP-2 block height
pub expip2_transition: u64,
/// EXPIP-2 duration limit
pub expip2_duration_limit: u64,
}
impl From<ethjson::spec::EthashParams> for EthashParams {
@@ -118,6 +122,8 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into),
eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into),
eip649_reward: p.eip649_reward.map(Into::into),
expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into),
expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into),
}
}
}
@@ -355,7 +361,13 @@ impl Ethash {
self.ethash_params.difficulty_bound_divisor
};
let duration_limit = self.ethash_params.duration_limit;
let expip2_hardfork = header.number() >= self.ethash_params.expip2_transition;
let duration_limit = if expip2_hardfork {
self.ethash_params.expip2_duration_limit
} else {
self.ethash_params.duration_limit
};
let frontier_limit = self.ethash_params.homestead_transition;
let mut target = if header.number() < frontier_limit {
@@ -364,8 +376,7 @@ impl Ethash {
} else {
*parent.difficulty() + (*parent.difficulty() / difficulty_bound_divisor)
}
}
else {
} else {
trace!(target: "ethash", "Calculating difficulty parent.difficulty={}, header.timestamp={}, parent.timestamp={}", parent.difficulty(), header.timestamp(), parent.timestamp());
//block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)
let (increment_divisor, threshold) = if header.number() < self.ethash_params.eip100b_transition {

View File

@@ -486,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()),
};
@@ -574,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())
};
@@ -936,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

View File

@@ -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(

View File

@@ -113,6 +113,8 @@ extern crate ansi_term;
extern crate semantic_version;
extern crate unexpected;
extern crate kvdb;
extern crate kvdb_rocksdb;
extern crate kvdb_memorydb;
extern crate util_error;
extern crate snappy;
extern crate migration;

View File

@@ -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;

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -40,7 +40,7 @@ use parking_lot::{Mutex, RwLock, RwLockReadGuard};
use util_error::UtilError;
use bytes::Bytes;
use util::journaldb::Algorithm;
use kvdb::{Database, DatabaseConfig};
use kvdb_rocksdb::{Database, DatabaseConfig};
use snappy;
/// Helper for removing directories in case of error.
@@ -682,7 +682,7 @@ mod tests {
#[test]
fn cannot_finish_with_invalid_chunks() {
use bigint::hash::H256;
use kvdb::DatabaseConfig;
use kvdb_rocksdb::DatabaseConfig;
let spec = get_test_spec();
let dir = RandomTempPath::new();

View File

@@ -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() }

View File

@@ -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());

View File

@@ -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;

View File

@@ -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;

View File

@@ -672,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,
);

View File

@@ -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],
}),
}];

View File

@@ -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;

View File

@@ -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,
}
}

View File

@@ -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;

View File

@@ -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]

View File

@@ -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,
},
}
}
}

View File

@@ -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(),

View File

@@ -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());
}

View File

@@ -273,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 + 15;
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(())
}
@@ -359,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),
}
}
@@ -643,11 +654,11 @@ 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 + 20);
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), true);
header = good.clone();
header.set_timestamp(get_time().sec as u64 + 10);

View File

@@ -4,7 +4,7 @@ set -e
# variables
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
PACKAGES=( "parity" "etherscan" "shapeshift" "jsonrpc" )
BRANCH=$CI_BUILD_REF_NAME
BRANCH="stable"
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git"
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"

View File

@@ -22,7 +22,7 @@ use super::ValidatorSet;
/// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
pub struct AuthorityRoundParams {
/// Block duration.
/// Block duration, in seconds.
#[serde(rename="stepDuration")]
pub step_duration: Uint,
/// Valid authorities

View File

@@ -125,6 +125,14 @@ pub struct EthashParams {
/// EIP-649 base reward.
#[serde(rename="eip649Reward")]
pub eip649_reward: Option<Uint>,
/// EXPIP-2 block height
#[serde(rename="expip2Transition")]
pub expip2_transition: Option<Uint>,
/// EXPIP-2 duration limit
#[serde(rename="expip2DurationLimit")]
pub expip2_duration_limit: Option<Uint>,
}
/// Ethash engine deserialization.
@@ -241,6 +249,8 @@ mod tests {
eip649_transition: None,
eip649_delay: None,
eip649_reward: None,
expip2_transition: None,
expip2_duration_limit: None,
}
});
}
@@ -287,6 +297,8 @@ mod tests {
eip649_transition: None,
eip649_delay: None,
eip649_reward: None,
expip2_transition: None,
expip2_duration_limit: None,
}
});
}

View File

@@ -14,4 +14,7 @@ serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
log = "0.3"
[dev-dependencies]
ethkey = { path = "../ethkey" }
kvdb-memorydb = { path = "../util/kvdb-memorydb" }

View File

@@ -44,6 +44,8 @@ extern crate log;
#[cfg(test)]
extern crate ethkey;
#[cfg(test)]
extern crate kvdb_memorydb;
const LOCAL_TRANSACTIONS_KEY: &'static [u8] = &*b"LOCAL_TXS";
@@ -243,7 +245,7 @@ mod tests {
#[test]
fn twice_empty() {
let db = Arc::new(::kvdb::in_memory(0));
let db = Arc::new(::kvdb_memorydb::create(0));
{
let store = super::create(db.clone(), None, Dummy(vec![]));
@@ -272,7 +274,7 @@ mod tests {
PendingTransaction::new(signed, condition)
}).collect();
let db = Arc::new(::kvdb::in_memory(0));
let db = Arc::new(::kvdb_memorydb::create(0));
{
// nothing written yet, will write pending.
@@ -311,7 +313,7 @@ mod tests {
PendingTransaction::new(signed, None)
});
let db = Arc::new(::kvdb::in_memory(0));
let db = Arc::new(::kvdb_memorydb::create(0));
{
// nothing written, will write bad.
let store = super::create(db.clone(), None, Dummy(transactions.clone()));

View File

@@ -13,6 +13,8 @@
0ACF9AC71E30FAB600D5C935 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0ACF9AC51E30FAB600D5C935 /* MainMenu.xib */; };
0AE564F11E3CE42C00BD01F7 /* GetBSDProcessList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE564F01E3CE42C00BD01F7 /* GetBSDProcessList.swift */; };
0AED4DA01E3E22F800BF87C0 /* ethstore in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0AED4D9F1E3E22F800BF87C0 /* ethstore */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
84CF92B3200E559900AD6E78 /* parity-evm in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84CF92B2200E559900AD6E78 /* parity-evm */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
84CF92B6200E56AE00AD6E78 /* ethkey in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84CF92B5200E56AE00AD6E78 /* ethkey */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -22,6 +24,8 @@
dstPath = "";
dstSubfolderSpec = 6;
files = (
84CF92B6200E56AE00AD6E78 /* ethkey in CopyFiles */,
84CF92B3200E559900AD6E78 /* parity-evm in CopyFiles */,
0AED4DA01E3E22F800BF87C0 /* ethstore in CopyFiles */,
0A7A475D1E3D2CDD0093D1AB /* parity in CopyFiles */,
);
@@ -38,6 +42,8 @@
0ACF9AC81E30FAB600D5C935 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0AE564F01E3CE42C00BD01F7 /* GetBSDProcessList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetBSDProcessList.swift; sourceTree = "<group>"; };
0AED4D9F1E3E22F800BF87C0 /* ethstore */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = ethstore; path = ../target/release/ethstore; sourceTree = "<group>"; };
84CF92B2200E559900AD6E78 /* parity-evm */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = "parity-evm"; path = "../target/release/parity-evm"; sourceTree = "<group>"; };
84CF92B5200E56AE00AD6E78 /* ethkey */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = ethkey; path = ../target/release/ethkey; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -54,6 +60,8 @@
0ACF9AB51E30FAB600D5C935 = {
isa = PBXGroup;
children = (
84CF92B5200E56AE00AD6E78 /* ethkey */,
84CF92B2200E559900AD6E78 /* parity-evm */,
0AED4D9F1E3E22F800BF87C0 /* ethstore */,
0A7A475C1E3D2CDD0093D1AB /* parity */,
0ACF9AC01E30FAB600D5C935 /* Parity Ethereum */,
@@ -110,7 +118,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0800;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = "Parity Technologies";
TargetAttributes = {
0ACF9ABD1E30FAB600D5C935 = {
@@ -192,6 +200,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -241,6 +250,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;

View File

@@ -462,7 +462,7 @@
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>VERSION</key>
<string>1.8.5</string>
<string>1.8.8</string>
</dict>
<key>UUID</key>
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>

View File

@@ -1,4 +1,4 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
@@ -22,12 +22,12 @@ import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var statusMenu: NSMenu!
@IBOutlet weak var startAtLogonMenuItem: NSMenuItem!
let statusItem = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength)
var parityPid: Int32? = nil
var commandLine: [String] = []
let defaultDefaults = "{\"fat_db\":false,\"mode\":\"passive\",\"mode.alarm\":3600,\"mode.timeout\":300,\"pruning\":\"fast\",\"tracing\":false}"
func menuAppPath() -> String {
return Bundle.main.executablePath!
}
@@ -40,20 +40,20 @@ class AppDelegate: NSObject, NSApplicationDelegate {
return NSRunningApplication.runningApplications(withBundleIdentifier: Bundle.main.bundleIdentifier!).count > 1
}
func isParityRunning() -> Bool {
if let pid = self.parityPid {
return kill(pid, 0) == 0
}
return false
}
func killParity() {
if let pid = self.parityPid {
kill(pid, SIGKILL)
}
}
func openUI() {
let parity = Process()
parity.launchPath = self.parityPath()
@@ -61,29 +61,29 @@ class AppDelegate: NSObject, NSApplicationDelegate {
parity.arguments!.append("ui")
parity.launch()
}
func writeConfigFiles() {
let basePath = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first?
.appendingPathComponent(Bundle.main.bundleIdentifier!, isDirectory: true)
if FileManager.default.fileExists(atPath: basePath!.path) {
return
}
do {
let defaultsFileDir = basePath?.appendingPathComponent("chains").appendingPathComponent("ethereum")
let defaultsFile = defaultsFileDir?.appendingPathComponent("user_defaults")
try FileManager.default.createDirectory(atPath: (defaultsFileDir?.path)!, withIntermediateDirectories: true, attributes: nil)
if !FileManager.default.fileExists(atPath: defaultsFile!.path) {
try defaultDefaults.write(to: defaultsFile!, atomically: false, encoding: String.Encoding.utf8)
}
let configFile = basePath?.appendingPathComponent("config.toml")
}
catch {}
}
func autostartEnabled() -> Bool {
return itemReferencesInLoginItems().existingReference != nil
}
@@ -123,7 +123,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
return (nil, nil)
}
func toggleLaunchAtStartup() {
let itemReferences = itemReferencesInLoginItems()
let shouldBeToggled = (itemReferences.existingReference == nil)
@@ -155,7 +155,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func launchParity() {
self.commandLine = CommandLine.arguments.dropFirst().filter({ $0 != "ui"})
let processes = GetBSDProcessList()!
let parityProcess = processes.index(where: {
var name = $0.kp_proc.p_comm
@@ -166,7 +166,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
return str == "parity"
})
if parityProcess == nil {
let parity = Process()
let p = self.parityPath()
@@ -178,7 +178,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.parityPid = processes[parityProcess!].kp_proc.p_pid
}
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
if self.isAlreadyRunning() {
openUI()
@@ -188,12 +188,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.writeConfigFiles()
self.launchParity()
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: {_ in
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: {_ in
if !self.isParityRunning() {
NSApplication.shared().terminate(self)
}
})
let icon = NSImage(named: "statusIcon")
icon?.isTemplate = true // best for dark mode
statusItem.image = icon
@@ -206,19 +206,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
return true
}
@IBAction func quitClicked(_ sender: NSMenuItem) {
self.killParity()
NSApplication.shared().terminate(self)
}
@IBAction func openClicked(_ sender: NSMenuItem) {
self.openUI()
}
@IBAction func startAtLogonClicked(_ sender: NSMenuItem) {
self.toggleLaunchAtStartup()
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,4 +1,4 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
@@ -21,21 +21,21 @@ import Foundation
import Darwin
public func GetBSDProcessList() -> ([kinfo_proc]?) {
var done = false
var result: [kinfo_proc]?
var err: Int32
repeat {
let name = [CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0];
let namePointer = name.withUnsafeBufferPointer { UnsafeMutablePointer<Int32>(mutating: $0.baseAddress) }
var length: Int = 0
err = sysctl(namePointer, u_int(name.count), nil, &length, nil, 0)
if err == -1 {
err = errno
}
if err == 0 {
let count = length / MemoryLayout<kinfo_proc>.stride
result = [kinfo_proc](repeating: kinfo_proc(), count: count)
@@ -54,6 +54,6 @@ public func GetBSDProcessList() -> ([kinfo_proc]?) {
}
}
} while err == 0 && !done
return result
}

View File

@@ -3,8 +3,6 @@ Parity Wallet
Welcome to Parity Wallet, your all-in-one Ethereum node and wallet.
WARNING: This installer is **EXPERIMENTAL**. Use it at your own risk.
If you continue, Parity will be installed as a user service. You will be able to use the Parity Wallet through your browser by using the menu bar icon, following the shortcut in the Launchpad or navigating to http://localhost:8080/ in your browser.
If you continue, Parity will be installed as a user service. You will be able to use the Parity Wallet through your browser by using the menu bar icon, following the shortcut in the Launchpad or navigating to http://localhost:8180/ in your browser.
Parity is distributed under the terms of the GPL.

View File

@@ -9,5 +9,4 @@ fi
PLIST=~/Library/LaunchAgents/io.parity.ethereum.plist
su $SUDO_USER -c "launchctl stop io.parity.ethereum"
su $SUDO_USER -c "launchctl unload $PLIST"
rm -f /usr/local/libexec/parity /usr/local/libexec/uninstall-parity.sh /usr/local/bin/ethstore $PLIST
rm -f /usr/local/libexec/parity /usr/local/libexec/uninstall-parity.sh /usr/local/bin/ethstore /usr/local/bin/ethkey /usr/local/bin/parity-evm $PLIST

View File

@@ -6,17 +6,17 @@
!define SYNC_TERM 0x00100001
!define APPNAME "Parity"
!define COMPANYNAME "Parity"
!define COMPANYNAME "Parity Technologies"
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
!define VERSIONMAJOR 1
!define VERSIONMINOR 8
!define VERSIONBUILD 5
!define VERSIONBUILD 8
!define ARGS ""
!define FIRST_START_ARGS "--mode=passive ui"
!addplugindir .\
!define HELPURL "https://github.com/paritytech/parity/wiki" # "Support Information" link
!define HELPURL "https://paritytech.github.io/wiki/" # "Support Information" link
!define UPDATEURL "https://github.com/paritytech/parity/releases" # "Product Updates" link
!define ABOUTURL "https://github.com/paritytech/parity" # "Publisher" link
!define INSTALLSIZE 26120
@@ -88,14 +88,13 @@ section "install"
!insertmacro TerminateApp
# Files added here should be removed by the uninstaller (see section "uninstall")
file /oname=parity.exe ..\target\release\parity.exe
file /oname=parity.exe ..\target\x86_64-pc-windows-msvc\release\parity.exe
file /oname=parity-evm.exe ..\target\x86_64-pc-windows-msvc\release\parity-evm.exe
file /oname=ethstore.exe ..\target\x86_64-pc-windows-msvc\release\ethstore.exe
file /oname=ethkey.exe ..\target\x86_64-pc-windows-msvc\release\ethkey.exe
file /oname=ptray.exe ..\windows\ptray\x64\Release\ptray.exe
file "logo.ico"
file vc_redist.x64.exe
ExecWait '"$INSTDIR\vc_redist.x64.exe" /passive /norestart'
delete $INSTDIR\vc_redist.x64.exe
# Add any other files for the install directory (license files, app data, etc) here
# Uninstaller - See function un.onInit and section "uninstall" for configuration
@@ -167,6 +166,9 @@ section "uninstall"
# Remove files
delete $INSTDIR\parity.exe
delete $INSTDIR\parity-evm.exe
delete $INSTDIR\ethstore.exe
delete $INSTDIR\ethkey.exe
delete $INSTDIR\ptray.exe
delete $INSTDIR\logo.ico
@@ -187,4 +189,3 @@ section "uninstall"
DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "${APPNAME}"
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${APPNAME}"
sectionEnd

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -591,8 +591,12 @@ fn execute_export(cmd: ExportBlockchain) -> Result<(), String> {
}
let b = client.block(BlockId::Number(i)).ok_or("Error exporting incomplete chain")?.into_inner();
match format {
DataFormat::Binary => { out.write(&b).expect("Couldn't write to stream."); }
DataFormat::Hex => { out.write_fmt(format_args!("{}", b.pretty())).expect("Couldn't write to stream."); }
DataFormat::Binary => {
out.write(&b).map_err(|e| format!("Couldn't write to stream. Cause: {}", e))?;
}
DataFormat::Hex => {
out.write_fmt(format_args!("{}", b.pretty())).map_err(|e| format!("Couldn't write to stream. Cause: {}", e))?;
}
}
}

View File

@@ -17,8 +17,10 @@
use std::cmp::max;
const MIN_BC_CACHE_MB: u32 = 4;
const MIN_DB_CACHE_MB: u32 = 2;
const MIN_DB_CACHE_MB: u32 = 8;
const MIN_BLOCK_QUEUE_SIZE_LIMIT_MB: u32 = 16;
const DEFAULT_DB_CACHE_SIZE: u32 = 128;
const DEFAULT_BC_CACHE_SIZE: u32 = 8;
const DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB: u32 = 40;
const DEFAULT_TRACE_CACHE_SIZE: u32 = 20;
const DEFAULT_STATE_CACHE_SIZE: u32 = 25;
@@ -41,7 +43,11 @@ pub struct CacheConfig {
impl Default for CacheConfig {
fn default() -> Self {
CacheConfig::new(32, 8, DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, DEFAULT_STATE_CACHE_SIZE)
CacheConfig::new(
DEFAULT_DB_CACHE_SIZE,
DEFAULT_BC_CACHE_SIZE,
DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB,
DEFAULT_STATE_CACHE_SIZE)
}
}
@@ -68,14 +74,9 @@ impl CacheConfig {
}
}
/// Size of db cache for blockchain.
pub fn db_blockchain_cache_size(&self) -> u32 {
max(MIN_DB_CACHE_MB, self.db / 4)
}
/// Size of db cache for state.
pub fn db_state_cache_size(&self) -> u32 {
max(MIN_DB_CACHE_MB, self.db * 3 / 4)
/// Size of db cache.
pub fn db_cache_size(&self) -> u32 {
max(MIN_DB_CACHE_MB, self.db)
}
/// Size of block queue size limit
@@ -122,13 +123,16 @@ mod tests {
fn test_cache_config_db_cache_sizes() {
let config = CacheConfig::new_with_total_cache_size(400);
assert_eq!(config.db, 280);
assert_eq!(config.db_blockchain_cache_size(), 70);
assert_eq!(config.db_state_cache_size(), 210);
assert_eq!(config.db_cache_size(), 280);
}
#[test]
fn test_cache_config_default() {
assert_eq!(CacheConfig::default(),
CacheConfig::new(32, 8, super::DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, super::DEFAULT_STATE_CACHE_SIZE));
CacheConfig::new(
super::DEFAULT_DB_CACHE_SIZE,
super::DEFAULT_BC_CACHE_SIZE,
super::DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB,
super::DEFAULT_STATE_CACHE_SIZE));
}
}

View File

@@ -257,12 +257,7 @@ usage! {
ARG arg_mode: (String) = "last", or |c: &Config| otry!(c.parity).mode.clone(),
"--mode=[MODE]",
"Set the operating mode. MODE can be one of:
last - Uses the last-used mode, active if none.
active - Parity continuously syncs the chain.
passive - Parity syncs initially, then sleeps and wakes regularly to resync.
dark - Parity syncs only when the RPC is active.
offline - Parity doesn't sync.",
"Set the operating mode. MODE can be one of: last - Uses the last-used mode, active if none; active - Parity continuously syncs the chain; passive - Parity syncs initially, then sleeps and wakes regularly to resync; dark - Parity syncs only when the RPC is active; offline - Parity doesn't sync.",
ARG arg_mode_timeout: (u64) = 300u64, or |c: &Config| otry!(c.parity).mode_timeout.clone(),
"--mode-timeout=[SECS]",
@@ -274,19 +269,11 @@ usage! {
ARG arg_auto_update: (String) = "critical", or |c: &Config| otry!(c.parity).auto_update.clone(),
"--auto-update=[SET]",
"Set a releases set to automatically update and install.
all - All updates in the our release track.
critical - Only consensus/security updates.
none - No updates will be auto-installed.",
"Set a releases set to automatically update and install. SET can be one of: all - All updates in the our release track; critical - Only consensus/security updates; none - No updates will be auto-installed.",
ARG arg_release_track: (String) = "current", or |c: &Config| otry!(c.parity).release_track.clone(),
"--release-track=[TRACK]",
"Set which release track we should use for updates.
stable - Stable releases.
beta - Beta releases.
nightly - Nightly releases (unstable).
testing - Testing releases (do not use).
current - Whatever track this executable was released on",
"Set which release track we should use for updates. TRACK can be one of: stable - Stable releases; beta - Beta releases; nightly - Nightly releases (unstable); testing - Testing releases (do not use); current - Whatever track this executable was released on.",
ARG arg_chain: (String) = "foundation", or |c: &Config| otry!(c.parity).chain.clone(),
"--chain=[CHAIN]",
@@ -311,8 +298,7 @@ usage! {
["Convenience options"]
FLAG flag_unsafe_expose: (bool) = false, or |c: &Config| otry!(c.misc).unsafe_expose,
"--unsafe-expose",
"All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --{{ws,jsonrpc,ui,ipfs,secret_store,stratum}}-interface=all --*-hosts=all
This option is UNSAFE and should be used with great care!",
"All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --{{ws,jsonrpc,ui,ipfs,secret_store,stratum}}-interface=all --*-hosts=all This option is UNSAFE and should be used with great care!",
ARG arg_config: (String) = "$BASE/config.toml", or |_| None,
"-c, --config=[CONFIG]",
@@ -342,6 +328,7 @@ usage! {
ARG arg_password: (Vec<String>) = Vec::new(), or |c: &Config| otry!(c.account).password.clone(),
"--password=[FILE]...",
"Provide a file containing a password for unlocking an account. Leading and trailing whitespace is trimmed.",
["UI options"]
FLAG flag_force_ui: (bool) = false, or |c: &Config| otry!(c.ui).force.clone(),
"--force-ui",
@@ -458,7 +445,7 @@ usage! {
"--jsonrpc-hosts=[HOSTS]",
"List of allowed Host header values. This option will validate the Host header sent by the browser, it is additional security against some attack vectors. Special options: \"all\", \"none\",.",
ARG arg_jsonrpc_threads: (usize) = 0usize, or |c: &Config| otry!(c.rpc).processing_threads,
ARG arg_jsonrpc_threads: (usize) = 4usize, or |c: &Config| otry!(c.rpc).processing_threads,
"--jsonrpc-threads=[THREADS]",
"Turn on additional processing threads in all RPC servers. Setting this to non-zero value allows parallel cpu-heavy queries execution.",
@@ -493,7 +480,7 @@ usage! {
ARG arg_ws_hosts: (String) = "none", or |c: &Config| otry!(c.websockets).hosts.as_ref().map(|vec| vec.join(",")),
"--ws-hosts=[HOSTS]",
"List of allowed Host header values. This option will validate the Host header sent by the browser, it is additional security against some attack vectors. Special options: \"all\", \"none\",.",
"List of allowed Host header values. This option will validate the Host header sent by the browser, it is additional security against some attack vectors. Special options: \"all\", \"none\".",
["API and console options IPC"]
FLAG flag_no_ipc: (bool) = false, or |c: &Config| otry!(c.ipc).disable.clone(),
@@ -573,7 +560,7 @@ usage! {
ARG arg_secretstore_path: (String) = "$BASE/secretstore", or |c: &Config| otry!(c.secretstore).path.clone(),
"--secretstore-path=[PATH]",
"Specify directory where Secret Store should save its data..",
"Specify directory where Secret Store should save its data.",
ARG arg_secretstore_secret: (Option<String>) = None, or |c: &Config| otry!(c.secretstore).self_secret.clone(),
"--secretstore-secret=[SECRET]",
@@ -658,7 +645,7 @@ usage! {
ARG arg_tx_queue_gas: (String) = "off", or |c: &Config| otry!(c.mining).tx_queue_gas.clone(),
"--tx-queue-gas=[LIMIT]",
"Maximum amount of total gas for external transactions in the queue. LIMIT can be either an amount of gas or 'auto' or 'off'. 'auto' sets the limit to be 20x the current block gas limit..",
"Maximum amount of total gas for external transactions in the queue. LIMIT can be either an amount of gas or 'auto' or 'off'. 'auto' sets the limit to be 20x the current block gas limit.",
ARG arg_tx_queue_strategy: (String) = "gas_price", or |c: &Config| otry!(c.mining).tx_queue_strategy.clone(),
"--tx-queue-strategy=[S]",
@@ -684,6 +671,10 @@ usage! {
"--min-gas-price=[STRING]",
"Minimum amount of Wei per GAS to be paid for a transaction to be accepted for mining. Overrides --basic-tx-usd.",
ARG arg_gas_price_percentile: (usize) = 50usize, or |c: &Config| otry!(c.mining).gas_price_percentile,
"--gas-price-percentile=[PCT]",
"Set PCT percentile gas price value from last 100 blocks as default gas price when sending transactions.",
ARG arg_author: (Option<String>) = None, or |c: &Config| otry!(c.mining).author.clone(),
"--author=[ADDRESS]",
"Specify the block author (aka \"coinbase\") address for sending block rewards from sealed blocks. NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION.", // Sealing/Mining Option
@@ -761,13 +752,13 @@ usage! {
ARG arg_pruning_history: (u64) = 64u64, or |c: &Config| otry!(c.footprint).pruning_history.clone(),
"--pruning-history=[NUM]",
"Set a minimum number of recent states to keep when pruning is active..",
"Set a minimum number of recent states to keep when pruning is active.",
ARG arg_pruning_memory: (usize) = 32usize, or |c: &Config| otry!(c.footprint).pruning_memory.clone(),
"--pruning-memory=[MB]",
"The ideal amount of memory in megabytes to use to store recent states. As many states as possible will be kept within this limit, and at least --pruning-history states will always be kept.",
ARG arg_cache_size_db: (u32) = 32u32, or |c: &Config| otry!(c.footprint).cache_size_db.clone(),
ARG arg_cache_size_db: (u32) = 128u32, or |c: &Config| otry!(c.footprint).cache_size_db.clone(),
"--cache-size-db=[MB]",
"Override database cache size.",
@@ -982,6 +973,7 @@ struct Config {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Operating {
mode: Option<String>,
mode_timeout: Option<u64>,
@@ -1001,6 +993,7 @@ struct Operating {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Account {
unlock: Option<Vec<String>>,
password: Option<Vec<String>>,
@@ -1010,6 +1003,7 @@ struct Account {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Ui {
force: Option<bool>,
disable: Option<bool>,
@@ -1020,6 +1014,7 @@ struct Ui {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Network {
warp: Option<bool>,
port: Option<u16>,
@@ -1039,6 +1034,7 @@ struct Network {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Rpc {
disable: Option<bool>,
port: Option<u16>,
@@ -1051,6 +1047,7 @@ struct Rpc {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Ws {
disable: Option<bool>,
port: Option<u16>,
@@ -1061,6 +1058,7 @@ struct Ws {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Ipc {
disable: Option<bool>,
path: Option<String>,
@@ -1068,6 +1066,7 @@ struct Ipc {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Dapps {
disable: Option<bool>,
port: Option<u16>,
@@ -1080,6 +1079,7 @@ struct Dapps {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct SecretStore {
disable: Option<bool>,
disable_http: Option<bool>,
@@ -1095,6 +1095,7 @@ struct SecretStore {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Ipfs {
enable: Option<bool>,
port: Option<u16>,
@@ -1104,6 +1105,7 @@ struct Ipfs {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Mining {
author: Option<String>,
engine_signer: Option<String>,
@@ -1117,6 +1119,7 @@ struct Mining {
tx_time_limit: Option<u64>,
relay_set: Option<String>,
min_gas_price: Option<u64>,
gas_price_percentile: Option<usize>,
usd_per_tx: Option<String>,
usd_per_eth: Option<String>,
price_update_period: Option<String>,
@@ -1135,6 +1138,7 @@ struct Mining {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Stratum {
interface: Option<String>,
port: Option<u16>,
@@ -1142,6 +1146,7 @@ struct Stratum {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Footprint {
tracing: Option<String>,
pruning: Option<String>,
@@ -1160,16 +1165,19 @@ struct Footprint {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Snapshots {
disable_periodic: Option<bool>,
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct VM {
jit: Option<bool>,
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Misc {
ntp_servers: Option<Vec<String>>,
logging: Option<String>,
@@ -1180,6 +1188,7 @@ struct Misc {
}
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Whisper {
enabled: Option<bool>,
pool_size: Option<usize>,
@@ -1284,12 +1293,15 @@ mod tests {
let args = Args::parse(&["parity", "--secretstore-nodes", "abc@127.0.0.1:3333,cde@10.10.10.10:4444"]).unwrap();
assert_eq!(args.arg_secretstore_nodes, "abc@127.0.0.1:3333,cde@10.10.10.10:4444");
// Arguments with a single value shouldn't accept multiple values
let args = Args::parse(&["parity", "--auto-update", "critical", "all"]);
assert!(args.is_err());
let args = Args::parse(&["parity", "--password", "~/.safe/1", "~/.safe/2"]).unwrap();
let args = Args::parse(&["parity", "--password", "~/.safe/1", "--password", "~/.safe/2", "--ui-port", "8123", "ui"]).unwrap();
assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]);
assert_eq!(args.arg_ui_port, 8123);
assert_eq!(args.cmd_ui, true);
let args = Args::parse(&["parity", "--password", "~/.safe/1,~/.safe/2", "--ui-port", "8123", "ui"]).unwrap();
assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]);
assert_eq!(args.arg_ui_port, 8123);
assert_eq!(args.cmd_ui, true);
}
#[test]
@@ -1461,7 +1473,7 @@ mod tests {
arg_jsonrpc_apis: "web3,eth,net,parity,traces,rpc,secretstore".into(),
arg_jsonrpc_hosts: "none".into(),
arg_jsonrpc_server_threads: None,
arg_jsonrpc_threads: 0,
arg_jsonrpc_threads: 4,
// WS
flag_no_ws: false,
@@ -1512,6 +1524,7 @@ mod tests {
arg_tx_time_limit: Some(100u64),
arg_relay_set: "cheap".into(),
arg_min_gas_price: Some(0u64),
arg_gas_price_percentile: 50usize,
arg_usd_per_tx: "0.0025".into(),
arg_usd_per_eth: "auto".into(),
arg_price_update_period: "hourly".into(),
@@ -1624,11 +1637,17 @@ mod tests {
let config1 = Args::parse_config(include_str!("./tests/config.invalid1.toml"));
let config2 = Args::parse_config(include_str!("./tests/config.invalid2.toml"));
let config3 = Args::parse_config(include_str!("./tests/config.invalid3.toml"));
let config4 = Args::parse_config(include_str!("./tests/config.invalid4.toml"));
match (config1, config2, config3) {
(Err(ArgsError::Decode(_)), Err(ArgsError::Decode(_)), Err(ArgsError::Decode(_))) => {},
(a, b, c) => {
assert!(false, "Got invalid error types: {:?}, {:?}, {:?}", a, b, c);
match (config1, config2, config3, config4) {
(
Err(ArgsError::Decode(_)),
Err(ArgsError::Decode(_)),
Err(ArgsError::Decode(_)),
Err(ArgsError::Decode(_)),
) => {},
(a, b, c, d) => {
assert!(false, "Got invalid error types: {:?}, {:?}, {:?}, {:?}", a, b, c, d);
}
}
}
@@ -1751,6 +1770,7 @@ mod tests {
work_queue_size: None,
relay_set: None,
min_gas_price: None,
gas_price_percentile: None,
usd_per_tx: None,
usd_per_eth: None,
price_update_period: Some("hourly".into()),
@@ -1776,7 +1796,7 @@ mod tests {
pruning_memory: None,
fast_and_loose: None,
cache_size: None,
cache_size_db: Some(128),
cache_size_db: Some(256),
cache_size_blocks: Some(16),
cache_size_queue: Some(100),
cache_size_state: Some(25),

View File

@@ -0,0 +1,2 @@
[account]
invalid = 5

View File

@@ -63,7 +63,7 @@ tx_queue_gas = "off"
tracing = "on"
pruning = "fast"
pruning_history = 64
cache_size_db = 128
cache_size_db = 256
cache_size_blocks = 16
cache_size_queue = 100
cache_size_state = 25

View File

@@ -150,14 +150,20 @@ macro_rules! usage {
}
) => {
use toml;
use std::{fs, io, process};
use std::{fs, io, process, cmp};
use std::io::{Read, Write};
use util::version;
use clap::{Arg, App, SubCommand, AppSettings, ArgMatches as ClapArgMatches, Error as ClapError, ErrorKind as ClapErrorKind};
use clap::{Arg, App, SubCommand, AppSettings, ArgSettings, Error as ClapError, ErrorKind as ClapErrorKind};
use helpers::replace_home;
use std::ffi::OsStr;
use std::collections::HashMap;
extern crate textwrap;
extern crate term_size;
use self::textwrap::{Wrapper};
const MAX_TERM_WIDTH: usize = 120;
#[cfg(test)]
use regex::Regex;
@@ -365,11 +371,23 @@ macro_rules! usage {
#[allow(unused_mut)] // subc_subc_exist may be assigned true by the macro
#[allow(unused_assignments)] // Rust issue #22630
pub fn print_help() -> String {
const TAB: &str = " ";
const TAB_TAB: &str = " ";
let term_width = match term_size::dimensions() {
None => MAX_TERM_WIDTH,
Some((w, _)) => {
cmp::min(w, MAX_TERM_WIDTH)
}
};
let mut help : String = include_str!("./usage_header.txt").to_owned();
help.push_str("\n\n");
help.push_str("\n");
// Subcommands
let mut subcommands_wrapper = Wrapper::new(term_width).subsequent_indent(TAB);
help.push_str("parity [options]\n");
$(
{
@@ -386,11 +404,14 @@ macro_rules! usage {
)*
];
if subc_subc_usages.is_empty() {
help.push_str(&format!("parity [options] {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..])));
} else {
help.push_str(&format!("parity [options] {} {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]), subc_subc_usages.join(" ")));
}
help.push_str(&subcommands_wrapper.fill(
format!(
"parity [options] {} {} {}\n",
underscore_to_hyphen!(&stringify!($subc)[4..]),
underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]),
subc_subc_usages.join(" ")
).as_ref())
);
)*
// Print the subcommand on its own only if it has no subsubcommands
@@ -404,22 +425,30 @@ macro_rules! usage {
)*
];
if subc_usages.is_empty() {
help.push_str(&format!("parity [options] {}\n", underscore_to_hyphen!(&stringify!($subc)[4..])));
} else {
help.push_str(&format!("parity [options] {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), subc_usages.join(" ")));
}
help.push_str(&subcommands_wrapper.fill(
format!(
"parity [options] {} {}\n",
underscore_to_hyphen!(&stringify!($subc)[4..]),
subc_usages.join(" ")
).as_ref())
);
}
}
)*
help.push_str("\n");
// Arguments and flags
let args_wrapper = Wrapper::new(term_width).initial_indent(TAB_TAB).subsequent_indent(TAB_TAB);
$(
help.push_str("\n");
help.push_str($group_name); help.push_str(":\n");
$(
help.push_str(&format!("\t{}\n\t\t{}\n", $flag_usage, $flag_help));
help.push_str(&format!("{}{}\n{}\n",
TAB, $flag_usage,
args_wrapper.fill($flag_help)
));
help.push_str("\n");
)*
$(
@@ -429,10 +458,24 @@ macro_rules! usage {
if_option_vec!(
$($arg_type_tt)+,
THEN {
help.push_str(&format!("\t{}\n\t\t{} (default: {:?})\n", $arg_usage, $arg_help, {let x : inner_option_type!($($arg_type_tt)+)> = $arg_default; x}))
help.push_str(&format!("{}{}\n{}\n",
TAB, $arg_usage,
args_wrapper.fill(format!(
"{} (default: {:?})",
$arg_help,
{let x : inner_option_type!($($arg_type_tt)+)> = $arg_default; x}
).as_ref())
))
}
ELSE {
help.push_str(&format!("\t{}\n\t\t{}{}\n", $arg_usage, $arg_help, $arg_default.map(|x: inner_option_type!($($arg_type_tt)+)| format!(" (default: {})",x)).unwrap_or("".to_owned())))
help.push_str(&format!("{}{}\n{}\n",
TAB, $arg_usage,
args_wrapper.fill(format!(
"{}{}",
$arg_help,
$arg_default.map(|x: inner_option_type!($($arg_type_tt)+)| format!(" (default: {})",x)).unwrap_or("".to_owned())
).as_ref())
))
}
)
}
@@ -440,14 +483,27 @@ macro_rules! usage {
if_vec!(
$($arg_type_tt)+,
THEN {
help.push_str(&format!("\t{}\n\t\t{} (default: {:?})\n", $arg_usage, $arg_help, {let x : $($arg_type_tt)+ = $arg_default; x}))
help.push_str(&format!("{}{}\n{}\n", TAB, $arg_usage,
args_wrapper.fill(format!(
"{} (default: {:?})",
$arg_help,
{let x : $($arg_type_tt)+ = $arg_default; x}
).as_ref())
))
}
ELSE {
help.push_str(&format!("\t{}\n\t\t{} (default: {})\n", $arg_usage, $arg_help, $arg_default))
help.push_str(&format!("{}{}\n{}\n", TAB, $arg_usage,
args_wrapper.fill(format!(
"{} (default: {})",
$arg_help,
$arg_default
).as_ref())
))
}
)
}
);
help.push_str("\n");
)*
)*
@@ -503,36 +559,6 @@ macro_rules! usage {
args
}
pub fn hydrate_with_globals(self: &mut Self, matches: &ClapArgMatches) -> Result<(), ClapError> {
$(
$(
self.$flag = self.$flag || matches.is_present(stringify!($flag));
)*
$(
if let some @ Some(_) = return_if_parse_error!(if_option!(
$($arg_type_tt)+,
THEN {
if_option_vec!(
$($arg_type_tt)+,
THEN { values_t!(matches, stringify!($arg), inner_option_vec_type!($($arg_type_tt)+)) }
ELSE { value_t!(matches, stringify!($arg), inner_option_type!($($arg_type_tt)+)) }
)
}
ELSE {
if_vec!(
$($arg_type_tt)+,
THEN { values_t!(matches, stringify!($arg), inner_vec_type!($($arg_type_tt)+)) }
ELSE { value_t!(matches, stringify!($arg), $($arg_type_tt)+) }
)
}
)) {
self.$arg = some;
}
)*
)*
Ok(())
}
#[allow(unused_variables)] // the submatches of arg-less subcommands aren't used
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, ClapError> {
@@ -582,21 +608,31 @@ macro_rules! usage {
let matches = App::new("Parity")
.global_setting(AppSettings::VersionlessSubcommands)
.global_setting(AppSettings::DisableHelpSubcommand)
.max_term_width(MAX_TERM_WIDTH)
.help(Args::print_help().as_ref())
.args(&usages.iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
.args(&usages.iter().map(|u| {
let mut arg = Arg::from_usage(u)
.allow_hyphen_values(true) // Allow for example --allow-ips -10.0.0.0/8
.global(true) // Argument doesn't have to come before the first subcommand
.hidden(true); // Hide global arguments from the (subcommand) help messages generated by Clap
if arg.is_set(ArgSettings::Multiple) {
arg = arg.require_delimiter(true); // Multiple values can only be separated by commas, not spaces (#7428)
}
arg
}).collect::<Vec<Arg>>())
$(
.subcommand(
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc)[4..]))
.about($subc_help)
.args(&subc_usages.get(stringify!($subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
.args(&usages.iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>()) // accept global arguments at this position
$(
.setting(AppSettings::SubcommandRequired) // prevent from running `parity account`
.subcommand(
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]))
.about($subc_subc_help)
.args(&subc_usages.get(stringify!($subc_subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
.args(&usages.iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>()) // accept global arguments at this position
)
)*
)
@@ -605,15 +641,39 @@ macro_rules! usage {
let mut raw_args : RawArgs = Default::default();
raw_args.hydrate_with_globals(&matches)?;
// Globals
$(
$(
raw_args.$flag = raw_args.$flag || matches.is_present(stringify!($flag));
)*
$(
if let some @ Some(_) = return_if_parse_error!(if_option!(
$($arg_type_tt)+,
THEN {
if_option_vec!(
$($arg_type_tt)+,
THEN { values_t!(matches, stringify!($arg), inner_option_vec_type!($($arg_type_tt)+)) }
ELSE { value_t!(matches, stringify!($arg), inner_option_type!($($arg_type_tt)+)) }
)
}
ELSE {
if_vec!(
$($arg_type_tt)+,
THEN { values_t!(matches, stringify!($arg), inner_vec_type!($($arg_type_tt)+)) }
ELSE { value_t!(matches, stringify!($arg), $($arg_type_tt)+) }
)
}
)) {
raw_args.$arg = some;
}
)*
)*
// Subcommands
$(
if let Some(submatches) = matches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc)[4..])) {
raw_args.$subc = true;
// Globals
raw_args.hydrate_with_globals(&submatches)?;
// Subcommand flags
$(
raw_args.$subc_flag = submatches.is_present(&stringify!($subc_flag));
@@ -643,8 +703,6 @@ macro_rules! usage {
if let Some(subsubmatches) = submatches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..])) {
raw_args.$subc_subc = true;
// Globals
raw_args.hydrate_with_globals(&subsubmatches)?;
// Sub-subcommand flags
$(
raw_args.$subc_subc_flag = subsubmatches.is_present(&stringify!($subc_subc_flag));

View File

@@ -1,3 +1,3 @@
Parity. Ethereum Client.
By Wood/Paronyan/Kotewicz/Drwięga/Volf et al.
Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd
Copyright 2015, 2016, 2017, 2018 Parity Technologies (UK) Ltd

View File

@@ -1,6 +1,6 @@
Parity
version {}
Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd
Copyright 2015, 2016, 2017, 2018 Parity Technologies (UK) Ltd
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

View File

@@ -337,6 +337,7 @@ impl Configuration {
daemon: daemon,
logger_config: logger_config.clone(),
miner_options: self.miner_options()?,
gas_price_percentile: self.args.arg_gas_price_percentile,
ntp_servers: self.ntp_servers(),
ws_conf: ws_conf,
http_conf: http_conf,
@@ -1327,6 +1328,7 @@ mod tests {
daemon: None,
logger_config: Default::default(),
miner_options: Default::default(),
gas_price_percentile: 50,
ntp_servers: vec![
"0.parity.pool.ntp.org:123".into(),
"1.parity.pool.ntp.org:123".into(),

View File

@@ -21,7 +21,7 @@ use std::fs::File;
use bigint::prelude::U256;
use bigint::hash::clean_0x;
use util::Address;
use kvdb::CompactionProfile;
use kvdb_rocksdb::CompactionProfile;
use util::journaldb::Algorithm;
use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType};
use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy};
@@ -239,10 +239,8 @@ pub fn to_client_config(
client_config.blockchain.max_cache_size = cache_config.blockchain() as usize * mb;
// in bytes
client_config.blockchain.pref_cache_size = cache_config.blockchain() as usize * 3 / 4 * mb;
// db blockchain cache size, in megabytes
client_config.blockchain.db_cache_size = Some(cache_config.db_blockchain_cache_size() as usize);
// db state cache size, in megabytes
client_config.db_cache_size = Some(cache_config.db_state_cache_size() as usize);
// db cache size, in megabytes
client_config.db_cache_size = Some(cache_config.db_cache_size() as usize);
// db queue cache size, in bytes
client_config.queue.max_mem_use = cache_config.queue() as usize * mb;
// in bytes

View File

@@ -62,7 +62,7 @@ extern crate ethcore_bigint as bigint;
extern crate ethcore_bytes as bytes;
extern crate ethcore_network as network;
extern crate migration as migr;
extern crate kvdb;
extern crate kvdb_rocksdb;
extern crate ethkey;
extern crate ethsync;
extern crate node_health;

View File

@@ -22,7 +22,7 @@ use std::fmt::{Display, Formatter, Error as FmtError};
use std::sync::Arc;
use util::journaldb::Algorithm;
use migr::{Manager as MigrationManager, Config as MigrationConfig, Error as MigrationError, Migration};
use kvdb::{CompactionProfile, Database, DatabaseConfig};
use kvdb_rocksdb::{CompactionProfile, Database, DatabaseConfig};
use ethcore::migrations;
use ethcore::db;
use ethcore::migrations::Extract;
@@ -167,7 +167,7 @@ fn consolidate_database(
let config = default_migration_settings(compaction_profile);
let mut db_config = DatabaseConfig {
max_open_files: 64,
cache_sizes: Default::default(),
memory_budget: None,
compaction: config.compaction_profile,
columns: None,
wal: true,
@@ -283,7 +283,7 @@ mod legacy {
use std::path::{Path, PathBuf};
use util::journaldb::Algorithm;
use migr::{Manager as MigrationManager};
use kvdb::CompactionProfile;
use kvdb_rocksdb::CompactionProfile;
use ethcore::migrations;
/// Blocks database path.

View File

@@ -62,7 +62,7 @@ impl Default for HttpConfiguration {
cors: Some(vec![]),
hosts: Some(vec![]),
server_threads: 1,
processing_threads: 0,
processing_threads: 4,
}
}
}

View File

@@ -15,8 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::cmp::PartialEq;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::collections::{BTreeMap, HashSet};
use std::str::FromStr;
use std::sync::{Arc, Weak};
@@ -227,6 +226,7 @@ pub struct FullDependencies {
pub fetch: FetchClient,
pub remote: parity_reactor::Remote,
pub whisper_rpc: Option<::whisper::RpcFactory>,
pub gas_price_percentile: usize,
}
impl FullDependencies {
@@ -239,10 +239,10 @@ impl FullDependencies {
use parity_rpc::v1::*;
macro_rules! add_signing_methods {
($namespace:ident, $handler:expr, $deps:expr) => {
($namespace:ident, $handler:expr, $deps:expr, $nonces:expr) => {
{
let deps = &$deps;
let dispatcher = FullDispatcher::new(deps.client.clone(), deps.miner.clone());
let dispatcher = FullDispatcher::new(deps.client.clone(), deps.miner.clone(), $nonces, deps.gas_price_percentile);
if deps.signer_service.is_enabled() {
$handler.extend_with($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, dispatcher, &deps.secret_store)))
} else {
@@ -252,7 +252,13 @@ impl FullDependencies {
}
}
let dispatcher = FullDispatcher::new(self.client.clone(), self.miner.clone());
let nonces = Arc::new(Mutex::new(dispatch::Reservations::with_pool(self.fetch.pool())));
let dispatcher = FullDispatcher::new(
self.client.clone(),
self.miner.clone(),
nonces.clone(),
self.gas_price_percentile,
);
for api in apis {
match *api {
Api::Web3 => {
@@ -273,6 +279,7 @@ impl FullDependencies {
pending_nonce_from_queue: self.geth_compatibility,
allow_pending_receipt_query: !self.geth_compatibility,
send_block_number_in_get_work: !self.geth_compatibility,
gas_price_percentile: self.gas_price_percentile,
}
);
handler.extend_with(client.to_delegate());
@@ -281,7 +288,7 @@ impl FullDependencies {
let filter_client = EthFilterClient::new(self.client.clone(), self.miner.clone());
handler.extend_with(filter_client.to_delegate());
add_signing_methods!(EthSigning, handler, self);
add_signing_methods!(EthSigning, handler, self, nonces.clone());
}
},
Api::EthPubSub => {
@@ -318,7 +325,7 @@ impl FullDependencies {
).to_delegate());
if !for_generic_pubsub {
add_signing_methods!(ParitySigning, handler, self);
add_signing_methods!(ParitySigning, handler, self, nonces.clone());
}
},
Api::ParityPubSub => {
@@ -418,6 +425,7 @@ pub struct LightDependencies<T> {
pub geth_compatibility: bool,
pub remote: parity_reactor::Remote,
pub whisper_rpc: Option<::whisper::RpcFactory>,
pub gas_price_percentile: usize,
}
impl<C: LightChainClient + 'static> LightDependencies<C> {
@@ -435,6 +443,8 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.on_demand.clone(),
self.cache.clone(),
self.transaction_queue.clone(),
Arc::new(Mutex::new(dispatch::Reservations::with_pool(self.fetch.pool()))),
self.gas_price_percentile,
);
macro_rules! add_signing_methods {
@@ -472,6 +482,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.transaction_queue.clone(),
self.secret_store.clone(),
self.cache.clone(),
self.gas_price_percentile,
);
handler.extend_with(Eth::to_delegate(client.clone()));
@@ -487,6 +498,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.sync.clone(),
self.cache.clone(),
self.remote.clone(),
self.gas_price_percentile,
);
self.client.add_listener(
Arc::downgrade(&client.handler()) as Weak<::light::client::LightChainNotify>
@@ -516,6 +528,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
signer,
self.dapps_address.clone(),
self.ws_address.clone(),
self.gas_price_percentile,
).to_delegate());
if !for_generic_pubsub {

View File

@@ -16,6 +16,8 @@
use std::fmt;
use std::sync::{Arc, Weak};
use std::time::{Duration, Instant};
use std::thread;
use std::net::{TcpListener};
use ctrlc::CtrlC;
@@ -87,6 +89,7 @@ pub struct RunCmd {
pub daemon: Option<String>,
pub logger_config: LogConfig,
pub miner_options: MinerOptions,
pub gas_price_percentile: usize,
pub ntp_servers: Vec<String>,
pub ws_conf: rpc::WsConfiguration,
pub http_conf: rpc::HttpConfiguration,
@@ -170,8 +173,10 @@ impl ::local_store::NodeInfo for FullNodeInfo {
}
}
type LightClient = ::light::client::Client<::light_helpers::EpochFetch>;
// helper for light execution.
fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<(bool, Option<String>), String> {
fn execute_light_impl(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<((bool, Option<String>), Weak<LightClient>), String> {
use light::client as light_client;
use ethsync::{LightSyncParams, LightSync, ManageNetwork};
use parking_lot::{Mutex, RwLock};
@@ -236,8 +241,9 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
let service = light_client::Service::start(config, &spec, fetch, &db_dirs.client_path(algorithm), cache.clone())
.map_err(|e| format!("Error starting light client: {}", e))?;
let client = service.client();
let txq = Arc::new(RwLock::new(::light::transaction_queue::TransactionQueue::default()));
let provider = ::light::provider::LightProvider::new(service.client().clone(), txq.clone());
let provider = ::light::provider::LightProvider::new(client.clone(), txq.clone());
// start network.
// set up bootnodes
@@ -274,7 +280,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
// queue cull service.
let queue_cull = Arc::new(::light_helpers::QueueCull {
client: service.client().clone(),
client: client.clone(),
sync: light_sync.clone(),
on_demand: on_demand.clone(),
txq: txq.clone(),
@@ -298,7 +304,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config));
let (node_health, dapps_deps) = {
let contract_client = Arc::new(::dapps::LightRegistrar {
client: service.client().clone(),
client: client.clone(),
sync: light_sync.clone(),
on_demand: on_demand.clone(),
});
@@ -341,7 +347,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
let dapps_service = dapps::service(&dapps_middleware);
let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
signer_service: signer_service,
client: service.client().clone(),
client: client.clone(),
sync: light_sync.clone(),
net: light_sync.clone(),
health: node_health,
@@ -358,6 +364,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
geth_compatibility: cmd.geth_compatibility,
remote: event_loop.remote(),
whisper_rpc: whisper_factory,
gas_price_percentile: cmd.gas_price_percentile,
});
let dependencies = rpc::Dependencies {
@@ -380,7 +387,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
// the informant
let informant = Arc::new(Informant::new(
LightNodeInformantData {
client: service.client().clone(),
client: client.clone(),
sync: light_sync.clone(),
cache: cache,
},
@@ -395,26 +402,13 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
let res = wait_for_exit(None, None, can_restart);
informant.shutdown();
Ok(res)
// Create a weak reference to the client so that we can wait on shutdown until it is dropped
let weak_client = Arc::downgrade(&client);
Ok((res, weak_client))
}
pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<(bool, Option<String>), String> {
if cmd.ui && cmd.dapps_conf.enabled {
// Check if Parity is already running
let addr = format!("{}:{}", cmd.ui_conf.interface, cmd.ui_conf.port);
if !TcpListener::bind(&addr as &str).is_ok() {
return open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config).map(|_| (false, None));
}
}
// increase max number of open files
raise_fd_limit();
// run as light client.
if cmd.light {
return execute_light(cmd, can_restart, logger);
}
pub fn execute_impl(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<((bool, Option<String>), Weak<Client>), String> {
// load spec
let spec = cmd.spec.spec(&cmd.dirs.cache)?;
@@ -765,6 +759,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
fetch: fetch.clone(),
remote: event_loop.remote(),
whisper_rpc: whisper_factory,
gas_price_percentile: cmd.gas_price_percentile,
});
let dependencies = rpc::Dependencies {
@@ -855,6 +850,9 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
open_dapp(&cmd.dapps_conf, &cmd.http_conf, &dapp)?;
}
// Create a weak reference to the client so that we can wait on shutdown until it is dropped
let weak_client = Arc::downgrade(&client);
// Handle exit
let restart = wait_for_exit(Some(updater), Some(client), can_restart);
@@ -872,7 +870,33 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
// terminated gracefully
drop(hypervisor);
Ok(restart)
Ok((restart, weak_client))
}
pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<(bool, Option<String>), String> {
if cmd.ui && cmd.dapps_conf.enabled {
// Check if Parity is already running
let addr = format!("{}:{}", cmd.ui_conf.interface, cmd.ui_conf.port);
if !TcpListener::bind(&addr as &str).is_ok() {
return open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config).map(|_| (false, None));
}
}
// increase max number of open files
raise_fd_limit();
fn wait<T>(res: Result<((bool, Option<String>), Weak<T>), String>) -> Result<(bool, Option<String>), String> {
res.map(|(restart, weak_client)| {
wait_for_drop(weak_client);
restart
})
}
if cmd.light {
wait(execute_light_impl(cmd, can_restart, logger))
} else {
wait(execute_impl(cmd, can_restart, logger))
}
}
#[cfg(not(windows))]
@@ -999,3 +1023,27 @@ fn wait_for_exit(
let _ = exit.1.wait(&mut l);
l.clone()
}
fn wait_for_drop<T>(w: Weak<T>) {
let sleep_duration = Duration::from_secs(1);
let warn_timeout = Duration::from_secs(60);
let max_timeout = Duration::from_secs(300);
let instant = Instant::now();
let mut warned = false;
while instant.elapsed() < max_timeout {
if w.upgrade().is_none() {
return;
}
if !warned && instant.elapsed() > warn_timeout {
warned = true;
warn!("Shutdown is taking longer than expected.");
}
thread::sleep(sleep_duration);
}
warn!("Shutdown timeout reached, exiting uncleanly.");
}

View File

@@ -51,7 +51,7 @@ impl PoolHandle for NetPoolHandle {
fn relay(&self, message: Message) -> bool {
let mut res = false;
let mut message = Some(message);
self.net.with_proto_context(whisper_net::PROTOCOL_ID, &mut move |ctx| {
self.net.with_proto_context(whisper_net::PROTOCOL_ID, &mut |ctx| {
if let Some(message) = message.take() {
res = self.handle.post_message(message, ctx);
}

View File

@@ -86,7 +86,7 @@ impl<F> cmp::PartialEq for Client<F> {
impl<F: Fetch> Client<F> {
/// Creates a new instance of the `Client` given a `fetch::Client`.
pub fn new(fetch: F) -> Client<F> {
let api_endpoint = "http://api.etherscan.io/api?module=stats&action=ethprice".to_owned();
let api_endpoint = "https://api.etherscan.io/api?module=stats&action=ethprice".to_owned();
Client { api_endpoint, fetch }
}
@@ -144,7 +144,7 @@ mod test {
type Result = FutureResult<fetch::Response, fetch::Error>;
fn new() -> Result<Self, fetch::Error> where Self: Sized { Ok(FakeFetch(None, Default::default())) }
fn fetch_with_abort(&self, url: &str, _abort: fetch::Abort) -> Self::Result {
assert_eq!(url, "http://api.etherscan.io/api?module=stats&action=ethprice");
assert_eq!(url, "https://api.etherscan.io/api?module=stats&action=ethprice");
let mut val = self.1.lock();
*val = *val + 1;
if let Some(ref response) = self.0 {

View File

@@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ansi_term = "0.9"
cid = "0.2"
futures = "0.1"
futures-cpupool = "0.1"
log = "0.3"
multihash ="0.6"
@@ -57,7 +58,6 @@ rlp = { path = "../util/rlp" }
stats = { path = "../util/stats" }
vm = { path = "../ethcore/vm" }
hash = { path = "../util/hash" }
kvdb = { path = "../util/kvdb" }
hardware-wallet = { path = "../hw" }
clippy = { version = "0.0.103", optional = true}
@@ -66,6 +66,7 @@ pretty_assertions = "0.1"
[dev-dependencies]
macros = { path = "../util/macros" }
ethcore-network = { path = "../util/network" }
kvdb-memorydb = { path = "../util/kvdb-memorydb" }
[features]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev"]

View File

@@ -65,8 +65,9 @@ extern crate rlp;
extern crate stats;
extern crate hash;
extern crate hardware_wallet;
extern crate kvdb;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate log;
#[macro_use]
@@ -85,6 +86,9 @@ extern crate pretty_assertions;
#[macro_use]
extern crate macros;
#[cfg(test)]
extern crate kvdb_memorydb;
pub extern crate jsonrpc_ws_server as ws;
mod authcodes;

View File

@@ -43,9 +43,9 @@ use ethcore::account_provider::AccountProvider;
use crypto::DEFAULT_MAC;
use jsonrpc_core::{BoxFuture, Error};
use jsonrpc_core::futures::{future, Future};
use jsonrpc_core::futures::{future, Future, Poll, Async};
use jsonrpc_core::futures::future::Either;
use v1::helpers::{errors, TransactionRequest, FilledTransactionRequest, ConfirmationPayload};
use v1::helpers::{errors, nonce, TransactionRequest, FilledTransactionRequest, ConfirmationPayload};
use v1::types::{
H256 as RpcH256, H520 as RpcH520, Bytes as RpcBytes,
RichRawTransaction as RpcRichRawTransaction,
@@ -55,6 +55,8 @@ use v1::types::{
DecryptRequest as RpcDecryptRequest,
};
pub use self::nonce::Reservations;
/// Has the capability to dispatch, sign, and decrypt.
///
/// Requires a clone implementation, with the implication that it be cheap;
@@ -75,7 +77,8 @@ pub trait Dispatcher: Send + Sync + Clone {
fn enrich(&self, SignedTransaction) -> RpcRichRawTransaction;
/// "Dispatch" a local transaction.
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error>;
fn dispatch_transaction(&self, signed_transaction: PendingTransaction)
-> Result<H256, Error>;
}
/// A dispatcher which uses references to a client and miner in order to sign
@@ -84,14 +87,23 @@ pub trait Dispatcher: Send + Sync + Clone {
pub struct FullDispatcher<C, M> {
client: Arc<C>,
miner: Arc<M>,
nonces: Arc<Mutex<nonce::Reservations>>,
gas_price_percentile: usize,
}
impl<C, M> FullDispatcher<C, M> {
/// Create a `FullDispatcher` from Arc references to a client and miner.
pub fn new(client: Arc<C>, miner: Arc<M>) -> Self {
pub fn new(
client: Arc<C>,
miner: Arc<M>,
nonces: Arc<Mutex<nonce::Reservations>>,
gas_price_percentile: usize,
) -> Self {
FullDispatcher {
client,
miner,
nonces,
gas_price_percentile,
}
}
}
@@ -101,15 +113,25 @@ impl<C, M> Clone for FullDispatcher<C, M> {
FullDispatcher {
client: self.client.clone(),
miner: self.miner.clone(),
nonces: self.nonces.clone(),
gas_price_percentile: self.gas_price_percentile,
}
}
}
impl<C: MiningBlockChainClient, M: MinerService> FullDispatcher<C, M> {
fn fill_nonce(nonce: Option<U256>, from: &Address, miner: &M, client: &C) -> U256 {
nonce
.or_else(|| miner.last_nonce(from).map(|nonce| nonce + U256::one()))
.unwrap_or_else(|| client.latest_nonce(from))
fn state_nonce(&self, from: &Address) -> U256 {
self.miner.last_nonce(from).map(|nonce| nonce + U256::one())
.unwrap_or_else(|| self.client.latest_nonce(from))
}
/// Imports transaction to the miner's queue.
pub fn dispatch_transaction(client: &C, miner: &M, signed_transaction: PendingTransaction) -> Result<H256, Error> {
let hash = signed_transaction.transaction.hash();
miner.import_own_transaction(client, signed_transaction)
.map_err(errors::transaction)
.map(|_| hash)
}
}
@@ -117,20 +139,23 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool)
-> BoxFuture<FilledTransactionRequest, Error>
{
let (client, miner) = (self.client.clone(), self.miner.clone());
let request = request;
let from = request.from.unwrap_or(default_sender);
let nonce = match force_nonce {
false => request.nonce,
true => Some(Self::fill_nonce(request.nonce, &from, &miner, &client)),
let nonce = if force_nonce {
request.nonce.or_else(|| Some(self.state_nonce(&from)))
} else {
request.nonce
};
Box::new(future::ok(FilledTransactionRequest {
from: from,
from,
used_default_from: request.from.is_none(),
to: request.to,
nonce: nonce,
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)),
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
nonce,
gas_price: request.gas_price.unwrap_or_else(|| {
default_gas_price(&*self.client, &*self.miner, self.gas_price_percentile)
}),
gas: request.gas.unwrap_or_else(|| self.miner.sensible_gas_limit()),
value: request.value.unwrap_or_else(|| 0.into()),
data: request.data.unwrap_or_else(Vec::new),
condition: request.condition,
@@ -140,30 +165,16 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
-> BoxFuture<WithToken<SignedTransaction>, Error>
{
let (client, miner) = (self.client.clone(), self.miner.clone());
let chain_id = client.signing_chain_id();
let address = filled.from;
Box::new(future::done({
let t = Transaction {
nonce: Self::fill_nonce(filled.nonce, &filled.from, &miner, &client),
action: filled.to.map_or(Action::Create, Action::Call),
gas: filled.gas,
gas_price: filled.gas_price,
value: filled.value,
data: filled.data,
};
let chain_id = self.client.signing_chain_id();
if accounts.is_hardware_address(address) {
hardware_signature(&*accounts, address, t, chain_id).map(WithToken::No)
} else {
let hash = t.hash(chain_id);
let signature = try_bf!(signature(&*accounts, address, hash, password));
Ok(signature.map(|sig| {
SignedTransaction::new(t.with_signature(sig, chain_id))
.expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed")
}))
}
}))
if let Some(nonce) = filled.nonce {
return Box::new(future::done(sign_transaction(&*accounts, filled, chain_id, nonce, password)));
}
let state = self.state_nonce(&filled.from);
let reserved = self.nonces.lock().reserve(filled.from, state);
Box::new(ProspectiveSigner::new(accounts, filled, chain_id, reserved, password))
}
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
@@ -172,11 +183,7 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
}
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error> {
let hash = signed_transaction.transaction.hash();
self.miner.import_own_transaction(&*self.client, signed_transaction)
.map_err(errors::transaction)
.map(|_| hash)
Self::dispatch_transaction(&*self.client, &*self.miner, signed_transaction)
}
}
@@ -217,8 +224,8 @@ pub fn fetch_gas_price_corpus(
})
})
.map(move |prices| {
// produce a corpus from the vector, cache it, and return
// the median as the intended gas price.
// produce a corpus from the vector and cache it.
// It's later used to get a percentile for default gas price.
let corpus: ::stats::Corpus<_> = prices.into();
cache.lock().set_gas_price_corpus(corpus.clone());
corpus
@@ -255,6 +262,10 @@ pub struct LightDispatcher {
pub cache: Arc<Mutex<LightDataCache>>,
/// Transaction queue.
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
/// Nonce reservations
pub nonces: Arc<Mutex<nonce::Reservations>>,
/// Gas Price percentile value used as default gas price.
pub gas_price_percentile: usize,
}
impl LightDispatcher {
@@ -267,6 +278,8 @@ impl LightDispatcher {
on_demand: Arc<OnDemand>,
cache: Arc<Mutex<LightDataCache>>,
transaction_queue: Arc<RwLock<LightTransactionQueue>>,
nonces: Arc<Mutex<nonce::Reservations>>,
gas_price_percentile: usize,
) -> Self {
LightDispatcher {
sync,
@@ -274,6 +287,8 @@ impl LightDispatcher {
on_demand,
cache,
transaction_queue,
nonces,
gas_price_percentile,
}
}
@@ -340,6 +355,7 @@ impl Dispatcher for LightDispatcher {
};
// fast path for known gas price.
let gas_price_percentile = self.gas_price_percentile;
let gas_price = match request_gas_price {
Some(gas_price) => Either::A(future::ok(with_gas_price(gas_price))),
None => Either::B(fetch_gas_price_corpus(
@@ -347,8 +363,8 @@ impl Dispatcher for LightDispatcher {
self.client.clone(),
self.on_demand.clone(),
self.cache.clone()
).and_then(|corp| match corp.median() {
Some(median) => Ok(*median),
).and_then(move |corp| match corp.percentile(gas_price_percentile) {
Some(percentile) => Ok(*percentile),
None => Ok(DEFAULT_GAS_PRICE), // fall back to default on error.
}).map(with_gas_price))
};
@@ -372,39 +388,20 @@ impl Dispatcher for LightDispatcher {
-> BoxFuture<WithToken<SignedTransaction>, Error>
{
let chain_id = self.client.signing_chain_id();
let address = filled.from;
let with_nonce = move |filled: FilledTransactionRequest, nonce| {
let t = Transaction {
nonce: nonce,
action: filled.to.map_or(Action::Create, Action::Call),
gas: filled.gas,
gas_price: filled.gas_price,
value: filled.value,
data: filled.data,
};
if accounts.is_hardware_address(address) {
return hardware_signature(&*accounts, address, t, chain_id).map(WithToken::No)
}
let hash = t.hash(chain_id);
let signature = signature(&*accounts, address, hash, password)?;
Ok(signature.map(|sig| {
SignedTransaction::new(t.with_signature(sig, chain_id))
.expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed")
}))
};
// fast path for pre-filled nonce.
if let Some(nonce) = filled.nonce {
return Box::new(future::done(with_nonce(filled, nonce)))
return Box::new(future::done(sign_transaction(&*accounts, filled, chain_id, nonce, password)))
}
Box::new(self.next_nonce(address)
let nonces = self.nonces.clone();
Box::new(self.next_nonce(filled.from)
.map_err(|_| errors::no_light_peers())
.and_then(move |nonce| with_nonce(filled, nonce)))
.and_then(move |nonce| {
let reserved = nonces.lock().reserve(filled.from, nonce);
ProspectiveSigner::new(accounts, filled, chain_id, reserved, password)
}))
}
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
@@ -422,6 +419,147 @@ impl Dispatcher for LightDispatcher {
}
}
fn sign_transaction(
accounts: &AccountProvider,
filled: FilledTransactionRequest,
chain_id: Option<u64>,
nonce: U256,
password: SignWith,
) -> Result<WithToken<SignedTransaction>, Error> {
let t = Transaction {
nonce: nonce,
action: filled.to.map_or(Action::Create, Action::Call),
gas: filled.gas,
gas_price: filled.gas_price,
value: filled.value,
data: filled.data,
};
if accounts.is_hardware_address(&filled.from) {
return hardware_signature(accounts, filled.from, t, chain_id).map(WithToken::No)
}
let hash = t.hash(chain_id);
let signature = signature(accounts, filled.from, hash, password)?;
Ok(signature.map(|sig| {
SignedTransaction::new(t.with_signature(sig, chain_id))
.expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed")
}))
}
#[derive(Debug, Clone, Copy)]
enum ProspectiveSignerState {
TryProspectiveSign,
WaitForNonce,
Finish,
}
struct ProspectiveSigner {
accounts: Arc<AccountProvider>,
filled: FilledTransactionRequest,
chain_id: Option<u64>,
reserved: nonce::Reserved,
password: SignWith,
state: ProspectiveSignerState,
prospective: Option<Result<WithToken<SignedTransaction>, Error>>,
ready: Option<nonce::Ready>,
}
impl ProspectiveSigner {
pub fn new(
accounts: Arc<AccountProvider>,
filled: FilledTransactionRequest,
chain_id: Option<u64>,
reserved: nonce::Reserved,
password: SignWith,
) -> Self {
// If the account is permanently unlocked we can try to sign
// using prospective nonce. This should speed up sending
// multiple subsequent transactions in multi-threaded RPC environment.
let is_unlocked_permanently = accounts.is_unlocked_permanently(&filled.from);
let has_password = password.is_password();
ProspectiveSigner {
accounts,
filled,
chain_id,
reserved,
password,
state: if is_unlocked_permanently || has_password {
ProspectiveSignerState::TryProspectiveSign
} else {
ProspectiveSignerState::WaitForNonce
},
prospective: None,
ready: None,
}
}
fn sign(&self, nonce: &U256) -> Result<WithToken<SignedTransaction>, Error> {
sign_transaction(
&*self.accounts,
self.filled.clone(),
self.chain_id,
*nonce,
self.password.clone()
)
}
fn poll_reserved(&mut self) -> Poll<nonce::Ready, Error> {
self.reserved.poll().map_err(|_| errors::internal("Nonce reservation failure", ""))
}
}
impl Future for ProspectiveSigner {
type Item = WithToken<SignedTransaction>;
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
use self::ProspectiveSignerState::*;
loop {
match self.state {
TryProspectiveSign => {
// Try to poll reserved, it might be ready.
match self.poll_reserved()? {
Async::NotReady => {
self.state = WaitForNonce;
self.prospective = Some(self.sign(self.reserved.prospective_value()));
},
Async::Ready(nonce) => {
self.state = Finish;
self.prospective = Some(self.sign(nonce.value()));
self.ready = Some(nonce);
},
}
},
WaitForNonce => {
let nonce = try_ready!(self.poll_reserved());
let result = match (self.prospective.take(), nonce.matches_prospective()) {
(Some(prospective), true) => prospective,
_ => self.sign(nonce.value()),
};
self.state = Finish;
self.prospective = Some(result);
self.ready = Some(nonce);
},
Finish => {
if let (Some(result), Some(nonce)) = (self.prospective.take(), self.ready.take()) {
// Mark nonce as used on successful signing
return result.map(move |tx| {
nonce.mark_used();
Async::Ready(tx)
})
} else {
panic!("Poll after ready.");
}
}
}
}
}
}
/// Single-use account token.
pub type AccountToken = String;
@@ -436,6 +574,16 @@ pub enum SignWith {
Token(AccountToken),
}
impl SignWith {
fn is_password(&self) -> bool {
if let SignWith::Password(_) = *self {
true
} else {
false
}
}
}
/// A value, potentially accompanied by a signing token.
#[derive(Debug)]
pub enum WithToken<T: Debug> {
@@ -529,7 +677,7 @@ pub fn execute<D: Dispatcher + 'static>(
))
},
ConfirmationPayload::EthSignMessage(address, data) => {
if accounts.is_hardware_address(address) {
if accounts.is_hardware_address(&address) {
return Box::new(future::err(errors::unsupported("Signing via hardware wallets is not supported.", None)));
}
@@ -543,7 +691,7 @@ pub fn execute<D: Dispatcher + 'static>(
Box::new(future::done(res))
},
ConfirmationPayload::Decrypt(address, data) => {
if accounts.is_hardware_address(address) {
if accounts.is_hardware_address(&address) {
return Box::new(future::err(errors::unsupported("Decrypting via hardware wallets is not supported.", None)));
}
@@ -572,7 +720,7 @@ fn signature(accounts: &AccountProvider, address: Address, hash: H256, password:
fn hardware_signature(accounts: &AccountProvider, address: Address, t: Transaction, chain_id: Option<u64>)
-> Result<SignedTransaction, Error>
{
debug_assert!(accounts.is_hardware_address(address));
debug_assert!(accounts.is_hardware_address(&address));
let mut stream = rlp::RlpStream::new();
t.rlp_append_unsigned_transaction(&mut stream, chain_id);
@@ -601,11 +749,11 @@ fn decrypt(accounts: &AccountProvider, address: Address, msg: Bytes, password: S
}
/// Extract the default gas price from a client and miner.
pub fn default_gas_price<C, M>(client: &C, miner: &M) -> U256 where
pub fn default_gas_price<C, M>(client: &C, miner: &M, percentile: usize) -> U256 where
C: MiningBlockChainClient,
M: MinerService,
{
client.gas_price_corpus(100).median().cloned().unwrap_or_else(|| miner.sensible_gas_price())
client.gas_price_corpus(100).percentile(percentile).cloned().unwrap_or_else(|| miner.sensible_gas_price())
}
/// Convert RPC confirmation payload to signer confirmation payload.

View File

@@ -46,7 +46,7 @@ pub fn sign_call<C: MiningBlockChainClient, M: MinerService> (
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
action: request.to.map_or(Action::Create, Action::Call),
gas,
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner)),
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner, 0)),
value: request.value.unwrap_or(0.into()),
data: request.data.unwrap_or_default(),
}.fake_sign(from))

View File

@@ -60,6 +60,8 @@ pub struct LightFetch {
pub sync: Arc<LightSync>,
/// The light data cache.
pub cache: Arc<Mutex<Cache>>,
/// Gas Price percentile
pub gas_price_percentile: usize,
}
/// Extract a transaction at given index.
@@ -203,6 +205,7 @@ impl LightFetch {
None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))),
};
let gas_price_percentile = self.gas_price_percentile;
let gas_price_fut = match req.gas_price {
Some(price) => Either::A(future::ok(price)),
None => Either::B(dispatch::fetch_gas_price_corpus(
@@ -210,8 +213,8 @@ impl LightFetch {
self.client.clone(),
self.on_demand.clone(),
self.cache.clone(),
).map(|corp| match corp.median() {
Some(median) => *median,
).map(move |corp| match corp.percentile(gas_price_percentile) {
Some(percentile) => *percentile,
None => DEFAULT_GAS_PRICE.into(),
}))
};

View File

@@ -22,14 +22,15 @@ pub mod block_import;
pub mod dapps;
pub mod dispatch;
pub mod fake_sign;
pub mod light_fetch;
pub mod oneshot;
pub mod ipfs;
pub mod light_fetch;
pub mod nonce;
pub mod oneshot;
pub mod secretstore;
mod network_settings;
mod poll_manager;
mod poll_filter;
mod poll_manager;
mod requests;
mod signer;
mod signing_queue;

315
rpc/src/v1/helpers/nonce.rs Normal file
View File

@@ -0,0 +1,315 @@
// Copyright 2015-2017 harity 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 std::{cmp, mem};
use std::collections::HashMap;
use std::sync::{atomic, Arc};
use std::sync::atomic::{AtomicBool, AtomicUsize};
use bigint::prelude::U256;
use futures::{Future, future, Poll, Async};
use futures::future::Either;
use futures::sync::oneshot;
use futures_cpupool::CpuPool;
use util::Address;
/// Manages currently reserved and prospective nonces
/// for multiple senders.
#[derive(Debug)]
pub struct Reservations {
nonces: HashMap<Address, SenderReservations>,
pool: CpuPool,
}
impl Reservations {
/// A maximal number of reserved nonces in the hashmap
/// before we start clearing the unused ones.
const CLEAN_AT: usize = 512;
/// Create new nonces manager and spawn a single-threaded cpu pool
/// for progressing execution of dropped nonces.
pub fn new() -> Self {
Self::with_pool(CpuPool::new(1))
}
/// Create new nonces manager with given cpupool.
pub fn with_pool(pool: CpuPool) -> Self {
Reservations {
nonces: Default::default(),
pool,
}
}
/// Reserve a nonce for particular address.
///
/// The reserved nonce cannot be smaller than the minimal nonce.
pub fn reserve(&mut self, sender: Address, minimal: U256) -> Reserved {
if self.nonces.len() + 1 > Self::CLEAN_AT {
self.nonces.retain(|_, v| !v.is_empty());
}
let pool = &self.pool;
self.nonces.entry(sender)
.or_insert_with(move || SenderReservations::with_pool(pool.clone()))
.reserve_nonce(minimal)
}
}
/// Manages currently reserved and prospective nonces.
#[derive(Debug)]
pub struct SenderReservations {
previous: Option<oneshot::Receiver<U256>>,
previous_ready: Arc<AtomicBool>,
pool: CpuPool,
prospective_value: U256,
dropped: Arc<AtomicUsize>,
}
impl SenderReservations {
/// Create new nonces manager and spawn a single-threaded cpu pool
/// for progressing execution of dropped nonces.
#[cfg(test)]
pub fn new() -> Self {
Self::with_pool(CpuPool::new(1))
}
/// Create new nonces manager with given cpu pool.
pub fn with_pool(pool: CpuPool) -> Self {
SenderReservations {
previous: None,
previous_ready: Arc::new(AtomicBool::new(true)),
pool,
prospective_value: Default::default(),
dropped: Default::default(),
}
}
/// Reserves a prospective nonce.
/// The caller should provide a minimal nonce that needs to be reserved (taken from state/txqueue).
/// If there were any previous reserved nonces the returned future will be resolved when those are finished
/// (confirmed that the nonce were indeed used).
/// The caller can use `prospective_nonce` and perform some heavy computation anticipating
/// that the `prospective_nonce` will be equal to the one he will get.
pub fn reserve_nonce(&mut self, minimal: U256) -> Reserved {
// Update prospective value
let dropped = self.dropped.swap(0, atomic::Ordering::SeqCst);
let prospective_value = cmp::max(minimal, self.prospective_value - dropped.into());
self.prospective_value = prospective_value + 1.into();
let (next, rx) = oneshot::channel();
let next = Some(next);
let next_sent = Arc::new(AtomicBool::default());
let pool = self.pool.clone();
let dropped = self.dropped.clone();
self.previous_ready = next_sent.clone();
match mem::replace(&mut self.previous, Some(rx)) {
Some(previous) => Reserved {
previous: Either::A(previous),
next,
next_sent,
minimal,
prospective_value,
pool,
dropped,
},
None => Reserved {
previous: Either::B(future::ok(minimal)),
next,
next_sent,
minimal,
prospective_value,
pool,
dropped,
},
}
}
/// Returns true if there are no reserved nonces.
pub fn is_empty(&self) -> bool {
self.previous_ready.load(atomic::Ordering::SeqCst)
}
}
/// Represents a future nonce.
#[derive(Debug)]
pub struct Reserved {
previous: Either<
oneshot::Receiver<U256>,
future::FutureResult<U256, oneshot::Canceled>,
>,
next: Option<oneshot::Sender<U256>>,
next_sent: Arc<AtomicBool>,
minimal: U256,
prospective_value: U256,
pool: CpuPool,
dropped: Arc<AtomicUsize>,
}
impl Reserved {
/// Returns a prospective value of the nonce.
/// NOTE: This might be different than the one we resolve to.
/// Make sure to check if both nonces match or use the latter one.
pub fn prospective_value(&self) -> &U256 {
&self.prospective_value
}
}
impl Future for Reserved {
type Item = Ready;
type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let mut value = try_ready!(self.previous.poll().map_err(|e| {
warn!("Unexpected nonce cancellation: {}", e);
}));
if value < self.minimal {
value = self.minimal
}
let matches_prospective = value == self.prospective_value;
Ok(Async::Ready(Ready {
value,
matches_prospective,
next: self.next.take(),
next_sent: self.next_sent.clone(),
dropped: self.dropped.clone(),
}))
}
}
impl Drop for Reserved {
fn drop(&mut self) {
if let Some(next) = self.next.take() {
let next_sent = self.next_sent.clone();
self.dropped.fetch_add(1, atomic::Ordering::SeqCst);
// If Reserved is dropped just pipe previous and next together.
let previous = mem::replace(&mut self.previous, Either::B(future::ok(U256::default())));
self.pool.spawn(previous.map(move |nonce| {
next_sent.store(true, atomic::Ordering::SeqCst);
next.send(nonce).expect(Ready::RECV_PROOF)
})).forget()
}
}
}
/// Represents a valid reserved nonce.
/// This can be used to dispatch the transaction.
///
/// After this nonce is used it should be marked as such
/// using `mark_used` method.
#[derive(Debug)]
pub struct Ready {
value: U256,
matches_prospective: bool,
next: Option<oneshot::Sender<U256>>,
next_sent: Arc<AtomicBool>,
dropped: Arc<AtomicUsize>,
}
impl Ready {
const RECV_PROOF: &'static str = "Receiver never dropped.";
/// Returns a value of the nonce.
pub fn value(&self) -> &U256 {
&self.value
}
/// Returns true if current value matches the prospective nonce.
pub fn matches_prospective(&self) -> bool {
self.matches_prospective
}
/// Marks this nonce as used.
/// Make sure to call that method after this nonce has been consumed.
pub fn mark_used(mut self) {
let next = self.next.take().expect("Nonce can be marked as used only once; qed");
self.next_sent.store(true, atomic::Ordering::SeqCst);
next.send(self.value + 1.into()).expect(Self::RECV_PROOF);
}
}
impl Drop for Ready {
fn drop(&mut self) {
if let Some(next) = self.next.take() {
self.dropped.fetch_add(1, atomic::Ordering::SeqCst);
self.next_sent.store(true, atomic::Ordering::SeqCst);
next.send(self.value).expect(Self::RECV_PROOF);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_reserve_a_set_of_nonces_and_resolve_them() {
let mut nonces = SenderReservations::new();
assert!(nonces.is_empty());
let n1 = nonces.reserve_nonce(5.into());
let n2 = nonces.reserve_nonce(5.into());
let n3 = nonces.reserve_nonce(5.into());
let n4 = nonces.reserve_nonce(5.into());
assert!(!nonces.is_empty());
// Check first nonce
let r = n1.wait().unwrap();
assert_eq!(r.value(), &U256::from(5));
assert!(r.matches_prospective());
r.mark_used();
// Drop second nonce
drop(n2);
// Drop third without marking as used
let r = n3.wait().unwrap();
drop(r);
// Last nonce should be resolved to 6
let r = n4.wait().unwrap();
assert_eq!(r.value(), &U256::from(6));
assert!(!r.matches_prospective());
r.mark_used();
// Next nonce should be immediately available.
let n5 = nonces.reserve_nonce(5.into());
let r = n5.wait().unwrap();
assert_eq!(r.value(), &U256::from(7));
assert!(r.matches_prospective());
r.mark_used();
// Should use start number if it's greater
let n6 = nonces.reserve_nonce(10.into());
let r = n6.wait().unwrap();
assert_eq!(r.value(), &U256::from(10));
assert!(r.matches_prospective());
r.mark_used();
assert!(nonces.is_empty());
}
#[test]
fn should_return_prospective_nonce() {
let mut nonces = SenderReservations::new();
let n1 = nonces.reserve_nonce(5.into());
let n2 = nonces.reserve_nonce(5.into());
assert_eq!(n1.prospective_value(), &U256::from(5));
assert_eq!(n2.prospective_value(), &U256::from(6));
}
}

View File

@@ -15,8 +15,9 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bigint::prelude::U256;
use util::Address;
use bytes::Bytes;
use util::Address;
use v1::types::{Origin, TransactionCondition};
/// Transaction request coming from RPC

View File

@@ -45,7 +45,7 @@ use jsonrpc_core::futures::future;
use jsonrpc_macros::Trailing;
use v1::helpers::{errors, limit_logs, fake_sign};
use v1::helpers::dispatch::{Dispatcher, FullDispatcher, default_gas_price};
use v1::helpers::dispatch::{FullDispatcher, default_gas_price};
use v1::helpers::block_import::is_major_importing;
use v1::helpers::accounts::unwrap_provider;
use v1::traits::Eth;
@@ -66,6 +66,8 @@ pub struct EthClientOptions {
pub allow_pending_receipt_query: bool,
/// Send additional block number when asking for work
pub send_block_number_in_get_work: bool,
/// Gas Price Percentile used as default gas price.
pub gas_price_percentile: usize,
}
impl EthClientOptions {
@@ -84,6 +86,7 @@ impl Default for EthClientOptions {
pending_nonce_from_queue: false,
allow_pending_receipt_query: true,
send_block_number_in_get_work: true,
gas_price_percentile: 50,
}
}
}
@@ -338,7 +341,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
}
fn gas_price(&self) -> Result<RpcU256, Error> {
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner)))
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner, self.options.gas_price_percentile)))
}
fn accounts(&self, meta: Metadata) -> Result<Vec<RpcH160>, Error> {
@@ -610,8 +613,11 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
.map_err(errors::rlp)
.and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))
.and_then(|signed_transaction| {
FullDispatcher::new(self.client.clone(), self.miner.clone())
.dispatch_transaction(signed_transaction.into())
FullDispatcher::dispatch_transaction(
&*self.client,
&*self.miner,
signed_transaction.into(),
)
})
.map(Into::into)
}

View File

@@ -92,12 +92,14 @@ impl EthPubSubClient<LightFetch> {
sync: Arc<LightSync>,
cache: Arc<Mutex<Cache>>,
remote: Remote,
gas_price_percentile: usize,
) -> Self {
let fetch = LightFetch {
client,
on_demand,
sync,
cache
cache,
gas_price_percentile,
};
EthPubSubClient::new(Arc::new(fetch), remote)
}

View File

@@ -62,6 +62,7 @@ pub struct EthClient<T> {
accounts: Arc<AccountProvider>,
cache: Arc<Mutex<LightDataCache>>,
polls: Mutex<PollManager<PollFilter>>,
gas_price_percentile: usize,
}
impl<T> Clone for EthClient<T> {
@@ -75,6 +76,7 @@ impl<T> Clone for EthClient<T> {
accounts: self.accounts.clone(),
cache: self.cache.clone(),
polls: Mutex::new(PollManager::new()),
gas_price_percentile: self.gas_price_percentile,
}
}
}
@@ -89,15 +91,17 @@ impl<T: LightChainClient + 'static> EthClient<T> {
transaction_queue: Arc<RwLock<TransactionQueue>>,
accounts: Arc<AccountProvider>,
cache: Arc<Mutex<LightDataCache>>,
gas_price_percentile: usize,
) -> Self {
EthClient {
sync: sync,
client: client,
on_demand: on_demand,
transaction_queue: transaction_queue,
accounts: accounts,
cache: cache,
sync,
client,
on_demand,
transaction_queue,
accounts,
cache,
polls: Mutex::new(PollManager::new()),
gas_price_percentile,
}
}
@@ -108,6 +112,7 @@ impl<T: LightChainClient + 'static> EthClient<T> {
on_demand: self.on_demand.clone(),
sync: self.sync.clone(),
cache: self.cache.clone(),
gas_price_percentile: self.gas_price_percentile,
}
}
@@ -239,7 +244,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
fn gas_price(&self) -> Result<RpcU256, Error> {
Ok(self.cache.lock().gas_price_corpus()
.and_then(|c| c.median().cloned())
.and_then(|c| c.percentile(self.gas_price_percentile).cloned())
.map(RpcU256::from)
.unwrap_or_else(Default::default))
}

View File

@@ -60,6 +60,7 @@ pub struct ParityClient {
dapps_address: Option<Host>,
ws_address: Option<Host>,
eip86_transition: u64,
gas_price_percentile: usize,
}
impl ParityClient {
@@ -74,6 +75,7 @@ impl ParityClient {
signer: Option<Arc<SignerService>>,
dapps_address: Option<Host>,
ws_address: Option<Host>,
gas_price_percentile: usize,
) -> Self {
ParityClient {
light_dispatch,
@@ -85,7 +87,8 @@ impl ParityClient {
dapps_address,
ws_address,
eip86_transition: client.eip86_transition(),
client: client,
client,
gas_price_percentile,
}
}
@@ -96,6 +99,7 @@ impl ParityClient {
on_demand: self.light_dispatch.on_demand.clone(),
sync: self.light_dispatch.sync.clone(),
cache: self.light_dispatch.cache.clone(),
gas_price_percentile: self.gas_price_percentile,
}
}
}

View File

@@ -119,7 +119,7 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
Box::new(dispatch::from_rpc(payload, default_account, &dispatcher)
.and_then(move |payload| {
let sender = payload.sender();
if accounts.is_unlocked(sender) {
if accounts.is_unlocked(&sender) {
Either::A(dispatch::execute(dispatcher, accounts, payload, dispatch::SignWith::Nothing)
.map(|v| v.into_value())
.map(DispatchResult::Value))

View File

@@ -19,25 +19,27 @@ use std::env;
use std::sync::Arc;
use std::time::Duration;
use ethcore::client::{BlockChainClient, Client, ClientConfig};
use ethcore::ids::BlockId;
use ethcore::spec::{Genesis, Spec};
use ethcore::block::Block;
use ethcore::views::BlockView;
use ethcore::ethereum;
use ethcore::miner::{MinerOptions, Banning, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy, GasLimit};
use bigint::hash::H256;
use bigint::prelude::U256;
use ethcore::account_provider::AccountProvider;
use ethcore::block::Block;
use ethcore::client::{BlockChainClient, Client, ClientConfig};
use ethcore::ethereum;
use ethcore::ids::BlockId;
use ethcore::miner::{MinerOptions, Banning, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy, GasLimit};
use ethcore::spec::{Genesis, Spec};
use ethcore::views::BlockView;
use ethjson::blockchain::BlockChain;
use ethjson::state::test::ForkSpec;
use io::IoChannel;
use bigint::prelude::U256;
use bigint::hash::H256;
use kvdb_memorydb;
use parking_lot::Mutex;
use util::Address;
use kvdb::in_memory;
use jsonrpc_core::IoHandler;
use v1::impls::{EthClient, SigningUnsafeClient};
use v1::helpers::dispatch::FullDispatcher;
use v1::helpers::nonce;
use v1::impls::{EthClient, SigningUnsafeClient};
use v1::metadata::Metadata;
use v1::tests::helpers::{TestSnapshotService, TestSyncProvider, Config};
use v1::traits::eth::Eth;
@@ -131,7 +133,7 @@ impl EthTester {
let client = Client::new(
ClientConfig::default(),
&spec,
Arc::new(in_memory(::ethcore::db::NUM_COLUMNS.unwrap_or(0))),
Arc::new(kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0))),
miner_service.clone(),
IoChannel::disconnected(),
).unwrap();
@@ -148,7 +150,9 @@ impl EthTester {
Default::default(),
);
let dispatcher = FullDispatcher::new(client.clone(), miner_service.clone());
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let dispatcher = FullDispatcher::new(client.clone(), miner_service.clone(), reservations, 50);
let eth_sign = SigningUnsafeClient::new(
&opt_account_provider,
dispatcher,

View File

@@ -37,6 +37,7 @@ use ethsync::SyncState;
use jsonrpc_core::IoHandler;
use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, SigningUnsafeClient};
use v1::helpers::nonce;
use v1::helpers::dispatch::FullDispatcher;
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestSnapshotService};
use v1::metadata::Metadata;
@@ -92,10 +93,12 @@ impl EthTester {
let snapshot = snapshot_service();
let hashrates = Arc::new(Mutex::new(HashMap::new()));
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
let gas_price_percentile = options.gas_price_percentile;
let eth = EthClient::new(&client, &snapshot, &sync, &opt_ap, &miner, &external_miner, options).to_delegate();
let filter = EthFilterClient::new(client.clone(), miner.clone()).to_delegate();
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let dispatcher = FullDispatcher::new(client.clone(), miner.clone());
let dispatcher = FullDispatcher::new(client.clone(), miner.clone(), reservations, gas_price_percentile);
let sign = SigningUnsafeClient::new(&opt_ap, dispatcher).to_delegate();
let mut io: IoHandler<Metadata> = IoHandler::default();
io.extend_with(eth);

View File

@@ -17,14 +17,16 @@
use std::sync::Arc;
use std::str::FromStr;
use bigint::prelude::U256;
use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Action, Transaction};
use jsonrpc_core::IoHandler;
use bigint::prelude::U256;
use parking_lot::Mutex;
use util::Address;
use v1::{PersonalClient, Personal, Metadata};
use v1::helpers::nonce;
use v1::helpers::dispatch::FullDispatcher;
use v1::tests::helpers::TestMinerService;
@@ -52,8 +54,9 @@ fn setup() -> PersonalTester {
let opt_accounts = Some(accounts.clone());
let client = blockchain_client();
let miner = miner_service();
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let dispatcher = FullDispatcher::new(client, miner.clone());
let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50);
let personal = PersonalClient::new(&opt_accounts, dispatcher, false);
let mut io = IoHandler::default();

View File

@@ -24,6 +24,7 @@ use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient;
use ethcore::transaction::{Transaction, Action, SignedTransaction};
use parity_reactor::EventLoop;
use parking_lot::Mutex;
use rlp::encode;
use serde_json;
@@ -32,7 +33,7 @@ use v1::{SignerClient, Signer, Origin};
use v1::metadata::Metadata;
use v1::tests::helpers::TestMinerService;
use v1::types::{Bytes as RpcBytes, H520};
use v1::helpers::{SigningQueue, SignerService, FilledTransactionRequest, ConfirmationPayload};
use v1::helpers::{nonce, SigningQueue, SignerService, FilledTransactionRequest, ConfirmationPayload};
use v1::helpers::dispatch::{FullDispatcher, eth_data_hash};
struct SignerTester {
@@ -61,9 +62,10 @@ fn signer_tester() -> SignerTester {
let opt_accounts = Some(accounts.clone());
let client = blockchain_client();
let miner = miner_service();
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let event_loop = EventLoop::spawn();
let dispatcher = FullDispatcher::new(client, miner.clone());
let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50);
let mut io = IoHandler::default();
io.extend_with(SignerClient::new(&opt_accounts, dispatcher, &signer, event_loop.remote()).to_delegate());

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