Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c6e3f314a | ||
|
|
96cbfba916 | ||
|
|
18b8d6aca6 | ||
|
|
6a44a0cf95 | ||
|
|
b7860e4a3f | ||
|
|
4a910a762d | ||
|
|
1626c78ae2 | ||
|
|
7f4e700013 | ||
|
|
987390fb7d | ||
|
|
797f23f30b | ||
|
|
c1da49bbc4 | ||
|
|
1164193019 | ||
|
|
1c217cbf2b | ||
|
|
d24f71f150 | ||
|
|
4c66a021ec | ||
|
|
ccc57328e2 | ||
|
|
77240b6e5a | ||
|
|
2e428ddd58 | ||
|
|
cd4081c149 | ||
|
|
428342d69d | ||
|
|
8ee9b262f9 |
@@ -26,14 +26,14 @@ linux-stable:
|
||||
- cargo build -j $(nproc) --release -p ethstore
|
||||
- cargo build -j $(nproc) --release -p ethkey
|
||||
- strip target/release/parity
|
||||
- strip target/release/evm
|
||||
- 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/evm deb/usr/bin/evm
|
||||
- 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")
|
||||
@@ -55,9 +55,9 @@ linux-stable:
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
- target/release/parity/evmbin
|
||||
- target/release/parity/ethstore
|
||||
- target/release/parity/ethkey
|
||||
- target/release/parity-evm
|
||||
- target/release/ethstore
|
||||
- target/release/ethkey
|
||||
name: "stable-x86_64-unknown-linux-gnu_parity"
|
||||
linux-stable-debian:
|
||||
stage: build
|
||||
@@ -73,14 +73,14 @@ linux-stable-debian:
|
||||
- cargo build -j $(nproc) --release -p ethstore
|
||||
- cargo build -j $(nproc) --release -p ethkey
|
||||
- strip target/release/parity
|
||||
- strip target/release/evm
|
||||
- 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/evm deb/usr/bin/evm
|
||||
- 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")
|
||||
@@ -308,10 +308,10 @@ linux-armv6:
|
||||
stage: build
|
||||
image: ethcore/rust-armv6:latest
|
||||
only:
|
||||
- beta
|
||||
# - beta
|
||||
# - tags
|
||||
# - stable
|
||||
# - triggers
|
||||
- triggers
|
||||
script:
|
||||
- export CC=arm-linux-gnueabi-gcc
|
||||
- export CXX=arm-linux-gnueabi-g++
|
||||
@@ -409,16 +409,16 @@ darwin:
|
||||
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"-osx-installer-EXPERIMENTAL.pkg"
|
||||
md5sum "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg" >> "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5"
|
||||
mv target/release/Parity\ Ethereum-signed.pkg "parity-"$VER"-osx-installer.pkg"
|
||||
md5sum "parity-"$VER"-osx-installer.pkg" >> "parity-"$VER"-osx-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)$ ]]; 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"-osx-installer-EXPERIMENTAL.pkg" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5"
|
||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-osx-installer.pkg" --body "parity-"$VER"-osx-installer.pkg"
|
||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-osx-installer.pkg.md5" --body "parity-"$VER"-osx-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
|
||||
tags:
|
||||
|
||||
318
Cargo.lock
generated
318
Cargo.lock
generated
@@ -1,6 +1,6 @@
|
||||
[root]
|
||||
name = "parity"
|
||||
version = "1.6.2"
|
||||
version = "1.6.6"
|
||||
dependencies = [
|
||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -23,7 +23,7 @@ dependencies = [
|
||||
"ethcore-secretstore 1.0.0",
|
||||
"ethcore-signer 1.6.0",
|
||||
"ethcore-stratum 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethsync 1.6.0",
|
||||
"evmbin 0.1.0",
|
||||
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -101,10 +101,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aster"
|
||||
version = "0.17.0"
|
||||
version = "0.41.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -204,7 +204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"multihash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -253,7 +253,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -261,7 +261,7 @@ name = "core-foundation-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -284,7 +284,7 @@ version = "1.1.1"
|
||||
source = "git+https://github.com/ethcore/rust-ctrlc.git#f4927770f89eca80ec250911eea3adcbf579ac48"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -293,7 +293,7 @@ name = "daemonize"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -348,7 +348,7 @@ source = "git+https://github.com/ethcore/rust-secp256k1#98ad9b9ecae44a563efdd642
|
||||
dependencies = [
|
||||
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -394,13 +394,14 @@ dependencies = [
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-ipc-nano 1.6.0",
|
||||
"ethcore-stratum 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"ethstore 0.1.0",
|
||||
"evmjit 1.6.0",
|
||||
"hardware-wallet 1.6.0",
|
||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -422,7 +423,7 @@ version = "0.1.2"
|
||||
dependencies = [
|
||||
"bigint 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -443,7 +444,7 @@ dependencies = [
|
||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-devtools 1.6.0",
|
||||
"ethcore-rpc 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
||||
@@ -453,7 +454,7 @@ dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.6.0",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-ui 1.6.0",
|
||||
@@ -491,8 +492,8 @@ name = "ethcore-ipc"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"ethcore-devtools 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||
"ethcore-util 1.6.6",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -500,11 +501,11 @@ dependencies = [
|
||||
name = "ethcore-ipc-codegen"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -515,7 +516,7 @@ dependencies = [
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-ipc-nano 1.6.0",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -527,7 +528,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.6.0",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -538,9 +539,9 @@ dependencies = [
|
||||
"ethcore-ipc 1.6.0",
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-ipc-nano 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -553,13 +554,13 @@ dependencies = [
|
||||
"ethcore-ipc 1.6.0",
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-network 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.1.0",
|
||||
"smallvec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stats 0.1.0",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -569,7 +570,7 @@ name = "ethcore-logger"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -585,11 +586,11 @@ dependencies = [
|
||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-devtools 1.6.0",
|
||||
"ethcore-io 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.1 (git+https://github.com/ethcore/mio)",
|
||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -613,7 +614,7 @@ dependencies = [
|
||||
"ethcore-io 1.6.0",
|
||||
"ethcore-ipc 1.6.0",
|
||||
"ethcore-light 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
@@ -648,7 +649,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.6.0",
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-ipc-nano 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"hyper 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -666,10 +667,10 @@ dependencies = [
|
||||
"ethcore-devtools 1.6.0",
|
||||
"ethcore-io 1.6.0",
|
||||
"ethcore-rpc 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-ui 1.6.0",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -685,7 +686,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.6.0",
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-ipc-nano 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||
"jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||
@@ -699,7 +700,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-util"
|
||||
version = "1.6.2"
|
||||
version = "1.6.6"
|
||||
dependencies = [
|
||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -713,7 +714,7 @@ dependencies = [
|
||||
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lru-cache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -748,7 +749,7 @@ dependencies = [
|
||||
name = "ethjson"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -776,12 +777,12 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-devtools 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -790,7 +791,7 @@ dependencies = [
|
||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -809,14 +810,15 @@ dependencies = [
|
||||
"ethcore-ipc-nano 1.6.0",
|
||||
"ethcore-light 1.6.0",
|
||||
"ethcore-network 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethkey 0.2.0",
|
||||
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.1.0",
|
||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -826,7 +828,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -842,7 +844,7 @@ name = "fdlimit"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -862,7 +864,7 @@ name = "flate2"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -937,7 +939,7 @@ version = "0.3.1"
|
||||
source = "git+https://github.com/ethcore/hidapi-rs#9a127c1dca7e327e4fdd428406a76c9f5ef48563"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1054,7 +1056,7 @@ version = "1.6.0"
|
||||
dependencies = [
|
||||
"ethcore-ipc 1.6.0",
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1064,7 +1066,7 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1173,7 +1175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.16"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -1182,7 +1184,7 @@ version = "0.3.0"
|
||||
source = "git+https://github.com/ethcore/libusb-rs#32bacf61abd981d5cbd4a8fecca5a2dc0b762a96"
|
||||
dependencies = [
|
||||
"bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libusb-sys 0.2.3 (git+https://github.com/ethcore/libusb-sys)",
|
||||
]
|
||||
|
||||
@@ -1192,7 +1194,7 @@ version = "0.2.3"
|
||||
source = "git+https://github.com/ethcore/libusb-sys#c10b1180646c9dc3f23a9b6bb825abcd3b7487ce"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1228,7 +1230,7 @@ name = "memchr"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1256,7 +1258,7 @@ version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1265,7 +1267,7 @@ version = "0.5.1"
|
||||
source = "git+https://github.com/ethcore/mio?branch=v0.5.x#3842d3b250ffd7bd9b16f9586b875ddcbac2b0dd"
|
||||
dependencies = [
|
||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1281,7 +1283,7 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1297,7 +1299,7 @@ version = "0.6.0-dev"
|
||||
source = "git+https://github.com/ethcore/mio?branch=timer-fix#31eccc40ece3d47abaefaf23bb2114033175b972"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1313,7 +1315,7 @@ source = "git+https://github.com/ethcore/mio#ef182bae193a9c7457cd2cf661fcaffb226
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1329,7 +1331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1369,29 +1371,29 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "multihash"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ring 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ring 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanomsg"
|
||||
version = "0.5.1"
|
||||
source = "git+https://github.com/ethcore/nanomsg.rs.git#c40fe442c9afaea5b38009a3d992ca044dcceb00"
|
||||
source = "git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanomsg-sys"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/ethcore/nanomsg.rs.git#c40fe442c9afaea5b38009a3d992ca044dcceb00"
|
||||
source = "git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1413,7 +1415,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -1424,7 +1426,7 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1434,7 +1436,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1447,7 +1449,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1537,7 +1539,7 @@ name = "num_cpus"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1545,7 +1547,7 @@ name = "num_cpus"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1577,7 +1579,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1587,7 +1589,7 @@ version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -1604,16 +1606,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "parity-dapps-glue"
|
||||
version = "1.4.0"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1621,7 +1623,7 @@ name = "parity-hash-fetch"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"ethabi 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1638,11 +1640,11 @@ version = "1.6.0"
|
||||
dependencies = [
|
||||
"cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
||||
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"multihash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.1.0",
|
||||
]
|
||||
|
||||
@@ -1652,7 +1654,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore 1.6.0",
|
||||
"ethcore-io 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethkey 0.2.0",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.1.0",
|
||||
@@ -1675,7 +1677,7 @@ version = "1.4.0"
|
||||
dependencies = [
|
||||
"ethcore-rpc 1.6.0",
|
||||
"ethcore-signer 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1691,24 +1693,24 @@ dependencies = [
|
||||
name = "parity-ui"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"parity-ui-dev 1.4.0",
|
||||
"parity-ui-dev 1.7.0",
|
||||
"parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git?branch=beta)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-ui-dev"
|
||||
version = "1.4.0"
|
||||
version = "1.7.0"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#2a7fc4e6c5f958e8716b028b6ded010a9e238f9b"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#ff37c140c4c73f96c77a77631fca1cbe2bb15af7"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1719,7 +1721,7 @@ dependencies = [
|
||||
"ethcore 1.6.0",
|
||||
"ethcore-ipc 1.6.0",
|
||||
"ethcore-ipc-codegen 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"ethsync 1.6.0",
|
||||
"ipc-common-types 1.6.0",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1743,7 +1745,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1836,20 +1838,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quasi"
|
||||
version = "0.11.0"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_errors 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quasi_codegen"
|
||||
version = "0.11.0"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_errors 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1872,7 +1876,7 @@ name = "rand"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1918,10 +1922,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.6.2"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"untrusted 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1940,7 +1945,7 @@ name = "rocksdb"
|
||||
version = "0.4.5"
|
||||
source = "git+https://github.com/ethcore/rust-rocksdb#64c63ccbe1f62c2e2b39262486f9ba813793af58"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)",
|
||||
]
|
||||
|
||||
@@ -1950,7 +1955,7 @@ version = "0.3.0"
|
||||
source = "git+https://github.com/ethcore/rust-rocksdb#64c63ccbe1f62c2e2b39262486f9ba813793af58"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1971,7 +1976,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -1982,7 +1987,7 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -1993,7 +1998,7 @@ version = "1.4.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.1.2",
|
||||
"ethcore-rpc 1.6.0",
|
||||
"ethcore-util 1.6.2",
|
||||
"ethcore-util 1.6.6",
|
||||
"futures 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc-client 1.4.0",
|
||||
"rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2005,7 +2010,7 @@ version = "0.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2059,7 +2064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -2069,7 +2074,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2093,6 +2098,14 @@ dependencies = [
|
||||
"semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.6.1"
|
||||
@@ -2102,6 +2115,11 @@ dependencies = [
|
||||
"regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.9.6"
|
||||
@@ -2205,8 +2223,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solicit"
|
||||
@@ -2250,23 +2271,44 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syntex"
|
||||
version = "0.33.0"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_errors 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syntex_errors"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_pos 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syntex_pos"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syntex_syntax"
|
||||
version = "0.33.0"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_errors 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_pos 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2293,7 +2335,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.2.14"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2305,7 +2347,7 @@ name = "termios"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2314,7 +2356,7 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2331,7 +2373,7 @@ version = "0.1.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -2431,11 +2473,6 @@ name = "unicode-normalization"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.0.4"
|
||||
@@ -2569,7 +2606,7 @@ dependencies = [
|
||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||
"checksum app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7d1c0d48a81bbb13043847f957971f4d87c81542d80ece5e84ba3cba4058fd4"
|
||||
"checksum arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "16e3bdb2f54b3ace0285975d59a97cf8ed3855294b2b6bc651fcf22a9c352975"
|
||||
"checksum aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07d344974f0a155f091948aa389fb1b912d3a58414fbdb9c8d446d193ee3496a"
|
||||
"checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0"
|
||||
"checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1"
|
||||
"checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c"
|
||||
"checksum bigint 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2311bcd71b281e142a095311c22509f0d6bcd87b3000d7dbaa810929b9d6f6ae"
|
||||
@@ -2635,7 +2672,7 @@ dependencies = [
|
||||
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
||||
"checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
|
||||
"checksum libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "408014cace30ee0f767b1c4517980646a573ec61a57957aeeabcac8ac0a02e8d"
|
||||
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
||||
"checksum libusb 0.3.0 (git+https://github.com/ethcore/libusb-rs)" = "<none>"
|
||||
"checksum libusb-sys 0.2.3 (git+https://github.com/ethcore/libusb-sys)" = "<none>"
|
||||
"checksum linked-hash-map 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bda158e0dabeb97ee8a401f4d17e479d6b891a14de0bba79d5cc2d4d325b5e48"
|
||||
@@ -2655,9 +2692,9 @@ dependencies = [
|
||||
"checksum miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bfc6782530ac8ace97af10a540054a37126b63b0702ddaaa243b73b5745b9a"
|
||||
"checksum msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c04b68cc63a8480fb2550343695f7be72effdec953a9d4508161c3e69041c7d8"
|
||||
"checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6"
|
||||
"checksum multihash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "755d5a39bee3faaf649437e873beab334990221b2faf1f2e56ca10a9e4600235"
|
||||
"checksum nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)" = "<none>"
|
||||
"checksum nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)" = "<none>"
|
||||
"checksum multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c9f70f2402fa07c16c40be8fd0a748a39257c5dc3ff5c857cbbde2f39135c505"
|
||||
"checksum nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
|
||||
"checksum nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
|
||||
"checksum native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4e52995154bb6f0b41e4379a279482c9387c1632e3798ba4e511ef8c54ee09"
|
||||
"checksum net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a816012ca11cb47009693c1e0c6130e26d39e4d97ee2a13c50e868ec83e3204"
|
||||
"checksum nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f05c2fc965fc1cd6b73fa57fa7b89f288178737f2f3ce9e63e4a6a141189000e"
|
||||
@@ -2681,7 +2718,7 @@ dependencies = [
|
||||
"checksum openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d2845e841700e7b04282ceaa115407ea84e0db918ae689ad9ceb6f06fa6046bd"
|
||||
"checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb"
|
||||
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
|
||||
"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
|
||||
"checksum parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1d06f6ee0fda786df3784a96ee3f0629f529b91cbfb7d142f6410e6bcd1ce2c"
|
||||
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git?branch=beta)" = "<none>"
|
||||
"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621"
|
||||
"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
|
||||
@@ -2696,8 +2733,8 @@ dependencies = [
|
||||
"checksum primal-check 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "647c81b67bb9551a7b88d0bcd785ac35b7d0bf4b2f358683d7c2375d04daec51"
|
||||
"checksum primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56ea4531dde757b56906493c8604641da14607bf9cdaa80fb9c9cabd2429f8d5"
|
||||
"checksum primal-sieve 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7aa73fd87e5984a00bdb4c1b14d3d5d6d0bad01b2caaaf924c16ab7260ac946c"
|
||||
"checksum quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b26543b563704e7d87f3ec7cfafb713010a905c5f1b155a8ab66863af43ca578"
|
||||
"checksum quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0881d9a45d5f9ebe4a7e77742f8c604f3658c212baf8dd711a692dd000bc648c"
|
||||
"checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
|
||||
"checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
|
||||
"checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c"
|
||||
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
|
||||
"checksum quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6732e32663c9c271bfc7c1823486b471f18c47a2dbf87c066897b7b51afc83be"
|
||||
@@ -2706,7 +2743,7 @@ dependencies = [
|
||||
"checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29"
|
||||
"checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9"
|
||||
"checksum reqwest 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bef9ed8fdfcc30947d6b774938dc0c3f369a474efe440df2c7f278180b2d2e6"
|
||||
"checksum ring 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "87ac4fce2ee4bb10dd106788e90fdfa4c5a7f3f9f6aae29824db77dc57e2767d"
|
||||
"checksum ring 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "595afba2db7545b940ec900dc59b5281f719d327fc0674eeadc9953617e55357"
|
||||
"checksum rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)" = "<none>"
|
||||
"checksum rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)" = "<none>"
|
||||
"checksum rotor 0.6.3 (git+https://github.com/ethcore/rotor)" = "<none>"
|
||||
@@ -2723,7 +2760,9 @@ dependencies = [
|
||||
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
|
||||
"checksum semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2ff60ecdb19c255841c066cbfa5f8c2a4ada1eb3ae47c77ab6667128da71f5"
|
||||
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
||||
"checksum semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e88e43a5a74dd2a11707f9c21dfd4a423c66bd871df813227bb0a3e78f3a1ae9"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0ae9a3c8b07c09dbe43022486d55a18c629a0618d2241e49829aaef9b6d862f9"
|
||||
"checksum serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3172bf2940b975c0e4f6ab42a511c0a4407d4f46ccef87a9d3615db5c26fa96"
|
||||
"checksum serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecc6e0379ca933ece58302d2d3034443f06fbf38fd535857c1dc516195cbc3bf"
|
||||
@@ -2738,18 +2777,20 @@ dependencies = [
|
||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||
"checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410"
|
||||
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
|
||||
"checksum smallvec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3c84984c278afe61a46e19868e8b23e2ee3be5b3cc6dea6edad4893bc6c841"
|
||||
"checksum smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dca03f2f42500a9ef8ac0d16183dff8bed40e3dcf98f9d4147928548d5c4236e"
|
||||
"checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2"
|
||||
"checksum spmc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93bdab61c1a413e591c4d17388ffa859eaff2df27f1e13a5ec8b716700605adf"
|
||||
"checksum stable-heap 0.1.0 (git+https://github.com/carllerche/stable-heap?rev=3c5cd1ca47)" = "<none>"
|
||||
"checksum strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e4d73a2c36a4d095ed1a6df5cbeac159863173447f7a82b3f4757426844ab825"
|
||||
"checksum syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f94368aae82bb29656c98443a7026ca931a659e8d19dcdc41d6e273054e820"
|
||||
"checksum syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393b6dd0889df2b064beeea954cfda6bc2571604ac460deeae0fed55a53988af"
|
||||
"checksum syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44bded3cabafc65c90b663b1071bd2d198a9ab7515e6ce729e4570aaf53c407e"
|
||||
"checksum syntex 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35f3cc9d446323ef8fefad933b65cd6de271d29fa14a2e9d036a084770c6d6d5"
|
||||
"checksum syntex_errors 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3af03823ea45d420dd2c1a44bb074e13ea55f9b99afe960fd58eb4069b7f6cad"
|
||||
"checksum syntex_pos 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e502a4a904d9f37cf975dbdbb0b08f2d111322f6792bda6eb095b4112c9a24b"
|
||||
"checksum syntex_syntax 0.58.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cf936464c3863952ea3fab848860ea891eba8647b6008b04c36f0bb007192a3"
|
||||
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
|
||||
"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe"
|
||||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||
"checksum term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "f2077e54d38055cf1ca0fd7933a2e00cd3ec8f6fed352b2a377f06dcdaaf3281"
|
||||
"checksum term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d168af3930b369cfe245132550579d47dfd873d69470755a19c2c6568dbbd989"
|
||||
"checksum termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
|
||||
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
|
||||
"checksum thread_local 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0694f51610ef7cfac7a1b81de7f1602ee5356e76541bcd62c40e71933338cab1"
|
||||
@@ -2766,7 +2807,6 @@ dependencies = [
|
||||
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
||||
"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
|
||||
"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
|
||||
"checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb"
|
||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||
"checksum untrusted 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "193df64312e3515fd983ded55ad5bcaa7647a035804828ed757e832ce6029ef3"
|
||||
"checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity"
|
||||
version = "1.6.2"
|
||||
version = "1.6.6"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ serde = "0.9"
|
||||
serde_json = "0.9"
|
||||
serde_derive = "0.9"
|
||||
linked-hash-map = "0.3"
|
||||
parity-dapps-glue = "1.4"
|
||||
parity-dapps-glue = "1.7"
|
||||
base32 = "0.3"
|
||||
mime = "0.2"
|
||||
mime_guess = "1.6.1"
|
||||
|
||||
@@ -7,17 +7,17 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
quasi_codegen = { version = "0.11", optional = true }
|
||||
syntex = { version = "0.33", optional = true }
|
||||
quasi_codegen = { version = "0.32", optional = true }
|
||||
syntex = { version = "0.58", optional = true }
|
||||
|
||||
[dependencies]
|
||||
glob = { version = "0.2.11" }
|
||||
mime_guess = { version = "1.6.1" }
|
||||
aster = { version = "0.17", default-features = false }
|
||||
quasi = { version = "0.11", default-features = false }
|
||||
quasi_macros = { version = "0.11", optional = true }
|
||||
syntex = { version = "0.33", optional = true }
|
||||
syntex_syntax = { version = "0.33", optional = true }
|
||||
aster = { version = "0.41", default-features = false }
|
||||
quasi = { version = "0.32", default-features = false }
|
||||
quasi_macros = { version = "0.32", optional = true }
|
||||
syntex = { version = "0.58", optional = true }
|
||||
syntex_syntax = { version = "0.58", optional = true }
|
||||
clippy = { version = "0.0.90", optional = true }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -25,13 +25,11 @@ mod inner {
|
||||
|
||||
pub fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let mut registry = syntex::Registry::new();
|
||||
quasi_codegen::register(&mut registry);
|
||||
|
||||
let src = Path::new("src/lib.rs.in");
|
||||
let dst = Path::new(&out_dir).join("lib.rs");
|
||||
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
quasi_codegen::expand(&src, &dst).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,8 @@ pub mod inner {
|
||||
|
||||
impl fold::Folder for StripAttributeFolder {
|
||||
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaItemKind::List(ref n, _) if n == &"webapp" => { return None; }
|
||||
_ => {}
|
||||
if &*attr.value.name.as_str() == "webapp" {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(attr)
|
||||
|
||||
@@ -22,16 +22,12 @@ use self::mime_guess::guess_mime_type;
|
||||
use std::path::{self, Path, PathBuf};
|
||||
use std::ops::Deref;
|
||||
|
||||
use syntax::ast::{MetaItem, Item};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::ast::{self, MetaItem, Item};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::ptr::P;
|
||||
use syntax::print::pprust::{lit_to_string};
|
||||
use syntax::parse::token::{InternedString};
|
||||
|
||||
use syntax::print::pprust::lit_to_string;
|
||||
use syntax::symbol::InternedString;
|
||||
|
||||
pub fn expand_webapp_implementation(
|
||||
cx: &mut ExtCtxt,
|
||||
@@ -48,7 +44,7 @@ pub fn expand_webapp_implementation(
|
||||
},
|
||||
};
|
||||
let builder = aster::AstBuilder::new().span(span);
|
||||
implement_webapp(cx, &builder, &item, push);
|
||||
implement_webapp(cx, &builder, item, push);
|
||||
}
|
||||
|
||||
fn implement_webapp(cx: &ExtCtxt, builder: &aster::AstBuilder, item: &Item, push: &mut FnMut(Annotatable)) {
|
||||
@@ -117,11 +113,12 @@ fn implement_webapp(cx: &ExtCtxt, builder: &aster::AstBuilder, item: &Item, push
|
||||
}
|
||||
|
||||
fn extract_path(cx: &ExtCtxt, item: &Item) -> String {
|
||||
for meta_items in item.attrs().iter().filter_map(webapp_meta_items) {
|
||||
for meta_items in item.attrs.iter().filter_map(webapp_meta_items) {
|
||||
for meta_item in meta_items {
|
||||
let is_path = &*meta_item.name.as_str() == "path";
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"path" => {
|
||||
if let Some(s) = get_str_from_lit(cx, name, lit) {
|
||||
ast::MetaItemKind::NameValue(ref lit) if is_path => {
|
||||
if let Some(s) = get_str_from_lit(cx, lit) {
|
||||
return s.deref().to_owned();
|
||||
}
|
||||
},
|
||||
@@ -134,14 +131,32 @@ fn extract_path(cx: &ExtCtxt, item: &Item) -> String {
|
||||
"web".to_owned()
|
||||
}
|
||||
|
||||
fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Option<InternedString> {
|
||||
fn webapp_meta_items(attr: &ast::Attribute) -> Option<Vec<ast::MetaItem>> {
|
||||
let is_webapp = &*attr.value.name.as_str() == "webapp";
|
||||
match attr.value.node {
|
||||
ast::MetaItemKind::List(ref items) if is_webapp => {
|
||||
attr::mark_used(&attr);
|
||||
Some(
|
||||
items.iter()
|
||||
.map(|item| item.node.clone())
|
||||
.filter_map(|item| match item {
|
||||
ast::NestedMetaItemKind::MetaItem(item) => Some(item),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_str_from_lit(cx: &ExtCtxt, lit: &ast::Lit) -> Option<InternedString> {
|
||||
match lit.node {
|
||||
ast::LitKind::Str(ref s, _) => Some(s.clone()),
|
||||
ast::LitKind::Str(ref s, _) => Some(s.clone().as_str()),
|
||||
_ => {
|
||||
cx.span_err(
|
||||
lit.span,
|
||||
&format!("webapp annotation `{}` must be a string, not `{}`",
|
||||
name,
|
||||
&format!("webapp annotation path must be a string, not `{}`",
|
||||
lit_to_string(lit)
|
||||
)
|
||||
);
|
||||
@@ -150,16 +165,6 @@ fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Option<Interned
|
||||
}
|
||||
}
|
||||
|
||||
fn webapp_meta_items(attr: &ast::Attribute) -> Option<&[P<ast::MetaItem>]> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaItemKind::List(ref name, ref items) if name == &"webapp" => {
|
||||
attr::mark_used(&attr);
|
||||
Some(items)
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn as_uri(path: &Path) -> String {
|
||||
let mut s = String::new();
|
||||
for component in path.iter() {
|
||||
@@ -169,7 +174,6 @@ fn as_uri(path: &Path) -> String {
|
||||
s[0..s.len()-1].into()
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn should_convert_path_separators_on_all_platforms() {
|
||||
// given
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
extern crate syntex;
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
#[macro_use]
|
||||
extern crate syntex_syntax as syntax;
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
|
||||
@@ -27,6 +27,7 @@ byteorder = "1.0"
|
||||
transient-hashmap = "0.1"
|
||||
linked-hash-map = "0.3.0"
|
||||
lru-cache = "0.1.0"
|
||||
itertools = "0.5"
|
||||
ethabi = "1.0.0"
|
||||
evmjit = { path = "../evmjit", optional = true }
|
||||
clippy = { version = "0.0.103", optional = true}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x",
|
||||
"gasLimit": "0x2fefd8"
|
||||
"gasLimit": "0x222222"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
||||
@@ -53,7 +53,9 @@
|
||||
"enode://5fbfb426fbb46f8b8c1bd3dd140f5b511da558cd37d60844b525909ab82e13a25ee722293c829e52cb65c2305b1637fa9a2ea4d6634a224d5f400bfe244ac0de@162.243.55.45:30303",
|
||||
"enode://42d8f29d1db5f4b2947cd5c3d76c6d0d3697e6b9b3430c3d41e46b4bb77655433aeedc25d4b4ea9d8214b6a43008ba67199374a9b53633301bca0cd20c6928ab@104.155.176.151:30303",
|
||||
"enode://814920f1ec9510aa9ea1c8f79d8b6e6a462045f09caa2ae4055b0f34f7416fca6facd3dd45f1cf1673c0209e0503f02776b8ff94020e98b6679a0dc561b4eba0@104.154.136.117:30303",
|
||||
"enode://72e445f4e89c0f476d404bc40478b0df83a5b500d2d2e850e08eb1af0cd464ab86db6160d0fde64bd77d5f0d33507ae19035671b3c74fec126d6e28787669740@104.198.71.200:30303"
|
||||
"enode://72e445f4e89c0f476d404bc40478b0df83a5b500d2d2e850e08eb1af0cd464ab86db6160d0fde64bd77d5f0d33507ae19035671b3c74fec126d6e28787669740@104.198.71.200:30303",
|
||||
"enode://39abab9d2a41f53298c0c9dc6bbca57b0840c3ba9dccf42aa27316addc1b7e56ade32a0a9f7f52d6c5db4fe74d8824bcedfeaecf1a4e533cacb71cf8100a9442@144.76.238.49:30303",
|
||||
"enode://f50e675a34f471af2438b921914b5f06499c7438f3146f6b8936f1faeb50b8a91d0d0c24fb05a66f05865cd58c24da3e664d0def806172ddd0d4c5bdbf37747e@144.76.238.49:30306"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
||||
@@ -23,14 +23,17 @@
|
||||
|
||||
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validateScoreTransition": 1000000,
|
||||
"eip155Transition": 1000000
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x2A"
|
||||
"networkID" : "0x2A",
|
||||
"validateReceiptsTransition" : 1000000
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x3",
|
||||
"forkBlock": 333922,
|
||||
"forkCanonHash": "0x8737eb141d4f05db57af63fc8d3b4d4d8f9cddb0c4e1ab855de8c288fdc1924f",
|
||||
"forkBlock": 641350,
|
||||
"forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb",
|
||||
"eip98Transition": "0x7fffffffffffff"
|
||||
},
|
||||
"genesis": {
|
||||
@@ -44,11 +44,8 @@
|
||||
"gasLimit": "0x1000000"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://a22f0977ce02653bf95e38730106356342df48b5222e2c2a1a6f9ef34769bf593bae9ca0a888cf60839edd52efc1b6e393c63a57d76f4c4fe14e641f1f9e637e@128.199.55.137:30303",
|
||||
"enode://012239fccf3ff1d92b036983a430cb6705c6528c96c0354413f8854802138e5135c084ab36e7c54efb621c46728df8c3a6f4c1db9bb48a1330efe3f82f2dd7a6@52.169.94.142:30303",
|
||||
"enode://1462682e4b7ba2258346d55e25e5b9d264b0db40cee12bdfba4e72b1d7050350ea954c006e9106dd96a128e6e0bd6dffb17eed51f9f99bf7f9cdadfeaf8da4ff@51.15.61.253:30303",
|
||||
"enode://98fbb020c799ae39a828bd75dc2bd5d4721539faf317076b275f91182a5c8900b592e8abfdddceae674a7c3bb40ea00a6ca9ccb7805ab58c4b7b29c61c8f7239@51.15.62.44:30303",
|
||||
"enode://d801dd4e3d15a8bf785931add164bd9c313e3f6b5749d9302b311f2b48064cba5c86c32b1302c27cd983fc89ae07d4d306dd1197610835b8782e95dfb1b3f9ea@51.15.43.255:30303"
|
||||
"enode://20c9ad97c081d63397d7b685a412227a40e23c8bdc6688c6f37e97cfbc22d2b4d1db1510d8f61e6a8866ad7f0e17c02b14182d37ea7c3c8b9c2683aeb6b733a1@52.169.14.227:30303",
|
||||
"enode://6ce05930c72abc632c58e2e4324f7c7ea478cec0ed4fa2528982cf34483094e9cbc9216e7aa349691242576d552a2a56aaeae426c5303ded677ce455ba1acd9d@13.84.180.240:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "0", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"eip98Transition": "0x7fffffffffffffff",
|
||||
"accountStartNonce": "0x00",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x",
|
||||
"gasLimit": "0x2fefd8"
|
||||
"gasLimit": "0x222222"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x",
|
||||
"gasLimit": "0x2fefd8"
|
||||
"gasLimit": "0x222222"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
||||
42
ethcore/res/validator_multi.json
Normal file
42
ethcore/res/validator_multi.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "TestMutiValidator",
|
||||
"engine": {
|
||||
"basicAuthority": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"durationLimit": "0x0d",
|
||||
"validators": {
|
||||
"multi": {
|
||||
"0": { "list": ["0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1"] },
|
||||
"2": { "list": ["0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"accountStartNonce": "0x0",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x69"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"generic": "0xc180"
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x",
|
||||
"gasLimit": "0x2fefd8"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { "balance": "99999999999999999999999" },
|
||||
"0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "99999999999999999999999" }
|
||||
}
|
||||
}
|
||||
@@ -493,6 +493,16 @@ impl LockedBlock {
|
||||
_ => Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes }),
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove state root from transaction receipts to make them EIP-98 compatible.
|
||||
pub fn strip_receipts(self) -> LockedBlock {
|
||||
let mut block = self;
|
||||
for receipt in &mut block.block.receipts {
|
||||
receipt.state_root = None;
|
||||
}
|
||||
block.block.header.set_receipts_root(ordered_trie_root(block.block.receipts.iter().map(|r| r.rlp_bytes().to_vec())));
|
||||
block
|
||||
}
|
||||
}
|
||||
|
||||
impl Drain for LockedBlock {
|
||||
@@ -553,7 +563,6 @@ pub fn enact(
|
||||
b.set_extra_data(header.extra_data().clone()).unwrap_or_else(|e| warn!("Couldn't set extradata: {}. Ignoring.", e));
|
||||
b.set_uncles_hash(header.uncles_hash().clone());
|
||||
b.set_transactions_root(header.transactions_root().clone());
|
||||
b.set_receipts_root(header.receipts_root().clone());
|
||||
|
||||
push_transactions(&mut b, transactions)?;
|
||||
for u in uncles {
|
||||
|
||||
@@ -253,7 +253,7 @@ impl Client {
|
||||
if let Some(reg_addr) = client.additional_params().get("registrar").and_then(|s| Address::from_str(s).ok()) {
|
||||
trace!(target: "client", "Found registrar at {}", reg_addr);
|
||||
let weak = Arc::downgrade(&client);
|
||||
let registrar = Registry::new(reg_addr, move |a, d| weak.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d)));
|
||||
let registrar = Registry::new(reg_addr, move |a, d| weak.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d)));
|
||||
*client.registrar.lock() = Some(registrar);
|
||||
}
|
||||
Ok(client)
|
||||
@@ -375,10 +375,14 @@ impl Client {
|
||||
let db = self.state_db.lock().boxed_clone_canon(header.parent_hash());
|
||||
|
||||
let enact_result = enact_verified(block, engine, self.tracedb.read().tracing_enabled(), db, &parent, last_hashes, self.factories.clone());
|
||||
let locked_block = enact_result.map_err(|e| {
|
||||
let mut locked_block = enact_result.map_err(|e| {
|
||||
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
})?;
|
||||
|
||||
if header.number() < self.engine().params().validate_receipts_transition && header.receipts_root() != locked_block.block().header().receipts_root() {
|
||||
locked_block = locked_block.strip_receipts();
|
||||
}
|
||||
|
||||
// Final Verification
|
||||
if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header()) {
|
||||
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
@@ -1445,7 +1449,7 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
}
|
||||
|
||||
fn call_contract(&self, address: Address, data: Bytes) -> Result<Bytes, String> {
|
||||
fn call_contract(&self, block_id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String> {
|
||||
let from = Address::default();
|
||||
let transaction = Transaction {
|
||||
nonce: self.latest_nonce(&from),
|
||||
@@ -1456,7 +1460,7 @@ impl BlockChainClient for Client {
|
||||
data: data,
|
||||
}.fake_sign(from);
|
||||
|
||||
self.call(&transaction, BlockId::Latest, Default::default())
|
||||
self.call(&transaction, block_id, Default::default())
|
||||
.map_err(|e| format!("{:?}", e))
|
||||
.map(|executed| {
|
||||
executed.output
|
||||
|
||||
@@ -731,7 +731,7 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
}
|
||||
}
|
||||
|
||||
fn call_contract(&self, _address: Address, _data: Bytes) -> Result<Bytes, String> { Ok(vec![]) }
|
||||
fn call_contract(&self, _id: BlockId, _address: Address, _data: Bytes) -> Result<Bytes, String> { Ok(vec![]) }
|
||||
|
||||
fn transact_contract(&self, address: Address, data: Bytes) -> Result<TransactionImportResult, EthcoreError> {
|
||||
let transaction = Transaction {
|
||||
|
||||
@@ -254,7 +254,7 @@ pub trait BlockChainClient : Sync + Send {
|
||||
fn pruning_info(&self) -> PruningInfo;
|
||||
|
||||
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
|
||||
fn call_contract(&self, address: Address, data: Bytes) -> Result<Bytes, String>;
|
||||
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String>;
|
||||
|
||||
/// Import a transaction: used for misbehaviour reporting.
|
||||
fn transact_contract(&self, address: Address, data: Bytes) -> Result<TransactionImportResult, EthcoreError>;
|
||||
|
||||
@@ -27,12 +27,13 @@ use block::*;
|
||||
use spec::CommonParams;
|
||||
use engines::{Engine, Seal, EngineError};
|
||||
use header::Header;
|
||||
use error::{Error, BlockError};
|
||||
use error::{Error, TransactionError, BlockError};
|
||||
use evm::Schedule;
|
||||
use ethjson;
|
||||
use io::{IoContext, IoHandler, TimerToken, IoService};
|
||||
use env_info::EnvInfo;
|
||||
use builtin::Builtin;
|
||||
use transaction::UnverifiedTransaction;
|
||||
use client::{Client, EngineClient};
|
||||
use state::CleanupMode;
|
||||
use super::signer::EngineSigner;
|
||||
@@ -53,6 +54,10 @@ pub struct AuthorityRoundParams {
|
||||
pub start_step: Option<u64>,
|
||||
/// Valid validators.
|
||||
pub validators: ethjson::spec::ValidatorSet,
|
||||
/// Chain score validation transition block.
|
||||
pub validate_score_transition: u64,
|
||||
/// Number of first block where EIP-155 rules are validated.
|
||||
pub eip155_transition: u64,
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
@@ -64,6 +69,8 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
|
||||
registrar: p.registrar.map_or_else(Address::new, Into::into),
|
||||
start_step: p.start_step.map(Into::into),
|
||||
validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
|
||||
eip155_transition: p.eip155_transition.map_or(0, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,9 +89,11 @@ pub struct AuthorityRound {
|
||||
proposed: AtomicBool,
|
||||
client: RwLock<Option<Weak<EngineClient>>>,
|
||||
signer: EngineSigner,
|
||||
validators: Box<ValidatorSet + Send + Sync>,
|
||||
validators: Box<ValidatorSet>,
|
||||
/// Is this Engine just for testing (prevents step calibration).
|
||||
calibrate_step: bool,
|
||||
validate_score_transition: u64,
|
||||
eip155_transition: u64,
|
||||
}
|
||||
|
||||
fn header_step(header: &Header) -> Result<usize, ::rlp::DecoderError> {
|
||||
@@ -125,6 +134,8 @@ impl AuthorityRound {
|
||||
signer: Default::default(),
|
||||
validators: new_validator_set(our_params.validators),
|
||||
calibrate_step: our_params.start_step.is_none(),
|
||||
validate_score_transition: our_params.validate_score_transition,
|
||||
eip155_transition: our_params.eip155_transition,
|
||||
});
|
||||
// Do not initialize timeouts for tests.
|
||||
if should_timeout {
|
||||
@@ -150,12 +161,12 @@ impl AuthorityRound {
|
||||
}
|
||||
}
|
||||
|
||||
fn step_proposer(&self, step: usize) -> Address {
|
||||
self.validators.get(step)
|
||||
fn step_proposer(&self, bh: &H256, step: usize) -> Address {
|
||||
self.validators.get(bh, step)
|
||||
}
|
||||
|
||||
fn is_step_proposer(&self, step: usize, address: &Address) -> bool {
|
||||
self.step_proposer(step) == *address
|
||||
fn is_step_proposer(&self, bh: &H256, step: usize, address: &Address) -> bool {
|
||||
self.step_proposer(bh, step) == *address
|
||||
}
|
||||
|
||||
fn is_future_step(&self, step: usize) -> bool {
|
||||
@@ -249,7 +260,7 @@ impl Engine for AuthorityRound {
|
||||
}
|
||||
|
||||
fn seals_internally(&self) -> Option<bool> {
|
||||
Some(self.validators.contains(&self.signer.address()))
|
||||
Some(self.signer.address() != Address::default())
|
||||
}
|
||||
|
||||
/// Attempt to seal the block internally.
|
||||
@@ -260,7 +271,7 @@ impl Engine for AuthorityRound {
|
||||
if self.proposed.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
||||
let header = block.header();
|
||||
let step = self.step.load(AtomicOrdering::SeqCst);
|
||||
if self.is_step_proposer(step, header.author()) {
|
||||
if self.is_step_proposer(header.parent_hash(), step, header.author()) {
|
||||
if let Ok(signature) = self.signer.sign(header.bare_hash()) {
|
||||
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
|
||||
self.proposed.store(true, AtomicOrdering::SeqCst);
|
||||
@@ -294,39 +305,45 @@ impl Engine for AuthorityRound {
|
||||
Err(From::from(BlockError::InvalidSealArity(
|
||||
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
|
||||
)))
|
||||
} else if header.number() >= self.validate_score_transition && *header.difficulty() >= U256::from(U128::max_value()) {
|
||||
Err(From::from(BlockError::DifficultyOutOfBounds(
|
||||
OutOfBounds { min: None, max: Some(U256::from(U128::max_value())), found: *header.difficulty() }
|
||||
)))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the signature belongs to the correct proposer.
|
||||
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
let header_step = header_step(header)?;
|
||||
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Do the validator and gas limit validation.
|
||||
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
let step = header_step(header)?;
|
||||
// Give one step slack if step is lagging, double vote is still not possible.
|
||||
if self.is_future_step(header_step) {
|
||||
if self.is_future_step(step) {
|
||||
trace!(target: "engine", "verify_block_unordered: block from the future");
|
||||
self.validators.report_benign(header.author());
|
||||
Err(BlockError::InvalidSeal)?
|
||||
} else {
|
||||
// Check if the signature belongs to a validator, can depend on parent state.
|
||||
let proposer_signature = header_signature(header)?;
|
||||
let correct_proposer = self.step_proposer(header_step);
|
||||
if verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())? {
|
||||
Ok(())
|
||||
} else {
|
||||
trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", header_step);
|
||||
let correct_proposer = self.step_proposer(header.parent_hash(), step);
|
||||
if !verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())? {
|
||||
trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", step);
|
||||
Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
// Do not calculate difficulty for genesis blocks.
|
||||
if header.number() == 0 {
|
||||
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
|
||||
}
|
||||
|
||||
let step = header_step(header)?;
|
||||
// Check if parent is from a previous step.
|
||||
if step == header_step(parent)? {
|
||||
let parent_step = header_step(parent)?;
|
||||
if step == parent_step {
|
||||
trace!(target: "engine", "Multiple blocks proposed for step {}.", step);
|
||||
self.validators.report_malicious(header.author());
|
||||
Err(EngineError::DoubleVote(header.author().clone()))?;
|
||||
@@ -341,6 +358,18 @@ impl Engine for AuthorityRound {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> {
|
||||
t.check_low_s()?;
|
||||
|
||||
if let Some(n) = t.network_id() {
|
||||
if header.number() >= self.eip155_transition && n != self.params().chain_id {
|
||||
return Err(TransactionError::InvalidNetworkId.into());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register_client(&self, client: Weak<Client>) {
|
||||
*self.client.write() = Some(client.clone());
|
||||
self.validators.register_contract(client);
|
||||
@@ -412,7 +441,7 @@ mod tests {
|
||||
let mut header: Header = Header::default();
|
||||
header.set_seal(vec![encode(&H520::default()).to_vec()]);
|
||||
|
||||
let verify_result = engine.verify_block_unordered(&header, None);
|
||||
let verify_result = engine.verify_block_family(&header, &Default::default(), None);
|
||||
assert!(verify_result.is_err());
|
||||
}
|
||||
|
||||
@@ -450,10 +479,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn proposer_switching() {
|
||||
let mut header: Header = Header::default();
|
||||
let tap = AccountProvider::transient_provider();
|
||||
let addr = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "0").unwrap();
|
||||
|
||||
let mut parent_header: Header = Header::default();
|
||||
parent_header.set_seal(vec![encode(&0usize).to_vec()]);
|
||||
parent_header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
let mut header: Header = Header::default();
|
||||
header.set_number(1);
|
||||
header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
header.set_author(addr);
|
||||
|
||||
let engine = Spec::new_test_round().engine;
|
||||
@@ -462,17 +495,22 @@ mod tests {
|
||||
// Two validators.
|
||||
// Spec starts with step 2.
|
||||
header.set_seal(vec![encode(&2usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||
assert!(engine.verify_block_seal(&header).is_err());
|
||||
assert!(engine.verify_block_family(&header, &parent_header, None).is_err());
|
||||
header.set_seal(vec![encode(&1usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||
assert!(engine.verify_block_seal(&header).is_ok());
|
||||
assert!(engine.verify_block_family(&header, &parent_header, None).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_future_block() {
|
||||
let mut header: Header = Header::default();
|
||||
let tap = AccountProvider::transient_provider();
|
||||
let addr = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "0").unwrap();
|
||||
|
||||
let mut parent_header: Header = Header::default();
|
||||
parent_header.set_seal(vec![encode(&0usize).to_vec()]);
|
||||
parent_header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
let mut header: Header = Header::default();
|
||||
header.set_number(1);
|
||||
header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
header.set_author(addr);
|
||||
|
||||
let engine = Spec::new_test_round().engine;
|
||||
@@ -481,8 +519,8 @@ mod tests {
|
||||
// Two validators.
|
||||
// Spec starts with step 2.
|
||||
header.set_seal(vec![encode(&1usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||
assert!(engine.verify_block_seal(&header).is_ok());
|
||||
assert!(engine.verify_block_family(&header, &parent_header, None).is_ok());
|
||||
header.set_seal(vec![encode(&5usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||
assert!(engine.verify_block_seal(&header).is_err());
|
||||
assert!(engine.verify_block_family(&header, &parent_header, None).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ pub struct BasicAuthority {
|
||||
gas_limit_bound_divisor: U256,
|
||||
builtins: BTreeMap<Address, Builtin>,
|
||||
signer: EngineSigner,
|
||||
validators: Box<ValidatorSet + Send + Sync>,
|
||||
validators: Box<ValidatorSet>,
|
||||
}
|
||||
|
||||
impl BasicAuthority {
|
||||
@@ -104,14 +104,14 @@ impl Engine for BasicAuthority {
|
||||
}
|
||||
|
||||
fn seals_internally(&self) -> Option<bool> {
|
||||
Some(self.validators.contains(&self.signer.address()))
|
||||
Some(self.signer.address() != Address::default())
|
||||
}
|
||||
|
||||
/// Attempt to seal the block internally.
|
||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||
let header = block.header();
|
||||
let author = header.author();
|
||||
if self.validators.contains(author) {
|
||||
if self.validators.contains(header.parent_hash(), author) {
|
||||
// account should be pernamently unlocked, otherwise sealing will fail
|
||||
if let Ok(signature) = self.signer.sign(header.bare_hash()) {
|
||||
return Seal::Regular(vec![::rlp::encode(&(&H520::from(signature) as &[u8])).to_vec()]);
|
||||
@@ -133,20 +133,20 @@ impl Engine for BasicAuthority {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
||||
use rlp::{UntrustedRlp, View};
|
||||
|
||||
// check the signature is legit.
|
||||
let sig = UntrustedRlp::new(&header.seal()[0]).as_val::<H520>()?;
|
||||
let signer = public_to_address(&recover(&sig.into(), &header.bare_hash())?);
|
||||
if !self.validators.contains(&signer) {
|
||||
return Err(BlockError::InvalidSeal)?;
|
||||
}
|
||||
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
||||
// we should not calculate difficulty for genesis blocks
|
||||
use rlp::{UntrustedRlp, View};
|
||||
// Check if the signature belongs to a validator, can depend on parent state.
|
||||
let sig = UntrustedRlp::new(&header.seal()[0]).as_val::<H520>()?;
|
||||
let signer = public_to_address(&recover(&sig.into(), &header.bare_hash())?);
|
||||
if !self.validators.contains(header.parent_hash(), &signer) {
|
||||
return Err(BlockError::InvalidSeal)?;
|
||||
}
|
||||
|
||||
// Do not calculate difficulty for genesis blocks.
|
||||
if header.number() == 0 {
|
||||
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
|
||||
}
|
||||
@@ -239,7 +239,7 @@ mod tests {
|
||||
let mut header: Header = Header::default();
|
||||
header.set_seal(vec![::rlp::encode(&H520::default()).to_vec()]);
|
||||
|
||||
let verify_result = engine.verify_block_unordered(&header, None);
|
||||
let verify_result = engine.verify_block_family(&header, &Default::default(), None);
|
||||
assert!(verify_result.is_err());
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ use account_provider::AccountProvider;
|
||||
use block::ExecutedBlock;
|
||||
use builtin::Builtin;
|
||||
use env_info::EnvInfo;
|
||||
use error::Error;
|
||||
use error::{Error, TransactionError};
|
||||
use spec::CommonParams;
|
||||
use evm::Schedule;
|
||||
use header::Header;
|
||||
@@ -157,6 +157,13 @@ pub trait Engine : Sync + Send {
|
||||
// TODO: consider including State in the params.
|
||||
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> {
|
||||
t.check_low_s()?;
|
||||
|
||||
if let Some(n) = t.network_id() {
|
||||
if n != self.params().chain_id {
|
||||
return Err(TransactionError::InvalidNetworkId.into());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -95,8 +95,10 @@ pub struct Tendermint {
|
||||
last_lock: AtomicUsize,
|
||||
/// Bare hash of the proposed block, used for seal submission.
|
||||
proposal: RwLock<Option<H256>>,
|
||||
/// Hash of the proposal parent block.
|
||||
proposal_parent: RwLock<H256>,
|
||||
/// Set used to determine the current validators.
|
||||
validators: Box<ValidatorSet + Send + Sync>,
|
||||
validators: Box<ValidatorSet>,
|
||||
}
|
||||
|
||||
impl Tendermint {
|
||||
@@ -114,11 +116,12 @@ impl Tendermint {
|
||||
height: AtomicUsize::new(1),
|
||||
view: AtomicUsize::new(0),
|
||||
step: RwLock::new(Step::Propose),
|
||||
votes: VoteCollector::default(),
|
||||
votes: Default::default(),
|
||||
signer: Default::default(),
|
||||
lock_change: RwLock::new(None),
|
||||
last_lock: AtomicUsize::new(0),
|
||||
proposal: RwLock::new(None),
|
||||
proposal_parent: Default::default(),
|
||||
validators: new_validator_set(our_params.validators),
|
||||
});
|
||||
let handler = TransitionHandler::new(Arc::downgrade(&engine) as Weak<Engine>, Box::new(our_params.timeouts));
|
||||
@@ -232,7 +235,7 @@ impl Tendermint {
|
||||
let height = self.height.load(AtomicOrdering::SeqCst);
|
||||
if let Some(block_hash) = *self.proposal.read() {
|
||||
// Generate seal and remove old votes.
|
||||
if self.is_signer_proposer() {
|
||||
if self.is_signer_proposer(&*self.proposal_parent.read()) {
|
||||
let proposal_step = VoteStep::new(height, view, Step::Propose);
|
||||
let precommit_step = VoteStep::new(proposal_step.height, proposal_step.view, Step::Precommit);
|
||||
if let Some(seal) = self.votes.seal_signatures(proposal_step, precommit_step, &block_hash) {
|
||||
@@ -254,23 +257,23 @@ impl Tendermint {
|
||||
}
|
||||
|
||||
fn is_authority(&self, address: &Address) -> bool {
|
||||
self.validators.contains(address)
|
||||
self.validators.contains(&*self.proposal_parent.read(), address)
|
||||
}
|
||||
|
||||
fn is_above_threshold(&self, n: usize) -> bool {
|
||||
n > self.validators.count() * 2/3
|
||||
n > self.validators.count(&*self.proposal_parent.read()) * 2/3
|
||||
}
|
||||
|
||||
/// Find the designated for the given view.
|
||||
fn view_proposer(&self, height: Height, view: View) -> Address {
|
||||
fn view_proposer(&self, bh: &H256, height: Height, view: View) -> Address {
|
||||
let proposer_nonce = height + view;
|
||||
trace!(target: "engine", "Proposer nonce: {}", proposer_nonce);
|
||||
self.validators.get(proposer_nonce)
|
||||
self.validators.get(bh, proposer_nonce)
|
||||
}
|
||||
|
||||
/// Check if address is a proposer for given view.
|
||||
fn is_view_proposer(&self, height: Height, view: View, address: &Address) -> Result<(), EngineError> {
|
||||
let proposer = self.view_proposer(height, view);
|
||||
fn is_view_proposer(&self, bh: &H256, height: Height, view: View, address: &Address) -> Result<(), EngineError> {
|
||||
let proposer = self.view_proposer(bh, height, view);
|
||||
if proposer == *address {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -279,8 +282,8 @@ impl Tendermint {
|
||||
}
|
||||
|
||||
/// Check if current signer is the current proposer.
|
||||
fn is_signer_proposer(&self) -> bool {
|
||||
let proposer = self.view_proposer(self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst));
|
||||
fn is_signer_proposer(&self, bh: &H256) -> bool {
|
||||
let proposer = self.view_proposer(bh, self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst));
|
||||
self.signer.is_address(&proposer)
|
||||
}
|
||||
|
||||
@@ -419,7 +422,7 @@ impl Engine for Tendermint {
|
||||
|
||||
/// Should this node participate.
|
||||
fn seals_internally(&self) -> Option<bool> {
|
||||
Some(self.is_authority(&self.signer.address()))
|
||||
Some(self.signer.address() != Address::default())
|
||||
}
|
||||
|
||||
/// Attempt to seal generate a proposal seal.
|
||||
@@ -427,7 +430,7 @@ impl Engine for Tendermint {
|
||||
let header = block.header();
|
||||
let author = header.author();
|
||||
// Only proposer can generate seal if None was generated.
|
||||
if !self.is_signer_proposer() || self.proposal.read().is_some() {
|
||||
if !self.is_signer_proposer(header.parent_hash()) || self.proposal.read().is_some() {
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
@@ -441,6 +444,7 @@ impl Engine for Tendermint {
|
||||
self.votes.vote(ConsensusMessage::new(signature, height, view, Step::Propose, bh), author);
|
||||
// Remember proposal for later seal submission.
|
||||
*self.proposal.write() = bh;
|
||||
*self.proposal_parent.write() = header.parent_hash().clone();
|
||||
Seal::Proposal(vec![
|
||||
::rlp::encode(&view).to_vec(),
|
||||
::rlp::encode(&signature).to_vec(),
|
||||
@@ -505,7 +509,12 @@ impl Engine for Tendermint {
|
||||
|
||||
}
|
||||
|
||||
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Verify validators and gas limit.
|
||||
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
let proposal = ConsensusMessage::new_proposal(header)?;
|
||||
let proposer = proposal.verify()?;
|
||||
if !self.is_authority(&proposer) {
|
||||
@@ -522,7 +531,7 @@ impl Engine for Tendermint {
|
||||
Some(a) => a,
|
||||
None => public_to_address(&recover(&precommit.signature.into(), &precommit_hash)?),
|
||||
};
|
||||
if !self.validators.contains(&address) {
|
||||
if !self.validators.contains(header.parent_hash(), &address) {
|
||||
Err(EngineError::NotAuthorized(address.to_owned()))?
|
||||
}
|
||||
|
||||
@@ -545,12 +554,9 @@ impl Engine for Tendermint {
|
||||
found: signatures_len
|
||||
}))?;
|
||||
}
|
||||
self.is_view_proposer(proposal.vote_step.height, proposal.vote_step.view, &proposer)?;
|
||||
self.is_view_proposer(header.parent_hash(), proposal.vote_step.height, proposal.vote_step.view, &proposer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
if header.number() == 0 {
|
||||
Err(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))?;
|
||||
}
|
||||
@@ -595,6 +601,7 @@ impl Engine for Tendermint {
|
||||
debug!(target: "engine", "Received a new proposal {:?} from {}.", proposal.vote_step, proposer);
|
||||
if self.is_view(&proposal) {
|
||||
*self.proposal.write() = proposal.block_hash.clone();
|
||||
*self.proposal_parent.write() = header.parent_hash().clone();
|
||||
}
|
||||
self.votes.vote(proposal, &proposer);
|
||||
true
|
||||
@@ -607,7 +614,7 @@ impl Engine for Tendermint {
|
||||
trace!(target: "engine", "Propose timeout.");
|
||||
if self.proposal.read().is_none() {
|
||||
// Report the proposer if no proposal was received.
|
||||
let current_proposer = self.view_proposer(self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst));
|
||||
let current_proposer = self.view_proposer(&*self.proposal_parent.read(), self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst));
|
||||
self.validators.report_benign(¤t_proposer);
|
||||
}
|
||||
Step::Prevote
|
||||
@@ -765,20 +772,25 @@ mod tests {
|
||||
let (spec, tap) = setup();
|
||||
let engine = spec.engine;
|
||||
|
||||
let mut header = Header::default();
|
||||
let validator = insert_and_unlock(&tap, "0");
|
||||
header.set_author(validator);
|
||||
let seal = proposal_seal(&tap, &header, 0);
|
||||
header.set_seal(seal);
|
||||
// Good proposer.
|
||||
assert!(engine.verify_block_unordered(&header.clone(), None).is_ok());
|
||||
let mut parent_header: Header = Header::default();
|
||||
parent_header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
|
||||
let mut header = Header::default();
|
||||
header.set_number(1);
|
||||
header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
let validator = insert_and_unlock(&tap, "1");
|
||||
header.set_author(validator);
|
||||
let seal = proposal_seal(&tap, &header, 0);
|
||||
header.set_seal(seal);
|
||||
// Good proposer.
|
||||
assert!(engine.verify_block_family(&header, &parent_header, None).is_ok());
|
||||
|
||||
let validator = insert_and_unlock(&tap, "0");
|
||||
header.set_author(validator);
|
||||
let seal = proposal_seal(&tap, &header, 0);
|
||||
header.set_seal(seal);
|
||||
// Bad proposer.
|
||||
match engine.verify_block_unordered(&header, None) {
|
||||
match engine.verify_block_family(&header, &parent_header, None) {
|
||||
Err(Error::Engine(EngineError::NotProposer(_))) => {},
|
||||
_ => panic!(),
|
||||
}
|
||||
@@ -788,7 +800,7 @@ mod tests {
|
||||
let seal = proposal_seal(&tap, &header, 0);
|
||||
header.set_seal(seal);
|
||||
// Not authority.
|
||||
match engine.verify_block_unordered(&header, None) {
|
||||
match engine.verify_block_family(&header, &parent_header, None) {
|
||||
Err(Error::Engine(EngineError::NotAuthorized(_))) => {},
|
||||
_ => panic!(),
|
||||
};
|
||||
@@ -800,19 +812,24 @@ mod tests {
|
||||
let (spec, tap) = setup();
|
||||
let engine = spec.engine;
|
||||
|
||||
let mut parent_header: Header = Header::default();
|
||||
parent_header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
|
||||
let mut header = Header::default();
|
||||
header.set_number(2);
|
||||
header.set_gas_limit(U256::from_str("222222").unwrap());
|
||||
let proposer = insert_and_unlock(&tap, "1");
|
||||
header.set_author(proposer);
|
||||
let mut seal = proposal_seal(&tap, &header, 0);
|
||||
|
||||
let vote_info = message_info_rlp(&VoteStep::new(0, 0, Step::Precommit), Some(header.bare_hash()));
|
||||
let vote_info = message_info_rlp(&VoteStep::new(2, 0, Step::Precommit), Some(header.bare_hash()));
|
||||
let signature1 = tap.sign(proposer, None, vote_info.sha3()).unwrap();
|
||||
|
||||
seal[2] = ::rlp::encode(&vec![H520::from(signature1.clone())]).to_vec();
|
||||
header.set_seal(seal.clone());
|
||||
|
||||
// One good signature is not enough.
|
||||
match engine.verify_block_unordered(&header, None) {
|
||||
match engine.verify_block_family(&header, &parent_header, None) {
|
||||
Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {},
|
||||
_ => panic!(),
|
||||
}
|
||||
@@ -823,7 +840,7 @@ mod tests {
|
||||
seal[2] = ::rlp::encode(&vec![H520::from(signature1.clone()), H520::from(signature0.clone())]).to_vec();
|
||||
header.set_seal(seal.clone());
|
||||
|
||||
assert!(engine.verify_block_unordered(&header, None).is_ok());
|
||||
assert!(engine.verify_block_family(&header, &parent_header, None).is_ok());
|
||||
|
||||
let bad_voter = insert_and_unlock(&tap, "101");
|
||||
let bad_signature = tap.sign(bad_voter, None, vote_info.sha3()).unwrap();
|
||||
@@ -832,7 +849,7 @@ mod tests {
|
||||
header.set_seal(seal);
|
||||
|
||||
// One good and one bad signature.
|
||||
match engine.verify_block_unordered(&header, None) {
|
||||
match engine.verify_block_family(&header, &parent_header, None) {
|
||||
Err(Error::Engine(EngineError::NotAuthorized(_))) => {},
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
@@ -26,30 +26,30 @@ use super::safe_contract::ValidatorSafeContract;
|
||||
/// The validator contract should have the following interface:
|
||||
/// [{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}]
|
||||
pub struct ValidatorContract {
|
||||
validators: Arc<ValidatorSafeContract>,
|
||||
validators: ValidatorSafeContract,
|
||||
provider: RwLock<Option<provider::Contract>>,
|
||||
}
|
||||
|
||||
impl ValidatorContract {
|
||||
pub fn new(contract_address: Address) -> Self {
|
||||
ValidatorContract {
|
||||
validators: Arc::new(ValidatorSafeContract::new(contract_address)),
|
||||
validators: ValidatorSafeContract::new(contract_address),
|
||||
provider: RwLock::new(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ValidatorSet for Arc<ValidatorContract> {
|
||||
fn contains(&self, address: &Address) -> bool {
|
||||
self.validators.contains(address)
|
||||
impl ValidatorSet for ValidatorContract {
|
||||
fn contains(&self, bh: &H256, address: &Address) -> bool {
|
||||
self.validators.contains(bh, address)
|
||||
}
|
||||
|
||||
fn get(&self, nonce: usize) -> Address {
|
||||
self.validators.get(nonce)
|
||||
fn get(&self, bh: &H256, nonce: usize) -> Address {
|
||||
self.validators.get(bh, nonce)
|
||||
}
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.validators.count()
|
||||
fn count(&self, bh: &H256) -> usize {
|
||||
self.validators.count(bh)
|
||||
}
|
||||
|
||||
fn report_malicious(&self, address: &Address) {
|
||||
@@ -144,6 +144,7 @@ mod tests {
|
||||
use header::Header;
|
||||
use account_provider::AccountProvider;
|
||||
use miner::MinerService;
|
||||
use types::ids::BlockId;
|
||||
use client::BlockChainClient;
|
||||
use tests::helpers::generate_dummy_client_with_spec_and_accounts;
|
||||
use super::super::ValidatorSet;
|
||||
@@ -154,8 +155,9 @@ mod tests {
|
||||
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None);
|
||||
let vc = Arc::new(ValidatorContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap()));
|
||||
vc.register_contract(Arc::downgrade(&client));
|
||||
assert!(vc.contains(&Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()));
|
||||
assert!(vc.contains(&Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap()));
|
||||
let last_hash = client.best_block_header().hash();
|
||||
assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()));
|
||||
assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -171,18 +173,21 @@ mod tests {
|
||||
|
||||
client.miner().set_engine_signer(v1, "".into()).unwrap();
|
||||
let mut header = Header::default();
|
||||
let seal = encode(&vec!(5u8)).to_vec();
|
||||
header.set_seal(vec!(seal));
|
||||
let seal = vec![encode(&5u8).to_vec(), encode(&(&H520::default() as &[u8])).to_vec()];
|
||||
header.set_seal(seal);
|
||||
header.set_author(v1);
|
||||
header.set_number(1);
|
||||
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_unordered(&header, None).is_err());
|
||||
assert!(client.engine().verify_block_family(&header, &header, None).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(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, None).is_err());
|
||||
// Seal a block.
|
||||
client.engine().step();
|
||||
|
||||
@@ -19,31 +19,36 @@
|
||||
mod simple_list;
|
||||
mod safe_contract;
|
||||
mod contract;
|
||||
mod multi;
|
||||
|
||||
use std::sync::Weak;
|
||||
use util::{Address, Arc};
|
||||
use util::{Address, H256};
|
||||
use ethjson::spec::ValidatorSet as ValidatorSpec;
|
||||
use client::Client;
|
||||
use self::simple_list::SimpleList;
|
||||
use self::contract::ValidatorContract;
|
||||
use self::safe_contract::ValidatorSafeContract;
|
||||
use self::multi::Multi;
|
||||
|
||||
/// Creates a validator set from spec.
|
||||
pub fn new_validator_set(spec: ValidatorSpec) -> Box<ValidatorSet + Send + Sync> {
|
||||
pub fn new_validator_set(spec: ValidatorSpec) -> Box<ValidatorSet> {
|
||||
match spec {
|
||||
ValidatorSpec::List(list) => Box::new(SimpleList::new(list.into_iter().map(Into::into).collect())),
|
||||
ValidatorSpec::SafeContract(address) => Box::new(Arc::new(ValidatorSafeContract::new(address.into()))),
|
||||
ValidatorSpec::Contract(address) => Box::new(Arc::new(ValidatorContract::new(address.into()))),
|
||||
ValidatorSpec::SafeContract(address) => Box::new(ValidatorSafeContract::new(address.into())),
|
||||
ValidatorSpec::Contract(address) => Box::new(ValidatorContract::new(address.into())),
|
||||
ValidatorSpec::Multi(sequence) => Box::new(
|
||||
Multi::new(sequence.into_iter().map(|(block, set)| (block.into(), new_validator_set(set))).collect())
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ValidatorSet {
|
||||
pub trait ValidatorSet: Send + Sync {
|
||||
/// Checks if a given address is a validator.
|
||||
fn contains(&self, address: &Address) -> bool;
|
||||
fn contains(&self, parent_block_hash: &H256, address: &Address) -> bool;
|
||||
/// Draws an validator nonce modulo number of validators.
|
||||
fn get(&self, nonce: usize) -> Address;
|
||||
fn get(&self, parent_block_hash: &H256, nonce: usize) -> Address;
|
||||
/// Returns the current number of validators.
|
||||
fn count(&self) -> usize;
|
||||
fn count(&self, parent_block_hash: &H256) -> usize;
|
||||
/// Notifies about malicious behaviour.
|
||||
fn report_malicious(&self, _validator: &Address) {}
|
||||
/// Notifies about benign misbehaviour.
|
||||
|
||||
158
ethcore/src/engines/validator_set/multi.rs
Normal file
158
ethcore/src/engines/validator_set/multi.rs
Normal file
@@ -0,0 +1,158 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/// Validator set changing at fork blocks.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Weak;
|
||||
use util::{H256, Address, RwLock};
|
||||
use ids::BlockId;
|
||||
use header::BlockNumber;
|
||||
use client::{Client, BlockChainClient};
|
||||
use super::ValidatorSet;
|
||||
|
||||
type BlockNumberLookup = Box<Fn(&H256) -> Result<BlockNumber, String> + Send + Sync + 'static>;
|
||||
|
||||
pub struct Multi {
|
||||
sets: BTreeMap<BlockNumber, Box<ValidatorSet>>,
|
||||
block_number: RwLock<BlockNumberLookup>,
|
||||
}
|
||||
|
||||
impl Multi {
|
||||
pub fn new(set_map: BTreeMap<BlockNumber, Box<ValidatorSet>>) -> Self {
|
||||
assert!(set_map.get(&0u64).is_some(), "ValidatorSet has to be specified from block 0.");
|
||||
Multi {
|
||||
sets: set_map,
|
||||
block_number: RwLock::new(Box::new(move |_| Err("No client!".into()))),
|
||||
}
|
||||
}
|
||||
|
||||
fn correct_set(&self, bh: &H256) -> Option<&Box<ValidatorSet>> {
|
||||
match self
|
||||
.block_number
|
||||
.read()(bh)
|
||||
.map(|parent_block| self
|
||||
.sets
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|&(block, _)| *block <= parent_block + 1)
|
||||
.expect("constructor validation ensures that there is at least one validator set for block 0;
|
||||
block 0 is less than any uint;
|
||||
qed")
|
||||
) {
|
||||
Ok((block, set)) => {
|
||||
trace!(target: "engine", "Multi ValidatorSet retrieved for block {}.", block);
|
||||
Some(set)
|
||||
},
|
||||
Err(e) => {
|
||||
debug!(target: "engine", "ValidatorSet could not be recovered: {}", e);
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ValidatorSet for Multi {
|
||||
fn contains(&self, bh: &H256, address: &Address) -> bool {
|
||||
self.correct_set(bh).map_or(false, |set| set.contains(bh, address))
|
||||
}
|
||||
|
||||
fn get(&self, bh: &H256, nonce: usize) -> Address {
|
||||
self.correct_set(bh).map_or_else(Default::default, |set| set.get(bh, nonce))
|
||||
}
|
||||
|
||||
fn count(&self, bh: &H256) -> usize {
|
||||
self.correct_set(bh).map_or_else(usize::max_value, |set| set.count(bh))
|
||||
}
|
||||
|
||||
fn report_malicious(&self, validator: &Address) {
|
||||
for set in self.sets.values() {
|
||||
set.report_malicious(validator);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_benign(&self, validator: &Address) {
|
||||
for set in self.sets.values() {
|
||||
set.report_benign(validator);
|
||||
}
|
||||
}
|
||||
|
||||
fn register_contract(&self, client: Weak<Client>) {
|
||||
for set in self.sets.values() {
|
||||
set.register_contract(client.clone());
|
||||
}
|
||||
*self.block_number.write() = Box::new(move |hash| client
|
||||
.upgrade()
|
||||
.ok_or("No client!".into())
|
||||
.and_then(|c| c.block_number(BlockId::Hash(*hash)).ok_or("Unknown block".into())));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use util::*;
|
||||
use types::ids::BlockId;
|
||||
use spec::Spec;
|
||||
use account_provider::AccountProvider;
|
||||
use client::{BlockChainClient, EngineClient};
|
||||
use ethkey::Secret;
|
||||
use miner::MinerService;
|
||||
use tests::helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data};
|
||||
|
||||
#[test]
|
||||
fn uses_current_set() {
|
||||
::env_logger::init().unwrap();
|
||||
let tap = Arc::new(AccountProvider::transient_provider());
|
||||
let s0 = Secret::from_slice(&"0".sha3()).unwrap();
|
||||
let v0 = tap.insert_account(s0.clone(), "").unwrap();
|
||||
let v1 = tap.insert_account(Secret::from_slice(&"1".sha3()).unwrap(), "").unwrap();
|
||||
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_multi, Some(tap));
|
||||
client.engine().register_client(Arc::downgrade(&client));
|
||||
|
||||
// Make sure txs go through.
|
||||
client.miner().set_gas_floor_target(1_000_000.into());
|
||||
|
||||
// Wrong signer for the first block.
|
||||
client.miner().set_engine_signer(v1, "".into()).unwrap();
|
||||
client.transact_contract(Default::default(), Default::default()).unwrap();
|
||||
client.update_sealing();
|
||||
assert_eq!(client.chain_info().best_block_number, 0);
|
||||
// Right signer for the first block.
|
||||
client.miner().set_engine_signer(v0, "".into()).unwrap();
|
||||
client.update_sealing();
|
||||
assert_eq!(client.chain_info().best_block_number, 1);
|
||||
// This time v0 is wrong.
|
||||
client.transact_contract(Default::default(), Default::default()).unwrap();
|
||||
client.update_sealing();
|
||||
assert_eq!(client.chain_info().best_block_number, 1);
|
||||
client.miner().set_engine_signer(v1, "".into()).unwrap();
|
||||
client.update_sealing();
|
||||
assert_eq!(client.chain_info().best_block_number, 2);
|
||||
// v1 is still good.
|
||||
client.transact_contract(Default::default(), Default::default()).unwrap();
|
||||
client.update_sealing();
|
||||
assert_eq!(client.chain_info().best_block_number, 3);
|
||||
|
||||
// Check syncing.
|
||||
let sync_client = generate_dummy_client_with_spec_and_data(Spec::new_validator_multi, 0, 0, &[]);
|
||||
sync_client.engine().register_client(Arc::downgrade(&sync_client));
|
||||
for i in 1..4 {
|
||||
sync_client.import_block(client.block(BlockId::Number(i)).unwrap().into_inner()).unwrap();
|
||||
}
|
||||
sync_client.flush_queue();
|
||||
assert_eq!(sync_client.chain_info().best_block_number, 3);
|
||||
}
|
||||
}
|
||||
@@ -17,17 +17,23 @@
|
||||
/// Validator set maintained in a contract, updated using `getValidators` method.
|
||||
|
||||
use std::sync::Weak;
|
||||
use ethabi;
|
||||
use util::*;
|
||||
use util::cache::MemoryLruCache;
|
||||
use types::ids::BlockId;
|
||||
use client::{Client, BlockChainClient};
|
||||
use client::chain_notify::ChainNotify;
|
||||
use super::ValidatorSet;
|
||||
use super::simple_list::SimpleList;
|
||||
|
||||
const MEMOIZE_CAPACITY: usize = 500;
|
||||
const CONTRACT_INTERFACE: &'static [u8] = b"[{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"type\":\"function\"}]";
|
||||
const GET_VALIDATORS: &'static str = "getValidators";
|
||||
|
||||
/// The validator contract should have the following interface:
|
||||
/// [{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}]
|
||||
pub struct ValidatorSafeContract {
|
||||
pub address: Address,
|
||||
validators: RwLock<SimpleList>,
|
||||
validators: RwLock<MemoryLruCache<H256, SimpleList>>,
|
||||
provider: RwLock<Option<provider::Contract>>,
|
||||
}
|
||||
|
||||
@@ -35,102 +41,127 @@ impl ValidatorSafeContract {
|
||||
pub fn new(contract_address: Address) -> Self {
|
||||
ValidatorSafeContract {
|
||||
address: contract_address,
|
||||
validators: Default::default(),
|
||||
validators: RwLock::new(MemoryLruCache::new(MEMOIZE_CAPACITY)),
|
||||
provider: RwLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries the state and updates the set of validators.
|
||||
pub fn update(&self) {
|
||||
/// Queries the state and gets the set of validators.
|
||||
fn get_list(&self, block_hash: H256) -> Option<SimpleList> {
|
||||
if let Some(ref provider) = *self.provider.read() {
|
||||
match provider.get_validators() {
|
||||
match provider.get_validators(BlockId::Hash(block_hash)) {
|
||||
Ok(new) => {
|
||||
debug!(target: "engine", "Set of validators obtained: {:?}", new);
|
||||
*self.validators.write() = SimpleList::new(new);
|
||||
Some(SimpleList::new(new))
|
||||
},
|
||||
Err(s) => {
|
||||
debug!(target: "engine", "Set of validators could not be updated: {}", s);
|
||||
None
|
||||
},
|
||||
Err(s) => warn!(target: "engine", "Set of validators could not be updated: {}", s),
|
||||
}
|
||||
} else {
|
||||
warn!(target: "engine", "Set of validators could not be updated: no provider contract.")
|
||||
warn!(target: "engine", "Set of validators could not be updated: no provider contract.");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks validators on every block.
|
||||
impl ChainNotify for ValidatorSafeContract {
|
||||
fn new_blocks(
|
||||
&self,
|
||||
_: Vec<H256>,
|
||||
_: Vec<H256>,
|
||||
enacted: Vec<H256>,
|
||||
_: Vec<H256>,
|
||||
_: Vec<H256>,
|
||||
_: Vec<Bytes>,
|
||||
_duration: u64) {
|
||||
if !enacted.is_empty() {
|
||||
self.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ValidatorSet for Arc<ValidatorSafeContract> {
|
||||
fn contains(&self, address: &Address) -> bool {
|
||||
self.validators.read().contains(address)
|
||||
impl ValidatorSet for ValidatorSafeContract {
|
||||
fn contains(&self, block_hash: &H256, address: &Address) -> bool {
|
||||
let mut guard = self.validators.write();
|
||||
let maybe_existing = guard
|
||||
.get_mut(block_hash)
|
||||
.map(|list| list.contains(block_hash, address));
|
||||
maybe_existing
|
||||
.unwrap_or_else(|| self
|
||||
.get_list(block_hash.clone())
|
||||
.map_or(false, |list| {
|
||||
let contains = list.contains(block_hash, address);
|
||||
guard.insert(block_hash.clone(), list);
|
||||
contains
|
||||
}))
|
||||
}
|
||||
|
||||
fn get(&self, nonce: usize) -> Address {
|
||||
self.validators.read().get(nonce)
|
||||
fn get(&self, block_hash: &H256, nonce: usize) -> Address {
|
||||
let mut guard = self.validators.write();
|
||||
let maybe_existing = guard
|
||||
.get_mut(block_hash)
|
||||
.map(|list| list.get(block_hash, nonce));
|
||||
maybe_existing
|
||||
.unwrap_or_else(|| self
|
||||
.get_list(block_hash.clone())
|
||||
.map_or_else(Default::default, |list| {
|
||||
let address = list.get(block_hash, nonce);
|
||||
guard.insert(block_hash.clone(), list);
|
||||
address
|
||||
}))
|
||||
}
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.validators.read().count()
|
||||
fn count(&self, block_hash: &H256) -> usize {
|
||||
let mut guard = self.validators.write();
|
||||
let maybe_existing = guard
|
||||
.get_mut(block_hash)
|
||||
.map(|list| list.count(block_hash));
|
||||
maybe_existing
|
||||
.unwrap_or_else(|| self
|
||||
.get_list(block_hash.clone())
|
||||
.map_or_else(usize::max_value, |list| {
|
||||
let address = list.count(block_hash);
|
||||
guard.insert(block_hash.clone(), list);
|
||||
address
|
||||
}))
|
||||
}
|
||||
|
||||
fn register_contract(&self, client: Weak<Client>) {
|
||||
if let Some(c) = client.upgrade() {
|
||||
c.add_notify(self.clone());
|
||||
}
|
||||
{
|
||||
*self.provider.write() = Some(provider::Contract::new(self.address, move |a, d| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d))));
|
||||
}
|
||||
self.update();
|
||||
trace!(target: "engine", "Setting up contract caller.");
|
||||
let contract = ethabi::Contract::new(ethabi::Interface::load(CONTRACT_INTERFACE).expect("JSON interface is valid; qed"));
|
||||
let call = contract.function(GET_VALIDATORS.into()).expect("Method name is valid; qed");
|
||||
let data = call.encode_call(vec![]).expect("get_validators does not take any arguments; qed");
|
||||
let contract_address = self.address.clone();
|
||||
let do_call = move |id| client
|
||||
.upgrade()
|
||||
.ok_or("No client!".into())
|
||||
.and_then(|c| c.call_contract(id, contract_address.clone(), data.clone()))
|
||||
.map(|raw_output| call.decode_output(raw_output).expect("ethabi is correct; qed"));
|
||||
*self.provider.write() = Some(provider::Contract::new(do_call));
|
||||
}
|
||||
}
|
||||
|
||||
mod provider {
|
||||
// Autogenerated from JSON contract definition using Rust contract convertor.
|
||||
#![allow(unused_imports)]
|
||||
use std::string::String;
|
||||
use std::result::Result;
|
||||
use std::fmt;
|
||||
use {util, ethabi};
|
||||
use util::{FixedHash, Uint};
|
||||
use types::ids::BlockId;
|
||||
|
||||
pub struct Contract {
|
||||
contract: ethabi::Contract,
|
||||
address: util::Address,
|
||||
do_call: Box<Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send + Sync + 'static>,
|
||||
do_call: Box<Fn(BlockId) -> Result<Vec<ethabi::Token>, String> + Send + Sync + 'static>,
|
||||
}
|
||||
|
||||
impl Contract {
|
||||
pub fn new<F>(address: util::Address, do_call: F) -> Self where F: Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send + Sync + 'static {
|
||||
pub fn new<F>(do_call: F) -> Self where F: Fn(BlockId) -> Result<Vec<ethabi::Token>, String> + Send + Sync + 'static {
|
||||
Contract {
|
||||
contract: ethabi::Contract::new(ethabi::Interface::load(b"[{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"type\":\"function\"}]").expect("JSON is autogenerated; qed")),
|
||||
address: address,
|
||||
do_call: Box::new(do_call),
|
||||
}
|
||||
}
|
||||
fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) }
|
||||
|
||||
/// Auto-generated from: `{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}`
|
||||
#[allow(dead_code)]
|
||||
pub fn get_validators(&self) -> Result<Vec<util::Address>, String> {
|
||||
let call = self.contract.function("getValidators".into()).map_err(Self::as_string)?;
|
||||
let data = call.encode_call(
|
||||
vec![]
|
||||
).map_err(Self::as_string)?;
|
||||
let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||
let mut result = output.into_iter().rev().collect::<Vec<_>>();
|
||||
Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_array().and_then(|v| v.into_iter().map(|a| a.to_address()).collect::<Option<Vec<[u8; 20]>>>()).ok_or("Invalid type returned")?; r.into_iter().map(|a| util::Address::from(a)).collect::<Vec<_>>() }))
|
||||
|
||||
/// Gets validators from contract with interface: `{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}`
|
||||
pub fn get_validators(&self, id: BlockId) -> Result<Vec<util::Address>, String> {
|
||||
Ok((self.do_call)(id)?
|
||||
.into_iter()
|
||||
.rev()
|
||||
.collect::<Vec<_>>()
|
||||
.pop()
|
||||
.expect("get_validators returns one argument; qed")
|
||||
.to_array()
|
||||
.and_then(|v| v
|
||||
.into_iter()
|
||||
.map(|a| a.to_address())
|
||||
.collect::<Option<Vec<[u8; 20]>>>())
|
||||
.expect("get_validators returns a list of addresses; qed")
|
||||
.into_iter()
|
||||
.map(util::Address::from)
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,13 +169,14 @@ mod provider {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use util::*;
|
||||
use types::ids::BlockId;
|
||||
use spec::Spec;
|
||||
use account_provider::AccountProvider;
|
||||
use transaction::{Transaction, Action};
|
||||
use client::{BlockChainClient, EngineClient};
|
||||
use ethkey::Secret;
|
||||
use miner::MinerService;
|
||||
use tests::helpers::generate_dummy_client_with_spec_and_accounts;
|
||||
use tests::helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data};
|
||||
use super::super::ValidatorSet;
|
||||
use super::ValidatorSafeContract;
|
||||
|
||||
@@ -153,12 +185,13 @@ mod tests {
|
||||
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
|
||||
let vc = Arc::new(ValidatorSafeContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap()));
|
||||
vc.register_contract(Arc::downgrade(&client));
|
||||
assert!(vc.contains(&Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()));
|
||||
assert!(vc.contains(&Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap()));
|
||||
let last_hash = client.best_block_header().hash();
|
||||
assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()));
|
||||
assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn updates_validators() {
|
||||
fn knows_validators() {
|
||||
let tap = Arc::new(AccountProvider::transient_provider());
|
||||
let s0 = Secret::from_slice(&"1".sha3()).unwrap();
|
||||
let v0 = tap.insert_account(s0.clone(), "").unwrap();
|
||||
@@ -212,5 +245,14 @@ mod tests {
|
||||
client.update_sealing();
|
||||
// Able to seal again.
|
||||
assert_eq!(client.chain_info().best_block_number, 3);
|
||||
|
||||
// Check syncing.
|
||||
let sync_client = generate_dummy_client_with_spec_and_data(Spec::new_validator_safe_contract, 0, 0, &[]);
|
||||
sync_client.engine().register_client(Arc::downgrade(&sync_client));
|
||||
for i in 1..4 {
|
||||
sync_client.import_block(client.block(BlockId::Number(i)).unwrap().into_inner()).unwrap();
|
||||
}
|
||||
sync_client.flush_queue();
|
||||
assert_eq!(sync_client.chain_info().best_block_number, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/// Preconfigured validator list.
|
||||
|
||||
use util::Address;
|
||||
use util::{H256, Address, HeapSizeOf};
|
||||
use super::ValidatorSet;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Default)]
|
||||
@@ -34,16 +34,22 @@ impl SimpleList {
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for SimpleList {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.validators.heap_size_of_children() + self.validator_n.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl ValidatorSet for SimpleList {
|
||||
fn contains(&self, address: &Address) -> bool {
|
||||
fn contains(&self, _bh: &H256, address: &Address) -> bool {
|
||||
self.validators.contains(address)
|
||||
}
|
||||
|
||||
fn get(&self, nonce: usize) -> Address {
|
||||
fn get(&self, _bh: &H256, nonce: usize) -> Address {
|
||||
self.validators.get(nonce % self.validator_n).expect("There are validator_n authorities; taking number modulo validator_n gives number in validator_n range; qed").clone()
|
||||
}
|
||||
|
||||
fn count(&self) -> usize {
|
||||
fn count(&self, _bh: &H256) -> usize {
|
||||
self.validator_n
|
||||
}
|
||||
}
|
||||
@@ -60,9 +66,9 @@ mod tests {
|
||||
let a1 = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||
let a2 = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||
let list = SimpleList::new(vec![a1.clone(), a2.clone()]);
|
||||
assert!(list.contains(&a1));
|
||||
assert_eq!(list.get(0), a1);
|
||||
assert_eq!(list.get(1), a2);
|
||||
assert_eq!(list.get(2), a1);
|
||||
assert!(list.contains(&Default::default(), &a1));
|
||||
assert_eq!(list.get(&Default::default(), 0), a1);
|
||||
assert_eq!(list.get(&Default::default(), 1), a2);
|
||||
assert_eq!(list.get(&Default::default(), 2), a1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ extern crate ethcore_stratum;
|
||||
extern crate ethabi;
|
||||
extern crate hardware_wallet;
|
||||
extern crate stats;
|
||||
extern crate itertools;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
@@ -230,7 +230,8 @@ pub struct Miner {
|
||||
impl Miner {
|
||||
/// Push notifier that will handle new jobs
|
||||
pub fn push_notifier(&self, notifier: Box<NotifyWork>) {
|
||||
self.notifiers.write().push(notifier)
|
||||
self.notifiers.write().push(notifier);
|
||||
self.sealing_work.lock().enabled = true;
|
||||
}
|
||||
|
||||
/// Creates new instance of miner Arc.
|
||||
@@ -298,7 +299,7 @@ impl Miner {
|
||||
}
|
||||
|
||||
fn forced_sealing(&self) -> bool {
|
||||
self.options.force_sealing || !self.options.new_work_notify.is_empty()
|
||||
self.options.force_sealing || !self.notifiers.read().is_empty()
|
||||
}
|
||||
|
||||
/// Clear all pending block states
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use types::ids::BlockId;
|
||||
use client::MiningBlockChainClient;
|
||||
use transaction::SignedTransaction;
|
||||
use util::{U256, Uint, Mutex};
|
||||
@@ -45,7 +46,7 @@ impl ServiceTransactionChecker {
|
||||
debug_assert_eq!(tx.gas_price, U256::zero());
|
||||
|
||||
if let Some(ref contract) = *self.contract.lock() {
|
||||
let do_call = |a, d| client.call_contract(a, d);
|
||||
let do_call = |a, d| client.call_contract(BlockId::Latest, a, d);
|
||||
contract.certified(&do_call, &tx.sender())
|
||||
} else {
|
||||
Err("contract is not configured".to_owned())
|
||||
|
||||
@@ -211,6 +211,8 @@ impl From<AddrParseError> for Error {
|
||||
|
||||
impl super::work_notify::NotifyWork for Stratum {
|
||||
fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) {
|
||||
trace!(target: "stratum", "Notify work");
|
||||
|
||||
self.service.push_work_all(
|
||||
self.dispatcher.payload(pow_hash, difficulty, number)
|
||||
).unwrap_or_else(
|
||||
|
||||
@@ -23,6 +23,7 @@ use snapshot::Error;
|
||||
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY, SHA3_NULL_RLP};
|
||||
use util::trie::{TrieDB, Trie};
|
||||
use rlp::{RlpStream, Stream, UntrustedRlp, View};
|
||||
use itertools::Itertools;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
@@ -60,55 +61,53 @@ impl CodeState {
|
||||
}
|
||||
}
|
||||
|
||||
// walk the account's storage trie, returning an RLP item containing the
|
||||
// account properties and the storage.
|
||||
pub fn to_fat_rlp(acc: &BasicAccount, acct_db: &AccountDB, used_code: &mut HashSet<H256>) -> Result<Bytes, Error> {
|
||||
// walk the account's storage trie, returning a vector of RLP items containing the
|
||||
// account properties and the storage. Each item contains at most `max_storage_items`
|
||||
// storage records split according to snapshot format definition.
|
||||
pub fn to_fat_rlps(acc: &BasicAccount, acct_db: &AccountDB, used_code: &mut HashSet<H256>, max_storage_items: usize) -> Result<Vec<Bytes>, Error> {
|
||||
if acc == &ACC_EMPTY {
|
||||
return Ok(::rlp::NULL_RLP.to_vec());
|
||||
return Ok(vec![::rlp::NULL_RLP.to_vec()]);
|
||||
}
|
||||
|
||||
let db = TrieDB::new(acct_db, &acc.storage_root)?;
|
||||
|
||||
let mut pairs = Vec::new();
|
||||
let chunks = db.iter()?.chunks(max_storage_items);
|
||||
let pair_chunks = chunks.into_iter().map(|chunk| chunk.collect());
|
||||
pair_chunks.pad_using(1, |_| Vec::new(), ).map(|pairs| {
|
||||
let mut stream = RlpStream::new_list(pairs.len());
|
||||
|
||||
for item in db.iter()? {
|
||||
let (k, v) = item?;
|
||||
pairs.push((k, v));
|
||||
}
|
||||
for r in pairs {
|
||||
let (k, v) = r?;
|
||||
stream.begin_list(2).append(&k).append(&&*v);
|
||||
}
|
||||
|
||||
let mut stream = RlpStream::new_list(pairs.len());
|
||||
let pairs_rlp = stream.out();
|
||||
|
||||
for (k, v) in pairs {
|
||||
stream.begin_list(2).append(&k).append(&&*v);
|
||||
}
|
||||
let mut account_stream = RlpStream::new_list(5);
|
||||
account_stream.append(&acc.nonce)
|
||||
.append(&acc.balance);
|
||||
|
||||
let pairs_rlp = stream.out();
|
||||
|
||||
let mut account_stream = RlpStream::new_list(5);
|
||||
account_stream.append(&acc.nonce)
|
||||
.append(&acc.balance);
|
||||
|
||||
// [has_code, code_hash].
|
||||
if acc.code_hash == SHA3_EMPTY {
|
||||
account_stream.append(&CodeState::Empty.raw()).append_empty_data();
|
||||
} else if used_code.contains(&acc.code_hash) {
|
||||
account_stream.append(&CodeState::Hash.raw()).append(&acc.code_hash);
|
||||
} else {
|
||||
match acct_db.get(&acc.code_hash) {
|
||||
Some(c) => {
|
||||
used_code.insert(acc.code_hash.clone());
|
||||
account_stream.append(&CodeState::Inline.raw()).append(&&*c);
|
||||
}
|
||||
None => {
|
||||
warn!("code lookup failed during snapshot");
|
||||
account_stream.append(&false).append_empty_data();
|
||||
// [has_code, code_hash].
|
||||
if acc.code_hash == SHA3_EMPTY {
|
||||
account_stream.append(&CodeState::Empty.raw()).append_empty_data();
|
||||
} else if used_code.contains(&acc.code_hash) {
|
||||
account_stream.append(&CodeState::Hash.raw()).append(&acc.code_hash);
|
||||
} else {
|
||||
match acct_db.get(&acc.code_hash) {
|
||||
Some(c) => {
|
||||
used_code.insert(acc.code_hash.clone());
|
||||
account_stream.append(&CodeState::Inline.raw()).append(&&*c);
|
||||
}
|
||||
None => {
|
||||
warn!("code lookup failed during snapshot");
|
||||
account_stream.append(&false).append_empty_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
account_stream.append_raw(&pairs_rlp, 1);
|
||||
|
||||
Ok(account_stream.out())
|
||||
account_stream.append_raw(&pairs_rlp, 1);
|
||||
Ok(account_stream.out())
|
||||
}).collect()
|
||||
}
|
||||
|
||||
// decode a fat rlp, and rebuild the storage trie as we go.
|
||||
@@ -117,6 +116,7 @@ pub fn to_fat_rlp(acc: &BasicAccount, acct_db: &AccountDB, used_code: &mut HashS
|
||||
pub fn from_fat_rlp(
|
||||
acct_db: &mut AccountDBMut,
|
||||
rlp: UntrustedRlp,
|
||||
mut storage_root: H256,
|
||||
) -> Result<(BasicAccount, Option<Bytes>), Error> {
|
||||
use util::{TrieDBMut, TrieMut};
|
||||
|
||||
@@ -148,10 +148,12 @@ pub fn from_fat_rlp(
|
||||
}
|
||||
};
|
||||
|
||||
let mut storage_root = H256::zero();
|
||||
|
||||
{
|
||||
let mut storage_trie = TrieDBMut::new(acct_db, &mut storage_root);
|
||||
let mut storage_trie = if storage_root.is_zero() {
|
||||
TrieDBMut::new(acct_db, &mut storage_root)
|
||||
} else {
|
||||
TrieDBMut::from_existing(acct_db, &mut storage_root)?
|
||||
};
|
||||
let pairs = rlp.at(4)?;
|
||||
for pair_rlp in pairs.iter() {
|
||||
let k: Bytes = pair_rlp.val_at(0)?;
|
||||
@@ -184,7 +186,7 @@ mod tests {
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::{ACC_EMPTY, to_fat_rlp, from_fat_rlp};
|
||||
use super::{ACC_EMPTY, to_fat_rlps, from_fat_rlp};
|
||||
|
||||
#[test]
|
||||
fn encoding_basic() {
|
||||
@@ -201,9 +203,9 @@ mod tests {
|
||||
let thin_rlp = ::rlp::encode(&account);
|
||||
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
|
||||
|
||||
let fat_rlp = to_fat_rlp(&account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default()).unwrap();
|
||||
let fat_rlp = UntrustedRlp::new(&fat_rlp);
|
||||
assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp).unwrap().0, account);
|
||||
let fat_rlps = to_fat_rlps(&account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value()).unwrap();
|
||||
let fat_rlp = UntrustedRlp::new(&fat_rlps[0]);
|
||||
assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -226,9 +228,40 @@ mod tests {
|
||||
let thin_rlp = ::rlp::encode(&account);
|
||||
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
|
||||
|
||||
let fat_rlp = to_fat_rlp(&account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default()).unwrap();
|
||||
let fat_rlp = UntrustedRlp::new(&fat_rlp);
|
||||
assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp).unwrap().0, account);
|
||||
let fat_rlp = to_fat_rlps(&account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value()).unwrap();
|
||||
let fat_rlp = UntrustedRlp::new(&fat_rlp[0]);
|
||||
assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encoding_storage_split() {
|
||||
let mut db = get_temp_state_db();
|
||||
let addr = Address::random();
|
||||
|
||||
let account = {
|
||||
let acct_db = AccountDBMut::new(db.as_hashdb_mut(), &addr);
|
||||
let mut root = SHA3_NULL_RLP;
|
||||
fill_storage(acct_db, &mut root, &mut H256::zero());
|
||||
BasicAccount {
|
||||
nonce: 25.into(),
|
||||
balance: 987654321.into(),
|
||||
storage_root: root,
|
||||
code_hash: SHA3_EMPTY,
|
||||
}
|
||||
};
|
||||
|
||||
let thin_rlp = ::rlp::encode(&account);
|
||||
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
|
||||
|
||||
let fat_rlps = to_fat_rlps(&account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), 100).unwrap();
|
||||
let mut root = SHA3_NULL_RLP;
|
||||
let mut restored_account = None;
|
||||
for rlp in fat_rlps {
|
||||
let fat_rlp = UntrustedRlp::new(&rlp);
|
||||
restored_account = Some(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, root).unwrap().0);
|
||||
root = restored_account.as_ref().unwrap().storage_root.clone();
|
||||
}
|
||||
assert_eq!(restored_account, Some(account));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -264,18 +297,18 @@ mod tests {
|
||||
|
||||
let mut used_code = HashSet::new();
|
||||
|
||||
let fat_rlp1 = to_fat_rlp(&account1, &AccountDB::new(db.as_hashdb(), &addr1), &mut used_code).unwrap();
|
||||
let fat_rlp2 = to_fat_rlp(&account2, &AccountDB::new(db.as_hashdb(), &addr2), &mut used_code).unwrap();
|
||||
let fat_rlp1 = to_fat_rlps(&account1, &AccountDB::new(db.as_hashdb(), &addr1), &mut used_code, usize::max_value()).unwrap();
|
||||
let fat_rlp2 = to_fat_rlps(&account2, &AccountDB::new(db.as_hashdb(), &addr2), &mut used_code, usize::max_value()).unwrap();
|
||||
assert_eq!(used_code.len(), 1);
|
||||
|
||||
let fat_rlp1 = UntrustedRlp::new(&fat_rlp1);
|
||||
let fat_rlp2 = UntrustedRlp::new(&fat_rlp2);
|
||||
let fat_rlp1 = UntrustedRlp::new(&fat_rlp1[0]);
|
||||
let fat_rlp2 = UntrustedRlp::new(&fat_rlp2[0]);
|
||||
|
||||
let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2).unwrap();
|
||||
let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2, H256::zero()).unwrap();
|
||||
assert!(maybe_code.is_none());
|
||||
assert_eq!(acc, account2);
|
||||
|
||||
let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr1), fat_rlp1).unwrap();
|
||||
let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr1), fat_rlp1, H256::zero()).unwrap();
|
||||
assert_eq!(maybe_code, Some(b"this is definitely code".to_vec()));
|
||||
assert_eq!(acc, account1);
|
||||
}
|
||||
@@ -285,7 +318,7 @@ mod tests {
|
||||
let mut db = get_temp_state_db();
|
||||
let mut used_code = HashSet::new();
|
||||
|
||||
assert_eq!(to_fat_rlp(&ACC_EMPTY, &AccountDB::new(db.as_hashdb(), &Address::default()), &mut used_code).unwrap(), ::rlp::NULL_RLP.to_vec());
|
||||
assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), UntrustedRlp::new(&::rlp::NULL_RLP)).unwrap(), (ACC_EMPTY, None));
|
||||
assert_eq!(to_fat_rlps(&ACC_EMPTY, &AccountDB::new(db.as_hashdb(), &Address::default()), &mut used_code, usize::max_value()).unwrap(), vec![::rlp::NULL_RLP.to_vec()]);
|
||||
assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), UntrustedRlp::new(&::rlp::NULL_RLP), H256::zero()).unwrap(), (ACC_EMPTY, None));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ pub enum Error {
|
||||
Decoder(DecoderError),
|
||||
/// Io error.
|
||||
Io(::std::io::Error),
|
||||
/// Snapshot version is not supported.
|
||||
VersionNotSupported(u64),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@@ -73,6 +75,7 @@ impl fmt::Display for Error {
|
||||
Error::Io(ref err) => err.fmt(f),
|
||||
Error::Decoder(ref err) => err.fmt(f),
|
||||
Error::Trie(ref err) => err.fmt(f),
|
||||
Error::VersionNotSupported(ref ver) => write!(f, "Snapshot version {} is not supprted.", ver),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ use rlp::{self, Encodable, RlpStream, UntrustedRlp, Stream, View};
|
||||
|
||||
use super::ManifestData;
|
||||
|
||||
const SNAPSHOT_VERSION: u64 = 2;
|
||||
|
||||
/// Something which can write snapshots.
|
||||
/// Writing the same chunk multiple times will lead to implementation-defined
|
||||
/// behavior, and is not advised.
|
||||
@@ -120,8 +122,9 @@ impl SnapshotWriter for PackedWriter {
|
||||
fn finish(mut self, manifest: ManifestData) -> io::Result<()> {
|
||||
// we ignore the hashes fields of the manifest under the assumption that
|
||||
// they are consistent with ours.
|
||||
let mut stream = RlpStream::new_list(5);
|
||||
let mut stream = RlpStream::new_list(6);
|
||||
stream
|
||||
.append(&SNAPSHOT_VERSION)
|
||||
.append(&self.state_hashes)
|
||||
.append(&self.block_hashes)
|
||||
.append(&manifest.state_root)
|
||||
@@ -223,7 +226,7 @@ impl PackedReader {
|
||||
/// Create a new `PackedReader` for the file at the given path.
|
||||
/// This will fail if any io errors are encountered or the file
|
||||
/// is not a valid packed snapshot.
|
||||
pub fn new(path: &Path) -> Result<Option<Self>, ::error::Error> {
|
||||
pub fn new(path: &Path) -> Result<Option<Self>, ::snapshot::error::Error> {
|
||||
let mut file = File::open(path)?;
|
||||
let file_len = file.metadata()?.len();
|
||||
if file_len < 8 {
|
||||
@@ -257,15 +260,26 @@ impl PackedReader {
|
||||
|
||||
let rlp = UntrustedRlp::new(&manifest_buf);
|
||||
|
||||
let state: Vec<ChunkInfo> = rlp.val_at(0)?;
|
||||
let blocks: Vec<ChunkInfo> = rlp.val_at(1)?;
|
||||
let (start, version) = if rlp.item_count() == 5 {
|
||||
(0, 1)
|
||||
} else {
|
||||
(1, rlp.val_at(0)?)
|
||||
};
|
||||
|
||||
if version > SNAPSHOT_VERSION {
|
||||
return Err(::snapshot::error::Error::VersionNotSupported(version));
|
||||
}
|
||||
|
||||
let state: Vec<ChunkInfo> = rlp.val_at(0 + start)?;
|
||||
let blocks: Vec<ChunkInfo> = rlp.val_at(1 + start)?;
|
||||
|
||||
let manifest = ManifestData {
|
||||
version: version,
|
||||
state_hashes: state.iter().map(|c| c.0).collect(),
|
||||
block_hashes: blocks.iter().map(|c| c.0).collect(),
|
||||
state_root: rlp.val_at(2)?,
|
||||
block_number: rlp.val_at(3)?,
|
||||
block_hash: rlp.val_at(4)?,
|
||||
state_root: rlp.val_at(2 + start)?,
|
||||
block_number: rlp.val_at(3 + start)?,
|
||||
block_hash: rlp.val_at(4 + start)?,
|
||||
};
|
||||
|
||||
Ok(Some(PackedReader {
|
||||
@@ -348,7 +362,7 @@ mod tests {
|
||||
use util::sha3::Hashable;
|
||||
|
||||
use snapshot::ManifestData;
|
||||
use super::{SnapshotWriter, SnapshotReader, PackedWriter, PackedReader, LooseWriter, LooseReader};
|
||||
use super::{SnapshotWriter, SnapshotReader, PackedWriter, PackedReader, LooseWriter, LooseReader, SNAPSHOT_VERSION};
|
||||
|
||||
const STATE_CHUNKS: &'static [&'static [u8]] = &[b"dog", b"cat", b"hello world", b"hi", b"notarealchunk"];
|
||||
const BLOCK_CHUNKS: &'static [&'static [u8]] = &[b"hello!", b"goodbye!", b"abcdefg", b"hijklmnop", b"qrstuvwxy", b"and", b"z"];
|
||||
@@ -374,6 +388,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let manifest = ManifestData {
|
||||
version: SNAPSHOT_VERSION,
|
||||
state_hashes: state_hashes,
|
||||
block_hashes: block_hashes,
|
||||
state_root: b"notarealroot".sha3(),
|
||||
@@ -412,6 +427,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let manifest = ManifestData {
|
||||
version: SNAPSHOT_VERSION,
|
||||
state_hashes: state_hashes,
|
||||
block_hashes: block_hashes,
|
||||
state_root: b"notarealroot".sha3(),
|
||||
@@ -428,4 +444,4 @@ mod tests {
|
||||
reader.chunk(hash.clone()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ pub use self::traits::SnapshotService;
|
||||
pub use self::watcher::Watcher;
|
||||
pub use types::snapshot_manifest::ManifestData;
|
||||
pub use types::restoration_status::RestorationStatus;
|
||||
pub use types::basic_account::BasicAccount;
|
||||
|
||||
pub mod io;
|
||||
pub mod service;
|
||||
@@ -82,6 +83,9 @@ mod traits {
|
||||
// Try to have chunks be around 4MB (before compression)
|
||||
const PREFERRED_CHUNK_SIZE: usize = 4 * 1024 * 1024;
|
||||
|
||||
// Try to have chunks be around 4MB (before compression)
|
||||
const MAX_STORAGE_ENTRIES_PER_ACCOUNT_RECORD: usize = 80_000;
|
||||
|
||||
// How many blocks to include in a snapshot, starting from the head of the chain.
|
||||
const SNAPSHOT_BLOCKS: u64 = 30000;
|
||||
|
||||
@@ -147,6 +151,7 @@ pub fn take_snapshot<W: SnapshotWriter + Send>(
|
||||
info!("produced {} state chunks and {} block chunks.", state_hashes.len(), block_hashes.len());
|
||||
|
||||
let manifest_data = ManifestData {
|
||||
version: 2,
|
||||
state_hashes: state_hashes,
|
||||
block_hashes: block_hashes,
|
||||
state_root: *state_root,
|
||||
@@ -300,14 +305,14 @@ impl<'a> StateChunker<'a> {
|
||||
//
|
||||
// If the buffer is greater than the desired chunk size,
|
||||
// this will write out the data to disk.
|
||||
fn push(&mut self, account_hash: Bytes, data: Bytes) -> Result<(), Error> {
|
||||
fn push(&mut self, account_hash: Bytes, data: Bytes, force_chunk: bool) -> Result<(), Error> {
|
||||
let pair = {
|
||||
let mut stream = RlpStream::new_list(2);
|
||||
stream.append(&account_hash).append_raw(&data, 1);
|
||||
stream.out()
|
||||
};
|
||||
|
||||
if self.cur_size + pair.len() >= PREFERRED_CHUNK_SIZE {
|
||||
if force_chunk || self.cur_size + pair.len() >= PREFERRED_CHUNK_SIZE {
|
||||
self.write_chunk()?;
|
||||
}
|
||||
|
||||
@@ -372,8 +377,10 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex<SnapshotWriter +
|
||||
|
||||
let account_db = AccountDB::from_hash(db, account_key_hash);
|
||||
|
||||
let fat_rlp = account::to_fat_rlp(&account, &account_db, &mut used_code)?;
|
||||
chunker.push(account_key, fat_rlp)?;
|
||||
let fat_rlps = account::to_fat_rlps(&account, &account_db, &mut used_code, MAX_STORAGE_ENTRIES_PER_ACCOUNT_RECORD)?;
|
||||
for (i, fat_rlp) in fat_rlps.into_iter().enumerate() {
|
||||
chunker.push(account_key.clone(), fat_rlp, i > 0)?;
|
||||
}
|
||||
}
|
||||
|
||||
if chunker.cur_size != 0 {
|
||||
@@ -390,6 +397,7 @@ pub struct StateRebuilder {
|
||||
known_code: HashMap<H256, H256>, // code hashes mapped to first account with this code.
|
||||
missing_code: HashMap<H256, Vec<H256>>, // maps code hashes to lists of accounts missing that code.
|
||||
bloom: Bloom,
|
||||
known_storage_roots: HashMap<H256, H256>, // maps account hashes to last known storage root. Only filled for last account per chunk.
|
||||
}
|
||||
|
||||
impl StateRebuilder {
|
||||
@@ -401,6 +409,7 @@ impl StateRebuilder {
|
||||
known_code: HashMap::new(),
|
||||
missing_code: HashMap::new(),
|
||||
bloom: StateDB::load_bloom(&*db),
|
||||
known_storage_roots: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,6 +427,7 @@ impl StateRebuilder {
|
||||
rlp,
|
||||
&mut pairs,
|
||||
&self.known_code,
|
||||
&mut self.known_storage_roots,
|
||||
flag
|
||||
)?;
|
||||
|
||||
@@ -464,14 +474,18 @@ impl StateRebuilder {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check for accounts missing code. Once all chunks have been fed, there should
|
||||
/// be none.
|
||||
pub fn check_missing(self) -> Result<(), Error> {
|
||||
/// Finalize the restoration. Check for accounts missing code and make a dummy
|
||||
/// journal entry.
|
||||
/// Once all chunks have been fed, there should be nothing missing.
|
||||
pub fn finalize(mut self, era: u64, id: H256) -> Result<(), ::error::Error> {
|
||||
let missing = self.missing_code.keys().cloned().collect::<Vec<_>>();
|
||||
match missing.is_empty() {
|
||||
true => Ok(()),
|
||||
false => Err(Error::MissingCode(missing)),
|
||||
}
|
||||
if !missing.is_empty() { return Err(Error::MissingCode(missing).into()) }
|
||||
|
||||
let mut batch = self.db.backing().transaction();
|
||||
self.db.journal_under(&mut batch, era, &id)?;
|
||||
self.db.backing().write_buffered(batch);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the state root of the rebuilder.
|
||||
@@ -492,10 +506,11 @@ fn rebuild_accounts(
|
||||
account_fat_rlps: UntrustedRlp,
|
||||
out_chunk: &mut [(H256, Bytes)],
|
||||
known_code: &HashMap<H256, H256>,
|
||||
known_storage_roots: &mut HashMap<H256, H256>,
|
||||
abort_flag: &AtomicBool,
|
||||
) -> Result<RebuiltStatus, ::error::Error> {
|
||||
let mut status = RebuiltStatus::default();
|
||||
for (account_rlp, out) in account_fat_rlps.into_iter().zip(out_chunk) {
|
||||
for (account_rlp, out) in account_fat_rlps.into_iter().zip(out_chunk.iter_mut()) {
|
||||
if !abort_flag.load(Ordering::SeqCst) { return Err(Error::RestorationAborted.into()) }
|
||||
|
||||
let hash: H256 = account_rlp.val_at(0)?;
|
||||
@@ -506,7 +521,8 @@ fn rebuild_accounts(
|
||||
// fill out the storage trie and code while decoding.
|
||||
let (acc, maybe_code) = {
|
||||
let mut acct_db = AccountDBMut::from_hash(db, hash);
|
||||
account::from_fat_rlp(&mut acct_db, fat_rlp)?
|
||||
let storage_root = known_storage_roots.get(&hash).cloned().unwrap_or(H256::zero());
|
||||
account::from_fat_rlp(&mut acct_db, fat_rlp, storage_root)?
|
||||
};
|
||||
|
||||
let code_hash = acc.code_hash.clone();
|
||||
@@ -538,6 +554,12 @@ fn rebuild_accounts(
|
||||
|
||||
*out = (hash, thin_rlp);
|
||||
}
|
||||
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().last() {
|
||||
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
|
||||
}
|
||||
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().next() {
|
||||
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
|
||||
}
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ impl Restoration {
|
||||
}
|
||||
|
||||
// check for missing code.
|
||||
self.state.check_missing()?;
|
||||
self.state.finalize(self.manifest.block_number, self.manifest.block_hash)?;
|
||||
|
||||
// connect out-of-order chunks and verify chain integrity.
|
||||
self.blocks.finalize(self.canonical_hashes)?;
|
||||
@@ -656,6 +656,7 @@ mod tests {
|
||||
assert_eq!(service.status(), RestorationStatus::Inactive);
|
||||
|
||||
let manifest = ManifestData {
|
||||
version: 2,
|
||||
state_hashes: vec![],
|
||||
block_hashes: vec![],
|
||||
state_root: Default::default(),
|
||||
|
||||
@@ -63,6 +63,7 @@ fn chunk_and_restore(amount: u64) {
|
||||
let writer = Mutex::new(PackedWriter::new(&snapshot_path).unwrap());
|
||||
let block_hashes = chunk_blocks(&bc, best_hash, &writer, &Progress::default()).unwrap();
|
||||
let manifest = ::snapshot::ManifestData {
|
||||
version: 2,
|
||||
state_hashes: Vec::new(),
|
||||
block_hashes: block_hashes,
|
||||
state_root: ::util::sha3::SHA3_NULL_RLP,
|
||||
@@ -125,6 +126,7 @@ fn checks_flag() {
|
||||
let chain = BlockChain::new(Default::default(), &genesis, db.clone());
|
||||
|
||||
let manifest = ::snapshot::ManifestData {
|
||||
version: 2,
|
||||
state_hashes: Vec::new(),
|
||||
block_hashes: Vec::new(),
|
||||
state_root: ::util::sha3::SHA3_NULL_RLP,
|
||||
|
||||
@@ -27,6 +27,7 @@ use super::ManifestData;
|
||||
#[test]
|
||||
fn manifest_rlp() {
|
||||
let manifest = ManifestData {
|
||||
version: 2,
|
||||
block_hashes: Vec::new(),
|
||||
state_hashes: Vec::new(),
|
||||
block_number: 1234567,
|
||||
@@ -35,4 +36,4 @@ fn manifest_rlp() {
|
||||
};
|
||||
let raw = manifest.clone().into_rlp();
|
||||
assert_eq!(ManifestData::from_rlp(&raw).unwrap(), manifest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ fn guards_delete_folders() {
|
||||
path.push("restoration");
|
||||
|
||||
let manifest = ManifestData {
|
||||
version: 2,
|
||||
state_hashes: vec![],
|
||||
block_hashes: vec![],
|
||||
block_number: 0,
|
||||
|
||||
@@ -58,10 +58,11 @@ fn snap_and_restore() {
|
||||
let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default()).unwrap();
|
||||
|
||||
writer.into_inner().finish(::snapshot::ManifestData {
|
||||
version: 2,
|
||||
state_hashes: state_hashes,
|
||||
block_hashes: Vec::new(),
|
||||
state_root: state_root,
|
||||
block_number: 0,
|
||||
block_number: 1000,
|
||||
block_hash: H256::default(),
|
||||
}).unwrap();
|
||||
|
||||
@@ -69,7 +70,7 @@ fn snap_and_restore() {
|
||||
db_path.push("db");
|
||||
let db = {
|
||||
let new_db = Arc::new(Database::open(&db_cfg, &db_path.to_string_lossy()).unwrap());
|
||||
let mut rebuilder = StateRebuilder::new(new_db.clone(), Algorithm::Archive);
|
||||
let mut rebuilder = StateRebuilder::new(new_db.clone(), Algorithm::OverlayRecent);
|
||||
let reader = PackedReader::new(&snap_file).unwrap().unwrap();
|
||||
|
||||
let flag = AtomicBool::new(true);
|
||||
@@ -82,12 +83,13 @@ fn snap_and_restore() {
|
||||
}
|
||||
|
||||
assert_eq!(rebuilder.state_root(), state_root);
|
||||
rebuilder.check_missing().unwrap();
|
||||
rebuilder.finalize(1000, H256::default()).unwrap();
|
||||
|
||||
new_db
|
||||
};
|
||||
|
||||
let new_db = journaldb::new(db, Algorithm::Archive, ::db::COL_STATE);
|
||||
let new_db = journaldb::new(db, Algorithm::OverlayRecent, ::db::COL_STATE);
|
||||
assert_eq!(new_db.earliest_era(), Some(1000));
|
||||
|
||||
compare_dbs(&old_db, new_db.as_hashdb());
|
||||
}
|
||||
@@ -120,10 +122,10 @@ fn get_code_from_prev_chunk() {
|
||||
let mut db = MemoryDB::new();
|
||||
AccountDBMut::from_hash(&mut db, hash).insert(&code[..]);
|
||||
|
||||
let fat_rlp = account::to_fat_rlp(&acc, &AccountDB::from_hash(&db, hash), &mut used_code).unwrap();
|
||||
let fat_rlp = account::to_fat_rlps(&acc, &AccountDB::from_hash(&db, hash), &mut used_code, usize::max_value()).unwrap();
|
||||
|
||||
let mut stream = RlpStream::new_list(1);
|
||||
stream.begin_list(2).append(&hash).append_raw(&fat_rlp, 1);
|
||||
stream.begin_list(2).append(&hash).append_raw(&fat_rlp[0], 1);
|
||||
stream.out()
|
||||
};
|
||||
|
||||
@@ -134,13 +136,18 @@ fn get_code_from_prev_chunk() {
|
||||
let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS);
|
||||
let new_db = Arc::new(Database::open(&db_cfg, &db_path.to_string_lossy()).unwrap());
|
||||
|
||||
let mut rebuilder = StateRebuilder::new(new_db, Algorithm::Archive);
|
||||
let flag = AtomicBool::new(true);
|
||||
{
|
||||
let mut rebuilder = StateRebuilder::new(new_db.clone(), Algorithm::OverlayRecent);
|
||||
let flag = AtomicBool::new(true);
|
||||
|
||||
rebuilder.feed(&chunk1, &flag).unwrap();
|
||||
rebuilder.feed(&chunk2, &flag).unwrap();
|
||||
rebuilder.feed(&chunk1, &flag).unwrap();
|
||||
rebuilder.feed(&chunk2, &flag).unwrap();
|
||||
|
||||
rebuilder.check_missing().unwrap();
|
||||
rebuilder.finalize(1000, H256::random()).unwrap();
|
||||
}
|
||||
|
||||
let state_db = journaldb::new(new_db, Algorithm::OverlayRecent, ::db::COL_STATE);
|
||||
assert_eq!(state_db.earliest_era(), Some(1000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -164,6 +171,7 @@ fn checks_flag() {
|
||||
let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default()).unwrap();
|
||||
|
||||
writer.into_inner().finish(::snapshot::ManifestData {
|
||||
version: 2,
|
||||
state_hashes: state_hashes,
|
||||
block_hashes: Vec::new(),
|
||||
state_root: state_root,
|
||||
@@ -175,7 +183,7 @@ fn checks_flag() {
|
||||
db_path.push("db");
|
||||
{
|
||||
let new_db = Arc::new(Database::open(&db_cfg, &db_path.to_string_lossy()).unwrap());
|
||||
let mut rebuilder = StateRebuilder::new(new_db.clone(), Algorithm::Archive);
|
||||
let mut rebuilder = StateRebuilder::new(new_db.clone(), Algorithm::OverlayRecent);
|
||||
let reader = PackedReader::new(&snap_file).unwrap().unwrap();
|
||||
|
||||
let flag = AtomicBool::new(false);
|
||||
|
||||
@@ -55,6 +55,8 @@ pub struct CommonParams {
|
||||
pub fork_block: Option<(BlockNumber, H256)>,
|
||||
/// Number of first block where EIP-98 rules begin.
|
||||
pub eip98_transition: BlockNumber,
|
||||
/// Validate block receipts root.
|
||||
pub validate_receipts_transition: u64,
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::Params> for CommonParams {
|
||||
@@ -68,6 +70,7 @@ impl From<ethjson::spec::Params> for CommonParams {
|
||||
min_gas_limit: p.min_gas_limit.into(),
|
||||
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
|
||||
eip98_transition: p.eip98_transition.map_or(0, Into::into),
|
||||
validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -357,6 +360,10 @@ impl Spec {
|
||||
/// Account is marked with `reportBenign` it can be checked as disliked with "0xd8f2e0bf".
|
||||
/// Validator can be removed with `reportMalicious`.
|
||||
pub fn new_validator_contract() -> Self { load_bundled!("validator_contract") }
|
||||
|
||||
/// Create a new Spec with BasicAuthority which uses multiple validator sets changing with height.
|
||||
/// Account with secrets "0".sha3() is the validator for block 1 and with "1".sha3() onwards.
|
||||
pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -546,7 +546,7 @@ impl<B: Backend> State<B> {
|
||||
|
||||
// TODO uncomment once to_pod() works correctly.
|
||||
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
||||
let state_root = if env_info.number < engine.params().eip98_transition {
|
||||
let state_root = if env_info.number < engine.params().eip98_transition || env_info.number < engine.params().validate_receipts_transition {
|
||||
self.commit()?;
|
||||
Some(self.root().clone())
|
||||
} else {
|
||||
|
||||
@@ -24,6 +24,8 @@ use util::Bytes;
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct ManifestData {
|
||||
/// Snapshot format version.
|
||||
pub version: u64,
|
||||
/// List of state chunk hashes.
|
||||
pub state_hashes: Vec<H256>,
|
||||
/// List of block chunk hashes.
|
||||
@@ -39,7 +41,8 @@ pub struct ManifestData {
|
||||
impl ManifestData {
|
||||
/// Encode the manifest data to rlp.
|
||||
pub fn into_rlp(self) -> Bytes {
|
||||
let mut stream = RlpStream::new_list(5);
|
||||
let mut stream = RlpStream::new_list(6);
|
||||
stream.append(&self.version);
|
||||
stream.append(&self.state_hashes);
|
||||
stream.append(&self.block_hashes);
|
||||
stream.append(&self.state_root);
|
||||
@@ -52,14 +55,20 @@ impl ManifestData {
|
||||
/// Try to restore manifest data from raw bytes, interpreted as RLP.
|
||||
pub fn from_rlp(raw: &[u8]) -> Result<Self, DecoderError> {
|
||||
let decoder = UntrustedRlp::new(raw);
|
||||
let (start, version) = if decoder.item_count() == 5 {
|
||||
(0, 1)
|
||||
} else {
|
||||
(1, decoder.val_at(0)?)
|
||||
};
|
||||
|
||||
let state_hashes: Vec<H256> = decoder.val_at(0)?;
|
||||
let block_hashes: Vec<H256> = decoder.val_at(1)?;
|
||||
let state_root: H256 = decoder.val_at(2)?;
|
||||
let block_number: u64 = decoder.val_at(3)?;
|
||||
let block_hash: H256 = decoder.val_at(4)?;
|
||||
let state_hashes: Vec<H256> = decoder.val_at(start + 0)?;
|
||||
let block_hashes: Vec<H256> = decoder.val_at(start + 1)?;
|
||||
let state_root: H256 = decoder.val_at(start + 2)?;
|
||||
let block_number: u64 = decoder.val_at(start + 3)?;
|
||||
let block_hash: H256 = decoder.val_at(start + 4)?;
|
||||
|
||||
Ok(ManifestData {
|
||||
version: version,
|
||||
state_hashes: state_hashes,
|
||||
block_hashes: block_hashes,
|
||||
state_root: state_root,
|
||||
|
||||
@@ -5,11 +5,11 @@ version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[lib]
|
||||
name = "evm"
|
||||
name = "evmbin"
|
||||
path = "./src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "evm"
|
||||
name = "parity-evm"
|
||||
path = "./src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -271,7 +271,7 @@ impl Manager {
|
||||
chunk_size += size;
|
||||
}
|
||||
trace!("writing {:?}", &hid_chunk[..]);
|
||||
let n = handle.write(&hid_chunk[0..chunk_size])?;
|
||||
let n = handle.write(&hid_chunk[..])?;
|
||||
if n < chunk_size {
|
||||
return Err(Error::Protocol("Write data size mismatch"));
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@ nightly-testing = ["clippy"]
|
||||
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
|
||||
|
||||
[build-dependencies]
|
||||
quasi_codegen = { version = "0.11", optional = true }
|
||||
syntex = { version = "0.33", optional = true }
|
||||
quasi_codegen = { version = "0.32", optional = true }
|
||||
syntex = { version = "0.58", optional = true }
|
||||
|
||||
[dependencies]
|
||||
aster = { version = "0.17", default-features = false }
|
||||
aster = { version = "0.41", default-features = false }
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
quasi = { version = "0.11", default-features = false }
|
||||
quasi_macros = { version = "0.11", optional = true }
|
||||
syntex = { version = "0.33", optional = true }
|
||||
syntex_syntax = { version = "0.33", optional = true }
|
||||
quasi = { version = "0.32", default-features = false }
|
||||
quasi_macros = { version = "0.32", optional = true }
|
||||
syntex = { version = "0.58", optional = true }
|
||||
syntex_syntax = { version = "0.58", optional = true }
|
||||
|
||||
@@ -25,13 +25,11 @@ mod inner {
|
||||
|
||||
pub fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let mut registry = syntex::Registry::new();
|
||||
quasi_codegen::register(&mut registry);
|
||||
|
||||
let src = Path::new("src/lib.rs.in");
|
||||
let dst = Path::new(&out_dir).join("lib.rs");
|
||||
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
quasi_codegen::expand(&src, &dst).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ pub fn expand_ipc_implementation(
|
||||
|
||||
let builder = aster::AstBuilder::new().span(span);
|
||||
|
||||
let interface_map = match implement_interface(cx, &builder, &item, push) {
|
||||
let interface_map = match implement_interface(cx, &builder, &item, push, meta_item) {
|
||||
Ok(interface_map) => interface_map,
|
||||
Err(Error) => { return; },
|
||||
};
|
||||
@@ -99,9 +99,9 @@ fn push_invoke_signature_aster(
|
||||
let inputs = &named_signature.sig.decl.inputs;
|
||||
let (input_type_name, input_arg_names, input_arg_tys) = if inputs.len() > 0 {
|
||||
let first_field_name = field_name(builder, &inputs[0]).name.as_str();
|
||||
if first_field_name == "self" && inputs.len() == 1 { (None, vec![], vec![]) }
|
||||
if &*first_field_name == "self" && inputs.len() == 1 { (None, vec![], vec![]) }
|
||||
else {
|
||||
let skip = if first_field_name == "self" { 2 } else { 1 };
|
||||
let skip = if &*first_field_name == "self" { 2 } else { 1 };
|
||||
let name_str = format!("{}_input", named_signature.ident.name.as_str());
|
||||
|
||||
let mut arg_names = Vec::new();
|
||||
@@ -181,6 +181,7 @@ fn implement_dispatch_arm_invoke_stmt(
|
||||
dispatch: &Dispatch,
|
||||
) -> ast::Stmt
|
||||
{
|
||||
use ::syntax::tokenstream::TokenTree::Token;
|
||||
let function_name = builder.id(dispatch.function_name.as_str());
|
||||
|
||||
let input_args_exprs = dispatch.input_arg_names.iter().enumerate().map(|(arg_index, arg_name)| {
|
||||
@@ -193,56 +194,56 @@ fn implement_dispatch_arm_invoke_stmt(
|
||||
let ext_cx = &*cx;
|
||||
::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
ext_cx.cfg(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
if dispatch.return_type_ty.is_some() {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
}
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&function_name, ext_cx).into_iter());
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
for arg_expr in input_args_exprs {
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&arg_expr, ext_cx).into_iter());
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Comma));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
}
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
if dispatch.return_type_ty.is_some() {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
}
|
||||
else {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Semi));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Vec"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("new"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Semi));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Vec"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("new"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
}
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
tt
|
||||
})).unwrap()
|
||||
}
|
||||
)).unwrap()
|
||||
}
|
||||
|
||||
fn implement_dispatch_arm_invoke(
|
||||
@@ -344,6 +345,8 @@ fn implement_client_method_body(
|
||||
interface_map: &InterfaceMap,
|
||||
) -> P<ast::Expr>
|
||||
{
|
||||
use ::syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
let dispatch = &interface_map.dispatches[index as usize];
|
||||
let index_ident = builder.id(format!("{}", index + RESERVED_MESSAGE_IDS).as_str());
|
||||
|
||||
@@ -391,26 +394,25 @@ fn implement_client_method_body(
|
||||
let ext_cx = &*cx;
|
||||
::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
ext_cx.cfg(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("let"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("payload"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Eq));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Request"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("let"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("payload"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Eq));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Request"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
for arg in dispatch.input_arg_names.iter() {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str()))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Colon));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str()))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Colon));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str()))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Comma));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str()))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
}
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
tt
|
||||
}))
|
||||
});
|
||||
@@ -465,6 +467,8 @@ fn implement_client_method(
|
||||
)
|
||||
-> ast::ImplItem
|
||||
{
|
||||
use ::syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
let dispatch = &interface_map.dispatches[index as usize];
|
||||
let method_name = builder.id(dispatch.function_name.as_str());
|
||||
let body = implement_client_method_body(cx, builder, index, interface_map);
|
||||
@@ -476,36 +480,35 @@ fn implement_client_method(
|
||||
let signature = ::syntax::parse::parser::Parser::parse_impl_item(
|
||||
&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
ext_cx.cfg(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("fn"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("fn"))));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&method_name, ext_cx).into_iter());
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Comma));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
|
||||
for arg_idx in 0..dispatch.input_arg_names.len() {
|
||||
let arg_name = dispatch.input_arg_names[arg_idx].as_str();
|
||||
let arg_ty = dispatch.input_arg_tys[arg_idx].clone();
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg_name))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Colon));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg_name))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Colon));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&arg_ty, ext_cx).into_iter());
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Comma));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
}
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
if let Some(ref return_ty) = dispatch.return_type_ty {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::RArrow));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::RArrow));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(return_ty, ext_cx).into_iter());
|
||||
}
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&body, ext_cx).into_iter());
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
tt
|
||||
}));
|
||||
@@ -526,7 +529,7 @@ fn client_generics(builder: &aster::AstBuilder, interface_map: &InterfaceMap) ->
|
||||
|
||||
fn client_qualified_ident(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P<Ty> {
|
||||
let generics = client_generics(builder, interface_map);
|
||||
aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item))
|
||||
aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(cx, builder))
|
||||
.with_generics(generics).build()
|
||||
.build()
|
||||
}
|
||||
@@ -542,7 +545,7 @@ fn client_phantom_ident(builder: &aster::AstBuilder, interface_map: &InterfaceMa
|
||||
/// for say `Service` it generates `ServiceClient`
|
||||
fn push_client_struct(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap, push: &mut FnMut(Annotatable)) {
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item);
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder);
|
||||
let phantom = client_phantom_ident(builder, interface_map);
|
||||
|
||||
let client_struct_item = quote_item!(cx,
|
||||
@@ -575,7 +578,7 @@ fn push_with_socket_client_implementation(
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_ident = client_qualified_ident(cx, builder, interface_map);
|
||||
let where_clause = &generics.where_clause;
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item);
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder);
|
||||
|
||||
let implement = quote_item!(cx,
|
||||
impl $generics ::ipc::WithSocket<S> for $client_ident $where_clause {
|
||||
@@ -717,33 +720,31 @@ fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result<String,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ipc_meta_items(attr: &ast::Attribute) -> Option<&[P<ast::MetaItem>]> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaItemKind::List(ref name, ref items) if name == &"ipc" => {
|
||||
Some(items)
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn client_ident_renamed(cx: &ExtCtxt, item: &ast::Item) -> Option<String> {
|
||||
for meta_items in item.attrs().iter().filter_map(get_ipc_meta_items) {
|
||||
for meta_item in meta_items {
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"client_ident" => {
|
||||
if let Ok(s) = get_str_from_lit(cx, name, lit) {
|
||||
return Some(s);
|
||||
fn client_ident_renamed(cx: &ExtCtxt, meta_item: &MetaItem) -> Option<String> {
|
||||
if let ast::MetaItemKind::List(ref list) = meta_item.node {
|
||||
for nested in list {
|
||||
match nested.node {
|
||||
ast::NestedMetaItemKind::MetaItem(ref meta_item) => {
|
||||
let is_client_ident = &*meta_item.name.as_str() == "client_ident";
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::NameValue(ref lit) if is_client_ident => {
|
||||
if let Ok(s) = get_str_from_lit(cx, "client_ident", lit) {
|
||||
return Some(s);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
cx.span_err(
|
||||
meta_item.span,
|
||||
&format!("unknown client_ident container attribute `{}`",
|
||||
::syntax::print::pprust::meta_item_to_string(&meta_item)));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
cx.span_err(
|
||||
meta_item.span,
|
||||
&format!("unknown client_ident container attribute `{}`",
|
||||
::syntax::print::pprust::meta_item_to_string(meta_item)));
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
@@ -759,6 +760,7 @@ struct InterfaceMap {
|
||||
|
||||
struct IdentMap {
|
||||
original_path: ast::Path,
|
||||
meta_item: MetaItem,
|
||||
}
|
||||
|
||||
impl IdentMap {
|
||||
@@ -766,8 +768,8 @@ impl IdentMap {
|
||||
builder.id(format!("{}", ::syntax::print::pprust::path_to_string(&self.original_path)))
|
||||
}
|
||||
|
||||
fn client_ident(&self, cx: &ExtCtxt, builder: &aster::AstBuilder, item: &ast::Item) -> Ident {
|
||||
if let Some(new_name) = client_ident_renamed(cx, item) {
|
||||
fn client_ident(&self, cx: &ExtCtxt, builder: &aster::AstBuilder) -> Ident {
|
||||
if let Some(new_name) = client_ident_renamed(cx, &self.meta_item) {
|
||||
builder.id(new_name)
|
||||
}
|
||||
else {
|
||||
@@ -776,12 +778,12 @@ impl IdentMap {
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_ident_map(original_ty: &P<Ty>) -> IdentMap {
|
||||
fn ty_ident_map(original_ty: &P<Ty>, meta_item: &MetaItem) -> IdentMap {
|
||||
let original_path = match original_ty.node {
|
||||
::syntax::ast::TyKind::Path(_, ref path) => path.clone(),
|
||||
_ => { panic!("incompatible implementation"); }
|
||||
};
|
||||
let ident_map = IdentMap { original_path: original_path };
|
||||
let ident_map = IdentMap { original_path: original_path, meta_item: meta_item.clone() };
|
||||
ident_map
|
||||
}
|
||||
|
||||
@@ -791,6 +793,7 @@ fn implement_interface(
|
||||
builder: &aster::AstBuilder,
|
||||
item: &Item,
|
||||
push: &mut FnMut(Annotatable),
|
||||
meta_item: &MetaItem,
|
||||
) -> Result<InterfaceMap, Error> {
|
||||
let (generics, impl_trait, original_ty, dispatch_table) = match item.node {
|
||||
ast::ItemKind::Impl(_, _, ref generics, ref impl_trait, ref ty, ref impl_items) => {
|
||||
@@ -844,7 +847,7 @@ fn implement_interface(
|
||||
|
||||
let (handshake_arm, handshake_arm_buf) = implement_handshake_arm(cx);
|
||||
|
||||
let ty = ty_ident_map(&original_ty).ident(builder);
|
||||
let ty = ty_ident_map(&original_ty, meta_item).ident(builder);
|
||||
let (interface_endpoint, host_generics) = match impl_trait {
|
||||
Some(ref trait_) => (builder.id(::syntax::print::pprust::path_to_string(&trait_.path)), None),
|
||||
None => (ty, Some(&impl_generics)),
|
||||
@@ -884,7 +887,7 @@ fn implement_interface(
|
||||
).unwrap();
|
||||
|
||||
Ok(InterfaceMap {
|
||||
ident_map: ty_ident_map(&original_ty),
|
||||
ident_map: ty_ident_map(&original_ty, meta_item),
|
||||
original_item: item.clone(),
|
||||
item: ipc_item,
|
||||
dispatches: dispatch_table,
|
||||
|
||||
@@ -66,9 +66,11 @@ struct StripAttributeFolder<'a> {
|
||||
#[cfg(feature = "with-syntex")]
|
||||
impl<'a> fold::Folder for StripAttributeFolder<'a> {
|
||||
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaItemKind::List(ref n, _) if n == self.attr_title => { return None; }
|
||||
ast::MetaItemKind::Word(ref n) if n == self.attr_title => { return None; }
|
||||
let is_self = &*attr.value.name.as_str() == self.attr_title;
|
||||
|
||||
match attr.value.node {
|
||||
ast::MetaItemKind::List(_) if is_self => { return None; }
|
||||
ast::MetaItemKind::Word if is_self => { return None; }
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ fn binary_expr(
|
||||
_ => {
|
||||
cx.span_bug(item.span,
|
||||
"expected ItemStruct or ItemEnum in #[derive(Binary)]");
|
||||
Err(Error)
|
||||
Err(Error) as Result<BinaryExpressions, Error>
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -184,13 +184,17 @@ fn binary_expr_struct(
|
||||
let size_exprs: Vec<P<ast::Expr>> = fields.iter().enumerate().map(|(index, field)| {
|
||||
let raw_ident = ::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty));
|
||||
let index_ident = builder.id(format!("__field{}", index));
|
||||
let field_id = match field.ident {
|
||||
Some(ident) => builder.id(ident),
|
||||
None => builder.id(format!("{}", index)),
|
||||
};
|
||||
|
||||
match raw_ident.as_ref() {
|
||||
"u8" => {
|
||||
quote_expr!(cx, 1)
|
||||
},
|
||||
"[u8]" => {
|
||||
value_ident.and_then(|x| {
|
||||
let field_id = builder.id(field.ident.unwrap());
|
||||
Some(quote_expr!(cx, $x. $field_id .len()))
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
@@ -207,7 +211,6 @@ fn binary_expr_struct(
|
||||
|
||||
value_ident.and_then(|x|
|
||||
{
|
||||
let field_id = builder.id(field.ident.unwrap());
|
||||
Some(quote_expr!(cx,
|
||||
match $field_type_ident_qualified::len_params() {
|
||||
0 => ::std::mem::size_of::<$field_type_ident>(),
|
||||
@@ -232,12 +235,12 @@ fn binary_expr_struct(
|
||||
}
|
||||
|
||||
let mut write_stmts = Vec::<ast::Stmt>::new();
|
||||
write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;).unwrap());
|
||||
write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;).expect("stmt1"));
|
||||
|
||||
let mut map_stmts = Vec::<ast::Stmt>::new();
|
||||
let field_amount = builder.id(&format!("{}",fields.len()));
|
||||
map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).unwrap());
|
||||
map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).unwrap());
|
||||
map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).expect("stmt2"));
|
||||
map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).expect("stmt3"));
|
||||
|
||||
let mut post_write_stmts = Vec::<ast::Stmt>::new();
|
||||
|
||||
@@ -248,9 +251,12 @@ fn binary_expr_struct(
|
||||
let field_type_ident_qualified = builder.id(
|
||||
replace_qualified(&::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty))));
|
||||
|
||||
let field_id = match field.ident {
|
||||
Some(ident) => builder.id(ident),
|
||||
None => builder.id(format!("{}", index)),
|
||||
};
|
||||
let member_expr = match value_ident {
|
||||
Some(x) => {
|
||||
let field_id = builder.id(field.ident.unwrap());
|
||||
quote_expr!(cx, $x . $field_id)
|
||||
},
|
||||
None => {
|
||||
@@ -267,8 +273,8 @@ fn binary_expr_struct(
|
||||
|
||||
match raw_ident.as_ref() {
|
||||
"u8" => {
|
||||
write_stmts.push(quote_stmt!(cx, let next_line = offset + 1;).unwrap());
|
||||
write_stmts.push(quote_stmt!(cx, buffer[offset] = $member_expr; ).unwrap());
|
||||
write_stmts.push(quote_stmt!(cx, let next_line = offset + 1;).expect("stmt4"));
|
||||
write_stmts.push(quote_stmt!(cx, buffer[offset] = $member_expr; ).expect("stm5"));
|
||||
},
|
||||
"[u8]" => {
|
||||
write_stmts.push(quote_stmt!(cx, let size = $member_expr .len();).unwrap());
|
||||
@@ -374,7 +380,7 @@ fn binary_expr_item_struct(
|
||||
cx.span_bug(span,
|
||||
&format!("#[derive(Binary)] Unsupported struct content, expected tuple/struct, found: {:?}",
|
||||
variant_data));
|
||||
Err(Error)
|
||||
Err(Error) as Result<BinaryExpressions, Error>
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -431,13 +437,12 @@ fn fields_sequence(
|
||||
variant_ident: &ast::Ident,
|
||||
) -> ast::Expr {
|
||||
use syntax::parse::token;
|
||||
use syntax::ast::TokenTree::Token;
|
||||
use syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
let named_members = fields.iter().any(|f| f.ident.is_some());
|
||||
|
||||
::quasi::parse_expr_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
ext_cx.cfg(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
@@ -569,11 +574,10 @@ fn named_fields_sequence(
|
||||
fields: &[ast::StructField],
|
||||
) -> ast::Stmt {
|
||||
use syntax::parse::token;
|
||||
use syntax::ast::TokenTree::Token;
|
||||
use syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
ext_cx.cfg(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
@@ -590,7 +594,10 @@ fn named_fields_sequence(
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Brace)));
|
||||
|
||||
for (idx, field) in fields.iter().enumerate() {
|
||||
tt.push(Token(_sp, token::Ident(field.ident.clone().expect("function is called for named fields"))));
|
||||
tt.push(Token(_sp, match field.ident {
|
||||
Some(ident) => token::Ident(ident),
|
||||
None => token::Ident(ext_cx.ident_of(&format!("{}", idx))),
|
||||
}));
|
||||
tt.push(Token(_sp, token::Colon));
|
||||
|
||||
// special case for u8, it just takes byte form sequence
|
||||
|
||||
@@ -9,7 +9,7 @@ build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
ethcore-ipc = { path = "../rpc" }
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git", branch = "parity-1.7" }
|
||||
ethcore-ipc-nano = { path = "../nano" }
|
||||
semver = "0.5"
|
||||
log = "0.3"
|
||||
|
||||
@@ -8,6 +8,6 @@ license = "GPL-3.0"
|
||||
|
||||
[dependencies]
|
||||
ethcore-ipc = { path = "../rpc" }
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git", branch = "parity-1.7" }
|
||||
log = "0.3"
|
||||
lazy_static = "0.2"
|
||||
|
||||
@@ -8,6 +8,6 @@ license = "GPL-3.0"
|
||||
|
||||
[dependencies]
|
||||
ethcore-devtools = { path = "../../devtools" }
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git", branch = "parity-1.7" }
|
||||
ethcore-util = { path = "../../util" }
|
||||
semver = "0.5"
|
||||
|
||||
@@ -11,7 +11,7 @@ path = "run.rs"
|
||||
ethcore-ipc = { path = "../rpc" }
|
||||
ethcore-devtools = { path = "../../devtools" }
|
||||
semver = "0.5"
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git", branch = "parity-1.7" }
|
||||
ethcore-ipc-nano = { path = "../nano" }
|
||||
ethcore-util = { path = "../../util" }
|
||||
log = "0.3"
|
||||
|
||||
@@ -12,8 +12,8 @@ use-precompiled-js = ["parity-dapps-glue/use-precompiled-js"]
|
||||
with-syntex = ["parity-dapps-glue/with-syntex"]
|
||||
|
||||
[build-dependencies]
|
||||
parity-dapps-glue = "1.4"
|
||||
parity-dapps-glue = "1.7"
|
||||
|
||||
[dependencies]
|
||||
parity-dapps-glue = "1.4"
|
||||
parity-dapps-glue = "1.7"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Parity built-in dapps."
|
||||
name = "parity-ui-dev"
|
||||
version = "1.4.0"
|
||||
version = "1.7.0"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
@@ -11,8 +11,8 @@ default = ["with-syntex"]
|
||||
with-syntex = ["parity-dapps-glue/with-syntex"]
|
||||
|
||||
[build-dependencies]
|
||||
parity-dapps-glue = "1.4"
|
||||
parity-dapps-glue = "1.7"
|
||||
|
||||
[dependencies]
|
||||
parity-dapps-glue = "1.4"
|
||||
parity-dapps-glue = "1.7"
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ set -e
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
PACKAGES=( "parity" "etherscan" "shapeshift" "jsonrpc" )
|
||||
BRANCH=$CI_BUILD_REF_NAME
|
||||
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/ethcore/js-precompiled.git"
|
||||
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/ethcore/parity.git"
|
||||
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git"
|
||||
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"
|
||||
|
||||
# setup the git user defaults for the current repo
|
||||
function setup_git_user {
|
||||
|
||||
@@ -120,20 +120,22 @@ export default class HardwareStore {
|
||||
});
|
||||
}
|
||||
|
||||
createAccountInfo (entry) {
|
||||
createAccountInfo (entry, original = {}) {
|
||||
const { address, manufacturer, name } = entry;
|
||||
|
||||
return Promise
|
||||
.all([
|
||||
this._api.parity.setAccountName(address, name),
|
||||
this._api.parity.setAccountMeta(address, {
|
||||
original.name
|
||||
? Promise.resolve(true)
|
||||
: this._api.parity.setAccountName(address, name),
|
||||
this._api.parity.setAccountMeta(address, Object.assign({
|
||||
description: `${manufacturer} ${name}`,
|
||||
hardware: {
|
||||
manufacturer
|
||||
},
|
||||
tags: ['hardware'],
|
||||
timestamp: Date.now()
|
||||
})
|
||||
}, original.meta || {}))
|
||||
])
|
||||
.catch((error) => {
|
||||
console.warn('HardwareStore::createEntry', error);
|
||||
|
||||
@@ -130,25 +130,58 @@ describe('mobx/HardwareStore', () => {
|
||||
|
||||
describe('operations', () => {
|
||||
describe('createAccountInfo', () => {
|
||||
beforeEach(() => {
|
||||
return store.createAccountInfo({
|
||||
address: 'testAddr',
|
||||
manufacturer: 'testMfg',
|
||||
name: 'testName'
|
||||
describe('when not existing', () => {
|
||||
beforeEach(() => {
|
||||
return store.createAccountInfo({
|
||||
address: 'testAddr',
|
||||
manufacturer: 'testMfg',
|
||||
name: 'testName'
|
||||
});
|
||||
});
|
||||
|
||||
it('calls into parity_setAccountName', () => {
|
||||
expect(api.parity.setAccountName).to.have.been.calledWith('testAddr', 'testName');
|
||||
});
|
||||
|
||||
it('calls into parity_setAccountMeta', () => {
|
||||
expect(api.parity.setAccountMeta).to.have.been.calledWith('testAddr', sinon.match({
|
||||
description: 'testMfg testName',
|
||||
hardware: {
|
||||
manufacturer: 'testMfg'
|
||||
},
|
||||
tags: ['hardware']
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it('calls into parity_setAccountName', () => {
|
||||
expect(api.parity.setAccountName).to.have.been.calledWith('testAddr', 'testName');
|
||||
});
|
||||
describe('when already exists', () => {
|
||||
beforeEach(() => {
|
||||
return store.createAccountInfo({
|
||||
address: 'testAddr',
|
||||
manufacturer: 'testMfg',
|
||||
name: 'testName'
|
||||
}, {
|
||||
name: 'originalName',
|
||||
meta: {
|
||||
description: 'originalDescription',
|
||||
tags: ['tagA', 'tagB']
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('calls into parity_setAccountMeta', () => {
|
||||
expect(api.parity.setAccountMeta).to.have.been.calledWith('testAddr', sinon.match({
|
||||
description: 'testMfg testName',
|
||||
hardware: {
|
||||
manufacturer: 'testMfg'
|
||||
}
|
||||
}));
|
||||
it('does not call into parity_setAccountName', () => {
|
||||
expect(api.parity.setAccountName).not.to.have.been.called;
|
||||
});
|
||||
|
||||
it('calls into parity_setAccountMeta', () => {
|
||||
expect(api.parity.setAccountMeta).to.have.been.calledWith('testAddr', sinon.match({
|
||||
description: 'originalDescription',
|
||||
hardware: {
|
||||
manufacturer: 'testMfg'
|
||||
},
|
||||
tags: ['tagA', 'tagB']
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export default class FirstRun extends Component {
|
||||
defaultMessage='As part of a new installation, the next few steps will guide you through the process of setting up you Parity instance and your associated accounts. Our aim is to make it as simple as possible and to get you up and running in record-time, so please bear with us. Once completed you will have -'
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
<FormattedMessage
|
||||
@@ -70,7 +70,7 @@ export default class FirstRun extends Component {
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='firstRun.welcome.next'
|
||||
|
||||
@@ -77,7 +77,8 @@
|
||||
}
|
||||
|
||||
.form {
|
||||
box-sizing: border-box;
|
||||
margin-top: 0;
|
||||
padding: 0.75rem 1.5rem 1.5rem 1.5rem;
|
||||
padding: 0.75rem 1.5rem 1.5rem;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,26 @@ export default class SecureApi extends Api {
|
||||
return this._transport.token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the current API with the given values
|
||||
* (`signerPort`, `dappsInterface`, `dappsPort`, ...)
|
||||
*/
|
||||
configure (configuration) {
|
||||
const { dappsInterface, dappsPort, signerPort } = configuration;
|
||||
|
||||
if (dappsInterface) {
|
||||
this._dappsInterface = dappsInterface;
|
||||
}
|
||||
|
||||
if (dappsPort) {
|
||||
this._dappsPort = dappsPort;
|
||||
}
|
||||
|
||||
if (signerPort) {
|
||||
this._signerPort = signerPort;
|
||||
}
|
||||
}
|
||||
|
||||
connect () {
|
||||
if (this._isConnecting) {
|
||||
return;
|
||||
|
||||
@@ -24,6 +24,7 @@ $transitionAll: all 0.75s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: 0em;
|
||||
max-width: 100%;
|
||||
position: relative;
|
||||
/*transform: translateZ(0);
|
||||
transition: $transitionAll;*/
|
||||
|
||||
@@ -51,7 +51,7 @@ $popoverZ: 3600;
|
||||
left: 0;
|
||||
right: 0;
|
||||
opacity: 0.25;
|
||||
z-index: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
@@ -68,12 +68,13 @@ $popoverZ: 3600;
|
||||
}
|
||||
|
||||
&.modal {
|
||||
z-index: $modalZ;
|
||||
|
||||
&:not(.small) {
|
||||
bottom: $modalBottom;
|
||||
left: $modalLeft;
|
||||
right: $modalRight;
|
||||
top: $modalTop;
|
||||
z-index: $modalZ;
|
||||
}
|
||||
|
||||
/* TODO: Small Portals don't adjust their overall height like we have with the
|
||||
|
||||
@@ -18,6 +18,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactPortal from 'react-portal';
|
||||
import keycode from 'keycode';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
import { CloseIcon } from '~/ui/Icons';
|
||||
@@ -29,7 +30,6 @@ import styles from './portal.css';
|
||||
|
||||
export default class Portal extends Component {
|
||||
static propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
activeStep: PropTypes.number,
|
||||
busy: PropTypes.bool,
|
||||
@@ -45,11 +45,16 @@ export default class Portal extends Component {
|
||||
isChildModal: PropTypes.bool,
|
||||
isSmallModal: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
onClose: PropTypes.func,
|
||||
onKeyDown: PropTypes.func,
|
||||
steps: PropTypes.array,
|
||||
title: nodeOrStringProptype()
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onClose: noop
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
this.setBodyOverflow(this.props.open);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
$transition: all 0.25s;
|
||||
$widthNormal: 33.33%;
|
||||
$widthExpanded: 42%;
|
||||
$widthContracted: 29%;
|
||||
|
||||
.section {
|
||||
position: relative;
|
||||
@@ -44,6 +45,8 @@ $widthExpanded: 42%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 0 1 $widthNormal;
|
||||
max-width: $widthNormal;
|
||||
min-width: $widthContracted;
|
||||
opacity: 0.85;
|
||||
padding: 0.25em;
|
||||
|
||||
|
||||
@@ -394,8 +394,12 @@ class Accounts extends Component {
|
||||
|
||||
Object
|
||||
.keys(wallets)
|
||||
.filter((address) => !accountsInfo[address])
|
||||
.forEach((address) => this.hwstore.createAccountInfo(wallets[address]));
|
||||
.filter((address) => {
|
||||
const account = accountsInfo[address];
|
||||
|
||||
return !account || !account.meta || !account.meta.hardware;
|
||||
})
|
||||
.forEach((address) => this.hwstore.createAccountInfo(wallets[address], accountsInfo[address]));
|
||||
|
||||
this.setVisibleAccounts();
|
||||
}
|
||||
|
||||
122
js/src/views/Accounts/accounts.spec.js
Normal file
122
js/src/views/Accounts/accounts.spec.js
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import Accounts from './';
|
||||
|
||||
let api;
|
||||
let component;
|
||||
let hwstore;
|
||||
let instance;
|
||||
let redux;
|
||||
|
||||
function createApi () {
|
||||
api = {};
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
function createHwStore (walletAddress = '0x456') {
|
||||
hwstore = {
|
||||
wallets: {
|
||||
[walletAddress]: {
|
||||
address: walletAddress
|
||||
}
|
||||
},
|
||||
createAccountInfo: sinon.stub()
|
||||
};
|
||||
|
||||
return hwstore;
|
||||
}
|
||||
|
||||
function createRedux () {
|
||||
redux = {
|
||||
dispatch: sinon.stub(),
|
||||
subscribe: sinon.stub(),
|
||||
getState: () => {
|
||||
return {
|
||||
personal: {
|
||||
accounts: {},
|
||||
accountsInfo: {
|
||||
'0x123': { meta: '1' },
|
||||
'0x999': { meta: { hardware: {} } }
|
||||
}
|
||||
},
|
||||
balances: {
|
||||
balances: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return redux;
|
||||
}
|
||||
|
||||
function render (props = {}) {
|
||||
component = shallow(
|
||||
<Accounts { ...props } />,
|
||||
{
|
||||
context: {
|
||||
store: createRedux()
|
||||
}
|
||||
}
|
||||
).find('Accounts').shallow({
|
||||
context: {
|
||||
api: createApi()
|
||||
}
|
||||
});
|
||||
instance = component.instance();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('views/Accounts', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
describe('instance event methods', () => {
|
||||
describe('onHardwareChange', () => {
|
||||
it('detects completely new entries', () => {
|
||||
instance.hwstore = createHwStore();
|
||||
instance.onHardwareChange();
|
||||
|
||||
expect(hwstore.createAccountInfo).to.have.been.calledWith({ address: '0x456' });
|
||||
});
|
||||
|
||||
it('detects addressbook entries', () => {
|
||||
instance.hwstore = createHwStore('0x123');
|
||||
instance.onHardwareChange();
|
||||
|
||||
expect(hwstore.createAccountInfo).to.have.been.calledWith({ address: '0x123' }, { meta: '1' });
|
||||
});
|
||||
|
||||
it('ignores existing hardware entries', () => {
|
||||
instance.hwstore = createHwStore('0x999');
|
||||
instance.onHardwareChange();
|
||||
|
||||
expect(hwstore.createAccountInfo).not.to.have.been.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -17,12 +17,20 @@
|
||||
import { action, observable } from 'mobx';
|
||||
import store from 'store';
|
||||
|
||||
const OLD_LS_FIRST_RUN_KEY = 'showFirstRun';
|
||||
const LS_FIRST_RUN_KEY = '_parity::showFirstRun';
|
||||
|
||||
export default class Store {
|
||||
@observable firstrunVisible = false;
|
||||
|
||||
constructor (api) {
|
||||
// Migrate the old key to the new one
|
||||
this._migrateStore();
|
||||
|
||||
this._api = api;
|
||||
this.firstrunVisible = store.get('showFirstRun');
|
||||
// Show the first run if it hasn't been shown before
|
||||
// (thus an undefined value)
|
||||
this.firstrunVisible = store.get(LS_FIRST_RUN_KEY) === undefined;
|
||||
|
||||
this._checkAccounts();
|
||||
}
|
||||
@@ -33,16 +41,41 @@ export default class Store {
|
||||
|
||||
@action toggleFirstrun = (visible = false) => {
|
||||
this.firstrunVisible = visible;
|
||||
store.set('showFirstRun', !!visible);
|
||||
|
||||
// There's no need to write to storage that the
|
||||
// First Run should be visible
|
||||
if (!visible) {
|
||||
store.set(LS_FIRST_RUN_KEY, !!visible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate the old LocalStorage ket format
|
||||
* to the new one
|
||||
*/
|
||||
_migrateStore () {
|
||||
const oldValue = store.get(OLD_LS_FIRST_RUN_KEY);
|
||||
const newValue = store.get(LS_FIRST_RUN_KEY);
|
||||
|
||||
if (newValue === undefined && oldValue !== undefined) {
|
||||
store.set(LS_FIRST_RUN_KEY, oldValue);
|
||||
store.remove(OLD_LS_FIRST_RUN_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
_checkAccounts () {
|
||||
this._api.parity
|
||||
.allAccountsInfo()
|
||||
.then((info) => {
|
||||
return Promise
|
||||
.all([
|
||||
this._api.parity.listVaults(),
|
||||
this._api.parity.allAccountsInfo()
|
||||
])
|
||||
.then(([ vaults, info ]) => {
|
||||
const accounts = Object.keys(info).filter((address) => info[address].uuid);
|
||||
// Has accounts if any vaults or accounts
|
||||
const hasAccounts = (accounts && accounts.length > 0) || (vaults && vaults.length > 0);
|
||||
|
||||
this.toggleFirstrun(this.firstrunVisible || !accounts || !accounts.length);
|
||||
// Show First Run if no accounts and no vaults
|
||||
this.toggleFirstrun(this.firstrunVisible || !hasAccounts);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('checkAccounts', error);
|
||||
|
||||
@@ -92,7 +92,7 @@ describe('views/Signer/RequestPending', () => {
|
||||
});
|
||||
|
||||
it('renders SignRequest component', () => {
|
||||
expect(component.find('SignRequest')).to.have.length(1);
|
||||
expect(component.find('Connect(SignRequest)')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { observer } from 'mobx-react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import Account from '../Account';
|
||||
import TransactionPendingForm from '../TransactionPendingForm';
|
||||
@@ -36,12 +37,13 @@ function isAscii (data) {
|
||||
}
|
||||
|
||||
@observer
|
||||
export default class SignRequest extends Component {
|
||||
class SignRequest extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
data: PropTypes.string.isRequired,
|
||||
id: PropTypes.object.isRequired,
|
||||
@@ -152,7 +154,10 @@ export default class SignRequest extends Component {
|
||||
}
|
||||
|
||||
renderActions () {
|
||||
const { address, focus, isFinished, status } = this.props;
|
||||
const { accounts, address, focus, isFinished, status } = this.props;
|
||||
const account = Object
|
||||
.values(accounts)
|
||||
.find((account) => address === account.address.toLowerCase());
|
||||
|
||||
if (isFinished) {
|
||||
if (status === 'confirmed') {
|
||||
@@ -182,6 +187,7 @@ export default class SignRequest extends Component {
|
||||
|
||||
return (
|
||||
<TransactionPendingForm
|
||||
account={ account }
|
||||
address={ address }
|
||||
focus={ focus }
|
||||
isSending={ this.props.isSending }
|
||||
@@ -203,3 +209,16 @@ export default class SignRequest extends Component {
|
||||
this.props.onReject(this.props.id);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts } = state.personal;
|
||||
|
||||
return {
|
||||
accounts
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
)(SignRequest);
|
||||
|
||||
@@ -20,15 +20,53 @@ import sinon from 'sinon';
|
||||
|
||||
import SignRequest from './';
|
||||
|
||||
const store = {
|
||||
balances: {},
|
||||
fetchBalance: sinon.stub()
|
||||
};
|
||||
let component;
|
||||
let reduxStore;
|
||||
let signerStore;
|
||||
|
||||
function createSignerStore () {
|
||||
return {
|
||||
balances: {},
|
||||
fetchBalance: sinon.stub()
|
||||
};
|
||||
}
|
||||
|
||||
function createReduxStore () {
|
||||
return {
|
||||
dispatch: sinon.stub(),
|
||||
subscribe: sinon.stub(),
|
||||
getState: () => {
|
||||
return {
|
||||
personal: {
|
||||
accounts: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function render () {
|
||||
reduxStore = createReduxStore();
|
||||
signerStore = createSignerStore();
|
||||
|
||||
component = shallow(
|
||||
<SignRequest signerstore={ signerStore } />,
|
||||
{
|
||||
context: {
|
||||
store: reduxStore
|
||||
}
|
||||
}
|
||||
).find('SignRequest').shallow();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('views/Signer/components/SignRequest', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(shallow(
|
||||
<SignRequest signerstore={ store } />,
|
||||
)).to.be.ok;
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ import styles from './transactionPendingFormConfirm.css';
|
||||
|
||||
export default class TransactionPendingFormConfirm extends Component {
|
||||
static propTypes = {
|
||||
account: PropTypes.object.isRequired,
|
||||
account: PropTypes.object,
|
||||
address: PropTypes.string.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
@@ -36,6 +36,7 @@ export default class TransactionPendingFormConfirm extends Component {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
account: {},
|
||||
focus: false
|
||||
};
|
||||
|
||||
@@ -80,7 +81,7 @@ export default class TransactionPendingFormConfirm extends Component {
|
||||
|
||||
getPasswordHint () {
|
||||
const { account } = this.props;
|
||||
const accountHint = account && account.meta && account.meta.passwordHint;
|
||||
const accountHint = account.meta && account.meta.passwordHint;
|
||||
|
||||
if (accountHint) {
|
||||
return accountHint;
|
||||
@@ -149,14 +150,16 @@ export default class TransactionPendingFormConfirm extends Component {
|
||||
const { account } = this.props;
|
||||
const { password } = this.state;
|
||||
|
||||
if (account && account.hardware) {
|
||||
if (account.hardware) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isAccount = account.uuid;
|
||||
|
||||
return (
|
||||
<Input
|
||||
hint={
|
||||
account.uuid
|
||||
isAccount
|
||||
? (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.password.unlock.hint'
|
||||
@@ -171,7 +174,7 @@ export default class TransactionPendingFormConfirm extends Component {
|
||||
)
|
||||
}
|
||||
label={
|
||||
account.uuid
|
||||
isAccount
|
||||
? (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.password.unlock.label'
|
||||
|
||||
@@ -48,7 +48,7 @@ function render (address) {
|
||||
|
||||
component = shallow(
|
||||
<TransactionPendingFormConfirm
|
||||
account={ ACCOUNTS[address] || {} }
|
||||
account={ ACCOUNTS[address] }
|
||||
address={ address }
|
||||
onConfirm={ onConfirm }
|
||||
isSending={ false }
|
||||
@@ -130,5 +130,9 @@ describe('views/Signer/TransactionPendingFormConfirm', () => {
|
||||
it('renders the password', () => {
|
||||
expect(instance.renderPassword()).not.to.be.null;
|
||||
});
|
||||
|
||||
it('renders the hint', () => {
|
||||
expect(instance.renderHint()).to.be.null;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ import styles from './transactionPendingForm.css';
|
||||
|
||||
export default class TransactionPendingForm extends Component {
|
||||
static propTypes = {
|
||||
account: PropTypes.object.isRequired,
|
||||
account: PropTypes.object,
|
||||
address: PropTypes.string.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
@@ -36,6 +36,7 @@ export default class TransactionPendingForm extends Component {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
account: {},
|
||||
focus: false
|
||||
};
|
||||
|
||||
|
||||
@@ -40,6 +40,12 @@ pub struct AuthorityRoundParams {
|
||||
/// To be used for testing only.
|
||||
#[serde(rename="startStep")]
|
||||
pub start_step: Option<Uint>,
|
||||
/// Block at which score validation should start.
|
||||
#[serde(rename="validateScoreTransition")]
|
||||
pub validate_score_transition: Option<Uint>,
|
||||
/// See main AuthorityRoundParams docs.
|
||||
#[serde(rename="eip155Transition")]
|
||||
pub eip155_transition: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Authority engine deserialization.
|
||||
@@ -64,7 +70,8 @@ mod tests {
|
||||
"list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"]
|
||||
},
|
||||
"blockReward": "0x50",
|
||||
"startStep" : 24
|
||||
"startStep" : 24,
|
||||
"eip155Transition": "0x42"
|
||||
}
|
||||
}"#;
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ pub struct Params {
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="eip98Transition")]
|
||||
pub eip98_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="validateReceiptsTransition")]
|
||||
pub validate_receipts_transition: Option<Uint>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
//! Validator set deserialization.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use uint::Uint;
|
||||
use hash::Address;
|
||||
|
||||
/// Different ways of specifying validators.
|
||||
@@ -30,6 +32,9 @@ pub enum ValidatorSet {
|
||||
/// Address of a contract that indicates the list of authorities and enables reporting of theor misbehaviour using transactions.
|
||||
#[serde(rename="contract")]
|
||||
Contract(Address),
|
||||
/// A map of starting blocks for each validator set.
|
||||
#[serde(rename="multi")]
|
||||
Multi(BTreeMap<Uint, ValidatorSet>),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -40,11 +45,17 @@ mod tests {
|
||||
#[test]
|
||||
fn validator_set_deserialization() {
|
||||
let s = r#"[{
|
||||
"list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"]
|
||||
"list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"]
|
||||
}, {
|
||||
"safeContract" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
"safeContract": "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
}, {
|
||||
"contract" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
"contract": "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
}, {
|
||||
"multi": {
|
||||
"0": { "list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"] },
|
||||
"10": { "list": ["0xd6d9d2cd449a754c494264e1809c50e34d64562b"] },
|
||||
"20": { "contract": "0xc6d9d2cd449a754c494264e1809c50e34d64562b" }
|
||||
}
|
||||
}]"#;
|
||||
|
||||
let _deserialized: Vec<ValidatorSet> = serde_json::from_str(s).unwrap();
|
||||
|
||||
@@ -462,7 +462,7 @@
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
<string>1.6.2</string>
|
||||
<string>1.6.6</string>
|
||||
</dict>
|
||||
<key>UUID</key>
|
||||
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.6</string>
|
||||
<string>1.6.6</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
|
||||
!define VERSIONMAJOR 1
|
||||
!define VERSIONMINOR 6
|
||||
!define VERSIONBUILD 2
|
||||
!define VERSIONBUILD 6
|
||||
!define ARGS "--warp"
|
||||
!define FIRST_START_ARGS "ui --warp --mode=passive"
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#!/bin/bash
|
||||
cd docker/hub
|
||||
docker build --build-arg BUILD_TAG=$1 --no-cache=true --tag ethcore/parity:$1 .
|
||||
if [ "$1" == "latest" ]; then DOCKER_BUILD_TAG="beta-release"; fi
|
||||
docker build --build-arg BUILD_TAG=$DOCKER_BUILD_TAG --no-cache=true --tag ethcore/parity:$1 .
|
||||
docker push ethcore/parity:$1
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ rand = "0.3.14"
|
||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git" }
|
||||
log = "0.3"
|
||||
env_logger = "0.3"
|
||||
parity-dapps-glue = { version = "1.4", optional = true }
|
||||
parity-dapps-glue = { version = "1.7", optional = true }
|
||||
ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "mio-upstream-stable" }
|
||||
ethcore-util = { path = "../util" }
|
||||
ethcore-io = { path = "../util/io" }
|
||||
|
||||
@@ -42,8 +42,8 @@ impl From<PushMessageError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[ipc(client_ident="RemoteJobDispatcher")]
|
||||
/// Interface that can provide pow/blockchain-specific responses for the clients
|
||||
#[ipc(client_ident="RemoteJobDispatcher")]
|
||||
pub trait JobDispatcher: Send + Sync {
|
||||
// json for initial client handshake
|
||||
fn initial(&self) -> Option<String> { None }
|
||||
@@ -55,8 +55,8 @@ pub trait JobDispatcher: Send + Sync {
|
||||
fn submit(&self, payload: Vec<String>) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
#[ipc(client_ident="RemoteWorkHandler")]
|
||||
/// Interface that can handle requests to push job for workers
|
||||
#[ipc(client_ident="RemoteWorkHandler")]
|
||||
pub trait PushWorkHandler: Send + Sync {
|
||||
/// push the same work package for all workers (`payload`: json of pow-specific set of work specification)
|
||||
fn push_work_all(&self, payload: String) -> Result<(), Error>;
|
||||
|
||||
@@ -25,7 +25,8 @@ time = "0.1.34"
|
||||
rand = "0.3.13"
|
||||
heapsize = "0.3"
|
||||
ethcore-ipc = { path = "../ipc/rpc" }
|
||||
semver = "0.5"
|
||||
semver = "0.6"
|
||||
smallvec = { version = "0.3", features = ["heapsizeof"] }
|
||||
ethcore-ipc-nano = { path = "../ipc/nano" }
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
ethkey = { path = "../ethkey" }
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
// 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::collections::hash_map::Entry;
|
||||
use smallvec::SmallVec;
|
||||
use util::*;
|
||||
use rlp::*;
|
||||
use network::NetworkError;
|
||||
@@ -21,6 +23,8 @@ use ethcore::header::Header as BlockHeader;
|
||||
|
||||
known_heap_size!(0, HeaderId);
|
||||
|
||||
type SmallHashVec = SmallVec<[H256; 1]>;
|
||||
|
||||
/// Block data with optional body.
|
||||
struct SyncBlock {
|
||||
header: Bytes,
|
||||
@@ -64,8 +68,8 @@ pub struct BlockCollection {
|
||||
parents: HashMap<H256, H256>,
|
||||
/// Used to map body to header.
|
||||
header_ids: HashMap<HeaderId, H256>,
|
||||
/// Used to map receipts root to header.
|
||||
receipt_ids: HashMap<H256, H256>,
|
||||
/// Used to map receipts root to headers.
|
||||
receipt_ids: HashMap<H256, SmallHashVec>,
|
||||
/// First block in `blocks`.
|
||||
head: Option<H256>,
|
||||
/// Set of block header hashes being downloaded
|
||||
@@ -202,7 +206,7 @@ impl BlockCollection {
|
||||
}
|
||||
}
|
||||
}
|
||||
for h in self.receipt_ids.values() {
|
||||
for h in self.receipt_ids.values().flat_map(|hashes| hashes) {
|
||||
if needed_receipts.len() >= count {
|
||||
break;
|
||||
}
|
||||
@@ -366,23 +370,26 @@ impl BlockCollection {
|
||||
let receipts = UntrustedRlp::new(&r);
|
||||
ordered_trie_root(receipts.iter().map(|r| r.as_raw().to_vec())) //TODO: get rid of vectors here
|
||||
};
|
||||
match self.receipt_ids.get(&receipt_root).cloned() {
|
||||
Some(h) => {
|
||||
self.receipt_ids.remove(&receipt_root);
|
||||
match self.receipt_ids.entry(receipt_root) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
let h = entry.get_mut().pop().expect("Empty vectors are not allowed in insert_receipt; qed");
|
||||
if entry.get().is_empty() {
|
||||
entry.remove();
|
||||
}
|
||||
self.downloading_receipts.remove(&h);
|
||||
match self.blocks.get_mut(&h) {
|
||||
Some(ref mut block) => {
|
||||
trace!(target: "sync", "Got receipt {}", h);
|
||||
block.receipts = Some(r);
|
||||
block.receipts = Some(r.clone());
|
||||
Ok(())
|
||||
},
|
||||
None => {
|
||||
warn!("Got receipt with no header {}", h);
|
||||
debug!("Got receipt with no header {}", h);
|
||||
Err(NetworkError::BadProtocol)
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
_ => {
|
||||
trace!(target: "sync", "Ignored unknown/stale block receipt {:?}", receipt_root);
|
||||
Err(NetworkError::BadProtocol)
|
||||
}
|
||||
@@ -429,10 +436,7 @@ impl BlockCollection {
|
||||
let receipts_stream = RlpStream::new_list(0);
|
||||
block.receipts = Some(receipts_stream.out());
|
||||
} else {
|
||||
if self.receipt_ids.contains_key(&receipt_root) {
|
||||
warn!(target: "sync", "Duplicate receipt root {:?}, block: {:?}", receipt_root, hash);
|
||||
}
|
||||
self.receipt_ids.insert(receipt_root, hash.clone());
|
||||
self.receipt_ids.entry(receipt_root).or_insert_with(|| SmallHashVec::new()).push(hash.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,8 @@ pub const SNAPSHOT_SYNC_PACKET_COUNT: u8 = 0x16;
|
||||
|
||||
const MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD: usize = 3;
|
||||
|
||||
const MIN_SUPPORTED_SNAPSHOT_MANIFEST_VERSION: u64 = 1;
|
||||
|
||||
const WAIT_PEERS_TIMEOUT_SEC: u64 = 5;
|
||||
const STATUS_TIMEOUT_SEC: u64 = 5;
|
||||
const HEADERS_TIMEOUT_SEC: u64 = 15;
|
||||
@@ -377,6 +379,8 @@ pub struct ChainSync {
|
||||
transactions_stats: TransactionsStats,
|
||||
/// Enable ancient block downloading
|
||||
download_old_blocks: bool,
|
||||
/// Enable warp sync.
|
||||
enable_warp_sync: bool,
|
||||
}
|
||||
|
||||
type RlpResponseResult = Result<Option<(PacketId, RlpStream)>, PacketDecodeError>;
|
||||
@@ -401,6 +405,7 @@ impl ChainSync {
|
||||
snapshot: Snapshot::new(),
|
||||
sync_start_time: None,
|
||||
transactions_stats: TransactionsStats::default(),
|
||||
enable_warp_sync: config.warp_sync,
|
||||
};
|
||||
sync.update_targets(chain);
|
||||
sync
|
||||
@@ -499,7 +504,10 @@ impl ChainSync {
|
||||
}
|
||||
|
||||
fn maybe_start_snapshot_sync(&mut self, io: &mut SyncIo) {
|
||||
if self.state != SyncState::WaitingPeers {
|
||||
if !self.enable_warp_sync {
|
||||
return;
|
||||
}
|
||||
if self.state != SyncState::WaitingPeers && self.state != SyncState::Blocks && self.state != SyncState::Waiting {
|
||||
return;
|
||||
}
|
||||
// Make sure the snapshot block is not too far away from best block and network best block and
|
||||
@@ -1023,12 +1031,18 @@ impl ChainSync {
|
||||
let manifest = match ManifestData::from_rlp(manifest_rlp.as_raw()) {
|
||||
Err(e) => {
|
||||
trace!(target: "sync", "{}: Ignored bad manifest: {:?}", peer_id, e);
|
||||
io.disconnect_peer(peer_id);
|
||||
io.disable_peer(peer_id);
|
||||
self.continue_sync(io);
|
||||
return Ok(());
|
||||
}
|
||||
Ok(manifest) => manifest,
|
||||
};
|
||||
if manifest.version < MIN_SUPPORTED_SNAPSHOT_MANIFEST_VERSION {
|
||||
trace!(target: "sync", "{}: Snapshot manifest version too low: {}", peer_id, manifest.version);
|
||||
io.disable_peer(peer_id);
|
||||
self.continue_sync(io);
|
||||
return Ok(());
|
||||
}
|
||||
self.snapshot.reset_to(&manifest, &manifest_rlp.as_raw().sha3());
|
||||
io.snapshot_service().begin_restore(manifest);
|
||||
self.state = SyncState::SnapshotData;
|
||||
|
||||
@@ -35,6 +35,7 @@ extern crate time;
|
||||
extern crate rand;
|
||||
extern crate semver;
|
||||
extern crate parking_lot;
|
||||
extern crate smallvec;
|
||||
extern crate rlp;
|
||||
|
||||
extern crate ethcore_light as light;
|
||||
|
||||
@@ -139,6 +139,7 @@ mod test {
|
||||
let state_chunks: Vec<Bytes> = (0..20).map(|_| H256::random().to_vec()).collect();
|
||||
let block_chunks: Vec<Bytes> = (0..20).map(|_| H256::random().to_vec()).collect();
|
||||
let manifest = ManifestData {
|
||||
version: 2,
|
||||
state_hashes: state_chunks.iter().map(|data| data.sha3()).collect(),
|
||||
block_hashes: block_chunks.iter().map(|data| data.sha3()).collect(),
|
||||
state_root: H256::new(),
|
||||
|
||||
@@ -49,6 +49,7 @@ impl TestSnapshotService {
|
||||
let state_chunks: Vec<Bytes> = (0..num_state_chunks).map(|_| H256::random().to_vec()).collect();
|
||||
let block_chunks: Vec<Bytes> = (0..num_block_chunks).map(|_| H256::random().to_vec()).collect();
|
||||
let manifest = ManifestData {
|
||||
version: 2,
|
||||
state_hashes: state_chunks.iter().map(|data| data.sha3()).collect(),
|
||||
block_hashes: block_chunks.iter().map(|data| data.sha3()).collect(),
|
||||
state_root: H256::new(),
|
||||
|
||||
@@ -247,7 +247,7 @@ impl Updater {
|
||||
if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) {
|
||||
trace!(target: "updater", "Found operations at {}", ops_addr);
|
||||
let client = self.client.clone();
|
||||
*self.operations.lock() = Some(Operations::new(ops_addr, move |a, d| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d))));
|
||||
*self.operations.lock() = Some(Operations::new(ops_addr, move |a, d| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d))));
|
||||
} else {
|
||||
// No Operations contract - bail.
|
||||
return;
|
||||
@@ -274,7 +274,7 @@ impl Updater {
|
||||
let running_latest = latest.track.version.hash == self.version_info().hash;
|
||||
let already_have_latest = s.installed.as_ref().or(s.ready.as_ref()).map_or(false, |t| *t == latest.track);
|
||||
|
||||
if self.update_policy.enable_downloading && !running_later && !running_latest && !already_have_latest {
|
||||
if !s.disabled && self.update_policy.enable_downloading && !running_later && !running_latest && !already_have_latest {
|
||||
if let Some(b) = latest.track.binary {
|
||||
if s.fetching.is_none() {
|
||||
if self.updates_path(&Self::update_file_name(&latest.track.version)).exists() {
|
||||
@@ -340,7 +340,7 @@ impl fetch::urlhint::ContractClient for Updater {
|
||||
|
||||
fn call(&self, address: Address, data: Bytes) -> Result<Bytes, String> {
|
||||
self.client.upgrade().ok_or_else(|| "Client not available".to_owned())?
|
||||
.call_contract(address, data)
|
||||
.call_contract(BlockId::Latest, address, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ description = "Ethcore utility library"
|
||||
homepage = "http://parity.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore-util"
|
||||
version = "1.6.2"
|
||||
version = "1.6.6"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
@@ -380,10 +380,7 @@ impl JournalDB for OverlayRecentDB {
|
||||
|
||||
match rc {
|
||||
0 => {}
|
||||
1 => {
|
||||
if cfg!(debug_assertions) && self.backing.get(self.column, &key)?.is_some() {
|
||||
return Err(BaseDataError::AlreadyExists(key).into());
|
||||
}
|
||||
_ if rc > 0 => {
|
||||
batch.put(self.column, &key, &value)
|
||||
}
|
||||
-1 => {
|
||||
@@ -392,7 +389,7 @@ impl JournalDB for OverlayRecentDB {
|
||||
}
|
||||
batch.delete(self.column, &key)
|
||||
}
|
||||
_ => panic!("Attempted to inject invalid state."),
|
||||
_ => panic!("Attempted to inject invalid state ({})", rc),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user