Merge branch 'master' into lightsync
This commit is contained in:
commit
f85313fbff
2
.gitignore
vendored
2
.gitignore
vendored
@ -32,3 +32,5 @@
|
|||||||
out/
|
out/
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
/parity.*
|
||||||
|
@ -20,8 +20,10 @@ linux-stable:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
|
- curl --data "secret=$RELEASES_SECRET" http://icarus.parity.io/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF
|
||||||
- cargo build -j $(nproc) --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
|
- export SHA3=$(target/release/parity tools hash 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
|
||||||
- cp target/release/parity deb/usr/bin/parity
|
- cp target/release/parity deb/usr/bin/parity
|
||||||
@ -36,6 +38,7 @@ linux-stable:
|
|||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity.md5 --body parity.md5
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity.md5 --body parity.md5
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
|
||||||
|
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-stable
|
- rust-stable
|
||||||
@ -92,15 +95,18 @@ linux-centos:
|
|||||||
script:
|
script:
|
||||||
- export CXX="g++"
|
- export CXX="g++"
|
||||||
- export CC="gcc"
|
- export CC="gcc"
|
||||||
|
- export PLATFORM=x86_64-unknown-centos-gnu
|
||||||
- cargo build -j $(nproc) --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
|
||||||
|
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- 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
|
- 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/x86_64-unknown-centos-gnu
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity --body target/release/parity
|
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity --body target/release/parity
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity.md5 --body parity.md5
|
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity.md5 --body parity.md5
|
||||||
|
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-centos
|
- rust-centos
|
||||||
@ -119,22 +125,26 @@ linux-i686:
|
|||||||
script:
|
script:
|
||||||
- export HOST_CC=gcc
|
- export HOST_CC=gcc
|
||||||
- export HOST_CXX=g++
|
- export HOST_CXX=g++
|
||||||
|
- export COMMIT=$(git rev-parse HEAD)
|
||||||
|
- export PLATFORM=i686-unknown-linux-gnu
|
||||||
- cargo build -j $(nproc) --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/$PLATFORM/release/parity
|
||||||
- md5sum target/i686-unknown-linux-gnu/release/parity > parity.md5
|
- md5sum target/$PLATFORM/release/parity > parity.md5
|
||||||
|
- export SHA3=$(target/$PLATFORM/release/parity tools hash target/$PLATFORM/release/parity)
|
||||||
- sh scripts/deb-build.sh i386
|
- sh scripts/deb-build.sh i386
|
||||||
- cp target/i686-unknown-linux-gnu/release/parity deb/usr/bin/parity
|
- cp target/$PLATFORM/release/parity deb/usr/bin/parity
|
||||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||||
- dpkg-deb -b deb "parity_"$VER"_i386.deb"
|
- dpkg-deb -b deb "parity_"$VER"_i386.deb"
|
||||||
- md5sum "parity_"$VER"_i386.deb" > "parity_"$VER"_i386.deb.md5"
|
- md5sum "parity_"$VER"_i386.deb" > "parity_"$VER"_i386.deb.md5"
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- 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
|
- 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/i686-unknown-linux-gnu
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity --body target/i686-unknown-linux-gnu/release/parity
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/$PLATFORM/release/parity
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity.md5 --body parity.md5
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb" --body "parity_"$VER"_i386.deb"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_i386.deb" --body "parity_"$VER"_i386.deb"
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb.md5" --body "parity_"$VER"_i386.deb.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_i386.deb.md5" --body "parity_"$VER"_i386.deb.md5"
|
||||||
|
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-i686
|
- rust-i686
|
||||||
@ -292,7 +302,6 @@ linux-aarch64:
|
|||||||
- aws configure set aws_secret_access_key $s3_secret
|
- 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
|
- 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 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.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" --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"
|
- 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"
|
||||||
@ -312,10 +321,13 @@ darwin:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
|
- export COMMIT=$(git rev-parse HEAD)
|
||||||
|
- export PLATFORM=x86_64-apple-darwin
|
||||||
- cargo build -j 8 --release #$CARGOFLAGS
|
- cargo build -j 8 --release #$CARGOFLAGS
|
||||||
- cargo build -j 8 --release -p ethstore #$CARGOFLAGS
|
- cargo build -j 8 --release -p ethstore #$CARGOFLAGS
|
||||||
- rm -rf parity.md5
|
- rm -rf parity.md5
|
||||||
- md5sum target/release/parity > parity.md5
|
- md5sum target/release/parity > parity.md5
|
||||||
|
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||||
- packagesbuild -v mac/Parity.pkgproj
|
- packagesbuild -v mac/Parity.pkgproj
|
||||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||||
- mv target/release/Parity\ Ethereum.pkg "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
- mv target/release/Parity\ Ethereum.pkg "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
||||||
@ -323,11 +335,12 @@ darwin:
|
|||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- 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
|
- 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/x86_64-apple-darwin
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity --body target/release/parity
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/release/parity
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity.md5 --body parity.md5
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
||||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5"
|
||||||
|
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
tags:
|
tags:
|
||||||
- osx
|
- osx
|
||||||
artifacts:
|
artifacts:
|
||||||
@ -345,12 +358,14 @@ windows:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
|
- set PLATFORM=x86_64-pc-windows-msvc
|
||||||
- set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt
|
- set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt
|
||||||
- set LIB=C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64
|
- set LIB=C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64
|
||||||
- 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 --release #%CARGOFLAGS%
|
||||||
|
- FOR /F "tokens=* USEBACKQ" %%i IN ('target\release\parity.exe tools hash target\release\parity.exe') DO set SHA3=%%i
|
||||||
- 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
|
||||||
@ -385,6 +400,7 @@ windows:
|
|||||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe.md5 --body nsis\InstallParity.exe.md5
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe.md5 --body nsis\InstallParity.exe.md5
|
||||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip --body nsis\win-installer.zip
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip --body nsis\win-installer.zip
|
||||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip.md5 --body nsis\win-installer.zip.md5
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip.md5 --body nsis\win-installer.zip.md5
|
||||||
|
- curl --data "commit=$CI_BUILD_REF&sha3=%SHA3%&filename=parity.exe&secret=%RELEASES_SECRET%" http://icarus.parity.io/push-build/$CI_BUILD_REF_NAME/%PLATFORM%
|
||||||
tags:
|
tags:
|
||||||
- rust-windows
|
- rust-windows
|
||||||
artifacts:
|
artifacts:
|
||||||
@ -399,9 +415,10 @@ test-darwin:
|
|||||||
- triggers
|
- triggers
|
||||||
before_script:
|
before_script:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
|
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
|
||||||
script:
|
script:
|
||||||
- export RUST_BACKTRACE=1
|
- export RUST_BACKTRACE=1
|
||||||
- ./test.sh $CARGOFLAGS
|
- if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
|
||||||
tags:
|
tags:
|
||||||
- osx
|
- osx
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
@ -413,7 +430,7 @@ test-windows:
|
|||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
script:
|
script:
|
||||||
- set RUST_BACKTRACE=1
|
- set RUST_BACKTRACE=1
|
||||||
- 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
|
- echo 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
|
||||||
tags:
|
tags:
|
||||||
- rust-windows
|
- rust-windows
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
@ -448,10 +465,10 @@ test-rust-beta:
|
|||||||
image: ethcore/rust:beta
|
image: ethcore/rust:beta
|
||||||
before_script:
|
before_script:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
|
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
|
||||||
script:
|
script:
|
||||||
- export RUST_BACKTRACE=1
|
- export RUST_BACKTRACE=1
|
||||||
- echo $JS_FILES_MODIFIED
|
- if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
|
||||||
- ./test.sh $CARGOFLAGS
|
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-beta
|
- rust-beta
|
||||||
@ -463,9 +480,10 @@ test-rust-nightly:
|
|||||||
image: ethcore/rust:nightly
|
image: ethcore/rust:nightly
|
||||||
before_script:
|
before_script:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
|
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
|
||||||
script:
|
script:
|
||||||
- export RUST_BACKTRACE=1
|
- export RUST_BACKTRACE=1
|
||||||
- ./test.sh $CARGOFLAGS
|
- if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-nightly
|
- rust-nightly
|
||||||
|
94
Cargo.lock
generated
94
Cargo.lock
generated
@ -12,7 +12,6 @@ dependencies = [
|
|||||||
"ethcore 1.5.0",
|
"ethcore 1.5.0",
|
||||||
"ethcore-dapps 1.5.0",
|
"ethcore-dapps 1.5.0",
|
||||||
"ethcore-devtools 1.5.0",
|
"ethcore-devtools 1.5.0",
|
||||||
"ethcore-hash-fetch 1.5.0",
|
|
||||||
"ethcore-io 1.5.0",
|
"ethcore-io 1.5.0",
|
||||||
"ethcore-ipc 1.5.0",
|
"ethcore-ipc 1.5.0",
|
||||||
"ethcore-ipc-codegen 1.5.0",
|
"ethcore-ipc-codegen 1.5.0",
|
||||||
@ -33,14 +32,16 @@ dependencies = [
|
|||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-hash-fetch 1.5.0",
|
||||||
"parity-rpc-client 1.4.0",
|
"parity-rpc-client 1.4.0",
|
||||||
|
"parity-updater 1.5.0",
|
||||||
"regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.1.0",
|
"rlp 0.1.0",
|
||||||
"rpassword 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rpassword 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rpc-cli 1.4.0",
|
"rpc-cli 1.4.0",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -306,6 +307,7 @@ dependencies = [
|
|||||||
"clippy 0.0.103 (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)",
|
||||||
|
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.5.0",
|
"ethash 1.5.0",
|
||||||
"ethcore-bloom-journal 0.1.0",
|
"ethcore-bloom-journal 0.1.0",
|
||||||
"ethcore-devtools 1.5.0",
|
"ethcore-devtools 1.5.0",
|
||||||
@ -330,7 +332,7 @@ dependencies = [
|
|||||||
"rlp 0.1.0",
|
"rlp 0.1.0",
|
||||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -359,7 +361,6 @@ dependencies = [
|
|||||||
"clippy 0.0.103 (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.5.0",
|
"ethcore-devtools 1.5.0",
|
||||||
"ethcore-hash-fetch 1.5.0",
|
|
||||||
"ethcore-rpc 1.5.0",
|
"ethcore-rpc 1.5.0",
|
||||||
"ethcore-util 1.5.0",
|
"ethcore-util 1.5.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
@ -371,6 +372,7 @@ dependencies = [
|
|||||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-hash-fetch 1.5.0",
|
||||||
"parity-ui 1.5.0",
|
"parity-ui 1.5.0",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -390,18 +392,6 @@ dependencies = [
|
|||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ethcore-hash-fetch"
|
|
||||||
version = "1.5.0"
|
|
||||||
dependencies = [
|
|
||||||
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ethcore-util 1.5.0",
|
|
||||||
"fetch 0.1.0",
|
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-io"
|
name = "ethcore-io"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@ -420,7 +410,7 @@ dependencies = [
|
|||||||
"ethcore-devtools 1.5.0",
|
"ethcore-devtools 1.5.0",
|
||||||
"ethcore-util 1.5.0",
|
"ethcore-util 1.5.0",
|
||||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -443,7 +433,7 @@ dependencies = [
|
|||||||
"ethcore-ipc-nano 1.5.0",
|
"ethcore-ipc-nano 1.5.0",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -468,7 +458,7 @@ dependencies = [
|
|||||||
"ethcore-util 1.5.0",
|
"ethcore-util 1.5.0",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -547,8 +537,10 @@ dependencies = [
|
|||||||
"jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||||
"jsonrpc-macros 0.1.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-macros 0.1.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-updater 1.5.0",
|
||||||
"rlp 0.1.0",
|
"rlp 0.1.0",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -590,7 +582,7 @@ dependencies = [
|
|||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
|
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -706,7 +698,7 @@ dependencies = [
|
|||||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.1.0",
|
"rlp 0.1.0",
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -795,6 +787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "https-fetch"
|
name = "https-fetch"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
|
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
|
||||||
"rustls 0.1.2 (git+https://github.com/ctz/rustls)",
|
"rustls 0.1.2 (git+https://github.com/ctz/rustls)",
|
||||||
@ -861,6 +854,17 @@ dependencies = [
|
|||||||
"xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipc-common-types"
|
||||||
|
version = "1.5.0"
|
||||||
|
dependencies = [
|
||||||
|
"ethcore-ipc 1.5.0",
|
||||||
|
"ethcore-ipc-codegen 1.5.0",
|
||||||
|
"ethcore-util 1.5.0",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "isatty"
|
name = "isatty"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -1325,6 +1329,18 @@ dependencies = [
|
|||||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parity-hash-fetch"
|
||||||
|
version = "1.5.0"
|
||||||
|
dependencies = [
|
||||||
|
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethcore-util 1.5.0",
|
||||||
|
"fetch 0.1.0",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-rpc-client"
|
name = "parity-rpc-client"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -1364,11 +1380,26 @@ 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#2cdda91549dfeebd94775b348a443f8ee5446e9f"
|
source = "git+https://github.com/ethcore/js-precompiled.git#3d390b35737ce212d358f26b5ec8d9644b252a88"
|
||||||
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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parity-updater"
|
||||||
|
version = "1.5.0"
|
||||||
|
dependencies = [
|
||||||
|
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethcore 1.5.0",
|
||||||
|
"ethcore-ipc 1.5.0",
|
||||||
|
"ethcore-ipc-codegen 1.5.0",
|
||||||
|
"ethcore-util 1.5.0",
|
||||||
|
"ethsync 1.5.0",
|
||||||
|
"ipc-common-types 1.5.0",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-hash-fetch 1.5.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
@ -1698,6 +1729,23 @@ dependencies = [
|
|||||||
"nom 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
@ -2271,6 +2319,8 @@ dependencies = [
|
|||||||
"checksum rustls 0.1.2 (git+https://github.com/ctz/rustls)" = "<none>"
|
"checksum rustls 0.1.2 (git+https://github.com/ctz/rustls)" = "<none>"
|
||||||
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||||
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
|
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
|
||||||
|
"checksum semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2ff60ecdb19c255841c066cbfa5f8c2a4ada1eb3ae47c77ab6667128da71f5"
|
||||||
|
"checksum semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e88e43a5a74dd2a11707f9c21dfd4a423c66bd871df813227bb0a3e78f3a1ae9"
|
||||||
"checksum serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b1dfda9ebb31d29fa8b94d7eb3031a86a8dcec065f0fe268a30f98867bf45775"
|
"checksum serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b1dfda9ebb31d29fa8b94d7eb3031a86a8dcec065f0fe268a30f98867bf45775"
|
||||||
"checksum serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e422ae53d7933f59c6ff57e7b5870b5c9094b1f473f78ec33d89f8a692c3ec02"
|
"checksum serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e422ae53d7933f59c6ff57e7b5870b5c9094b1f473f78ec33d89f8a692c3ec02"
|
||||||
"checksum serde_codegen_internals 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f877e2781ed0a323295d1c9f0e26556117b5a11489fc47b1848dfb98b3173d21"
|
"checksum serde_codegen_internals 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f877e2781ed0a323295d1c9f0e26556117b5a11489fc47b1848dfb98b3173d21"
|
||||||
|
15
Cargo.toml
15
Cargo.toml
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
description = "Ethcore client."
|
description = "Parity Ethereum client"
|
||||||
name = "parity"
|
name = "parity"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
@ -20,7 +20,7 @@ time = "0.1"
|
|||||||
num_cpus = "0.2"
|
num_cpus = "0.2"
|
||||||
number_prefix = "0.2"
|
number_prefix = "0.2"
|
||||||
rpassword = "0.2.1"
|
rpassword = "0.2.1"
|
||||||
semver = "0.2"
|
semver = "0.5"
|
||||||
ansi_term = "0.7"
|
ansi_term = "0.7"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
regex = "0.1"
|
regex = "0.1"
|
||||||
@ -32,25 +32,26 @@ app_dirs = "1.1.1"
|
|||||||
hyper = { version = "0.9", default-features = false }
|
hyper = { version = "0.9", default-features = false }
|
||||||
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
||||||
fdlimit = "0.1"
|
fdlimit = "0.1"
|
||||||
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
rlp = { path = "util/rlp" }
|
||||||
|
ethsync = { path = "sync" }
|
||||||
ethcore = { path = "ethcore" }
|
ethcore = { path = "ethcore" }
|
||||||
ethcore-util = { path = "util" }
|
ethcore-util = { path = "util" }
|
||||||
ethsync = { path = "sync" }
|
|
||||||
ethcore-io = { path = "util/io" }
|
ethcore-io = { path = "util/io" }
|
||||||
ethcore-devtools = { path = "devtools" }
|
ethcore-devtools = { path = "devtools" }
|
||||||
ethcore-rpc = { path = "rpc" }
|
ethcore-rpc = { path = "rpc" }
|
||||||
ethcore-signer = { path = "signer" }
|
ethcore-signer = { path = "signer" }
|
||||||
ethcore-ipc-nano = { path = "ipc/nano" }
|
|
||||||
ethcore-ipc = { path = "ipc/rpc" }
|
ethcore-ipc = { path = "ipc/rpc" }
|
||||||
|
ethcore-ipc-nano = { path = "ipc/nano" }
|
||||||
ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
|
ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
|
||||||
ethcore-logger = { path = "logger" }
|
ethcore-logger = { path = "logger" }
|
||||||
ethcore-hash-fetch = { path = "ethcore/hash-fetch" }
|
|
||||||
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.103", optional = true}
|
|
||||||
rpc-cli = { path = "rpc_cli" }
|
rpc-cli = { path = "rpc_cli" }
|
||||||
parity-rpc-client = { path = "rpc_client" }
|
parity-rpc-client = { path = "rpc_client" }
|
||||||
ethcore-light = { path = "ethcore/light" }
|
ethcore-light = { path = "ethcore/light" }
|
||||||
|
parity-hash-fetch = { path = "hash-fetch" }
|
||||||
|
parity-updater = { path = "updater" }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.2"
|
winapi = "0.2"
|
||||||
|
@ -30,9 +30,9 @@ zip = { version = "0.1", default-features = false }
|
|||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
ethcore-rpc = { path = "../rpc" }
|
ethcore-rpc = { path = "../rpc" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore-hash-fetch = { path = "../ethcore/hash-fetch" }
|
|
||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
parity-ui = { path = "./ui" }
|
parity-ui = { path = "./ui" }
|
||||||
|
parity-hash-fetch = { path = "../hash-fetch" }
|
||||||
|
|
||||||
clippy = { version = "0.0.103", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ extern crate mime_guess;
|
|||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate ethcore_rpc;
|
extern crate ethcore_rpc;
|
||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
extern crate ethcore_hash_fetch as hash_fetch;
|
extern crate parity_hash_fetch as hash_fetch;
|
||||||
extern crate linked_hash_map;
|
extern crate linked_hash_map;
|
||||||
extern crate fetch;
|
extern crate fetch;
|
||||||
extern crate parity_dapps_glue as parity_dapps;
|
extern crate parity_dapps_glue as parity_dapps;
|
||||||
|
@ -65,7 +65,7 @@ fn init_logger() {
|
|||||||
if let Ok(log) = env::var("RUST_LOG") {
|
if let Ok(log) = env::var("RUST_LOG") {
|
||||||
let mut builder = LogBuilder::new();
|
let mut builder = LogBuilder::new();
|
||||||
builder.parse(&log);
|
builder.parse(&log);
|
||||||
builder.init().expect("Logger is initialized only once.");
|
let _ = builder.init(); // ignore errors since ./test.sh will call this multiple times.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ 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" }
|
||||||
semver = "0.2"
|
semver = "0.5"
|
||||||
ethcore-ipc-nano = { path = "../ipc/nano" }
|
ethcore-ipc-nano = { path = "../ipc/nano" }
|
||||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||||
crossbeam = "0.2"
|
crossbeam = "0.2"
|
||||||
|
@ -270,8 +270,7 @@ impl DatabaseService for Database {
|
|||||||
Ok(next_iterator)
|
Ok(next_iterator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_next(&self, handle: IteratorHandle) -> Option<KeyValue>
|
fn iter_next(&self, handle: IteratorHandle) -> Option<KeyValue> {
|
||||||
{
|
|
||||||
let mut iterators = self.iterators.write();
|
let mut iterators = self.iterators.write();
|
||||||
let mut iterator = match iterators.get_mut(&handle) {
|
let mut iterator = match iterators.get_mut(&handle) {
|
||||||
Some(some_iterator) => some_iterator,
|
Some(some_iterator) => some_iterator,
|
||||||
|
@ -21,7 +21,7 @@ crossbeam = "0.2.9"
|
|||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
bloomchain = "0.1"
|
bloomchain = "0.1"
|
||||||
rayon = "0.4.2"
|
rayon = "0.4.2"
|
||||||
semver = "0.2"
|
semver = "0.5"
|
||||||
bit-set = "0.4"
|
bit-set = "0.4"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
@ -42,6 +42,7 @@ ethcore-ipc-nano = { path = "../ipc/nano" }
|
|||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
lru-cache = "0.1.0"
|
lru-cache = "0.1.0"
|
||||||
ethcore-bloom-journal = { path = "../util/bloom" }
|
ethcore-bloom-journal = { path = "../util/bloom" }
|
||||||
|
ethabi = "0.2.2"
|
||||||
|
|
||||||
[dependencies.hyper]
|
[dependencies.hyper]
|
||||||
git = "https://github.com/ethcore/hyper"
|
git = "https://github.com/ethcore/hyper"
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
"eip155Transition": 10,
|
"eip155Transition": 10,
|
||||||
"eip160Transition": 10,
|
"eip160Transition": 10,
|
||||||
"eip161abcTransition": 10,
|
"eip161abcTransition": 10,
|
||||||
"eip161dTransition": 10
|
"eip161dTransition": 10,
|
||||||
|
"maxCodeSize": 24576
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit e8f4624b7f1a15c63674eecf577c7ab76c3b16be
|
Subproject commit 9028c4801fd39fbb71a9796979182549a24e81c8
|
@ -13,7 +13,9 @@
|
|||||||
|
|
||||||
// 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/>.
|
||||||
|
|
||||||
use std::collections::{HashSet, HashMap, BTreeMap, VecDeque};
|
use std::collections::{HashSet, HashMap, BTreeMap, VecDeque};
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::path::{Path};
|
use std::path::{Path};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -22,7 +24,7 @@ use std::time::{Instant};
|
|||||||
use time::precise_time_ns;
|
use time::precise_time_ns;
|
||||||
|
|
||||||
// util
|
// util
|
||||||
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, Hashable};
|
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, MutexGuard, Hashable};
|
||||||
use util::{journaldb, TrieFactory, Trie};
|
use util::{journaldb, TrieFactory, Trie};
|
||||||
use util::{U256, H256, Address, H2048, Uint, FixedHash};
|
use util::{U256, H256, Address, H2048, Uint, FixedHash};
|
||||||
use util::trie::TrieSpec;
|
use util::trie::TrieSpec;
|
||||||
@ -42,7 +44,7 @@ use env_info::LastHashes;
|
|||||||
use verification;
|
use verification;
|
||||||
use verification::{PreverifiedBlock, Verifier};
|
use verification::{PreverifiedBlock, Verifier};
|
||||||
use block::*;
|
use block::*;
|
||||||
use transaction::{LocalizedTransaction, SignedTransaction, Action};
|
use transaction::{LocalizedTransaction, SignedTransaction, Transaction, Action};
|
||||||
use blockchain::extras::TransactionAddress;
|
use blockchain::extras::TransactionAddress;
|
||||||
use types::filter::Filter;
|
use types::filter::Filter;
|
||||||
use types::mode::Mode as IpcMode;
|
use types::mode::Mode as IpcMode;
|
||||||
@ -68,6 +70,7 @@ use factory::Factories;
|
|||||||
use rlp::{decode, View, UntrustedRlp};
|
use rlp::{decode, View, UntrustedRlp};
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use rand::OsRng;
|
use rand::OsRng;
|
||||||
|
use client::registry::Registry;
|
||||||
|
|
||||||
// re-export
|
// re-export
|
||||||
pub use types::blockchain_info::BlockChainInfo;
|
pub use types::blockchain_info::BlockChainInfo;
|
||||||
@ -124,6 +127,7 @@ impl SleepState {
|
|||||||
/// Blockchain database client backed by a persistent database. Owns and manages a blockchain and a block queue.
|
/// Blockchain database client backed by a persistent database. Owns and manages a blockchain and a block queue.
|
||||||
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
|
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
|
enabled: AtomicBool,
|
||||||
mode: Mutex<Mode>,
|
mode: Mutex<Mode>,
|
||||||
chain: RwLock<Arc<BlockChain>>,
|
chain: RwLock<Arc<BlockChain>>,
|
||||||
tracedb: RwLock<TraceDB<BlockChain>>,
|
tracedb: RwLock<TraceDB<BlockChain>>,
|
||||||
@ -148,6 +152,7 @@ pub struct Client {
|
|||||||
history: u64,
|
history: u64,
|
||||||
rng: Mutex<OsRng>,
|
rng: Mutex<OsRng>,
|
||||||
on_mode_change: Mutex<Option<Box<FnMut(&Mode) + 'static + Send>>>,
|
on_mode_change: Mutex<Option<Box<FnMut(&Mode) + 'static + Send>>>,
|
||||||
|
registrar: Mutex<Option<Registry>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
@ -160,6 +165,7 @@ impl Client {
|
|||||||
message_channel: IoChannel<ClientIoMessage>,
|
message_channel: IoChannel<ClientIoMessage>,
|
||||||
db_config: &DatabaseConfig,
|
db_config: &DatabaseConfig,
|
||||||
) -> Result<Arc<Client>, ClientError> {
|
) -> Result<Arc<Client>, ClientError> {
|
||||||
|
|
||||||
let path = path.to_path_buf();
|
let path = path.to_path_buf();
|
||||||
let gb = spec.genesis_block();
|
let gb = spec.genesis_block();
|
||||||
|
|
||||||
@ -221,7 +227,8 @@ impl Client {
|
|||||||
accountdb: Default::default(),
|
accountdb: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let client = Client {
|
let client = Arc::new(Client {
|
||||||
|
enabled: AtomicBool::new(true),
|
||||||
sleep_state: Mutex::new(SleepState::new(awake)),
|
sleep_state: Mutex::new(SleepState::new(awake)),
|
||||||
liveness: AtomicBool::new(awake),
|
liveness: AtomicBool::new(awake),
|
||||||
mode: Mutex::new(config.mode.clone()),
|
mode: Mutex::new(config.mode.clone()),
|
||||||
@ -246,8 +253,15 @@ impl Client {
|
|||||||
history: history,
|
history: history,
|
||||||
rng: Mutex::new(try!(OsRng::new().map_err(::util::UtilError::StdIo))),
|
rng: Mutex::new(try!(OsRng::new().map_err(::util::UtilError::StdIo))),
|
||||||
on_mode_change: Mutex::new(None),
|
on_mode_change: Mutex::new(None),
|
||||||
};
|
registrar: Mutex::new(None),
|
||||||
Ok(Arc::new(client))
|
});
|
||||||
|
if let Some(reg_addr) = client.additional_params().get("registrar").and_then(|s| Address::from_str(s).ok()) {
|
||||||
|
trace!(target: "client", "Found registrar at {}", reg_addr);
|
||||||
|
let weak = Arc::downgrade(&client);
|
||||||
|
let registrar = Registry::new(reg_addr, move |a, d| weak.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d)));
|
||||||
|
*client.registrar.lock() = Some(registrar);
|
||||||
|
}
|
||||||
|
Ok(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an actor to be notified on certain events
|
/// Adds an actor to be notified on certain events
|
||||||
@ -268,6 +282,11 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the Registry object - useful for looking up names.
|
||||||
|
pub fn registrar(&self) -> MutexGuard<Option<Registry>> {
|
||||||
|
self.registrar.lock()
|
||||||
|
}
|
||||||
|
|
||||||
/// Register an action to be done if a mode change happens.
|
/// Register an action to be done if a mode change happens.
|
||||||
pub fn on_mode_change<F>(&self, f: F) where F: 'static + FnMut(&Mode) + Send {
|
pub fn on_mode_change<F>(&self, f: F) where F: 'static + FnMut(&Mode) + Send {
|
||||||
*self.on_mode_change.lock() = Some(Box::new(f));
|
*self.on_mode_change.lock() = Some(Box::new(f));
|
||||||
@ -395,6 +414,12 @@ impl Client {
|
|||||||
|
|
||||||
/// This is triggered by a message coming from a block queue when the block is ready for insertion
|
/// This is triggered by a message coming from a block queue when the block is ready for insertion
|
||||||
pub fn import_verified_blocks(&self) -> usize {
|
pub fn import_verified_blocks(&self) -> usize {
|
||||||
|
|
||||||
|
// Shortcut out if we know we're incapable of syncing the chain.
|
||||||
|
if !self.enabled.load(AtomicOrdering::Relaxed) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
let max_blocks_to_import = 4;
|
let max_blocks_to_import = 4;
|
||||||
let (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration, is_empty) = {
|
let (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration, is_empty) = {
|
||||||
let mut imported_blocks = Vec::with_capacity(max_blocks_to_import);
|
let mut imported_blocks = Vec::with_capacity(max_blocks_to_import);
|
||||||
@ -663,10 +688,17 @@ impl Client {
|
|||||||
/// Tick the client.
|
/// Tick the client.
|
||||||
// TODO: manage by real events.
|
// TODO: manage by real events.
|
||||||
pub fn tick(&self) {
|
pub fn tick(&self) {
|
||||||
|
self.check_garbage();
|
||||||
|
self.check_snooze();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_garbage(&self) {
|
||||||
self.chain.read().collect_garbage();
|
self.chain.read().collect_garbage();
|
||||||
self.block_queue.collect_garbage();
|
self.block_queue.collect_garbage();
|
||||||
self.tracedb.read().collect_garbage();
|
self.tracedb.read().collect_garbage();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_snooze(&self) {
|
||||||
let mode = self.mode.lock().clone();
|
let mode = self.mode.lock().clone();
|
||||||
match mode {
|
match mode {
|
||||||
Mode::Dark(timeout) => {
|
Mode::Dark(timeout) => {
|
||||||
@ -700,16 +732,6 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look up the block number for the given block ID.
|
|
||||||
pub fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
|
||||||
match id {
|
|
||||||
BlockId::Number(number) => Some(number),
|
|
||||||
BlockId::Hash(ref hash) => self.chain.read().block_number(hash),
|
|
||||||
BlockId::Earliest => Some(0),
|
|
||||||
BlockId::Latest | BlockId::Pending => Some(self.chain.read().best_block_number()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Take a snapshot at the given block.
|
/// Take a snapshot at the given block.
|
||||||
/// If the ID given is "latest", this will default to 1000 blocks behind.
|
/// If the ID given is "latest", this will default to 1000 blocks behind.
|
||||||
pub fn take_snapshot<W: snapshot_io::SnapshotWriter + Send>(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> {
|
pub fn take_snapshot<W: snapshot_io::SnapshotWriter + Send>(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> {
|
||||||
@ -908,8 +930,17 @@ impl BlockChainClient for Client {
|
|||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn disable(&self) {
|
||||||
|
self.set_mode(IpcMode::Off);
|
||||||
|
self.enabled.store(false, AtomicOrdering::Relaxed);
|
||||||
|
self.clear_queue();
|
||||||
|
}
|
||||||
|
|
||||||
fn set_mode(&self, new_mode: IpcMode) {
|
fn set_mode(&self, new_mode: IpcMode) {
|
||||||
trace!(target: "mode", "Client::set_mode({:?})", new_mode);
|
trace!(target: "mode", "Client::set_mode({:?})", new_mode);
|
||||||
|
if !self.enabled.load(AtomicOrdering::Relaxed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
let mut mode = self.mode.lock();
|
let mut mode = self.mode.lock();
|
||||||
*mode = new_mode.clone().into();
|
*mode = new_mode.clone().into();
|
||||||
@ -935,6 +966,15 @@ impl BlockChainClient for Client {
|
|||||||
Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash))
|
Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
||||||
|
match id {
|
||||||
|
BlockId::Number(number) => Some(number),
|
||||||
|
BlockId::Hash(ref hash) => self.chain.read().block_number(hash),
|
||||||
|
BlockId::Earliest => Some(0),
|
||||||
|
BlockId::Latest | BlockId::Pending => Some(self.chain.read().best_block_number()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||||
let chain = self.chain.read();
|
let chain = self.chain.read();
|
||||||
Self::block_hash(&chain, id).and_then(|hash| chain.block_body(&hash))
|
Self::block_hash(&chain, id).and_then(|hash| chain.block_body(&hash))
|
||||||
@ -1331,6 +1371,34 @@ impl BlockChainClient for Client {
|
|||||||
earliest_state: self.state_db.lock().journal_db().earliest_era().unwrap_or(0),
|
earliest_state: self.state_db.lock().journal_db().earliest_era().unwrap_or(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn call_contract(&self, address: Address, data: Bytes) -> Result<Bytes, String> {
|
||||||
|
let from = Address::default();
|
||||||
|
let transaction = Transaction {
|
||||||
|
nonce: self.latest_nonce(&from),
|
||||||
|
action: Action::Call(address),
|
||||||
|
gas: U256::from(50_000_000),
|
||||||
|
gas_price: U256::default(),
|
||||||
|
value: U256::default(),
|
||||||
|
data: data,
|
||||||
|
}.fake_sign(from);
|
||||||
|
|
||||||
|
self.call(&transaction, BlockId::Latest, Default::default())
|
||||||
|
.map_err(|e| format!("{:?}", e))
|
||||||
|
.map(|executed| {
|
||||||
|
executed.output
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn registrar_address(&self) -> Option<Address> {
|
||||||
|
self.registrar.lock().as_ref().map(|r| r.address.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn registry_address(&self, name: String) -> Option<Address> {
|
||||||
|
self.registrar.lock().as_ref()
|
||||||
|
.and_then(|r| r.get_address(&(name.as_bytes().sha3()), "A").ok())
|
||||||
|
.and_then(|a| if a.is_zero() { None } else { Some(a) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MiningBlockChainClient for Client {
|
impl MiningBlockChainClient for Client {
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use trace::Error as TraceError;
|
use trace::Error as TraceError;
|
||||||
use util::UtilError;
|
use util::UtilError;
|
||||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
//! Blockchain database client.
|
//! Blockchain database client.
|
||||||
|
|
||||||
|
mod registry;
|
||||||
mod config;
|
mod config;
|
||||||
mod error;
|
mod error;
|
||||||
mod test_client;
|
mod test_client;
|
||||||
|
264
ethcore/src/client/registry.rs
Normal file
264
ethcore/src/client/registry.rs
Normal file
File diff suppressed because one or more lines are too long
@ -488,6 +488,10 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| Rlp::new(r).at(0).as_raw().to_vec()))
|
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| Rlp::new(r).at(0).as_raw().to_vec()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_number(&self, _id: BlockId) -> Option<BlockNumber> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||||
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| {
|
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| {
|
||||||
let mut stream = RlpStream::new_list(2);
|
let mut stream = RlpStream::new_list(2);
|
||||||
@ -694,10 +698,18 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
|
|
||||||
fn set_mode(&self, _: Mode) { unimplemented!(); }
|
fn set_mode(&self, _: Mode) { unimplemented!(); }
|
||||||
|
|
||||||
|
fn disable(&self) { unimplemented!(); }
|
||||||
|
|
||||||
fn pruning_info(&self) -> PruningInfo {
|
fn pruning_info(&self) -> PruningInfo {
|
||||||
PruningInfo {
|
PruningInfo {
|
||||||
earliest_chain: 1,
|
earliest_chain: 1,
|
||||||
earliest_state: 1,
|
earliest_state: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn call_contract(&self, _address: Address, _data: Bytes) -> Result<Bytes, String> { Ok(vec![]) }
|
||||||
|
|
||||||
|
fn registrar_address(&self) -> Option<Address> { None }
|
||||||
|
|
||||||
|
fn registry_address(&self, _name: String) -> Option<Address> { None }
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,9 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// Get raw block header data by block id.
|
/// Get raw block header data by block id.
|
||||||
fn block_header(&self, id: BlockId) -> Option<Bytes>;
|
fn block_header(&self, id: BlockId) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Look up the block number for the given block ID.
|
||||||
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
||||||
|
|
||||||
/// Get raw block body data by block id.
|
/// Get raw block body data by block id.
|
||||||
/// Block body is an RLP list of two items: uncles and transactions.
|
/// Block body is an RLP list of two items: uncles and transactions.
|
||||||
fn block_body(&self, id: BlockId) -> Option<Bytes>;
|
fn block_body(&self, id: BlockId) -> Option<Bytes>;
|
||||||
@ -255,6 +258,10 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// Set the mode.
|
/// Set the mode.
|
||||||
fn set_mode(&self, mode: Mode);
|
fn set_mode(&self, mode: Mode);
|
||||||
|
|
||||||
|
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
||||||
|
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
||||||
|
fn disable(&self);
|
||||||
|
|
||||||
/// Returns engine-related extra info for `BlockId`.
|
/// Returns engine-related extra info for `BlockId`.
|
||||||
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>>;
|
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>>;
|
||||||
|
|
||||||
@ -263,6 +270,15 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
|
|
||||||
/// Returns information about pruning/data availability.
|
/// Returns information about pruning/data availability.
|
||||||
fn pruning_info(&self) -> PruningInfo;
|
fn pruning_info(&self) -> PruningInfo;
|
||||||
|
|
||||||
|
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
|
||||||
|
fn call_contract(&self, address: Address, data: Bytes) -> Result<Bytes, String>;
|
||||||
|
|
||||||
|
/// Get the address of the registry itself.
|
||||||
|
fn registrar_address(&self) -> Option<Address>;
|
||||||
|
|
||||||
|
/// Get the address of a particular blockchain service, if available.
|
||||||
|
fn registry_address(&self, name: String) -> Option<Address>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IpcConfig for BlockChainClient { }
|
impl IpcConfig for BlockChainClient { }
|
||||||
|
@ -100,6 +100,7 @@ impl AsMillis for Duration {
|
|||||||
impl AuthorityRound {
|
impl AuthorityRound {
|
||||||
/// Create a new instance of AuthorityRound engine.
|
/// Create a new instance of AuthorityRound engine.
|
||||||
pub fn new(params: CommonParams, our_params: AuthorityRoundParams, builtins: BTreeMap<Address, Builtin>) -> Result<Arc<Self>, Error> {
|
pub fn new(params: CommonParams, our_params: AuthorityRoundParams, builtins: BTreeMap<Address, Builtin>) -> Result<Arc<Self>, Error> {
|
||||||
|
let should_timeout = our_params.start_step.is_none();
|
||||||
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / our_params.step_duration.as_secs())) as usize;
|
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / our_params.step_duration.as_secs())) as usize;
|
||||||
let engine = Arc::new(
|
let engine = Arc::new(
|
||||||
AuthorityRound {
|
AuthorityRound {
|
||||||
@ -113,18 +114,17 @@ impl AuthorityRound {
|
|||||||
account_provider: Mutex::new(None),
|
account_provider: Mutex::new(None),
|
||||||
password: RwLock::new(None),
|
password: RwLock::new(None),
|
||||||
});
|
});
|
||||||
let handler = TransitionHandler { engine: Arc::downgrade(&engine) };
|
// Do not initialize timeouts for tests.
|
||||||
try!(engine.transition_service.register_handler(Arc::new(handler)));
|
if should_timeout {
|
||||||
|
let handler = TransitionHandler { engine: Arc::downgrade(&engine) };
|
||||||
|
try!(engine.transition_service.register_handler(Arc::new(handler)));
|
||||||
|
}
|
||||||
Ok(engine)
|
Ok(engine)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(&self) -> usize {
|
|
||||||
self.step.load(AtomicOrdering::SeqCst)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remaining_step_duration(&self) -> Duration {
|
fn remaining_step_duration(&self) -> Duration {
|
||||||
let now = unix_now();
|
let now = unix_now();
|
||||||
let step_end = self.our_params.step_duration * (self.step() as u32 + 1);
|
let step_end = self.our_params.step_duration * (self.step.load(AtomicOrdering::SeqCst) as u32 + 1);
|
||||||
if step_end > now {
|
if step_end > now {
|
||||||
step_end - now
|
step_end - now
|
||||||
} else {
|
} else {
|
||||||
@ -228,7 +228,7 @@ impl Engine for AuthorityRound {
|
|||||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
||||||
if self.proposed.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
if self.proposed.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
let step = self.step();
|
let step = self.step.load(AtomicOrdering::SeqCst);
|
||||||
if self.is_step_proposer(step, header.author()) {
|
if self.is_step_proposer(step, header.author()) {
|
||||||
if let Some(ref ap) = *self.account_provider.lock() {
|
if let Some(ref ap) = *self.account_provider.lock() {
|
||||||
// Account should be permanently unlocked, otherwise sealing will fail.
|
// Account should be permanently unlocked, otherwise sealing will fail.
|
||||||
@ -265,7 +265,7 @@ impl Engine for AuthorityRound {
|
|||||||
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||||
let header_step = try!(header_step(header));
|
let header_step = try!(header_step(header));
|
||||||
// Give one step slack if step is lagging, double vote is still not possible.
|
// Give one step slack if step is lagging, double vote is still not possible.
|
||||||
if header_step <= self.step() + 1 {
|
if header_step <= self.step.load(AtomicOrdering::SeqCst) + 1 {
|
||||||
let proposer_signature = try!(header_signature(header));
|
let proposer_signature = try!(header_signature(header));
|
||||||
let ok_sig = try!(verify_address(self.step_proposer(header_step), &proposer_signature, &header.bare_hash()));
|
let ok_sig = try!(verify_address(self.step_proposer(header_step), &proposer_signature, &header.bare_hash()));
|
||||||
if ok_sig {
|
if ok_sig {
|
||||||
|
@ -29,6 +29,12 @@ pub use self::denominations::*;
|
|||||||
|
|
||||||
use super::spec::*;
|
use super::spec::*;
|
||||||
|
|
||||||
|
/// Most recent fork block that we support on Mainnet.
|
||||||
|
pub const FORK_SUPPORTED_FRONTIER: u64 = 2675000;
|
||||||
|
|
||||||
|
/// Most recent fork block that we support on Ropsten.
|
||||||
|
pub const FORK_SUPPORTED_ROPSTEN: u64 = 10;
|
||||||
|
|
||||||
fn load(b: &[u8]) -> Spec {
|
fn load(b: &[u8]) -> Spec {
|
||||||
Spec::load(b).expect("chain spec is invalid")
|
Spec::load(b).expect("chain spec is invalid")
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,7 @@ extern crate lru_cache;
|
|||||||
|
|
||||||
#[cfg(feature = "jit" )]
|
#[cfg(feature = "jit" )]
|
||||||
extern crate evmjit;
|
extern crate evmjit;
|
||||||
|
extern crate ethabi;
|
||||||
|
|
||||||
pub extern crate ethstore;
|
pub extern crate ethstore;
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
use util::{U256, H256};
|
use util::{U256, H256};
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
|
use types::security_level::SecurityLevel;
|
||||||
|
|
||||||
/// Information about the blockchain gathered together.
|
/// Information about the blockchain gathered together.
|
||||||
#[derive(Clone, Debug, Binary)]
|
#[derive(Clone, Debug, Binary)]
|
||||||
@ -41,3 +42,15 @@ pub struct BlockChainInfo {
|
|||||||
/// Number of the first block on the best sequence.
|
/// Number of the first block on the best sequence.
|
||||||
pub first_block_number: Option<BlockNumber>,
|
pub first_block_number: Option<BlockNumber>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BlockChainInfo {
|
||||||
|
/// Determine the security model for the current state.
|
||||||
|
pub fn security_level(&self) -> SecurityLevel {
|
||||||
|
// TODO: Detect SecurityLevel::FullState : https://github.com/ethcore/parity/issues/3834
|
||||||
|
if self.ancient_block_number.is_none() || self.first_block_number.is_none() {
|
||||||
|
SecurityLevel::FullProofOfWork
|
||||||
|
} else {
|
||||||
|
SecurityLevel::PartialProofOfWork(self.best_block_number - self.first_block_number.expect("Guard condition means this is not none"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,4 +34,5 @@ pub mod block_import_error;
|
|||||||
pub mod restoration_status;
|
pub mod restoration_status;
|
||||||
pub mod snapshot_manifest;
|
pub mod snapshot_manifest;
|
||||||
pub mod mode;
|
pub mod mode;
|
||||||
pub mod pruning_info;
|
pub mod pruning_info;
|
||||||
|
pub mod security_level;
|
40
ethcore/src/types/security_level.rs
Normal file
40
ethcore/src/types/security_level.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Indication of how secure the chain is.
|
||||||
|
|
||||||
|
use header::BlockNumber;
|
||||||
|
|
||||||
|
/// Indication of how secure the chain is.
|
||||||
|
#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, Binary)]
|
||||||
|
pub enum SecurityLevel {
|
||||||
|
/// All blocks from genesis to chain head are known to have valid state transitions and PoW.
|
||||||
|
FullState,
|
||||||
|
/// All blocks from genesis to chain head are known to have a valid PoW.
|
||||||
|
FullProofOfWork,
|
||||||
|
/// Some recent headers (the argument) are known to have a valid PoW.
|
||||||
|
PartialProofOfWork(BlockNumber),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SecurityLevel {
|
||||||
|
/// `true` for `FullPoW`/`FullState`.
|
||||||
|
pub fn is_full(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
SecurityLevel::FullState | SecurityLevel::FullProofOfWork => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
description = "Fetching hash-addressed content."
|
description = "Fetching hash-addressed content."
|
||||||
homepage = "http://parity.io"
|
homepage = "http://parity.io"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
name = "ethcore-hash-fetch"
|
name = "parity-hash-fetch"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
@ -11,5 +11,5 @@ log = "0.3"
|
|||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
ethabi = "0.2.2"
|
ethabi = "0.2.2"
|
||||||
mime_guess = "1.6.1"
|
mime_guess = "1.6.1"
|
||||||
fetch = { path = "../../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
ethcore-util = { path = "../../util" }
|
ethcore-util = { path = "../util" }
|
@ -26,7 +26,7 @@ use fetch::{Fetch, FetchError, Client as FetchClient};
|
|||||||
use urlhint::{ContractClient, URLHintContract, URLHint, URLHintResult};
|
use urlhint::{ContractClient, URLHintContract, URLHint, URLHintResult};
|
||||||
|
|
||||||
/// API for fetching by hash.
|
/// API for fetching by hash.
|
||||||
pub trait HashFetch {
|
pub trait HashFetch: Send + Sync + 'static {
|
||||||
/// Fetch hash-addressed content.
|
/// Fetch hash-addressed content.
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
/// 1. `hash` - content hash
|
/// 1. `hash` - content hash
|
||||||
@ -42,7 +42,12 @@ pub enum Error {
|
|||||||
/// Hash could not be resolved to a valid content address.
|
/// Hash could not be resolved to a valid content address.
|
||||||
NoResolution,
|
NoResolution,
|
||||||
/// Downloaded content hash does not match.
|
/// Downloaded content hash does not match.
|
||||||
HashMismatch { expected: H256, got: H256 },
|
HashMismatch {
|
||||||
|
/// Expected hash
|
||||||
|
expected: H256,
|
||||||
|
/// Computed hash
|
||||||
|
got: H256,
|
||||||
|
},
|
||||||
/// IO Error while validating hash.
|
/// IO Error while validating hash.
|
||||||
IO(io::Error),
|
IO(io::Error),
|
||||||
/// Error during fetch.
|
/// Error during fetch.
|
||||||
@ -79,7 +84,7 @@ impl Client {
|
|||||||
|
|
||||||
impl HashFetch for Client {
|
impl HashFetch for Client {
|
||||||
fn fetch(&self, hash: H256, on_done: Box<Fn(Result<PathBuf, Error>) + Send>) -> Result<(), Error> {
|
fn fetch(&self, hash: H256, on_done: Box<Fn(Result<PathBuf, Error>) + Send>) -> Result<(), Error> {
|
||||||
debug!(target: "dapps", "Fetching: {:?}", hash);
|
debug!(target: "fetch", "Fetching: {:?}", hash);
|
||||||
|
|
||||||
let url = try!(
|
let url = try!(
|
||||||
self.contract.resolve(hash.to_vec()).map(|content| match content {
|
self.contract.resolve(hash.to_vec()).map(|content| match content {
|
||||||
@ -92,7 +97,7 @@ impl HashFetch for Client {
|
|||||||
}).ok_or_else(|| Error::NoResolution)
|
}).ok_or_else(|| Error::NoResolution)
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!(target: "dapps", "Resolved {:?} to {:?}. Fetching...", hash, url);
|
debug!(target: "fetch", "Resolved {:?} to {:?}. Fetching...", hash, url);
|
||||||
|
|
||||||
self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| {
|
self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| {
|
||||||
fn validate_hash(hash: H256, result: Result<PathBuf, FetchError>) -> Result<PathBuf, Error> {
|
fn validate_hash(hash: H256, result: Result<PathBuf, FetchError>) -> Result<PathBuf, Error> {
|
||||||
@ -107,7 +112,7 @@ impl HashFetch for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(target: "dapps", "Content fetched, validating hash ({:?})", hash);
|
debug!(target: "fetch", "Content fetched, validating hash ({:?})", hash);
|
||||||
on_done(validate_hash(hash, result))
|
on_done(validate_hash(hash, result))
|
||||||
})).map_err(Into::into)
|
})).map_err(Into::into)
|
||||||
}
|
}
|
@ -30,4 +30,4 @@ mod client;
|
|||||||
|
|
||||||
pub mod urlhint;
|
pub mod urlhint;
|
||||||
|
|
||||||
pub use client::{HashFetch, Client};
|
pub use client::{HashFetch, Client, Error};
|
20
ipc-common-types/Cargo.toml
Normal file
20
ipc-common-types/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
description = "Types that implement IPC and are common to multiple modules."
|
||||||
|
name = "ipc-common-types"
|
||||||
|
version = "1.5.0"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = "0.3"
|
||||||
|
semver = "0.5"
|
||||||
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
|
ethcore-util = { path = "../util" }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
lto = false
|
21
ipc-common-types/build.rs
Normal file
21
ipc-common-types/build.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
extern crate ethcore_ipc_codegen;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap();
|
||||||
|
}
|
26
ipc-common-types/src/lib.rs
Normal file
26
ipc-common-types/src/lib.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Updater for Parity executables
|
||||||
|
|
||||||
|
#[macro_use] extern crate log;
|
||||||
|
extern crate semver;
|
||||||
|
extern crate ethcore_util as util;
|
||||||
|
extern crate ethcore_ipc as ipc;
|
||||||
|
|
||||||
|
mod types;
|
||||||
|
|
||||||
|
pub use types::*;
|
21
ipc-common-types/src/types/mod.rs
Normal file
21
ipc-common-types/src/types/mod.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Types used in the public api
|
||||||
|
|
||||||
|
#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/mod.rs.in"));
|
||||||
|
|
21
ipc-common-types/src/types/mod.rs.in
Normal file
21
ipc-common-types/src/types/mod.rs.in
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
pub mod release_track;
|
||||||
|
pub mod version_info;
|
||||||
|
|
||||||
|
pub use release_track::{ReleaseTrack};
|
||||||
|
pub use version_info::{VersionInfo};
|
82
ipc-common-types/src/types/release_track.rs
Normal file
82
ipc-common-types/src/types/release_track.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Types used in the public API
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
/// A release's track.
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Debug, Binary)]
|
||||||
|
pub enum ReleaseTrack {
|
||||||
|
/// Stable track.
|
||||||
|
Stable,
|
||||||
|
/// Beta track.
|
||||||
|
Beta,
|
||||||
|
/// Nightly track.
|
||||||
|
Nightly,
|
||||||
|
/// Testing track.
|
||||||
|
Testing,
|
||||||
|
/// No known track, also "current executable's track" when it's not yet known.
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ReleaseTrack {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
write!(f, "{}", match *self {
|
||||||
|
ReleaseTrack::Stable => "stable",
|
||||||
|
ReleaseTrack::Beta => "beta",
|
||||||
|
ReleaseTrack::Nightly => "nightly",
|
||||||
|
ReleaseTrack::Testing => "testing",
|
||||||
|
ReleaseTrack::Unknown => "unknown",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for ReleaseTrack {
|
||||||
|
fn from(s: &'a str) -> Self {
|
||||||
|
match s {
|
||||||
|
"stable" => ReleaseTrack::Stable,
|
||||||
|
"beta" => ReleaseTrack::Beta,
|
||||||
|
"nightly" => ReleaseTrack::Nightly,
|
||||||
|
"testing" => ReleaseTrack::Testing,
|
||||||
|
_ => ReleaseTrack::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for ReleaseTrack {
|
||||||
|
fn from(i: u8) -> Self {
|
||||||
|
match i {
|
||||||
|
1 => ReleaseTrack::Stable,
|
||||||
|
2 => ReleaseTrack::Beta,
|
||||||
|
3 => ReleaseTrack::Nightly,
|
||||||
|
4 => ReleaseTrack::Testing,
|
||||||
|
_ => ReleaseTrack::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<u8> for ReleaseTrack {
|
||||||
|
fn into(self) -> u8 {
|
||||||
|
match self {
|
||||||
|
ReleaseTrack::Stable => 1,
|
||||||
|
ReleaseTrack::Beta => 2,
|
||||||
|
ReleaseTrack::Nightly => 3,
|
||||||
|
ReleaseTrack::Testing => 4,
|
||||||
|
ReleaseTrack::Unknown => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
ipc-common-types/src/types/version_info.rs
Normal file
68
ipc-common-types/src/types/version_info.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Types used in the public API
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use semver::{Version};
|
||||||
|
use util::{H160};
|
||||||
|
use util::misc::raw_package_info;
|
||||||
|
use release_track::ReleaseTrack;
|
||||||
|
|
||||||
|
/// Version information of a particular release.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Binary)]
|
||||||
|
pub struct VersionInfo {
|
||||||
|
/// The track on which it was released.
|
||||||
|
pub track: ReleaseTrack,
|
||||||
|
/// The version.
|
||||||
|
pub version: Version,
|
||||||
|
/// The (SHA1?) 160-bit hash of this build's code base.
|
||||||
|
pub hash: H160,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for VersionInfo {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
write!(f, "{}.{}.{}-{}-{}", self.version.major, self.version.minor, self.version.patch, self.track, self.hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VersionInfo {
|
||||||
|
/// Get information for this (currently running) binary.
|
||||||
|
pub fn this() -> Self {
|
||||||
|
let raw = raw_package_info();
|
||||||
|
VersionInfo {
|
||||||
|
track: raw.0.into(),
|
||||||
|
version: { let mut v = Version::parse(raw.1).expect("Environment variables are known to be valid; qed"); v.build = vec![]; v.pre = vec![]; v },
|
||||||
|
hash: raw.2.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compose the information from the provided raw fields.
|
||||||
|
pub fn from_raw(semver: u32, track: u8, hash: H160) -> Self {
|
||||||
|
let t = track.into();
|
||||||
|
VersionInfo {
|
||||||
|
version: Version {
|
||||||
|
major: (semver >> 16) as u64,
|
||||||
|
minor: ((semver >> 8) & 0xff) as u64,
|
||||||
|
patch: (semver & 0xff) as u64,
|
||||||
|
build: vec![],
|
||||||
|
pre: vec![],
|
||||||
|
},
|
||||||
|
track: t,
|
||||||
|
hash: hash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -263,7 +263,7 @@ fn binary_expr_struct(
|
|||||||
let range_ident = builder.id(format!("r{}", index));
|
let range_ident = builder.id(format!("r{}", index));
|
||||||
|
|
||||||
let error_message = "Error serializing member: ".to_owned() + &::syntax::print::pprust::expr_to_string(&member_expr);
|
let error_message = "Error serializing member: ".to_owned() + &::syntax::print::pprust::expr_to_string(&member_expr);
|
||||||
let error_message_literal = builder.expr().lit().str::<&str>(&error_message);
|
let _error_message_literal = builder.expr().lit().str::<&str>(&error_message);
|
||||||
|
|
||||||
match raw_ident.as_ref() {
|
match raw_ident.as_ref() {
|
||||||
"u8" => {
|
"u8" => {
|
||||||
@ -286,7 +286,6 @@ fn binary_expr_struct(
|
|||||||
post_write_stmts.push(quote_stmt!(cx,
|
post_write_stmts.push(quote_stmt!(cx,
|
||||||
if $range_ident.end - $range_ident.start > 0 {
|
if $range_ident.end - $range_ident.start > 0 {
|
||||||
if let Err(e) = $member_expr .to_bytes(&mut buffer[$range_ident], length_stack) {
|
if let Err(e) = $member_expr .to_bytes(&mut buffer[$range_ident], length_stack) {
|
||||||
warn!(target: "ipc", $error_message_literal);
|
|
||||||
return Err(e)
|
return Err(e)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ build = "build.rs"
|
|||||||
ethcore-ipc = { path = "../rpc" }
|
ethcore-ipc = { path = "../rpc" }
|
||||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||||
ethcore-ipc-nano = { path = "../nano" }
|
ethcore-ipc-nano = { path = "../nano" }
|
||||||
semver = "0.2"
|
semver = "0.5"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
|
|
||||||
|
@ -10,4 +10,4 @@ license = "GPL-3.0"
|
|||||||
ethcore-devtools = { path = "../../devtools" }
|
ethcore-devtools = { path = "../../devtools" }
|
||||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||||
ethcore-util = { path = "../../util" }
|
ethcore-util = { path = "../../util" }
|
||||||
semver = "0.2"
|
semver = "0.5"
|
||||||
|
@ -804,6 +804,17 @@ binary_fixed_size!(H512);
|
|||||||
binary_fixed_size!(H2048);
|
binary_fixed_size!(H2048);
|
||||||
binary_fixed_size!(Address);
|
binary_fixed_size!(Address);
|
||||||
binary_fixed_size!(BinHandshake);
|
binary_fixed_size!(BinHandshake);
|
||||||
|
binary_fixed_size!(BinVersion);
|
||||||
|
|
||||||
|
impl BinaryConvertable for ::semver::Version {
|
||||||
|
fn from_bytes(bytes: &[u8], length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<Self, BinaryConvertError> {
|
||||||
|
BinVersion::from_bytes(bytes, length_stack).map(BinVersion::to_semver)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<(), BinaryConvertError> {
|
||||||
|
BinVersion::from(self.clone()).to_bytes(buffer, length_stack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn vec_serialize() {
|
fn vec_serialize() {
|
||||||
|
@ -24,4 +24,4 @@ extern crate ethcore_util as util;
|
|||||||
pub mod interface;
|
pub mod interface;
|
||||||
pub mod binary;
|
pub mod binary;
|
||||||
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
|
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
|
||||||
pub use binary::{BinaryConvertable, BinaryConvertError, BinHandshake};
|
pub use binary::{BinaryConvertable, BinaryConvertError, BinVersion, BinHandshake};
|
||||||
|
@ -10,7 +10,7 @@ path = "run.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ethcore-ipc = { path = "../rpc" }
|
ethcore-ipc = { path = "../rpc" }
|
||||||
ethcore-devtools = { path = "../../devtools" }
|
ethcore-devtools = { path = "../../devtools" }
|
||||||
semver = "0.2"
|
semver = "0.5"
|
||||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||||
ethcore-ipc-nano = { path = "../nano" }
|
ethcore-ipc-nano = { path = "../nano" }
|
||||||
ethcore-util = { path = "../../util" }
|
ethcore-util = { path = "../../util" }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "0.2.127",
|
"version": "0.2.128",
|
||||||
"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>",
|
||||||
@ -36,7 +36,7 @@
|
|||||||
"ci:build:npm": "NODE_ENV=production webpack --config webpack/npm",
|
"ci:build:npm": "NODE_ENV=production webpack --config webpack/npm",
|
||||||
"start": "npm install && npm run build:lib && npm run build:dll && npm run start:app",
|
"start": "npm install && npm run build:lib && npm run build:dll && npm run start:app",
|
||||||
"start:app": "node webpack/dev.server",
|
"start:app": "node webpack/dev.server",
|
||||||
"clean": "rm -rf ./build ./coverage",
|
"clean": "rm -rf ./.build ./.coverage ./.happypack ./.npmjs ./build",
|
||||||
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
||||||
"lint": "npm run lint:css && npm run lint:js",
|
"lint": "npm run lint:css && npm run lint:js",
|
||||||
"lint:cached": "npm run lint:css && npm run lint:js:cached",
|
"lint:cached": "npm run lint:css && npm run lint:js:cached",
|
||||||
|
@ -110,7 +110,8 @@ export function outPeers (peers) {
|
|||||||
return {
|
return {
|
||||||
active: outNumber(peers.active),
|
active: outNumber(peers.active),
|
||||||
connected: outNumber(peers.connected),
|
connected: outNumber(peers.connected),
|
||||||
max: outNumber(peers.max)
|
max: outNumber(peers.max),
|
||||||
|
peers: peers.peers.map(p => { Object.keys(p.protocols).forEach(k => { p.protocols[k].difficulty = outNumber(p.protocols[k].difficulty); }); return p; })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,10 +147,50 @@ describe('api/format/output', () => {
|
|||||||
|
|
||||||
describe('outPeers', () => {
|
describe('outPeers', () => {
|
||||||
it('converts all internal numbers to BigNumbers', () => {
|
it('converts all internal numbers to BigNumbers', () => {
|
||||||
expect(outPeers({ active: 789, connected: '456', max: 0x7b })).to.deep.equal({
|
expect(outPeers({
|
||||||
|
active: 789,
|
||||||
|
connected: '456',
|
||||||
|
max: 0x7b,
|
||||||
|
peers: [
|
||||||
|
{
|
||||||
|
caps: ['par/1'],
|
||||||
|
id: '0x01',
|
||||||
|
name: 'Parity',
|
||||||
|
network: {
|
||||||
|
localAddress: '10.0.0.1',
|
||||||
|
remoteAddress: '10.0.0.1'
|
||||||
|
},
|
||||||
|
protocols: {
|
||||||
|
par: {
|
||||||
|
difficulty: '0x0f',
|
||||||
|
head: '0x02',
|
||||||
|
version: 63
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})).to.deep.equal({
|
||||||
active: new BigNumber(789),
|
active: new BigNumber(789),
|
||||||
connected: new BigNumber(456),
|
connected: new BigNumber(456),
|
||||||
max: new BigNumber(123)
|
max: new BigNumber(123),
|
||||||
|
peers: [
|
||||||
|
{
|
||||||
|
caps: ['par/1'],
|
||||||
|
id: '0x01',
|
||||||
|
name: 'Parity',
|
||||||
|
network: {
|
||||||
|
localAddress: '10.0.0.1',
|
||||||
|
remoteAddress: '10.0.0.1'
|
||||||
|
},
|
||||||
|
protocols: {
|
||||||
|
par: {
|
||||||
|
difficulty: new BigNumber(15),
|
||||||
|
head: '0x02',
|
||||||
|
version: 63
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -54,6 +54,11 @@ export default class Parity {
|
|||||||
.execute('parity_checkRequest', inNumber16(requestId));
|
.execute('parity_checkRequest', inNumber16(requestId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consensusCapability () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_consensusCapability');
|
||||||
|
}
|
||||||
|
|
||||||
dappsPort () {
|
dappsPort () {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_dappsPort')
|
.execute('parity_dappsPort')
|
||||||
@ -90,6 +95,11 @@ export default class Parity {
|
|||||||
.execute('parity_enode');
|
.execute('parity_enode');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
executeUpgrade () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_executeUpgrade');
|
||||||
|
}
|
||||||
|
|
||||||
extraData () {
|
extraData () {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_extraData');
|
.execute('parity_extraData');
|
||||||
@ -243,6 +253,11 @@ export default class Parity {
|
|||||||
.then(outAddress);
|
.then(outAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
releasesInfo () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_releasesInfo');
|
||||||
|
}
|
||||||
|
|
||||||
removeReservedPeer (encode) {
|
removeReservedPeer (encode) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_removeReservedPeer', encode);
|
.execute('parity_removeReservedPeer', encode);
|
||||||
@ -315,4 +330,14 @@ export default class Parity {
|
|||||||
.execute('parity_unsignedTransactionsCount')
|
.execute('parity_unsignedTransactionsCount')
|
||||||
.then(outNumber);
|
.then(outNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upgradeReady () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_upgradeReady');
|
||||||
|
}
|
||||||
|
|
||||||
|
versionInfo () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_versionInfo');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ describe('api/rpc/parity', () => {
|
|||||||
|
|
||||||
describe('newPeers', () => {
|
describe('newPeers', () => {
|
||||||
it('returns the peer structure, formatted', () => {
|
it('returns the peer structure, formatted', () => {
|
||||||
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]);
|
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789, peers: [] } } }]);
|
||||||
|
|
||||||
return instance.netPeers().then((peers) => {
|
return instance.netPeers().then((peers) => {
|
||||||
expect(peers.active.eq(123)).to.be.true;
|
expect(peers.active.eq(123)).to.be.true;
|
||||||
|
@ -100,6 +100,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
consensusCapability: {
|
||||||
|
desc: 'Returns an object or string detailing the state of parity capability of maintaining consensus',
|
||||||
|
params: [],
|
||||||
|
returns: {
|
||||||
|
type: Object,
|
||||||
|
desc: 'Either "capable", {"capableUntil":N}, {"incapableSince":N} or "unknown" (N is a block number)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
dappsPort: {
|
dappsPort: {
|
||||||
desc: 'Returns the port the dapps are running on, error if not enabled',
|
desc: 'Returns the port the dapps are running on, error if not enabled',
|
||||||
params: [],
|
params: [],
|
||||||
@ -163,6 +172,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
executeUpgrade: {
|
||||||
|
desc: 'Performs an upgrade',
|
||||||
|
params: [],
|
||||||
|
returns: {
|
||||||
|
type: Boolean,
|
||||||
|
desc: 'returns true if the upgrade to the release specified in parity_upgradeReady was successfully executed, false if not'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
extraData: {
|
extraData: {
|
||||||
desc: 'Returns currently set extra data',
|
desc: 'Returns currently set extra data',
|
||||||
params: [],
|
params: [],
|
||||||
@ -468,6 +486,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
releasesInfo: {
|
||||||
|
desc: 'returns a ReleasesInfo object describing the current status of releases',
|
||||||
|
params: [],
|
||||||
|
returns: {
|
||||||
|
type: Object,
|
||||||
|
desc: '"fork":N,"minor":null,"this_fork":MN,"track":R} (N is a block number representing the latest known fork of this chain which may be in the future, MN is a block number representing the latest known fork that the currently running binary can sync past or null if not known, R is a ReleaseInfo object describing the latest release in this release track)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
removeReservedPeer: {
|
removeReservedPeer: {
|
||||||
desc: '?',
|
desc: '?',
|
||||||
params: [
|
params: [
|
||||||
@ -651,5 +678,23 @@ export default {
|
|||||||
type: Quantity,
|
type: Quantity,
|
||||||
desc: 'Number of unsigned transactions'
|
desc: 'Number of unsigned transactions'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
upgradeReady: {
|
||||||
|
desc: 'returns a ReleaseInfo object describing the release which is available for upgrade or null if none is available',
|
||||||
|
params: [],
|
||||||
|
returns: {
|
||||||
|
type: Object,
|
||||||
|
desc: '{"binary":H,"fork":15100,"is_critical":true,"version":V} where H is the Keccak-256 checksum of the release parity binary and V is a VersionInfo object describing the release'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
versionInfo: {
|
||||||
|
desc: 'returns a VersionInfo object describing our current version',
|
||||||
|
params: [],
|
||||||
|
returns: {
|
||||||
|
type: Object,
|
||||||
|
desc: '{"hash":H,"track":T,"version":{"major":N,"minor":N,"patch":N}} (H is a 160-bit Git commit hash, T is a ReleaseTrack, either "stable", "beta", "nightly" or "unknown" and N is a version number)'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
17
js/src/modals/UpgradeParity/index.js
Normal file
17
js/src/modals/UpgradeParity/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './upgradeParity';
|
146
js/src/modals/UpgradeParity/store.js
Normal file
146
js/src/modals/UpgradeParity/store.js
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { action, computed, observable, transaction } from 'mobx';
|
||||||
|
import store from 'store';
|
||||||
|
|
||||||
|
const LS_UPDATE = '_parity::update';
|
||||||
|
|
||||||
|
const A_MINUTE = 60 * 1000;
|
||||||
|
const A_DAY = 24 * 60 * A_MINUTE;
|
||||||
|
|
||||||
|
const STEP_INFO = 0;
|
||||||
|
const STEP_UPDATING = 1;
|
||||||
|
const STEP_COMPLETED = 2;
|
||||||
|
const STEP_ERROR = 2;
|
||||||
|
|
||||||
|
const CHECK_INTERVAL = 1 * A_MINUTE;
|
||||||
|
|
||||||
|
export default class Store {
|
||||||
|
@observable available = null;
|
||||||
|
@observable consensusCapability = null;
|
||||||
|
@observable closed = true;
|
||||||
|
@observable error = null;
|
||||||
|
@observable remindAt = 0;
|
||||||
|
@observable step = 0;
|
||||||
|
@observable upgrading = null;
|
||||||
|
@observable version = null;
|
||||||
|
|
||||||
|
constructor (api) {
|
||||||
|
this._api = api;
|
||||||
|
|
||||||
|
this.loadStorage();
|
||||||
|
this.checkUpgrade();
|
||||||
|
|
||||||
|
setInterval(this.checkUpgrade, CHECK_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@computed get isVisible () {
|
||||||
|
return !this.closed && Date.now() >= this.remindAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action closeModal = () => {
|
||||||
|
transaction(() => {
|
||||||
|
this.closed = true;
|
||||||
|
this.setStep(0, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@action loadStorage = () => {
|
||||||
|
const values = store.get(LS_UPDATE) || {};
|
||||||
|
|
||||||
|
this.remindAt = values.remindAt ? values.remindAt : 0;
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action openModal = () => {
|
||||||
|
this.closed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action setStep = (step, error = null) => {
|
||||||
|
transaction(() => {
|
||||||
|
this.error = error;
|
||||||
|
this.step = step;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@action setUpgrading () {
|
||||||
|
transaction(() => {
|
||||||
|
this.upgrading = this.available;
|
||||||
|
this.setStep(STEP_UPDATING, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@action setVersions (available, version, consensusCapability) {
|
||||||
|
transaction(() => {
|
||||||
|
this.available = available;
|
||||||
|
this.consensusCapability = consensusCapability;
|
||||||
|
this.version = version;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@action snoozeTillTomorrow = () => {
|
||||||
|
this.remindAt = Date.now() + A_DAY;
|
||||||
|
store.set(LS_UPDATE, Object.assign(this.loadStorage(), { remindAt: this.remindAt }));
|
||||||
|
}
|
||||||
|
|
||||||
|
@action upgradeNow = () => {
|
||||||
|
this.setUpgrading();
|
||||||
|
|
||||||
|
return this._api.parity
|
||||||
|
.executeUpgrade()
|
||||||
|
.then((result) => {
|
||||||
|
if (!result) {
|
||||||
|
throw new Error('Unable to complete update');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setStep(STEP_COMPLETED, null);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('upgradeNow', error);
|
||||||
|
|
||||||
|
this.setStep(STEP_ERROR, error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkUpgrade = () => {
|
||||||
|
if (!this._api) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise
|
||||||
|
.all([
|
||||||
|
this._api.parity.upgradeReady(),
|
||||||
|
this._api.parity.consensusCapability(),
|
||||||
|
this._api.parity.versionInfo()
|
||||||
|
])
|
||||||
|
.then(([available, consensusCapability, version]) => {
|
||||||
|
console.log('[checkUpgrade]', 'available:', available, 'version:', version, 'consensusCapability:', consensusCapability);
|
||||||
|
this.setVersions(available, version, consensusCapability);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn('checkUpgrade', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
STEP_COMPLETED,
|
||||||
|
STEP_ERROR,
|
||||||
|
STEP_INFO,
|
||||||
|
STEP_UPDATING
|
||||||
|
};
|
58
js/src/modals/UpgradeParity/store.spec.js
Normal file
58
js/src/modals/UpgradeParity/store.spec.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import Store from './store';
|
||||||
|
|
||||||
|
let store;
|
||||||
|
|
||||||
|
describe('modals/UpgradeParity/store', () => {
|
||||||
|
describe('@actions', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
store = new Store();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('openModal & closeModal', () => {
|
||||||
|
it('toggles between the closed states', () => {
|
||||||
|
expect(store.closed).to.be.true;
|
||||||
|
store.openModal();
|
||||||
|
expect(store.closed).to.be.false;
|
||||||
|
store.closeModal();
|
||||||
|
expect(store.closed).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resets the step state upon closing', () => {
|
||||||
|
store.setStep(5, 'soem error');
|
||||||
|
store.closeModal();
|
||||||
|
expect(store.step).to.equal(0);
|
||||||
|
expect(store.error).to.be.null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setStep', () => {
|
||||||
|
it('sets the step as provided', () => {
|
||||||
|
expect(store.step).to.equal(0);
|
||||||
|
store.setStep(3);
|
||||||
|
expect(store.step).to.equal(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets the error when provided', () => {
|
||||||
|
expect(store.error).to.be.null;
|
||||||
|
store.setStep(3, new Error('some error'));
|
||||||
|
expect(store.error).to.match(/some error/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
32
js/src/modals/UpgradeParity/upgradeParity.css
Normal file
32
js/src/modals/UpgradeParity/upgradeParity.css
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.error {
|
||||||
|
padding-top: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoStep {
|
||||||
|
div+div {
|
||||||
|
padding-top: 1.25em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.version {
|
||||||
|
display: inline;
|
||||||
|
opacity: 0.5;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
257
js/src/modals/UpgradeParity/upgradeParity.js
Normal file
257
js/src/modals/UpgradeParity/upgradeParity.js
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Button } from '~/ui';
|
||||||
|
import { CancelIcon, DoneIcon, NextIcon } from '~/ui/Icons';
|
||||||
|
import Modal, { Busy, Completed } from '~/ui/Modal';
|
||||||
|
|
||||||
|
import { STEP_COMPLETED, STEP_ERROR, STEP_INFO, STEP_UPDATING } from './store';
|
||||||
|
import styles from './upgradeParity.css';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class UpgradeParity extends Component {
|
||||||
|
static contextTypes = {
|
||||||
|
api: PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
store: PropTypes.object.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { store } = this.props;
|
||||||
|
|
||||||
|
if (!store.isVisible) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
actions={ this.renderActions() }
|
||||||
|
current={ store.step }
|
||||||
|
steps={ [
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.step.info'
|
||||||
|
key='info'
|
||||||
|
defaultMessage='upgrade available' />,
|
||||||
|
<FormattedMessage
|
||||||
|
key='updating'
|
||||||
|
id='upgradeParity.step.updating'
|
||||||
|
defaultMessage='upgrading parity' />,
|
||||||
|
store.step === STEP_ERROR
|
||||||
|
? <FormattedMessage
|
||||||
|
id='upgradeParity.step.error'
|
||||||
|
key='error'
|
||||||
|
defaultMessage='error' />
|
||||||
|
: <FormattedMessage
|
||||||
|
id='upgradeParity.step.completed'
|
||||||
|
key='completed'
|
||||||
|
defaultMessage='upgrade completed' />
|
||||||
|
] }
|
||||||
|
visible>
|
||||||
|
{ this.renderStep() }
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderActions () {
|
||||||
|
const { store } = this.props;
|
||||||
|
|
||||||
|
const closeButton =
|
||||||
|
<Button
|
||||||
|
icon={ <CancelIcon /> }
|
||||||
|
key='close'
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.button.close'
|
||||||
|
defaultMessage='close' />
|
||||||
|
}
|
||||||
|
onClick={ store.closeModal } />;
|
||||||
|
const doneButton =
|
||||||
|
<Button
|
||||||
|
icon={ <DoneIcon /> }
|
||||||
|
key='done'
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.button.done'
|
||||||
|
defaultMessage='done' />
|
||||||
|
}
|
||||||
|
onClick={ store.closeModal } />;
|
||||||
|
|
||||||
|
switch (store.step) {
|
||||||
|
case STEP_INFO:
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
icon={ <NextIcon /> }
|
||||||
|
key='upgrade'
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.button.upgrade'
|
||||||
|
defaultMessage='upgrade now' />
|
||||||
|
}
|
||||||
|
onClick={ store.upgradeNow } />,
|
||||||
|
closeButton
|
||||||
|
];
|
||||||
|
|
||||||
|
case STEP_UPDATING:
|
||||||
|
return [
|
||||||
|
closeButton
|
||||||
|
];
|
||||||
|
|
||||||
|
case STEP_COMPLETED:
|
||||||
|
case STEP_ERROR:
|
||||||
|
return [
|
||||||
|
doneButton
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStep () {
|
||||||
|
const { store } = this.props;
|
||||||
|
|
||||||
|
const currentversion = this.formatVersion(store);
|
||||||
|
const newversion = store.upgrading
|
||||||
|
? this.formatVersion(store.upgrading)
|
||||||
|
: this.formatVersion(store.available);
|
||||||
|
|
||||||
|
switch (store.step) {
|
||||||
|
case STEP_INFO:
|
||||||
|
return (
|
||||||
|
<div className={ styles.infoStep }>
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.info.upgrade'
|
||||||
|
defaultMessage='A new version of Parity, version {newversion} is available as an upgrade from your current version {currentversion}'
|
||||||
|
values={ {
|
||||||
|
currentversion: <div className={ styles.version }>{ currentversion }</div>,
|
||||||
|
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||||
|
} } />
|
||||||
|
</div>
|
||||||
|
{ this.renderConsensusInfo() }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
case STEP_UPDATING:
|
||||||
|
return (
|
||||||
|
<Busy
|
||||||
|
title={
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.busy'
|
||||||
|
defaultMessage='Your upgrade to Parity {newversion} is currently in progress'
|
||||||
|
values={ {
|
||||||
|
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||||
|
} } />
|
||||||
|
} />
|
||||||
|
);
|
||||||
|
|
||||||
|
case STEP_COMPLETED:
|
||||||
|
case STEP_ERROR:
|
||||||
|
if (store.error) {
|
||||||
|
return (
|
||||||
|
<Completed>
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.failed'
|
||||||
|
defaultMessage='Your upgrade to Parity {newversion} has failed with an error.'
|
||||||
|
values={ {
|
||||||
|
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||||
|
} } />
|
||||||
|
</div>
|
||||||
|
<div className={ styles.error }>
|
||||||
|
{ store.error.message }
|
||||||
|
</div>
|
||||||
|
</Completed>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Completed>
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.completed'
|
||||||
|
defaultMessage='Your upgrade to Parity {newversion} has been successfully completed.'
|
||||||
|
values={ {
|
||||||
|
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||||
|
} } />
|
||||||
|
</Completed>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderConsensusInfo () {
|
||||||
|
const { store } = this.props;
|
||||||
|
const { consensusCapability } = store;
|
||||||
|
|
||||||
|
if (consensusCapability) {
|
||||||
|
if (consensusCapability === 'capable') {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.consensus.capable'
|
||||||
|
defaultMessage='Your current Parity version is capable of handling the network requirements.' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (consensusCapability.capableUntil) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.consensus.capableUntil'
|
||||||
|
defaultMessage='Your current Parity version is capable of handling the network requirements until block {blockNumber}'
|
||||||
|
values={ {
|
||||||
|
blockNumber: consensusCapability.capableUntil
|
||||||
|
} } />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (consensusCapability.incapableSince) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.consensus.incapableSince'
|
||||||
|
defaultMessage='Your current Parity version is incapable of handling the network requirements since block {blockNumber}'
|
||||||
|
values={ {
|
||||||
|
blockNumber: consensusCapability.incapableSince
|
||||||
|
} } />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.consensus.unknown'
|
||||||
|
defaultMessage='Your current Parity version is capable of handling the network requirements.' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatVersion (struct) {
|
||||||
|
if (!struct || !struct.version) {
|
||||||
|
return (
|
||||||
|
<FormattedMessage
|
||||||
|
id='upgradeParity.version.unknown'
|
||||||
|
defaultMessage='unknown' />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { track, version } = struct.version;
|
||||||
|
|
||||||
|
return `${version.major}.${version.minor}.${version.patch}-${track}`;
|
||||||
|
}
|
||||||
|
}
|
@ -23,12 +23,13 @@ import DeployContract from './DeployContract';
|
|||||||
import EditMeta from './EditMeta';
|
import EditMeta from './EditMeta';
|
||||||
import ExecuteContract from './ExecuteContract';
|
import ExecuteContract from './ExecuteContract';
|
||||||
import FirstRun from './FirstRun';
|
import FirstRun from './FirstRun';
|
||||||
|
import LoadContract from './LoadContract';
|
||||||
|
import SaveContract from './SaveContract';
|
||||||
import Shapeshift from './Shapeshift';
|
import Shapeshift from './Shapeshift';
|
||||||
import Verification from './Verification';
|
import Verification from './Verification';
|
||||||
import Transfer from './Transfer';
|
import Transfer from './Transfer';
|
||||||
import PasswordManager from './PasswordManager';
|
import PasswordManager from './PasswordManager';
|
||||||
import SaveContract from './SaveContract';
|
import UpgradeParity from './UpgradeParity';
|
||||||
import LoadContract from './LoadContract';
|
|
||||||
import WalletSettings from './WalletSettings';
|
import WalletSettings from './WalletSettings';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@ -41,11 +42,12 @@ export {
|
|||||||
EditMeta,
|
EditMeta,
|
||||||
ExecuteContract,
|
ExecuteContract,
|
||||||
FirstRun,
|
FirstRun,
|
||||||
|
LoadContract,
|
||||||
|
SaveContract,
|
||||||
Shapeshift,
|
Shapeshift,
|
||||||
Verification,
|
Verification,
|
||||||
Transfer,
|
Transfer,
|
||||||
PasswordManager,
|
PasswordManager,
|
||||||
LoadContract,
|
UpgradeParity,
|
||||||
SaveContract,
|
|
||||||
WalletSettings
|
WalletSettings
|
||||||
};
|
};
|
||||||
|
31
js/src/ui/Icons/index.js
Normal file
31
js/src/ui/Icons/index.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||||
|
import CancelIcon from 'material-ui/svg-icons/content/clear';
|
||||||
|
import DoneIcon from 'material-ui/svg-icons/action/done-all';
|
||||||
|
import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back';
|
||||||
|
import NextIcon from 'material-ui/svg-icons/navigation/arrow-forward';
|
||||||
|
import SnoozeIcon from 'material-ui/svg-icons/av/snooze';
|
||||||
|
|
||||||
|
export {
|
||||||
|
AddIcon,
|
||||||
|
CancelIcon,
|
||||||
|
DoneIcon,
|
||||||
|
PrevIcon,
|
||||||
|
NextIcon,
|
||||||
|
SnoozeIcon
|
||||||
|
};
|
@ -16,17 +16,19 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||||
|
|
||||||
import styles from './busy.css';
|
import styles from './busy.css';
|
||||||
|
|
||||||
export default class Busy extends Component {
|
export default class Busy extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
title: PropTypes.string,
|
children: PropTypes.node,
|
||||||
state: PropTypes.string,
|
state: nodeOrStringProptype(),
|
||||||
children: PropTypes.node
|
title: nodeOrStringProptype()
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, title, state } = this.props;
|
const { children, state, title } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.center }>
|
<div className={ styles.center }>
|
||||||
|
@ -36,7 +36,13 @@ export default class Title extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.title }>
|
<div className={ styles.title }>
|
||||||
<h3>{ steps ? steps[current] : title }</h3>
|
<h3>
|
||||||
|
{
|
||||||
|
steps
|
||||||
|
? steps[current]
|
||||||
|
: title
|
||||||
|
}
|
||||||
|
</h3>
|
||||||
{ this.renderSteps() }
|
{ this.renderSteps() }
|
||||||
{ this.renderWaiting() }
|
{ this.renderWaiting() }
|
||||||
</div>
|
</div>
|
||||||
@ -63,10 +69,10 @@ export default class Title extends Component {
|
|||||||
renderTimeline () {
|
renderTimeline () {
|
||||||
const { steps } = this.props;
|
const { steps } = this.props;
|
||||||
|
|
||||||
return steps.map((label) => {
|
return steps.map((label, index) => {
|
||||||
return (
|
return (
|
||||||
<Step
|
<Step
|
||||||
key={ label }>
|
key={ label.key || index }>
|
||||||
<StepLabel>
|
<StepLabel>
|
||||||
{ label }
|
{ label }
|
||||||
</StepLabel>
|
</StepLabel>
|
||||||
|
@ -14,16 +14,17 @@
|
|||||||
/* 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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
background: rgba(0, 0, 0, 0.25) !important;
|
background: rgba(0, 0, 0, 0.25) !important;
|
||||||
}
|
|
||||||
|
|
||||||
.actions button:not([disabled]) {
|
button:not([disabled]) {
|
||||||
color: white !important;
|
color: white !important;
|
||||||
}
|
|
||||||
|
|
||||||
.actions button:not([disabled]) svg {
|
svg {
|
||||||
fill: white !important;
|
fill: white !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
@ -36,26 +37,26 @@
|
|||||||
.content {
|
.content {
|
||||||
transform: translate(0px, 0px) !important;
|
transform: translate(0px, 0px) !important;
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
|
||||||
|
|
||||||
.content>div {
|
&>div {
|
||||||
background: rgba(0, 0, 0, 0.5) !important;
|
background: rgba(0, 0, 0, 0.5) !important;
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
background: rgba(0, 0, 0, 0.25) !important;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
background: rgba(0, 0, 0, 0.25) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title .steps {
|
.steps {
|
||||||
margin-bottom: -1em;
|
margin-bottom: -1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.waiting {
|
.waiting {
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// 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 { Dialog } from 'material-ui';
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { Dialog } from 'material-ui';
|
|
||||||
|
|
||||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ class Modal extends Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { muiTheme } = this.context;
|
const { muiTheme } = this.context;
|
||||||
const { actions, busy, className, current, children, compact, steps, waiting, title, visible, settings } = this.props;
|
const { actions, busy, children, className, current, compact, settings, steps, title, visible, waiting } = this.props;
|
||||||
const contentStyle = muiTheme.parity.getBackgroundStyle(null, settings.backgroundSeed);
|
const contentStyle = muiTheme.parity.getBackgroundStyle(null, settings.backgroundSeed);
|
||||||
const header = (
|
const header = (
|
||||||
<Title
|
<Title
|
||||||
|
@ -33,6 +33,7 @@ import Errors from './Errors';
|
|||||||
import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select, RadioButtons } from './Form';
|
import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select, RadioButtons } from './Form';
|
||||||
import GasPriceEditor from './GasPriceEditor';
|
import GasPriceEditor from './GasPriceEditor';
|
||||||
import GasPriceSelector from './GasPriceSelector';
|
import GasPriceSelector from './GasPriceSelector';
|
||||||
|
import Icons from './Icons';
|
||||||
import IdentityIcon from './IdentityIcon';
|
import IdentityIcon from './IdentityIcon';
|
||||||
import IdentityName from './IdentityName';
|
import IdentityName from './IdentityName';
|
||||||
import LanguageSelector from './LanguageSelector';
|
import LanguageSelector from './LanguageSelector';
|
||||||
@ -72,6 +73,7 @@ export {
|
|||||||
FormWrap,
|
FormWrap,
|
||||||
GasPriceEditor,
|
GasPriceEditor,
|
||||||
GasPriceSelector,
|
GasPriceSelector,
|
||||||
|
Icons,
|
||||||
Input,
|
Input,
|
||||||
InputAddress,
|
InputAddress,
|
||||||
InputAddressSelect,
|
InputAddressSelect,
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
import { FirstRun } from '~/modals';
|
import { FirstRun, UpgradeParity } from '~/modals';
|
||||||
import { Errors, ParityBackground, Tooltips } from '~/ui';
|
import { Errors, ParityBackground, Tooltips } from '~/ui';
|
||||||
|
|
||||||
import styles from '../application.css';
|
import styles from '../application.css';
|
||||||
@ -28,20 +28,24 @@ export default class Container extends Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired,
|
||||||
|
onCloseFirstRun: PropTypes.func,
|
||||||
showFirstRun: PropTypes.bool,
|
showFirstRun: PropTypes.bool,
|
||||||
onCloseFirstRun: PropTypes.func
|
upgradeStore: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, showFirstRun, onCloseFirstRun } = this.props;
|
|
||||||
const { muiTheme } = this.context;
|
const { muiTheme } = this.context;
|
||||||
|
const { children, onCloseFirstRun, showFirstRun, upgradeStore } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ParityBackground className={ styles.container } muiTheme={ muiTheme }>
|
<ParityBackground
|
||||||
|
className={ styles.container }
|
||||||
|
muiTheme={ muiTheme }>
|
||||||
<FirstRun
|
<FirstRun
|
||||||
visible={ showFirstRun }
|
onClose={ onCloseFirstRun }
|
||||||
onClose={ onCloseFirstRun } />
|
visible={ showFirstRun } />
|
||||||
<Tooltips />
|
<Tooltips />
|
||||||
|
<UpgradeParity store={ upgradeStore } />
|
||||||
<Errors />
|
<Errors />
|
||||||
{ children }
|
{ children }
|
||||||
</ParityBackground>
|
</ParityBackground>
|
||||||
|
@ -14,55 +14,52 @@
|
|||||||
/* 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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
position: fixed;
|
align-items: center;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
color: #ccc;
|
||||||
|
display: flex;
|
||||||
|
font-size: 0.75em;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
padding: .4em .5em;
|
||||||
|
position: fixed;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: .4em .5em;
|
|
||||||
font-size: x-small;
|
|
||||||
color: #ccc;
|
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.enode {
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.enode > * {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 .25em;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.enode > :last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.netinfo {
|
.netinfo {
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
align-items: center;
|
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
}
|
flex-grow: 1;
|
||||||
|
text-align: right;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
.netinfo > * {
|
div {
|
||||||
margin-left: 1em;
|
display: inline-block;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.network {
|
.network {
|
||||||
padding: 0.25em 0.5em;
|
border-radius: 0.4em;
|
||||||
border-radius: .4em;
|
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
&.live {
|
||||||
|
background: rgb(0, 136, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.test {
|
||||||
|
background: rgb(136, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.networklive {
|
.upgrade {
|
||||||
background: rgb(0, 136, 0);
|
div {
|
||||||
}
|
display: inline-block;
|
||||||
|
margin-left: 1em;
|
||||||
.networktest {
|
}
|
||||||
background: rgb(136, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
@ -15,78 +15,118 @@
|
|||||||
// 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 { FormattedMessage } from 'react-intl';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import { BlockStatus } from '~/ui';
|
import { BlockStatus } from '~/ui';
|
||||||
import CopyToClipboard from '~/ui/CopyToClipboard';
|
|
||||||
|
|
||||||
import styles from './status.css';
|
import styles from './status.css';
|
||||||
|
|
||||||
class Status extends Component {
|
class Status extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
blockNumber: PropTypes.object.isRequired,
|
|
||||||
clientVersion: PropTypes.string,
|
clientVersion: PropTypes.string,
|
||||||
enode: PropTypes.string,
|
isTest: PropTypes.bool,
|
||||||
netPeers: PropTypes.object,
|
|
||||||
netChain: PropTypes.string,
|
netChain: PropTypes.string,
|
||||||
isTest: PropTypes.bool
|
netPeers: PropTypes.object,
|
||||||
|
upgradeStore: PropTypes.object.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { blockNumber, clientVersion, netChain, netPeers, isTest } = this.props;
|
const { clientVersion, isTest, netChain, netPeers } = this.props;
|
||||||
const netStyle = `${styles.network} ${styles[isTest ? 'networktest' : 'networklive']}`;
|
|
||||||
|
|
||||||
if (!blockNumber) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.status }>
|
<div className={ styles.status }>
|
||||||
<div className={ styles.version }>
|
<div className={ styles.version }>
|
||||||
{ clientVersion }
|
{ clientVersion }
|
||||||
</div>
|
</div>
|
||||||
|
<div className={ styles.upgrade }>
|
||||||
|
{ this.renderConsensus() }
|
||||||
|
{ this.renderUpgradeButton() }
|
||||||
|
</div>
|
||||||
<div className={ styles.netinfo }>
|
<div className={ styles.netinfo }>
|
||||||
<BlockStatus />
|
<BlockStatus />
|
||||||
<div className={ netStyle }>
|
<div className={ `${styles.network} ${styles[isTest ? 'test' : 'live']}` }>
|
||||||
{ isTest ? 'test' : netChain }
|
{ netChain }
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.peers }>
|
<div className={ styles.peers }>
|
||||||
{ 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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEnode () {
|
renderConsensus () {
|
||||||
const { enode } = this.props;
|
const { upgradeStore } = this.props;
|
||||||
|
|
||||||
if (!enode) {
|
if (upgradeStore.consensusCapability === 'capable') {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='application.status.consensus.capable'
|
||||||
|
defaultMessage='Capable' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (upgradeStore.consensusCapability.capableUntil) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='application.status.consensus.capableUntil'
|
||||||
|
defaultMessage='Capable until #{blockNumber}'
|
||||||
|
values={ {
|
||||||
|
blockNumber: upgradeStore.consensusCapability.capableUntil
|
||||||
|
} } />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (upgradeStore.consensusCapability.incapableSince) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='application.status.consensus.incapableSince'
|
||||||
|
defaultMessage='Incapable since #{blockNumber}'
|
||||||
|
values={ {
|
||||||
|
blockNumber: upgradeStore.consensusCapability.incapableSince
|
||||||
|
} } />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='application.status.consensus.unknown'
|
||||||
|
defaultMessage='Unknown capability' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderUpgradeButton () {
|
||||||
|
const { upgradeStore } = this.props;
|
||||||
|
|
||||||
|
if (!upgradeStore.available) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [protocol, rest] = enode.split('://');
|
|
||||||
const [id, host] = rest.split('@');
|
|
||||||
const abbreviated = `${protocol}://${id.slice(0, 3)}…${id.slice(-3)}@${host}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.enode }>
|
<div>
|
||||||
<CopyToClipboard data={ enode } size={ 12 } />
|
<a
|
||||||
<div>{ abbreviated }</div>
|
href='javascript:void(0)'
|
||||||
|
onClick={ upgradeStore.openModal }>
|
||||||
|
<FormattedMessage
|
||||||
|
id='application.status.upgrade'
|
||||||
|
defaultMessage='Upgrade' />
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
const { blockNumber, clientVersion, enode, netPeers, netChain, isTest } = state.nodeStatus;
|
const { clientVersion, netPeers, netChain, isTest } = state.nodeStatus;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
blockNumber,
|
|
||||||
clientVersion,
|
clientVersion,
|
||||||
enode,
|
|
||||||
netPeers,
|
netPeers,
|
||||||
netChain,
|
netChain,
|
||||||
isTest
|
isTest
|
||||||
|
@ -22,5 +22,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1.25em;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ import { connect } from 'react-redux';
|
|||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import UpgradeStore from '~/modals/UpgradeParity/store';
|
||||||
|
|
||||||
import Connection from '../Connection';
|
import Connection from '../Connection';
|
||||||
import ParityBar from '../ParityBar';
|
import ParityBar from '../ParityBar';
|
||||||
|
|
||||||
@ -42,14 +44,15 @@ class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
blockNumber: PropTypes.object,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
netChain: PropTypes.string,
|
|
||||||
isTest: PropTypes.bool,
|
isTest: PropTypes.bool,
|
||||||
pending: PropTypes.array,
|
netChain: PropTypes.string,
|
||||||
blockNumber: PropTypes.object
|
pending: PropTypes.array
|
||||||
}
|
}
|
||||||
|
|
||||||
store = new Store(this.context.api);
|
store = new Store(this.context.api);
|
||||||
|
upgradeStore = new UpgradeStore(this.context.api);
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const [root] = (window.location.hash || '').replace('#/', '').split('/');
|
const [root] = (window.location.hash || '').replace('#/', '').split('/');
|
||||||
@ -71,12 +74,13 @@ class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderApp () {
|
renderApp () {
|
||||||
const { children, pending, netChain, isTest, blockNumber } = this.props;
|
const { blockNumber, children, pending, netChain, isTest } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
showFirstRun={ this.store.firstrunVisible }
|
upgradeStore={ this.upgradeStore }
|
||||||
onCloseFirstRun={ this.store.closeFirstrun }>
|
onCloseFirstRun={ this.store.closeFirstrun }
|
||||||
|
showFirstRun={ this.store.firstrunVisible }>
|
||||||
<TabBar
|
<TabBar
|
||||||
netChain={ netChain }
|
netChain={ netChain }
|
||||||
isTest={ isTest }
|
isTest={ isTest }
|
||||||
@ -84,7 +88,11 @@ class Application extends Component {
|
|||||||
<div className={ styles.content }>
|
<div className={ styles.content }>
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
{ blockNumber ? (<Status />) : null }
|
{
|
||||||
|
blockNumber
|
||||||
|
? <Status upgradeStore={ this.upgradeStore } />
|
||||||
|
: null
|
||||||
|
}
|
||||||
<Snackbar />
|
<Snackbar />
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
@ -102,16 +110,16 @@ class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
const { netChain, isTest, blockNumber } = state.nodeStatus;
|
const { blockNumber, netChain, isTest } = state.nodeStatus;
|
||||||
const { hasAccounts } = state.personal;
|
const { hasAccounts } = state.personal;
|
||||||
const { pending } = state.signer;
|
const { pending } = state.signer;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
blockNumber,
|
||||||
hasAccounts,
|
hasAccounts,
|
||||||
netChain,
|
|
||||||
isTest,
|
isTest,
|
||||||
pending,
|
netChain,
|
||||||
blockNumber
|
pending
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
|
|
||||||
.row {
|
.row {
|
||||||
margin: 0 -1em;
|
margin: 0 -1em;
|
||||||
}
|
|
||||||
|
|
||||||
.row::after {
|
&::after {
|
||||||
display: table;
|
display: table;
|
||||||
clear: both;
|
clear: both;
|
||||||
content: '';
|
content: '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.blockInfo {
|
.blockInfo {
|
||||||
@ -44,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.col,
|
.col,
|
||||||
.col1, .col2, .col3, .col4, .col5, .col6, .col7, .col8, .col9, .col10, .col11, .col12 {
|
.col3, .col4_5, .col6, .col12 {
|
||||||
float: left;
|
float: left;
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -57,18 +57,11 @@
|
|||||||
width: calc(100% / 12 * 3);
|
width: calc(100% / 12 * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.col4 {
|
.col4_5 {
|
||||||
width: 33.33333%;
|
width: 37.5%;
|
||||||
width: -webkit-calc(100% / 12 * 4);
|
width: -webkit-calc(100% / 12 * 4.5);
|
||||||
width: -moz-calc(100% / 12 * 4);
|
width: -moz-calc(100% / 12 * 4.5);
|
||||||
width: calc(100% / 12 * 4);
|
width: calc(100% / 12 * 4.5);
|
||||||
}
|
|
||||||
|
|
||||||
.col5 {
|
|
||||||
width: 41.66665%;
|
|
||||||
width: -webkit-calc(100% / 12 * 5);
|
|
||||||
width: -moz-calc(100% / 12 * 5);
|
|
||||||
width: calc(100% / 12 * 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.col6 {
|
.col6 {
|
||||||
|
@ -68,13 +68,13 @@ export default class Status extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.col5 }>
|
<div className={ styles.col4_5 }>
|
||||||
<MiningSettings
|
<MiningSettings
|
||||||
{ ...this._test('mining') }
|
{ ...this._test('mining') }
|
||||||
nodeStatus={ nodeStatus }
|
nodeStatus={ nodeStatus }
|
||||||
actions={ this.props.actions } />
|
actions={ this.props.actions } />
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.col4 }>
|
<div className={ styles.col4_5 }>
|
||||||
{ this.renderSettings() }
|
{ this.renderSettings() }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -102,6 +102,7 @@ export default class Status extends Component {
|
|||||||
<div { ...this._test('settings') }>
|
<div { ...this._test('settings') }>
|
||||||
<ContainerTitle title='network settings' />
|
<ContainerTitle title='network settings' />
|
||||||
<Input
|
<Input
|
||||||
|
allowCopy
|
||||||
readOnly
|
readOnly
|
||||||
label='chain'
|
label='chain'
|
||||||
value={ nodeStatus.netChain }
|
value={ nodeStatus.netChain }
|
||||||
@ -109,6 +110,7 @@ export default class Status extends Component {
|
|||||||
<div className={ styles.row }>
|
<div className={ styles.row }>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
|
allowCopy
|
||||||
readOnly
|
readOnly
|
||||||
label='peers'
|
label='peers'
|
||||||
value={ peers }
|
value={ peers }
|
||||||
@ -116,6 +118,7 @@ export default class Status extends Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
|
allowCopy
|
||||||
readOnly
|
readOnly
|
||||||
label='network port'
|
label='network port'
|
||||||
value={ nodeStatus.netPort.toString() }
|
value={ nodeStatus.netPort.toString() }
|
||||||
@ -124,6 +127,7 @@ export default class Status extends Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
|
allowCopy
|
||||||
readOnly
|
readOnly
|
||||||
label='rpc enabled'
|
label='rpc enabled'
|
||||||
value={ rpcSettings.enabled ? 'yes' : 'no' }
|
value={ rpcSettings.enabled ? 'yes' : 'no' }
|
||||||
@ -131,6 +135,7 @@ export default class Status extends Component {
|
|||||||
<div className={ styles.row }>
|
<div className={ styles.row }>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
|
allowCopy
|
||||||
readOnly
|
readOnly
|
||||||
label='rpc interface'
|
label='rpc interface'
|
||||||
value={ rpcSettings.interface }
|
value={ rpcSettings.interface }
|
||||||
@ -138,12 +143,24 @@ export default class Status extends Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
|
allowCopy
|
||||||
readOnly
|
readOnly
|
||||||
label='rpc port'
|
label='rpc port'
|
||||||
value={ rpcSettings.port.toString() }
|
value={ rpcSettings.port.toString() }
|
||||||
{ ...this._test('rpc-port') } />
|
{ ...this._test('rpc-port') } />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={ styles.row }>
|
||||||
|
<div className={ styles.col12 }>
|
||||||
|
<Input
|
||||||
|
allowCopy
|
||||||
|
readOnly
|
||||||
|
label='enode'
|
||||||
|
value={ nodeStatus.enode }
|
||||||
|
{ ...this._test('node-enode') } />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,12 @@ extern crate time;
|
|||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
use std::{env, thread, fs};
|
use std::{env, thread, fs};
|
||||||
use std::sync::Arc;
|
use std::sync::{Weak, Arc};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use isatty::{stderr_isatty, stdout_isatty};
|
use isatty::{stderr_isatty, stdout_isatty};
|
||||||
use env_logger::LogBuilder;
|
use env_logger::LogBuilder;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use util::RotatingLogger;
|
use util::{Mutex, RotatingLogger} ;
|
||||||
use util::log::Colour;
|
use util::log::Colour;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
@ -52,6 +52,10 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref ROTATING_LOGGER : Mutex<Weak<RotatingLogger>> = Mutex::new(Default::default());
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets up the logger
|
/// Sets up the logger
|
||||||
pub fn setup_log(config: &Config) -> Result<Arc<RotatingLogger>, String> {
|
pub fn setup_log(config: &Config) -> Result<Arc<RotatingLogger>, String> {
|
||||||
use rlog::*;
|
use rlog::*;
|
||||||
@ -121,9 +125,17 @@ pub fn setup_log(config: &Config) -> Result<Arc<RotatingLogger>, String> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
builder.format(format);
|
builder.format(format);
|
||||||
builder.init().expect("Logger initialized only once.");
|
builder.init()
|
||||||
|
.and_then(|_| {
|
||||||
Ok(logs)
|
*ROTATING_LOGGER.lock() = Arc::downgrade(&logs);
|
||||||
|
Ok(logs)
|
||||||
|
})
|
||||||
|
// couldn't create new logger - try to fall back on previous logger.
|
||||||
|
.or_else(|err| match ROTATING_LOGGER.lock().upgrade() {
|
||||||
|
Some(l) => Ok(l),
|
||||||
|
// no previous logger. fatal.
|
||||||
|
None => Err(format!("{:?}", err)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kill_color(s: &str) -> String {
|
fn kill_color(s: &str) -> String {
|
||||||
|
@ -32,7 +32,6 @@ use ethcore::verification::queue::VerifierSettings;
|
|||||||
use cache::CacheConfig;
|
use cache::CacheConfig;
|
||||||
use informant::{Informant, MillisecondDuration};
|
use informant::{Informant, MillisecondDuration};
|
||||||
use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_bool};
|
use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_bool};
|
||||||
use io_handler::ImportIoHandler;
|
|
||||||
use helpers::{to_client_config, execute_upgrades};
|
use helpers::{to_client_config, execute_upgrades};
|
||||||
use dir::Directories;
|
use dir::Directories;
|
||||||
use user_defaults::UserDefaults;
|
use user_defaults::UserDefaults;
|
||||||
@ -134,7 +133,7 @@ pub struct ExportState {
|
|||||||
pub max_balance: Option<U256>,
|
pub max_balance: Option<U256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
|
pub fn execute(cmd: BlockchainCmd) -> Result<(), String> {
|
||||||
match cmd {
|
match cmd {
|
||||||
BlockchainCmd::Kill(kill_cmd) => kill_db(kill_cmd),
|
BlockchainCmd::Kill(kill_cmd) => kill_db(kill_cmd),
|
||||||
BlockchainCmd::Import(import_cmd) => execute_import(import_cmd),
|
BlockchainCmd::Import(import_cmd) => execute_import(import_cmd),
|
||||||
@ -143,7 +142,7 @@ pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
fn execute_import(cmd: ImportBlockchain) -> Result<(), String> {
|
||||||
let timer = Instant::now();
|
let timer = Instant::now();
|
||||||
|
|
||||||
// Setup panic handler
|
// Setup panic handler
|
||||||
@ -180,7 +179,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
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.db_root_path().as_path())));
|
try!(execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||||
|
|
||||||
// create dirs used by parity
|
// create dirs used by parity
|
||||||
try!(cmd.dirs.create_dirs(false, false));
|
try!(cmd.dirs.create_dirs(false, false));
|
||||||
@ -239,11 +238,8 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let informant = Informant::new(client.clone(), None, None, None, cmd.with_color);
|
let informant = Arc::new(Informant::new(client.clone(), None, None, None, cmd.with_color));
|
||||||
|
service.register_io_handler(informant).map_err(|_| "Unable to register informant handler".to_owned())?;
|
||||||
try!(service.register_io_handler(Arc::new(ImportIoHandler {
|
|
||||||
info: Arc::new(informant),
|
|
||||||
})).map_err(|_| "Unable to register informant handler".to_owned()));
|
|
||||||
|
|
||||||
let do_import = |bytes| {
|
let do_import = |bytes| {
|
||||||
while client.queue_info().is_full() { sleep(Duration::from_secs(1)); }
|
while client.queue_info().is_full() { sleep(Duration::from_secs(1)); }
|
||||||
@ -259,7 +255,6 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
match format {
|
match format {
|
||||||
DataFormat::Binary => {
|
DataFormat::Binary => {
|
||||||
loop {
|
loop {
|
||||||
@ -298,7 +293,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
let report = client.report();
|
let report = client.report();
|
||||||
|
|
||||||
let ms = timer.elapsed().as_milliseconds();
|
let ms = timer.elapsed().as_milliseconds();
|
||||||
Ok(format!("Import completed in {} seconds, {} blocks, {} blk/s, {} transactions, {} tx/s, {} Mgas, {} Mgas/s",
|
info!("Import completed in {} seconds, {} blocks, {} blk/s, {} transactions, {} tx/s, {} Mgas, {} Mgas/s",
|
||||||
ms / 1000,
|
ms / 1000,
|
||||||
report.blocks_imported,
|
report.blocks_imported,
|
||||||
(report.blocks_imported * 1000) as u64 / ms,
|
(report.blocks_imported * 1000) as u64 / ms,
|
||||||
@ -306,7 +301,8 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
|||||||
(report.transactions_applied * 1000) as u64 / ms,
|
(report.transactions_applied * 1000) as u64 / ms,
|
||||||
report.gas_processed / From::from(1_000_000),
|
report.gas_processed / From::from(1_000_000),
|
||||||
(report.gas_processed / From::from(ms * 1000)).low_u64(),
|
(report.gas_processed / From::from(ms * 1000)).low_u64(),
|
||||||
).into())
|
);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_client(
|
fn start_client(
|
||||||
@ -318,7 +314,8 @@ fn start_client(
|
|||||||
fat_db: Switch,
|
fat_db: Switch,
|
||||||
compaction: DatabaseCompactionProfile,
|
compaction: DatabaseCompactionProfile,
|
||||||
wal: bool,
|
wal: bool,
|
||||||
cache_config: CacheConfig) -> Result<ClientService, String> {
|
cache_config: CacheConfig
|
||||||
|
) -> Result<ClientService, String> {
|
||||||
|
|
||||||
// load spec file
|
// load spec file
|
||||||
let spec = try!(spec.spec());
|
let spec = try!(spec.spec());
|
||||||
@ -351,7 +348,7 @@ fn start_client(
|
|||||||
let snapshot_path = db_dirs.snapshot_path();
|
let snapshot_path = db_dirs.snapshot_path();
|
||||||
|
|
||||||
// execute upgrades
|
// execute upgrades
|
||||||
try!(execute_upgrades(&db_dirs, algorithm, compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
try!(execute_upgrades(&dirs.base, &db_dirs, algorithm, compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||||
|
|
||||||
// create dirs used by parity
|
// create dirs used by parity
|
||||||
try!(dirs.create_dirs(false, false));
|
try!(dirs.create_dirs(false, false));
|
||||||
@ -372,7 +369,7 @@ fn start_client(
|
|||||||
Ok(service)
|
Ok(service)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
fn execute_export(cmd: ExportBlockchain) -> Result<(), String> {
|
||||||
// Setup panic handler
|
// 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 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 panic_handler = PanicHandler::new_in_arc();
|
||||||
@ -400,10 +397,11 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok("Export completed.".into())
|
info!("Export completed.");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_export_state(cmd: ExportState) -> Result<String, String> {
|
fn execute_export_state(cmd: ExportState) -> Result<(), String> {
|
||||||
// Setup panic handler
|
// 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 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 panic_handler = PanicHandler::new_in_arc();
|
||||||
@ -479,10 +477,11 @@ fn execute_export_state(cmd: ExportState) -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.write_fmt(format_args!("\n]}}")).expect("Write error");
|
out.write_fmt(format_args!("\n]}}")).expect("Write error");
|
||||||
Ok("Export completed.".into())
|
info!("Export completed.");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kill_db(cmd: KillBlockchain) -> Result<String, String> {
|
pub fn kill_db(cmd: KillBlockchain) -> Result<(), String> {
|
||||||
let spec = try!(cmd.spec.spec());
|
let spec = try!(cmd.spec.spec());
|
||||||
let genesis_hash = spec.genesis_header().hash();
|
let genesis_hash = spec.genesis_header().hash();
|
||||||
let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir);
|
let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir);
|
||||||
@ -491,7 +490,8 @@ pub fn kill_db(cmd: KillBlockchain) -> Result<String, String> {
|
|||||||
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
|
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
|
||||||
let dir = db_dirs.db_path(algorithm);
|
let dir = db_dirs.db_path(algorithm);
|
||||||
try!(fs::remove_dir_all(&dir).map_err(|e| format!("Error removing database: {:?}", e)));
|
try!(fs::remove_dir_all(&dir).map_err(|e| format!("Error removing database: {:?}", e)));
|
||||||
Ok("Database deleted.".to_owned())
|
info!("Database deleted.");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -2,8 +2,14 @@
|
|||||||
mode = "last"
|
mode = "last"
|
||||||
mode_timeout = 300
|
mode_timeout = 300
|
||||||
mode_alarm = 3600
|
mode_alarm = 3600
|
||||||
|
auto_update = "critical"
|
||||||
|
release_track = "current"
|
||||||
|
no_download = false
|
||||||
|
no_consensus = false
|
||||||
|
|
||||||
chain = "homestead"
|
chain = "homestead"
|
||||||
db_path = "$HOME/.parity"
|
base_path = "$HOME/.parity"
|
||||||
|
db_path = "$HOME/.parity/chains"
|
||||||
keys_path = "$HOME/.parity/keys"
|
keys_path = "$HOME/.parity/keys"
|
||||||
identity = ""
|
identity = ""
|
||||||
|
|
||||||
|
@ -85,9 +85,14 @@ usage! {
|
|||||||
flag_mode: String = "last", or |c: &Config| otry!(c.parity).mode.clone(),
|
flag_mode: String = "last", or |c: &Config| otry!(c.parity).mode.clone(),
|
||||||
flag_mode_timeout: u64 = 300u64, or |c: &Config| otry!(c.parity).mode_timeout.clone(),
|
flag_mode_timeout: u64 = 300u64, or |c: &Config| otry!(c.parity).mode_timeout.clone(),
|
||||||
flag_mode_alarm: u64 = 3600u64, or |c: &Config| otry!(c.parity).mode_alarm.clone(),
|
flag_mode_alarm: u64 = 3600u64, or |c: &Config| otry!(c.parity).mode_alarm.clone(),
|
||||||
|
flag_auto_update: String = "critical", or |c: &Config| otry!(c.parity).auto_update.clone(),
|
||||||
|
flag_release_track: String = "current", or |c: &Config| otry!(c.parity).release_track.clone(),
|
||||||
|
flag_no_download: bool = false, or |c: &Config| otry!(c.parity).no_download.clone(),
|
||||||
|
flag_no_consensus: bool = false, or |c: &Config| otry!(c.parity).no_consensus.clone(),
|
||||||
flag_chain: String = "homestead", or |c: &Config| otry!(c.parity).chain.clone(),
|
flag_chain: String = "homestead", or |c: &Config| otry!(c.parity).chain.clone(),
|
||||||
flag_db_path: String = default_data_path(), or |c: &Config| otry!(c.parity).db_path.clone(),
|
flag_base_path: String = default_data_path(), or |c: &Config| otry!(c.parity).base_path.clone(),
|
||||||
flag_keys_path: String = "$DATA/keys", or |c: &Config| otry!(c.parity).keys_path.clone(),
|
flag_db_path: String = "$BASE/chains", or |c: &Config| otry!(c.parity).db_path.clone(),
|
||||||
|
flag_keys_path: String = "$BASE/keys", or |c: &Config| otry!(c.parity).keys_path.clone(),
|
||||||
flag_identity: String = "", or |c: &Config| otry!(c.parity).identity.clone(),
|
flag_identity: String = "", or |c: &Config| otry!(c.parity).identity.clone(),
|
||||||
|
|
||||||
// -- Account Options
|
// -- Account Options
|
||||||
@ -106,7 +111,7 @@ usage! {
|
|||||||
or |c: &Config| otry!(c.ui).port.clone(),
|
or |c: &Config| otry!(c.ui).port.clone(),
|
||||||
flag_ui_interface: String = "local",
|
flag_ui_interface: String = "local",
|
||||||
or |c: &Config| otry!(c.ui).interface.clone(),
|
or |c: &Config| otry!(c.ui).interface.clone(),
|
||||||
flag_ui_path: String = "$DATA/signer",
|
flag_ui_path: String = "$BASE/signer",
|
||||||
or |c: &Config| otry!(c.ui).path.clone(),
|
or |c: &Config| otry!(c.ui).path.clone(),
|
||||||
// NOTE [todr] For security reasons don't put this to config files
|
// NOTE [todr] For security reasons don't put this to config files
|
||||||
flag_ui_no_validation: bool = false, or |_| None,
|
flag_ui_no_validation: bool = false, or |_| None,
|
||||||
@ -162,7 +167,7 @@ usage! {
|
|||||||
// IPC
|
// IPC
|
||||||
flag_no_ipc: bool = false,
|
flag_no_ipc: bool = false,
|
||||||
or |c: &Config| otry!(c.ipc).disable.clone(),
|
or |c: &Config| otry!(c.ipc).disable.clone(),
|
||||||
flag_ipc_path: String = "$DATA/jsonrpc.ipc",
|
flag_ipc_path: String = "$BASE/jsonrpc.ipc",
|
||||||
or |c: &Config| otry!(c.ipc).path.clone(),
|
or |c: &Config| otry!(c.ipc).path.clone(),
|
||||||
flag_ipc_apis: String = "web3,eth,net,parity,parity_accounts,traces,rpc",
|
flag_ipc_apis: String = "web3,eth,net,parity,parity_accounts,traces,rpc",
|
||||||
or |c: &Config| otry!(c.ipc).apis.clone().map(|vec| vec.join(",")),
|
or |c: &Config| otry!(c.ipc).apis.clone().map(|vec| vec.join(",")),
|
||||||
@ -176,7 +181,7 @@ usage! {
|
|||||||
or |c: &Config| otry!(c.dapps).interface.clone(),
|
or |c: &Config| otry!(c.dapps).interface.clone(),
|
||||||
flag_dapps_hosts: String = "none",
|
flag_dapps_hosts: String = "none",
|
||||||
or |c: &Config| otry!(c.dapps).hosts.clone().map(|vec| vec.join(",")),
|
or |c: &Config| otry!(c.dapps).hosts.clone().map(|vec| vec.join(",")),
|
||||||
flag_dapps_path: String = "$DATA/dapps",
|
flag_dapps_path: String = "$BASE/dapps",
|
||||||
or |c: &Config| otry!(c.dapps).path.clone(),
|
or |c: &Config| otry!(c.dapps).path.clone(),
|
||||||
flag_dapps_user: Option<String> = None,
|
flag_dapps_user: Option<String> = None,
|
||||||
or |c: &Config| otry!(c.dapps).user.clone().map(Some),
|
or |c: &Config| otry!(c.dapps).user.clone().map(Some),
|
||||||
@ -277,7 +282,7 @@ usage! {
|
|||||||
or |c: &Config| otry!(c.vm).jit.clone(),
|
or |c: &Config| otry!(c.vm).jit.clone(),
|
||||||
|
|
||||||
// -- Miscellaneous Options
|
// -- Miscellaneous Options
|
||||||
flag_config: String = "$DATA/config.toml", or |_| None,
|
flag_config: String = "$BASE/config.toml", or |_| None,
|
||||||
flag_logging: Option<String> = None,
|
flag_logging: Option<String> = None,
|
||||||
or |c: &Config| otry!(c.misc).logging.clone().map(Some),
|
or |c: &Config| otry!(c.misc).logging.clone().map(Some),
|
||||||
flag_log_file: Option<String> = None,
|
flag_log_file: Option<String> = None,
|
||||||
@ -309,7 +314,12 @@ struct Operating {
|
|||||||
mode: Option<String>,
|
mode: Option<String>,
|
||||||
mode_timeout: Option<u64>,
|
mode_timeout: Option<u64>,
|
||||||
mode_alarm: Option<u64>,
|
mode_alarm: Option<u64>,
|
||||||
|
auto_update: Option<String>,
|
||||||
|
release_track: Option<String>,
|
||||||
|
no_download: Option<bool>,
|
||||||
|
no_consensus: Option<bool>,
|
||||||
chain: Option<String>,
|
chain: Option<String>,
|
||||||
|
base_path: Option<String>,
|
||||||
db_path: Option<String>,
|
db_path: Option<String>,
|
||||||
keys_path: Option<String>,
|
keys_path: Option<String>,
|
||||||
identity: Option<String>,
|
identity: Option<String>,
|
||||||
@ -533,8 +543,13 @@ mod tests {
|
|||||||
flag_mode: "last".into(),
|
flag_mode: "last".into(),
|
||||||
flag_mode_timeout: 300u64,
|
flag_mode_timeout: 300u64,
|
||||||
flag_mode_alarm: 3600u64,
|
flag_mode_alarm: 3600u64,
|
||||||
|
flag_auto_update: "critical".into(),
|
||||||
|
flag_release_track: "current".into(),
|
||||||
|
flag_no_download: false,
|
||||||
|
flag_no_consensus: false,
|
||||||
flag_chain: "xyz".into(),
|
flag_chain: "xyz".into(),
|
||||||
flag_db_path: "$HOME/.parity".into(),
|
flag_base_path: "$HOME/.parity".into(),
|
||||||
|
flag_db_path: "$HOME/.parity/chains".into(),
|
||||||
flag_keys_path: "$HOME/.parity/keys".into(),
|
flag_keys_path: "$HOME/.parity/keys".into(),
|
||||||
flag_identity: "".into(),
|
flag_identity: "".into(),
|
||||||
|
|
||||||
@ -676,7 +691,7 @@ mod tests {
|
|||||||
|
|
||||||
// -- Miscellaneous Options
|
// -- Miscellaneous Options
|
||||||
flag_version: false,
|
flag_version: false,
|
||||||
flag_config: "$DATA/config.toml".into(),
|
flag_config: "$BASE/config.toml".into(),
|
||||||
flag_logging: Some("own_tx=trace".into()),
|
flag_logging: Some("own_tx=trace".into()),
|
||||||
flag_log_file: Some("/var/log/parity.log".into()),
|
flag_log_file: Some("/var/log/parity.log".into()),
|
||||||
flag_no_color: false,
|
flag_no_color: false,
|
||||||
@ -707,7 +722,12 @@ mod tests {
|
|||||||
mode: Some("dark".into()),
|
mode: Some("dark".into()),
|
||||||
mode_timeout: Some(15u64),
|
mode_timeout: Some(15u64),
|
||||||
mode_alarm: Some(10u64),
|
mode_alarm: Some(10u64),
|
||||||
|
auto_update: None,
|
||||||
|
release_track: None,
|
||||||
|
no_download: None,
|
||||||
|
no_consensus: None,
|
||||||
chain: Some("./chain.json".into()),
|
chain: Some("./chain.json".into()),
|
||||||
|
base_path: None,
|
||||||
db_path: None,
|
db_path: None,
|
||||||
keys_path: None,
|
keys_path: None,
|
||||||
identity: None,
|
identity: None,
|
||||||
|
@ -34,11 +34,34 @@ Operating Options:
|
|||||||
--mode-alarm SECS Specify the number of seconds before auto sleep
|
--mode-alarm SECS Specify the number of seconds before auto sleep
|
||||||
reawake timeout occurs when mode is passive
|
reawake timeout occurs when mode is passive
|
||||||
(default: {flag_mode_alarm}).
|
(default: {flag_mode_alarm}).
|
||||||
|
--auto-update SET Set a releases set to automatically update and
|
||||||
|
install.
|
||||||
|
all - All updates in the our release track.
|
||||||
|
critical - Only consensus/security updates.
|
||||||
|
none - No updates will be auto-installed.
|
||||||
|
(default: {flag_auto_update}).
|
||||||
|
--release-track TRACK Set which release track we should use for updates.
|
||||||
|
stable - Stable releases.
|
||||||
|
beta - Beta releases.
|
||||||
|
nightly - Nightly releases (unstable).
|
||||||
|
testing - Testing releases (do not use).
|
||||||
|
current - Whatever track this executable was
|
||||||
|
released on (default: {flag_release_track}).
|
||||||
|
--no-download Normally new releases will be downloaded ready for
|
||||||
|
updating. This disables it. Not recommended.
|
||||||
|
(default: {flag_no_download}).
|
||||||
|
--no-consensus Force the binary to run even if there are known
|
||||||
|
issues regarding consensus. Not recommended.
|
||||||
|
(default: {flag_no_consensus}).
|
||||||
|
--force-direct Run the originally installed version of Parity,
|
||||||
|
ignoring any updates that have since been installed.
|
||||||
--chain CHAIN Specify the blockchain type. CHAIN may be either a
|
--chain CHAIN Specify the blockchain type. CHAIN may be either a
|
||||||
JSON chain specification file or olympic, frontier,
|
JSON chain specification file or olympic, frontier,
|
||||||
homestead, mainnet, morden, ropsten, classic, expanse,
|
homestead, mainnet, morden, ropsten, classic, expanse,
|
||||||
testnet or dev (default: {flag_chain}).
|
testnet or dev (default: {flag_chain}).
|
||||||
-d --db-path PATH Specify the database & configuration directory path
|
-d --base-path PATH Specify the base data storage path.
|
||||||
|
(default: {flag_base_path}).
|
||||||
|
--db-path PATH Specify the database directory path
|
||||||
(default: {flag_db_path}).
|
(default: {flag_db_path}).
|
||||||
--keys-path PATH Specify the path for JSON key files to be found
|
--keys-path PATH Specify the path for JSON key files to be found
|
||||||
(default: {flag_keys_path}).
|
(default: {flag_keys_path}).
|
||||||
@ -339,6 +362,9 @@ Legacy Options:
|
|||||||
--extradata STRING Equivalent to --extra-data STRING.
|
--extradata STRING Equivalent to --extra-data STRING.
|
||||||
--cache MB Equivalent to --cache-size MB.
|
--cache MB Equivalent to --cache-size MB.
|
||||||
|
|
||||||
|
Internal Options:
|
||||||
|
--can-restart Executable will auto-restart if exiting with 69.
|
||||||
|
|
||||||
Miscellaneous Options:
|
Miscellaneous Options:
|
||||||
-c --config CONFIG Specify a filename containing a configuration file.
|
-c --config CONFIG Specify a filename containing a configuration file.
|
||||||
(default: {flag_config})
|
(default: {flag_config})
|
||||||
|
@ -23,7 +23,7 @@ use cli::{Args, ArgsError};
|
|||||||
use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address};
|
use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address};
|
||||||
use util::log::Colour;
|
use util::log::Colour;
|
||||||
use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP};
|
use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP};
|
||||||
use ethcore::client::VMType;
|
use ethcore::client::{VMType};
|
||||||
use ethcore::miner::{MinerOptions, Banning};
|
use ethcore::miner::{MinerOptions, Banning};
|
||||||
use ethcore::verification::queue::VerifierSettings;
|
use ethcore::verification::queue::VerifierSettings;
|
||||||
|
|
||||||
@ -34,9 +34,10 @@ use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_pri
|
|||||||
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy};
|
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy};
|
||||||
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras};
|
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras};
|
||||||
use ethcore_logger::Config as LogConfig;
|
use ethcore_logger::Config as LogConfig;
|
||||||
use dir::Directories;
|
use dir::{Directories, default_hypervisor_path};
|
||||||
use dapps::Configuration as DappsConfiguration;
|
use dapps::Configuration as DappsConfiguration;
|
||||||
use signer::{Configuration as SignerConfiguration};
|
use signer::{Configuration as SignerConfiguration};
|
||||||
|
use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};
|
||||||
use run::RunCmd;
|
use run::RunCmd;
|
||||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
|
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
|
||||||
use presale::ImportWallet;
|
use presale::ImportWallet;
|
||||||
@ -99,6 +100,7 @@ impl Configuration {
|
|||||||
let pruning_history = self.args.flag_pruning_history;
|
let pruning_history = self.args.flag_pruning_history;
|
||||||
let vm_type = try!(self.vm_type());
|
let vm_type = try!(self.vm_type());
|
||||||
let mode = match self.args.flag_mode.as_ref() { "last" => None, mode => Some(try!(to_mode(&mode, self.args.flag_mode_timeout, self.args.flag_mode_alarm))), };
|
let mode = match self.args.flag_mode.as_ref() { "last" => None, mode => Some(try!(to_mode(&mode, self.args.flag_mode_timeout, self.args.flag_mode_alarm))), };
|
||||||
|
let update_policy = try!(self.update_policy());
|
||||||
let miner_options = try!(self.miner_options());
|
let miner_options = try!(self.miner_options());
|
||||||
let logger_config = self.logger_config();
|
let logger_config = self.logger_config();
|
||||||
let http_conf = try!(self.http_config());
|
let http_conf = try!(self.http_config());
|
||||||
@ -320,6 +322,7 @@ impl Configuration {
|
|||||||
acc_conf: try!(self.accounts_config()),
|
acc_conf: try!(self.accounts_config()),
|
||||||
gas_pricer: try!(self.gas_pricer_config()),
|
gas_pricer: try!(self.gas_pricer_config()),
|
||||||
miner_extras: try!(self.miner_extras()),
|
miner_extras: try!(self.miner_extras()),
|
||||||
|
update_policy: update_policy,
|
||||||
mode: mode,
|
mode: mode,
|
||||||
tracing: tracing,
|
tracing: tracing,
|
||||||
fat_db: fat_db,
|
fat_db: fat_db,
|
||||||
@ -589,7 +592,7 @@ impl Configuration {
|
|||||||
ret.snapshot_peers = self.snapshot_peers();
|
ret.snapshot_peers = self.snapshot_peers();
|
||||||
ret.allow_ips = try!(self.allow_ips());
|
ret.allow_ips = try!(self.allow_ips());
|
||||||
ret.max_pending_peers = self.max_pending_peers();
|
ret.max_pending_peers = self.max_pending_peers();
|
||||||
let mut net_path = PathBuf::from(self.directories().data);
|
let mut net_path = PathBuf::from(self.directories().base);
|
||||||
net_path.push("network");
|
net_path.push("network");
|
||||||
ret.config_path = Some(net_path.to_str().unwrap().to_owned());
|
ret.config_path = Some(net_path.to_str().unwrap().to_owned());
|
||||||
ret.reserved_nodes = try!(self.init_reserved_nodes());
|
ret.reserved_nodes = try!(self.init_reserved_nodes());
|
||||||
@ -680,11 +683,34 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_policy(&self) -> Result<UpdatePolicy, String> {
|
||||||
|
Ok(UpdatePolicy {
|
||||||
|
enable_downloading: !self.args.flag_no_download,
|
||||||
|
require_consensus: !self.args.flag_no_consensus,
|
||||||
|
filter: match self.args.flag_auto_update.as_ref() {
|
||||||
|
"none" => UpdateFilter::None,
|
||||||
|
"critical" => UpdateFilter::Critical,
|
||||||
|
"all" => UpdateFilter::All,
|
||||||
|
_ => return Err("Invalid value for `--auto-update`. See `--help` for more information.".into()),
|
||||||
|
},
|
||||||
|
track: match self.args.flag_release_track.as_ref() {
|
||||||
|
"stable" => ReleaseTrack::Stable,
|
||||||
|
"beta" => ReleaseTrack::Beta,
|
||||||
|
"nightly" => ReleaseTrack::Nightly,
|
||||||
|
"testing" => ReleaseTrack::Testing,
|
||||||
|
"current" => ReleaseTrack::Unknown,
|
||||||
|
_ => return Err("Invalid value for `--releases-track`. See `--help` for more information.".into()),
|
||||||
|
},
|
||||||
|
path: default_hypervisor_path(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn directories(&self) -> Directories {
|
fn directories(&self) -> Directories {
|
||||||
use util::path;
|
use util::path;
|
||||||
|
|
||||||
let data_path = replace_home("", self.args.flag_datadir.as_ref().unwrap_or(&self.args.flag_db_path));
|
let data_path = replace_home("", self.args.flag_datadir.as_ref().unwrap_or(&self.args.flag_base_path));
|
||||||
|
|
||||||
|
let db_path = replace_home(&data_path, &self.args.flag_db_path);
|
||||||
let keys_path = replace_home(&data_path, &self.args.flag_keys_path);
|
let keys_path = replace_home(&data_path, &self.args.flag_keys_path);
|
||||||
let dapps_path = replace_home(&data_path, &self.args.flag_dapps_path);
|
let dapps_path = replace_home(&data_path, &self.args.flag_dapps_path);
|
||||||
let ui_path = replace_home(&data_path, &self.args.flag_ui_path);
|
let ui_path = replace_home(&data_path, &self.args.flag_ui_path);
|
||||||
@ -706,7 +732,8 @@ impl Configuration {
|
|||||||
|
|
||||||
Directories {
|
Directories {
|
||||||
keys: keys_path,
|
keys: keys_path,
|
||||||
data: data_path,
|
base: data_path,
|
||||||
|
db: db_path,
|
||||||
dapps: dapps_path,
|
dapps: dapps_path,
|
||||||
signer: ui_path,
|
signer: ui_path,
|
||||||
}
|
}
|
||||||
@ -716,7 +743,7 @@ impl Configuration {
|
|||||||
if self.args.flag_geth {
|
if self.args.flag_geth {
|
||||||
geth_ipc_path(self.args.flag_testnet)
|
geth_ipc_path(self.args.flag_testnet)
|
||||||
} else {
|
} else {
|
||||||
parity_ipc_path(&self.directories().data, &self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone()))
|
parity_ipc_path(&self.directories().base, &self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,13 +813,14 @@ mod tests {
|
|||||||
use ethcore::miner::{MinerOptions, PrioritizationStrategy};
|
use ethcore::miner::{MinerOptions, PrioritizationStrategy};
|
||||||
use helpers::{default_network_config};
|
use helpers::{default_network_config};
|
||||||
use run::RunCmd;
|
use run::RunCmd;
|
||||||
use dir::Directories;
|
use dir::{Directories, default_hypervisor_path};
|
||||||
use signer::{Configuration as SignerConfiguration};
|
use signer::{Configuration as SignerConfiguration};
|
||||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat, ExportState};
|
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat, ExportState};
|
||||||
use presale::ImportWallet;
|
use presale::ImportWallet;
|
||||||
use params::SpecType;
|
use params::SpecType;
|
||||||
use account::{AccountCmd, NewAccount, ImportAccounts, ListAccounts};
|
use account::{AccountCmd, NewAccount, ImportAccounts, ListAccounts};
|
||||||
use devtools::{RandomTempPath};
|
use devtools::{RandomTempPath};
|
||||||
|
use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::fs::{File, create_dir};
|
use std::fs::{File, create_dir};
|
||||||
|
|
||||||
@ -986,6 +1014,7 @@ mod tests {
|
|||||||
acc_conf: Default::default(),
|
acc_conf: Default::default(),
|
||||||
gas_pricer: Default::default(),
|
gas_pricer: Default::default(),
|
||||||
miner_extras: Default::default(),
|
miner_extras: Default::default(),
|
||||||
|
update_policy: UpdatePolicy { enable_downloading: true, require_consensus: true, filter: UpdateFilter::Critical, track: ReleaseTrack::Unknown, path: default_hypervisor_path() },
|
||||||
mode: Default::default(),
|
mode: Default::default(),
|
||||||
tracing: Default::default(),
|
tracing: Default::default(),
|
||||||
compaction: Default::default(),
|
compaction: Default::default(),
|
||||||
@ -1029,6 +1058,21 @@ mod tests {
|
|||||||
assert_eq!(conf3.miner_options().unwrap(), mining_options);
|
assert_eq!(conf3.miner_options().unwrap(), mining_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_parse_updater_options() {
|
||||||
|
// when
|
||||||
|
let conf0 = parse(&["parity", "--release-track=testing"]);
|
||||||
|
let conf1 = parse(&["parity", "--auto-update", "all", "--no-consensus"]);
|
||||||
|
let conf2 = parse(&["parity", "--no-download", "--auto-update=all", "--release-track=beta"]);
|
||||||
|
let conf3 = parse(&["parity", "--auto-update=xxx"]);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(conf0.update_policy().unwrap(), UpdatePolicy{enable_downloading: true, require_consensus: true, filter: UpdateFilter::Critical, track: ReleaseTrack::Testing, path: default_hypervisor_path()});
|
||||||
|
assert_eq!(conf1.update_policy().unwrap(), UpdatePolicy{enable_downloading: true, require_consensus: false, filter: UpdateFilter::All, track: ReleaseTrack::Unknown, path: default_hypervisor_path()});
|
||||||
|
assert_eq!(conf2.update_policy().unwrap(), UpdatePolicy{enable_downloading: false, require_consensus: true, filter: UpdateFilter::All, track: ReleaseTrack::Beta, path: default_hypervisor_path()});
|
||||||
|
assert!(conf3.update_policy().is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_parse_network_settings() {
|
fn should_parse_network_settings() {
|
||||||
// given
|
// given
|
||||||
|
@ -43,7 +43,7 @@ impl Default for Configuration {
|
|||||||
hosts: Some(Vec::new()),
|
hosts: Some(Vec::new()),
|
||||||
user: None,
|
user: None,
|
||||||
pass: None,
|
pass: None,
|
||||||
dapps_path: replace_home(&data_dir, "$DATA/dapps"),
|
dapps_path: replace_home(&data_dir, "$BASE/dapps"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,8 @@ const LEGACY_CLIENT_DB_VER_STR: &'static str = "5.3";
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Directories {
|
pub struct Directories {
|
||||||
pub data: String,
|
pub base: String,
|
||||||
|
pub db: String,
|
||||||
pub keys: String,
|
pub keys: String,
|
||||||
pub signer: String,
|
pub signer: String,
|
||||||
pub dapps: String,
|
pub dapps: String,
|
||||||
@ -37,17 +38,19 @@ impl Default for Directories {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let data_dir = default_data_path();
|
let data_dir = default_data_path();
|
||||||
Directories {
|
Directories {
|
||||||
data: replace_home(&data_dir, "$DATA"),
|
base: replace_home(&data_dir, "$BASE"),
|
||||||
keys: replace_home(&data_dir, "$DATA/keys"),
|
db: replace_home(&data_dir, "$BASE/chains"),
|
||||||
signer: replace_home(&data_dir, "$DATA/signer"),
|
keys: replace_home(&data_dir, "$BASE/keys"),
|
||||||
dapps: replace_home(&data_dir, "$DATA/dapps"),
|
signer: replace_home(&data_dir, "$BASE/signer"),
|
||||||
|
dapps: replace_home(&data_dir, "$BASE/dapps"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Directories {
|
impl Directories {
|
||||||
pub fn create_dirs(&self, dapps_enabled: bool, signer_enabled: bool) -> Result<(), String> {
|
pub fn create_dirs(&self, dapps_enabled: bool, signer_enabled: bool) -> Result<(), String> {
|
||||||
try!(fs::create_dir_all(&self.data).map_err(|e| e.to_string()));
|
try!(fs::create_dir_all(&self.base).map_err(|e| e.to_string()));
|
||||||
|
try!(fs::create_dir_all(&self.db).map_err(|e| e.to_string()));
|
||||||
try!(fs::create_dir_all(&self.keys).map_err(|e| e.to_string()));
|
try!(fs::create_dir_all(&self.keys).map_err(|e| e.to_string()));
|
||||||
if signer_enabled {
|
if signer_enabled {
|
||||||
try!(fs::create_dir_all(&self.signer).map_err(|e| e.to_string()));
|
try!(fs::create_dir_all(&self.signer).map_err(|e| e.to_string()));
|
||||||
@ -61,7 +64,8 @@ impl Directories {
|
|||||||
/// Database paths.
|
/// Database paths.
|
||||||
pub fn database(&self, genesis_hash: H256, fork_name: Option<String>, spec_name: String) -> DatabaseDirectories {
|
pub fn database(&self, genesis_hash: H256, fork_name: Option<String>, spec_name: String) -> DatabaseDirectories {
|
||||||
DatabaseDirectories {
|
DatabaseDirectories {
|
||||||
path: self.data.clone(),
|
path: self.db.clone(),
|
||||||
|
legacy_path: self.base.clone(),
|
||||||
genesis_hash: genesis_hash,
|
genesis_hash: genesis_hash,
|
||||||
fork_name: fork_name,
|
fork_name: fork_name,
|
||||||
spec_name: spec_name,
|
spec_name: spec_name,
|
||||||
@ -70,14 +74,14 @@ impl Directories {
|
|||||||
|
|
||||||
/// Get the ipc sockets path
|
/// Get the ipc sockets path
|
||||||
pub fn ipc_path(&self) -> PathBuf {
|
pub fn ipc_path(&self) -> PathBuf {
|
||||||
let mut dir = Path::new(&self.data).to_path_buf();
|
let mut dir = Path::new(&self.base).to_path_buf();
|
||||||
dir.push("ipc");
|
dir.push("ipc");
|
||||||
dir
|
dir
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove in 1.7
|
// TODO: remove in 1.7
|
||||||
pub fn legacy_keys_path(&self, testnet: bool) -> PathBuf {
|
pub fn legacy_keys_path(&self, testnet: bool) -> PathBuf {
|
||||||
let mut dir = Path::new(&self.data).to_path_buf();
|
let mut dir = Path::new(&self.base).to_path_buf();
|
||||||
if testnet {
|
if testnet {
|
||||||
dir.push("testnet_keys");
|
dir.push("testnet_keys");
|
||||||
} else {
|
} else {
|
||||||
@ -96,6 +100,7 @@ impl Directories {
|
|||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct DatabaseDirectories {
|
pub struct DatabaseDirectories {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
|
pub legacy_path: String,
|
||||||
pub genesis_hash: H256,
|
pub genesis_hash: H256,
|
||||||
pub fork_name: Option<String>,
|
pub fork_name: Option<String>,
|
||||||
pub spec_name: String,
|
pub spec_name: String,
|
||||||
@ -105,14 +110,13 @@ impl DatabaseDirectories {
|
|||||||
/// Base DB directory for the given fork.
|
/// Base DB directory for the given fork.
|
||||||
// TODO: remove in 1.7
|
// TODO: remove in 1.7
|
||||||
pub fn legacy_fork_path(&self) -> PathBuf {
|
pub fn legacy_fork_path(&self) -> PathBuf {
|
||||||
let mut dir = Path::new(&self.path).to_path_buf();
|
let mut dir = Path::new(&self.legacy_path).to_path_buf();
|
||||||
dir.push(format!("{:?}{}", H64::from(self.genesis_hash), self.fork_name.as_ref().map(|f| format!("-{}", f)).unwrap_or_default()));
|
dir.push(format!("{:?}{}", H64::from(self.genesis_hash), self.fork_name.as_ref().map(|f| format!("-{}", f)).unwrap_or_default()));
|
||||||
dir
|
dir
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spec_root_path(&self) -> PathBuf {
|
pub fn spec_root_path(&self) -> PathBuf {
|
||||||
let mut dir = Path::new(&self.path).to_path_buf();
|
let mut dir = Path::new(&self.path).to_path_buf();
|
||||||
dir.push("chains");
|
|
||||||
dir.push(&self.spec_name);
|
dir.push(&self.spec_name);
|
||||||
dir
|
dir
|
||||||
}
|
}
|
||||||
@ -195,6 +199,11 @@ pub fn default_data_path() -> String {
|
|||||||
get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity".to_owned())
|
get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn default_hypervisor_path() -> String {
|
||||||
|
let app_info = AppInfo { name: "parity-hypervisor", author: "parity" };
|
||||||
|
get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity-hypervisor".to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Directories;
|
use super::Directories;
|
||||||
@ -204,10 +213,11 @@ mod tests {
|
|||||||
fn test_default_directories() {
|
fn test_default_directories() {
|
||||||
let data_dir = super::default_data_path();
|
let data_dir = super::default_data_path();
|
||||||
let expected = Directories {
|
let expected = Directories {
|
||||||
data: replace_home(&data_dir, "$DATA"),
|
base: replace_home(&data_dir, "$BASE"),
|
||||||
keys: replace_home(&data_dir, "$DATA/keys"),
|
db: replace_home(&data_dir, "$BASE/chains"),
|
||||||
signer: replace_home(&data_dir, "$DATA/signer"),
|
keys: replace_home(&data_dir, "$BASE/keys"),
|
||||||
dapps: replace_home(&data_dir, "$DATA/dapps"),
|
signer: replace_home(&data_dir, "$BASE/signer"),
|
||||||
|
dapps: replace_home(&data_dir, "$BASE/dapps"),
|
||||||
};
|
};
|
||||||
assert_eq!(expected, Directories::default());
|
assert_eq!(expected, Directories::default());
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ pub fn to_price(s: &str) -> Result<f32, String> {
|
|||||||
pub fn replace_home(base: &str, arg: &str) -> String {
|
pub fn replace_home(base: &str, arg: &str) -> String {
|
||||||
// the $HOME directory on mac os should be `~/Library` or `~/Library/Application Support`
|
// the $HOME directory on mac os should be `~/Library` or `~/Library/Application Support`
|
||||||
let r = arg.replace("$HOME", env::home_dir().unwrap().to_str().unwrap());
|
let r = arg.replace("$HOME", env::home_dir().unwrap().to_str().unwrap());
|
||||||
let r = r.replace("$DATA", base );
|
let r = r.replace("$BASE", base );
|
||||||
r.replace("/", &::std::path::MAIN_SEPARATOR.to_string() )
|
r.replace("/", &::std::path::MAIN_SEPARATOR.to_string() )
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
|
|||||||
pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
|
pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
|
||||||
use ethsync::{NetworkConfiguration, AllowIP};
|
use ethsync::{NetworkConfiguration, AllowIP};
|
||||||
NetworkConfiguration {
|
NetworkConfiguration {
|
||||||
config_path: Some(replace_home(&::dir::default_data_path(), "$DATA/network")),
|
config_path: Some(replace_home(&::dir::default_data_path(), "$BASE/network")),
|
||||||
net_config_path: None,
|
net_config_path: None,
|
||||||
listen_address: Some("0.0.0.0:30303".into()),
|
listen_address: Some("0.0.0.0:30303".into()),
|
||||||
public_address: None,
|
public_address: None,
|
||||||
@ -257,12 +257,13 @@ pub fn to_client_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_upgrades(
|
pub fn execute_upgrades(
|
||||||
|
base_path: &str,
|
||||||
dirs: &DatabaseDirectories,
|
dirs: &DatabaseDirectories,
|
||||||
pruning: Algorithm,
|
pruning: Algorithm,
|
||||||
compaction_profile: CompactionProfile
|
compaction_profile: CompactionProfile
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
|
||||||
upgrade_data_paths(dirs, pruning);
|
upgrade_data_paths(base_path, dirs, pruning);
|
||||||
|
|
||||||
match upgrade(Some(&dirs.path)) {
|
match upgrade(Some(&dirs.path)) {
|
||||||
Ok(upgrades_applied) if upgrades_applied > 0 => {
|
Ok(upgrades_applied) if upgrades_applied > 0 => {
|
||||||
|
@ -19,12 +19,14 @@ use self::ansi_term::Colour::{White, Yellow, Green, Cyan, Blue};
|
|||||||
use self::ansi_term::Style;
|
use self::ansi_term::Style;
|
||||||
|
|
||||||
use std::sync::{Arc};
|
use std::sync::{Arc};
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
|
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
|
use io::{TimerToken, IoContext, IoHandler};
|
||||||
use isatty::{stdout_isatty};
|
use isatty::{stdout_isatty};
|
||||||
use ethsync::{SyncProvider, ManageNetwork};
|
use ethsync::{SyncProvider, ManageNetwork};
|
||||||
use util::{Uint, RwLock, Mutex, H256, Colour, Bytes};
|
use util::{Uint, RwLock, Mutex, H256, Colour, Bytes};
|
||||||
use ethcore::client::*;
|
use ethcore::client::*;
|
||||||
|
use ethcore::service::ClientIoMessage;
|
||||||
use ethcore::views::BlockView;
|
use ethcore::views::BlockView;
|
||||||
use ethcore::snapshot::service::Service as SnapshotService;
|
use ethcore::snapshot::service::Service as SnapshotService;
|
||||||
use ethcore::snapshot::{RestorationStatus, SnapshotService as SS};
|
use ethcore::snapshot::{RestorationStatus, SnapshotService as SS};
|
||||||
@ -44,6 +46,7 @@ pub struct Informant {
|
|||||||
last_import: Mutex<Instant>,
|
last_import: Mutex<Instant>,
|
||||||
skipped: AtomicUsize,
|
skipped: AtomicUsize,
|
||||||
skipped_txs: AtomicUsize,
|
skipped_txs: AtomicUsize,
|
||||||
|
in_shutdown: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format byte counts to standard denominations.
|
/// Format byte counts to standard denominations.
|
||||||
@ -82,9 +85,14 @@ impl Informant {
|
|||||||
last_import: Mutex::new(Instant::now()),
|
last_import: Mutex::new(Instant::now()),
|
||||||
skipped: AtomicUsize::new(0),
|
skipped: AtomicUsize::new(0),
|
||||||
skipped_txs: AtomicUsize::new(0),
|
skipped_txs: AtomicUsize::new(0),
|
||||||
|
in_shutdown: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Signal that we're shutting down; no more output necessary.
|
||||||
|
pub fn shutdown(&self) {
|
||||||
|
self.in_shutdown.store(true, ::std::sync::atomic::Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(match_bool))]
|
#[cfg_attr(feature="dev", allow(match_bool))]
|
||||||
pub fn tick(&self) {
|
pub fn tick(&self) {
|
||||||
@ -221,3 +229,16 @@ impl ChainNotify for Informant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const INFO_TIMER: TimerToken = 0;
|
||||||
|
|
||||||
|
impl IoHandler<ClientIoMessage> for Informant {
|
||||||
|
fn initialize(&self, io: &IoContext<ClientIoMessage>) {
|
||||||
|
io.register_timer(INFO_TIMER, 5000).expect("Error registering timer");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
|
||||||
|
if timer == INFO_TIMER && !self.in_shutdown.load(AtomicOrdering::SeqCst) {
|
||||||
|
self.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use ethcore::client::Client;
|
|
||||||
use ethcore::service::ClientIoMessage;
|
|
||||||
use ethsync::{SyncProvider, ManageNetwork};
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
|
||||||
use io::{TimerToken, IoHandler, IoContext};
|
|
||||||
|
|
||||||
use informant::Informant;
|
|
||||||
|
|
||||||
const INFO_TIMER: TimerToken = 0;
|
|
||||||
|
|
||||||
pub struct ClientIoHandler {
|
|
||||||
pub client: Arc<Client>,
|
|
||||||
pub sync: Arc<SyncProvider>,
|
|
||||||
pub net: Arc<ManageNetwork>,
|
|
||||||
pub accounts: Arc<AccountProvider>,
|
|
||||||
pub info: Arc<Informant>,
|
|
||||||
pub shutdown: Arc<AtomicBool>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IoHandler<ClientIoMessage> for ClientIoHandler {
|
|
||||||
fn initialize(&self, io: &IoContext<ClientIoMessage>) {
|
|
||||||
io.register_timer(INFO_TIMER, 5000).expect("Error registering timer");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
|
|
||||||
if timer == INFO_TIMER && !self.shutdown.load(Ordering::SeqCst) {
|
|
||||||
self.info.tick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ImportIoHandler {
|
|
||||||
pub info: Arc<Informant>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IoHandler<ClientIoMessage> for ImportIoHandler {
|
|
||||||
fn initialize(&self, io: &IoContext<ClientIoMessage>) {
|
|
||||||
io.register_timer(INFO_TIMER, 5000).expect("Error registering timer");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
|
|
||||||
if let INFO_TIMER = timer {
|
|
||||||
self.info.tick()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
183
parity/main.rs
183
parity/main.rs
@ -42,13 +42,14 @@ extern crate ethcore_ipc_nano as nanoipc;
|
|||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate ethcore_hash_fetch as hash_fetch;
|
|
||||||
extern crate ethcore_light as light;
|
extern crate ethcore_light as light;
|
||||||
|
extern crate parity_hash_fetch as hash_fetch;
|
||||||
|
|
||||||
extern crate ethcore_ipc_hypervisor as hypervisor;
|
extern crate ethcore_ipc_hypervisor as hypervisor;
|
||||||
extern crate ethcore_rpc;
|
extern crate ethcore_rpc;
|
||||||
|
|
||||||
extern crate ethcore_signer;
|
extern crate ethcore_signer;
|
||||||
|
extern crate parity_updater as updater;
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
|
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
@ -90,7 +91,6 @@ mod upgrade;
|
|||||||
mod rpc;
|
mod rpc;
|
||||||
mod dapps;
|
mod dapps;
|
||||||
mod informant;
|
mod informant;
|
||||||
mod io_handler;
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod configuration;
|
mod configuration;
|
||||||
mod migration;
|
mod migration;
|
||||||
@ -117,13 +117,16 @@ mod user_defaults;
|
|||||||
mod stratum;
|
mod stratum;
|
||||||
|
|
||||||
use std::{process, env};
|
use std::{process, env};
|
||||||
use std::io::{self as stdio, BufReader, Write};
|
use std::collections::HashMap;
|
||||||
|
use std::io::{self as stdio, BufReader, Read, Write};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use std::path::PathBuf;
|
||||||
use util::sha3::sha3;
|
use util::sha3::sha3;
|
||||||
use cli::Args;
|
use cli::Args;
|
||||||
use configuration::{Cmd, Execute, Configuration};
|
use configuration::{Cmd, Execute, Configuration};
|
||||||
use deprecated::find_deprecated;
|
use deprecated::find_deprecated;
|
||||||
use ethcore_logger::setup_log;
|
use ethcore_logger::setup_log;
|
||||||
|
use dir::default_hypervisor_path;
|
||||||
|
|
||||||
fn print_hash_of(maybe_file: Option<String>) -> Result<String, String> {
|
fn print_hash_of(maybe_file: Option<String>) -> Result<String, String> {
|
||||||
if let Some(file) = maybe_file {
|
if let Some(file) = maybe_file {
|
||||||
@ -135,31 +138,34 @@ fn print_hash_of(maybe_file: Option<String>) -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(command: Execute) -> Result<String, String> {
|
enum PostExecutionAction {
|
||||||
|
Print(String),
|
||||||
|
Restart,
|
||||||
|
Quit,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute(command: Execute, can_restart: bool) -> Result<PostExecutionAction, String> {
|
||||||
let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed");
|
let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed");
|
||||||
|
|
||||||
match command.cmd {
|
match command.cmd {
|
||||||
Cmd::Run(run_cmd) => {
|
Cmd::Run(run_cmd) => {
|
||||||
try!(run::execute(run_cmd, logger));
|
let restart = run::execute(run_cmd, can_restart, logger)?;
|
||||||
Ok("".into())
|
Ok(if restart { PostExecutionAction::Restart } else { PostExecutionAction::Quit })
|
||||||
},
|
},
|
||||||
Cmd::Version => Ok(Args::print_version()),
|
Cmd::Version => Ok(PostExecutionAction::Print(Args::print_version())),
|
||||||
Cmd::Hash(maybe_file) => print_hash_of(maybe_file),
|
Cmd::Hash(maybe_file) => print_hash_of(maybe_file).map(|s| PostExecutionAction::Print(s)),
|
||||||
Cmd::Account(account_cmd) => account::execute(account_cmd),
|
Cmd::Account(account_cmd) => account::execute(account_cmd).map(|s| PostExecutionAction::Print(s)),
|
||||||
Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd),
|
Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd).map(|s| PostExecutionAction::Print(s)),
|
||||||
Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd),
|
Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd).map(|_| PostExecutionAction::Quit),
|
||||||
Cmd::SignerToken(signer_cmd) => signer::execute(signer_cmd),
|
Cmd::SignerToken(signer_cmd) => signer::execute(signer_cmd).map(|s| PostExecutionAction::Print(s)),
|
||||||
Cmd::SignerSign { id, pwfile, port, authfile } =>
|
Cmd::SignerSign { id, pwfile, port, authfile } => rpc_cli::signer_sign(id, pwfile, port, authfile).map(|s| PostExecutionAction::Print(s)),
|
||||||
rpc_cli::cmd_signer_sign(id, pwfile, port, authfile),
|
Cmd::SignerList { port, authfile } => rpc_cli::signer_list(port, authfile).map(|s| PostExecutionAction::Print(s)),
|
||||||
Cmd::SignerList { port, authfile } =>
|
Cmd::SignerReject { id, port, authfile } => rpc_cli::signer_reject(id, port, authfile).map(|s| PostExecutionAction::Print(s)),
|
||||||
rpc_cli::cmd_signer_list(port, authfile),
|
Cmd::Snapshot(snapshot_cmd) => snapshot::execute(snapshot_cmd).map(|s| PostExecutionAction::Print(s)),
|
||||||
Cmd::SignerReject { id, port, authfile } =>
|
|
||||||
rpc_cli::cmd_signer_reject(id, port, authfile),
|
|
||||||
Cmd::Snapshot(snapshot_cmd) => snapshot::execute(snapshot_cmd),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start() -> Result<String, String> {
|
fn start(can_restart: bool) -> Result<PostExecutionAction, String> {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
let conf = Configuration::parse(&args).unwrap_or_else(|e| e.exit());
|
let conf = Configuration::parse(&args).unwrap_or_else(|e| e.exit());
|
||||||
|
|
||||||
@ -169,61 +175,118 @@ fn start() -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let cmd = try!(conf.into_command());
|
let cmd = try!(conf.into_command());
|
||||||
execute(cmd)
|
execute(cmd, can_restart)
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature="stratum")]
|
|
||||||
mod stratum_optional {
|
|
||||||
pub fn probably_run() -> bool {
|
|
||||||
// just redirect to the stratum::main()
|
|
||||||
if ::std::env::args().nth(1).map_or(false, |arg| arg == "stratum") {
|
|
||||||
super::stratum::main();
|
|
||||||
true
|
|
||||||
}
|
|
||||||
else { false }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature="stratum"))]
|
#[cfg(not(feature="stratum"))]
|
||||||
mod stratum_optional {
|
fn stratum_main(_: &mut HashMap<String, fn()>) {}
|
||||||
pub fn probably_run() -> bool {
|
|
||||||
false
|
#[cfg(feature="stratum")]
|
||||||
}
|
fn stratum_main(alt_mains: &mut HashMap<String, fn()>) {
|
||||||
|
alt_mains.insert("stratum".to_owned(), stratum::main);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature="ipc"))]
|
#[cfg(not(feature="ipc"))]
|
||||||
fn sync_main() -> bool {
|
fn sync_main(_: &mut HashMap<String, fn()>) {}
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature="ipc")]
|
#[cfg(feature="ipc")]
|
||||||
fn sync_main() -> bool {
|
fn sync_main(alt_mains: &mut HashMap<String, fn()>) {
|
||||||
// just redirect to the sync::main()
|
alt_mains.insert("sync".to_owned(), sync::main);
|
||||||
if std::env::args().nth(1).map_or(false, |arg| arg == "sync") {
|
}
|
||||||
sync::main();
|
|
||||||
true
|
fn updates_path(name: &str) -> PathBuf {
|
||||||
|
let mut dest = PathBuf::from(default_hypervisor_path());
|
||||||
|
dest.push(name);
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
fn latest_exe_path() -> Option<PathBuf> {
|
||||||
|
File::open(updates_path("latest")).ok()
|
||||||
|
.and_then(|mut f| { let mut exe = String::new(); f.read_to_string(&mut exe).ok().map(|_| updates_path(&exe)) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts ~/.parity-updates/parity and returns the code it exits with.
|
||||||
|
fn run_parity() -> Option<i32> {
|
||||||
|
use ::std::ffi::OsString;
|
||||||
|
let prefix = vec![OsString::from("--can-restart"), OsString::from("--force-direct")];
|
||||||
|
latest_exe_path().and_then(|exe| process::Command::new(exe)
|
||||||
|
.args(&(env::args_os().chain(prefix.into_iter()).collect::<Vec<_>>()))
|
||||||
|
.status()
|
||||||
|
.map(|es| es.code().unwrap_or(128))
|
||||||
|
.ok()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const PLEASE_RESTART_EXIT_CODE: i32 = 69;
|
||||||
|
|
||||||
|
// Run our version of parity.
|
||||||
|
// Returns the exit error code.
|
||||||
|
fn main_direct(can_restart: bool) -> i32 {
|
||||||
|
let mut alt_mains = HashMap::new();
|
||||||
|
sync_main(&mut alt_mains);
|
||||||
|
stratum_main(&mut alt_mains);
|
||||||
|
if let Some(f) = std::env::args().nth(1).and_then(|arg| alt_mains.get(&arg.to_string())) {
|
||||||
|
f();
|
||||||
|
0
|
||||||
} else {
|
} else {
|
||||||
false
|
match start(can_restart) {
|
||||||
|
Ok(result) => match result {
|
||||||
|
PostExecutionAction::Print(s) => { println!("{}", s); 0 },
|
||||||
|
PostExecutionAction::Restart => PLEASE_RESTART_EXIT_CODE,
|
||||||
|
PostExecutionAction::Quit => 0,
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
writeln!(&mut stdio::stderr(), "{}", err).expect("StdErr available; qed");
|
||||||
|
1
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn println_trace_main(s: String) {
|
||||||
|
if env::var("RUST_LOG").ok().and_then(|s| s.find("main=trace")).is_some() {
|
||||||
|
println!("{}", s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! trace_main {
|
||||||
|
($arg:expr) => (println_trace_main($arg.into()));
|
||||||
|
($($arg:tt)*) => (println_trace_main(format!("{}", format_args!($($arg)*))));
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Always print backtrace on panic.
|
// Always print backtrace on panic.
|
||||||
::std::env::set_var("RUST_BACKTRACE", "1");
|
env::set_var("RUST_BACKTRACE", "1");
|
||||||
|
|
||||||
if sync_main() {
|
// assuming the user is not running with `--force-direct`, then:
|
||||||
return;
|
// if argv[0] == "parity" and this executable != ~/.parity-updates/parity, run that instead.
|
||||||
}
|
let force_direct = std::env::args().any(|arg| arg == "--force-direct");
|
||||||
|
let exe = std::env::current_exe().ok();
|
||||||
if stratum_optional::probably_run() { return; }
|
let development = exe.as_ref().and_then(|p| p.parent().and_then(|p| p.parent()).and_then(|p| p.file_name()).map(|n| n == "target")).unwrap_or(false);
|
||||||
|
let same_name = exe.as_ref().map(|p| p.file_stem().map_or(false, |s| s == "parity") && p.extension().map_or(true, |x| x == "exe")).unwrap_or(false);
|
||||||
match start() {
|
let latest_exe = latest_exe_path();
|
||||||
Ok(result) => {
|
let have_update = latest_exe.as_ref().map_or(false, |p| p.exists());
|
||||||
info!("{}", result);
|
let is_non_updated_current = exe.map_or(false, |exe| latest_exe.as_ref().map_or(false, |lexe| exe.canonicalize().ok() != lexe.canonicalize().ok()));
|
||||||
},
|
trace_main!("Starting up {} (force-direct: {}, development: {}, same-name: {}, have-update: {}, non-updated-current: {})", std::env::current_exe().map(|x| format!("{}", x.display())).unwrap_or("<unknown>".to_owned()), force_direct, development, same_name, have_update, is_non_updated_current);
|
||||||
Err(err) => {
|
if !force_direct && !development && same_name && have_update && is_non_updated_current {
|
||||||
writeln!(&mut stdio::stderr(), "{}", err).expect("StdErr available; qed");
|
// looks like we're not running ~/.parity-updates/parity when the user is expecting otherwise.
|
||||||
process::exit(1);
|
// Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly.
|
||||||
|
loop {
|
||||||
|
// If we fail to run the updated parity then fallback to local version.
|
||||||
|
trace_main!("Attempting to run latest update ({})...", latest_exe.as_ref().expect("guarded by have_update; latest_exe must exist for have_update; qed").display());
|
||||||
|
let exit_code = run_parity().unwrap_or_else(|| { trace_main!("Falling back to local..."); main_direct(true) });
|
||||||
|
trace_main!("Latest exited with {}", exit_code);
|
||||||
|
if exit_code != PLEASE_RESTART_EXIT_CODE {
|
||||||
|
trace_main!("Quitting...");
|
||||||
|
process::exit(exit_code);
|
||||||
|
}
|
||||||
|
trace_main!("Rerunning...");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
trace_main!("Running direct");
|
||||||
|
// Otherwise, we're presumably running the version we want. Just run and fall-through.
|
||||||
|
let can_restart = std::env::args().any(|arg| arg == "--can-restart");
|
||||||
|
process::exit(main_direct(can_restart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ impl Default for IpcConfiguration {
|
|||||||
let data_dir = default_data_path();
|
let data_dir = default_data_path();
|
||||||
IpcConfiguration {
|
IpcConfiguration {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
socket_addr: parity_ipc_path(&data_dir, "$DATA/jsonrpc.ipc"),
|
socket_addr: parity_ipc_path(&data_dir, "$BASE/jsonrpc.ipc"),
|
||||||
apis: ApiSet::IpcContext,
|
apis: ApiSet::IpcContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ use ethcore::snapshot::SnapshotService;
|
|||||||
use ethsync::{ManageNetwork, SyncProvider};
|
use ethsync::{ManageNetwork, SyncProvider};
|
||||||
use ethcore_rpc::{Extendable, NetworkSettings};
|
use ethcore_rpc::{Extendable, NetworkSettings};
|
||||||
pub use ethcore_rpc::SignerService;
|
pub use ethcore_rpc::SignerService;
|
||||||
|
use updater::Updater;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
||||||
pub enum Api {
|
pub enum Api {
|
||||||
@ -118,6 +118,7 @@ pub struct Dependencies {
|
|||||||
pub logger: Arc<RotatingLogger>,
|
pub logger: Arc<RotatingLogger>,
|
||||||
pub settings: Arc<NetworkSettings>,
|
pub settings: Arc<NetworkSettings>,
|
||||||
pub net_service: Arc<ManageNetwork>,
|
pub net_service: Arc<ManageNetwork>,
|
||||||
|
pub updater: Arc<Updater>,
|
||||||
pub geth_compatibility: bool,
|
pub geth_compatibility: bool,
|
||||||
pub dapps_interface: Option<String>,
|
pub dapps_interface: Option<String>,
|
||||||
pub dapps_port: Option<u16>,
|
pub dapps_port: Option<u16>,
|
||||||
@ -224,6 +225,7 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
|||||||
&deps.client,
|
&deps.client,
|
||||||
&deps.miner,
|
&deps.miner,
|
||||||
&deps.sync,
|
&deps.sync,
|
||||||
|
&deps.updater,
|
||||||
&deps.net_service,
|
&deps.net_service,
|
||||||
&deps.secret_store,
|
&deps.secret_store,
|
||||||
deps.logger.clone(),
|
deps.logger.clone(),
|
||||||
@ -240,7 +242,7 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
|||||||
server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate());
|
server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate());
|
||||||
},
|
},
|
||||||
Api::ParitySet => {
|
Api::ParitySet => {
|
||||||
server.add_delegate(ParitySetClient::new(&deps.client, &deps.miner, &deps.net_service).to_delegate())
|
server.add_delegate(ParitySetClient::new(&deps.client, &deps.miner, &deps.updater, &deps.net_service).to_delegate())
|
||||||
},
|
},
|
||||||
Api::Traces => {
|
Api::Traces => {
|
||||||
server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate())
|
server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate())
|
||||||
|
@ -14,16 +14,16 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex, Condvar};
|
use std::sync::Arc;
|
||||||
use std::net::{TcpListener};
|
use std::net::{TcpListener};
|
||||||
use ctrlc::CtrlC;
|
use ctrlc::CtrlC;
|
||||||
use fdlimit::raise_fd_limit;
|
use fdlimit::raise_fd_limit;
|
||||||
use ethcore_rpc::{NetworkSettings, is_major_importing};
|
use ethcore_rpc::{NetworkSettings, is_major_importing};
|
||||||
use ethsync::NetworkConfiguration;
|
use ethsync::NetworkConfiguration;
|
||||||
use util::{Colour, version, RotatingLogger};
|
use util::{Colour, version, RotatingLogger, Mutex, Condvar};
|
||||||
use io::{MayPanic, ForwardPanic, PanicHandler};
|
use io::{MayPanic, ForwardPanic, PanicHandler};
|
||||||
use ethcore_logger::{Config as LogConfig};
|
use ethcore_logger::{Config as LogConfig};
|
||||||
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, ChainNotify, BlockChainClient};
|
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockChainClient};
|
||||||
use ethcore::service::ClientService;
|
use ethcore::service::ClientService;
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
|
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
|
||||||
@ -31,11 +31,11 @@ use ethcore::snapshot;
|
|||||||
use ethcore::verification::queue::VerifierSettings;
|
use ethcore::verification::queue::VerifierSettings;
|
||||||
use ethsync::SyncConfig;
|
use ethsync::SyncConfig;
|
||||||
use informant::Informant;
|
use informant::Informant;
|
||||||
|
use updater::{UpdatePolicy, Updater};
|
||||||
|
|
||||||
use rpc::{HttpServer, IpcServer, HttpConfiguration, IpcConfiguration};
|
use rpc::{HttpServer, IpcServer, HttpConfiguration, IpcConfiguration};
|
||||||
use signer::SignerServer;
|
use signer::SignerServer;
|
||||||
use dapps::WebappServer;
|
use dapps::WebappServer;
|
||||||
use io_handler::ClientIoHandler;
|
|
||||||
use params::{
|
use params::{
|
||||||
SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch,
|
SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch,
|
||||||
tracing_switch_to_bool, fatdb_switch_to_bool, mode_switch_to_bool
|
tracing_switch_to_bool, fatdb_switch_to_bool, mode_switch_to_bool
|
||||||
@ -77,6 +77,7 @@ pub struct RunCmd {
|
|||||||
pub acc_conf: AccountsConfig,
|
pub acc_conf: AccountsConfig,
|
||||||
pub gas_pricer: GasPricerConfig,
|
pub gas_pricer: GasPricerConfig,
|
||||||
pub miner_extras: MinerExtras,
|
pub miner_extras: MinerExtras,
|
||||||
|
pub update_policy: UpdatePolicy,
|
||||||
pub mode: Option<Mode>,
|
pub mode: Option<Mode>,
|
||||||
pub tracing: Switch,
|
pub tracing: Switch,
|
||||||
pub fat_db: Switch,
|
pub fat_db: Switch,
|
||||||
@ -115,12 +116,12 @@ pub fn open_ui(dapps_conf: &dapps::Configuration, signer_conf: &signer::Configur
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<bool, String> {
|
||||||
if cmd.ui && cmd.dapps_conf.enabled {
|
if cmd.ui && cmd.dapps_conf.enabled {
|
||||||
// Check if Parity is already running
|
// Check if Parity is already running
|
||||||
let addr = format!("{}:{}", cmd.dapps_conf.interface, cmd.dapps_conf.port);
|
let addr = format!("{}:{}", cmd.dapps_conf.interface, cmd.dapps_conf.port);
|
||||||
if !TcpListener::bind(&addr as &str).is_ok() {
|
if !TcpListener::bind(&addr as &str).is_ok() {
|
||||||
return open_ui(&cmd.dapps_conf, &cmd.signer_conf);
|
return open_ui(&cmd.dapps_conf, &cmd.signer_conf).map(|_| false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,12 +160,15 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
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, };
|
||||||
|
|
||||||
|
// get the update policy
|
||||||
|
let update_policy = cmd.update_policy;
|
||||||
|
|
||||||
// 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.db_root_path().as_path())));
|
try!(execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||||
|
|
||||||
// create dirs used by parity
|
// create dirs used by parity
|
||||||
try!(cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.signer_conf.enabled));
|
try!(cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.signer_conf.enabled));
|
||||||
@ -307,6 +311,10 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
chain_notify.start();
|
chain_notify.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the updater service
|
||||||
|
let updater = Updater::new(Arc::downgrade(&(service.client() as Arc<BlockChainClient>)), Arc::downgrade(&sync_provider), update_policy);
|
||||||
|
service.add_notify(updater.clone());
|
||||||
|
|
||||||
// set up dependencies for rpc servers
|
// set up dependencies for rpc servers
|
||||||
let signer_path = cmd.signer_conf.signer_path.clone();
|
let signer_path = cmd.signer_conf.signer_path.clone();
|
||||||
let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies {
|
let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies {
|
||||||
@ -323,6 +331,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
logger: logger.clone(),
|
logger: logger.clone(),
|
||||||
settings: Arc::new(cmd.net_settings.clone()),
|
settings: Arc::new(cmd.net_settings.clone()),
|
||||||
net_service: manage_network.clone(),
|
net_service: manage_network.clone(),
|
||||||
|
updater: updater.clone(),
|
||||||
geth_compatibility: cmd.geth_compatibility,
|
geth_compatibility: cmd.geth_compatibility,
|
||||||
dapps_interface: match cmd.dapps_conf.enabled {
|
dapps_interface: match cmd.dapps_conf.enabled {
|
||||||
true => Some(cmd.dapps_conf.interface.clone()),
|
true => Some(cmd.dapps_conf.interface.clone()),
|
||||||
@ -343,24 +352,23 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
let http_server = try!(rpc::new_http(cmd.http_conf, &dependencies));
|
let http_server = try!(rpc::new_http(cmd.http_conf, &dependencies));
|
||||||
let ipc_server = try!(rpc::new_ipc(cmd.ipc_conf, &dependencies));
|
let ipc_server = try!(rpc::new_ipc(cmd.ipc_conf, &dependencies));
|
||||||
|
|
||||||
|
// the dapps server
|
||||||
let dapps_deps = dapps::Dependencies {
|
let dapps_deps = dapps::Dependencies {
|
||||||
panic_handler: panic_handler.clone(),
|
panic_handler: panic_handler.clone(),
|
||||||
apis: deps_for_rpc_apis.clone(),
|
apis: deps_for_rpc_apis.clone(),
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
sync: sync_provider.clone(),
|
sync: sync_provider.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// start dapps server
|
|
||||||
let dapps_server = try!(dapps::new(cmd.dapps_conf.clone(), dapps_deps));
|
let dapps_server = try!(dapps::new(cmd.dapps_conf.clone(), dapps_deps));
|
||||||
|
|
||||||
|
// the signer server
|
||||||
let signer_deps = signer::Dependencies {
|
let signer_deps = signer::Dependencies {
|
||||||
panic_handler: panic_handler.clone(),
|
panic_handler: panic_handler.clone(),
|
||||||
apis: deps_for_rpc_apis.clone(),
|
apis: deps_for_rpc_apis.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// start signer server
|
|
||||||
let signer_server = try!(signer::start(cmd.signer_conf.clone(), signer_deps));
|
let signer_server = try!(signer::start(cmd.signer_conf.clone(), signer_deps));
|
||||||
|
|
||||||
|
// the informant
|
||||||
let informant = Arc::new(Informant::new(
|
let informant = Arc::new(Informant::new(
|
||||||
service.client(),
|
service.client(),
|
||||||
Some(sync_provider.clone()),
|
Some(sync_provider.clone()),
|
||||||
@ -368,17 +376,8 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
Some(snapshot_service.clone()),
|
Some(snapshot_service.clone()),
|
||||||
cmd.logger_config.color
|
cmd.logger_config.color
|
||||||
));
|
));
|
||||||
let info_notify: Arc<ChainNotify> = informant.clone();
|
service.add_notify(informant.clone());
|
||||||
service.add_notify(info_notify);
|
service.register_io_handler(informant.clone()).map_err(|_| "Unable to register informant handler".to_owned())?;
|
||||||
let io_handler = Arc::new(ClientIoHandler {
|
|
||||||
client: service.client(),
|
|
||||||
info: informant,
|
|
||||||
sync: sync_provider.clone(),
|
|
||||||
net: manage_network.clone(),
|
|
||||||
accounts: account_provider.clone(),
|
|
||||||
shutdown: Default::default(),
|
|
||||||
});
|
|
||||||
service.register_io_handler(io_handler.clone()).expect("Error registering IO handler");
|
|
||||||
|
|
||||||
// save user defaults
|
// save user defaults
|
||||||
user_defaults.pruning = algorithm;
|
user_defaults.pruning = algorithm;
|
||||||
@ -387,13 +386,11 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
user_defaults.mode = mode;
|
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| {
|
// tell client how to save the default mode if it gets changed.
|
||||||
|
client.on_mode_change(move |mode: &Mode| {
|
||||||
user_defaults.mode = mode.clone();
|
user_defaults.mode = mode.clone();
|
||||||
let _ = user_defaults.save(&user_defaults_path); // discard failures - there's nothing we can do
|
let _ = user_defaults.save(&user_defaults_path); // discard failures - there's nothing we can do
|
||||||
};
|
});
|
||||||
|
|
||||||
// tell client how to save the default mode if it gets changed.
|
|
||||||
client.on_mode_change(on_mode_change);
|
|
||||||
|
|
||||||
// the watcher must be kept alive.
|
// the watcher must be kept alive.
|
||||||
let _watcher = match cmd.no_periodic_snapshot {
|
let _watcher = match cmd.no_periodic_snapshot {
|
||||||
@ -419,18 +416,20 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle exit
|
// Handle exit
|
||||||
wait_for_exit(panic_handler, http_server, ipc_server, dapps_server, signer_server);
|
let restart = wait_for_exit(panic_handler, http_server, ipc_server, dapps_server, signer_server, updater, can_restart);
|
||||||
|
|
||||||
|
info!("Finishing work, please wait...");
|
||||||
|
|
||||||
// to make sure timer does not spawn requests while shutdown is in progress
|
// to make sure timer does not spawn requests while shutdown is in progress
|
||||||
io_handler.shutdown.store(true, ::std::sync::atomic::Ordering::SeqCst);
|
informant.shutdown();
|
||||||
// just Arc is dropping here, to allow other reference release in its default time
|
// just Arc is dropping here, to allow other reference release in its default time
|
||||||
drop(io_handler);
|
drop(informant);
|
||||||
|
|
||||||
// hypervisor should be shutdown first while everything still works and can be
|
// hypervisor should be shutdown first while everything still works and can be
|
||||||
// terminated gracefully
|
// terminated gracefully
|
||||||
drop(hypervisor);
|
drop(hypervisor);
|
||||||
|
|
||||||
Ok(())
|
Ok(restart)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
@ -438,11 +437,11 @@ fn daemonize(pid_file: String) -> Result<(), String> {
|
|||||||
extern crate daemonize;
|
extern crate daemonize;
|
||||||
|
|
||||||
daemonize::Daemonize::new()
|
daemonize::Daemonize::new()
|
||||||
.pid_file(pid_file)
|
.pid_file(pid_file)
|
||||||
.chown_pid_file(true)
|
.chown_pid_file(true)
|
||||||
.start()
|
.start()
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.map_err(|e| format!("Couldn't daemonize; {}", e))
|
.map_err(|e| format!("Couldn't daemonize; {}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -475,20 +474,30 @@ fn wait_for_exit(
|
|||||||
_http_server: Option<HttpServer>,
|
_http_server: Option<HttpServer>,
|
||||||
_ipc_server: Option<IpcServer>,
|
_ipc_server: Option<IpcServer>,
|
||||||
_dapps_server: Option<WebappServer>,
|
_dapps_server: Option<WebappServer>,
|
||||||
_signer_server: Option<SignerServer>
|
_signer_server: Option<SignerServer>,
|
||||||
) {
|
updater: Arc<Updater>,
|
||||||
let exit = Arc::new(Condvar::new());
|
can_restart: bool
|
||||||
|
) -> bool {
|
||||||
|
let exit = Arc::new((Mutex::new(false), Condvar::new()));
|
||||||
|
|
||||||
// Handle possible exits
|
// Handle possible exits
|
||||||
let e = exit.clone();
|
let e = exit.clone();
|
||||||
CtrlC::set_handler(move || { e.notify_all(); });
|
CtrlC::set_handler(move || { e.1.notify_all(); });
|
||||||
|
|
||||||
// Handle panics
|
// Handle panics
|
||||||
let e = exit.clone();
|
let e = exit.clone();
|
||||||
panic_handler.on_panic(move |_reason| { e.notify_all(); });
|
panic_handler.on_panic(move |_reason| { e.1.notify_all(); });
|
||||||
|
|
||||||
|
// Handle updater wanting to restart us
|
||||||
|
if can_restart {
|
||||||
|
let e = exit.clone();
|
||||||
|
updater.set_exit_handler(move || { *e.0.lock() = true; e.1.notify_all(); });
|
||||||
|
} else {
|
||||||
|
updater.set_exit_handler(|| info!("Update installed; ready for restart."));
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for signal
|
// Wait for signal
|
||||||
let mutex = Mutex::new(());
|
let mut l = exit.0.lock();
|
||||||
let _ = exit.wait(mutex.lock().unwrap());
|
let _ = exit.1.wait(&mut l);
|
||||||
info!("Finishing work, please wait...");
|
*l
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ impl Default for Configuration {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
port: 8180,
|
port: 8180,
|
||||||
interface: "127.0.0.1".into(),
|
interface: "127.0.0.1".into(),
|
||||||
signer_path: replace_home(&data_dir, "$DATA/signer"),
|
signer_path: replace_home(&data_dir, "$BASE/signer"),
|
||||||
skip_origin_validation: false,
|
skip_origin_validation: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ impl SnapshotCommand {
|
|||||||
let snapshot_path = db_dirs.snapshot_path();
|
let snapshot_path = db_dirs.snapshot_path();
|
||||||
|
|
||||||
// execute upgrades
|
// execute upgrades
|
||||||
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
try!(execute_upgrades(&self.dirs.base, &db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||||
|
|
||||||
// prepare client config
|
// prepare client config
|
||||||
let client_config = to_client_config(&self.cache_config, Mode::Active, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
|
let client_config = to_client_config(&self.cache_config, Mode::Active, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
|
||||||
|
@ -200,11 +200,11 @@ fn upgrade_user_defaults(dirs: &DatabaseDirectories) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upgrade_data_paths(dirs: &DatabaseDirectories, pruning: Algorithm) {
|
pub fn upgrade_data_paths(base_path: &str, dirs: &DatabaseDirectories, pruning: Algorithm) {
|
||||||
let legacy_root_path = replace_home("", "$HOME/.parity");
|
let legacy_root_path = replace_home("", "$HOME/.parity");
|
||||||
let default_path = default_data_path();
|
let default_path = default_data_path();
|
||||||
if legacy_root_path != dirs.path && dirs.path == default_path {
|
if legacy_root_path != base_path && base_path == default_path {
|
||||||
upgrade_dir_location(&PathBuf::from(legacy_root_path), &PathBuf::from(&dirs.path));
|
upgrade_dir_location(&PathBuf::from(legacy_root_path), &PathBuf::from(&base_path));
|
||||||
}
|
}
|
||||||
upgrade_dir_location(&dirs.legacy_version_path(pruning), &dirs.db_path(pruning));
|
upgrade_dir_location(&dirs.legacy_version_path(pruning), &dirs.db_path(pruning));
|
||||||
upgrade_dir_location(&dirs.legacy_snapshot_path(), &dirs.snapshot_path());
|
upgrade_dir_location(&dirs.legacy_snapshot_path(), &dirs.snapshot_path());
|
||||||
|
@ -26,6 +26,7 @@ ethash = { path = "../ethash" }
|
|||||||
ethsync = { path = "../sync" }
|
ethsync = { path = "../sync" }
|
||||||
ethjson = { path = "../json" }
|
ethjson = { path = "../json" }
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
|
parity-updater = { path = "../updater" }
|
||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
@ -34,6 +35,7 @@ serde_macros = { version = "0.8.0", optional = true }
|
|||||||
clippy = { version = "0.0.103", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
|
semver = "0.5"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde_codegen = { version = "0.8.0", optional = true }
|
serde_codegen = { version = "0.8.0", optional = true }
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))]
|
#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))]
|
||||||
#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))]
|
#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))]
|
||||||
|
|
||||||
|
extern crate semver;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
@ -37,6 +38,7 @@ extern crate ethcore_ipc;
|
|||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate fetch;
|
extern crate fetch;
|
||||||
|
extern crate parity_updater as updater;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
@ -30,6 +30,7 @@ use ethcore::miner::MinerService;
|
|||||||
use ethcore::client::{MiningBlockChainClient};
|
use ethcore::client::{MiningBlockChainClient};
|
||||||
use ethcore::mode::Mode;
|
use ethcore::mode::Mode;
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
use updater::{Service as UpdateService};
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use jsonrpc_macros::Trailing;
|
use jsonrpc_macros::Trailing;
|
||||||
@ -38,20 +39,23 @@ 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,
|
BlockNumber, ConsensusCapability, VersionInfo,
|
||||||
|
OperationsInfo
|
||||||
};
|
};
|
||||||
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;
|
||||||
|
|
||||||
/// Parity implementation.
|
/// Parity implementation.
|
||||||
pub struct ParityClient<C, M, S: ?Sized> where
|
pub struct ParityClient<C, M, S: ?Sized, U> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService,
|
M: MinerService,
|
||||||
S: SyncProvider,
|
S: SyncProvider,
|
||||||
|
U: UpdateService,
|
||||||
{
|
{
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
sync: Weak<S>,
|
sync: Weak<S>,
|
||||||
|
updater: Weak<U>,
|
||||||
net: Weak<ManageNetwork>,
|
net: Weak<ManageNetwork>,
|
||||||
accounts: Weak<AccountProvider>,
|
accounts: Weak<AccountProvider>,
|
||||||
logger: Arc<RotatingLogger>,
|
logger: Arc<RotatingLogger>,
|
||||||
@ -61,16 +65,18 @@ pub struct ParityClient<C, M, S: ?Sized> where
|
|||||||
dapps_port: Option<u16>,
|
dapps_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M, S: ?Sized> ParityClient<C, M, S> where
|
impl<C, M, S: ?Sized, U> ParityClient<C, M, S, U> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService,
|
M: MinerService,
|
||||||
S: SyncProvider,
|
S: SyncProvider,
|
||||||
|
U: UpdateService,
|
||||||
{
|
{
|
||||||
/// Creates new `ParityClient`.
|
/// Creates new `ParityClient`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
client: &Arc<C>,
|
client: &Arc<C>,
|
||||||
miner: &Arc<M>,
|
miner: &Arc<M>,
|
||||||
sync: &Arc<S>,
|
sync: &Arc<S>,
|
||||||
|
updater: &Arc<U>,
|
||||||
net: &Arc<ManageNetwork>,
|
net: &Arc<ManageNetwork>,
|
||||||
store: &Arc<AccountProvider>,
|
store: &Arc<AccountProvider>,
|
||||||
logger: Arc<RotatingLogger>,
|
logger: Arc<RotatingLogger>,
|
||||||
@ -83,6 +89,7 @@ impl<C, M, S: ?Sized> ParityClient<C, M, S> where
|
|||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
miner: Arc::downgrade(miner),
|
miner: Arc::downgrade(miner),
|
||||||
sync: Arc::downgrade(sync),
|
sync: Arc::downgrade(sync),
|
||||||
|
updater: Arc::downgrade(updater),
|
||||||
net: Arc::downgrade(net),
|
net: Arc::downgrade(net),
|
||||||
accounts: Arc::downgrade(store),
|
accounts: Arc::downgrade(store),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
@ -100,10 +107,11 @@ impl<C, M, S: ?Sized> ParityClient<C, M, S> where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M, S: ?Sized> Parity for ParityClient<C, M, S> where
|
impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
||||||
M: MinerService + 'static,
|
M: MinerService + 'static,
|
||||||
C: MiningBlockChainClient + 'static,
|
C: MiningBlockChainClient + 'static,
|
||||||
S: SyncProvider + 'static {
|
S: SyncProvider + 'static,
|
||||||
|
U: UpdateService + 'static {
|
||||||
|
|
||||||
fn transactions_limit(&self) -> Result<usize, Error> {
|
fn transactions_limit(&self) -> Result<usize, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
@ -353,4 +361,22 @@ impl<C, M, S: ?Sized> Parity for ParityClient<C, M, S> where
|
|||||||
(format!("0x{}", a.hex()), m)
|
(format!("0x{}", a.hex()), m)
|
||||||
}).collect())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn consensus_capability(&self) -> Result<ConsensusCapability, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
let updater = take_weak!(self.updater);
|
||||||
|
Ok(updater.capability().into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version_info(&self) -> Result<VersionInfo, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
let updater = take_weak!(self.updater);
|
||||||
|
Ok(updater.version_info().into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn releases_info(&self) -> Result<Option<OperationsInfo>, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
let updater = take_weak!(self.updater);
|
||||||
|
Ok(updater.info().map(Into::into))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,45 +24,51 @@ use ethcore::mode::Mode;
|
|||||||
use ethsync::ManageNetwork;
|
use ethsync::ManageNetwork;
|
||||||
use fetch::{Client as FetchClient, Fetch};
|
use fetch::{Client as FetchClient, Fetch};
|
||||||
use util::{Mutex, sha3};
|
use util::{Mutex, sha3};
|
||||||
|
use updater::{Service as UpdateService};
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use jsonrpc_macros::Ready;
|
use jsonrpc_macros::Ready;
|
||||||
use v1::helpers::errors;
|
use v1::helpers::errors;
|
||||||
use v1::traits::ParitySet;
|
use v1::traits::ParitySet;
|
||||||
use v1::types::{Bytes, H160, H256, U256};
|
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo};
|
||||||
|
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
pub struct ParitySetClient<C, M, F=FetchClient> where
|
pub struct ParitySetClient<C, M, U, F=FetchClient> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService,
|
M: MinerService,
|
||||||
|
U: UpdateService,
|
||||||
F: Fetch,
|
F: Fetch,
|
||||||
{
|
{
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
|
updater: Weak<U>,
|
||||||
net: Weak<ManageNetwork>,
|
net: Weak<ManageNetwork>,
|
||||||
fetch: Mutex<F>,
|
fetch: Mutex<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> ParitySetClient<C, M, FetchClient> where
|
impl<C, M, U> ParitySetClient<C, M, U, FetchClient> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService
|
M: MinerService,
|
||||||
|
U: UpdateService,
|
||||||
{
|
{
|
||||||
/// Creates new `ParitySetClient` with default `FetchClient`.
|
/// Creates new `ParitySetClient` with default `FetchClient`.
|
||||||
pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self {
|
pub fn new(client: &Arc<C>, miner: &Arc<M>, updater: &Arc<U>, net: &Arc<ManageNetwork>) -> Self {
|
||||||
Self::with_fetch(client, miner, net)
|
Self::with_fetch(client, miner, updater, net)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M, F> ParitySetClient<C, M, F> where
|
impl<C, M, U, F> ParitySetClient<C, M, U, F> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService,
|
M: MinerService,
|
||||||
|
U: UpdateService,
|
||||||
F: Fetch,
|
F: Fetch,
|
||||||
{
|
{
|
||||||
/// Creates new `ParitySetClient` with default `FetchClient`.
|
/// Creates new `ParitySetClient` with default `FetchClient`.
|
||||||
pub fn with_fetch(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self {
|
pub fn with_fetch(client: &Arc<C>, miner: &Arc<M>, updater: &Arc<U>, net: &Arc<ManageNetwork>) -> Self {
|
||||||
ParitySetClient {
|
ParitySetClient {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
miner: Arc::downgrade(miner),
|
miner: Arc::downgrade(miner),
|
||||||
|
updater: Arc::downgrade(updater),
|
||||||
net: Arc::downgrade(net),
|
net: Arc::downgrade(net),
|
||||||
fetch: Mutex::new(F::default()),
|
fetch: Mutex::new(F::default()),
|
||||||
}
|
}
|
||||||
@ -75,9 +81,10 @@ impl<C, M, F> ParitySetClient<C, M, F> where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M, F> ParitySet for ParitySetClient<C, M, F> where
|
impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
||||||
C: MiningBlockChainClient + 'static,
|
C: MiningBlockChainClient + 'static,
|
||||||
M: MinerService + 'static,
|
M: MinerService + 'static,
|
||||||
|
U: UpdateService + 'static,
|
||||||
F: Fetch + 'static,
|
F: Fetch + 'static,
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -230,4 +237,16 @@ impl<C, M, F> ParitySet for ParitySetClient<C, M, F> where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
let updater = take_weak!(self.updater);
|
||||||
|
Ok(updater.upgrade_ready().map(Into::into))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_upgrade(&self) -> Result<bool, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
let updater = take_weak!(self.updater);
|
||||||
|
Ok(updater.execute_upgrade())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,10 @@ mod sync_provider;
|
|||||||
mod miner_service;
|
mod miner_service;
|
||||||
mod fetch;
|
mod fetch;
|
||||||
mod snapshot_service;
|
mod snapshot_service;
|
||||||
|
mod update_service;
|
||||||
|
|
||||||
pub use self::sync_provider::{Config, TestSyncProvider};
|
pub use self::sync_provider::{Config, TestSyncProvider};
|
||||||
pub use self::miner_service::TestMinerService;
|
pub use self::miner_service::TestMinerService;
|
||||||
pub use self::fetch::TestFetch;
|
pub use self::fetch::TestFetch;
|
||||||
pub use self::snapshot_service::TestSnapshotService;
|
pub use self::snapshot_service::TestSnapshotService;
|
||||||
|
pub use self::update_service::TestUpdater;
|
97
rpc/src/v1/tests/helpers/update_service.rs
Normal file
97
rpc/src/v1/tests/helpers/update_service.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Test implementation of fetch client.
|
||||||
|
|
||||||
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
|
use semver::Version;
|
||||||
|
use updater::{Service as UpdateService, CapState, ReleaseInfo, VersionInfo, OperationsInfo, ReleaseTrack};
|
||||||
|
|
||||||
|
/// Test implementation of fetcher. Will always return the same file.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct TestUpdater {
|
||||||
|
updated: AtomicBool,
|
||||||
|
current_block: AtomicUsize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestUpdater {
|
||||||
|
/// Update the (faked) current block.
|
||||||
|
pub fn set_current_block(&self, n: usize) {
|
||||||
|
self.current_block.store(n, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the (faked) current block.
|
||||||
|
pub fn set_updated(&self, v: bool) {
|
||||||
|
self.updated.store(v, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UpdateService for TestUpdater {
|
||||||
|
fn capability(&self) -> CapState {
|
||||||
|
if self.updated.load(Ordering::Relaxed) {
|
||||||
|
CapState::Capable
|
||||||
|
} else {
|
||||||
|
if self.current_block.load(Ordering::Relaxed) < 15100 {
|
||||||
|
CapState::CapableUntil(15100)
|
||||||
|
} else {
|
||||||
|
CapState::IncapableSince(15100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upgrade_ready(&self) -> Option<ReleaseInfo> {
|
||||||
|
if self.updated.load(Ordering::Relaxed) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.info().map(|i| i.track)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_upgrade(&self) -> bool {
|
||||||
|
if self.updated.load(Ordering::Relaxed) {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
self.updated.store(true, Ordering::Relaxed);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version_info(&self) -> VersionInfo {
|
||||||
|
VersionInfo {
|
||||||
|
track: ReleaseTrack::Beta,
|
||||||
|
version: Version{major: 1, minor: 5, patch: 0, build: vec![], pre: vec![]},
|
||||||
|
hash: 150.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn info(&self) -> Option<OperationsInfo> {
|
||||||
|
Some(OperationsInfo {
|
||||||
|
fork: 15100,
|
||||||
|
this_fork: Some(15000),
|
||||||
|
track: ReleaseInfo {
|
||||||
|
version: VersionInfo {
|
||||||
|
track: ReleaseTrack::Beta,
|
||||||
|
version: Version{major: 1, minor: 5, patch: 1, build: vec![], pre: vec![]},
|
||||||
|
hash: 151.into(),
|
||||||
|
},
|
||||||
|
is_critical: true,
|
||||||
|
fork: 15100,
|
||||||
|
binary: Some(1510.into()),
|
||||||
|
},
|
||||||
|
minor: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -26,15 +26,16 @@ use ethstore::ethkey::{Generator, Random};
|
|||||||
use jsonrpc_core::{IoHandler, GenericIoHandler};
|
use jsonrpc_core::{IoHandler, GenericIoHandler};
|
||||||
use v1::{Parity, ParityClient};
|
use v1::{Parity, ParityClient};
|
||||||
use v1::helpers::{SignerService, NetworkSettings};
|
use v1::helpers::{SignerService, NetworkSettings};
|
||||||
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
|
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestUpdater};
|
||||||
use super::manage_network::TestManageNetwork;
|
use super::manage_network::TestManageNetwork;
|
||||||
|
|
||||||
pub type TestParityClient = ParityClient<TestBlockChainClient, TestMinerService, TestSyncProvider>;
|
pub type TestParityClient = ParityClient<TestBlockChainClient, TestMinerService, TestSyncProvider, TestUpdater>;
|
||||||
|
|
||||||
pub struct Dependencies {
|
pub struct Dependencies {
|
||||||
pub miner: Arc<TestMinerService>,
|
pub miner: Arc<TestMinerService>,
|
||||||
pub client: Arc<TestBlockChainClient>,
|
pub client: Arc<TestBlockChainClient>,
|
||||||
pub sync: Arc<TestSyncProvider>,
|
pub sync: Arc<TestSyncProvider>,
|
||||||
|
pub updater: Arc<TestUpdater>,
|
||||||
pub logger: Arc<RotatingLogger>,
|
pub logger: Arc<RotatingLogger>,
|
||||||
pub settings: Arc<NetworkSettings>,
|
pub settings: Arc<NetworkSettings>,
|
||||||
pub network: Arc<ManageNetwork>,
|
pub network: Arc<ManageNetwork>,
|
||||||
@ -52,6 +53,7 @@ impl Dependencies {
|
|||||||
network_id: 3,
|
network_id: 3,
|
||||||
num_peers: 120,
|
num_peers: 120,
|
||||||
})),
|
})),
|
||||||
|
updater: Arc::new(TestUpdater::default()),
|
||||||
logger: Arc::new(RotatingLogger::new("rpc=trace".to_owned())),
|
logger: Arc::new(RotatingLogger::new("rpc=trace".to_owned())),
|
||||||
settings: Arc::new(NetworkSettings {
|
settings: Arc::new(NetworkSettings {
|
||||||
name: "mynode".to_owned(),
|
name: "mynode".to_owned(),
|
||||||
@ -73,6 +75,7 @@ impl Dependencies {
|
|||||||
&self.client,
|
&self.client,
|
||||||
&self.miner,
|
&self.miner,
|
||||||
&self.sync,
|
&self.sync,
|
||||||
|
&self.updater,
|
||||||
&self.network,
|
&self.network,
|
||||||
&self.accounts,
|
&self.accounts,
|
||||||
self.logger.clone(),
|
self.logger.clone(),
|
||||||
@ -96,6 +99,48 @@ impl Dependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_consensus_capability() {
|
||||||
|
let deps = Dependencies::new();
|
||||||
|
let io = deps.default_client();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_consensusCapability", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":{"capableUntil":15100},"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
|
deps.updater.set_current_block(15101);
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_consensusCapability", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":{"incapableSince":15100},"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
|
deps.updater.set_updated(true);
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_consensusCapability", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":"capable","id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_version_info() {
|
||||||
|
let deps = Dependencies::new();
|
||||||
|
let io = deps.default_client();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_versionInfo", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":{"hash":"0x0000000000000000000000000000000000000096","track":"beta","version":{"major":1,"minor":5,"patch":0}},"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_releases_info() {
|
||||||
|
let deps = Dependencies::new();
|
||||||
|
let io = deps.default_client();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_releasesInfo", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":{"fork":15100,"minor":null,"this_fork":15000,"track":{"binary":"0x00000000000000000000000000000000000000000000000000000000000005e6","fork":15100,"is_critical":true,"version":{"hash":"0x0000000000000000000000000000000000000097","track":"beta","version":{"major":1,"minor":5,"patch":1}}}},"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_parity_extra_data() {
|
fn rpc_parity_extra_data() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
@ -196,12 +241,7 @@ fn rpc_parity_net_peers() {
|
|||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
|
||||||
let response = "{\"jsonrpc\":\"2.0\",\"result\":{\"active\":0,\"connected\":120,\"max\":50,\"peers\":[{\"caps\":[\"eth/62\",\"eth/63\"],\
|
let response = r#"{"jsonrpc":"2.0","result":{"active":0,"connected":120,"max":50,"peers":[{"caps":["eth/62","eth/63"],"id":"node1","name":"Parity/1","network":{"localAddress":"127.0.0.1:8888","remoteAddress":"127.0.0.1:7777"},"protocols":{"eth":{"difficulty":"0x28","head":"0000000000000000000000000000000000000000000000000000000000000032","version":62}}},{"caps":["eth/63","eth/64"],"id":null,"name":"Parity/2","network":{"localAddress":"127.0.0.1:3333","remoteAddress":"Handshake"},"protocols":{"eth":{"difficulty":null,"head":"000000000000000000000000000000000000000000000000000000000000003c","version":64}}}]},"id":1}"#;
|
||||||
\"id\":\"node1\",\"name\":\"Parity/1\",\"network\":{\"localAddress\":\"127.0.0.1:8888\",\"remoteAddress\":\"127.0.0.1:7777\"}\
|
|
||||||
,\"protocols\":{\"eth\":{\"difficulty\":\"0x28\",\"head\":\"0000000000000000000000000000000000000000000000000000000000000032\"\
|
|
||||||
,\"version\":62}}},{\"caps\":[\"eth/63\",\"eth/64\"],\"id\":null,\"name\":\"Parity/2\",\"network\":{\"localAddress\":\
|
|
||||||
\"127.0.0.1:3333\",\"remoteAddress\":\"Handshake\"},\"protocols\":{\"eth\":{\"difficulty\":null,\"head\":\
|
|
||||||
\"000000000000000000000000000000000000000000000000000000000000003c\",\"version\":64}}}]},\"id\":1}";
|
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ use ethsync::ManageNetwork;
|
|||||||
|
|
||||||
use jsonrpc_core::{IoHandler, GenericIoHandler};
|
use jsonrpc_core::{IoHandler, GenericIoHandler};
|
||||||
use v1::{ParitySet, ParitySetClient};
|
use v1::{ParitySet, ParitySetClient};
|
||||||
use v1::tests::helpers::{TestMinerService, TestFetch};
|
use v1::tests::helpers::{TestMinerService, TestFetch, TestUpdater};
|
||||||
use super::manage_network::TestManageNetwork;
|
use super::manage_network::TestManageNetwork;
|
||||||
|
|
||||||
fn miner_service() -> Arc<TestMinerService> {
|
fn miner_service() -> Arc<TestMinerService> {
|
||||||
@ -40,10 +40,52 @@ fn network_service() -> Arc<TestManageNetwork> {
|
|||||||
Arc::new(TestManageNetwork)
|
Arc::new(TestManageNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TestParitySetClient = ParitySetClient<TestBlockChainClient, TestMinerService, TestFetch>;
|
fn updater_service() -> Arc<TestUpdater> {
|
||||||
|
Arc::new(TestUpdater::default())
|
||||||
|
}
|
||||||
|
|
||||||
fn parity_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, net: &Arc<TestManageNetwork>) -> TestParitySetClient {
|
pub type TestParitySetClient = ParitySetClient<TestBlockChainClient, TestMinerService, TestUpdater, TestFetch>;
|
||||||
ParitySetClient::with_fetch(client, miner, &(net.clone() as Arc<ManageNetwork>))
|
|
||||||
|
fn parity_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, updater: &Arc<TestUpdater>, net: &Arc<TestManageNetwork>) -> TestParitySetClient {
|
||||||
|
ParitySetClient::with_fetch(client, miner, updater, &(net.clone() as Arc<ManageNetwork>))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_execute_upgrade() {
|
||||||
|
let miner = miner_service();
|
||||||
|
let client = client_service();
|
||||||
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
|
let io = IoHandler::new();
|
||||||
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_executeUpgrade", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_executeUpgrade", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_upgrade_ready() {
|
||||||
|
let miner = miner_service();
|
||||||
|
let client = client_service();
|
||||||
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
|
let io = IoHandler::new();
|
||||||
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_upgradeReady", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":{"binary":"0x00000000000000000000000000000000000000000000000000000000000005e6","fork":15100,"is_critical":true,"version":{"hash":"0x0000000000000000000000000000000000000097","track":"beta","version":{"major":1,"minor":5,"patch":1}}},"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
|
updater.set_updated(true);
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_upgradeReady", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -51,8 +93,9 @@ fn rpc_parity_set_min_gas_price() {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -66,8 +109,9 @@ fn rpc_parity_set_gas_floor_target() {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -81,8 +125,9 @@ fn rpc_parity_set_extra_data() {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -96,8 +141,9 @@ fn rpc_parity_set_author() {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -111,8 +157,9 @@ fn rpc_parity_set_engine_signer() {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setEngineSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setEngineSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -128,8 +175,9 @@ fn rpc_parity_set_transactions_limit() {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
@ -143,8 +191,9 @@ fn rpc_parity_set_hash_content() {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
|
let updater = updater_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &updater, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_hashContent", "params":["https://ethcore.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_hashContent", "params":["https://ethcore.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#;
|
||||||
|
@ -25,7 +25,8 @@ 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
|
BlockNumber, ConsensusCapability, VersionInfo,
|
||||||
|
OperationsInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
@ -157,5 +158,17 @@ build_rpc_trait! {
|
|||||||
/// Returns accounts information.
|
/// Returns accounts information.
|
||||||
#[rpc(name = "parity_accounts")]
|
#[rpc(name = "parity_accounts")]
|
||||||
fn accounts(&self) -> Result<BTreeMap<String, BTreeMap<String, String>>, Error>;
|
fn accounts(&self) -> Result<BTreeMap<String, BTreeMap<String, String>>, Error>;
|
||||||
|
|
||||||
|
/// Returns information on current consensus capability.
|
||||||
|
#[rpc(name = "parity_consensusCapability")]
|
||||||
|
fn consensus_capability(&self) -> Result<ConsensusCapability, Error>;
|
||||||
|
|
||||||
|
/// Get our version information in a nice object.
|
||||||
|
#[rpc(name = "parity_versionInfo")]
|
||||||
|
fn version_info(&self) -> Result<VersionInfo, Error>;
|
||||||
|
|
||||||
|
/// Get information concerning the latest releases if available.
|
||||||
|
#[rpc(name = "parity_releasesInfo")]
|
||||||
|
fn releases_info(&self) -> Result<Option<OperationsInfo>, Error>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use jsonrpc_macros::Ready;
|
use jsonrpc_macros::Ready;
|
||||||
|
|
||||||
use v1::types::{Bytes, H160, H256, U256};
|
use v1::types::{Bytes, H160, H256, U256, ReleaseInfo};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
@ -91,5 +91,13 @@ build_rpc_trait! {
|
|||||||
/// Hash a file content under given URL.
|
/// Hash a file content under given URL.
|
||||||
#[rpc(async, name = "parity_hashContent")]
|
#[rpc(async, name = "parity_hashContent")]
|
||||||
fn hash_content(&self, Ready<H256>, String);
|
fn hash_content(&self, Ready<H256>, String);
|
||||||
|
|
||||||
|
/// Is there a release ready for install?
|
||||||
|
#[rpc(name = "parity_upgradeReady")]
|
||||||
|
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>, Error>;
|
||||||
|
|
||||||
|
/// Execute a release which is ready according to upgrade_ready().
|
||||||
|
#[rpc(name = "parity_executeUpgrade")]
|
||||||
|
fn execute_upgrade(&self) -> Result<bool, Error>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
169
rpc/src/v1/types/consensus_status.rs
Normal file
169
rpc/src/v1/types/consensus_status.rs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use semver;
|
||||||
|
use v1::types::{H160, H256};
|
||||||
|
use updater::{self, CapState};
|
||||||
|
|
||||||
|
/// Capability info
|
||||||
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
|
pub enum ConsensusCapability {
|
||||||
|
/// Unknown.
|
||||||
|
#[serde(rename="unknown")]
|
||||||
|
Unknown,
|
||||||
|
/// Capable of consensus indefinitely.
|
||||||
|
#[serde(rename="capable")]
|
||||||
|
Capable,
|
||||||
|
/// Capable of consensus up until a definite block.
|
||||||
|
#[serde(rename="capableUntil")]
|
||||||
|
CapableUntil(u64),
|
||||||
|
/// Incapable of consensus since a particular block.
|
||||||
|
#[serde(rename="incapableSince")]
|
||||||
|
IncapableSince(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<ConsensusCapability> for CapState {
|
||||||
|
fn into(self) -> ConsensusCapability {
|
||||||
|
match self {
|
||||||
|
CapState::Unknown => ConsensusCapability::Unknown,
|
||||||
|
CapState::Capable => ConsensusCapability::Capable,
|
||||||
|
CapState::CapableUntil(n) => ConsensusCapability::CapableUntil(n),
|
||||||
|
CapState::IncapableSince(n) => ConsensusCapability::IncapableSince(n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A release's track.
|
||||||
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
|
pub enum ReleaseTrack {
|
||||||
|
/// Stable track.
|
||||||
|
#[serde(rename="stable")]
|
||||||
|
Stable,
|
||||||
|
/// Beta track.
|
||||||
|
#[serde(rename="beta")]
|
||||||
|
Beta,
|
||||||
|
/// Nightly track.
|
||||||
|
#[serde(rename="nightly")]
|
||||||
|
Nightly,
|
||||||
|
/// Testing track.
|
||||||
|
#[serde(rename="testing")]
|
||||||
|
Testing,
|
||||||
|
/// No known track.
|
||||||
|
#[serde(rename="null")]
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<ReleaseTrack> for updater::ReleaseTrack {
|
||||||
|
fn into(self) -> ReleaseTrack {
|
||||||
|
match self {
|
||||||
|
updater::ReleaseTrack::Stable => ReleaseTrack::Stable,
|
||||||
|
updater::ReleaseTrack::Beta => ReleaseTrack::Beta,
|
||||||
|
updater::ReleaseTrack::Nightly => ReleaseTrack::Nightly,
|
||||||
|
updater::ReleaseTrack::Testing => ReleaseTrack::Testing,
|
||||||
|
updater::ReleaseTrack::Unknown => ReleaseTrack::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Semantic version.
|
||||||
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
|
pub struct Version {
|
||||||
|
/// Major part.
|
||||||
|
major: u64,
|
||||||
|
/// Minor part.
|
||||||
|
minor: u64,
|
||||||
|
/// Patch part.
|
||||||
|
patch: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Version> for semver::Version {
|
||||||
|
fn into(self) -> Version {
|
||||||
|
Version {
|
||||||
|
major: self.major,
|
||||||
|
minor: self.minor,
|
||||||
|
patch: self.patch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Version information of a particular release.
|
||||||
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
|
pub struct VersionInfo {
|
||||||
|
/// The track on which it was released.
|
||||||
|
pub track: ReleaseTrack,
|
||||||
|
/// The version.
|
||||||
|
pub version: Version,
|
||||||
|
/// The (SHA1?) 160-bit hash of this build's code base.
|
||||||
|
pub hash: H160,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<VersionInfo> for updater::VersionInfo {
|
||||||
|
fn into(self) -> VersionInfo {
|
||||||
|
VersionInfo {
|
||||||
|
track: self.track.into(),
|
||||||
|
version: self.version.into(),
|
||||||
|
hash: self.hash.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information regarding a particular release of Parity
|
||||||
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
|
pub struct ReleaseInfo {
|
||||||
|
/// Information on the version.
|
||||||
|
pub version: VersionInfo,
|
||||||
|
/// Does this release contain critical security updates?
|
||||||
|
pub is_critical: bool,
|
||||||
|
/// The latest fork that this release can handle.
|
||||||
|
pub fork: u64,
|
||||||
|
/// Our platform's binary, if known.
|
||||||
|
pub binary: Option<H256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<ReleaseInfo> for updater::ReleaseInfo {
|
||||||
|
fn into(self) -> ReleaseInfo {
|
||||||
|
ReleaseInfo {
|
||||||
|
version: self.version.into(),
|
||||||
|
is_critical: self.is_critical,
|
||||||
|
fork: self.fork,
|
||||||
|
binary: self.binary.map(Into::into),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information on our operations environment.
|
||||||
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
|
pub struct OperationsInfo {
|
||||||
|
/// Our blockchain's latest fork.
|
||||||
|
pub fork: u64,
|
||||||
|
/// Last fork our client supports, if known.
|
||||||
|
pub this_fork: Option<u64>,
|
||||||
|
/// Information on our track's latest release.
|
||||||
|
pub track: ReleaseInfo,
|
||||||
|
/// Information on our minor version's latest release.
|
||||||
|
pub minor: Option<ReleaseInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<OperationsInfo> for updater::OperationsInfo {
|
||||||
|
fn into(self) -> OperationsInfo {
|
||||||
|
OperationsInfo {
|
||||||
|
fork: self.fork,
|
||||||
|
this_fork: self.this_fork,
|
||||||
|
track: self.track.into(),
|
||||||
|
minor: self.minor.map(Into::into),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@ mod trace_filter;
|
|||||||
mod uint;
|
mod uint;
|
||||||
mod work;
|
mod work;
|
||||||
mod histogram;
|
mod histogram;
|
||||||
|
mod consensus_status;
|
||||||
|
|
||||||
pub use self::bytes::Bytes;
|
pub use self::bytes::Bytes;
|
||||||
pub use self::block::{RichBlock, Block, BlockTransactions};
|
pub use self::block::{RichBlock, Block, BlockTransactions};
|
||||||
@ -58,3 +59,4 @@ pub use self::trace_filter::TraceFilter;
|
|||||||
pub use self::uint::{U128, U256};
|
pub use self::uint::{U128, U256};
|
||||||
pub use self::work::Work;
|
pub use self::work::Work;
|
||||||
pub use self::histogram::Histogram;
|
pub use self::histogram::Histogram;
|
||||||
|
pub use self::consensus_status::*;
|
@ -117,7 +117,7 @@ fn reject_transaction(
|
|||||||
|
|
||||||
// cmds
|
// cmds
|
||||||
|
|
||||||
pub fn cmd_signer_list(
|
pub fn signer_list(
|
||||||
signerport: u16, authfile: PathBuf
|
signerport: u16, authfile: PathBuf
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let addr = &format!("ws://127.0.0.1:{}", signerport);
|
let addr = &format!("ws://127.0.0.1:{}", signerport);
|
||||||
@ -127,7 +127,7 @@ pub fn cmd_signer_list(
|
|||||||
list_transactions(&mut signer)
|
list_transactions(&mut signer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cmd_signer_reject(
|
pub fn signer_reject(
|
||||||
id: Option<usize>, signerport: u16, authfile: PathBuf
|
id: Option<usize>, signerport: u16, authfile: PathBuf
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let id = try!(id.ok_or(format!("id required for signer reject")));
|
let id = try!(id.ok_or(format!("id required for signer reject")));
|
||||||
@ -138,7 +138,7 @@ pub fn cmd_signer_reject(
|
|||||||
reject_transaction(&mut signer, U256::from(id))
|
reject_transaction(&mut signer, U256::from(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cmd_signer_sign(
|
pub fn signer_sign(
|
||||||
id: Option<usize>,
|
id: Option<usize>,
|
||||||
pwfile: Option<PathBuf>,
|
pwfile: Option<PathBuf>,
|
||||||
signerport: u16,
|
signerport: u16,
|
||||||
|
222
scripts/contractABI.js
Normal file
222
scripts/contractABI.js
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user