Merge remote-tracking branch 'origin/master' into fix-tx-rpc
This commit is contained in:
commit
d3e684698a
@ -8,7 +8,6 @@ variables:
|
|||||||
RUST_BACKTRACE: "1"
|
RUST_BACKTRACE: "1"
|
||||||
RUSTFLAGS: ""
|
RUSTFLAGS: ""
|
||||||
CARGOFLAGS: ""
|
CARGOFLAGS: ""
|
||||||
NIGHTLY: "nigtly"
|
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
|
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
|
||||||
untracked: true
|
untracked: true
|
||||||
@ -21,7 +20,7 @@ linux-stable:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
- md5sum target/release/parity > parity.md5
|
- md5sum target/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh amd64
|
- sh scripts/deb-build.sh amd64
|
||||||
@ -53,7 +52,7 @@ linux-beta:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
@ -72,7 +71,7 @@ linux-nightly:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
@ -93,7 +92,7 @@ linux-centos:
|
|||||||
script:
|
script:
|
||||||
- export CXX="g++"
|
- export CXX="g++"
|
||||||
- export CC="gcc"
|
- export CC="gcc"
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
- md5sum target/release/parity > parity.md5
|
- md5sum target/release/parity > parity.md5
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
@ -120,7 +119,7 @@ linux-i686:
|
|||||||
script:
|
script:
|
||||||
- export HOST_CC=gcc
|
- export HOST_CC=gcc
|
||||||
- export HOST_CXX=g++
|
- export HOST_CXX=g++
|
||||||
- cargo build --target i686-unknown-linux-gnu --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target i686-unknown-linux-gnu --release $CARGOFLAGS
|
||||||
- strip target/i686-unknown-linux-gnu/release/parity
|
- strip target/i686-unknown-linux-gnu/release/parity
|
||||||
- md5sum target/i686-unknown-linux-gnu/release/parity > parity.md5
|
- md5sum target/i686-unknown-linux-gnu/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh i386
|
- sh scripts/deb-build.sh i386
|
||||||
@ -162,7 +161,7 @@ linux-armv7:
|
|||||||
- echo "[target.armv7-unknown-linux-gnueabihf]" >> .cargo/config
|
- echo "[target.armv7-unknown-linux-gnueabihf]" >> .cargo/config
|
||||||
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target armv7-unknown-linux-gnueabihf --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target armv7-unknown-linux-gnueabihf --release $CARGOFLAGS
|
||||||
- arm-linux-gnueabihf-strip target/armv7-unknown-linux-gnueabihf/release/parity
|
- arm-linux-gnueabihf-strip target/armv7-unknown-linux-gnueabihf/release/parity
|
||||||
- md5sum target/armv7-unknown-linux-gnueabihf/release/parity > parity.md5
|
- md5sum target/armv7-unknown-linux-gnueabihf/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh armhf
|
- sh scripts/deb-build.sh armhf
|
||||||
@ -204,7 +203,7 @@ linux-arm:
|
|||||||
- echo "[target.arm-unknown-linux-gnueabihf]" >> .cargo/config
|
- echo "[target.arm-unknown-linux-gnueabihf]" >> .cargo/config
|
||||||
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target arm-unknown-linux-gnueabihf --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target arm-unknown-linux-gnueabihf --release $CARGOFLAGS
|
||||||
- arm-linux-gnueabihf-strip target/arm-unknown-linux-gnueabihf/release/parity
|
- arm-linux-gnueabihf-strip target/arm-unknown-linux-gnueabihf/release/parity
|
||||||
- md5sum target/arm-unknown-linux-gnueabihf/release/parity > parity.md5
|
- md5sum target/arm-unknown-linux-gnueabihf/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh armhf
|
- sh scripts/deb-build.sh armhf
|
||||||
@ -232,9 +231,9 @@ linux-armv6:
|
|||||||
stage: build
|
stage: build
|
||||||
image: ethcore/rust-armv6:latest
|
image: ethcore/rust-armv6:latest
|
||||||
only:
|
only:
|
||||||
- beta
|
# - beta
|
||||||
- tags
|
# - tags
|
||||||
- stable
|
# - stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- export CC=arm-linux-gnueabi-gcc
|
- export CC=arm-linux-gnueabi-gcc
|
||||||
@ -246,7 +245,7 @@ linux-armv6:
|
|||||||
- echo "[target.arm-unknown-linux-gnueabi]" >> .cargo/config
|
- echo "[target.arm-unknown-linux-gnueabi]" >> .cargo/config
|
||||||
- echo "linker= \"arm-linux-gnueabi-gcc\"" >> .cargo/config
|
- echo "linker= \"arm-linux-gnueabi-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target arm-unknown-linux-gnueabi --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target arm-unknown-linux-gnueabi --release $CARGOFLAGS
|
||||||
- arm-linux-gnueabi-strip target/arm-unknown-linux-gnueabi/release/parity
|
- arm-linux-gnueabi-strip target/arm-unknown-linux-gnueabi/release/parity
|
||||||
- md5sum target/arm-unknown-linux-gnueabi/release/parity > parity.md5
|
- md5sum target/arm-unknown-linux-gnueabi/release/parity > parity.md5
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
@ -281,7 +280,7 @@ linux-aarch64:
|
|||||||
- echo "[target.aarch64-unknown-linux-gnu]" >> .cargo/config
|
- echo "[target.aarch64-unknown-linux-gnu]" >> .cargo/config
|
||||||
- echo "linker= \"aarch64-linux-gnu-gcc\"" >> .cargo/config
|
- echo "linker= \"aarch64-linux-gnu-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target aarch64-unknown-linux-gnu --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target aarch64-unknown-linux-gnu --release $CARGOFLAGS
|
||||||
- aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/parity
|
- aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/parity
|
||||||
- md5sum target/aarch64-unknown-linux-gnu/release/parity > parity.md5
|
- md5sum target/aarch64-unknown-linux-gnu/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh arm64
|
- sh scripts/deb-build.sh arm64
|
||||||
@ -305,41 +304,6 @@ linux-aarch64:
|
|||||||
- target/aarch64-unknown-linux-gnu/release/parity
|
- target/aarch64-unknown-linux-gnu/release/parity
|
||||||
name: "aarch64-unknown-linux-gnu_parity"
|
name: "aarch64-unknown-linux-gnu_parity"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
#linux-alpine:
|
|
||||||
# stage: build
|
|
||||||
# image: ethcore/rust-alpine:latest
|
|
||||||
# only:
|
|
||||||
# - beta
|
|
||||||
# - tags
|
|
||||||
# - stable
|
|
||||||
# - triggers
|
|
||||||
# script:
|
|
||||||
# - export HOST_CC=gcc
|
|
||||||
# - export HOST_CXX=g++
|
|
||||||
# - cargo build --release $CARGOFLAGS
|
|
||||||
# - strip target/release/parity
|
|
||||||
# - md5sum target/release/parity > parity.md5
|
|
||||||
# - sh scripts/deb-build.sh arm64
|
|
||||||
# - cp target/aarch64-unknown-linux-gnu/release/parity deb/usr/bin/parity
|
|
||||||
# - export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
|
||||||
# - dpkg-deb -b deb "parity_"$VER"_arm64.deb"
|
|
||||||
# - md5sum "parity_"$VER"_arm64.deb" > "parity_"$VER"_arm64.deb.md5"
|
|
||||||
# - aws configure set aws_access_key_id $s3_key
|
|
||||||
# - aws configure set aws_secret_access_key $s3_secret
|
|
||||||
# - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; 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/aarch64-unknown-linux-gnu
|
|
||||||
# - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/parity --body target/aarch64-unknown-linux-gnu/release/parity
|
|
||||||
# - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/parity.md5 --body parity.md5
|
|
||||||
# - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/"parity_"$VER"_arm64.deb" --body "parity_"$VER"_arm64.deb"
|
|
||||||
# - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/"parity_"$VER"_arm64.deb.md5" --body "parity_"$VER"_arm64.deb.md5"
|
|
||||||
# tags:
|
|
||||||
# - rust
|
|
||||||
# - rust-alpine
|
|
||||||
# artifacts:
|
|
||||||
# paths:
|
|
||||||
# - target/aarch64-unknown-linux-gnu/release/parity
|
|
||||||
# name: "aarch64-unknown-linux-gnu_parity"
|
|
||||||
# allow_failure: true
|
|
||||||
darwin:
|
darwin:
|
||||||
stage: build
|
stage: build
|
||||||
only:
|
only:
|
||||||
@ -348,8 +312,8 @@ darwin:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release -p ethstore $CARGOFLAGS
|
- cargo build -j 8 --release -p ethstore #$CARGOFLAGS
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j 8 --release #$CARGOFLAGS
|
||||||
- rm -rf parity.md5
|
- rm -rf parity.md5
|
||||||
- md5sum target/release/parity > parity.md5
|
- md5sum target/release/parity > parity.md5
|
||||||
- packagesbuild -v mac/Parity.pkgproj
|
- packagesbuild -v mac/Parity.pkgproj
|
||||||
@ -386,7 +350,7 @@ windows:
|
|||||||
- set RUST_BACKTRACE=1
|
- set RUST_BACKTRACE=1
|
||||||
- set RUSTFLAGS=%RUSTFLAGS%
|
- set RUSTFLAGS=%RUSTFLAGS%
|
||||||
- rustup default stable-x86_64-pc-windows-msvc
|
- rustup default stable-x86_64-pc-windows-msvc
|
||||||
- cargo build --release %CARGOFLAGS%
|
- cargo build -j 8 --release #%CARGOFLAGS%
|
||||||
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll
|
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll
|
||||||
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe
|
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe
|
||||||
- signtool sign /f %keyfile% /p %certpass% target\release\parity.exe
|
- signtool sign /f %keyfile% /p %certpass% target\release\parity.exe
|
||||||
@ -449,7 +413,7 @@ test-windows:
|
|||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
script:
|
script:
|
||||||
- set RUST_BACKTRACE=1
|
- set RUST_BACKTRACE=1
|
||||||
- cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release
|
- cargo -j 8 test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release
|
||||||
tags:
|
tags:
|
||||||
- rust-windows
|
- rust-windows
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
28
Cargo.lock
generated
28
Cargo.lock
generated
@ -3,7 +3,7 @@ name = "parity"
|
|||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)",
|
"ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)",
|
||||||
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -146,15 +146,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.0.96"
|
version = "0.0.103"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy_lints 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.0.96"
|
version = "0.0.103"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -224,7 +224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "elastic-array"
|
name = "elastic-array"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/ethcore/elastic-array#70e4012e691b732c7c4cb04e9232799e6aa268bc"
|
source = "git+https://github.com/ethcore/elastic-array#346f1ba5982576dab9d0b8fa178b50e1db0a21cd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -280,7 +280,7 @@ dependencies = [
|
|||||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.4.0",
|
"ethash 1.4.0",
|
||||||
@ -333,7 +333,7 @@ dependencies = [
|
|||||||
name = "ethcore-dapps"
|
name = "ethcore-dapps"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-devtools 1.4.0",
|
"ethcore-devtools 1.4.0",
|
||||||
"ethcore-hash-fetch 1.5.0",
|
"ethcore-hash-fetch 1.5.0",
|
||||||
@ -490,7 +490,7 @@ dependencies = [
|
|||||||
name = "ethcore-rpc"
|
name = "ethcore-rpc"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.4.0",
|
"ethash 1.4.0",
|
||||||
"ethcore 1.5.0",
|
"ethcore 1.5.0",
|
||||||
"ethcore-devtools 1.4.0",
|
"ethcore-devtools 1.4.0",
|
||||||
@ -520,7 +520,7 @@ dependencies = [
|
|||||||
name = "ethcore-signer"
|
name = "ethcore-signer"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-devtools 1.4.0",
|
"ethcore-devtools 1.4.0",
|
||||||
"ethcore-io 1.5.0",
|
"ethcore-io 1.5.0",
|
||||||
@ -559,7 +559,7 @@ version = "1.5.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"elastic-array 0.6.0 (git+https://github.com/ethcore/elastic-array)",
|
"elastic-array 0.6.0 (git+https://github.com/ethcore/elastic-array)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
|
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
|
||||||
@ -649,7 +649,7 @@ dependencies = [
|
|||||||
name = "ethsync"
|
name = "ethsync"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.5.0",
|
"ethcore 1.5.0",
|
||||||
"ethcore-io 1.5.0",
|
"ethcore-io 1.5.0",
|
||||||
@ -1263,7 +1263,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-precompiled"
|
name = "parity-ui-precompiled"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "git+https://github.com/ethcore/js-precompiled.git#cb6836dddf8c9951e056283dcd9e105e97923d07"
|
source = "git+https://github.com/ethcore/js-precompiled.git#b3f0e3ddedf9afee35ca8384a74158df572973c7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2005,8 +2005,8 @@ dependencies = [
|
|||||||
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
||||||
"checksum bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)" = "<none>"
|
"checksum bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)" = "<none>"
|
||||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||||
"checksum clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)" = "6eacf01b0aad84a0817703498f72d252df7c0faf6a5b86d0be4265f1829e459f"
|
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
|
||||||
"checksum clippy_lints 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)" = "a49960c9aab544ce86b004dcb61620e8b898fea5fc0f697a028f460f48221ed6"
|
"checksum clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "ce96ec05bfe018a0d5d43da115e54850ea2217981ff0f2e462780ab9d594651a"
|
||||||
"checksum cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90266f45846f14a1e986c77d1e9c2626b8c342ed806fe60241ec38cc8697b245"
|
"checksum cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90266f45846f14a1e986c77d1e9c2626b8c342ed806fe60241ec38cc8697b245"
|
||||||
"checksum crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "fb974f835e90390c5f9dfac00f05b06dc117299f5ea4e85fbc7bb443af4911cc"
|
"checksum crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "fb974f835e90390c5f9dfac00f05b06dc117299f5ea4e85fbc7bb443af4911cc"
|
||||||
"checksum ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)" = "<none>"
|
"checksum ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)" = "<none>"
|
||||||
|
@ -47,7 +47,7 @@ ethcore-hash-fetch = { path = "ethcore/hash-fetch" }
|
|||||||
rlp = { path = "util/rlp" }
|
rlp = { path = "util/rlp" }
|
||||||
ethcore-stratum = { path = "stratum" }
|
ethcore-stratum = { path = "stratum" }
|
||||||
ethcore-dapps = { path = "dapps", optional = true }
|
ethcore-dapps = { path = "dapps", optional = true }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.2"
|
winapi = "0.2"
|
||||||
|
@ -34,7 +34,7 @@ ethcore-hash-fetch = { path = "../ethcore/hash-fetch" }
|
|||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
parity-ui = { path = "./ui" }
|
parity-ui = { path = "./ui" }
|
||||||
|
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde_codegen = { version = "0.8", optional = true }
|
serde_codegen = { version = "0.8", optional = true }
|
||||||
|
@ -11,7 +11,7 @@ build = "build.rs"
|
|||||||
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
||||||
|
@ -29,7 +29,7 @@ byteorder = "0.5"
|
|||||||
transient-hashmap = "0.1"
|
transient-hashmap = "0.1"
|
||||||
linked-hash-map = "0.3.0"
|
linked-hash-map = "0.3.0"
|
||||||
evmjit = { path = "../evmjit", optional = true }
|
evmjit = { path = "../evmjit", optional = true }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore-io = { path = "../util/io" }
|
ethcore-io = { path = "../util/io" }
|
||||||
|
@ -121,10 +121,6 @@ impl<'db> HashDB for AccountDB<'db>{
|
|||||||
fn remove(&mut self, _key: &H256) {
|
fn remove(&mut self, _key: &H256) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_aux(&self, hash: &[u8]) -> Option<DBValue> {
|
|
||||||
self.db.get_aux(hash)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DB backend wrapper for Account trie
|
/// DB backend wrapper for Account trie
|
||||||
@ -197,18 +193,6 @@ impl<'db> HashDB for AccountDBMut<'db>{
|
|||||||
let key = combine_key(&self.address_hash, key);
|
let key = combine_key(&self.address_hash, key);
|
||||||
self.db.remove(&key)
|
self.db.remove(&key)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_aux(&mut self, hash: Vec<u8>, value: Vec<u8>) {
|
|
||||||
self.db.insert_aux(hash, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_aux(&self, hash: &[u8]) -> Option<DBValue> {
|
|
||||||
self.db.get_aux(hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_aux(&mut self, hash: &[u8]) {
|
|
||||||
self.db.remove_aux(hash);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Wrapping<'db>(&'db HashDB);
|
struct Wrapping<'db>(&'db HashDB);
|
||||||
|
@ -594,9 +594,9 @@ mod tests {
|
|||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use views::BlockView;
|
use views::BlockView;
|
||||||
use util::Address;
|
use util::{Address, TrieFactory};
|
||||||
use util::hash::FixedHash;
|
use util::hash::FixedHash;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
@ -637,7 +637,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
@ -653,7 +653,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
|
||||||
.close_and_lock().seal(engine, vec![]).unwrap();
|
.close_and_lock().seal(engine, vec![]).unwrap();
|
||||||
@ -662,7 +662,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
||||||
|
|
||||||
assert_eq!(e.rlp_bytes(), orig_bytes);
|
assert_eq!(e.rlp_bytes(), orig_bytes);
|
||||||
@ -681,7 +681,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let mut uncle1_header = Header::new();
|
let mut uncle1_header = Header::new();
|
||||||
@ -697,7 +697,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
||||||
|
|
||||||
let bytes = e.rlp_bytes();
|
let bytes = e.rlp_bytes();
|
||||||
|
@ -22,7 +22,7 @@ use std::time::{Instant};
|
|||||||
use time::precise_time_ns;
|
use time::precise_time_ns;
|
||||||
|
|
||||||
// util
|
// util
|
||||||
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock};
|
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, Hashable};
|
||||||
use util::{journaldb, TrieFactory, Trie};
|
use util::{journaldb, TrieFactory, Trie};
|
||||||
use util::trie::TrieSpec;
|
use util::trie::TrieSpec;
|
||||||
use util::{U256, H256, Address, H2048, Uint, FixedHash};
|
use util::{U256, H256, Address, H2048, Uint, FixedHash};
|
||||||
@ -172,9 +172,10 @@ impl Client {
|
|||||||
false => TrieSpec::Secure,
|
false => TrieSpec::Secure,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let trie_factory = TrieFactory::new(trie_spec);
|
||||||
let journal_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
let journal_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
||||||
let mut state_db = StateDB::new(journal_db, config.state_cache_size);
|
let mut state_db = StateDB::new(journal_db, config.state_cache_size);
|
||||||
if state_db.journal_db().is_empty() && try!(spec.ensure_db_good(&mut state_db)) {
|
if state_db.journal_db().is_empty() && try!(spec.ensure_db_good(&mut state_db, &trie_factory)) {
|
||||||
let mut batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
try!(state_db.journal_under(&mut batch, 0, &spec.genesis_header().hash()));
|
try!(state_db.journal_under(&mut batch, 0, &spec.genesis_header().hash()));
|
||||||
try!(db.write(batch).map_err(ClientError::Database));
|
try!(db.write(batch).map_err(ClientError::Database));
|
||||||
@ -216,7 +217,7 @@ impl Client {
|
|||||||
|
|
||||||
let factories = Factories {
|
let factories = Factories {
|
||||||
vm: EvmFactory::new(config.vm_type.clone(), config.jump_table_size),
|
vm: EvmFactory::new(config.vm_type.clone(), config.jump_table_size),
|
||||||
trie: TrieFactory::new(trie_spec),
|
trie: trie_factory,
|
||||||
accountdb: Default::default(),
|
accountdb: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -869,8 +870,8 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn keep_alive(&self) {
|
fn keep_alive(&self) {
|
||||||
let should_wake = match &*self.mode.lock() {
|
let should_wake = match *self.mode.lock() {
|
||||||
&Mode::Dark(..) | &Mode::Passive(..) => true,
|
Mode::Dark(..) | Mode::Passive(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if should_wake {
|
if should_wake {
|
||||||
@ -952,6 +953,10 @@ impl BlockChainClient for Client {
|
|||||||
self.state_at(id).map(|s| s.nonce(address))
|
self.state_at(id).map(|s| s.nonce(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_root(&self, address: &Address, id: BlockID) -> Option<H256> {
|
||||||
|
self.state_at(id).and_then(|s| s.storage_root(address))
|
||||||
|
}
|
||||||
|
|
||||||
fn block_hash(&self, id: BlockID) -> Option<H256> {
|
fn block_hash(&self, id: BlockID) -> Option<H256> {
|
||||||
let chain = self.chain.read();
|
let chain = self.chain.read();
|
||||||
Self::block_hash(&chain, id)
|
Self::block_hash(&chain, id)
|
||||||
@ -969,7 +974,7 @@ impl BlockChainClient for Client {
|
|||||||
self.state_at(id).map(|s| s.storage_at(address, position))
|
self.state_at(id).map(|s| s.storage_at(address, position))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_accounts(&self, id: BlockID) -> Option<Vec<Address>> {
|
fn list_accounts(&self, id: BlockID, after: Option<&Address>, count: u64) -> Option<Vec<Address>> {
|
||||||
if !self.factories.trie.is_fat() {
|
if !self.factories.trie.is_fat() {
|
||||||
trace!(target: "fatdb", "list_accounts: Not a fat DB");
|
trace!(target: "fatdb", "list_accounts: Not a fat DB");
|
||||||
return None;
|
return None;
|
||||||
@ -989,18 +994,68 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let iter = match trie.iter() {
|
let mut iter = match trie.iter() {
|
||||||
Ok(iter) => iter,
|
Ok(iter) => iter,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(after) = after {
|
||||||
|
if let Err(e) = iter.seek(after) {
|
||||||
|
trace!(target: "fatdb", "list_accounts: Couldn't seek the DB: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let accounts = iter.filter_map(|item| {
|
let accounts = iter.filter_map(|item| {
|
||||||
item.ok().map(|(addr, _)| Address::from_slice(&addr))
|
item.ok().map(|(addr, _)| Address::from_slice(&addr))
|
||||||
}).collect();
|
}).take(count as usize).collect();
|
||||||
|
|
||||||
Some(accounts)
|
Some(accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn list_storage(&self, id: BlockID, account: &Address, after: Option<&H256>, count: u64) -> Option<Vec<H256>> {
|
||||||
|
if !self.factories.trie.is_fat() {
|
||||||
|
trace!(target: "fatdb", "list_stroage: Not a fat DB");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let state = match self.state_at(id) {
|
||||||
|
Some(state) => state,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let root = match state.storage_root(account) {
|
||||||
|
Some(root) => root,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (_, db) = state.drop();
|
||||||
|
let account_db = self.factories.accountdb.readonly(db.as_hashdb(), account.sha3());
|
||||||
|
let trie = match self.factories.trie.readonly(account_db.as_hashdb(), &root) {
|
||||||
|
Ok(trie) => trie,
|
||||||
|
_ => {
|
||||||
|
trace!(target: "fatdb", "list_storage: Couldn't open the DB");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut iter = match trie.iter() {
|
||||||
|
Ok(iter) => iter,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(after) = after {
|
||||||
|
if let Err(e) = iter.seek(after) {
|
||||||
|
trace!(target: "fatdb", "list_accounts: Couldn't seek the DB: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let keys = iter.filter_map(|item| {
|
||||||
|
item.ok().map(|(key, _)| H256::from_slice(&key))
|
||||||
|
}).take(count as usize).collect();
|
||||||
|
|
||||||
|
Some(keys)
|
||||||
|
}
|
||||||
|
|
||||||
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction> {
|
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction> {
|
||||||
self.transaction_address(id).and_then(|address| self.chain.read().transaction(&address))
|
self.transaction_address(id).and_then(|address| self.chain.read().transaction(&address))
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
|||||||
let genesis_header = self.spec.genesis_header();
|
let genesis_header = self.spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
self.spec.ensure_db_good(&mut db).unwrap();
|
self.spec.ensure_db_good(&mut db, &TrieFactory::default()).unwrap();
|
||||||
|
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let mut open_block = OpenBlock::new(
|
let mut open_block = OpenBlock::new(
|
||||||
@ -385,6 +385,10 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_root(&self, _address: &Address, _id: BlockID) -> Option<H256> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn latest_nonce(&self, address: &Address) -> U256 {
|
fn latest_nonce(&self, address: &Address) -> U256 {
|
||||||
self.nonce(address, BlockID::Latest).unwrap()
|
self.nonce(address, BlockID::Latest).unwrap()
|
||||||
}
|
}
|
||||||
@ -416,10 +420,13 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_accounts(&self, _id: BlockID) -> Option<Vec<Address>> {
|
fn list_accounts(&self, _id: BlockID, _after: Option<&Address>, _count: u64) -> Option<Vec<Address>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn list_storage(&self, _id: BlockID, _account: &Address, _after: Option<&H256>, _count: u64) -> Option<Vec<H256>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
fn transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
|
fn transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
|
||||||
None // Simple default.
|
None // Simple default.
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,10 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// May not fail on BlockID::Latest.
|
/// May not fail on BlockID::Latest.
|
||||||
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256>;
|
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256>;
|
||||||
|
|
||||||
|
/// Attempt to get address storage root at given block.
|
||||||
|
/// May not fail on BlockID::Latest.
|
||||||
|
fn storage_root(&self, address: &Address, id: BlockID) -> Option<H256>;
|
||||||
|
|
||||||
/// Get address nonce at the latest block's state.
|
/// Get address nonce at the latest block's state.
|
||||||
fn latest_nonce(&self, address: &Address) -> U256 {
|
fn latest_nonce(&self, address: &Address) -> U256 {
|
||||||
self.nonce(address, BlockID::Latest)
|
self.nonce(address, BlockID::Latest)
|
||||||
@ -114,7 +118,12 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`.
|
/// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`.
|
||||||
fn list_accounts(&self, id: BlockID) -> Option<Vec<Address>>;
|
/// If `after` is set the list starts with the following item.
|
||||||
|
fn list_accounts(&self, id: BlockID, after: Option<&Address>, count: u64) -> Option<Vec<Address>>;
|
||||||
|
|
||||||
|
/// Get a list of all storage keys in the block `id`, if fat DB is in operation, otherwise `None`.
|
||||||
|
/// If `after` is set the list starts with the following item.
|
||||||
|
fn list_storage(&self, id: BlockID, account: &Address, after: Option<&H256>, count: u64) -> Option<Vec<H256>>;
|
||||||
|
|
||||||
/// Get transaction with given hash.
|
/// Get transaction with given hash.
|
||||||
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction>;
|
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction>;
|
||||||
|
@ -124,7 +124,7 @@ impl AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn step_proposer(&self, step: usize) -> &Address {
|
fn step_proposer(&self, step: usize) -> &Address {
|
||||||
let ref p = self.our_params;
|
let p = &self.our_params;
|
||||||
p.authorities.get(step % p.authority_n).expect("There are authority_n authorities; taking number modulo authority_n gives number in authority_n range; qed")
|
p.authorities.get(step % p.authority_n).expect("There are authority_n authorities; taking number modulo authority_n gives number in authority_n range; qed")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ impl Engine for AuthorityRound {
|
|||||||
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
|
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
|
||||||
|
|
||||||
fn is_sealer(&self, author: &Address) -> Option<bool> {
|
fn is_sealer(&self, author: &Address) -> Option<bool> {
|
||||||
let ref p = self.our_params;
|
let p = &self.our_params;
|
||||||
Some(p.authorities.contains(author))
|
Some(p.authorities.contains(author))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ impl Engine for AuthorityRound {
|
|||||||
|
|
||||||
let step = try!(header_step(header));
|
let step = try!(header_step(header));
|
||||||
// Check if parent is from a previous step.
|
// Check if parent is from a previous step.
|
||||||
if step == try!(header_step(parent)) {
|
if step == try!(header_step(parent)) {
|
||||||
trace!(target: "poa", "Multiple blocks proposed for step {}.", step);
|
trace!(target: "poa", "Multiple blocks proposed for step {}.", step);
|
||||||
try!(Err(BlockError::DoubleVote(header.author().clone())));
|
try!(Err(BlockError::DoubleVote(header.author().clone())));
|
||||||
}
|
}
|
||||||
@ -315,6 +315,7 @@ impl Engine for AuthorityRound {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use header::Header;
|
use header::Header;
|
||||||
use error::{Error, BlockError};
|
use error::{Error, BlockError};
|
||||||
@ -384,9 +385,9 @@ mod tests {
|
|||||||
let engine = &*spec.engine;
|
let engine = &*spec.engine;
|
||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db1 = get_temp_state_db().take();
|
let mut db1 = get_temp_state_db().take();
|
||||||
spec.ensure_db_good(&mut db1).unwrap();
|
spec.ensure_db_good(&mut db1, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let mut db2 = get_temp_state_db().take();
|
let mut db2 = get_temp_state_db().take();
|
||||||
spec.ensure_db_good(&mut db2).unwrap();
|
spec.ensure_db_good(&mut db2, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b1 = b1.close_and_lock();
|
let b1 = b1.close_and_lock();
|
||||||
|
@ -184,6 +184,7 @@ impl Engine for BasicAuthority {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use block::*;
|
use block::*;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use error::{BlockError, Error};
|
use error::{BlockError, Error};
|
||||||
@ -256,7 +257,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
|
@ -68,6 +68,7 @@ impl Engine for InstantSeal {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
@ -84,7 +85,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
|
@ -422,6 +422,7 @@ impl Header {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use block::*;
|
use block::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
@ -438,7 +439,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
@ -452,7 +453,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let mut uncle = Header::new();
|
let mut uncle = Header::new();
|
||||||
|
@ -72,6 +72,7 @@ pub fn new_morden() -> Spec { load(include_bytes!("../../res/ethereum/morden.jso
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use state::*;
|
use state::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
@ -84,7 +85,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap();
|
let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap();
|
||||||
assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()), 1u64.into());
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()), 1u64.into());
|
||||||
assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()), 1u64.into());
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()), 1u64.into());
|
||||||
|
@ -197,19 +197,17 @@ impl<Gas: CostType> Gasometer<Gas> {
|
|||||||
let address = u256_to_address(stack.peek(1));
|
let address = u256_to_address(stack.peek(1));
|
||||||
let is_value_transfer = !stack.peek(2).is_zero();
|
let is_value_transfer = !stack.peek(2).is_zero();
|
||||||
|
|
||||||
if instruction == instructions::CALL {
|
if instruction == instructions::CALL && (
|
||||||
if (
|
(!schedule.no_empty && !ext.exists(&address))
|
||||||
!schedule.no_empty && !ext.exists(&address)
|
||
|
||||||
) || (
|
(schedule.no_empty && is_value_transfer && !ext.exists_and_not_null(&address))
|
||||||
schedule.no_empty && is_value_transfer && !ext.exists_and_not_null(&address)
|
) {
|
||||||
) {
|
gas = overflowing!(gas.overflow_add(schedule.call_new_account_gas.into()));
|
||||||
gas = overflowing!(gas.overflow_add(schedule.call_new_account_gas.into()));
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if is_value_transfer {
|
if is_value_transfer {
|
||||||
gas = overflowing!(gas.overflow_add(schedule.call_value_transfer_gas.into()));
|
gas = overflowing!(gas.overflow_add(schedule.call_value_transfer_gas.into()));
|
||||||
};
|
}
|
||||||
|
|
||||||
let requested = *stack.peek(0);
|
let requested = *stack.peek(0);
|
||||||
|
|
||||||
@ -347,7 +345,7 @@ fn test_mem_gas_cost() {
|
|||||||
let result = gasometer.mem_gas_cost(&schedule, current_mem_size, &mem_size);
|
let result = gasometer.mem_gas_cost(&schedule, current_mem_size, &mem_size);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
if let Ok(_) = result {
|
if result.is_ok() {
|
||||||
assert!(false, "Should fail with OutOfGas");
|
assert!(false, "Should fail with OutOfGas");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ impl Ext for FakeExt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exists_and_not_null(&self, address: &Address) -> bool {
|
fn exists_and_not_null(&self, address: &Address) -> bool {
|
||||||
self.balances.get(address).map_or(false, |b| !b.is_zero())
|
self.balances.get(address).map_or(false, |b| !b.is_zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn origin_balance(&self) -> U256 {
|
fn origin_balance(&self) -> U256 {
|
||||||
@ -103,7 +103,7 @@ impl Ext for FakeExt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn balance(&self, address: &Address) -> U256 {
|
fn balance(&self, address: &Address) -> U256 {
|
||||||
*self.balances.get(address).unwrap()
|
self.balances[address]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blockhash(&self, number: &U256) -> H256 {
|
fn blockhash(&self, number: &U256) -> H256 {
|
||||||
|
@ -445,7 +445,7 @@ impl<'a> Executive<'a> {
|
|||||||
|
|
||||||
trace!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, sender);
|
trace!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, sender);
|
||||||
// Below: NoEmpty is safe since the sender must already be non-null to have sent this transaction
|
// Below: NoEmpty is safe since the sender must already be non-null to have sent this transaction
|
||||||
self.state.add_balance(&sender, &refund_value, CleanupMode::NoEmpty);
|
self.state.add_balance(&sender, &refund_value, CleanupMode::NoEmpty);
|
||||||
trace!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author);
|
trace!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author);
|
||||||
self.state.add_balance(&self.info.author, &fees_value, substate.to_cleanup_mode(&schedule));
|
self.state.add_balance(&self.info.author, &fees_value, substate.to_cleanup_mode(&schedule));
|
||||||
|
|
||||||
@ -514,9 +514,11 @@ impl<'a> Executive<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::sync::Arc;
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::*;
|
use util::{H256, U256, U512, Address, Uint, FixedHash, FromHex, FromStr};
|
||||||
|
use util::bytes::BytesRef;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use action_params::{ActionParams, ActionValue};
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use evm::{Factory, VMType};
|
use evm::{Factory, VMType};
|
||||||
|
@ -151,7 +151,7 @@ impl GasPriceCalibrator {
|
|||||||
if Instant::now() >= self.next_calibration {
|
if Instant::now() >= self.next_calibration {
|
||||||
let usd_per_tx = self.options.usd_per_tx;
|
let usd_per_tx = self.options.usd_per_tx;
|
||||||
trace!(target: "miner", "Getting price info");
|
trace!(target: "miner", "Getting price info");
|
||||||
if let Ok(_) = PriceInfo::get(move |price: PriceInfo| {
|
let price_info = PriceInfo::get(move |price: PriceInfo| {
|
||||||
trace!(target: "miner", "Price info arrived: {:?}", price);
|
trace!(target: "miner", "Price info arrived: {:?}", price);
|
||||||
let usd_per_eth = price.ethusd;
|
let usd_per_eth = price.ethusd;
|
||||||
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
||||||
@ -159,7 +159,9 @@ impl GasPriceCalibrator {
|
|||||||
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
||||||
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
||||||
set_price(U256::from(wei_per_gas as u64));
|
set_price(U256::from(wei_per_gas as u64));
|
||||||
}) {
|
});
|
||||||
|
|
||||||
|
if price_info.is_ok() {
|
||||||
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
||||||
} else {
|
} else {
|
||||||
warn!(target: "miner", "Unable to update Ether price.");
|
warn!(target: "miner", "Unable to update Ether price.");
|
||||||
@ -1139,15 +1141,16 @@ impl MinerService for Miner {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use super::super::{MinerService, PrioritizationStrategy};
|
use super::super::{MinerService, PrioritizationStrategy};
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::*;
|
use block::IsBlock;
|
||||||
|
use util::{U256, Uint, FromHex};
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
|
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use types::transaction::{Transaction, SignedTransaction, Action};
|
use types::transaction::{Transaction, SignedTransaction, Action};
|
||||||
use block::*;
|
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use tests::helpers::{generate_dummy_client};
|
use tests::helpers::{generate_dummy_client};
|
||||||
|
|
||||||
|
@ -990,7 +990,7 @@ impl TransactionQueue {
|
|||||||
let mut update_last_nonce_to = None;
|
let mut update_last_nonce_to = None;
|
||||||
{
|
{
|
||||||
let by_nonce = self.future.by_address.row_mut(&address);
|
let by_nonce = self.future.by_address.row_mut(&address);
|
||||||
if let None = by_nonce {
|
if by_nonce.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut by_nonce = by_nonce.expect("None is tested in early-exit condition above; qed");
|
let mut by_nonce = by_nonce.expect("None is tested in early-exit condition above; qed");
|
||||||
@ -1212,12 +1212,12 @@ mod test {
|
|||||||
use util::table::*;
|
use util::table::*;
|
||||||
use util::*;
|
use util::*;
|
||||||
use ethkey::{Random, Generator};
|
use ethkey::{Random, Generator};
|
||||||
use transaction::*;
|
|
||||||
use error::{Error, TransactionError};
|
use error::{Error, TransactionError};
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::{TransactionSet, TransactionOrder, VerifiedTransaction};
|
use super::{TransactionSet, TransactionOrder, VerifiedTransaction};
|
||||||
use miner::local_transactions::LocalTransactionsList;
|
use miner::local_transactions::LocalTransactionsList;
|
||||||
use client::TransactionImportResult;
|
use client::TransactionImportResult;
|
||||||
|
use transaction::{SignedTransaction, Transaction, Action};
|
||||||
|
|
||||||
fn unwrap_tx_err(err: Result<TransactionImportResult, Error>) -> TransactionError {
|
fn unwrap_tx_err(err: Result<TransactionImportResult, Error>) -> TransactionError {
|
||||||
match err.unwrap_err() {
|
match err.unwrap_err() {
|
||||||
|
@ -64,13 +64,13 @@ impl PodAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Place additional data into given hash DB.
|
/// Place additional data into given hash DB.
|
||||||
pub fn insert_additional(&self, db: &mut AccountDBMut) {
|
pub fn insert_additional(&self, db: &mut AccountDBMut, factory: &TrieFactory) {
|
||||||
match self.code {
|
match self.code {
|
||||||
Some(ref c) if !c.is_empty() => { db.insert(c); }
|
Some(ref c) if !c.is_empty() => { db.insert(c); }
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
let mut r = H256::new();
|
let mut r = H256::new();
|
||||||
let mut t = SecTrieDBMut::new(db, &mut r);
|
let mut t = factory.create(db, &mut r);
|
||||||
for (k, v) in &self.storage {
|
for (k, v) in &self.storage {
|
||||||
if let Err(e) = t.insert(k, &rlp::encode(&U256::from(&**v))) {
|
if let Err(e) = t.insert(k, &rlp::encode(&U256::from(&**v))) {
|
||||||
warn!("Encountered potential DB corruption: {}", e);
|
warn!("Encountered potential DB corruption: {}", e);
|
||||||
|
@ -552,11 +552,11 @@ const POW_VERIFY_RATE: f32 = 0.02;
|
|||||||
pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &Engine, chain: &BlockChain, body: Option<&[u8]>, always: bool) -> Result<(), ::error::Error> {
|
pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &Engine, chain: &BlockChain, body: Option<&[u8]>, always: bool) -> Result<(), ::error::Error> {
|
||||||
if always || rng.gen::<f32>() <= POW_VERIFY_RATE {
|
if always || rng.gen::<f32>() <= POW_VERIFY_RATE {
|
||||||
match chain.block_header(header.parent_hash()) {
|
match chain.block_header(header.parent_hash()) {
|
||||||
Some(parent) => engine.verify_block_family(&header, &parent, body),
|
Some(parent) => engine.verify_block_family(header, &parent, body),
|
||||||
None => engine.verify_block_seal(&header),
|
None => engine.verify_block_seal(header),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
engine.verify_block_basic(&header, body)
|
engine.verify_block_basic(header, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,13 +244,13 @@ impl Spec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
||||||
pub fn ensure_db_good(&self, db: &mut StateDB) -> Result<bool, Box<TrieError>> {
|
pub fn ensure_db_good(&self, db: &mut StateDB, factory: &TrieFactory) -> Result<bool, Box<TrieError>> {
|
||||||
if !db.as_hashdb().contains(&self.state_root()) {
|
if !db.as_hashdb().contains(&self.state_root()) {
|
||||||
trace!(target: "spec", "ensure_db_good: Fresh database? Cannot find state root {}", self.state_root());
|
trace!(target: "spec", "ensure_db_good: Fresh database? Cannot find state root {}", self.state_root());
|
||||||
let mut root = H256::new();
|
let mut root = H256::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut t = SecTrieDBMut::new(db.as_hashdb_mut(), &mut root);
|
let mut t = factory.create(db.as_hashdb_mut(), &mut root);
|
||||||
for (address, account) in self.genesis_state.get().iter() {
|
for (address, account) in self.genesis_state.get().iter() {
|
||||||
try!(t.insert(&**address, &account.rlp()));
|
try!(t.insert(&**address, &account.rlp()));
|
||||||
}
|
}
|
||||||
@ -258,7 +258,7 @@ impl Spec {
|
|||||||
trace!(target: "spec", "ensure_db_good: Populated sec trie; root is {}", root);
|
trace!(target: "spec", "ensure_db_good: Populated sec trie; root is {}", root);
|
||||||
for (address, account) in self.genesis_state.get().iter() {
|
for (address, account) in self.genesis_state.get().iter() {
|
||||||
db.note_non_null_account(address);
|
db.note_non_null_account(address);
|
||||||
account.insert_additional(&mut AccountDBMut::new(db.as_hashdb_mut(), address));
|
account.insert_additional(&mut AccountDBMut::new(db.as_hashdb_mut(), address), factory);
|
||||||
}
|
}
|
||||||
assert!(db.as_hashdb().contains(&self.state_root()));
|
assert!(db.as_hashdb().contains(&self.state_root()));
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
@ -314,11 +314,10 @@ impl Account {
|
|||||||
self.code_hash == SHA3_EMPTY
|
self.code_hash == SHA3_EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
/// Return the storage root associated with this account or None if it has been altered via the overlay.
|
||||||
/// return the storage root associated with this account or None if it has been altered via the overlay.
|
|
||||||
pub fn storage_root(&self) -> Option<&H256> { if self.storage_is_clean() {Some(&self.storage_root)} else {None} }
|
pub fn storage_root(&self) -> Option<&H256> { if self.storage_is_clean() {Some(&self.storage_root)} else {None} }
|
||||||
|
|
||||||
/// return the storage overlay.
|
/// Return the storage overlay.
|
||||||
pub fn storage_changes(&self) -> &HashMap<H256, H256> { &self.storage_changes }
|
pub fn storage_changes(&self) -> &HashMap<H256, H256> { &self.storage_changes }
|
||||||
|
|
||||||
/// Increment the nonce of the account by one.
|
/// Increment the nonce of the account by one.
|
||||||
@ -445,11 +444,10 @@ impl fmt::Debug for Account {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use rlp::{UntrustedRlp, RlpType, View, Compressible};
|
||||||
use util::*;
|
use util::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use account_db::*;
|
use account_db::*;
|
||||||
use rlp::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn account_compress() {
|
fn account_compress() {
|
||||||
|
@ -369,6 +369,12 @@ impl State {
|
|||||||
|a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce()))
|
|a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the storage root of account `a`.
|
||||||
|
pub fn storage_root(&self, a: &Address) -> Option<H256> {
|
||||||
|
self.ensure_cached(a, RequireCache::None, true,
|
||||||
|
|a| a.as_ref().and_then(|account| account.storage_root().cloned()))
|
||||||
|
}
|
||||||
|
|
||||||
/// Mutate storage of account `address` so that it is `value` for `key`.
|
/// Mutate storage of account `address` so that it is `value` for `key`.
|
||||||
pub fn storage_at(&self, address: &Address, key: &H256) -> H256 {
|
pub fn storage_at(&self, address: &Address, key: &H256) -> H256 {
|
||||||
// Storage key search and update works like this:
|
// Storage key search and update works like this:
|
||||||
@ -445,6 +451,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add `incr` to the balance of account `a`.
|
/// Add `incr` to the balance of account `a`.
|
||||||
|
#[cfg_attr(feature="dev", allow(single_match))]
|
||||||
pub fn add_balance(&mut self, a: &Address, incr: &U256, cleanup_mode: CleanupMode) {
|
pub fn add_balance(&mut self, a: &Address, incr: &U256, cleanup_mode: CleanupMode) {
|
||||||
trace!(target: "state", "add_balance({}, {}): {}", a, incr, self.balance(a));
|
trace!(target: "state", "add_balance({}, {}): {}", a, incr, self.balance(a));
|
||||||
let is_value_transfer = !incr.is_zero();
|
let is_value_transfer = !incr.is_zero();
|
||||||
|
@ -57,6 +57,7 @@ impl Substate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the cleanup mode object from this.
|
/// Get the cleanup mode object from this.
|
||||||
|
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
||||||
pub fn to_cleanup_mode(&mut self, schedule: &Schedule) -> CleanupMode {
|
pub fn to_cleanup_mode(&mut self, schedule: &Schedule) -> CleanupMode {
|
||||||
match (schedule.no_empty, schedule.kill_empty) {
|
match (schedule.no_empty, schedule.kill_empty) {
|
||||||
(false, _) => CleanupMode::ForceCreate,
|
(false, _) => CleanupMode::ForceCreate,
|
||||||
|
@ -397,6 +397,7 @@ impl StateDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get cached code based on hash.
|
/// Get cached code based on hash.
|
||||||
|
#[cfg_attr(feature="dev", allow(map_clone))]
|
||||||
pub fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>> {
|
pub fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>> {
|
||||||
let mut cache = self.code_cache.lock();
|
let mut cache = self.code_cache.lock();
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ fn should_return_registrar() {
|
|||||||
&db_config
|
&db_config
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let params = client.additional_params();
|
let params = client.additional_params();
|
||||||
let address = params.get("registrar").unwrap();
|
let address = ¶ms["registrar"];
|
||||||
|
|
||||||
assert_eq!(address.len(), 40);
|
assert_eq!(address.len(), 40);
|
||||||
assert!(U256::from_str(address).is_ok());
|
assert!(U256::from_str(address).is_ok());
|
||||||
@ -93,7 +93,7 @@ fn imports_good_block() {
|
|||||||
&db_config
|
&db_config
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let good_block = get_good_dummy_block();
|
let good_block = get_good_dummy_block();
|
||||||
if let Err(_) = client.import_block(good_block) {
|
if client.import_block(good_block).is_err() {
|
||||||
panic!("error importing block being good by definition");
|
panic!("error importing block being good by definition");
|
||||||
}
|
}
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
@ -203,18 +203,18 @@ fn can_collect_garbage() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_generate_gas_price_median() {
|
fn can_generate_gas_price_median() {
|
||||||
let client_result = generate_dummy_client_with_data(3, 1, &vec_into![1, 2, 3]);
|
let client_result = generate_dummy_client_with_data(3, 1, slice_into![1, 2, 3]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
assert_eq!(Some(U256::from(2)), client.gas_price_median(3));
|
assert_eq!(Some(U256::from(2)), client.gas_price_median(3));
|
||||||
|
|
||||||
let client_result = generate_dummy_client_with_data(4, 1, &vec_into![1, 4, 3, 2]);
|
let client_result = generate_dummy_client_with_data(4, 1, slice_into![1, 4, 3, 2]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
assert_eq!(Some(U256::from(3)), client.gas_price_median(4));
|
assert_eq!(Some(U256::from(3)), client.gas_price_median(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_generate_gas_price_histogram() {
|
fn can_generate_gas_price_histogram() {
|
||||||
let client_result = generate_dummy_client_with_data(20, 1, &vec_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]);
|
let client_result = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
|
|
||||||
let hist = client.gas_price_histogram(20, 5).unwrap();
|
let hist = client.gas_price_histogram(20, 5).unwrap();
|
||||||
@ -224,7 +224,7 @@ fn can_generate_gas_price_histogram() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_gas_price_histogram() {
|
fn empty_gas_price_histogram() {
|
||||||
let client_result = generate_dummy_client_with_data(20, 0, &vec_into![]);
|
let client_result = generate_dummy_client_with_data(20, 0, slice_into![]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
|
|
||||||
assert!(client.gas_price_histogram(20, 5).is_none());
|
assert!(client.gas_price_histogram(20, 5).is_none());
|
||||||
|
@ -18,6 +18,7 @@ use ethkey::KeyPair;
|
|||||||
use io::*;
|
use io::*;
|
||||||
use client::{BlockChainClient, Client, ClientConfig};
|
use client::{BlockChainClient, Client, ClientConfig};
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use spec::*;
|
use spec::*;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use block::{OpenBlock, Drain};
|
use block::{OpenBlock, Drain};
|
||||||
@ -157,7 +158,7 @@ pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_numbe
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
test_spec.ensure_db_good(&mut db).unwrap();
|
test_spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let genesis_header = test_spec.genesis_header();
|
let genesis_header = test_spec.genesis_header();
|
||||||
|
|
||||||
let mut rolling_timestamp = 40;
|
let mut rolling_timestamp = 40;
|
||||||
@ -262,7 +263,7 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<
|
|||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
for block in &blocks {
|
for block in &blocks {
|
||||||
if let Err(_) = client.import_block(block.clone()) {
|
if client.import_block(block.clone()).is_err() {
|
||||||
panic!("panic importing block which is well-formed");
|
panic!("panic importing block which is well-formed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,16 +19,16 @@
|
|||||||
pub use std::time::Duration;
|
pub use std::time::Duration;
|
||||||
use client::Mode as ClientMode;
|
use client::Mode as ClientMode;
|
||||||
|
|
||||||
/// IPC-capable shadow-type for client::config::Mode
|
/// IPC-capable shadow-type for `client::config::Mode`
|
||||||
#[derive(Clone, Binary, Debug)]
|
#[derive(Clone, Binary, Debug)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
/// Same as ClientMode::Off.
|
/// Same as `ClientMode::Off`.
|
||||||
Off,
|
Off,
|
||||||
/// Same as ClientMode::Dark; values in seconds.
|
/// Same as `ClientMode::Dark`; values in seconds.
|
||||||
Dark(u64),
|
Dark(u64),
|
||||||
/// Same as ClientMode::Passive; values in seconds.
|
/// Same as `ClientMode::Passive`; values in seconds.
|
||||||
Passive(u64, u64),
|
Passive(u64, u64),
|
||||||
/// Same as ClientMode::Active.
|
/// Same as `ClientMode::Active`.
|
||||||
Active,
|
Active,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,4 +52,4 @@ impl From<Mode> for ClientMode {
|
|||||||
Mode::Active => ClientMode::Active,
|
Mode::Active => ClientMode::Active,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ pub struct Transaction {
|
|||||||
impl Transaction {
|
impl Transaction {
|
||||||
/// Append object with a without signature into RLP stream
|
/// Append object with a without signature into RLP stream
|
||||||
pub fn rlp_append_unsigned_transaction(&self, s: &mut RlpStream, network_id: Option<u8>) {
|
pub fn rlp_append_unsigned_transaction(&self, s: &mut RlpStream, network_id: Option<u8>) {
|
||||||
s.begin_list(if let None = network_id { 6 } else { 9 });
|
s.begin_list(if network_id.is_none() { 6 } else { 9 });
|
||||||
s.append(&self.nonce);
|
s.append(&self.nonce);
|
||||||
s.append(&self.gas_price);
|
s.append(&self.gas_price);
|
||||||
s.append(&self.gas);
|
s.append(&self.gas);
|
||||||
@ -210,7 +210,7 @@ pub struct SignedTransaction {
|
|||||||
/// Plain Transaction.
|
/// Plain Transaction.
|
||||||
unsigned: Transaction,
|
unsigned: Transaction,
|
||||||
/// The V field of the signature; the LS bit described which half of the curve our point falls
|
/// The V field of the signature; the LS bit described which half of the curve our point falls
|
||||||
/// in. The MS bits describe which network this transaction is for. If 27/28, its for all networks.
|
/// in. The MS bits describe which network this transaction is for. If 27/28, its for all networks.
|
||||||
v: u8,
|
v: u8,
|
||||||
/// The R field of the signature; helps describe the point on the curve.
|
/// The R field of the signature; helps describe the point on the curve.
|
||||||
r: U256,
|
r: U256,
|
||||||
@ -464,7 +464,7 @@ fn should_agree_with_vitalik() {
|
|||||||
let signed: SignedTransaction = decode(&FromHex::from_hex(tx_data).unwrap());
|
let signed: SignedTransaction = decode(&FromHex::from_hex(tx_data).unwrap());
|
||||||
signed.check_low_s().unwrap();
|
signed.check_low_s().unwrap();
|
||||||
assert_eq!(signed.sender().unwrap(), address.into());
|
assert_eq!(signed.sender().unwrap(), address.into());
|
||||||
flushln!("networkid: {:?}", signed.network_id());
|
flushln!("networkid: {:?}", signed.network_id());
|
||||||
};
|
};
|
||||||
|
|
||||||
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce")
|
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce")
|
||||||
@ -477,4 +477,4 @@ fn should_agree_with_vitalik() {
|
|||||||
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332")
|
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332")
|
||||||
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029")
|
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029")
|
||||||
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f")
|
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f")
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ use header::{BlockNumber, Header};
|
|||||||
use rlp::{UntrustedRlp, View};
|
use rlp::{UntrustedRlp, View};
|
||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
use views::BlockView;
|
use views::BlockView;
|
||||||
|
use time::get_time;
|
||||||
|
|
||||||
/// Preprocessed block data gathered in `verify_block_unordered` call
|
/// Preprocessed block data gathered in `verify_block_unordered` call
|
||||||
pub struct PreverifiedBlock {
|
pub struct PreverifiedBlock {
|
||||||
@ -209,6 +210,10 @@ pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Erro
|
|||||||
if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size {
|
if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size {
|
||||||
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
|
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
|
||||||
}
|
}
|
||||||
|
let max_time = get_time().sec as u64 + 30;
|
||||||
|
if header.timestamp() > max_time {
|
||||||
|
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +263,7 @@ mod tests {
|
|||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use types::log_entry::{LogEntry, LocalizedLogEntry};
|
use types::log_entry::{LogEntry, LocalizedLogEntry};
|
||||||
use rlp::View;
|
use rlp::View;
|
||||||
|
use time::get_time;
|
||||||
|
|
||||||
fn check_ok(result: Result<(), Error>) {
|
fn check_ok(result: Result<(), Error>) {
|
||||||
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
||||||
@ -271,6 +277,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_fail_timestamp(result: Result<(), Error>) {
|
||||||
|
match result {
|
||||||
|
Err(Error::Block(BlockError::InvalidTimestamp(_))) => (),
|
||||||
|
Err(other) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: {:?}", other),
|
||||||
|
Ok(_) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: Ok"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct TestBlockChain {
|
struct TestBlockChain {
|
||||||
blocks: HashMap<H256, Bytes>,
|
blocks: HashMap<H256, Bytes>,
|
||||||
numbers: HashMap<BlockNumber, H256>,
|
numbers: HashMap<BlockNumber, H256>,
|
||||||
@ -515,6 +529,14 @@ mod tests {
|
|||||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
||||||
InvalidTimestamp(OutOfBounds { max: None, min: Some(parent.timestamp() + 1), found: header.timestamp() }));
|
InvalidTimestamp(OutOfBounds { max: None, min: Some(parent.timestamp() + 1), found: header.timestamp() }));
|
||||||
|
|
||||||
|
header = good.clone();
|
||||||
|
header.set_timestamp(2450000000);
|
||||||
|
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||||
|
|
||||||
|
header = good.clone();
|
||||||
|
header.set_timestamp(get_time().sec as u64 + 40);
|
||||||
|
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||||
|
|
||||||
header = good.clone();
|
header = good.clone();
|
||||||
header.set_number(9);
|
header.set_number(9);
|
||||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
||||||
|
4
js/assets/images/certifications/unknown.svg
Normal file
4
js/assets/images/certifications/unknown.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle fill="#4A90E2" cx="50" cy="50" r="50"/>
|
||||||
|
<path d="M20 45 L10 55 L35 85 L90 35 L80 25 L36 65 z" fill="#FFF"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 213 B |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "0.2.78",
|
"version": "0.2.80",
|
||||||
"main": "release/index.js",
|
"main": "release/index.js",
|
||||||
"jsnext:main": "src/index.js",
|
"jsnext:main": "src/index.js",
|
||||||
"author": "Parity Team <admin@parity.io>",
|
"author": "Parity Team <admin@parity.io>",
|
||||||
@ -72,6 +72,7 @@
|
|||||||
"core-js": "~2.4.1",
|
"core-js": "~2.4.1",
|
||||||
"coveralls": "~2.11.11",
|
"coveralls": "~2.11.11",
|
||||||
"css-loader": "~0.26.0",
|
"css-loader": "~0.26.0",
|
||||||
|
"ejs-loader": "~0.3.0",
|
||||||
"enzyme": "2.3.0",
|
"enzyme": "2.3.0",
|
||||||
"eslint": "~3.10.2",
|
"eslint": "~3.10.2",
|
||||||
"eslint-config-semistandard": "~7.0.0",
|
"eslint-config-semistandard": "~7.0.0",
|
||||||
|
@ -144,7 +144,8 @@ export function outSignerRequest (request) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'payload':
|
case 'payload':
|
||||||
request[key].transaction = outTransaction(request[key].transaction);
|
request[key].signTransaction = outTransaction(request[key].signTransaction);
|
||||||
|
request[key].sendTransaction = outTransaction(request[key].sendTransaction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
1
js/src/contracts/abi/badgereg.json
Normal file
1
js/src/contracts/abi/badgereg.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"fromName","outputs":[{"name":"id","type":"uint256"},{"name":"addr","type":"address"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"badgeCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"}],"name":"meta","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"}],"name":"unregister","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"fromAddress","outputs":[{"name":"id","type":"uint256"},{"name":"name","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"badge","outputs":[{"name":"addr","type":"address"},{"name":"name","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"},{"name":"_value","type":"bytes32"}],"name":"setMeta","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_name","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"registerAs","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"addr","type":"address"}],"name":"Registered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"id","type":"uint256"}],"name":"Unregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":true,"name":"key","type":"bytes32"},{"indexed":false,"name":"value","type":"bytes32"}],"name":"MetaChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]
|
1
js/src/contracts/abi/certifier.json
Normal file
1
js/src/contracts/abi/certifier.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"certified","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Confirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Revoked","type":"event"}]
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import badgereg from './badgereg.json';
|
||||||
import basiccoin from './basiccoin.json';
|
import basiccoin from './basiccoin.json';
|
||||||
import basiccoinmanager from './basiccoinmanager.json';
|
import basiccoinmanager from './basiccoinmanager.json';
|
||||||
import dappreg from './dappreg.json';
|
import dappreg from './dappreg.json';
|
||||||
@ -28,6 +29,7 @@ import tokenreg from './tokenreg.json';
|
|||||||
import wallet from './wallet.json';
|
import wallet from './wallet.json';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
badgereg,
|
||||||
basiccoin,
|
basiccoin,
|
||||||
basiccoinmanager,
|
basiccoinmanager,
|
||||||
dappreg,
|
dappreg,
|
||||||
|
66
js/src/contracts/badgereg.js
Normal file
66
js/src/contracts/badgereg.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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 { bytesToHex, hex2Ascii } from '../api/util/format';
|
||||||
|
|
||||||
|
import ABI from './abi/certifier.json';
|
||||||
|
|
||||||
|
const ZERO = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||||
|
|
||||||
|
export default class BadgeReg {
|
||||||
|
constructor (api, registry) {
|
||||||
|
this._api = api;
|
||||||
|
this._registry = registry;
|
||||||
|
|
||||||
|
registry.getContract('badgereg');
|
||||||
|
this.certifiers = {}; // by name
|
||||||
|
this.contracts = {}; // by name
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchCertifier (name) {
|
||||||
|
if (this.certifiers[name]) {
|
||||||
|
return Promise.resolve(this.certifiers[name]);
|
||||||
|
}
|
||||||
|
return this._registry.getContract('badgereg')
|
||||||
|
.then((badgeReg) => {
|
||||||
|
return badgeReg.instance.fromName.call({}, [name])
|
||||||
|
.then(([ id, address ]) => {
|
||||||
|
return Promise.all([
|
||||||
|
badgeReg.instance.meta.call({}, [id, 'TITLE']),
|
||||||
|
badgeReg.instance.meta.call({}, [id, 'IMG'])
|
||||||
|
])
|
||||||
|
.then(([ title, img ]) => {
|
||||||
|
title = bytesToHex(title);
|
||||||
|
title = title === ZERO ? null : hex2Ascii(title);
|
||||||
|
if (bytesToHex(img) === ZERO) img = null;
|
||||||
|
|
||||||
|
const data = { address, name, title, icon: img };
|
||||||
|
this.certifiers[name] = data;
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIfCertified (certifier, address) {
|
||||||
|
if (!this.contracts[certifier]) {
|
||||||
|
this.contracts[certifier] = this._api.newContract(ABI, certifier);
|
||||||
|
}
|
||||||
|
const contract = this.contracts[certifier];
|
||||||
|
|
||||||
|
return contract.instance.certified.call({}, [address]);
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ import SignatureReg from './signaturereg';
|
|||||||
import TokenReg from './tokenreg';
|
import TokenReg from './tokenreg';
|
||||||
import GithubHint from './githubhint';
|
import GithubHint from './githubhint';
|
||||||
import * as smsVerification from './sms-verification';
|
import * as smsVerification from './sms-verification';
|
||||||
|
import BadgeReg from './badgereg';
|
||||||
|
|
||||||
let instance = null;
|
let instance = null;
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ export default class Contracts {
|
|||||||
this._signaturereg = new SignatureReg(api, this._registry);
|
this._signaturereg = new SignatureReg(api, this._registry);
|
||||||
this._tokenreg = new TokenReg(api, this._registry);
|
this._tokenreg = new TokenReg(api, this._registry);
|
||||||
this._githubhint = new GithubHint(api, this._registry);
|
this._githubhint = new GithubHint(api, this._registry);
|
||||||
|
this.badgeReg = new BadgeReg(api, this._registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
get registry () {
|
get registry () {
|
||||||
|
@ -17,10 +17,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import injectTapEventPlugin from 'react-tap-event-plugin';
|
import injectTapEventPlugin from 'react-tap-event-plugin';
|
||||||
import { useStrict } from 'mobx';
|
|
||||||
|
|
||||||
injectTapEventPlugin();
|
injectTapEventPlugin();
|
||||||
useStrict(true);
|
|
||||||
|
|
||||||
import Application from './dappreg/Application';
|
import Application from './dappreg/Application';
|
||||||
|
|
||||||
|
@ -11,28 +11,23 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
background: white;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
.loading-container {
|
font-size: 16px;
|
||||||
display: flex;
|
font-weight: 300;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
|
||||||
font-family: Roboto;
|
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
|
||||||
color: #ddd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
font-size: 4em;
|
text-align: center;
|
||||||
|
padding-top: 5em;
|
||||||
|
font-size: 2em;
|
||||||
|
color: #999;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div class="loading-container">
|
<div class="loading">Loading</div>
|
||||||
<span class="loading">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<script src="vendor.js"></script>
|
<script src="vendor.js"></script>
|
||||||
<% if (!htmlWebpackPlugin.options.secure) { %>
|
<% if (!htmlWebpackPlugin.options.secure) { %>
|
||||||
|
@ -11,28 +11,23 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
background: white;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
.loading-container {
|
font-size: 16px;
|
||||||
display: flex;
|
font-weight: 300;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
|
||||||
font-family: Roboto;
|
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
|
||||||
color: #ddd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
font-size: 4em;
|
text-align: center;
|
||||||
|
padding-top: 5em;
|
||||||
|
font-size: 2em;
|
||||||
|
color: #999;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div class="loading-container">
|
<div class="loading">Loading</span>
|
||||||
<span class="loading">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<script src="vendor.js"></script>
|
<script src="vendor.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -15,8 +15,15 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import PrintIcon from 'material-ui/svg-icons/action/print';
|
||||||
|
|
||||||
import { Form, Input, InputAddress } from '../../../ui';
|
import { Form, Input, InputAddress } from '../../../ui';
|
||||||
|
import Button from '../../../ui/Button';
|
||||||
|
|
||||||
|
import { createIdentityImg } from '../../../api/util/identity';
|
||||||
|
import print from './print';
|
||||||
|
import recoveryPage from './recovery-page.ejs';
|
||||||
|
import ParityLogo from '../../../../assets/images/parity-logo-black-no-text.svg';
|
||||||
|
|
||||||
export default class AccountDetails extends Component {
|
export default class AccountDetails extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -42,6 +49,7 @@ export default class AccountDetails extends Component {
|
|||||||
label='address'
|
label='address'
|
||||||
value={ address } />
|
value={ address } />
|
||||||
{ this.renderPhrase() }
|
{ this.renderPhrase() }
|
||||||
|
{ this.renderPhraseCopyButton() }
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -62,4 +70,26 @@ export default class AccountDetails extends Component {
|
|||||||
value={ phrase } />
|
value={ phrase } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderPhraseCopyButton () {
|
||||||
|
const { phrase } = this.props;
|
||||||
|
if (!phrase) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
icon={ <PrintIcon /> }
|
||||||
|
label={ 'print recovery phrase' }
|
||||||
|
onClick={ this.printPhrase }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
printPhrase = () => {
|
||||||
|
const { address, phrase, name } = this.props;
|
||||||
|
const identity = createIdentityImg(address);
|
||||||
|
|
||||||
|
print(recoveryPage({ phrase, name, identity, address, logo: ParityLogo }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
63
js/src/modals/CreateAccount/AccountDetails/print.js
Normal file
63
js/src/modals/CreateAccount/AccountDetails/print.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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/>.
|
||||||
|
|
||||||
|
export const onPrint = (window, cb) => {
|
||||||
|
let called = false; let query, queryFn;
|
||||||
|
|
||||||
|
const onPrint = () => {
|
||||||
|
if (queryFn) {
|
||||||
|
query.removeListener(queryFn);
|
||||||
|
}
|
||||||
|
window.removeEventListener('afterprint', onPrint, false);
|
||||||
|
if (!called) {
|
||||||
|
called = true;
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (window.matchMedia) {
|
||||||
|
queryFn = (query) => {
|
||||||
|
if (!query.matches) {
|
||||||
|
onPrint();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
query = window.matchMedia('print');
|
||||||
|
query.addListener(queryFn);
|
||||||
|
}
|
||||||
|
window.addEventListener('afterprint', onPrint, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (html) => {
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.setAttribute('sandbox', 'allow-modals allow-same-origin allow-scripts');
|
||||||
|
iframe.setAttribute('src', '/');
|
||||||
|
iframe.setAttribute('style', 'display: none');
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
const teardown = () => {
|
||||||
|
// Safari crashes without a timeout.
|
||||||
|
setTimeout(() => document.body.removeChild(iframe), 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
iframe.contentDocument.write(html);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
onPrint(iframe.contentWindow, teardown);
|
||||||
|
iframe.contentWindow.focus();
|
||||||
|
iframe.contentWindow.print();
|
||||||
|
}, 20);
|
||||||
|
}, 0);
|
||||||
|
};
|
49
js/src/modals/CreateAccount/AccountDetails/recovery-page.ejs
Normal file
49
js/src/modals/CreateAccount/AccountDetails/recovery-page.ejs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Recovery phrase for <%= name %></title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 2em auto;
|
||||||
|
max-width: 30em;
|
||||||
|
padding: 1em;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 110%;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
#logo {
|
||||||
|
max-width: 4rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
figure {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
figure.address img {
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
white-space: normal;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<img id="logo" src="<%= logo %>" alt="Parity Logo" />
|
||||||
|
<p>This is your account <em><%= name %></em>:</p>
|
||||||
|
<figure class="address">
|
||||||
|
<img src="<%= identity %>" alt="symbol for the address of the account" />
|
||||||
|
<figcaption><code><%= address %></code></figcaption>
|
||||||
|
</figure>
|
||||||
|
<p>This is the recovery phrase:</p>
|
||||||
|
<pre><code><%= phrase %></code></pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -20,17 +20,20 @@ import SettingsMiddleware from '../views/Settings/middleware';
|
|||||||
import SignerMiddleware from './providers/signerMiddleware';
|
import SignerMiddleware from './providers/signerMiddleware';
|
||||||
|
|
||||||
import statusMiddleware from '../views/Status/middleware';
|
import statusMiddleware from '../views/Status/middleware';
|
||||||
|
import CertificationsMiddleware from './providers/certifications/middleware';
|
||||||
|
|
||||||
export default function (api) {
|
export default function (api) {
|
||||||
const errors = new ErrorsMiddleware();
|
const errors = new ErrorsMiddleware();
|
||||||
const signer = new SignerMiddleware(api);
|
const signer = new SignerMiddleware(api);
|
||||||
const settings = new SettingsMiddleware();
|
const settings = new SettingsMiddleware();
|
||||||
const status = statusMiddleware();
|
const status = statusMiddleware();
|
||||||
|
const certifications = new CertificationsMiddleware();
|
||||||
|
|
||||||
const middleware = [
|
const middleware = [
|
||||||
settings.toMiddleware(),
|
settings.toMiddleware(),
|
||||||
signer.toMiddleware(),
|
signer.toMiddleware(),
|
||||||
errors.toMiddleware()
|
errors.toMiddleware(),
|
||||||
|
certifications.toMiddleware()
|
||||||
];
|
];
|
||||||
|
|
||||||
return middleware.concat(status, thunk);
|
return middleware.concat(status, thunk);
|
||||||
|
23
js/src/redux/providers/certifications/actions.js
Normal file
23
js/src/redux/providers/certifications/actions.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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/>.
|
||||||
|
|
||||||
|
export const fetchCertifications = (address) => ({
|
||||||
|
type: 'fetchCertifications', address
|
||||||
|
});
|
||||||
|
|
||||||
|
export const addCertification = (address, name, title, icon) => ({
|
||||||
|
type: 'addCertification', address, name, title, icon
|
||||||
|
});
|
51
js/src/redux/providers/certifications/middleware.js
Normal file
51
js/src/redux/providers/certifications/middleware.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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 Contracts from '../../../contracts';
|
||||||
|
import { addCertification } from './actions';
|
||||||
|
|
||||||
|
const knownCertifiers = [ 'smsverification' ];
|
||||||
|
|
||||||
|
export default class CertificationsMiddleware {
|
||||||
|
toMiddleware () {
|
||||||
|
return (store) => (next) => (action) => {
|
||||||
|
if (action.type !== 'fetchCertifications') {
|
||||||
|
return next(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { address } = action;
|
||||||
|
const badgeReg = Contracts.get().badgeReg;
|
||||||
|
|
||||||
|
knownCertifiers.forEach((name) => {
|
||||||
|
badgeReg.fetchCertifier(name)
|
||||||
|
.then((cert) => {
|
||||||
|
return badgeReg.checkIfCertified(cert.address, address)
|
||||||
|
.then((isCertified) => {
|
||||||
|
if (isCertified) {
|
||||||
|
const { name, title, icon } = cert;
|
||||||
|
store.dispatch(addCertification(address, name, title, icon));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(`Failed to check if ${address} certified by ${name}:`, err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
33
js/src/redux/providers/certifications/reducer.js
Normal file
33
js/src/redux/providers/certifications/reducer.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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/>.
|
||||||
|
|
||||||
|
const initialState = {};
|
||||||
|
|
||||||
|
export default (state = initialState, action) => {
|
||||||
|
if (action.type !== 'addCertification') {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { address, name, icon, title } = action;
|
||||||
|
const certifications = state[address] || [];
|
||||||
|
|
||||||
|
if (certifications.some((c) => c.name === name)) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
const newCertifications = certifications.concat({ name, icon, title });
|
||||||
|
|
||||||
|
return { ...state, [address]: newCertifications };
|
||||||
|
};
|
@ -72,9 +72,8 @@ export default class SignerMiddleware {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Sign request in-browser
|
// Sign request in-browser
|
||||||
if (wallet && payload.transaction) {
|
const transaction = payload.sendTransaction || payload.signTransaction;
|
||||||
const { transaction } = payload;
|
if (wallet && transaction) {
|
||||||
|
|
||||||
(transaction.nonce.isZero()
|
(transaction.nonce.isZero()
|
||||||
? this._api.parity.nextNonce(transaction.from)
|
? this._api.parity.nextNonce(transaction.from)
|
||||||
: Promise.resolve(transaction.nonce)
|
: Promise.resolve(transaction.nonce)
|
||||||
|
@ -18,6 +18,7 @@ import { combineReducers } from 'redux';
|
|||||||
import { routerReducer } from 'react-router-redux';
|
import { routerReducer } from 'react-router-redux';
|
||||||
|
|
||||||
import { apiReducer, balancesReducer, blockchainReducer, compilerReducer, imagesReducer, personalReducer, signerReducer, statusReducer as nodeStatusReducer, snackbarReducer } from './providers';
|
import { apiReducer, balancesReducer, blockchainReducer, compilerReducer, imagesReducer, personalReducer, signerReducer, statusReducer as nodeStatusReducer, snackbarReducer } from './providers';
|
||||||
|
import certificationsReducer from './providers/certifications/reducer';
|
||||||
|
|
||||||
import errorReducer from '../ui/Errors/reducers';
|
import errorReducer from '../ui/Errors/reducers';
|
||||||
import settingsReducer from '../views/Settings/reducers';
|
import settingsReducer from '../views/Settings/reducers';
|
||||||
@ -32,6 +33,7 @@ export default function () {
|
|||||||
settings: settingsReducer,
|
settings: settingsReducer,
|
||||||
|
|
||||||
balances: balancesReducer,
|
balances: balancesReducer,
|
||||||
|
certifications: certificationsReducer,
|
||||||
blockchain: blockchainReducer,
|
blockchain: blockchainReducer,
|
||||||
compiler: compilerReducer,
|
compiler: compilerReducer,
|
||||||
images: imagesReducer,
|
images: imagesReducer,
|
||||||
|
46
js/src/ui/Certifications/certifications.css
Normal file
46
js/src/ui/Certifications/certifications.css
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.certifications {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.certification {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
margin-right: .5em;
|
||||||
|
padding: .3em .6em .2em 2.6em;
|
||||||
|
border-radius: 1em;
|
||||||
|
line-height: 1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background-color: rgba(255, 255, 255, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.certification:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
position: absolute;
|
||||||
|
top: -.25em;
|
||||||
|
left: 0;
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
87
js/src/ui/Certifications/certifications.js
Normal file
87
js/src/ui/Certifications/certifications.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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 React, { Component, PropTypes } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
|
import { hashToImageUrl } from '../../redux/providers/imagesReducer';
|
||||||
|
import { fetchCertifications } from '../../redux/providers/certifications/actions';
|
||||||
|
|
||||||
|
import defaultIcon from '../../../assets/images/certifications/unknown.svg';
|
||||||
|
|
||||||
|
import styles from './certifications.css';
|
||||||
|
|
||||||
|
class Certifications extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
account: PropTypes.string.isRequired,
|
||||||
|
certifications: PropTypes.array.isRequired,
|
||||||
|
dappsUrl: PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
fetchCertifications: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount () {
|
||||||
|
const { account, fetchCertifications } = this.props;
|
||||||
|
fetchCertifications(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { certifications } = this.props;
|
||||||
|
|
||||||
|
if (certifications.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.certifications }>
|
||||||
|
{ certifications.map(this.renderCertification) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCertification = (certification) => {
|
||||||
|
const { name, title, icon } = certification;
|
||||||
|
const { dappsUrl } = this.props;
|
||||||
|
|
||||||
|
const classNames = `${styles.certification} ${!icon ? styles.noIcon : ''}`;
|
||||||
|
const img = icon ? dappsUrl + hashToImageUrl(icon) : defaultIcon;
|
||||||
|
return (
|
||||||
|
<div className={ classNames } key={ name }>
|
||||||
|
<img className={ styles.icon } src={ img } />
|
||||||
|
<div className={ styles.text }>{ title || name }</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps (_, initProps) {
|
||||||
|
const { account } = initProps;
|
||||||
|
|
||||||
|
return (state) => {
|
||||||
|
const certifications = state.certifications[account] || [];
|
||||||
|
return { certifications };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps (dispatch) {
|
||||||
|
return bindActionCreators({ fetchCertifications }, dispatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(Certifications);
|
17
js/src/ui/Certifications/index.js
Normal file
17
js/src/ui/Certifications/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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/>.
|
||||||
|
|
||||||
|
export default from './certifications';
|
@ -23,6 +23,7 @@ import Badge from './Badge';
|
|||||||
import Balance from './Balance';
|
import Balance from './Balance';
|
||||||
import BlockStatus from './BlockStatus';
|
import BlockStatus from './BlockStatus';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
|
import Certifications from './Certifications';
|
||||||
import ConfirmDialog from './ConfirmDialog';
|
import ConfirmDialog from './ConfirmDialog';
|
||||||
import Container, { Title as ContainerTitle } from './Container';
|
import Container, { Title as ContainerTitle } from './Container';
|
||||||
import ContextProvider from './ContextProvider';
|
import ContextProvider from './ContextProvider';
|
||||||
@ -55,6 +56,7 @@ export {
|
|||||||
Balance,
|
Balance,
|
||||||
BlockStatus,
|
BlockStatus,
|
||||||
Button,
|
Button,
|
||||||
|
Certifications,
|
||||||
ConfirmDialog,
|
ConfirmDialog,
|
||||||
Container,
|
Container,
|
||||||
ContainerTitle,
|
ContainerTitle,
|
||||||
|
@ -18,6 +18,7 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
|
|
||||||
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags } from '../../../ui';
|
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags } from '../../../ui';
|
||||||
import CopyToClipboard from '../../../ui/CopyToClipboard';
|
import CopyToClipboard from '../../../ui/CopyToClipboard';
|
||||||
|
import Certifications from '../../../ui/Certifications';
|
||||||
|
|
||||||
import styles from './header.css';
|
import styles from './header.css';
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ export default class Header extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const { api } = this.context;
|
||||||
const { account, balance } = this.props;
|
const { account, balance } = this.props;
|
||||||
const { address, meta, uuid } = account;
|
const { address, meta, uuid } = account;
|
||||||
|
|
||||||
@ -67,6 +69,10 @@ export default class Header extends Component {
|
|||||||
<Balance
|
<Balance
|
||||||
account={ account }
|
account={ account }
|
||||||
balance={ balance } />
|
balance={ balance } />
|
||||||
|
<Certifications
|
||||||
|
account={ account.address }
|
||||||
|
dappsUrl={ api.dappsUrl }
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,12 +64,6 @@ class Account extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { api } = this.context;
|
|
||||||
const { address } = this.props.params;
|
|
||||||
const { isTestnet } = this.props;
|
|
||||||
|
|
||||||
const verificationStore = new VerificationStore(api, address, isTestnet);
|
|
||||||
this.setState({ verificationStore });
|
|
||||||
this.setVisibleAccounts();
|
this.setVisibleAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +74,15 @@ class Account extends Component {
|
|||||||
if (prevAddress !== nextAddress) {
|
if (prevAddress !== nextAddress) {
|
||||||
this.setVisibleAccounts(nextProps);
|
this.setVisibleAccounts(nextProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { isTestnet } = nextProps;
|
||||||
|
if (typeof isTestnet === 'boolean' && !this.state.verificationStore) {
|
||||||
|
const { api } = this.context;
|
||||||
|
const { address } = nextProps.params;
|
||||||
|
this.setState({
|
||||||
|
verificationStore: new VerificationStore(api, address, isTestnet)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
@ -115,7 +118,8 @@ class Account extends Component {
|
|||||||
<Page>
|
<Page>
|
||||||
<Header
|
<Header
|
||||||
account={ account }
|
account={ account }
|
||||||
balance={ balance } />
|
balance={ balance }
|
||||||
|
/>
|
||||||
<Transactions
|
<Transactions
|
||||||
accounts={ accounts }
|
accounts={ accounts }
|
||||||
address={ address } />
|
address={ address } />
|
||||||
|
@ -19,10 +19,17 @@ import { connect } from 'react-redux';
|
|||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import { Snackbar as SnackbarMUI } from 'material-ui';
|
import { Snackbar as SnackbarMUI } from 'material-ui';
|
||||||
import { darkBlack } from 'material-ui/styles/colors';
|
import { darkBlack, grey800 } from 'material-ui/styles/colors';
|
||||||
|
|
||||||
import { closeSnackbar } from '../../../redux/providers/snackbarActions';
|
import { closeSnackbar } from '../../../redux/providers/snackbarActions';
|
||||||
|
|
||||||
|
const bodyStyle = {
|
||||||
|
backgroundColor: darkBlack,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: grey800,
|
||||||
|
borderWidth: '1px 1px 0 1px'
|
||||||
|
};
|
||||||
|
|
||||||
class Snackbar extends Component {
|
class Snackbar extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
closeSnackbar: PropTypes.func.isRequired,
|
closeSnackbar: PropTypes.func.isRequired,
|
||||||
@ -40,7 +47,7 @@ class Snackbar extends Component {
|
|||||||
open={ open }
|
open={ open }
|
||||||
message={ message }
|
message={ message }
|
||||||
autoHideDuration={ cooldown }
|
autoHideDuration={ cooldown }
|
||||||
bodyStyle={ { backgroundColor: darkBlack } }
|
bodyStyle={ bodyStyle }
|
||||||
onRequestClose={ this.handleClose }
|
onRequestClose={ this.handleClose }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -15,45 +15,46 @@
|
|||||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
.status {
|
.status {
|
||||||
padding: 0.5em;
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: .4em .5em;
|
||||||
font-size: x-small;
|
font-size: x-small;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
background-color: rgba(0, 0, 0, 0.2)
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin: 0 0.5em 0 2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.enode {
|
.enode {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
float: right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.enode > * {
|
.enode > * {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0.25em 0.5em;
|
margin: 0 .25em;
|
||||||
vertical-align: top;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
.enode > :last-child {
|
||||||
.block {
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.netinfo {
|
.netinfo {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.netinfo > * {
|
.netinfo > * {
|
||||||
display: inline-block;
|
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.network {
|
.network {
|
||||||
padding: 0.25em 0.5em;
|
padding: 0.25em 0.5em;
|
||||||
display: inline-block;
|
border-radius: .4em;
|
||||||
border-radius: 4px;
|
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
@ -65,14 +66,3 @@
|
|||||||
.networktest {
|
.networktest {
|
||||||
background: rgb(136, 0, 0);
|
background: rgb(136, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.peers {
|
|
||||||
}
|
|
||||||
|
|
||||||
.version {
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syncing {
|
|
||||||
}
|
|
||||||
|
@ -46,7 +46,6 @@ class Status extends Component {
|
|||||||
<div className={ styles.version }>
|
<div className={ styles.version }>
|
||||||
{ clientVersion }
|
{ clientVersion }
|
||||||
</div>
|
</div>
|
||||||
{ this.renderEnode() }
|
|
||||||
<div className={ styles.netinfo }>
|
<div className={ styles.netinfo }>
|
||||||
<BlockStatus />
|
<BlockStatus />
|
||||||
<div className={ netStyle }>
|
<div className={ netStyle }>
|
||||||
@ -56,6 +55,7 @@ class Status extends Component {
|
|||||||
{ netPeers.active.toFormat() }/{ netPeers.connected.toFormat() }/{ netPeers.max.toFormat() } peers
|
{ netPeers.active.toFormat() }/{ netPeers.connected.toFormat() }/{ netPeers.max.toFormat() } peers
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{ this.renderEnode() }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ class Status extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.enode }>
|
<div className={ styles.enode }>
|
||||||
<CopyToClipboard data={ enode } />
|
<CopyToClipboard data={ enode } size={ 12 } />
|
||||||
<div>{ abbreviated }</div>
|
<div>{ abbreviated }</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -59,7 +59,7 @@ class Tab extends Component {
|
|||||||
selected={ active }
|
selected={ active }
|
||||||
icon={ view.icon }
|
icon={ view.icon }
|
||||||
label={ label }
|
label={ label }
|
||||||
onClick={ this.handleClick }
|
onTouchTap={ this.handleClick }
|
||||||
>
|
>
|
||||||
{ children }
|
{ children }
|
||||||
</MUITab>
|
</MUITab>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
import { Container, ContainerTitle } from '../../../ui';
|
import { Container } from '../../../ui';
|
||||||
|
|
||||||
import Event from './Event';
|
import Event from './Event';
|
||||||
import styles from '../contract.css';
|
import styles from '../contract.css';
|
||||||
@ -48,8 +48,7 @@ export default class Events extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container title='events'>
|
||||||
<ContainerTitle title='events' />
|
|
||||||
<table className={ styles.events }>
|
<table className={ styles.events }>
|
||||||
<tbody>{ list }</tbody>
|
<tbody>{ list }</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -19,7 +19,7 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import { Card, CardTitle, CardText } from 'material-ui/Card';
|
import { Card, CardTitle, CardText } from 'material-ui/Card';
|
||||||
|
|
||||||
import InputQuery from './inputQuery';
|
import InputQuery from './inputQuery';
|
||||||
import { Container, ContainerTitle, Input, InputAddress } from '../../../ui';
|
import { Container, Input, InputAddress } from '../../../ui';
|
||||||
|
|
||||||
import styles from './queries.css';
|
import styles from './queries.css';
|
||||||
|
|
||||||
@ -55,8 +55,7 @@ export default class Queries extends Component {
|
|||||||
.map((fn) => this.renderInputQuery(fn));
|
.map((fn) => this.renderInputQuery(fn));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container title='queries'>
|
||||||
<ContainerTitle title='queries' />
|
|
||||||
<div className={ styles.methods }>
|
<div className={ styles.methods }>
|
||||||
<div className={ styles.vMethods }>
|
<div className={ styles.vMethods }>
|
||||||
{ noInputQueries }
|
{ noInputQueries }
|
||||||
|
@ -132,7 +132,8 @@ class Contract extends Component {
|
|||||||
<Page>
|
<Page>
|
||||||
<Header
|
<Header
|
||||||
account={ account }
|
account={ account }
|
||||||
balance={ balance } />
|
balance={ balance }
|
||||||
|
/>
|
||||||
<Queries
|
<Queries
|
||||||
contract={ contract }
|
contract={ contract }
|
||||||
values={ queryValues } />
|
values={ queryValues } />
|
||||||
@ -447,7 +448,10 @@ function mapStateToProps (state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapDispatchToProps (dispatch) {
|
function mapDispatchToProps (dispatch) {
|
||||||
return bindActionCreators({ newError, setVisibleAccounts }, dispatch);
|
return bindActionCreators({
|
||||||
|
newError,
|
||||||
|
setVisibleAccounts
|
||||||
|
}, dispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
@ -42,25 +42,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.expanded {
|
.expanded {
|
||||||
right: 16px;
|
right: 1em;
|
||||||
max-height: 300px;
|
|
||||||
border-radius: 4px 4px 0 0;
|
border-radius: 4px 4px 0 0;
|
||||||
overflow-y: auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
max-height: 19em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.expanded .content {
|
.expanded .content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
background: rgba(0, 0, 0, 0.8);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
min-height: 16em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.corner {
|
.corner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 16px;
|
right: 1em;
|
||||||
border-radius: 4px 4px 0 0;
|
border-radius: 4px 4px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +119,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
height: 36px;
|
height: 2em;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
background: rgba(0, 0, 0, 0.25);
|
background: rgba(0, 0, 0, 0.25);
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
@ -148,6 +149,7 @@
|
|||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
float: right;
|
float: right;
|
||||||
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions div {
|
.actions div {
|
||||||
|
@ -19,7 +19,7 @@ import { connect } from 'react-redux';
|
|||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import NavigationRefresh from 'material-ui/svg-icons/navigation/refresh';
|
import NavigationRefresh from 'material-ui/svg-icons/navigation/refresh';
|
||||||
|
|
||||||
import { Button, Container, ContainerTitle, ParityBackground } from '../../../ui';
|
import { Button, Container, ParityBackground } from '../../../ui';
|
||||||
|
|
||||||
import { updateBackground } from '../actions';
|
import { updateBackground } from '../actions';
|
||||||
|
|
||||||
@ -55,8 +55,7 @@ class Background extends Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container title='Background Pattern'>
|
||||||
<ContainerTitle title='Background Pattern' />
|
|
||||||
<div className={ layout.layout }>
|
<div className={ layout.layout }>
|
||||||
<div className={ layout.overview }>
|
<div className={ layout.overview }>
|
||||||
<div>The background pattern you can see right now is unique to your Parity installation. It will change every time you create a new Signer token. This is so that decentralized applications cannot pretend to be trustworthy.</div>
|
<div>The background pattern you can see right now is unique to your Parity installation. It will change every time you create a new Signer token. This is so that decentralized applications cannot pretend to be trustworthy.</div>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { MenuItem } from 'material-ui';
|
import { MenuItem } from 'material-ui';
|
||||||
|
|
||||||
import { Select, Container, ContainerTitle } from '../../../ui';
|
import { Select, Container } from '../../../ui';
|
||||||
|
|
||||||
import layout from '../layout.css';
|
import layout from '../layout.css';
|
||||||
|
|
||||||
@ -43,8 +43,7 @@ export default class Parity extends Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container title='Parity'>
|
||||||
<ContainerTitle title='Parity' />
|
|
||||||
<div className={ layout.layout }>
|
<div className={ layout.layout }>
|
||||||
<div className={ layout.overview }>
|
<div className={ layout.overview }>
|
||||||
<div>Control the Parity node settings and mode of operation via this interface.</div>
|
<div>Control the Parity node settings and mode of operation via this interface.</div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
import { Container, ContainerTitle } from '../../../ui';
|
import { Container } from '../../../ui';
|
||||||
|
|
||||||
import layout from '../layout.css';
|
import layout from '../layout.css';
|
||||||
import styles from './proxy.css';
|
import styles from './proxy.css';
|
||||||
@ -31,8 +31,7 @@ export default class Proxy extends Component {
|
|||||||
const proxyurl = `${dappsUrl}/proxy/proxy.pac`;
|
const proxyurl = `${dappsUrl}/proxy/proxy.pac`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container title='Proxy'>
|
||||||
<ContainerTitle title='Proxy' />
|
|
||||||
<div className={ layout.layout }>
|
<div className={ layout.layout }>
|
||||||
<div className={ layout.overview }>
|
<div className={ layout.overview }>
|
||||||
<div>The proxy setup allows you to access Parity and all associated decentralized applications via memorable addresses.</div>
|
<div>The proxy setup allows you to access Parity and all associated decentralized applications via memorable addresses.</div>
|
||||||
|
@ -19,7 +19,7 @@ import { connect } from 'react-redux';
|
|||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { Checkbox } from 'material-ui';
|
import { Checkbox } from 'material-ui';
|
||||||
|
|
||||||
import { Container, ContainerTitle } from '../../../ui';
|
import { Container } from '../../../ui';
|
||||||
|
|
||||||
import { toggleView } from '../actions';
|
import { toggleView } from '../actions';
|
||||||
|
|
||||||
@ -34,8 +34,7 @@ class Views extends Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container title='Views'>
|
||||||
<ContainerTitle title='Views' />
|
|
||||||
<div className={ layout.layout }>
|
<div className={ layout.layout }>
|
||||||
<div className={ layout.overview }>
|
<div className={ layout.overview }>
|
||||||
<div>Manage the available application views, using only the parts of the application that is applicable to you.</div>
|
<div>Manage the available application views, using only the parts of the application that is applicable to you.</div>
|
||||||
|
@ -25,7 +25,8 @@ export default class RequestFinished extends Component {
|
|||||||
result: PropTypes.any.isRequired,
|
result: PropTypes.any.isRequired,
|
||||||
date: PropTypes.instanceOf(Date).isRequired,
|
date: PropTypes.instanceOf(Date).isRequired,
|
||||||
payload: PropTypes.oneOfType([
|
payload: PropTypes.oneOfType([
|
||||||
PropTypes.shape({ transaction: PropTypes.object.isRequired }),
|
PropTypes.shape({ signTransaction: PropTypes.object.isRequired }),
|
||||||
|
PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }),
|
||||||
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
msg: PropTypes.string,
|
msg: PropTypes.string,
|
||||||
@ -58,9 +59,8 @@ export default class RequestFinished extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payload.transaction) {
|
const transaction = payload.sendTransaction || payload.signTransaction;
|
||||||
const { transaction } = payload;
|
if (transaction) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TransactionFinished
|
<TransactionFinished
|
||||||
className={ className }
|
className={ className }
|
||||||
|
@ -27,7 +27,8 @@ export default class RequestPending extends Component {
|
|||||||
isSending: PropTypes.bool.isRequired,
|
isSending: PropTypes.bool.isRequired,
|
||||||
date: PropTypes.instanceOf(Date).isRequired,
|
date: PropTypes.instanceOf(Date).isRequired,
|
||||||
payload: PropTypes.oneOfType([
|
payload: PropTypes.oneOfType([
|
||||||
PropTypes.shape({ transaction: PropTypes.object.isRequired }),
|
PropTypes.shape({ signTransaction: PropTypes.object.isRequired }),
|
||||||
|
PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }),
|
||||||
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
@ -64,9 +65,8 @@ export default class RequestPending extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payload.transaction) {
|
const transaction = payload.sendTransaction || payload.signTransaction;
|
||||||
const { transaction } = payload;
|
if (transaction) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TransactionPending
|
<TransactionPending
|
||||||
className={ className }
|
className={ className }
|
||||||
|
@ -20,7 +20,7 @@ import AvPlay from 'material-ui/svg-icons/av/play-arrow';
|
|||||||
import AvReplay from 'material-ui/svg-icons/av/replay';
|
import AvReplay from 'material-ui/svg-icons/av/replay';
|
||||||
import ReorderIcon from 'material-ui/svg-icons/action/reorder';
|
import ReorderIcon from 'material-ui/svg-icons/action/reorder';
|
||||||
|
|
||||||
import { Container, ContainerTitle } from '../../../../ui';
|
import { Container } from '../../../../ui';
|
||||||
|
|
||||||
import styles from './Debug.css';
|
import styles from './Debug.css';
|
||||||
|
|
||||||
@ -42,9 +42,7 @@ export default class Debug extends Component {
|
|||||||
const { devLogsLevels } = nodeStatus;
|
const { devLogsLevels } = nodeStatus;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container title='Node Logs'>
|
||||||
<ContainerTitle
|
|
||||||
title='Node Logs' />
|
|
||||||
{ this.renderActions() }
|
{ this.renderActions() }
|
||||||
<h2 className={ styles.subheader }>
|
<h2 className={ styles.subheader }>
|
||||||
{ devLogsLevels || '-' }
|
{ devLogsLevels || '-' }
|
||||||
|
@ -64,6 +64,10 @@ module.exports = {
|
|||||||
test: /\.json$/,
|
test: /\.json$/,
|
||||||
use: [ 'json-loader' ]
|
use: [ 'json-loader' ]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /\.ejs$/,
|
||||||
|
use: [ 'ejs-loader' ]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.html$/,
|
test: /\.html$/,
|
||||||
use: [
|
use: [
|
||||||
|
@ -10,7 +10,7 @@ rustc-serialize = "0.3"
|
|||||||
serde = "0.8"
|
serde = "0.8"
|
||||||
serde_json = "0.8"
|
serde_json = "0.8"
|
||||||
serde_macros = { version = "0.8", optional = true }
|
serde_macros = { version = "0.8", optional = true }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde_codegen = { version = "0.8", optional = true }
|
serde_codegen = { version = "0.8", optional = true }
|
||||||
|
@ -22,7 +22,7 @@ use std::thread::sleep;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rustc_serialize::hex::FromHex;
|
use rustc_serialize::hex::FromHex;
|
||||||
use io::{PanicHandler, ForwardPanic};
|
use io::{PanicHandler, ForwardPanic};
|
||||||
use util::{ToPretty, Uint};
|
use util::{ToPretty, Uint, U256, H256, Address, Hashable};
|
||||||
use rlp::PayloadInfo;
|
use rlp::PayloadInfo;
|
||||||
use ethcore::service::ClientService;
|
use ethcore::service::ClientService;
|
||||||
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockImportError, BlockChainClient, BlockID};
|
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockImportError, BlockChainClient, BlockID};
|
||||||
@ -65,6 +65,7 @@ impl FromStr for DataFormat {
|
|||||||
pub enum BlockchainCmd {
|
pub enum BlockchainCmd {
|
||||||
Import(ImportBlockchain),
|
Import(ImportBlockchain),
|
||||||
Export(ExportBlockchain),
|
Export(ExportBlockchain),
|
||||||
|
ExportState(ExportState),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -103,10 +104,31 @@ pub struct ExportBlockchain {
|
|||||||
pub check_seal: bool,
|
pub check_seal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct ExportState {
|
||||||
|
pub spec: SpecType,
|
||||||
|
pub cache_config: CacheConfig,
|
||||||
|
pub dirs: Directories,
|
||||||
|
pub file_path: Option<String>,
|
||||||
|
pub format: Option<DataFormat>,
|
||||||
|
pub pruning: Pruning,
|
||||||
|
pub pruning_history: u64,
|
||||||
|
pub compaction: DatabaseCompactionProfile,
|
||||||
|
pub wal: bool,
|
||||||
|
pub fat_db: Switch,
|
||||||
|
pub tracing: Switch,
|
||||||
|
pub at: BlockID,
|
||||||
|
pub storage: bool,
|
||||||
|
pub code: bool,
|
||||||
|
pub min_balance: Option<U256>,
|
||||||
|
pub max_balance: Option<U256>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
|
pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
|
||||||
match cmd {
|
match cmd {
|
||||||
BlockchainCmd::Import(import_cmd) => execute_import(import_cmd),
|
BlockchainCmd::Import(import_cmd) => execute_import(import_cmd),
|
||||||
BlockchainCmd::Export(export_cmd) => execute_export(export_cmd),
|
BlockchainCmd::Export(export_cmd) => execute_export(export_cmd),
|
||||||
|
BlockchainCmd::ExportState(export_cmd) => execute_export_state(export_cmd),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +267,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
// save user defaults
|
// save user defaults
|
||||||
user_defaults.pruning = algorithm;
|
user_defaults.pruning = algorithm;
|
||||||
user_defaults.tracing = tracing;
|
user_defaults.tracing = tracing;
|
||||||
|
user_defaults.fat_db = fat_db;
|
||||||
try!(user_defaults.save(&user_defaults_path));
|
try!(user_defaults.save(&user_defaults_path));
|
||||||
|
|
||||||
let report = client.report();
|
let report = client.report();
|
||||||
@ -261,23 +284,28 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
).into())
|
).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
fn start_client(
|
||||||
// Setup panic handler
|
dirs: Directories,
|
||||||
let panic_handler = PanicHandler::new_in_arc();
|
spec: SpecType,
|
||||||
|
pruning: Pruning,
|
||||||
|
pruning_history: u64,
|
||||||
|
tracing: Switch,
|
||||||
|
fat_db: Switch,
|
||||||
|
compaction: DatabaseCompactionProfile,
|
||||||
|
wal: bool,
|
||||||
|
cache_config: CacheConfig) -> Result<ClientService, String> {
|
||||||
|
|
||||||
// create dirs used by parity
|
// create dirs used by parity
|
||||||
try!(cmd.dirs.create_dirs(false, false));
|
try!(dirs.create_dirs(false, false));
|
||||||
|
|
||||||
let format = cmd.format.unwrap_or_default();
|
|
||||||
|
|
||||||
// load spec file
|
// load spec file
|
||||||
let spec = try!(cmd.spec.spec());
|
let spec = try!(spec.spec());
|
||||||
|
|
||||||
// load genesis hash
|
// load genesis hash
|
||||||
let genesis_hash = spec.genesis_header().hash();
|
let genesis_hash = spec.genesis_header().hash();
|
||||||
|
|
||||||
// database paths
|
// database paths
|
||||||
let db_dirs = cmd.dirs.database(genesis_hash, spec.fork_name.clone());
|
let db_dirs = dirs.database(genesis_hash, spec.fork_name.clone());
|
||||||
|
|
||||||
// user defaults path
|
// user defaults path
|
||||||
let user_defaults_path = db_dirs.user_defaults_path();
|
let user_defaults_path = db_dirs.user_defaults_path();
|
||||||
@ -288,34 +316,42 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
|||||||
fdlimit::raise_fd_limit();
|
fdlimit::raise_fd_limit();
|
||||||
|
|
||||||
// select pruning algorithm
|
// select pruning algorithm
|
||||||
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
|
let algorithm = pruning.to_algorithm(&user_defaults);
|
||||||
|
|
||||||
// check if tracing is on
|
// check if tracing is on
|
||||||
let tracing = try!(tracing_switch_to_bool(cmd.tracing, &user_defaults));
|
let tracing = try!(tracing_switch_to_bool(tracing, &user_defaults));
|
||||||
|
|
||||||
// check if fatdb is on
|
// check if fatdb is on
|
||||||
let fat_db = try!(fatdb_switch_to_bool(cmd.fat_db, &user_defaults, algorithm));
|
let fat_db = try!(fatdb_switch_to_bool(fat_db, &user_defaults, algorithm));
|
||||||
|
|
||||||
// prepare client and snapshot paths.
|
// prepare client and snapshot paths.
|
||||||
let client_path = db_dirs.client_path(algorithm);
|
let client_path = db_dirs.client_path(algorithm);
|
||||||
let snapshot_path = db_dirs.snapshot_path();
|
let snapshot_path = db_dirs.snapshot_path();
|
||||||
|
|
||||||
// execute upgrades
|
// execute upgrades
|
||||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
try!(execute_upgrades(&db_dirs, algorithm, compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||||
|
|
||||||
// prepare client config
|
// prepare client config
|
||||||
let client_config = to_client_config(&cmd.cache_config, Mode::Active, tracing, fat_db, cmd.compaction, cmd.wal, VMType::default(), "".into(), algorithm, cmd.pruning_history, cmd.check_seal);
|
let client_config = to_client_config(&cache_config, Mode::Active, tracing, fat_db, compaction, wal, VMType::default(), "".into(), algorithm, pruning_history, true);
|
||||||
|
|
||||||
let service = try!(ClientService::start(
|
let service = try!(ClientService::start(
|
||||||
client_config,
|
client_config,
|
||||||
&spec,
|
&spec,
|
||||||
&client_path,
|
&client_path,
|
||||||
&snapshot_path,
|
&snapshot_path,
|
||||||
&cmd.dirs.ipc_path(),
|
&dirs.ipc_path(),
|
||||||
Arc::new(Miner::with_spec(&spec)),
|
Arc::new(Miner::with_spec(&spec)),
|
||||||
).map_err(|e| format!("Client service error: {:?}", e)));
|
).map_err(|e| format!("Client service error: {:?}", e)));
|
||||||
|
|
||||||
drop(spec);
|
drop(spec);
|
||||||
|
Ok(service)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
||||||
|
// Setup panic handler
|
||||||
|
let service = try!(start_client(cmd.dirs, cmd.spec, cmd.pruning, cmd.pruning_history, cmd.tracing, cmd.fat_db, cmd.compaction, cmd.wal, cmd.cache_config));
|
||||||
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
|
let format = cmd.format.unwrap_or_default();
|
||||||
|
|
||||||
panic_handler.forward_from(&service);
|
panic_handler.forward_from(&service);
|
||||||
let client = service.client();
|
let client = service.client();
|
||||||
@ -329,6 +365,9 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
|||||||
let to = try!(client.block_number(cmd.to_block).ok_or("To block could not be found"));
|
let to = try!(client.block_number(cmd.to_block).ok_or("To block could not be found"));
|
||||||
|
|
||||||
for i in from..(to + 1) {
|
for i in from..(to + 1) {
|
||||||
|
if i % 10000 == 0 {
|
||||||
|
info!("#{}", i);
|
||||||
|
}
|
||||||
let b = try!(client.block(BlockID::Number(i)).ok_or("Error exporting incomplete chain"));
|
let b = try!(client.block(BlockID::Number(i)).ok_or("Error exporting incomplete chain"));
|
||||||
match format {
|
match format {
|
||||||
DataFormat::Binary => { out.write(&b).expect("Couldn't write to stream."); }
|
DataFormat::Binary => { out.write(&b).expect("Couldn't write to stream."); }
|
||||||
@ -339,6 +378,85 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
|||||||
Ok("Export completed.".into())
|
Ok("Export completed.".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn execute_export_state(cmd: ExportState) -> Result<String, String> {
|
||||||
|
// Setup panic handler
|
||||||
|
let service = try!(start_client(cmd.dirs, cmd.spec, cmd.pruning, cmd.pruning_history, cmd.tracing, cmd.fat_db, cmd.compaction, cmd.wal, cmd.cache_config));
|
||||||
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
|
|
||||||
|
panic_handler.forward_from(&service);
|
||||||
|
let client = service.client();
|
||||||
|
|
||||||
|
let mut out: Box<io::Write> = match cmd.file_path {
|
||||||
|
Some(f) => Box::new(try!(fs::File::create(&f).map_err(|_| format!("Cannot write to file given: {}", f)))),
|
||||||
|
None => Box::new(io::stdout()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut last: Option<Address> = None;
|
||||||
|
let at = cmd.at;
|
||||||
|
let mut i = 0usize;
|
||||||
|
|
||||||
|
out.write_fmt(format_args!("{{ \"state\": [", )).expect("Couldn't write to stream.");
|
||||||
|
loop {
|
||||||
|
let accounts = try!(client.list_accounts(at, last.as_ref(), 1000).ok_or("Specified block not found"));
|
||||||
|
if accounts.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for account in accounts.into_iter() {
|
||||||
|
let balance = client.balance(&account, at).unwrap_or_else(U256::zero);
|
||||||
|
if cmd.min_balance.map_or(false, |m| balance < m) || cmd.max_balance.map_or(false, |m| balance > m) {
|
||||||
|
last = Some(account);
|
||||||
|
continue; //filtered out
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != 0 {
|
||||||
|
out.write(b",").expect("Write error");
|
||||||
|
}
|
||||||
|
out.write_fmt(format_args!("\n\"0x{}\": {{\"balance\": \"{:x}\", \"nonce\": \"{:x}\"", account.hex(), balance, client.nonce(&account, at).unwrap_or_else(U256::zero))).expect("Write error");
|
||||||
|
let code = client.code(&account, at).unwrap_or(None).unwrap_or_else(Vec::new);
|
||||||
|
if !code.is_empty() {
|
||||||
|
out.write_fmt(format_args!(", \"code_hash\": \"0x{}\"", code.sha3().hex())).expect("Write error");
|
||||||
|
if cmd.code {
|
||||||
|
out.write_fmt(format_args!(", \"code\": \"{}\"", code.to_hex())).expect("Write error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let storage_root = client.storage_root(&account, at).unwrap_or(::util::SHA3_NULL_RLP);
|
||||||
|
if storage_root != ::util::SHA3_NULL_RLP {
|
||||||
|
out.write_fmt(format_args!(", \"storage_root\": \"0x{}\"", storage_root.hex())).expect("Write error");
|
||||||
|
if cmd.storage {
|
||||||
|
out.write_fmt(format_args!(", \"storage\": {{")).expect("Write error");
|
||||||
|
let mut last_storage: Option<H256> = None;
|
||||||
|
loop {
|
||||||
|
let keys = try!(client.list_storage(at, &account, last_storage.as_ref(), 1000).ok_or("Specified block not found"));
|
||||||
|
if keys.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut si = 0;
|
||||||
|
for key in keys.into_iter() {
|
||||||
|
if si != 0 {
|
||||||
|
out.write(b",").expect("Write error");
|
||||||
|
}
|
||||||
|
out.write_fmt(format_args!("\n\t\"0x{}\": \"0x{}\"", key.hex(), client.storage_at(&account, &key, at).unwrap_or_else(Default::default).hex())).expect("Write error");
|
||||||
|
si += 1;
|
||||||
|
last_storage = Some(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write(b"\n}").expect("Write error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write(b"}").expect("Write error");
|
||||||
|
i += 1;
|
||||||
|
if i % 10000 == 0 {
|
||||||
|
info!("Account #{}", i);
|
||||||
|
}
|
||||||
|
last = Some(account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write_fmt(format_args!("\n]}}")).expect("Write error");
|
||||||
|
Ok("Export completed.".into())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::DataFormat;
|
use super::DataFormat;
|
||||||
|
@ -26,6 +26,8 @@ usage! {
|
|||||||
cmd_new: bool,
|
cmd_new: bool,
|
||||||
cmd_list: bool,
|
cmd_list: bool,
|
||||||
cmd_export: bool,
|
cmd_export: bool,
|
||||||
|
cmd_blocks: bool,
|
||||||
|
cmd_state: bool,
|
||||||
cmd_import: bool,
|
cmd_import: bool,
|
||||||
cmd_signer: bool,
|
cmd_signer: bool,
|
||||||
cmd_new_token: bool,
|
cmd_new_token: bool,
|
||||||
@ -246,6 +248,10 @@ usage! {
|
|||||||
flag_to: String = "latest", or |_| None,
|
flag_to: String = "latest", or |_| None,
|
||||||
flag_format: Option<String> = None, or |_| None,
|
flag_format: Option<String> = None, or |_| None,
|
||||||
flag_no_seal_check: bool = false, or |_| None,
|
flag_no_seal_check: bool = false, or |_| None,
|
||||||
|
flag_no_storage: bool = false, or |_| None,
|
||||||
|
flag_no_code: bool = false, or |_| None,
|
||||||
|
flag_min_balance: Option<String> = None, or |_| None,
|
||||||
|
flag_max_balance: Option<String> = None, or |_| None,
|
||||||
|
|
||||||
// -- Snapshot Optons
|
// -- Snapshot Optons
|
||||||
flag_at: String = "latest", or |_| None,
|
flag_at: String = "latest", or |_| None,
|
||||||
@ -484,6 +490,8 @@ mod tests {
|
|||||||
cmd_new: false,
|
cmd_new: false,
|
||||||
cmd_list: false,
|
cmd_list: false,
|
||||||
cmd_export: false,
|
cmd_export: false,
|
||||||
|
cmd_state: false,
|
||||||
|
cmd_blocks: false,
|
||||||
cmd_import: false,
|
cmd_import: false,
|
||||||
cmd_signer: false,
|
cmd_signer: false,
|
||||||
cmd_new_token: false,
|
cmd_new_token: false,
|
||||||
@ -600,6 +608,10 @@ mod tests {
|
|||||||
flag_to: "latest".into(),
|
flag_to: "latest".into(),
|
||||||
flag_format: None,
|
flag_format: None,
|
||||||
flag_no_seal_check: false,
|
flag_no_seal_check: false,
|
||||||
|
flag_no_code: false,
|
||||||
|
flag_no_storage: false,
|
||||||
|
flag_min_balance: None,
|
||||||
|
flag_max_balance: None,
|
||||||
|
|
||||||
// -- Snapshot Optons
|
// -- Snapshot Optons
|
||||||
flag_at: "latest".into(),
|
flag_at: "latest".into(),
|
||||||
|
@ -10,7 +10,7 @@ Usage:
|
|||||||
parity account import <path>... [options]
|
parity account import <path>... [options]
|
||||||
parity wallet import <path> --password FILE [options]
|
parity wallet import <path> --password FILE [options]
|
||||||
parity import [ <file> ] [options]
|
parity import [ <file> ] [options]
|
||||||
parity export [ <file> ] [options]
|
parity export (blocks | state) [ <file> ] [options]
|
||||||
parity signer new-token [options]
|
parity signer new-token [options]
|
||||||
parity snapshot <file> [options]
|
parity snapshot <file> [options]
|
||||||
parity restore [ <file> ] [options]
|
parity restore [ <file> ] [options]
|
||||||
@ -271,6 +271,16 @@ Import/Export Options:
|
|||||||
one of 'hex' and 'binary'.
|
one of 'hex' and 'binary'.
|
||||||
(default: {flag_format:?} = Import: auto, Export: binary)
|
(default: {flag_format:?} = Import: auto, Export: binary)
|
||||||
--no-seal-check Skip block seal check. (default: {flag_no_seal_check})
|
--no-seal-check Skip block seal check. (default: {flag_no_seal_check})
|
||||||
|
--at BLOCK Export state at the given block, which may be an
|
||||||
|
index, hash, or 'latest'. Note that taking snapshots at
|
||||||
|
non-recent blocks will only work with --pruning archive
|
||||||
|
(default: {flag_at})
|
||||||
|
--no-storage Don't export account storge. (default: {flag_no_storage})
|
||||||
|
--no-code Don't export account code. (default: {flag_no_code})
|
||||||
|
--min-balance WEI Don't export accounts with balance less than specified.
|
||||||
|
(default: {flag_min_balance:?})
|
||||||
|
--max-balance WEI Don't export accounts with balance greater than specified.
|
||||||
|
(default: {flag_max_balance:?})
|
||||||
|
|
||||||
Snapshot Options:
|
Snapshot Options:
|
||||||
--at BLOCK Take a snapshot at the given block, which may be an
|
--at BLOCK Take a snapshot at the given block, which may be an
|
||||||
|
@ -37,7 +37,7 @@ use dir::Directories;
|
|||||||
use dapps::Configuration as DappsConfiguration;
|
use dapps::Configuration as DappsConfiguration;
|
||||||
use signer::{Configuration as SignerConfiguration};
|
use signer::{Configuration as SignerConfiguration};
|
||||||
use run::RunCmd;
|
use run::RunCmd;
|
||||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat};
|
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, ExportState, DataFormat};
|
||||||
use presale::ImportWallet;
|
use presale::ImportWallet;
|
||||||
use account::{AccountCmd, NewAccount, ImportAccounts, ImportFromGethAccounts};
|
use account::{AccountCmd, NewAccount, ImportAccounts, ImportFromGethAccounts};
|
||||||
use snapshot::{self, SnapshotCommand};
|
use snapshot::{self, SnapshotCommand};
|
||||||
@ -161,23 +161,47 @@ impl Configuration {
|
|||||||
};
|
};
|
||||||
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
||||||
} else if self.args.cmd_export {
|
} else if self.args.cmd_export {
|
||||||
let export_cmd = ExportBlockchain {
|
if self.args.cmd_blocks {
|
||||||
spec: spec,
|
let export_cmd = ExportBlockchain {
|
||||||
cache_config: cache_config,
|
spec: spec,
|
||||||
dirs: dirs,
|
cache_config: cache_config,
|
||||||
file_path: self.args.arg_file.clone(),
|
dirs: dirs,
|
||||||
format: format,
|
file_path: self.args.arg_file.clone(),
|
||||||
pruning: pruning,
|
format: format,
|
||||||
pruning_history: pruning_history,
|
pruning: pruning,
|
||||||
compaction: compaction,
|
pruning_history: pruning_history,
|
||||||
wal: wal,
|
compaction: compaction,
|
||||||
tracing: tracing,
|
wal: wal,
|
||||||
fat_db: fat_db,
|
tracing: tracing,
|
||||||
from_block: try!(to_block_id(&self.args.flag_from)),
|
fat_db: fat_db,
|
||||||
to_block: try!(to_block_id(&self.args.flag_to)),
|
from_block: try!(to_block_id(&self.args.flag_from)),
|
||||||
check_seal: !self.args.flag_no_seal_check,
|
to_block: try!(to_block_id(&self.args.flag_to)),
|
||||||
};
|
check_seal: !self.args.flag_no_seal_check,
|
||||||
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
|
};
|
||||||
|
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
|
||||||
|
} else if self.args.cmd_state {
|
||||||
|
let export_cmd = ExportState {
|
||||||
|
spec: spec,
|
||||||
|
cache_config: cache_config,
|
||||||
|
dirs: dirs,
|
||||||
|
file_path: self.args.arg_file.clone(),
|
||||||
|
format: format,
|
||||||
|
pruning: pruning,
|
||||||
|
pruning_history: pruning_history,
|
||||||
|
compaction: compaction,
|
||||||
|
wal: wal,
|
||||||
|
tracing: tracing,
|
||||||
|
fat_db: fat_db,
|
||||||
|
at: try!(to_block_id(&self.args.flag_at)),
|
||||||
|
storage: !self.args.flag_no_storage,
|
||||||
|
code: !self.args.flag_no_code,
|
||||||
|
min_balance: self.args.flag_min_balance.and_then(|s| to_u256(&s).ok()),
|
||||||
|
max_balance: self.args.flag_max_balance.and_then(|s| to_u256(&s).ok()),
|
||||||
|
};
|
||||||
|
Cmd::Blockchain(BlockchainCmd::ExportState(export_cmd))
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
} else if self.args.cmd_snapshot {
|
} else if self.args.cmd_snapshot {
|
||||||
let snapshot_cmd = SnapshotCommand {
|
let snapshot_cmd = SnapshotCommand {
|
||||||
cache_config: cache_config,
|
cache_config: cache_config,
|
||||||
@ -690,7 +714,7 @@ mod tests {
|
|||||||
use helpers::{replace_home, default_network_config};
|
use helpers::{replace_home, default_network_config};
|
||||||
use run::RunCmd;
|
use run::RunCmd;
|
||||||
use signer::{Configuration as SignerConfiguration};
|
use signer::{Configuration as SignerConfiguration};
|
||||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat};
|
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat, ExportState};
|
||||||
use presale::ImportWallet;
|
use presale::ImportWallet;
|
||||||
use account::{AccountCmd, NewAccount, ImportAccounts};
|
use account::{AccountCmd, NewAccount, ImportAccounts};
|
||||||
use devtools::{RandomTempPath};
|
use devtools::{RandomTempPath};
|
||||||
@ -779,7 +803,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_command_blockchain_export() {
|
fn test_command_blockchain_export() {
|
||||||
let args = vec!["parity", "export", "blockchain.json"];
|
let args = vec!["parity", "export", "blocks", "blockchain.json"];
|
||||||
let conf = parse(&args);
|
let conf = parse(&args);
|
||||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
||||||
spec: Default::default(),
|
spec: Default::default(),
|
||||||
@ -799,9 +823,33 @@ mod tests {
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_command_state_export() {
|
||||||
|
let args = vec!["parity", "export", "state", "state.json"];
|
||||||
|
let conf = parse(&args);
|
||||||
|
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::ExportState(ExportState {
|
||||||
|
spec: Default::default(),
|
||||||
|
cache_config: Default::default(),
|
||||||
|
dirs: Default::default(),
|
||||||
|
file_path: Some("state.json".into()),
|
||||||
|
pruning: Default::default(),
|
||||||
|
pruning_history: 64,
|
||||||
|
format: Default::default(),
|
||||||
|
compaction: Default::default(),
|
||||||
|
wal: true,
|
||||||
|
tracing: Default::default(),
|
||||||
|
fat_db: Default::default(),
|
||||||
|
at: BlockID::Latest,
|
||||||
|
storage: true,
|
||||||
|
code: true,
|
||||||
|
min_balance: None,
|
||||||
|
max_balance: None,
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_command_blockchain_export_with_custom_format() {
|
fn test_command_blockchain_export_with_custom_format() {
|
||||||
let args = vec!["parity", "export", "--format", "hex", "blockchain.json"];
|
let args = vec!["parity", "export", "blocks", "--format", "hex", "blockchain.json"];
|
||||||
let conf = parse(&args);
|
let conf = parse(&args);
|
||||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
||||||
spec: Default::default(),
|
spec: Default::default(),
|
||||||
|
@ -257,17 +257,13 @@ pub fn tracing_switch_to_bool(switch: Switch, user_defaults: &UserDefaults) -> R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fatdb_switch_to_bool(switch: Switch, user_defaults: &UserDefaults, algorithm: Algorithm) -> Result<bool, String> {
|
pub fn fatdb_switch_to_bool(switch: Switch, user_defaults: &UserDefaults, _algorithm: Algorithm) -> Result<bool, String> {
|
||||||
let result = match (user_defaults.is_first_launch, switch, user_defaults.fat_db) {
|
let result = match (user_defaults.is_first_launch, switch, user_defaults.fat_db) {
|
||||||
(false, Switch::On, false) => Err("FatDB resync required".into()),
|
(false, Switch::On, false) => Err("FatDB resync required".into()),
|
||||||
(_, Switch::On, _) => Ok(true),
|
(_, Switch::On, _) => Ok(true),
|
||||||
(_, Switch::Off, _) => Ok(false),
|
(_, Switch::Off, _) => Ok(false),
|
||||||
(_, Switch::Auto, def) => Ok(def),
|
(_, Switch::Auto, def) => Ok(def),
|
||||||
};
|
};
|
||||||
|
|
||||||
if result.clone().unwrap_or(false) && algorithm != Algorithm::Archive {
|
|
||||||
return Err("Fat DB is not supported with the chosen pruning option. Please rerun with `--pruning=archive`".into());
|
|
||||||
}
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
// get the mode
|
// get the mode
|
||||||
let mode = try!(mode_switch_to_bool(cmd.mode, &user_defaults));
|
let mode = try!(mode_switch_to_bool(cmd.mode, &user_defaults));
|
||||||
trace!(target: "mode", "mode is {:?}", mode);
|
trace!(target: "mode", "mode is {:?}", mode);
|
||||||
let network_enabled = match &mode { &Mode::Dark(_) | &Mode::Off => false, _ => true, };
|
let network_enabled = match mode { Mode::Dark(_) | Mode::Off => false, _ => true, };
|
||||||
|
|
||||||
// prepare client and snapshot paths.
|
// prepare client and snapshot paths.
|
||||||
let client_path = db_dirs.client_path(algorithm);
|
let client_path = db_dirs.client_path(algorithm);
|
||||||
@ -219,7 +219,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
// create client config
|
// create client config
|
||||||
let client_config = to_client_config(
|
let client_config = to_client_config(
|
||||||
&cmd.cache_config,
|
&cmd.cache_config,
|
||||||
mode,
|
mode.clone(),
|
||||||
tracing,
|
tracing,
|
||||||
fat_db,
|
fat_db,
|
||||||
cmd.compaction,
|
cmd.compaction,
|
||||||
@ -354,6 +354,8 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
// save user defaults
|
// save user defaults
|
||||||
user_defaults.pruning = algorithm;
|
user_defaults.pruning = algorithm;
|
||||||
user_defaults.tracing = tracing;
|
user_defaults.tracing = tracing;
|
||||||
|
user_defaults.fat_db = fat_db;
|
||||||
|
user_defaults.mode = mode;
|
||||||
try!(user_defaults.save(&user_defaults_path));
|
try!(user_defaults.save(&user_defaults_path));
|
||||||
|
|
||||||
let on_mode_change = move |mode: &Mode| {
|
let on_mode_change = move |mode: &Mode| {
|
||||||
|
@ -29,7 +29,7 @@ fetch = { path = "../util/fetch" }
|
|||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
transient-hashmap = "0.1"
|
transient-hashmap = "0.1"
|
||||||
serde_macros = { version = "0.8.0", optional = true }
|
serde_macros = { version = "0.8.0", optional = true }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
|
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
|
@ -28,7 +28,6 @@ use ethstore::random_phrase;
|
|||||||
use ethsync::{SyncProvider, ManageNetwork};
|
use ethsync::{SyncProvider, ManageNetwork};
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::client::{MiningBlockChainClient};
|
use ethcore::client::{MiningBlockChainClient};
|
||||||
use ethcore::ids::BlockID;
|
|
||||||
use ethcore::mode::Mode;
|
use ethcore::mode::Mode;
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
|
||||||
@ -38,9 +37,11 @@ use v1::types::{
|
|||||||
Bytes, U256, H160, H256, H512,
|
Bytes, U256, H160, H256, H512,
|
||||||
Peers, Transaction, RpcSettings, Histogram,
|
Peers, Transaction, RpcSettings, Histogram,
|
||||||
TransactionStats, LocalTransactionStatus,
|
TransactionStats, LocalTransactionStatus,
|
||||||
|
BlockNumber,
|
||||||
};
|
};
|
||||||
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
|
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
|
||||||
use v1::helpers::dispatch::DEFAULT_MAC;
|
use v1::helpers::dispatch::DEFAULT_MAC;
|
||||||
|
use v1::helpers::auto_args::Trailing;
|
||||||
|
|
||||||
/// Parity implementation.
|
/// Parity implementation.
|
||||||
pub struct ParityClient<C, M, S: ?Sized> where
|
pub struct ParityClient<C, M, S: ?Sized> where
|
||||||
@ -234,19 +235,20 @@ impl<C, M, S: ?Sized> Parity for ParityClient<C, M, S> where
|
|||||||
Ok(Brain::new(phrase).generate().unwrap().address().into())
|
Ok(Brain::new(phrase).generate().unwrap().address().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_accounts(&self) -> Result<Option<Vec<H160>>, Error> {
|
fn list_accounts(&self, count: u64, after: Option<H160>, block_number: Trailing<BlockNumber>) -> Result<Option<Vec<H160>>, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
|
|
||||||
Ok(take_weak!(self.client)
|
Ok(take_weak!(self.client)
|
||||||
.list_accounts(BlockID::Latest)
|
.list_accounts(block_number.0.into(), after.map(Into::into).as_ref(), count)
|
||||||
.map(|a| a.into_iter().map(Into::into).collect()))
|
.map(|a| a.into_iter().map(Into::into).collect()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_storage_keys(&self, _address: H160) -> Result<Option<Vec<H256>>, Error> {
|
fn list_storage_keys(&self, address: H160, count: u64, after: Option<H256>, block_number: Trailing<BlockNumber>) -> Result<Option<Vec<H256>>, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
|
|
||||||
// TODO: implement this
|
Ok(take_weak!(self.client)
|
||||||
Ok(None)
|
.list_storage(block_number.0.into(), &address.into(), after.map(Into::into).as_ref(), count)
|
||||||
|
.map(|a| a.into_iter().map(Into::into).collect()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes, Error> {
|
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes, Error> {
|
||||||
|
@ -89,7 +89,7 @@ fn should_return_list_of_items_to_confirm() {
|
|||||||
let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#;
|
||||||
let response = concat!(
|
let response = concat!(
|
||||||
r#"{"jsonrpc":"2.0","result":["#,
|
r#"{"jsonrpc":"2.0","result":["#,
|
||||||
r#"{"id":"0x1","payload":{"transaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
|
r#"{"id":"0x1","payload":{"sendTransaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
|
||||||
r#"{"id":"0x2","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#,
|
r#"{"id":"0x2","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#,
|
||||||
r#"],"id":1}"#
|
r#"],"id":1}"#
|
||||||
);
|
);
|
||||||
|
@ -18,11 +18,12 @@
|
|||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use v1::helpers::auto_args::Wrap;
|
use v1::helpers::auto_args::{Wrap, Trailing};
|
||||||
use v1::types::{
|
use v1::types::{
|
||||||
H160, H256, H512, U256, Bytes,
|
H160, H256, H512, U256, Bytes,
|
||||||
Peers, Transaction, RpcSettings, Histogram,
|
Peers, Transaction, RpcSettings, Histogram,
|
||||||
TransactionStats, LocalTransactionStatus,
|
TransactionStats, LocalTransactionStatus,
|
||||||
|
BlockNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
@ -103,12 +104,12 @@ build_rpc_trait! {
|
|||||||
|
|
||||||
/// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not.
|
/// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not.
|
||||||
#[rpc(name = "parity_listAccounts")]
|
#[rpc(name = "parity_listAccounts")]
|
||||||
fn list_accounts(&self) -> Result<Option<Vec<H160>>, Error>;
|
fn list_accounts(&self, u64, Option<H160>, Trailing<BlockNumber>) -> Result<Option<Vec<H160>>, Error>;
|
||||||
|
|
||||||
/// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`),
|
/// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`),
|
||||||
/// or null if not.
|
/// or null if not.
|
||||||
#[rpc(name = "parity_listStorageKeys")]
|
#[rpc(name = "parity_listStorageKeys")]
|
||||||
fn list_storage_keys(&self, H160) -> Result<Option<Vec<H256>>, Error>;
|
fn list_storage_keys(&self, H160, u64, Option<H256>, Trailing<BlockNumber>) -> Result<Option<Vec<H256>>, Error>;
|
||||||
|
|
||||||
/// Encrypt some data with a public key under ECIES.
|
/// Encrypt some data with a public key under ECIES.
|
||||||
/// First parameter is the 512-byte destination public key, second is the message.
|
/// First parameter is the 512-byte destination public key, second is the message.
|
||||||
|
@ -105,10 +105,10 @@ impl Serialize for ConfirmationResponse {
|
|||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize)]
|
||||||
pub enum ConfirmationPayload {
|
pub enum ConfirmationPayload {
|
||||||
/// Send Transaction
|
/// Send Transaction
|
||||||
#[serde(rename="transaction")]
|
#[serde(rename="sendTransaction")]
|
||||||
SendTransaction(TransactionRequest),
|
SendTransaction(TransactionRequest),
|
||||||
/// Sign Transaction
|
/// Sign Transaction
|
||||||
#[serde(rename="transaction")]
|
#[serde(rename="signTransaction")]
|
||||||
SignTransaction(TransactionRequest),
|
SignTransaction(TransactionRequest),
|
||||||
/// Signature
|
/// Signature
|
||||||
#[serde(rename="sign")]
|
#[serde(rename="sign")]
|
||||||
@ -221,7 +221,49 @@ mod tests {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
let res = serde_json::to_string(&ConfirmationRequest::from(request));
|
let res = serde_json::to_string(&ConfirmationRequest::from(request));
|
||||||
let expected = r#"{"id":"0xf","payload":{"transaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1"}}}"#;
|
let expected = r#"{"id":"0xf","payload":{"sendTransaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1"}}}"#;
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(res.unwrap(), expected.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_serialize_sign_transaction_confirmation() {
|
||||||
|
// given
|
||||||
|
let request = helpers::ConfirmationRequest {
|
||||||
|
id: 15.into(),
|
||||||
|
payload: helpers::ConfirmationPayload::SignTransaction(helpers::FilledTransactionRequest {
|
||||||
|
from: 0.into(),
|
||||||
|
to: None,
|
||||||
|
gas: 15_000.into(),
|
||||||
|
gas_price: 10_000.into(),
|
||||||
|
value: 100_000.into(),
|
||||||
|
data: vec![1, 2, 3],
|
||||||
|
nonce: Some(1.into()),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
let res = serde_json::to_string(&ConfirmationRequest::from(request));
|
||||||
|
let expected = r#"{"id":"0xf","payload":{"signTransaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1"}}}"#;
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(res.unwrap(), expected.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_serialize_decrypt_confirmation() {
|
||||||
|
// given
|
||||||
|
let request = helpers::ConfirmationRequest {
|
||||||
|
id: 15.into(),
|
||||||
|
payload: helpers::ConfirmationPayload::Decrypt(
|
||||||
|
10.into(), vec![1, 2, 3].into(),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
let res = serde_json::to_string(&ConfirmationRequest::from(request));
|
||||||
|
let expected = r#"{"id":"0xf","payload":{"decrypt":{"address":"0x000000000000000000000000000000000000000a","msg":"0x010203"}}}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(res.unwrap(), expected.to_owned());
|
assert_eq!(res.unwrap(), expected.to_owned());
|
||||||
|
@ -23,7 +23,7 @@ ethcore-rpc = { path = "../rpc" }
|
|||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
parity-ui = { path = "../dapps/ui", version = "1.4", optional = true }
|
parity-ui = { path = "../dapps/ui", version = "1.4", optional = true }
|
||||||
|
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
dev = ["clippy"]
|
dev = ["clippy"]
|
||||||
|
@ -80,6 +80,7 @@ pub struct AuthCodes<T: TimeProvider = DefaultTimeProvider> {
|
|||||||
impl AuthCodes<DefaultTimeProvider> {
|
impl AuthCodes<DefaultTimeProvider> {
|
||||||
|
|
||||||
/// Reads `AuthCodes` from file and creates new instance using `DefaultTimeProvider`.
|
/// Reads `AuthCodes` from file and creates new instance using `DefaultTimeProvider`.
|
||||||
|
#[cfg_attr(feature="dev", allow(single_char_pattern))]
|
||||||
pub fn from_file(file: &Path) -> io::Result<AuthCodes> {
|
pub fn from_file(file: &Path) -> io::Result<AuthCodes> {
|
||||||
let content = {
|
let content = {
|
||||||
if let Ok(mut file) = fs::File::open(file) {
|
if let Ok(mut file) = fs::File::open(file) {
|
||||||
@ -128,7 +129,7 @@ impl<T: TimeProvider> AuthCodes<T> {
|
|||||||
let mut file = try!(fs::File::create(file));
|
let mut file = try!(fs::File::create(file));
|
||||||
let content = self.codes.iter().map(|code| {
|
let content = self.codes.iter().map(|code| {
|
||||||
let mut data = vec![code.code.clone(), encode_time(code.created_at.clone())];
|
let mut data = vec![code.code.clone(), encode_time(code.created_at.clone())];
|
||||||
if let Some(used_at) = code.last_used_at.clone() {
|
if let Some(used_at) = code.last_used_at {
|
||||||
data.push(encode_time(used_at));
|
data.push(encode_time(used_at));
|
||||||
}
|
}
|
||||||
data.join(SEPARATOR)
|
data.join(SEPARATOR)
|
||||||
|
@ -99,7 +99,7 @@ fn auth_is_valid(codes_path: &Path, protocols: ws::Result<Vec<&str>>) -> bool {
|
|||||||
|
|
||||||
let res = codes.is_valid(&auth, time);
|
let res = codes.is_valid(&auth, time);
|
||||||
// make sure to save back authcodes - it might have been modified
|
// make sure to save back authcodes - it might have been modified
|
||||||
if let Err(_) = codes.to_file(codes_path) {
|
if codes.to_file(codes_path).is_err() {
|
||||||
warn!(target: "signer", "Couldn't save authorization codes to file.");
|
warn!(target: "signer", "Couldn't save authorization codes to file.");
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
|
@ -17,7 +17,7 @@ ethcore-network = { path = "../util/network" }
|
|||||||
ethcore-io = { path = "../util/io" }
|
ethcore-io = { path = "../util/io" }
|
||||||
ethcore = { path = "../ethcore" }
|
ethcore = { path = "../ethcore" }
|
||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
time = "0.1.34"
|
time = "0.1.34"
|
||||||
|
@ -625,7 +625,7 @@ impl ChainSync {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
#[cfg_attr(feature="dev", allow(cyclomatic_complexity, needless_borrow))]
|
||||||
/// Called by peer once it has new block headers during sync
|
/// Called by peer once it has new block headers during sync
|
||||||
fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> {
|
fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> {
|
||||||
let confirmed = match self.peers.get_mut(&peer_id) {
|
let confirmed = match self.peers.get_mut(&peer_id) {
|
||||||
@ -1174,7 +1174,7 @@ impl ChainSync {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
SyncState::SnapshotData => {
|
SyncState::SnapshotData => {
|
||||||
if let RestorationStatus::Ongoing { state_chunks: _, block_chunks: _, state_chunks_done, block_chunks_done, } = io.snapshot_service().status() {
|
if let RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } = io.snapshot_service().status() {
|
||||||
if self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize > MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD {
|
if self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize > MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD {
|
||||||
trace!(target: "sync", "Snapshot queue full, pausing sync");
|
trace!(target: "sync", "Snapshot queue full, pausing sync");
|
||||||
self.state = SyncState::SnapshotWaiting;
|
self.state = SyncState::SnapshotWaiting;
|
||||||
@ -1426,7 +1426,10 @@ impl ChainSync {
|
|||||||
packet.append(&chain.best_block_hash);
|
packet.append(&chain.best_block_hash);
|
||||||
packet.append(&chain.genesis_hash);
|
packet.append(&chain.genesis_hash);
|
||||||
if warp_protocol {
|
if warp_protocol {
|
||||||
let manifest = io.snapshot_service().manifest();
|
let manifest = match self.old_blocks.is_some() {
|
||||||
|
true => None,
|
||||||
|
false => io.snapshot_service().manifest(),
|
||||||
|
};
|
||||||
let block_number = manifest.as_ref().map_or(0, |m| m.block_number);
|
let block_number = manifest.as_ref().map_or(0, |m| m.block_number);
|
||||||
let manifest_hash = manifest.map_or(H256::new(), |m| m.into_rlp().sha3());
|
let manifest_hash = manifest.map_or(H256::new(), |m| m.into_rlp().sha3());
|
||||||
packet.append(&manifest_hash);
|
packet.append(&manifest_hash);
|
||||||
@ -1745,7 +1748,7 @@ impl ChainSync {
|
|||||||
self.restart(io);
|
self.restart(io);
|
||||||
self.continue_sync(io);
|
self.continue_sync(io);
|
||||||
},
|
},
|
||||||
RestorationStatus::Ongoing { state_chunks: _, block_chunks: _, state_chunks_done, block_chunks_done, } => {
|
RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } => {
|
||||||
if !self.snapshot.is_complete() && self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize <= MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD {
|
if !self.snapshot.is_complete() && self.snapshot.done_chunks() - (state_chunks_done + block_chunks_done) as usize <= MAX_SNAPSHOT_CHUNKS_DOWNLOAD_AHEAD {
|
||||||
trace!(target:"sync", "Resuming snapshot sync");
|
trace!(target:"sync", "Resuming snapshot sync");
|
||||||
self.state = SyncState::SnapshotData;
|
self.state = SyncState::SnapshotData;
|
||||||
@ -1999,12 +2002,16 @@ impl ChainSync {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::collections::{HashSet, VecDeque};
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use tests::snapshot::TestSnapshotService;
|
use tests::snapshot::TestSnapshotService;
|
||||||
|
use util::{U256, RwLock};
|
||||||
|
use util::sha3::Hashable;
|
||||||
|
use util::hash::{H256, FixedHash};
|
||||||
|
use util::bytes::Bytes;
|
||||||
|
use rlp::{Rlp, RlpStream, UntrustedRlp, View, Stream};
|
||||||
use super::*;
|
use super::*;
|
||||||
use ::SyncConfig;
|
use ::SyncConfig;
|
||||||
use util::*;
|
|
||||||
use rlp::*;
|
|
||||||
use super::{PeerInfo, PeerAsking};
|
use super::{PeerInfo, PeerAsking};
|
||||||
use ethcore::views::BlockView;
|
use ethcore::views::BlockView;
|
||||||
use ethcore::header::*;
|
use ethcore::header::*;
|
||||||
|
@ -158,19 +158,19 @@ impl TestNet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn peer(&self, i: usize) -> &TestPeer {
|
pub fn peer(&self, i: usize) -> &TestPeer {
|
||||||
self.peers.get(i).unwrap()
|
&self.peers[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn peer_mut(&mut self, i: usize) -> &mut TestPeer {
|
pub fn peer_mut(&mut self, i: usize) -> &mut TestPeer {
|
||||||
self.peers.get_mut(i).unwrap()
|
&mut self.peers[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self) {
|
pub fn start(&mut self) {
|
||||||
for peer in 0..self.peers.len() {
|
for peer in 0..self.peers.len() {
|
||||||
for client in 0..self.peers.len() {
|
for client in 0..self.peers.len() {
|
||||||
if peer != client {
|
if peer != client {
|
||||||
let mut p = self.peers.get_mut(peer).unwrap();
|
let mut p = &mut self.peers[peer];
|
||||||
p.sync.write().update_targets(&mut p.chain);
|
p.sync.write().update_targets(&p.chain);
|
||||||
p.sync.write().on_peer_connected(&mut TestIo::new(&mut p.chain, &p.snapshot_service, &mut p.queue, Some(client as PeerId)), client as PeerId);
|
p.sync.write().on_peer_connected(&mut TestIo::new(&mut p.chain, &p.snapshot_service, &mut p.queue, Some(client as PeerId)), client as PeerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,7 +181,7 @@ impl TestNet {
|
|||||||
for peer in 0..self.peers.len() {
|
for peer in 0..self.peers.len() {
|
||||||
if let Some(packet) = self.peers[peer].queue.pop_front() {
|
if let Some(packet) = self.peers[peer].queue.pop_front() {
|
||||||
let disconnecting = {
|
let disconnecting = {
|
||||||
let mut p = self.peers.get_mut(packet.recipient).unwrap();
|
let mut p = &mut self.peers[packet.recipient];
|
||||||
trace!("--- {} -> {} ---", peer, packet.recipient);
|
trace!("--- {} -> {} ---", peer, packet.recipient);
|
||||||
let to_disconnect = {
|
let to_disconnect = {
|
||||||
let mut io = TestIo::new(&mut p.chain, &p.snapshot_service, &mut p.queue, Some(peer as PeerId));
|
let mut io = TestIo::new(&mut p.chain, &p.snapshot_service, &mut p.queue, Some(peer as PeerId));
|
||||||
@ -198,7 +198,7 @@ impl TestNet {
|
|||||||
};
|
};
|
||||||
for d in &disconnecting {
|
for d in &disconnecting {
|
||||||
// notify other peers that this peer is disconnecting
|
// notify other peers that this peer is disconnecting
|
||||||
let mut p = self.peers.get_mut(*d).unwrap();
|
let mut p = &mut self.peers[*d];
|
||||||
let mut io = TestIo::new(&mut p.chain, &p.snapshot_service, &mut p.queue, Some(peer as PeerId));
|
let mut io = TestIo::new(&mut p.chain, &p.snapshot_service, &mut p.queue, Some(peer as PeerId));
|
||||||
p.sync.write().on_peer_aborting(&mut io, peer as PeerId);
|
p.sync.write().on_peer_aborting(&mut io, peer as PeerId);
|
||||||
}
|
}
|
||||||
|
2
test.sh
2
test.sh
@ -19,5 +19,5 @@ case $1 in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
. ./scripts/targets.sh
|
. ./scripts/targets.sh
|
||||||
cargo test $OPTIONS --features "$FEATURES" $TARGETS $1 \
|
cargo test -j 8 $OPTIONS --features "$FEATURES" $TARGETS $1 \
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ rlp = { path = "rlp" }
|
|||||||
heapsize = { version = "0.3", features = ["unstable"] }
|
heapsize = { version = "0.3", features = ["unstable"] }
|
||||||
itertools = "0.4"
|
itertools = "0.4"
|
||||||
sha3 = { path = "sha3" }
|
sha3 = { path = "sha3" }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
libc = "0.2.7"
|
libc = "0.2.7"
|
||||||
vergen = "0.1"
|
vergen = "0.1"
|
||||||
|
@ -15,7 +15,7 @@ time = "0.1.34"
|
|||||||
tiny-keccak = "1.0"
|
tiny-keccak = "1.0"
|
||||||
rust-crypto = "0.2.34"
|
rust-crypto = "0.2.34"
|
||||||
slab = "0.2"
|
slab = "0.2"
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
igd = "0.5.0"
|
igd = "0.5.0"
|
||||||
libc = "0.2.7"
|
libc = "0.2.7"
|
||||||
parking_lot = "0.3"
|
parking_lot = "0.3"
|
||||||
|
@ -507,7 +507,7 @@ mod tests {
|
|||||||
use std::io::{Read, Write, Error, Cursor, ErrorKind};
|
use std::io::{Read, Write, Error, Cursor, ErrorKind};
|
||||||
use mio::{Ready};
|
use mio::{Ready};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use util::bytes::*;
|
use util::bytes::Bytes;
|
||||||
use devtools::*;
|
use devtools::*;
|
||||||
use io::*;
|
use io::*;
|
||||||
|
|
||||||
|
@ -555,10 +555,11 @@ impl Discovery {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::hash::*;
|
use std::net::{SocketAddr};
|
||||||
use util::sha3::*;
|
use util::sha3::Hashable;
|
||||||
use std::net::*;
|
use util::FixedHash;
|
||||||
use node_table::*;
|
use node_table::{Node, NodeId, NodeEndpoint};
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use rustc_serialize::hex::FromHex;
|
use rustc_serialize::hex::FromHex;
|
||||||
use ethkey::{Random, Generator};
|
use ethkey::{Random, Generator};
|
||||||
|
@ -333,7 +333,7 @@ mod test {
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rustc_serialize::hex::FromHex;
|
use rustc_serialize::hex::FromHex;
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::hash::*;
|
use util::hash::{H256, FixedHash};
|
||||||
use io::*;
|
use io::*;
|
||||||
use mio::tcp::TcpStream;
|
use mio::tcp::TcpStream;
|
||||||
use stats::NetworkStats;
|
use stats::NetworkStats;
|
||||||
|
@ -357,9 +357,9 @@ pub fn is_valid_node_url(url: &str) -> bool {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
|
||||||
|
use util::H512;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::net::*;
|
|
||||||
use util::hash::*;
|
|
||||||
use devtools::*;
|
use devtools::*;
|
||||||
use AllowIP;
|
use AllowIP;
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user