Merge branch 'master' into pip-msg
This commit is contained in:
commit
8be41ad946
@ -1,8 +1,8 @@
|
|||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
- js-build
|
- js-build
|
||||||
- build
|
|
||||||
- push-release
|
- push-release
|
||||||
|
- build
|
||||||
variables:
|
variables:
|
||||||
GIT_DEPTH: "3"
|
GIT_DEPTH: "3"
|
||||||
SIMPLECOV: "true"
|
SIMPLECOV: "true"
|
||||||
@ -26,14 +26,14 @@ linux-stable:
|
|||||||
- cargo build -j $(nproc) --release -p ethstore
|
- cargo build -j $(nproc) --release -p ethstore
|
||||||
- cargo build -j $(nproc) --release -p ethkey
|
- cargo build -j $(nproc) --release -p ethkey
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
- strip target/release/evm
|
- strip target/release/parity-evm
|
||||||
- strip target/release/ethstore
|
- strip target/release/ethstore
|
||||||
- strip target/release/ethkey
|
- strip target/release/ethkey
|
||||||
- export SHA3=$(target/release/parity tools hash 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
|
||||||
- cp target/release/evm deb/usr/bin/evm
|
- cp target/release/parity-evm deb/usr/bin/parity-evm
|
||||||
- cp target/release/ethstore deb/usr/bin/ethstore
|
- cp target/release/ethstore deb/usr/bin/ethstore
|
||||||
- cp target/release/ethkey deb/usr/bin/ethkey
|
- cp target/release/ethkey deb/usr/bin/ethkey
|
||||||
- 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")
|
||||||
@ -55,9 +55,9 @@ linux-stable:
|
|||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- target/release/parity
|
- target/release/parity
|
||||||
- target/release/parity/evmbin
|
- target/release/parity-evm
|
||||||
- target/release/parity/ethstore
|
- target/release/ethstore
|
||||||
- target/release/parity/ethkey
|
- target/release/ethkey
|
||||||
name: "stable-x86_64-unknown-linux-gnu_parity"
|
name: "stable-x86_64-unknown-linux-gnu_parity"
|
||||||
linux-stable-debian:
|
linux-stable-debian:
|
||||||
stage: build
|
stage: build
|
||||||
@ -73,14 +73,14 @@ linux-stable-debian:
|
|||||||
- cargo build -j $(nproc) --release -p ethstore
|
- cargo build -j $(nproc) --release -p ethstore
|
||||||
- cargo build -j $(nproc) --release -p ethkey
|
- cargo build -j $(nproc) --release -p ethkey
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
- strip target/release/evm
|
- strip target/release/parity-evm
|
||||||
- strip target/release/ethstore
|
- strip target/release/ethstore
|
||||||
- strip target/release/ethkey
|
- strip target/release/ethkey
|
||||||
- export SHA3=$(target/release/parity tools hash 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
|
||||||
- cp target/release/evm deb/usr/bin/evm
|
- cp target/release/parity-evm deb/usr/bin/parity-evm
|
||||||
- cp target/release/ethstore deb/usr/bin/ethstore
|
- cp target/release/ethstore deb/usr/bin/ethstore
|
||||||
- cp target/release/ethkey deb/usr/bin/ethkey
|
- cp target/release/ethkey deb/usr/bin/ethkey
|
||||||
- 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")
|
||||||
@ -409,16 +409,16 @@ darwin:
|
|||||||
packagesbuild -v mac/Parity.pkgproj
|
packagesbuild -v mac/Parity.pkgproj
|
||||||
productsign --sign 'Developer ID Installer: PARITY TECHNOLOGIES LIMITED (P2PX3JU8FT)' target/release/Parity\ Ethereum.pkg target/release/Parity\ Ethereum-signed.pkg
|
productsign --sign 'Developer ID Installer: PARITY TECHNOLOGIES LIMITED (P2PX3JU8FT)' target/release/Parity\ Ethereum.pkg target/release/Parity\ Ethereum-signed.pkg
|
||||||
export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||||
mv target/release/Parity\ Ethereum-signed.pkg "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
mv target/release/Parity\ Ethereum-signed.pkg "parity-"$VER"-macos-installer.pkg"
|
||||||
md5sum "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg" >> "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5"
|
md5sum "parity-"$VER"-macos-installer.pkg" >> "parity-"$VER"-macos-installer.pkg.md5"
|
||||||
aws configure set aws_access_key_id $s3_key
|
aws configure set aws_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/$PLATFORM
|
aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/release/parity
|
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/release/parity
|
||||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
|
||||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-macos-installer.pkg" --body "parity-"$VER"-macos-installer.pkg"
|
||||||
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5"
|
aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity-"$VER"-macos-installer.pkg.md5" --body "parity-"$VER"-macos-installer.pkg.md5"
|
||||||
curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$PLATFORM
|
||||||
tags:
|
tags:
|
||||||
@ -460,9 +460,8 @@ windows:
|
|||||||
- zip win-installer.zip InstallParity.exe InstallParity.exe.md5
|
- zip win-installer.zip InstallParity.exe InstallParity.exe.md5
|
||||||
- md5sums win-installer.zip > win-installer.zip.md5
|
- md5sums win-installer.zip > win-installer.zip.md5
|
||||||
- cd ..\target\release\
|
- cd ..\target\release\
|
||||||
- md5sums parity.exe parity.pdb > parity.md5
|
|
||||||
- md5sums parity.exe > parity.exe.md5
|
- md5sums parity.exe > parity.exe.md5
|
||||||
- zip parity.zip parity.exe parity.pdb parity.md5
|
- zip parity.zip parity.exe parity.md5
|
||||||
- md5sums parity.zip > parity.zip.md5
|
- md5sums parity.zip > parity.zip.md5
|
||||||
- cd ..\..
|
- cd ..\..
|
||||||
- aws configure set aws_access_key_id %s3_key%
|
- aws configure set aws_access_key_id %s3_key%
|
||||||
@ -504,6 +503,19 @@ docker-build:
|
|||||||
- sh scripts/docker-build.sh $DOCKER_TAG
|
- sh scripts/docker-build.sh $DOCKER_TAG
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- docker
|
||||||
|
test-coverage:
|
||||||
|
stage: test
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
script:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- rm -rf target/*
|
||||||
|
- rm -rf js/.coverage
|
||||||
|
- scripts/cov.sh
|
||||||
|
# - COVERAGE=$(grep -Po 'covered":.*?[^\\]"' target/cov/index.json | grep "[0-9]*\.[0-9]" -o)
|
||||||
|
# - echo "Coverage:" $COVERAGE
|
||||||
|
tags:
|
||||||
|
- kcov
|
||||||
test-darwin:
|
test-darwin:
|
||||||
stage: test
|
stage: test
|
||||||
only:
|
only:
|
||||||
|
125
Cargo.lock
generated
125
Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
[root]
|
[root]
|
||||||
name = "parity"
|
name = "parity"
|
||||||
version = "1.6.0"
|
version = "1.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -29,9 +29,9 @@ dependencies = [
|
|||||||
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
||||||
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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 1.2.0 (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.7.0",
|
"parity-hash-fetch 1.7.0",
|
||||||
"parity-ipfs-api 1.7.0",
|
"parity-ipfs-api 1.7.0",
|
||||||
@ -44,6 +44,7 @@ dependencies = [
|
|||||||
"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.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -347,7 +348,7 @@ version = "0.5.6"
|
|||||||
source = "git+https://github.com/ethcore/rust-secp256k1#98ad9b9ecae44a563efdd64273bcebc6b4ed81c6"
|
source = "git+https://github.com/ethcore/rust-secp256k1#98ad9b9ecae44a563efdd64273bcebc6b4ed81c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (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)",
|
||||||
"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)",
|
||||||
@ -405,7 +406,7 @@ dependencies = [
|
|||||||
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lru-cache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lru-cache 0.1.0 (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 1.2.0 (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",
|
||||||
"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)",
|
||||||
@ -447,8 +448,8 @@ dependencies = [
|
|||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -621,10 +622,10 @@ dependencies = [
|
|||||||
"ethsync 1.7.0",
|
"ethsync 1.7.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"jsonrpc-ipc-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-ipc-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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)",
|
||||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
@ -667,7 +668,7 @@ dependencies = [
|
|||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.7.0",
|
||||||
"ethcore-rpc 1.7.0",
|
"ethcore-rpc 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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-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-ui 1.7.0",
|
"parity-ui 1.7.0",
|
||||||
@ -687,9 +688,9 @@ dependencies = [
|
|||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"jsonrpc-tcp-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-tcp-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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)",
|
||||||
@ -883,10 +884,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.35"
|
version = "0.3.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rayon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -933,7 +934,7 @@ name = "hidapi"
|
|||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "git+https://github.com/ethcore/hidapi-rs#9a127c1dca7e327e4fdd428406a76c9f5ef48563"
|
source = "git+https://github.com/ethcore/hidapi-rs#9a127c1dca7e327e4fdd428406a76c9f5ef48563"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1081,7 +1082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-core"
|
name = "jsonrpc-core"
|
||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (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)",
|
||||||
@ -1094,10 +1095,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-http-server"
|
name = "jsonrpc-http-server"
|
||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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)",
|
||||||
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1106,11 +1107,11 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-ipc-server"
|
name = "jsonrpc-ipc-server"
|
||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.3.0 (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)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1122,19 +1123,19 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-macros"
|
name = "jsonrpc-macros"
|
||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-tcp-server"
|
name = "jsonrpc-tcp-server"
|
||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"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)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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)",
|
||||||
"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)",
|
||||||
@ -1188,7 +1189,7 @@ name = "libusb-sys"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "git+https://github.com/ethcore/libusb-sys#c10b1180646c9dc3f23a9b6bb825abcd3b7487ce"
|
source = "git+https://github.com/ethcore/libusb-sys#c10b1180646c9dc3f23a9b6bb825abcd3b7487ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1252,7 +1253,7 @@ name = "miniz-sys"
|
|||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1387,7 +1388,7 @@ name = "nanomsg-sys"
|
|||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/ethcore/nanomsg.rs.git#c40fe442c9afaea5b38009a3d992ca044dcceb00"
|
source = "git+https://github.com/ethcore/nanomsg.rs.git#c40fe442c9afaea5b38009a3d992ca044dcceb00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1529,14 +1530,6 @@ name = "num-traits"
|
|||||||
version = "0.1.32"
|
version = "0.1.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num_cpus"
|
|
||||||
version = "0.2.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -1637,7 +1630,7 @@ dependencies = [
|
|||||||
"ethcore 1.7.0",
|
"ethcore 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
||||||
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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)",
|
||||||
"multihash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"multihash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.1.0",
|
"rlp 0.1.0",
|
||||||
@ -1674,7 +1667,7 @@ dependencies = [
|
|||||||
"ethcore-signer 1.7.0",
|
"ethcore-signer 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
||||||
"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)",
|
||||||
"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)",
|
||||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1703,7 +1696,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-precompiled"
|
name = "parity-ui-precompiled"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "git+https://github.com/ethcore/js-precompiled.git#9eef2b78d363560fe942062caaaa7f6b1d64dd17"
|
source = "git+https://github.com/ethcore/js-precompiled.git#547a5352d779bc7821a7a2ec14c6d480833aeabb"
|
||||||
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)",
|
||||||
]
|
]
|
||||||
@ -1874,11 +1867,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "0.4.2"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.2.0 (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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1946,7 +1940,7 @@ name = "rocksdb-sys"
|
|||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/ethcore/rust-rocksdb#64c63ccbe1f62c2e2b39262486f9ba813793af58"
|
source = "git+https://github.com/ethcore/rust-rocksdb#64c63ccbe1f62c2e2b39262486f9ba813793af58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2001,7 +1995,7 @@ name = "rust-crypto"
|
|||||||
version = "0.2.36"
|
version = "0.2.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (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)",
|
||||||
"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)",
|
||||||
@ -2021,6 +2015,14 @@ dependencies = [
|
|||||||
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schannel"
|
name = "schannel"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -2090,6 +2092,14 @@ dependencies = [
|
|||||||
"semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver-parser"
|
name = "semver-parser"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@ -2099,6 +2109,11 @@ dependencies = [
|
|||||||
"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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
@ -2153,7 +2168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "sha3"
|
name = "sha3"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2605,7 +2620,7 @@ dependencies = [
|
|||||||
"checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb"
|
"checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb"
|
||||||
"checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d"
|
"checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d"
|
||||||
"checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82"
|
"checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82"
|
||||||
"checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312"
|
"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
|
||||||
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
||||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||||
"checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1"
|
"checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1"
|
||||||
@ -2623,11 +2638,11 @@ dependencies = [
|
|||||||
"checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c"
|
"checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c"
|
||||||
"checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a"
|
"checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a"
|
||||||
"checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5"
|
"checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5"
|
||||||
"checksum jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
|
"checksum jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
||||||
"checksum jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
|
"checksum jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
||||||
"checksum jsonrpc-ipc-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
|
"checksum jsonrpc-ipc-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
||||||
"checksum jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
|
"checksum jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
||||||
"checksum jsonrpc-tcp-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
|
"checksum jsonrpc-tcp-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||||
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
||||||
@ -2669,7 +2684,6 @@ dependencies = [
|
|||||||
"checksum num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c"
|
"checksum num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c"
|
||||||
"checksum num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "48cdcc9ff4ae2a8296805ac15af88b3d88ce62128ded0cb74ffb63a587502a84"
|
"checksum num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "48cdcc9ff4ae2a8296805ac15af88b3d88ce62128ded0cb74ffb63a587502a84"
|
||||||
"checksum num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "51eab148f171aefad295f8cece636fc488b9b392ef544da31ea4b8ef6b9e9c39"
|
"checksum num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "51eab148f171aefad295f8cece636fc488b9b392ef544da31ea4b8ef6b9e9c39"
|
||||||
"checksum num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "51fedae97a05f7353612fe017ab705a37e6db8f4d67c5c6fe739a9e70d6eed09"
|
|
||||||
"checksum num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55aabf4e2d6271a2e4e4c0f2ea1f5b07cc589cc1a9e9213013b54a76678ca4f3"
|
"checksum num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55aabf4e2d6271a2e4e4c0f2ea1f5b07cc589cc1a9e9213013b54a76678ca4f3"
|
||||||
"checksum number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "084d05f4bf60621a9ac9bde941a410df548f4de9545f06e5ee9d3aef4b97cd77"
|
"checksum number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "084d05f4bf60621a9ac9bde941a410df548f4de9545f06e5ee9d3aef4b97cd77"
|
||||||
"checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1"
|
"checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1"
|
||||||
@ -2699,7 +2713,7 @@ dependencies = [
|
|||||||
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
|
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
|
||||||
"checksum quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6732e32663c9c271bfc7c1823486b471f18c47a2dbf87c066897b7b51afc83be"
|
"checksum quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6732e32663c9c271bfc7c1823486b471f18c47a2dbf87c066897b7b51afc83be"
|
||||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||||
"checksum rayon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "655df67c314c30fa3055a365eae276eb88aa4f3413a352a1ab32c1320eda41ea"
|
"checksum rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50c575b58c2b109e2fbc181820cbe177474f35610ff9e357dc75f6bac854ffbf"
|
||||||
"checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29"
|
"checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29"
|
||||||
"checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9"
|
"checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9"
|
||||||
"checksum reqwest 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bef9ed8fdfcc30947d6b774938dc0c3f369a474efe440df2c7f278180b2d2e6"
|
"checksum reqwest 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bef9ed8fdfcc30947d6b774938dc0c3f369a474efe440df2c7f278180b2d2e6"
|
||||||
@ -2712,6 +2726,7 @@ dependencies = [
|
|||||||
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||||
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
|
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
|
||||||
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
||||||
|
"checksum rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e114e275f7c9b5d50bb52b28f9aac1921209f02aa6077c8b255e21eefaf8ffa"
|
||||||
"checksum schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "167852e03fcd0029c3ddebb5afb0715b2996f6e262b2c2aceaa7cd84edd4b158"
|
"checksum schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "167852e03fcd0029c3ddebb5afb0715b2996f6e262b2c2aceaa7cd84edd4b158"
|
||||||
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
|
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
|
||||||
"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc"
|
"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc"
|
||||||
@ -2720,7 +2735,9 @@ dependencies = [
|
|||||||
"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 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2ff60ecdb19c255841c066cbfa5f8c2a4ada1eb3ae47c77ab6667128da71f5"
|
||||||
|
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
||||||
"checksum semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e88e43a5a74dd2a11707f9c21dfd4a423c66bd871df813227bb0a3e78f3a1ae9"
|
"checksum semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e88e43a5a74dd2a11707f9c21dfd4a423c66bd871df813227bb0a3e78f3a1ae9"
|
||||||
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
"checksum serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0ae9a3c8b07c09dbe43022486d55a18c629a0618d2241e49829aaef9b6d862f9"
|
"checksum serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0ae9a3c8b07c09dbe43022486d55a18c629a0618d2241e49829aaef9b6d862f9"
|
||||||
"checksum serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3172bf2940b975c0e4f6ab42a511c0a4407d4f46ccef87a9d3615db5c26fa96"
|
"checksum serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3172bf2940b975c0e4f6ab42a511c0a4407d4f46ccef87a9d3615db5c26fa96"
|
||||||
"checksum serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecc6e0379ca933ece58302d2d3034443f06fbf38fd535857c1dc516195cbc3bf"
|
"checksum serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecc6e0379ca933ece58302d2d3034443f06fbf38fd535857c1dc516195cbc3bf"
|
||||||
|
10
Cargo.toml
10
Cargo.toml
@ -1,9 +1,10 @@
|
|||||||
[package]
|
[package]
|
||||||
description = "Parity Ethereum client"
|
description = "Parity Ethereum client"
|
||||||
name = "parity"
|
name = "parity"
|
||||||
version = "1.6.0"
|
version = "1.7.0"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
@ -11,7 +12,7 @@ env_logger = "0.3"
|
|||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
docopt = "0.6"
|
docopt = "0.6"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
num_cpus = "0.2"
|
num_cpus = "1.2"
|
||||||
number_prefix = "0.2"
|
number_prefix = "0.2"
|
||||||
rpassword = "0.2.1"
|
rpassword = "0.2.1"
|
||||||
semver = "0.5"
|
semver = "0.5"
|
||||||
@ -25,7 +26,7 @@ app_dirs = "1.1.1"
|
|||||||
fdlimit = "0.1"
|
fdlimit = "0.1"
|
||||||
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
||||||
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git" }
|
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
||||||
ethsync = { path = "sync" }
|
ethsync = { path = "sync" }
|
||||||
ethcore = { path = "ethcore" }
|
ethcore = { path = "ethcore" }
|
||||||
ethcore-util = { path = "util" }
|
ethcore-util = { path = "util" }
|
||||||
@ -52,6 +53,9 @@ ethcore-dapps = { path = "dapps", optional = true }
|
|||||||
clippy = { version = "0.0.103", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
ethcore-secretstore = { path = "secret_store", optional = true }
|
ethcore-secretstore = { path = "secret_store", optional = true }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
rustc_version = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ethcore-ipc-tests = { path = "ipc/tests" }
|
ethcore-ipc-tests = { path = "ipc/tests" }
|
||||||
|
|
||||||
|
@ -14,25 +14,22 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
extern crate ethcore_ipc_codegen as codegen;
|
extern crate rustc_version;
|
||||||
|
|
||||||
use std::env;
|
const MIN_RUSTC_VERSION: &'static str = "1.15.1";
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
pub fn main() {
|
fn main() {
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let is = rustc_version::version().unwrap();
|
||||||
|
let required = MIN_RUSTC_VERSION.parse().unwrap();
|
||||||
|
assert!(is >= required, format!("
|
||||||
|
|
||||||
// ipc pass
|
It looks like you are compiling Parity with an old rustc compiler {}.
|
||||||
{
|
Parity requires version {}. Please update your compiler.
|
||||||
let src = Path::new("src/lib.rs.in");
|
If you use rustup, try this:
|
||||||
let dst = Path::new(&out_dir).join("lib.intermediate.rs.in");
|
|
||||||
codegen::expand(&src, &dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
// binary serialization pass
|
rustup update stable
|
||||||
{
|
|
||||||
let src = Path::new(&out_dir).join("lib.intermediate.rs.in");
|
and try building Parity again.
|
||||||
let dst = Path::new(&out_dir).join("lib.rs");
|
|
||||||
codegen::expand(&src, &dst);
|
", is, required));
|
||||||
}
|
|
||||||
}
|
}
|
@ -12,8 +12,8 @@ rand = "0.3"
|
|||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git" }
|
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
||||||
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git" }
|
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
||||||
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
||||||
unicase = "1.3"
|
unicase = "1.3"
|
||||||
url = "1.0"
|
url = "1.0"
|
||||||
|
@ -11,7 +11,8 @@ rustc_version = "0.1"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
parity-ui-dev = { path = "../../js", optional = true }
|
parity-ui-dev = { path = "../../js", optional = true }
|
||||||
parity-ui-precompiled = { git = "https://github.com/ethcore/js-precompiled.git", optional = true }
|
# This is managed by the js/scripts/release.sh script on CI - keep it in a single line
|
||||||
|
parity-ui-precompiled = { git = "https://github.com/ethcore/js-precompiled.git", optional = true, branch = "master" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
no-precompiled-js = ["parity-ui-dev"]
|
no-precompiled-js = ["parity-ui-dev"]
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
[package]
|
|
||||||
description = "Ethcore Database"
|
|
||||||
homepage = "http://parity.io"
|
|
||||||
license = "GPL-3.0"
|
|
||||||
name = "ethcore-db"
|
|
||||||
version = "1.7.0"
|
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
|
||||||
build = "build.rs"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
clippy = { version = "0.0.103", optional = true}
|
|
||||||
ethcore-devtools = { path = "../devtools" }
|
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
|
||||||
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
|
||||||
semver = "0.5"
|
|
||||||
ethcore-ipc-nano = { path = "../ipc/nano" }
|
|
||||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
|
||||||
crossbeam = "0.2"
|
|
||||||
ethcore-util = { path = "../util" }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
dev = ["clippy"]
|
|
@ -1,565 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Ethcore rocksdb ipc service
|
|
||||||
|
|
||||||
use traits::*;
|
|
||||||
use rocksdb::{DB, Writable, WriteBatch, IteratorMode, DBIterator, IndexType, Options, DBCompactionStyle, BlockBasedOptions, Direction};
|
|
||||||
use std::sync::{RwLock, Arc};
|
|
||||||
use std::convert::From;
|
|
||||||
use ipc::IpcConfig;
|
|
||||||
use std::mem;
|
|
||||||
use ipc::binary::BinaryConvertError;
|
|
||||||
use std::collections::{VecDeque, HashMap, BTreeMap};
|
|
||||||
|
|
||||||
enum WriteCacheEntry {
|
|
||||||
Remove,
|
|
||||||
Write(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WriteCache {
|
|
||||||
entries: HashMap<Vec<u8>, WriteCacheEntry>,
|
|
||||||
preferred_len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
const FLUSH_BATCH_SIZE: usize = 4096;
|
|
||||||
|
|
||||||
impl WriteCache {
|
|
||||||
fn new(cache_len: usize) -> WriteCache {
|
|
||||||
WriteCache {
|
|
||||||
entries: HashMap::new(),
|
|
||||||
preferred_len: cache_len,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&mut self, key: Vec<u8>, val: Vec<u8>) {
|
|
||||||
self.entries.insert(key, WriteCacheEntry::Write(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove(&mut self, key: Vec<u8>) {
|
|
||||||
self.entries.insert(key, WriteCacheEntry::Remove);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
|
|
||||||
self.entries.get(key).and_then(
|
|
||||||
|vec_ref| match vec_ref {
|
|
||||||
&WriteCacheEntry::Write(ref val) => Some(val.clone()),
|
|
||||||
&WriteCacheEntry::Remove => None
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// WriteCache should be locked for this
|
|
||||||
fn flush(&mut self, db: &DB, amount: usize) -> Result<(), Error> {
|
|
||||||
let batch = WriteBatch::new();
|
|
||||||
let mut removed_so_far = 0;
|
|
||||||
while removed_so_far < amount {
|
|
||||||
if self.entries.len() == 0 { break; }
|
|
||||||
let removed_key = {
|
|
||||||
let (key, cache_entry) = self.entries.iter().nth(0)
|
|
||||||
.expect("if entries.len == 0, we should have break in the loop, still we got here somehow");
|
|
||||||
|
|
||||||
match *cache_entry {
|
|
||||||
WriteCacheEntry::Write(ref val) => {
|
|
||||||
batch.put(&key, val)?;
|
|
||||||
},
|
|
||||||
WriteCacheEntry::Remove => {
|
|
||||||
batch.delete(&key)?;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
key.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
self.entries.remove(&removed_key);
|
|
||||||
|
|
||||||
removed_so_far = removed_so_far + 1;
|
|
||||||
}
|
|
||||||
if removed_so_far > 0 {
|
|
||||||
db.write(batch)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// flushes until cache is empty
|
|
||||||
fn flush_all(&mut self, db: &DB) -> Result<(), Error> {
|
|
||||||
while !self.is_empty() { self.flush(db, FLUSH_BATCH_SIZE)?; }
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
|
||||||
self.entries.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_shrink(&mut self, db: &DB) -> Result<(), Error> {
|
|
||||||
if self.entries.len() > self.preferred_len {
|
|
||||||
self.flush(db, FLUSH_BATCH_SIZE)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Database {
|
|
||||||
db: RwLock<Option<DB>>,
|
|
||||||
/// Iterators - dont't use between threads!
|
|
||||||
iterators: RwLock<BTreeMap<IteratorHandle, DBIterator>>,
|
|
||||||
write_cache: RwLock<WriteCache>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for Database {}
|
|
||||||
unsafe impl Sync for Database {}
|
|
||||||
|
|
||||||
impl Database {
|
|
||||||
pub fn new() -> Database {
|
|
||||||
Database {
|
|
||||||
db: RwLock::new(None),
|
|
||||||
iterators: RwLock::new(BTreeMap::new()),
|
|
||||||
write_cache: RwLock::new(WriteCache::new(DEFAULT_CACHE_LEN)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn flush(&self) -> Result<(), Error> {
|
|
||||||
let mut cache_lock = self.write_cache.write();
|
|
||||||
let db_lock = self.db.read();
|
|
||||||
if db_lock.is_none() { return Ok(()); }
|
|
||||||
let db = db_lock.as_ref().unwrap();
|
|
||||||
|
|
||||||
cache_lock.try_shrink(&db)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn flush_all(&self) -> Result<(), Error> {
|
|
||||||
let mut cache_lock = self.write_cache.write();
|
|
||||||
let db_lock = self.db.read();
|
|
||||||
if db_lock.is_none() { return Ok(()); }
|
|
||||||
let db = db_lock.as_ref().expect("we should have exited with Ok(()) on the previous step");
|
|
||||||
|
|
||||||
cache_lock.flush_all(&db)?;
|
|
||||||
Ok(())
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Database {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.flush().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ipc]
|
|
||||||
impl DatabaseService for Database {
|
|
||||||
fn open(&self, config: DatabaseConfig, path: String) -> Result<(), Error> {
|
|
||||||
let mut db = self.db.write();
|
|
||||||
if db.is_some() { return Err(Error::AlreadyOpen); }
|
|
||||||
|
|
||||||
let mut opts = Options::new();
|
|
||||||
opts.set_max_open_files(256);
|
|
||||||
opts.create_if_missing(true);
|
|
||||||
opts.set_use_fsync(false);
|
|
||||||
opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction);
|
|
||||||
if let Some(size) = config.prefix_size {
|
|
||||||
let mut block_opts = BlockBasedOptions::new();
|
|
||||||
block_opts.set_index_type(IndexType::HashSearch);
|
|
||||||
opts.set_block_based_table_factory(&block_opts);
|
|
||||||
opts.set_prefix_extractor_fixed_size(size);
|
|
||||||
}
|
|
||||||
*db = Some(DB::open(&opts, &path)?);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Opens database in the specified path with the default config
|
|
||||||
fn open_default(&self, path: String) -> Result<(), Error> {
|
|
||||||
self.open(DatabaseConfig::default(), path)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn close(&self) -> Result<(), Error> {
|
|
||||||
self.flush_all()?;
|
|
||||||
|
|
||||||
let mut db = self.db.write();
|
|
||||||
if db.is_none() { return Err(Error::IsClosed); }
|
|
||||||
|
|
||||||
*db = None;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> {
|
|
||||||
let mut cache_lock = self.write_cache.write();
|
|
||||||
cache_lock.write(key.to_vec(), value.to_vec());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete(&self, key: &[u8]) -> Result<(), Error> {
|
|
||||||
let mut cache_lock = self.write_cache.write();
|
|
||||||
cache_lock.remove(key.to_vec());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, transaction: DBTransaction) -> Result<(), Error> {
|
|
||||||
let mut cache_lock = self.write_cache.write();
|
|
||||||
|
|
||||||
let mut writes = transaction.writes.borrow_mut();
|
|
||||||
for kv in writes.drain(..) {
|
|
||||||
cache_lock.write(kv.key, kv.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut removes = transaction.removes.borrow_mut();
|
|
||||||
for k in removes.drain(..) {
|
|
||||||
cache_lock.remove(k);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
|
|
||||||
{
|
|
||||||
let key_vec = key.to_vec();
|
|
||||||
let cache_hit = self.write_cache.read().get(&key_vec);
|
|
||||||
|
|
||||||
if cache_hit.is_some() {
|
|
||||||
return Ok(Some(cache_hit.expect("cache_hit.is_some() = true, still there is none somehow here")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let db_lock = self.db.read();
|
|
||||||
let db = db_lock.as_ref().ok_or(Error::IsClosed)?;
|
|
||||||
|
|
||||||
match db.get(key)? {
|
|
||||||
Some(db_vec) => {
|
|
||||||
Ok(Some(db_vec.to_vec()))
|
|
||||||
},
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_by_prefix(&self, prefix: &[u8]) -> Result<Option<Vec<u8>>, Error> {
|
|
||||||
let db_lock = self.db.read();
|
|
||||||
let db = db_lock.as_ref().ok_or(Error::IsClosed)?;
|
|
||||||
|
|
||||||
let mut iter = db.iterator(IteratorMode::From(prefix, Direction::Forward));
|
|
||||||
match iter.next() {
|
|
||||||
// TODO: use prefix_same_as_start read option (not availabele in C API currently)
|
|
||||||
Some((k, v)) => if k[0 .. prefix.len()] == prefix[..] { Ok(Some(v.to_vec())) } else { Ok(None) },
|
|
||||||
_ => Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_empty(&self) -> Result<bool, Error> {
|
|
||||||
let db_lock = self.db.read();
|
|
||||||
let db = db_lock.as_ref().ok_or(Error::IsClosed)?;
|
|
||||||
|
|
||||||
Ok(db.iterator(IteratorMode::Start).next().is_none())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn iter(&self) -> Result<IteratorHandle, Error> {
|
|
||||||
let db_lock = self.db.read();
|
|
||||||
let db = db_lock.as_ref().ok_or(Error::IsClosed)?;
|
|
||||||
|
|
||||||
let mut iterators = self.iterators.write();
|
|
||||||
let next_iterator = iterators.keys().last().unwrap_or(&0) + 1;
|
|
||||||
iterators.insert(next_iterator, db.iterator(IteratorMode::Start));
|
|
||||||
Ok(next_iterator)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn iter_next(&self, handle: IteratorHandle) -> Option<KeyValue> {
|
|
||||||
let mut iterators = self.iterators.write();
|
|
||||||
let mut iterator = match iterators.get_mut(&handle) {
|
|
||||||
Some(some_iterator) => some_iterator,
|
|
||||||
None => { return None; },
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator.next().and_then(|(some_key, some_val)| {
|
|
||||||
Some(KeyValue {
|
|
||||||
key: some_key.to_vec(),
|
|
||||||
value: some_val.to_vec(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dispose_iter(&self, handle: IteratorHandle) -> Result<(), Error> {
|
|
||||||
let mut iterators = self.iterators.write();
|
|
||||||
iterators.remove(&handle);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO : put proper at compile-time
|
|
||||||
impl IpcConfig for Database {}
|
|
||||||
|
|
||||||
/// Database iterator
|
|
||||||
pub struct DatabaseIterator {
|
|
||||||
client: Arc<DatabaseClient<::nanomsg::Socket>>,
|
|
||||||
handle: IteratorHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for DatabaseIterator {
|
|
||||||
type Item = (Vec<u8>, Vec<u8>);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.client.iter_next(self.handle).and_then(|kv| Some((kv.key, kv.value)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for DatabaseIterator {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.client.dispose_iter(self.handle).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
|
|
||||||
use super::Database;
|
|
||||||
use traits::*;
|
|
||||||
use devtools::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_be_created() {
|
|
||||||
let db = Database::new();
|
|
||||||
assert!(db.is_empty().is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_be_open_empty() {
|
|
||||||
let db = Database::new();
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
db.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
|
|
||||||
assert!(db.is_empty().is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_store_key() {
|
|
||||||
let db = Database::new();
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
db.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
|
|
||||||
db.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
|
|
||||||
db.flush_all().unwrap();
|
|
||||||
assert!(!db.is_empty().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_retrieve() {
|
|
||||||
let db = Database::new();
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
db.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
db.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
|
|
||||||
db.close().unwrap();
|
|
||||||
|
|
||||||
db.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
assert_eq!(db.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod write_cache_tests {
|
|
||||||
use super::Database;
|
|
||||||
use traits::*;
|
|
||||||
use devtools::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cache_write_flush() {
|
|
||||||
let db = Database::new();
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
|
|
||||||
db.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
db.put("100500".as_bytes(), "1".as_bytes()).unwrap();
|
|
||||||
db.delete("100500".as_bytes()).unwrap();
|
|
||||||
db.flush_all().unwrap();
|
|
||||||
|
|
||||||
let val = db.get("100500".as_bytes()).unwrap();
|
|
||||||
assert!(val.is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod client_tests {
|
|
||||||
use super::{DatabaseClient, Database};
|
|
||||||
use traits::*;
|
|
||||||
use devtools::*;
|
|
||||||
use nanoipc;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{Ordering, AtomicBool};
|
|
||||||
use crossbeam;
|
|
||||||
use run_worker;
|
|
||||||
|
|
||||||
fn init_worker(addr: &str) -> nanoipc::Worker<Database> {
|
|
||||||
let mut worker = nanoipc::Worker::<Database>::new(&Arc::new(Database::new()));
|
|
||||||
worker.add_duplex(addr).unwrap();
|
|
||||||
worker
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_call_handshake() {
|
|
||||||
let url = "ipc:///tmp/parity-db-ipc-test-10.ipc";
|
|
||||||
let worker_should_exit = Arc::new(AtomicBool::new(false));
|
|
||||||
let worker_is_ready = Arc::new(AtomicBool::new(false));
|
|
||||||
let c_worker_should_exit = worker_should_exit.clone();
|
|
||||||
let c_worker_is_ready = worker_is_ready.clone();
|
|
||||||
|
|
||||||
::std::thread::spawn(move || {
|
|
||||||
let mut worker = init_worker(url);
|
|
||||||
while !c_worker_should_exit.load(Ordering::Relaxed) {
|
|
||||||
worker.poll();
|
|
||||||
c_worker_is_ready.store(true, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
while !worker_is_ready.load(Ordering::Relaxed) { }
|
|
||||||
let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap();
|
|
||||||
|
|
||||||
let hs = client.handshake();
|
|
||||||
|
|
||||||
worker_should_exit.store(true, Ordering::Relaxed);
|
|
||||||
assert!(hs.is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_open_db() {
|
|
||||||
let url = "ipc:///tmp/parity-db-ipc-test-20.ipc";
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
|
|
||||||
let worker_should_exit = Arc::new(AtomicBool::new(false));
|
|
||||||
let worker_is_ready = Arc::new(AtomicBool::new(false));
|
|
||||||
let c_worker_should_exit = worker_should_exit.clone();
|
|
||||||
let c_worker_is_ready = worker_is_ready.clone();
|
|
||||||
|
|
||||||
::std::thread::spawn(move || {
|
|
||||||
let mut worker = init_worker(url);
|
|
||||||
while !c_worker_should_exit.load(Ordering::Relaxed) {
|
|
||||||
worker.poll();
|
|
||||||
c_worker_is_ready.store(true, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
while !worker_is_ready.load(Ordering::Relaxed) { }
|
|
||||||
let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap();
|
|
||||||
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
assert!(client.is_empty().unwrap());
|
|
||||||
worker_should_exit.store(true, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_put() {
|
|
||||||
let url = "ipc:///tmp/parity-db-ipc-test-30.ipc";
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
|
|
||||||
crossbeam::scope(move |scope| {
|
|
||||||
let stop = Arc::new(AtomicBool::new(false));
|
|
||||||
run_worker(scope, stop.clone(), url);
|
|
||||||
let client = nanoipc::generic_client::<DatabaseClient<_>>(url).unwrap();
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
|
|
||||||
client.close().unwrap();
|
|
||||||
|
|
||||||
stop.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_put_and_read() {
|
|
||||||
let url = "ipc:///tmp/parity-db-ipc-test-40.ipc";
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
|
|
||||||
crossbeam::scope(move |scope| {
|
|
||||||
let stop = Arc::new(AtomicBool::new(false));
|
|
||||||
run_worker(scope, stop.clone(), url);
|
|
||||||
let client = nanoipc::generic_client::<DatabaseClient<_>>(url).unwrap();
|
|
||||||
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
|
|
||||||
client.close().unwrap();
|
|
||||||
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
assert_eq!(client.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
|
|
||||||
|
|
||||||
stop.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_read_empty() {
|
|
||||||
let url = "ipc:///tmp/parity-db-ipc-test-45.ipc";
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
|
|
||||||
crossbeam::scope(move |scope| {
|
|
||||||
let stop = Arc::new(AtomicBool::new(false));
|
|
||||||
run_worker(scope, stop.clone(), url);
|
|
||||||
let client = nanoipc::generic_client::<DatabaseClient<_>>(url).unwrap();
|
|
||||||
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
assert!(client.get("xxx".as_bytes()).unwrap().is_none());
|
|
||||||
|
|
||||||
stop.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_commit_client_transaction() {
|
|
||||||
let url = "ipc:///tmp/parity-db-ipc-test-60.ipc";
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
|
|
||||||
crossbeam::scope(move |scope| {
|
|
||||||
let stop = Arc::new(AtomicBool::new(false));
|
|
||||||
run_worker(scope, stop.clone(), url);
|
|
||||||
let client = nanoipc::generic_client::<DatabaseClient<_>>(url).unwrap();
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
|
|
||||||
let transaction = DBTransaction::new();
|
|
||||||
transaction.put("xxx".as_bytes(), "1".as_bytes());
|
|
||||||
client.write(transaction).unwrap();
|
|
||||||
|
|
||||||
client.close().unwrap();
|
|
||||||
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
assert_eq!(client.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
|
|
||||||
|
|
||||||
stop.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn key_write_read_ipc() {
|
|
||||||
let url = "ipc:///tmp/parity-db-ipc-test-70.ipc";
|
|
||||||
let path = RandomTempPath::create_dir();
|
|
||||||
|
|
||||||
crossbeam::scope(|scope| {
|
|
||||||
let stop = StopGuard::new();
|
|
||||||
run_worker(&scope, stop.share(), url);
|
|
||||||
|
|
||||||
let client = nanoipc::generic_client::<DatabaseClient<_>>(url).unwrap();
|
|
||||||
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
let mut batch = Vec::new();
|
|
||||||
for _ in 0..100 {
|
|
||||||
batch.push((random_str(256).as_bytes().to_vec(), random_str(256).as_bytes().to_vec()));
|
|
||||||
batch.push((random_str(256).as_bytes().to_vec(), random_str(2048).as_bytes().to_vec()));
|
|
||||||
batch.push((random_str(2048).as_bytes().to_vec(), random_str(2048).as_bytes().to_vec()));
|
|
||||||
batch.push((random_str(2048).as_bytes().to_vec(), random_str(256).as_bytes().to_vec()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for &(ref k, ref v) in batch.iter() {
|
|
||||||
client.put(k, v).unwrap();
|
|
||||||
}
|
|
||||||
client.close().unwrap();
|
|
||||||
|
|
||||||
client.open_default(path.as_str().to_owned()).unwrap();
|
|
||||||
for &(ref k, ref v) in batch.iter() {
|
|
||||||
assert_eq!(v, &client.get(k).unwrap().unwrap());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
extern crate ethcore_ipc as ipc;
|
|
||||||
extern crate rocksdb;
|
|
||||||
extern crate ethcore_devtools as devtools;
|
|
||||||
extern crate semver;
|
|
||||||
extern crate ethcore_ipc_nano as nanoipc;
|
|
||||||
extern crate nanomsg;
|
|
||||||
extern crate crossbeam;
|
|
||||||
extern crate ethcore_util as util;
|
|
||||||
|
|
||||||
pub mod database;
|
|
||||||
pub mod traits;
|
|
||||||
|
|
||||||
pub use traits::{DatabaseService, DBTransaction, Error};
|
|
||||||
pub use database::{Database, DatabaseClient, DatabaseIterator};
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::*;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub type DatabaseNanoClient = DatabaseClient<::nanomsg::Socket>;
|
|
||||||
pub type DatabaseConnection = nanoipc::GuardedSocket<DatabaseNanoClient>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ServiceError {
|
|
||||||
Io(std::io::Error),
|
|
||||||
Socket(nanoipc::SocketError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::convert::From<std::io::Error> for ServiceError {
|
|
||||||
fn from(io_error: std::io::Error) -> ServiceError { ServiceError::Io(io_error) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::convert::From<nanoipc::SocketError> for ServiceError {
|
|
||||||
fn from(socket_error: nanoipc::SocketError) -> ServiceError { ServiceError::Socket(socket_error) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blocks_service_url(db_path: &str) -> Result<String, std::io::Error> {
|
|
||||||
let mut path = PathBuf::from(db_path);
|
|
||||||
::std::fs::create_dir_all(db_path)?;
|
|
||||||
path.push("blocks.ipc");
|
|
||||||
Ok(format!("ipc://{}", path.to_str().unwrap()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extras_service_url(db_path: &str) -> Result<String, ::std::io::Error> {
|
|
||||||
let mut path = PathBuf::from(db_path);
|
|
||||||
::std::fs::create_dir_all(db_path)?;
|
|
||||||
path.push("extras.ipc");
|
|
||||||
Ok(format!("ipc://{}", path.to_str().unwrap()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blocks_client(db_path: &str) -> Result<DatabaseConnection, ServiceError> {
|
|
||||||
let url = blocks_service_url(db_path)?;
|
|
||||||
let client = nanoipc::generic_client::<DatabaseClient<_>>(&url)?;
|
|
||||||
Ok(client)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extras_client(db_path: &str) -> Result<DatabaseConnection, ServiceError> {
|
|
||||||
let url = extras_service_url(db_path)?;
|
|
||||||
let client = nanoipc::generic_client::<DatabaseClient<_>>(&url)?;
|
|
||||||
Ok(client)
|
|
||||||
}
|
|
||||||
|
|
||||||
// for tests
|
|
||||||
pub fn run_worker(scope: &crossbeam::Scope, stop: Arc<AtomicBool>, socket_path: &str) {
|
|
||||||
let socket_path = socket_path.to_owned();
|
|
||||||
scope.spawn(move || {
|
|
||||||
let mut worker = nanoipc::Worker::new(&Arc::new(Database::new()));
|
|
||||||
worker.add_reqrep(&socket_path).unwrap();
|
|
||||||
while !stop.load(Ordering::Relaxed) {
|
|
||||||
worker.poll();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
135
db/src/traits.rs
135
db/src/traits.rs
@ -1,135 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Ethcore database trait
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
pub type IteratorHandle = u32;
|
|
||||||
|
|
||||||
pub const DEFAULT_CACHE_LEN: usize = 12288;
|
|
||||||
|
|
||||||
#[derive(Binary)]
|
|
||||||
pub struct KeyValue {
|
|
||||||
pub key: Vec<u8>,
|
|
||||||
pub value: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Binary)]
|
|
||||||
pub enum Error {
|
|
||||||
AlreadyOpen,
|
|
||||||
IsClosed,
|
|
||||||
RocksDb(String),
|
|
||||||
TransactionUnknown,
|
|
||||||
IteratorUnknown,
|
|
||||||
UncommitedTransactions,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for Error {
|
|
||||||
fn from(s: String) -> Error {
|
|
||||||
Error::RocksDb(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Database configuration
|
|
||||||
#[derive(Binary)]
|
|
||||||
pub struct DatabaseConfig {
|
|
||||||
/// Optional prefix size in bytes. Allows lookup by partial key.
|
|
||||||
pub prefix_size: Option<usize>,
|
|
||||||
/// write cache length
|
|
||||||
pub cache: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for DatabaseConfig {
|
|
||||||
fn default() -> DatabaseConfig {
|
|
||||||
DatabaseConfig {
|
|
||||||
prefix_size: None,
|
|
||||||
cache: DEFAULT_CACHE_LEN,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DatabaseConfig {
|
|
||||||
fn with_prefix(prefix: usize) -> DatabaseConfig {
|
|
||||||
DatabaseConfig {
|
|
||||||
prefix_size: Some(prefix),
|
|
||||||
cache: DEFAULT_CACHE_LEN,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait DatabaseService : Sized {
|
|
||||||
/// Opens database in the specified path
|
|
||||||
fn open(&self, config: DatabaseConfig, path: String) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Opens database in the specified path with the default config
|
|
||||||
fn open_default(&self, path: String) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Closes database
|
|
||||||
fn close(&self) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten.
|
|
||||||
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Delete value by key.
|
|
||||||
fn delete(&self, key: &[u8]) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Get value by key.
|
|
||||||
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error>;
|
|
||||||
|
|
||||||
/// Get value by partial key. Prefix size should match configured prefix size.
|
|
||||||
fn get_by_prefix(&self, prefix: &[u8]) -> Result<Option<Vec<u8>>, Error>;
|
|
||||||
|
|
||||||
/// Check if there is anything in the database.
|
|
||||||
fn is_empty(&self) -> Result<bool, Error>;
|
|
||||||
|
|
||||||
/// Get handle to iterate through keys
|
|
||||||
fn iter(&self) -> Result<IteratorHandle, Error>;
|
|
||||||
|
|
||||||
/// Next key-value for the the given iterator
|
|
||||||
fn iter_next(&self, iterator: IteratorHandle) -> Option<KeyValue>;
|
|
||||||
|
|
||||||
/// Dispose iteration that is no longer needed
|
|
||||||
fn dispose_iter(&self, handle: IteratorHandle) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Write client transaction
|
|
||||||
fn write(&self, transaction: DBTransaction) -> Result<(), Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Binary)]
|
|
||||||
pub struct DBTransaction {
|
|
||||||
pub writes: RefCell<Vec<KeyValue>>,
|
|
||||||
pub removes: RefCell<Vec<Vec<u8>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DBTransaction {
|
|
||||||
pub fn new() -> DBTransaction {
|
|
||||||
DBTransaction {
|
|
||||||
writes: RefCell::new(Vec::new()),
|
|
||||||
removes: RefCell::new(Vec::new()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn put(&self, key: &[u8], value: &[u8]) {
|
|
||||||
let mut brw = self.writes.borrow_mut();
|
|
||||||
brw.push(KeyValue { key: key.to_vec(), value: value.to_vec() });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete(&self, key: &[u8]) {
|
|
||||||
let mut brw = self.removes.borrow_mut();
|
|
||||||
brw.push(key.to_vec());
|
|
||||||
}
|
|
||||||
}
|
|
3
docker/hub/README.md
Normal file
3
docker/hub/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Usage
|
||||||
|
|
||||||
|
```docker build --build-arg BUILD_TAG=branch_or_tag_name --no-cache=true --tag ethcore/parity:branch_or_tag_name .```
|
@ -15,7 +15,7 @@ log = "0.3"
|
|||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
rust-crypto = "0.2.34"
|
rust-crypto = "0.2.34"
|
||||||
num_cpus = "0.2"
|
num_cpus = "1.2"
|
||||||
crossbeam = "0.2.9"
|
crossbeam = "0.2.9"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
bloomchain = "0.1"
|
bloomchain = "0.1"
|
||||||
|
@ -373,7 +373,7 @@ pub fn write_announcement(announcement: &Announcement) -> Vec<u8> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::request_credits::FlowParams;
|
use super::super::request_credits::FlowParams;
|
||||||
use util::{U256, H256, FixedHash};
|
use util::{U256, H256};
|
||||||
use rlp::{RlpStream, Stream ,UntrustedRlp, View};
|
use rlp::{RlpStream, Stream ,UntrustedRlp, View};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -256,7 +256,7 @@ impl TransactionProof {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::{MemoryDB, Address, H256, FixedHash};
|
use util::{MemoryDB, Address, H256};
|
||||||
use util::trie::{Trie, TrieMut, SecTrieDB, SecTrieDBMut};
|
use util::trie::{Trie, TrieMut, SecTrieDB, SecTrieDBMut};
|
||||||
use util::trie::recorder::Recorder;
|
use util::trie::recorder::Recorder;
|
||||||
|
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
"params": {
|
"params": {
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x2A"
|
"networkID" : "0x2A",
|
||||||
|
"validateReceipts" : false
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -139,6 +139,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
|
"eip98Transition": "0x7fffffffffffffff",
|
||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
|
@ -23,7 +23,7 @@ use self::stores::{AddressBook, DappsSettingsStore, NewDappsPolicy};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use util::{FixedHash, RwLock};
|
use util::{RwLock};
|
||||||
use ethstore::{SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore,
|
use ethstore::{SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore,
|
||||||
random_string, SecretVaultRef, StoreAccountRef};
|
random_string, SecretVaultRef, StoreAccountRef};
|
||||||
use ethstore::dir::MemoryDirectory;
|
use ethstore::dir::MemoryDirectory;
|
||||||
@ -152,7 +152,7 @@ impl AccountProvider {
|
|||||||
manager.set_key_path(if settings.hardware_wallet_classic_key { KeyPath::EthereumClassic } else { KeyPath::Ethereum });
|
manager.set_key_path(if settings.hardware_wallet_classic_key { KeyPath::EthereumClassic } else { KeyPath::Ethereum });
|
||||||
hardware_store = Some(manager)
|
hardware_store = Some(manager)
|
||||||
},
|
},
|
||||||
Err(e) => warn!("Error initializing hardware wallets: {}", e),
|
Err(e) => debug!("Error initializing hardware wallets: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AccountProvider {
|
AccountProvider {
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Evm input params.
|
//! Evm input params.
|
||||||
use util::{Address, Bytes, Uint, U256};
|
use util::{Address, Bytes, Uint, U256};
|
||||||
use util::hash::{H256, FixedHash};
|
use util::hash::{H256};
|
||||||
use util::sha3::{Hashable, SHA3_EMPTY};
|
use util::sha3::{Hashable, SHA3_EMPTY};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use types::executed::CallType;
|
use types::executed::CallType;
|
||||||
|
@ -21,7 +21,7 @@ use std::sync::Arc;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, Decoder, DecoderError, View, Stream};
|
use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, Decoder, DecoderError, View, Stream};
|
||||||
use util::{Bytes, Address, Uint, FixedHash, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RLP};
|
use util::{Bytes, Address, Uint, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RLP};
|
||||||
use util::error::{Mismatch, OutOfBounds};
|
use util::error::{Mismatch, OutOfBounds};
|
||||||
|
|
||||||
use basic_types::{LogBloom, Seal};
|
use basic_types::{LogBloom, Seal};
|
||||||
@ -553,7 +553,6 @@ pub fn enact(
|
|||||||
b.set_extra_data(header.extra_data().clone()).unwrap_or_else(|e| warn!("Couldn't set extradata: {}. Ignoring.", e));
|
b.set_extra_data(header.extra_data().clone()).unwrap_or_else(|e| warn!("Couldn't set extradata: {}. Ignoring.", e));
|
||||||
b.set_uncles_hash(header.uncles_hash().clone());
|
b.set_uncles_hash(header.uncles_hash().clone());
|
||||||
b.set_transactions_root(header.transactions_root().clone());
|
b.set_transactions_root(header.transactions_root().clone());
|
||||||
b.set_receipts_root(header.receipts_root().clone());
|
|
||||||
|
|
||||||
push_transactions(&mut b, transactions)?;
|
push_transactions(&mut b, transactions)?;
|
||||||
for u in uncles {
|
for u in uncles {
|
||||||
@ -618,7 +617,6 @@ mod tests {
|
|||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use views::BlockView;
|
use views::BlockView;
|
||||||
use util::Address;
|
use util::Address;
|
||||||
use util::hash::FixedHash;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use crypto::sha2::Sha256 as Sha256Digest;
|
|||||||
use crypto::ripemd160::Ripemd160 as Ripemd160Digest;
|
use crypto::ripemd160::Ripemd160 as Ripemd160Digest;
|
||||||
use crypto::digest::Digest;
|
use crypto::digest::Digest;
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use util::{U256, H256, Hashable, FixedHash, BytesRef};
|
use util::{U256, H256, Hashable, BytesRef};
|
||||||
use ethkey::{Signature, recover as ec_recover};
|
use ethkey::{Signature, recover as ec_recover};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ use time::precise_time_ns;
|
|||||||
// util
|
// util
|
||||||
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, MutexGuard, Hashable};
|
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, MutexGuard, Hashable};
|
||||||
use util::{journaldb, DBValue, TrieFactory, Trie};
|
use util::{journaldb, DBValue, TrieFactory, Trie};
|
||||||
use util::{U256, H256, Address, H2048, Uint, FixedHash};
|
use util::{U256, H256, Address, H2048, Uint};
|
||||||
use util::trie::TrieSpec;
|
use util::trie::TrieSpec;
|
||||||
use util::kvdb::*;
|
use util::kvdb::*;
|
||||||
|
|
||||||
@ -151,8 +151,9 @@ pub struct Client {
|
|||||||
factories: Factories,
|
factories: Factories,
|
||||||
history: u64,
|
history: u64,
|
||||||
rng: Mutex<OsRng>,
|
rng: Mutex<OsRng>,
|
||||||
on_mode_change: Mutex<Option<Box<FnMut(&Mode) + 'static + Send>>>,
|
on_user_defaults_change: Mutex<Option<Box<FnMut(Option<Mode>) + 'static + Send>>>,
|
||||||
registrar: Mutex<Option<Registry>>,
|
registrar: Mutex<Option<Registry>>,
|
||||||
|
exit_handler: Mutex<Option<Box<Fn(bool, Option<String>) + 'static + Send>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
@ -240,8 +241,9 @@ impl Client {
|
|||||||
factories: factories,
|
factories: factories,
|
||||||
history: history,
|
history: history,
|
||||||
rng: Mutex::new(OsRng::new().map_err(::util::UtilError::StdIo)?),
|
rng: Mutex::new(OsRng::new().map_err(::util::UtilError::StdIo)?),
|
||||||
on_mode_change: Mutex::new(None),
|
on_user_defaults_change: Mutex::new(None),
|
||||||
registrar: Mutex::new(None),
|
registrar: Mutex::new(None),
|
||||||
|
exit_handler: Mutex::new(None),
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -276,6 +278,11 @@ impl Client {
|
|||||||
self.notify.write().push(Arc::downgrade(&target));
|
self.notify.write().push(Arc::downgrade(&target));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set a closure to call when we want to restart the client
|
||||||
|
pub fn set_exit_handler<F>(&self, f: F) where F: Fn(bool, Option<String>) + 'static + Send {
|
||||||
|
*self.exit_handler.lock() = Some(Box::new(f));
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns engine reference.
|
/// Returns engine reference.
|
||||||
pub fn engine(&self) -> &Engine {
|
pub fn engine(&self) -> &Engine {
|
||||||
&*self.engine
|
&*self.engine
|
||||||
@ -294,9 +301,9 @@ impl Client {
|
|||||||
self.registrar.lock()
|
self.registrar.lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register an action to be done if a mode change happens.
|
/// Register an action to be done if a mode/spec_name change happens.
|
||||||
pub fn on_mode_change<F>(&self, f: F) where F: 'static + FnMut(&Mode) + Send {
|
pub fn on_user_defaults_change<F>(&self, f: F) where F: 'static + FnMut(Option<Mode>) + Send {
|
||||||
*self.on_mode_change.lock() = Some(Box::new(f));
|
*self.on_user_defaults_change.lock() = Some(Box::new(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush the block import queue.
|
/// Flush the block import queue.
|
||||||
@ -386,7 +393,7 @@ impl Client {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Final Verification
|
// Final Verification
|
||||||
if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header()) {
|
if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header(), self.engine().params().validate_receipts) {
|
||||||
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
@ -651,7 +658,6 @@ impl Client {
|
|||||||
self.miner.clone()
|
self.miner.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Replace io channel. Useful for testing.
|
/// Replace io channel. Useful for testing.
|
||||||
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
|
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
|
||||||
*self.io_channel.lock() = io_channel;
|
*self.io_channel.lock() = io_channel;
|
||||||
@ -1030,9 +1036,9 @@ impl BlockChainClient for Client {
|
|||||||
let mut mode = self.mode.lock();
|
let mut mode = self.mode.lock();
|
||||||
*mode = new_mode.clone().into();
|
*mode = new_mode.clone().into();
|
||||||
trace!(target: "mode", "Mode now {:?}", &*mode);
|
trace!(target: "mode", "Mode now {:?}", &*mode);
|
||||||
if let Some(ref mut f) = *self.on_mode_change.lock() {
|
if let Some(ref mut f) = *self.on_user_defaults_change.lock() {
|
||||||
trace!(target: "mode", "Making callback...");
|
trace!(target: "mode", "Making callback...");
|
||||||
f(&*mode)
|
f(Some((&*mode).clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match new_mode {
|
match new_mode {
|
||||||
@ -1042,6 +1048,22 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn spec_name(&self) -> String {
|
||||||
|
self.config.spec_name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_spec_name(&self, new_spec_name: String) {
|
||||||
|
trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name);
|
||||||
|
if !self.enabled.load(AtomicOrdering::Relaxed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(ref h) = *self.exit_handler.lock() {
|
||||||
|
(*h)(true, Some(new_spec_name));
|
||||||
|
} else {
|
||||||
|
warn!("Not hypervised; cannot change chain.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn best_block_header(&self) -> encoded::Header {
|
fn best_block_header(&self) -> encoded::Header {
|
||||||
self.chain.read().best_block_header()
|
self.chain.read().best_block_header()
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,8 @@ pub struct ClientConfig {
|
|||||||
pub db_wal: bool,
|
pub db_wal: bool,
|
||||||
/// Operating mode
|
/// Operating mode
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
|
/// The chain spec name
|
||||||
|
pub spec_name: String,
|
||||||
/// Type of block verifier used by client.
|
/// Type of block verifier used by client.
|
||||||
pub verifier_type: VerifierType,
|
pub verifier_type: VerifierType,
|
||||||
/// State db cache-size.
|
/// State db cache-size.
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
// 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 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};
|
||||||
|
|
||||||
@ -23,8 +22,6 @@ use util::trie::TrieError;
|
|||||||
/// Client configuration errors.
|
/// Client configuration errors.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// TraceDB configuration error.
|
|
||||||
Trace(TraceError),
|
|
||||||
/// TrieDB-related error.
|
/// TrieDB-related error.
|
||||||
Trie(TrieError),
|
Trie(TrieError),
|
||||||
/// Database error
|
/// Database error
|
||||||
@ -33,12 +30,6 @@ pub enum Error {
|
|||||||
Util(UtilError),
|
Util(UtilError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TraceError> for Error {
|
|
||||||
fn from(err: TraceError) -> Self {
|
|
||||||
Error::Trace(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<TrieError> for Error {
|
impl From<TrieError> for Error {
|
||||||
fn from(err: TrieError) -> Self {
|
fn from(err: TrieError) -> Self {
|
||||||
Error::Trie(err)
|
Error::Trie(err)
|
||||||
@ -60,7 +51,6 @@ impl<E> From<Box<E>> for Error where Error: From<E> {
|
|||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Trace(ref err) => write!(f, "{}", err),
|
|
||||||
Error::Trie(ref err) => write!(f, "{}", err),
|
Error::Trie(ref err) => write!(f, "{}", err),
|
||||||
Error::Util(ref err) => write!(f, "{}", err),
|
Error::Util(ref err) => write!(f, "{}", err),
|
||||||
Error::Database(ref s) => write!(f, "Database error: {}", s),
|
Error::Database(ref s) => write!(f, "Database error: {}", s),
|
||||||
|
@ -5,7 +5,7 @@ use std::string::String;
|
|||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use {util, ethabi};
|
use {util, ethabi};
|
||||||
use util::{FixedHash, Uint};
|
use util::{Uint};
|
||||||
|
|
||||||
pub struct Registry {
|
pub struct Registry {
|
||||||
contract: ethabi::Contract,
|
contract: ethabi::Contract,
|
||||||
@ -22,7 +22,7 @@ impl Registry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) }
|
fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) }
|
||||||
|
|
||||||
/// Auto-generated from: `{"constant":true,"inputs":[{"name":"_data","type":"address"}],"name":"canReverse","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}`
|
/// Auto-generated from: `{"constant":true,"inputs":[{"name":"_data","type":"address"}],"name":"canReverse","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}`
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn can_reverse(&self, _data: &util::Address) -> Result<bool, String>
|
pub fn can_reverse(&self, _data: &util::Address) -> Result<bool, String>
|
||||||
@ -45,7 +45,7 @@ impl Registry {
|
|||||||
vec![ethabi::Token::Address(_new.clone().0)]
|
vec![ethabi::Token::Address(_new.clone().0)]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +318,7 @@ impl Registry {
|
|||||||
vec![]
|
vec![]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,6 +722,10 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
|
|
||||||
fn set_mode(&self, _: Mode) { unimplemented!(); }
|
fn set_mode(&self, _: Mode) { unimplemented!(); }
|
||||||
|
|
||||||
|
fn spec_name(&self) -> String { "foundation".into() }
|
||||||
|
|
||||||
|
fn set_spec_name(&self, _: String) { unimplemented!(); }
|
||||||
|
|
||||||
fn disable(&self) { unimplemented!(); }
|
fn disable(&self) { unimplemented!(); }
|
||||||
|
|
||||||
fn pruning_info(&self) -> PruningInfo {
|
fn pruning_info(&self) -> PruningInfo {
|
||||||
|
@ -242,6 +242,12 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// Set the mode.
|
/// Set the mode.
|
||||||
fn set_mode(&self, mode: Mode);
|
fn set_mode(&self, mode: Mode);
|
||||||
|
|
||||||
|
/// Get the chain spec name.
|
||||||
|
fn spec_name(&self) -> String;
|
||||||
|
|
||||||
|
/// Set the chain via a spec name.
|
||||||
|
fn set_spec_name(&self, spec_name: String);
|
||||||
|
|
||||||
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
/// 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.
|
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
||||||
fn disable(&self);
|
fn disable(&self);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! Tendermint specific parameters.
|
//! Tendermint specific parameters.
|
||||||
|
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use util::{U256, Uint, Address, FixedHash};
|
use util::{U256, Uint, Address};
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
use super::super::transition::Timeouts;
|
use super::super::transition::Timeouts;
|
||||||
use super::Step;
|
use super::Step;
|
||||||
|
@ -92,7 +92,7 @@ mod provider {
|
|||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use {util, ethabi};
|
use {util, ethabi};
|
||||||
use util::{FixedHash, Uint};
|
use util::{Uint};
|
||||||
|
|
||||||
pub struct Contract {
|
pub struct Contract {
|
||||||
contract: ethabi::Contract,
|
contract: ethabi::Contract,
|
||||||
@ -108,7 +108,7 @@ mod provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) }
|
fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) }
|
||||||
|
|
||||||
/// Auto-generated from: `{"constant":false,"inputs":[{"name":"validator","type":"address"}],"name":"reportMalicious","outputs":[],"payable":false,"type":"function"}`
|
/// Auto-generated from: `{"constant":false,"inputs":[{"name":"validator","type":"address"}],"name":"reportMalicious","outputs":[],"payable":false,"type":"function"}`
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn report_malicious(&self, validator: &util::Address) -> Result<(), String> {
|
pub fn report_malicious(&self, validator: &util::Address) -> Result<(), String> {
|
||||||
@ -117,7 +117,7 @@ mod provider {
|
|||||||
vec![ethabi::Token::Address(validator.clone().0)]
|
vec![ethabi::Token::Address(validator.clone().0)]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ mod provider {
|
|||||||
vec![ethabi::Token::Address(validator.clone().0)]
|
vec![ethabi::Token::Address(validator.clone().0)]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ mod tests {
|
|||||||
assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()));
|
assert!(vc.contains(&last_hash, &Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()));
|
||||||
assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap()));
|
assert!(vc.contains(&last_hash, &Address::from_str("82a978b3f5962a5b0957d9ee9eef472ee55b42f1").unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reports_validators() {
|
fn reports_validators() {
|
||||||
let tap = Arc::new(AccountProvider::transient_provider());
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
@ -173,12 +173,12 @@ mod tests {
|
|||||||
|
|
||||||
client.miner().set_engine_signer(v1, "".into()).unwrap();
|
client.miner().set_engine_signer(v1, "".into()).unwrap();
|
||||||
let mut header = Header::default();
|
let mut header = Header::default();
|
||||||
let seal = vec![encode(&5u8).to_vec(), encode(&(&H520::default() as &[u8])).to_vec()];
|
let seal = vec![encode(&5u8).to_vec(), encode(&(&H520::default() as &[u8])).to_vec()];
|
||||||
header.set_seal(seal);
|
header.set_seal(seal);
|
||||||
header.set_author(v1);
|
header.set_author(v1);
|
||||||
header.set_number(2);
|
header.set_number(2);
|
||||||
header.set_parent_hash(client.chain_info().best_block_hash);
|
header.set_parent_hash(client.chain_info().best_block_hash);
|
||||||
|
|
||||||
// `reportBenign` when the designated proposer releases block from the future (bad clock).
|
// `reportBenign` when the designated proposer releases block from the future (bad clock).
|
||||||
assert!(client.engine().verify_block_family(&header, &header, None).is_err());
|
assert!(client.engine().verify_block_family(&header, &header, None).is_err());
|
||||||
// Seal a block.
|
// Seal a block.
|
||||||
|
@ -509,7 +509,7 @@ mod tests {
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::{H256, U256, U512, Address, Uint, FixedHash, FromHex, FromStr};
|
use util::{H256, U256, U512, Address, Uint, FromHex, FromStr};
|
||||||
use util::bytes::BytesRef;
|
use util::bytes::BytesRef;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use action_params::{ActionParams, ActionValue};
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use util::Bytes;
|
use util::Bytes;
|
||||||
use util::{Address, FixedHash, H256};
|
use util::{Address, H256};
|
||||||
use util::kvdb::Database;
|
use util::kvdb::Database;
|
||||||
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
|
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
|
||||||
use util::sha3::Hashable;
|
use util::sha3::Hashable;
|
||||||
|
@ -24,7 +24,7 @@ use views::HeaderView;
|
|||||||
use bloom_journal::Bloom;
|
use bloom_journal::Bloom;
|
||||||
use util::migration::{Error, Migration, Progress, Batch, Config};
|
use util::migration::{Error, Migration, Progress, Batch, Config};
|
||||||
use util::journaldb;
|
use util::journaldb;
|
||||||
use util::{H256, FixedHash, Trie};
|
use util::{H256, Trie};
|
||||||
use util::{Database, DBTransaction};
|
use util::{Database, DBTransaction};
|
||||||
|
|
||||||
/// Account bloom upgrade routine. If bloom already present, does nothing.
|
/// Account bloom upgrade routine. If bloom already present, does nothing.
|
||||||
|
@ -90,6 +90,8 @@ pub struct MinerOptions {
|
|||||||
pub reseal_on_own_tx: bool,
|
pub reseal_on_own_tx: bool,
|
||||||
/// Minimum period between transaction-inspired reseals.
|
/// Minimum period between transaction-inspired reseals.
|
||||||
pub reseal_min_period: Duration,
|
pub reseal_min_period: Duration,
|
||||||
|
/// Maximum period between blocks (enables force sealing after that).
|
||||||
|
pub reseal_max_period: Duration,
|
||||||
/// Maximum amount of gas to bother considering for block insertion.
|
/// Maximum amount of gas to bother considering for block insertion.
|
||||||
pub tx_gas_limit: U256,
|
pub tx_gas_limit: U256,
|
||||||
/// Maximum size of the transaction queue.
|
/// Maximum size of the transaction queue.
|
||||||
@ -123,6 +125,7 @@ impl Default for MinerOptions {
|
|||||||
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
|
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
|
||||||
pending_set: PendingSet::AlwaysQueue,
|
pending_set: PendingSet::AlwaysQueue,
|
||||||
reseal_min_period: Duration::from_secs(2),
|
reseal_min_period: Duration::from_secs(2),
|
||||||
|
reseal_max_period: Duration::from_secs(120),
|
||||||
work_queue_size: 20,
|
work_queue_size: 20,
|
||||||
enable_resubmission: true,
|
enable_resubmission: true,
|
||||||
tx_queue_banning: Banning::Disabled,
|
tx_queue_banning: Banning::Disabled,
|
||||||
@ -212,6 +215,7 @@ pub struct Miner {
|
|||||||
transaction_queue: Arc<Mutex<BanningTransactionQueue>>,
|
transaction_queue: Arc<Mutex<BanningTransactionQueue>>,
|
||||||
sealing_work: Mutex<SealingWork>,
|
sealing_work: Mutex<SealingWork>,
|
||||||
next_allowed_reseal: Mutex<Instant>,
|
next_allowed_reseal: Mutex<Instant>,
|
||||||
|
next_mandatory_reseal: RwLock<Instant>,
|
||||||
sealing_block_last_request: Mutex<u64>,
|
sealing_block_last_request: Mutex<u64>,
|
||||||
// for sealing...
|
// for sealing...
|
||||||
options: MinerOptions,
|
options: MinerOptions,
|
||||||
@ -268,6 +272,7 @@ impl Miner {
|
|||||||
Miner {
|
Miner {
|
||||||
transaction_queue: Arc::new(Mutex::new(txq)),
|
transaction_queue: Arc::new(Mutex::new(txq)),
|
||||||
next_allowed_reseal: Mutex::new(Instant::now()),
|
next_allowed_reseal: Mutex::new(Instant::now()),
|
||||||
|
next_mandatory_reseal: RwLock::new(Instant::now() + options.reseal_max_period),
|
||||||
sealing_block_last_request: Mutex::new(0),
|
sealing_block_last_request: Mutex::new(0),
|
||||||
sealing_work: Mutex::new(SealingWork{
|
sealing_work: Mutex::new(SealingWork{
|
||||||
queue: UsingQueue::new(options.work_queue_size),
|
queue: UsingQueue::new(options.work_queue_size),
|
||||||
@ -298,7 +303,9 @@ impl Miner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn forced_sealing(&self) -> bool {
|
fn forced_sealing(&self) -> bool {
|
||||||
self.options.force_sealing || !self.options.new_work_notify.is_empty()
|
self.options.force_sealing
|
||||||
|
|| !self.options.new_work_notify.is_empty()
|
||||||
|
|| Instant::now() > *self.next_mandatory_reseal.read()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all pending block states
|
/// Clear all pending block states
|
||||||
@ -482,6 +489,7 @@ impl Miner {
|
|||||||
// Save proposal for later seal submission and broadcast it.
|
// Save proposal for later seal submission and broadcast it.
|
||||||
Seal::Proposal(seal) => {
|
Seal::Proposal(seal) => {
|
||||||
trace!(target: "miner", "Received a Proposal seal.");
|
trace!(target: "miner", "Received a Proposal seal.");
|
||||||
|
*self.next_mandatory_reseal.write() = Instant::now() + self.options.reseal_max_period;
|
||||||
{
|
{
|
||||||
let mut sealing_work = self.sealing_work.lock();
|
let mut sealing_work = self.sealing_work.lock();
|
||||||
sealing_work.queue.push(block.clone());
|
sealing_work.queue.push(block.clone());
|
||||||
@ -497,7 +505,8 @@ impl Miner {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
// Directly import a regular sealed block.
|
// Directly import a regular sealed block.
|
||||||
Seal::Regular(seal) =>
|
Seal::Regular(seal) => {
|
||||||
|
*self.next_mandatory_reseal.write() = Instant::now() + self.options.reseal_max_period;
|
||||||
block
|
block
|
||||||
.lock()
|
.lock()
|
||||||
.seal(&*self.engine, seal)
|
.seal(&*self.engine, seal)
|
||||||
@ -505,7 +514,8 @@ impl Miner {
|
|||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
warn!("ERROR: seal failed when given internally generated seal: {}", e);
|
warn!("ERROR: seal failed when given internally generated seal: {}", e);
|
||||||
false
|
false
|
||||||
}),
|
})
|
||||||
|
},
|
||||||
Seal::None => false,
|
Seal::None => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1290,6 +1300,7 @@ mod tests {
|
|||||||
reseal_on_external_tx: false,
|
reseal_on_external_tx: false,
|
||||||
reseal_on_own_tx: true,
|
reseal_on_own_tx: true,
|
||||||
reseal_min_period: Duration::from_secs(5),
|
reseal_min_period: Duration::from_secs(5),
|
||||||
|
reseal_max_period: Duration::from_secs(120),
|
||||||
tx_gas_limit: !U256::zero(),
|
tx_gas_limit: !U256::zero(),
|
||||||
tx_queue_size: 1024,
|
tx_queue_size: 1024,
|
||||||
tx_queue_gas_limit: GasLimit::None,
|
tx_queue_gas_limit: GasLimit::None,
|
||||||
|
@ -62,12 +62,12 @@ mod provider {
|
|||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use {util, ethabi};
|
use {util, ethabi};
|
||||||
use util::{FixedHash, Uint};
|
use util::{Uint};
|
||||||
|
|
||||||
pub struct Contract {
|
pub struct Contract {
|
||||||
contract: ethabi::Contract,
|
contract: ethabi::Contract,
|
||||||
address: util::Address,
|
address: util::Address,
|
||||||
|
|
||||||
}
|
}
|
||||||
impl Contract {
|
impl Contract {
|
||||||
pub fn new(address: util::Address) -> Self
|
pub fn new(address: util::Address) -> Self
|
||||||
@ -75,11 +75,11 @@ mod provider {
|
|||||||
Contract {
|
Contract {
|
||||||
contract: ethabi::Contract::new(ethabi::Interface::load(b"[{\"constant\":false,\"inputs\":[{\"name\":\"_new\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"certify\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"},{\"name\":\"_field\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"delegate\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"},{\"name\":\"_field\",\"type\":\"string\"}],\"name\":\"getUint\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_new\",\"type\":\"address\"}],\"name\":\"setDelegate\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"certified\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"},{\"name\":\"_field\",\"type\":\"string\"}],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"}]").expect("JSON is autogenerated; qed")),
|
contract: ethabi::Contract::new(ethabi::Interface::load(b"[{\"constant\":false,\"inputs\":[{\"name\":\"_new\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"certify\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"},{\"name\":\"_field\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"revoke\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"delegate\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"},{\"name\":\"_field\",\"type\":\"string\"}],\"name\":\"getUint\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_new\",\"type\":\"address\"}],\"name\":\"setDelegate\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"certified\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_who\",\"type\":\"address\"},{\"name\":\"_field\",\"type\":\"string\"}],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"}]").expect("JSON is autogenerated; qed")),
|
||||||
address: address,
|
address: address,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) }
|
fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) }
|
||||||
|
|
||||||
/// Auto-generated from: `{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"}`
|
/// Auto-generated from: `{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"}`
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn set_owner<F>(&self, do_call: &F, _new: &util::Address) -> Result<(), String>
|
pub fn set_owner<F>(&self, do_call: &F, _new: &util::Address) -> Result<(), String>
|
||||||
@ -89,7 +89,7 @@ mod provider {
|
|||||||
vec![ethabi::Token::Address(_new.clone().0)]
|
vec![ethabi::Token::Address(_new.clone().0)]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ mod provider {
|
|||||||
vec![ethabi::Token::Address(_who.clone().0)]
|
vec![ethabi::Token::Address(_who.clone().0)]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ mod provider {
|
|||||||
vec![ethabi::Token::Address(_who.clone().0)]
|
vec![ethabi::Token::Address(_who.clone().0)]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ mod provider {
|
|||||||
vec![ethabi::Token::Address(_new.clone().0)]
|
vec![ethabi::Token::Address(_new.clone().0)]
|
||||||
).map_err(Self::as_string)?;
|
).map_err(Self::as_string)?;
|
||||||
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
call.decode_output((do_call)(self.address.clone(), data)?).map_err(Self::as_string)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ use std::sync::{Arc, Weak};
|
|||||||
use std::net::{SocketAddr, AddrParseError};
|
use std::net::{SocketAddr, AddrParseError};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use util::{H256, U256, FixedHash, H64, clean_0x};
|
use util::{H256, U256, H64, clean_0x};
|
||||||
use ethereum::ethash::Ethash;
|
use ethereum::ethash::Ethash;
|
||||||
use ethash::SeedHashCompute;
|
use ethash::SeedHashCompute;
|
||||||
use util::Mutex;
|
use util::Mutex;
|
||||||
|
@ -485,7 +485,7 @@ pub struct AccountDetails {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Transactions with `gas > (gas_limit + gas_limit * Factor(in percents))` are not imported to the queue.
|
/// Transactions with `gas > (gas_limit + gas_limit * Factor(in percents))` are not imported to the queue.
|
||||||
const GAS_LIMIT_HYSTERESIS: usize = 10; // (100/GAS_LIMIT_HYSTERESIS) %
|
const GAS_LIMIT_HYSTERESIS: usize = 200; // (100/GAS_LIMIT_HYSTERESIS) %
|
||||||
|
|
||||||
/// Describes the strategy used to prioritize transactions in the queue.
|
/// Describes the strategy used to prioritize transactions in the queue.
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
||||||
@ -1867,7 +1867,7 @@ pub mod test {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded {
|
assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded {
|
||||||
limit: U256::from(55_000), // Should be 110% of set_gas_limit
|
limit: U256::from(50_250), // Should be 100.5% of set_gas_limit
|
||||||
got: gas,
|
got: gas,
|
||||||
});
|
});
|
||||||
let stats = txq.status();
|
let stats = txq.status();
|
||||||
|
@ -20,7 +20,7 @@ use account_db::{AccountDB, AccountDBMut};
|
|||||||
use basic_account::BasicAccount;
|
use basic_account::BasicAccount;
|
||||||
use snapshot::Error;
|
use snapshot::Error;
|
||||||
|
|
||||||
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY, SHA3_NULL_RLP};
|
use util::{U256, H256, Bytes, HashDB, SHA3_EMPTY, SHA3_NULL_RLP};
|
||||||
use util::trie::{TrieDB, Trie};
|
use util::trie::{TrieDB, Trie};
|
||||||
use rlp::{RlpStream, Stream, UntrustedRlp, View};
|
use rlp::{RlpStream, Stream, UntrustedRlp, View};
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ mod tests {
|
|||||||
use snapshot::tests::helpers::fill_storage;
|
use snapshot::tests::helpers::fill_storage;
|
||||||
|
|
||||||
use util::sha3::{SHA3_EMPTY, SHA3_NULL_RLP};
|
use util::sha3::{SHA3_EMPTY, SHA3_NULL_RLP};
|
||||||
use util::{Address, FixedHash, H256, HashDB, DBValue};
|
use util::{Address, H256, HashDB, DBValue};
|
||||||
use rlp::{UntrustedRlp, View};
|
use rlp::{UntrustedRlp, View};
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
@ -134,7 +134,7 @@ mod tests {
|
|||||||
use super::AbridgedBlock;
|
use super::AbridgedBlock;
|
||||||
use types::transaction::{Action, Transaction};
|
use types::transaction::{Action, Transaction};
|
||||||
|
|
||||||
use util::{Address, H256, FixedHash, U256, Bytes};
|
use util::{Address, H256, U256, Bytes};
|
||||||
|
|
||||||
fn encode_block(b: &Block) -> Bytes {
|
fn encode_block(b: &Block) -> Bytes {
|
||||||
b.rlp_bytes(::basic_types::Seal::With)
|
b.rlp_bytes(::basic_types::Seal::With)
|
||||||
|
@ -32,7 +32,7 @@ use views::BlockView;
|
|||||||
|
|
||||||
use util::{Bytes, Hashable, HashDB, DBValue, snappy, U256, Uint};
|
use util::{Bytes, Hashable, HashDB, DBValue, snappy, U256, Uint};
|
||||||
use util::Mutex;
|
use util::Mutex;
|
||||||
use util::hash::{FixedHash, H256};
|
use util::hash::{H256};
|
||||||
use util::journaldb::{self, Algorithm, JournalDB};
|
use util::journaldb::{self, Algorithm, JournalDB};
|
||||||
use util::kvdb::Database;
|
use util::kvdb::Database;
|
||||||
use util::trie::{TrieDB, TrieDBMut, Trie, TrieMut};
|
use util::trie::{TrieDB, TrieDBMut, Trie, TrieMut};
|
||||||
|
@ -22,7 +22,7 @@ use account_db::AccountDBMut;
|
|||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use util::DBValue;
|
use util::DBValue;
|
||||||
use util::hash::{FixedHash, H256};
|
use util::hash::H256;
|
||||||
use util::hashdb::HashDB;
|
use util::hashdb::HashDB;
|
||||||
use util::trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode};
|
use util::trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode};
|
||||||
use util::trie::{TrieDB, TrieDBMut, Trie};
|
use util::trie::{TrieDB, TrieDBMut, Trie};
|
||||||
|
@ -96,7 +96,7 @@ fn snap_and_restore() {
|
|||||||
fn get_code_from_prev_chunk() {
|
fn get_code_from_prev_chunk() {
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use rlp::{RlpStream, Stream};
|
use rlp::{RlpStream, Stream};
|
||||||
use util::{HashDB, H256, FixedHash, U256, Hashable};
|
use util::{HashDB, H256, U256, Hashable};
|
||||||
|
|
||||||
use account_db::{AccountDBMut, AccountDB};
|
use account_db::{AccountDBMut, AccountDB};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use util::{Address, H256, Uint, U256, FixedHash};
|
use util::{Address, H256, Uint, U256};
|
||||||
use util::sha3::SHA3_NULL_RLP;
|
use util::sha3::SHA3_NULL_RLP;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use super::seal::Seal;
|
use super::seal::Seal;
|
||||||
|
@ -55,6 +55,8 @@ pub struct CommonParams {
|
|||||||
pub fork_block: Option<(BlockNumber, H256)>,
|
pub fork_block: Option<(BlockNumber, H256)>,
|
||||||
/// Number of first block where EIP-98 rules begin.
|
/// Number of first block where EIP-98 rules begin.
|
||||||
pub eip98_transition: BlockNumber,
|
pub eip98_transition: BlockNumber,
|
||||||
|
/// Validate block receipts root.
|
||||||
|
pub validate_receipts: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethjson::spec::Params> for CommonParams {
|
impl From<ethjson::spec::Params> for CommonParams {
|
||||||
@ -68,6 +70,7 @@ impl From<ethjson::spec::Params> for CommonParams {
|
|||||||
min_gas_limit: p.min_gas_limit.into(),
|
min_gas_limit: p.min_gas_limit.into(),
|
||||||
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
|
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
|
||||||
eip98_transition: p.eip98_transition.map_or(0, Into::into),
|
eip98_transition: p.eip98_transition.map_or(0, Into::into),
|
||||||
|
validate_receipts: p.validate_receipts.unwrap_or(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -937,7 +937,7 @@ mod tests {
|
|||||||
use rustc_serialize::hex::FromHex;
|
use rustc_serialize::hex::FromHex;
|
||||||
use super::*;
|
use super::*;
|
||||||
use ethkey::Secret;
|
use ethkey::Secret;
|
||||||
use util::{U256, H256, FixedHash, Address, Hashable};
|
use util::{U256, H256, Address, Hashable};
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use devtools::*;
|
use devtools::*;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
|
@ -454,7 +454,7 @@ impl state::Backend for StateDB {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::{U256, H256, FixedHash, Address, DBTransaction};
|
use util::{U256, H256, Address, DBTransaction};
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use state::{Account, Backend};
|
use state::{Account, Backend};
|
||||||
use util::log::init_log;
|
use util::log::init_log;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
mod bloom;
|
mod bloom;
|
||||||
mod config;
|
mod config;
|
||||||
mod db;
|
mod db;
|
||||||
mod error;
|
|
||||||
mod executive_tracer;
|
mod executive_tracer;
|
||||||
mod import;
|
mod import;
|
||||||
mod noop_tracer;
|
mod noop_tracer;
|
||||||
@ -28,7 +27,6 @@ pub use types::trace_types::{filter, flat, localized, trace};
|
|||||||
pub use types::trace_types::error::Error as TraceError;
|
pub use types::trace_types::error::Error as TraceError;
|
||||||
pub use self::config::Config;
|
pub use self::config::Config;
|
||||||
pub use self::db::TraceDB;
|
pub use self::db::TraceDB;
|
||||||
pub use self::error::Error;
|
|
||||||
pub use types::trace_types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
|
pub use types::trace_types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
|
||||||
pub use types::trace_types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
pub use types::trace_types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
||||||
pub use self::noop_tracer::{NoopTracer, NoopVMTracer};
|
pub use self::noop_tracer::{NoopTracer, NoopVMTracer};
|
||||||
|
@ -113,7 +113,6 @@ impl Filter {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::FixedHash;
|
|
||||||
use filter::Filter;
|
use filter::Filter;
|
||||||
use client::BlockId;
|
use client::BlockId;
|
||||||
use log_entry::LogEntry;
|
use log_entry::LogEntry;
|
||||||
|
@ -31,7 +31,7 @@ impl Verifier for CanonVerifier {
|
|||||||
verification::verify_block_family(header, bytes, engine, bc)
|
verification::verify_block_family(header, bytes, engine, bc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error> {
|
fn verify_block_final(&self, expected: &Header, got: &Header, receipts: bool) -> Result<(), Error> {
|
||||||
verification::verify_block_final(expected, got)
|
verification::verify_block_final(expected, got, receipts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ impl Verifier for NoopVerifier {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_final(&self, _expected: &Header, _got: &Header) -> Result<(), Error> {
|
fn verify_block_final(&self, _expected: &Header, _got: &Header, _receipts: bool) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Phase 4 verification. Check block information against transaction enactment results,
|
/// Phase 4 verification. Check block information against transaction enactment results,
|
||||||
pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> {
|
pub fn verify_block_final(expected: &Header, got: &Header, check_receipts: bool) -> Result<(), Error> {
|
||||||
if expected.gas_used() != got.gas_used() {
|
if expected.gas_used() != got.gas_used() {
|
||||||
return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: expected.gas_used().clone(), found: got.gas_used().clone() })))
|
return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: expected.gas_used().clone(), found: got.gas_used().clone() })))
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error>
|
|||||||
if expected.state_root() != got.state_root() {
|
if expected.state_root() != got.state_root() {
|
||||||
return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root().clone(), found: got.state_root().clone() })))
|
return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root().clone(), found: got.state_root().clone() })))
|
||||||
}
|
}
|
||||||
if expected.receipts_root() != got.receipts_root() {
|
if check_receipts && expected.receipts_root() != got.receipts_root() {
|
||||||
return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: expected.receipts_root().clone(), found: got.receipts_root().clone() })))
|
return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: expected.receipts_root().clone(), found: got.receipts_root().clone() })))
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -26,5 +26,5 @@ pub trait Verifier: Send + Sync {
|
|||||||
/// Verify a block relative to its parent and uncles.
|
/// Verify a block relative to its parent and uncles.
|
||||||
fn verify_block_family(&self, header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error>;
|
fn verify_block_family(&self, header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error>;
|
||||||
/// Do a final verification check for an enacted header vs its expected counterpart.
|
/// Do a final verification check for an enacted header vs its expected counterpart.
|
||||||
fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error>;
|
fn verify_block_final(&self, expected: &Header, got: &Header, receipts: bool) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ pub mod ecies {
|
|||||||
use rcrypto::sha2::Sha256;
|
use rcrypto::sha2::Sha256;
|
||||||
use rcrypto::hmac::Hmac;
|
use rcrypto::hmac::Hmac;
|
||||||
use rcrypto::mac::Mac;
|
use rcrypto::mac::Mac;
|
||||||
use bigint::hash::{FixedHash, H128};
|
use bigint::hash::H128;
|
||||||
use ethkey::{Random, Generator, Public, Secret};
|
use ethkey::{Random, Generator, Public, Secret};
|
||||||
use {Error, ecdh, aes, Keccak256};
|
use {Error, ecdh, aes, Keccak256};
|
||||||
|
|
||||||
|
@ -51,6 +51,12 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<String> for Error {
|
||||||
|
fn into(self) -> String {
|
||||||
|
format!("{}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<::secp256k1::Error> for Error {
|
impl From<::secp256k1::Error> for Error {
|
||||||
fn from(e: ::secp256k1::Error) -> Error {
|
fn from(e: ::secp256k1::Error) -> Error {
|
||||||
match e {
|
match e {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use secret::Secret;
|
use secret::Secret;
|
||||||
use Public;
|
use Public;
|
||||||
use bigint::hash::{H256, FixedHash};
|
use bigint::hash::H256;
|
||||||
pub use self::derivation::Error as DerivationError;
|
pub use self::derivation::Error as DerivationError;
|
||||||
|
|
||||||
/// Represents label that can be stored as a part of key derivation
|
/// Represents label that can be stored as a part of key derivation
|
||||||
@ -212,7 +212,7 @@ mod derivation {
|
|||||||
use rcrypto::hmac::Hmac;
|
use rcrypto::hmac::Hmac;
|
||||||
use rcrypto::mac::Mac;
|
use rcrypto::mac::Mac;
|
||||||
use rcrypto::sha2::Sha512;
|
use rcrypto::sha2::Sha512;
|
||||||
use bigint::hash::{H512, H256, FixedHash};
|
use bigint::hash::{H512, H256};
|
||||||
use bigint::prelude::{U256, U512, Uint};
|
use bigint::prelude::{U256, U512, Uint};
|
||||||
use secp256k1;
|
use secp256k1;
|
||||||
use secp256k1::key::{SecretKey, PublicKey};
|
use secp256k1::key::{SecretKey, PublicKey};
|
||||||
|
@ -36,6 +36,17 @@ pub fn public_add(public: &mut Public, other: &Public) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Inplace sub one public key from another (EC point - EC point)
|
||||||
|
pub fn public_sub(public: &mut Public, other: &Public) -> Result<(), Error> {
|
||||||
|
let mut key_neg_other = to_secp256k1_public(other)?;
|
||||||
|
key_neg_other.mul_assign(&SECP256K1, &key::MINUS_ONE_KEY)?;
|
||||||
|
|
||||||
|
let mut key_public = to_secp256k1_public(public)?;
|
||||||
|
key_public.add_assign(&SECP256K1, &key_neg_other)?;
|
||||||
|
set_public(public, &key_public);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Return base point of secp256k1
|
/// Return base point of secp256k1
|
||||||
pub fn generation_point() -> Public {
|
pub fn generation_point() -> Public {
|
||||||
let mut public_sec_raw = [0u8; 65];
|
let mut public_sec_raw = [0u8; 65];
|
||||||
@ -64,3 +75,35 @@ fn set_public(public: &mut Public, key_public: &key::PublicKey) {
|
|||||||
let key_public_serialized = key_public.serialize_vec(&SECP256K1, false);
|
let key_public_serialized = key_public.serialize_vec(&SECP256K1, false);
|
||||||
public.copy_from_slice(&key_public_serialized[1..65]);
|
public.copy_from_slice(&key_public_serialized[1..65]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::{Random, Generator};
|
||||||
|
use super::{public_add, public_sub};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn public_addition_is_commutative() {
|
||||||
|
let public1 = Random.generate().unwrap().public().clone();
|
||||||
|
let public2 = Random.generate().unwrap().public().clone();
|
||||||
|
|
||||||
|
let mut left = public1.clone();
|
||||||
|
public_add(&mut left, &public2).unwrap();
|
||||||
|
|
||||||
|
let mut right = public2.clone();
|
||||||
|
public_add(&mut right, &public1).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn public_addition_is_reversible_with_subtraction() {
|
||||||
|
let public1 = Random.generate().unwrap().public().clone();
|
||||||
|
let public2 = Random.generate().unwrap().public().clone();
|
||||||
|
|
||||||
|
let mut sum = public1.clone();
|
||||||
|
public_add(&mut sum, &public2).unwrap();
|
||||||
|
public_sub(&mut sum, &public2).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(sum, public1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -130,3 +130,54 @@ impl Deref for Secret {
|
|||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::str::FromStr;
|
||||||
|
use super::super::{Random, Generator};
|
||||||
|
use super::Secret;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiplicating_secret_inversion_with_secret_gives_one() {
|
||||||
|
let secret = Random.generate().unwrap().secret().clone();
|
||||||
|
let mut inversion = secret.clone();
|
||||||
|
inversion.inv().unwrap();
|
||||||
|
inversion.mul(&secret).unwrap();
|
||||||
|
assert_eq!(inversion, Secret::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secret_inversion_is_reversible_with_inversion() {
|
||||||
|
let secret = Random.generate().unwrap().secret().clone();
|
||||||
|
let mut inversion = secret.clone();
|
||||||
|
inversion.inv().unwrap();
|
||||||
|
inversion.inv().unwrap();
|
||||||
|
assert_eq!(inversion, secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secret_pow() {
|
||||||
|
let secret = Random.generate().unwrap().secret().clone();
|
||||||
|
|
||||||
|
let mut pow0 = secret.clone();
|
||||||
|
pow0.pow(0).unwrap();
|
||||||
|
assert_eq!(pow0, Secret::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap());
|
||||||
|
|
||||||
|
let mut pow1 = secret.clone();
|
||||||
|
pow1.pow(1).unwrap();
|
||||||
|
assert_eq!(pow1, secret);
|
||||||
|
|
||||||
|
let mut pow2 = secret.clone();
|
||||||
|
pow2.pow(2).unwrap();
|
||||||
|
let mut pow2_expected = secret.clone();
|
||||||
|
pow2_expected.mul(&secret).unwrap();
|
||||||
|
assert_eq!(pow2, pow2_expected);
|
||||||
|
|
||||||
|
let mut pow3 = secret.clone();
|
||||||
|
pow3.pow(3).unwrap();
|
||||||
|
let mut pow3_expected = secret.clone();
|
||||||
|
pow3_expected.mul(&secret).unwrap();
|
||||||
|
pow3_expected.mul(&secret).unwrap();
|
||||||
|
assert_eq!(pow3, pow3_expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -22,7 +22,7 @@ use std::hash::{Hash, Hasher};
|
|||||||
use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError};
|
use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError};
|
||||||
use secp256k1::key::{SecretKey, PublicKey};
|
use secp256k1::key::{SecretKey, PublicKey};
|
||||||
use rustc_serialize::hex::{ToHex, FromHex};
|
use rustc_serialize::hex::{ToHex, FromHex};
|
||||||
use bigint::hash::{H520, H256, FixedHash};
|
use bigint::hash::{H520, H256};
|
||||||
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
|
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -67,7 +67,7 @@ impl KeyDirectory for MemoryDirectory {
|
|||||||
fn unique_repr(&self) -> Result<u64, Error> {
|
fn unique_repr(&self) -> Result<u64, Error> {
|
||||||
let mut val = 0u64;
|
let mut val = 0u64;
|
||||||
let accounts = self.accounts.read();
|
let accounts = self.accounts.read();
|
||||||
for acc in accounts.keys() { val = val ^ ::util::FixedHash::low_u64(acc) }
|
for acc in accounts.keys() { val = val ^ acc.low_u64() }
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,11 @@ version = "0.1.0"
|
|||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "evm"
|
name = "evmbin"
|
||||||
path = "./src/main.rs"
|
path = "./src/main.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "evm"
|
name = "parity-evm"
|
||||||
path = "./src/main.rs"
|
path = "./src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use util::{U256, H256, Address, Bytes, FixedHash, trie};
|
use util::{U256, H256, Address, Bytes, trie};
|
||||||
use ethcore::client::EnvInfo;
|
use ethcore::client::EnvInfo;
|
||||||
use ethcore::evm::{self, Ext, ContractCreateResult, MessageCallResult, Schedule, CallType};
|
use ethcore::evm::{self, Ext, ContractCreateResult, MessageCallResult, Schedule, CallType};
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ use std::str::FromStr;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use super::WalletInfo;
|
use super::WalletInfo;
|
||||||
use ethkey::{Address, Signature};
|
use ethkey::{Address, Signature};
|
||||||
use ethcore_bigint::hash::{H256, FixedHash};
|
use ethcore_bigint::hash::H256;
|
||||||
|
|
||||||
const LEDGER_VID: u16 = 0x2c97;
|
const LEDGER_VID: u16 = 0x2c97;
|
||||||
const LEDGER_PIDS: [u16; 2] = [0x0000, 0x0001]; // Nano S and Blue
|
const LEDGER_PIDS: [u16; 2] = [0x0000, 0x0001]; // Nano S and Blue
|
||||||
@ -260,12 +260,12 @@ impl Manager {
|
|||||||
{
|
{
|
||||||
let mut chunk = &mut hid_chunk[HID_PREFIX_ZERO..];
|
let mut chunk = &mut hid_chunk[HID_PREFIX_ZERO..];
|
||||||
&mut chunk[0..5].copy_from_slice(&[0x01, 0x01, APDU_TAG, (chunk_index >> 8) as u8, (chunk_index & 0xff) as u8 ]);
|
&mut chunk[0..5].copy_from_slice(&[0x01, 0x01, APDU_TAG, (chunk_index >> 8) as u8, (chunk_index & 0xff) as u8 ]);
|
||||||
|
|
||||||
if chunk_index == 0 {
|
if chunk_index == 0 {
|
||||||
let data_len = data.len() + 5;
|
let data_len = data.len() + 5;
|
||||||
&mut chunk[5..12].copy_from_slice(&[ (data_len >> 8) as u8, (data_len & 0xff) as u8, APDU_CLA, command, p1, p2, data.len() as u8 ]);
|
&mut chunk[5..12].copy_from_slice(&[ (data_len >> 8) as u8, (data_len & 0xff) as u8, APDU_CLA, command, p1, p2, data.len() as u8 ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
&mut chunk[chunk_size..chunk_size + size].copy_from_slice(&data[offset..offset + size]);
|
&mut chunk[chunk_size..chunk_size + size].copy_from_slice(&data[offset..offset + size]);
|
||||||
offset += size;
|
offset += size;
|
||||||
chunk_size += size;
|
chunk_size += size;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use semver::{Version};
|
use semver::{Version};
|
||||||
use util::{H160, FixedHash};
|
use util::H160;
|
||||||
use util::misc::raw_package_info;
|
use util::misc::raw_package_info;
|
||||||
use release_track::ReleaseTrack;
|
use release_track::ReleaseTrack;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ethcore = { path = "../ethcore" }
|
ethcore = { path = "../ethcore" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git" }
|
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
mime = "0.2"
|
mime = "0.2"
|
||||||
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
||||||
|
12
js/assets/images/dapps/close.svg
Normal file
12
js/assets/images/dapps/close.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512" viewBox="0 0 512 512">
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<path d="M295.516 216.494h154v78.992h-154v-78.992z" fill="#FFFFFF" />
|
||||||
|
<path d="M62.474 216.514h154.050v78.971h-154.050v-78.971z" fill="#FFFFFF" />
|
||||||
|
<path d="M216.525 295.465h79.001v154.050h-79.001v-154.050z" fill="#FFFFFF" />
|
||||||
|
<path d="M216.525 62.474h79.001v154.041h-79.001v-154.041z" fill="#FFFFFF" />
|
||||||
|
<path d="M216.525 216.514h79.001v78.971h-79.001v-78.971z" fill="#FFFFFF" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 720 B |
12
js/assets/images/dapps/plus.svg
Normal file
12
js/assets/images/dapps/plus.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512" viewBox="0 0 512 512">
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<path d="M295.516 216.494h154v78.992h-154v-78.992z" fill="#000000" />
|
||||||
|
<path d="M62.474 216.514h154.050v78.971h-154.050v-78.971z" fill="#000000" />
|
||||||
|
<path d="M216.525 295.465h79.001v154.050h-79.001v-154.050z" fill="#000000" />
|
||||||
|
<path d="M216.525 62.474h79.001v154.041h-79.001v-154.041z" fill="#000000" />
|
||||||
|
<path d="M216.525 216.514h79.001v78.971h-79.001v-78.971z" fill="#000000" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 715 B |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "1.7.3",
|
"version": "1.7.18",
|
||||||
"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>",
|
||||||
@ -201,6 +201,7 @@
|
|||||||
"scryptsy": "2.0.0",
|
"scryptsy": "2.0.0",
|
||||||
"solc": "ngotchac/solc-js",
|
"solc": "ngotchac/solc-js",
|
||||||
"store": "1.3.20",
|
"store": "1.3.20",
|
||||||
|
"sw-toolbox": "^3.6.0",
|
||||||
"u2f-api": "0.0.9",
|
"u2f-api": "0.0.9",
|
||||||
"u2f-api-polyfill": "0.4.3",
|
"u2f-api-polyfill": "0.4.3",
|
||||||
"uglify-js": "2.8.2",
|
"uglify-js": "2.8.2",
|
||||||
@ -210,6 +211,7 @@
|
|||||||
"validator": "6.2.0",
|
"validator": "6.2.0",
|
||||||
"web3": "0.17.0-beta",
|
"web3": "0.17.0-beta",
|
||||||
"whatwg-fetch": "2.0.1",
|
"whatwg-fetch": "2.0.1",
|
||||||
|
"worker-loader": "^0.8.0",
|
||||||
"zxcvbn": "4.4.1"
|
"zxcvbn": "4.4.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,11 +89,13 @@ fi
|
|||||||
|
|
||||||
echo "*** Updating cargo parity-ui-precompiled#$PRECOMPILED_HASH"
|
echo "*** Updating cargo parity-ui-precompiled#$PRECOMPILED_HASH"
|
||||||
git submodule update
|
git submodule update
|
||||||
|
sed -i "/^parity-ui-precompiled/ { s/branch = \".*\"/branch = \"$BRANCH\"/g; }" dapps/ui/Cargo.toml
|
||||||
cargo update -p parity-ui-precompiled
|
cargo update -p parity-ui-precompiled
|
||||||
# --precise "$PRECOMPILED_HASH"
|
# --precise "$PRECOMPILED_HASH"
|
||||||
|
|
||||||
echo "*** Committing updated files"
|
echo "*** Committing updated files"
|
||||||
git add js
|
git add js
|
||||||
|
git add dapps/ui/Cargo.toml
|
||||||
git add Cargo.lock
|
git add Cargo.lock
|
||||||
git commit -m "[ci skip] js-precompiled $UTCDATE"
|
git commit -m "[ci skip] js-precompiled $UTCDATE"
|
||||||
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
||||||
|
@ -1 +1,2 @@
|
|||||||
// test script 7
|
// test script 8
|
||||||
|
// trigger rebuild on master 15 Mar 2017, 11:19
|
||||||
|
@ -107,13 +107,25 @@ export default class Contract {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deploy (options, values, statecb = () => {}) {
|
deploy (options, values, statecb = () => {}, skipGasEstimate = false) {
|
||||||
statecb(null, { state: 'estimateGas' });
|
let gasEstPromise;
|
||||||
|
|
||||||
return this
|
if (skipGasEstimate) {
|
||||||
.deployEstimateGas(options, values)
|
gasEstPromise = Promise.resolve(null);
|
||||||
.then(([gasEst, gas]) => {
|
} else {
|
||||||
options.gas = gas.toFixed(0);
|
statecb(null, { state: 'estimateGas' });
|
||||||
|
|
||||||
|
gasEstPromise = this.deployEstimateGas(options, values)
|
||||||
|
.then(([gasEst, gas]) => gas);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gasEstPromise
|
||||||
|
.then((_gas) => {
|
||||||
|
if (_gas) {
|
||||||
|
options.gas = _gas.toFixed(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gas = _gas || options.gas;
|
||||||
|
|
||||||
statecb(null, { state: 'postTransaction', gas });
|
statecb(null, { state: 'postTransaction', gas });
|
||||||
|
|
||||||
|
@ -143,8 +143,15 @@ export function inOptions (options) {
|
|||||||
if (options) {
|
if (options) {
|
||||||
Object.keys(options).forEach((key) => {
|
Object.keys(options).forEach((key) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'from':
|
|
||||||
case 'to':
|
case 'to':
|
||||||
|
// Don't encode the `to` option if it's empty
|
||||||
|
// (eg. contract deployments)
|
||||||
|
if (options[key]) {
|
||||||
|
options[key] = inAddress(options[key]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'from':
|
||||||
options[key] = inAddress(options[key]);
|
options[key] = inAddress(options[key]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -208,6 +208,13 @@ describe('api/format/input', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not encode an empty `to` value', () => {
|
||||||
|
const options = { to: '' };
|
||||||
|
const formatted = inOptions(options);
|
||||||
|
|
||||||
|
expect(formatted.to).to.equal('');
|
||||||
|
});
|
||||||
|
|
||||||
['gas', 'gasPrice', 'value', 'minBlock', 'nonce'].forEach((input) => {
|
['gas', 'gasPrice', 'value', 'minBlock', 'nonce'].forEach((input) => {
|
||||||
it(`formats ${input} number as hexnumber`, () => {
|
it(`formats ${input} number as hexnumber`, () => {
|
||||||
const block = {};
|
const block = {};
|
||||||
|
@ -284,9 +284,15 @@ export default class Parity {
|
|||||||
.execute('parity_mode');
|
.execute('parity_mode');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEPRECATED - use chain instead.
|
||||||
netChain () {
|
netChain () {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_netChain');
|
.execute('parity_chain');
|
||||||
|
}
|
||||||
|
|
||||||
|
chain () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_chain');
|
||||||
}
|
}
|
||||||
|
|
||||||
netPeers () {
|
netPeers () {
|
||||||
@ -454,6 +460,11 @@ export default class Parity {
|
|||||||
.execute('parity_setMode', mode);
|
.execute('parity_setMode', mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setChain (specName) {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_setChain', specName);
|
||||||
|
}
|
||||||
|
|
||||||
setNewDappsAddresses (addresses) {
|
setNewDappsAddresses (addresses) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_setNewDappsAddresses', addresses ? inAddresses(addresses) : null);
|
.execute('parity_setNewDappsAddresses', addresses ? inAddresses(addresses) : null);
|
||||||
|
File diff suppressed because one or more lines are too long
@ -16,7 +16,14 @@
|
|||||||
|
|
||||||
import * as abis from './abi';
|
import * as abis from './abi';
|
||||||
|
|
||||||
|
const REGISTRY_V1_HASHES = [
|
||||||
|
'0x34f7c51bbb1b1902fbdabfdf04811100f5c9f998f26dd535d2f6f977492c748e', // ropsten
|
||||||
|
'0x64c3ee34851517a9faecd995c102b339f03e564ad6772dc43a26f993238b20ec' // homestead
|
||||||
|
];
|
||||||
|
|
||||||
export default class Registry {
|
export default class Registry {
|
||||||
|
_registryContract = null;
|
||||||
|
|
||||||
constructor (api) {
|
constructor (api) {
|
||||||
this._api = api;
|
this._api = api;
|
||||||
|
|
||||||
@ -43,11 +50,10 @@ export default class Registry {
|
|||||||
|
|
||||||
this._fetching = true;
|
this._fetching = true;
|
||||||
|
|
||||||
return this._api.parity
|
return this.fetchContract()
|
||||||
.registryAddress()
|
.then((contract) => {
|
||||||
.then((address) => {
|
|
||||||
this._fetching = false;
|
this._fetching = false;
|
||||||
this._instance = this._api.newContract(abis.registry, address).instance;
|
this._instance = contract.instance;
|
||||||
|
|
||||||
this._queue.forEach((queued) => {
|
this._queue.forEach((queued) => {
|
||||||
queued.resolve(this._instance);
|
queued.resolve(this._instance);
|
||||||
@ -89,6 +95,47 @@ export default class Registry {
|
|||||||
.then((contract) => contract.instance);
|
.then((contract) => contract.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetchContract () {
|
||||||
|
if (this._registryContract) {
|
||||||
|
return Promise.resolve(this._registryContract);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._api.parity
|
||||||
|
.registryAddress()
|
||||||
|
.then((address) => Promise.all([ address, this._api.eth.getCode(address) ]))
|
||||||
|
.then(([ address, code ]) => {
|
||||||
|
const codeHash = this._api.util.sha3(code);
|
||||||
|
const version = REGISTRY_V1_HASHES.includes(codeHash)
|
||||||
|
? 1
|
||||||
|
: 2;
|
||||||
|
const abi = version === 1
|
||||||
|
? abis.registry
|
||||||
|
: abis.registry2;
|
||||||
|
const contract = this._api.newContract(abi, address);
|
||||||
|
|
||||||
|
// Add support for previous `set` and `get` methods
|
||||||
|
if (!contract.instance.get && contract.instance.getData) {
|
||||||
|
contract.instance.get = contract.instance.getData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contract.instance.get && !contract.instance.getData) {
|
||||||
|
contract.instance.getData = contract.instance.get;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!contract.instance.set && contract.instance.setData) {
|
||||||
|
contract.instance.set = contract.instance.setData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contract.instance.set && !contract.instance.setData) {
|
||||||
|
contract.instance.setData = contract.instance.set;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`registry at ${address}, code ${codeHash}, version ${version}`);
|
||||||
|
this._registryContract = contract;
|
||||||
|
return this._registryContract;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_createGetParams (_name, key) {
|
_createGetParams (_name, key) {
|
||||||
const name = _name.toLowerCase();
|
const name = _name.toLowerCase();
|
||||||
const sha3 = this._api.util.sha3.text(name);
|
const sha3 = this._api.util.sha3.text(name);
|
||||||
|
@ -35,6 +35,9 @@ function create () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
api = {
|
api = {
|
||||||
|
eth: {
|
||||||
|
getCode: sinon.stub().resolves('0x123456')
|
||||||
|
},
|
||||||
parity: {
|
parity: {
|
||||||
registryAddress: sinon.stub().resolves('testRegistryAddress')
|
registryAddress: sinon.stub().resolves('testRegistryAddress')
|
||||||
},
|
},
|
||||||
|
@ -294,7 +294,7 @@ contract multisig {
|
|||||||
|
|
||||||
// TODO: document
|
// TODO: document
|
||||||
function execute(address _to, uint _value, bytes _data) external returns (bytes32 o_hash);
|
function execute(address _to, uint _value, bytes _data) external returns (bytes32 o_hash);
|
||||||
function confirm(bytes32 _h) external returns (bool o_success);
|
function confirm(bytes32 _h) returns (bool o_success);
|
||||||
}
|
}
|
||||||
|
|
||||||
// usage:
|
// usage:
|
||||||
|
29
js/src/dapps/chaindeploy.js
Normal file
29
js/src/dapps/chaindeploy.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import Application from './chaindeploy/Application';
|
||||||
|
|
||||||
|
import '../../assets/fonts/Roboto/font.css';
|
||||||
|
import '../../assets/fonts/RobotoMono/font.css';
|
||||||
|
import './style.css';
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Application />,
|
||||||
|
document.querySelector('#container')
|
||||||
|
);
|
78
js/src/dapps/chaindeploy/Application/application.css
Normal file
78
js/src/dapps/chaindeploy/Application/application.css
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.body {
|
||||||
|
font-size: 0.8em;
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
position: fixed;
|
||||||
|
right: 0.5em;
|
||||||
|
top: 0.5em;
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: rgb(0, 200, 255);
|
||||||
|
border: 2px solid rgba(0, 200, 255, 0.5);
|
||||||
|
border-radius: 0.25em;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 0 0 0 0.5em;
|
||||||
|
outline: none;
|
||||||
|
padding: 0.75em 1.5em;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
background: rgb(230, 230, 230);
|
||||||
|
border: 2px solid rgba(230, 230, 230, 0.5);
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: white !important;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 24px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin: 0 1em 3em 1em;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
background: rgba(0, 0, 0, 0.025);
|
||||||
|
border-radius: 0.25em;
|
||||||
|
padding: 0.75em 1em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
|
||||||
|
small {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
178
js/src/dapps/chaindeploy/Application/application.js
Normal file
178
js/src/dapps/chaindeploy/Application/application.js
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import Contract from '../Contract';
|
||||||
|
import Dapp from '../Dapp';
|
||||||
|
import Store from '../store';
|
||||||
|
|
||||||
|
import styles from './application.css';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class Application extends Component {
|
||||||
|
store = new Store();
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div className={ styles.body }>
|
||||||
|
{ this.renderContracts(false) }
|
||||||
|
{ this.renderContracts(true) }
|
||||||
|
{ this.renderApps() }
|
||||||
|
{ this.renderContracts(false, true) }
|
||||||
|
{ this.renderApps(true) }
|
||||||
|
{ this.renderButtons() }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButton (text, clickHandler, disabled) {
|
||||||
|
const onClick = (event) => {
|
||||||
|
if (!disabled) {
|
||||||
|
clickHandler(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
disabled={ disabled }
|
||||||
|
onClick={ onClick }
|
||||||
|
>
|
||||||
|
<div className={ styles.text }>
|
||||||
|
{ text }
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons () {
|
||||||
|
const { contractBadgereg, contractDappreg, isBadgeDeploying, isContractDeploying, isDappDeploying, haveAllBadges, haveAllContracts, haveAllDapps, registry } = this.store;
|
||||||
|
const disableRegistry = registry.address || registry.isDeploying;
|
||||||
|
const disableContracts = !registry.address || isContractDeploying || haveAllContracts;
|
||||||
|
const disableDapps = !contractDappreg.address || isDappDeploying || haveAllDapps;
|
||||||
|
const disableBadges = !registry.address || !contractBadgereg.address || isBadgeDeploying || haveAllBadges;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.buttons }>
|
||||||
|
{ this.renderButton('registry', this.deployRegistry, disableRegistry) }
|
||||||
|
{ this.renderButton('contracts', this.deployContracts, disableContracts) }
|
||||||
|
{ this.renderButton('badges', this.deployBadges, disableBadges) }
|
||||||
|
{ this.renderButton('apps', this.deployApps, disableDapps) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderContracts (isBadges, isExternal) {
|
||||||
|
const { badges, contracts, contractBadgereg, registry } = this.store;
|
||||||
|
const regaddress = isBadges
|
||||||
|
? contractBadgereg.address
|
||||||
|
: registry.address;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.section }>
|
||||||
|
<h3>
|
||||||
|
{
|
||||||
|
isExternal
|
||||||
|
? 'External '
|
||||||
|
: ''
|
||||||
|
}{
|
||||||
|
isBadges
|
||||||
|
? 'Badges '
|
||||||
|
: 'Contracts '
|
||||||
|
}<small>(registry { regaddress || 'unknown' })</small>
|
||||||
|
</h3>
|
||||||
|
<div className={ styles.list }>
|
||||||
|
{
|
||||||
|
isExternal || isBadges
|
||||||
|
? null
|
||||||
|
: (
|
||||||
|
<Contract
|
||||||
|
contract={ registry }
|
||||||
|
key='registry'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(isBadges ? badges : contracts)
|
||||||
|
.filter((contract) => contract.isExternal === isExternal)
|
||||||
|
.map((contract) => {
|
||||||
|
return (
|
||||||
|
<Contract
|
||||||
|
contract={ contract }
|
||||||
|
disabled={ !registry.address }
|
||||||
|
key={ contract.id }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderApps (isExternal) {
|
||||||
|
const { apps, contractDappreg, contractGithubhint } = this.store;
|
||||||
|
const isDisabled = !contractDappreg.isOnChain || !contractGithubhint.isOnChain;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.section }>
|
||||||
|
<h3>
|
||||||
|
{
|
||||||
|
isExternal
|
||||||
|
? 'External '
|
||||||
|
: ''
|
||||||
|
}Applications <small>(registry {
|
||||||
|
contractDappreg.address
|
||||||
|
? contractDappreg.address
|
||||||
|
: 'unknown'
|
||||||
|
})</small>
|
||||||
|
</h3>
|
||||||
|
<div className={ styles.list }>
|
||||||
|
{
|
||||||
|
apps
|
||||||
|
.filter((app) => app.isExternal === isExternal)
|
||||||
|
.map((app) => {
|
||||||
|
return (
|
||||||
|
<Dapp
|
||||||
|
dapp={ app }
|
||||||
|
disabled={ isDisabled }
|
||||||
|
key={ app.id }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
deployApps = () => {
|
||||||
|
return this.store.deployApps();
|
||||||
|
}
|
||||||
|
|
||||||
|
deployBadges = () => {
|
||||||
|
return this.store.deployBadges();
|
||||||
|
}
|
||||||
|
|
||||||
|
deployContracts = () => {
|
||||||
|
return this.store.deployContracts();
|
||||||
|
}
|
||||||
|
|
||||||
|
deployRegistry = () => {
|
||||||
|
return this.store.deployRegistry();
|
||||||
|
}
|
||||||
|
}
|
17
js/src/dapps/chaindeploy/Application/index.js
Normal file
17
js/src/dapps/chaindeploy/Application/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './application';
|
132
js/src/dapps/chaindeploy/Contract/contract.js
Normal file
132
js/src/dapps/chaindeploy/Contract/contract.js
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import ListItem, { Header, Row } from '../ListItem';
|
||||||
|
|
||||||
|
export default class Contract extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
contract: PropTypes.object.isRequired,
|
||||||
|
disabled: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { contract, disabled } = this.props;
|
||||||
|
const location = contract.id === 'registry'
|
||||||
|
? 'chain'
|
||||||
|
: 'registry';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListItem
|
||||||
|
disabled={ disabled }
|
||||||
|
status={ contract.status }
|
||||||
|
>
|
||||||
|
<Header
|
||||||
|
isBusy={ contract.isDeploying }
|
||||||
|
isOk={ !!contract.instance && contract.isOnChain && contract.hasLatestCode }
|
||||||
|
>
|
||||||
|
{ contract.id } was {
|
||||||
|
contract.address
|
||||||
|
? 'deployed'
|
||||||
|
: 'not found'
|
||||||
|
}
|
||||||
|
</Header>
|
||||||
|
<Row
|
||||||
|
disabled={ !contract.instance }
|
||||||
|
isBusy={ contract.isDeploying }
|
||||||
|
isOk={ !!contract.address }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
contract.address
|
||||||
|
? contract.address
|
||||||
|
: 'no address'
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
<Row
|
||||||
|
disabled={ !contract.instance }
|
||||||
|
isBusy={ contract.isDeploying }
|
||||||
|
isOk={ contract.hasLatestCode }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
contract.hasLatestCode
|
||||||
|
? 'has latest available code'
|
||||||
|
: 'does not have latest code'
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
<Row
|
||||||
|
disabled={ !contract.instance }
|
||||||
|
isBusy={ contract.isDeploying }
|
||||||
|
isOk={ !!contract.isOnChain }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
contract.isOnChain
|
||||||
|
? `registered on ${location}`
|
||||||
|
: `not registered on ${location}`
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
{ this.renderBadgeInfo() }
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBadgeInfo () {
|
||||||
|
const { contract } = this.props;
|
||||||
|
|
||||||
|
if (!contract.isBadge) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
<Row
|
||||||
|
disabled={ !contract.instance }
|
||||||
|
isBusy={ contract.isDeploying }
|
||||||
|
isOk={ contract.isBadgeRegistered }
|
||||||
|
key='isBadgeRegistered'
|
||||||
|
>
|
||||||
|
{
|
||||||
|
contract.isBadgeRegistered
|
||||||
|
? 'found in badgereg'
|
||||||
|
: 'not found in badgereg'
|
||||||
|
}
|
||||||
|
</Row>,
|
||||||
|
<Row
|
||||||
|
disabled={ !contract.instance }
|
||||||
|
isBusy={ contract.isDeploying }
|
||||||
|
isOk={ !!contract.badgeImageHash }
|
||||||
|
key='imageHash'
|
||||||
|
>
|
||||||
|
{
|
||||||
|
contract.badgeImageHash
|
||||||
|
? `badge imageHash ${contract.badgeImageHash}`
|
||||||
|
: 'has not registered a badge imageHash'
|
||||||
|
}
|
||||||
|
</Row>,
|
||||||
|
<Row
|
||||||
|
disabled={ !contract.instance }
|
||||||
|
isBusy={ contract.isDeploying }
|
||||||
|
isOk={ contract.badgeImageMatch }
|
||||||
|
key='imageMatch'
|
||||||
|
>
|
||||||
|
{
|
||||||
|
contract.badgeImageMatch
|
||||||
|
? 'has latest badge imageHash'
|
||||||
|
: 'does not have latest badge imageHash'
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -14,4 +14,4 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
export default from './buttonBar';
|
export default from './contract';
|
98
js/src/dapps/chaindeploy/Dapp/dapp.js
Normal file
98
js/src/dapps/chaindeploy/Dapp/dapp.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import ListItem, { Header, Row } from '../ListItem';
|
||||||
|
|
||||||
|
export default class Dapp extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
dapp: PropTypes.object.isRequired,
|
||||||
|
disabled: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { dapp, disabled } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListItem
|
||||||
|
disabled={ disabled }
|
||||||
|
status={ dapp.status }
|
||||||
|
>
|
||||||
|
<Header
|
||||||
|
isBusy={ dapp.isDeploying }
|
||||||
|
isOk={
|
||||||
|
dapp.isOnChain &&
|
||||||
|
!!dapp.imageHash && !!dapp.imageMatch &&
|
||||||
|
(!dapp.source.contentHash || !!dapp.contentMatch) &&
|
||||||
|
(!dapp.source.manifestHash || !!dapp.manifestMatch)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{ dapp.name }
|
||||||
|
</Header>
|
||||||
|
<Row
|
||||||
|
isBusy={ dapp.isDeploying }
|
||||||
|
isOk={ dapp.isOnChain }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
dapp.isOnChain
|
||||||
|
? 'found in dappreg'
|
||||||
|
: 'not found in dappreg'
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
{ this.renderHash(dapp, 'image') }
|
||||||
|
{ this.renderHash(dapp, 'manifest') }
|
||||||
|
{ this.renderHash(dapp, 'content') }
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderHash (dapp, type) {
|
||||||
|
if (!dapp.source[`${type}Hash`]) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isMatch = dapp[`${type}Match`];
|
||||||
|
const hash = dapp[`${type}Hash`];
|
||||||
|
|
||||||
|
return [
|
||||||
|
<Row
|
||||||
|
disabled={ !dapp.isOnChain }
|
||||||
|
isBusy={ dapp.isDeploying }
|
||||||
|
isOk={ !!hash }
|
||||||
|
key={ `${type}Hash` }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
hash
|
||||||
|
? `${type}Hash ${hash}`
|
||||||
|
: `has not registered an ${type}Hash`
|
||||||
|
}
|
||||||
|
</Row>,
|
||||||
|
<Row
|
||||||
|
disabled={ !dapp.isOnChain }
|
||||||
|
isBusy={ dapp.isDeploying }
|
||||||
|
isOk={ isMatch }
|
||||||
|
key={ `${type}Match` }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
isMatch
|
||||||
|
? `has latest ${type}Hash`
|
||||||
|
: `does not have latest ${type}Hash`
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
45
js/src/dapps/chaindeploy/ListItem/Header/header.js
Normal file
45
js/src/dapps/chaindeploy/ListItem/Header/header.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import Icon from '../Icon';
|
||||||
|
|
||||||
|
import styles from '../listItem.css';
|
||||||
|
|
||||||
|
export default class Header extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
isBusy: PropTypes.bool,
|
||||||
|
isOk: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { children, isBusy, isOk } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.header }>
|
||||||
|
<Icon
|
||||||
|
isBusy={ isBusy }
|
||||||
|
isOk={ isOk }
|
||||||
|
/>
|
||||||
|
<div className={ styles.title }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -14,4 +14,4 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
export default from './selectDapp';
|
export default from './header';
|
53
js/src/dapps/chaindeploy/ListItem/Icon/icon.js
Normal file
53
js/src/dapps/chaindeploy/ListItem/Icon/icon.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import styles from '../listItem.css';
|
||||||
|
|
||||||
|
export default class Icon extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
isBusy: PropTypes.bool,
|
||||||
|
isOk: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { isBusy, isOk } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
[
|
||||||
|
styles.icon,
|
||||||
|
isOk
|
||||||
|
? styles.ok
|
||||||
|
: styles.error
|
||||||
|
].join(' ')
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
isOk
|
||||||
|
? '\u2714'
|
||||||
|
: (
|
||||||
|
isBusy
|
||||||
|
? '\u29d6'
|
||||||
|
: '\u2716'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
js/src/dapps/chaindeploy/ListItem/Icon/index.js
Normal file
17
js/src/dapps/chaindeploy/ListItem/Icon/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './icon';
|
17
js/src/dapps/chaindeploy/ListItem/Row/index.js
Normal file
17
js/src/dapps/chaindeploy/ListItem/Row/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './row';
|
54
js/src/dapps/chaindeploy/ListItem/Row/row.js
Normal file
54
js/src/dapps/chaindeploy/ListItem/Row/row.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import Icon from '../Icon';
|
||||||
|
|
||||||
|
import styles from '../listItem.css';
|
||||||
|
|
||||||
|
export default class Row extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
isBusy: PropTypes.bool,
|
||||||
|
isOk: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { children, disabled, isBusy, isOk } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
[
|
||||||
|
styles.details,
|
||||||
|
disabled
|
||||||
|
? styles.muted
|
||||||
|
: ''
|
||||||
|
].join(' ') }
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
isBusy={ isBusy }
|
||||||
|
isOk={ isOk }
|
||||||
|
/>
|
||||||
|
<div className={ styles.title }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Database ipc service
|
export Header from './Header';
|
||||||
|
export Row from './Row';
|
||||||
|
|
||||||
#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues
|
export default from './listItem';
|
||||||
include!(concat!(env!("OUT_DIR"), "/lib.rs"));
|
|
94
js/src/dapps/chaindeploy/ListItem/listItem.css
Normal file
94
js/src/dapps/chaindeploy/ListItem/listItem.css
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.listItem {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 0 1 33.33%;
|
||||||
|
max-width: 33.33%;
|
||||||
|
padding: 0.5em;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background: rgba(0, 0, 0, 0.025);
|
||||||
|
border-radius: 0.25em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
background: #f80;
|
||||||
|
border-radius: 0.25em;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.75em;
|
||||||
|
line-height: 1em;
|
||||||
|
opacity: 0.9;
|
||||||
|
padding: 0.5em;
|
||||||
|
position: absolute;
|
||||||
|
right: 1em;
|
||||||
|
top: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header,
|
||||||
|
.details {
|
||||||
|
display: flex;
|
||||||
|
line-height: 1.5em;
|
||||||
|
padding: 0.125em 0;
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.details {
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
border-radius: 0.25em;
|
||||||
|
display: inline-block;
|
||||||
|
flex: 0 0 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
opacity: 0.75;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 1.5em;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
box-shadow: inset 0 0 0 2px rgb(200, 0, 0);
|
||||||
|
color: rgb(200, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ok {
|
||||||
|
box-shadow: inset 0 0 0 2px rgb(0, 200, 0);
|
||||||
|
color: rgb(0, 200, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted {
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
63
js/src/dapps/chaindeploy/ListItem/listItem.js
Normal file
63
js/src/dapps/chaindeploy/ListItem/listItem.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import styles from './listItem.css';
|
||||||
|
|
||||||
|
export default class ListItem extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
status: PropTypes.string
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { children, disabled } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
[
|
||||||
|
styles.listItem,
|
||||||
|
disabled
|
||||||
|
? styles.muted
|
||||||
|
: ''
|
||||||
|
].join(' ')
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className={ styles.body }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
{ this.renderStatus() }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStatus () {
|
||||||
|
const { status } = this.props;
|
||||||
|
|
||||||
|
if (!status) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.status }>
|
||||||
|
{ status }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
43
js/src/dapps/chaindeploy/_dapps.js
Normal file
43
js/src/dapps/chaindeploy/_dapps.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import builtinsJson from '~/views/Dapps/builtin.json';
|
||||||
|
|
||||||
|
const REGISTER_URLS = {
|
||||||
|
console: 'https://raw.githubusercontent.com/ethcore/console/3ea0dbfefded359ccdbea37bc4cf350c0aa16948/console.jpeg',
|
||||||
|
dappreg: 'https://raw.githubusercontent.com/ethcore/dapp-assets/cdd6ac4f1e2f11619bed72a53ae71217dffe19ad/dapps/legos-64x64.png',
|
||||||
|
githubhint: 'https://raw.githubusercontent.com/ethcore/dapp-assets/b88e983abaa1a6a6345b8d9448c15b117ddb540e/dapps/link-64x64.jpg',
|
||||||
|
localtx: 'https://raw.githubusercontent.com/ethcore/dapp-assets/cdd6ac4f1e2f11619bed72a53ae71217dffe19ad/dapps/stack-64x64.png',
|
||||||
|
registry: 'https://raw.githubusercontent.com/ethcore/dapp-assets/b88e983abaa1a6a6345b8d9448c15b117ddb540e/dapps/register-64x64.jpg',
|
||||||
|
signaturereg: 'https://raw.githubusercontent.com/ethcore/dapp-assets/b88e983abaa1a6a6345b8d9448c15b117ddb540e/dapps/hex-64x64.jpg',
|
||||||
|
tokendeploy: 'https://raw.githubusercontent.com/ethcore/dapp-assets/b88e983abaa1a6a6345b8d9448c15b117ddb540e/dapps/interlock-64x64.png',
|
||||||
|
tokenreg: 'https://raw.githubusercontent.com/ethcore/dapp-assets/b88e983abaa1a6a6345b8d9448c15b117ddb540e/dapps/coins-64x64.jpg',
|
||||||
|
web: 'https://raw.githubusercontent.com/ethcore/dapp-assets/ec6138115d0e1f45258969cd90b3b274e0ff2258/dapps/earth-64x64.jpg'
|
||||||
|
};
|
||||||
|
|
||||||
|
const builtins = builtinsJson
|
||||||
|
.filter((app) => app.id)
|
||||||
|
.map((app) => {
|
||||||
|
app.source = {
|
||||||
|
imageUrl: REGISTER_URLS[app.id]
|
||||||
|
};
|
||||||
|
|
||||||
|
return app;
|
||||||
|
});
|
||||||
|
|
||||||
|
export {
|
||||||
|
builtins
|
||||||
|
};
|
1
js/src/dapps/chaindeploy/contracts/abi/jg-voting.json
Normal file
1
js/src/dapps/chaindeploy/contracts/abi/jg-voting.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[{"constant":true,"inputs":[],"name":"count","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalVotes","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"hasSenderVoted","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_index","type":"uint256"},{"name":"_answer","type":"uint256"}],"name":"newAnswer","outputs":[{"name":"","type":"bool"}],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setQuestionFee","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"questionFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"get","outputs":[{"name":"closed","type":"bool"},{"name":"owner","type":"address"},{"name":"question","type":"string"},{"name":"balanceNo","type":"uint256"},{"name":"balanceYes","type":"uint256"},{"name":"balanceMaybe","type":"uint256"},{"name":"votesNo","type":"uint256"},{"name":"votesYes","type":"uint256"},{"name":"votesMaybe","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_question","type":"string"}],"name":"newQuestion","outputs":[{"name":"","type":"bool"}],"payable":true,"type":"function"},{"constant":true,"inputs":[],"name":"totalBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"answerFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_index","type":"uint256"}],"name":"closeQuestion","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setAnswerFee","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"index","type":"uint256"},{"indexed":false,"name":"question","type":"string"}],"name":"NewQuestion","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"index","type":"uint256"},{"indexed":true,"name":"answer","type":"uint256"},{"indexed":false,"name":"value","type":"uint256"}],"name":"NewAnswer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]
|
30
js/src/dapps/chaindeploy/contracts/badgereg.js
Normal file
30
js/src/dapps/chaindeploy/contracts/badgereg.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import abi from '~/contracts/abi/badgereg';
|
||||||
|
import { compiler, source as sourceUrl, output as byteCode } from './code/badgereg';
|
||||||
|
|
||||||
|
const id = 'badgereg';
|
||||||
|
const deployParams = [];
|
||||||
|
|
||||||
|
export {
|
||||||
|
abi,
|
||||||
|
byteCode,
|
||||||
|
compiler,
|
||||||
|
deployParams,
|
||||||
|
id,
|
||||||
|
sourceUrl
|
||||||
|
};
|
5
js/src/dapps/chaindeploy/contracts/code/badgereg.json
Normal file
5
js/src/dapps/chaindeploy/contracts/code/badgereg.json
Normal file
File diff suppressed because one or more lines are too long
5
js/src/dapps/chaindeploy/contracts/code/dappreg.json
Normal file
5
js/src/dapps/chaindeploy/contracts/code/dappreg.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"compiler": "v0.4.9+commit.364da425",
|
||||||
|
"source": "https://github.com/ethcore/contracts/blob/225bf022ddd967af2b9ea188e8f611489ca5d7fe/DappReg.sol",
|
||||||
|
"output": "0x606060405260008054600160a060020a03191633600160a060020a0316179055670de0b6b3a7640000600355341561003357fe5b5b6106ee806100436000396000f300606060405236156100a95763ffffffff60e060020a6000350416630257c48c81146100ab57806306661abd146100d357806313af4035146100f55780631a0919dc1461011357806369fe0e2d146101285780638da5cb5b1461013d5780638eaa6ac01461016957806391cd242d1461019d5780639890220b146101b8578063c52bd836146101ca578063ddca3f43146101eb578063e0886f901461020d578063e1fa8e8414610241575bfe5b34156100b357fe5b6100c160043560243561024e565b60408051918252519081900360200190f35b34156100db57fe5b6100c1610272565b60408051918252519081900360200190f35b34156100fd57fe5b610111600160a060020a0360043516610279565b005b341561011b57fe5b6101116004356102ed565b005b341561013057fe5b610111600435610388565b005b341561014557fe5b61014d6103ad565b60408051600160a060020a039092168252519081900360200190f35b341561017157fe5b61017c6004356103bc565b60408051928352600160a060020a0390911660208301528051918290030190f35b34156101a557fe5b6101116004356024356044356103e4565b005b34156101c057fe5b61011161046d565b005b34156101d257fe5b610111600435600160a060020a03602435166104c0565b005b34156101f357fe5b6100c161054e565b60408051918252519081900360200190f35b341561021557fe5b61017c600435610554565b60408051928352600160a060020a0390911660208301528051918290030190f35b6101116004356105ab565b005b60008281526001602090815260408083208484526002019091529020545b92915050565b6002545b90565b60005433600160a060020a0390811691161461029457610000565b60008054604051600160a060020a03808516939216917f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236491a360008054600160a060020a031916600160a060020a0383161790555b5b50565b60008181526001602081905260409091200154819033600160a060020a0390811691161480159061032d575060005433600160a060020a03908116911614155b1561033757610000565b60008281526001602081905260408083208381559091018054600160a060020a03191690555183917fe17fec26316aebe957e188549d659a89f359c49766bcc0ae2fb7ded274ffe14691a25b5b5050565b60005433600160a060020a039081169116146103a357610000565b60038190555b5b50565b600054600160a060020a031681565b6000818152600160208190526040909120805491810154600160a060020a0316905b50915091565b60008381526001602081905260409091200154839033600160a060020a0390811691161461041157610000565b600084815260016020908152604080832086845260020182529182902084905581518481529151859287927f4dcd4fb147bb133a0da8fbf4e5fc3ddd64f04d4b3f6cbee584374b889d28c78d92918290030190a35b5b50505050565b60005433600160a060020a0390811691161461048857610000565b604051600160a060020a0333811691309091163180156108fc02916000818181858888f1935050505015156104bc57610000565b5b5b565b60008281526001602081905260409091200154829033600160a060020a039081169116146104ed57610000565b60008381526001602081905260408083209091018054600160a060020a031916600160a060020a0386169081179091559051909185917fd3d10d874a10020c2bce719499d1fd8756d880b128eb2945dd01b3830854e7169190a35b5b505050565b60035481565b6000600060006001600060028681548110151561056d57fe5b906000526020600020900160005b50548152602081019190915260400160002080546001820154909450600160a060020a0316925090505b50915091565b6003543410156105ba57610000565b6000818152600160205260409020548190156105d557610000565b60028054600181016105e78382610677565b916000526020600020900160005b508390555060408051808201825283815233600160a060020a0390811660208084018281526000888152600192839052868120955186559051949091018054600160a060020a0319169490931693909317909155915184917f7d917fcbc9a29a9705ff9936ffa599500e4fd902e4486bae317414fe967b307c91a35b5b505b50565b815481835581811511610548576000838152602090206105489181019083016106a1565b5b505050565b61027691905b808211156106bb57600081556001016106a7565b5090565b905600a165627a7a7230582011d8a45e381635e9de17e14cc4de97a1e17758cfac1fd25e8a5bc1d5f4d1da9d0029"
|
||||||
|
}
|
5
js/src/dapps/chaindeploy/contracts/code/gavcoin.json
Normal file
5
js/src/dapps/chaindeploy/contracts/code/gavcoin.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"compiler": "v0.4.9+commit.364da425",
|
||||||
|
"source": "https://github.com/ethcore/contracts/blob/58842b92c00e3c45a84b6d0ac9b842f016dde50a/GavCoin.sol",
|
||||||
|
"output": "0x606060405266038d7ea4c680006002556305f5e100600355341561001f57fe5b5b6108008061002f6000396000f300606060405236156100885763ffffffff60e060020a600035041663095ea7b3811461009f57806318160ddd146100d257806323b872dd146100f457806329cbdc861461012d57806355234ec0146101465780635af36e3e1461016857806370a0823114610192578063a035b1fe146101c0578063a9059cbb146101e2578063dd62ed3e14610215575b61009d5b61009a3360ff60020a610249565b5b565b005b34156100a757fe5b6100be600160a060020a0360043516602435610390565b604080519115158252519081900360200190f35b34156100da57fe5b6100e2610416565b60408051918252519081900360200190f35b34156100fc57fe5b6100be600160a060020a036004358116906024351660443561041c565b604080519115158252519081900360200190f35b61009d600160a060020a036004351660243561052a565b005b341561014e57fe5b6100e2610539565b60408051918252519081900360200190f35b341561017057fe5b6100be60043560243561053f565b604080519115158252519081900360200190f35b341561019a57fe5b6100e2600160a060020a03600435166106d0565b60408051918252519081900360200190f35b34156101c857fe5b6100e26106ef565b60408051918252519081900360200190f35b34156101ea57fe5b6100be600160a060020a03600435166024356106f5565b604080519115158252519081900360200190f35b341561021d57fe5b6100e2600160a060020a03600435811690602435166107a3565b60408051918252519081900360200190f35b34600080805b60008411801561026157508460025411155b1561038757600354600254620f424091025b0492508284116102835783610285565b825b9150600254620f4240830281151561029957fe5b33600160a060020a03166000818152600160208181526040808420805497909604968701865560028054855295830190915280832080548701905584548352808320909101805463ffffffff191662093a80420163ffffffff161790558154850182559254925193945084937f689dcb02b6a65e0e2f1d23ef47c1ec86604ffbed0bcb65f20150cfc7d5e5a9489190a4600380548290039081905593829003931515610382576002805466038d7ea4c6800001908190556305f5e1006003556040517f23c3dae768238f239632b5c4acb89485b440e0fa72481c4aad9f9b4f9b5a0a5f90600090a25b61024f565b5b505050505050565b600082600160a060020a031633600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a350600160a060020a0333811660009081526001602081815260408084209487168452600290940190529190208054830190555b92915050565b60005481565b600160a060020a038316600090815260016020526040812054849083908190101561044657610521565b600160a060020a0380871660009081526001602090815260408083203394851684526002019091529020548791908690819010156104835761051c565b87600160a060020a031689600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef896040518082815260200191505060405180910390a3600160a060020a03808a166000908152600160208181526040808420338616855260028101835281852080548e900390559183905281548c9003909155928b16825291902080548901905595505b5b5050505b50509392505050565b6105348282610249565b5b5050565b60035481565b600160a060020a0333166000908152600160208181526040808420868552909201905281205483908390819010806105a35750600160a060020a03331660009081526001602081815260408084208685528301909152909120015463ffffffff1642105b156105ad576106c8565b33600160a060020a0381166000908152600160205260409020548590819010156105d6576106c4565b60405186908890600160a060020a033316907f73f04af9dcc582a923ec15d3eea990fe34adabfff2879e28d44572e01a54abb690600090a433600160a060020a0316600090815260016020818152604080842080548b9003815584548b0185558b855290920190529020805487900390819055151561068457600160a060020a03331660009081526001602081815260408084208b85528301909152822091825501805463ffffffff191690555b600160a060020a0333166108fc620f4240888a025b604051919004801590920291906000818181858888f1935050505015156106bf57610000565b600194505b5b50505b505092915050565b600160a060020a0381166000908152600160205260409020545b919050565b60025481565b33600160a060020a038116600090815260016020526040812054909190839081901015610721576106c8565b84600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390a3600160a060020a03338116600090815260016020526040808220805488900390559187168152208054850190555b5b505092915050565b600160a060020a03808316600090815260016020908152604080832093851683526002909301905220545b929150505600a165627a7a72305820ca533a37c92e41888bda66ae0e66415d21a61c60027b269bca633d85b727875c0029"
|
||||||
|
}
|
5
js/src/dapps/chaindeploy/contracts/code/githubhint.json
Normal file
5
js/src/dapps/chaindeploy/contracts/code/githubhint.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"compiler": "v0.4.9+commit.364da425",
|
||||||
|
"source": "https://github.com/ethcore/contracts/blob/58842b92c00e3c45a84b6d0ac9b842f016dde50a/GithubHint.sol",
|
||||||
|
"output": "0x6060604052341561000c57fe5b5b6105868061001c6000396000f300606060405263ffffffff60e060020a60003504166302f2008d81146100425780632196ae0d1461009b578063267b6922146101055780637c8c6643146101c9575bfe5b341561004a57fe5b60408051602060046024803582810135601f810185900485028601850190965285855261009995833595939460449493929092019181908401838280828437509496506101de95505050505050565b005b34156100a357fe5b60408051602060046024803582810135601f81018590048502860185019096528585526100999583359593946044949392909201918190840183828082843750949650505092356bffffffffffffffffffffffff191692506102be915050565b005b341561010d57fe5b6101186004356103b1565b604080516bffffffffffffffffffffffff1984166020820152600160a060020a03831691810191909152606080825284546002600019610100600184161502019091160490820181905281906080820190869080156101b85780601f1061018d576101008083540402835291602001916101b8565b820191906000526020600020905b81548152906001019060200180831161019b57829003601f168201915b505094505050505060405180910390f35b34156101d157fe5b6100996004356103de565b005b6000828152602081905260409020600201548290600160a060020a031615801590610227575060008181526020819052604090206002015433600160a060020a03908116911614155b15610231576102b8565b6040805160608101825283815260006020808301829052600160a060020a0333168385015286825281815292902081518051929391926102749284920190610472565b506020820151600182018054606060020a909204600160a060020a031992831617905560409092015160029091018054600160a060020a0392909216919092161790555b5b505050565b6000838152602081905260409020600201548390600160a060020a031615801590610307575060008181526020819052604090206002015433600160a060020a03908116911614155b15610311576103aa565b604080516060810182528481526bffffffffffffffffffffffff198416602080830191909152600160a060020a0333168284015260008781528082529290922081518051929391926103669284920190610472565b506020820151600182018054606060020a909204600160a060020a031992831617905560409092015160029091018054600160a060020a0392909216919092161790555b5b50505050565b600060208190529081526040902060018101546002820154606060020a90910290600160a060020a031683565b6000818152602081905260409020600201548190600160a060020a031615801590610427575060008181526020819052604090206002015433600160a060020a03908116911614155b156104315761046d565b60008281526020819052604081209061044a82826104f1565b50600181018054600160a060020a03199081169091556002909101805490911690555b5b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106104b357805160ff19168380011785556104e0565b828001600101855582156104e0579182015b828111156104e05782518255916020019190600101906104c5565b5b506104ed929150610539565b5090565b50805460018160011615610100020316600290046000825580601f106105175750610535565b601f0160209004906000526020600020908101906105359190610539565b5b50565b61055791905b808211156104ed576000815560010161053f565b5090565b905600a165627a7a72305820a83571409e7b0cc4fe48edd09087f315930ab4e017c62b6d100462285a8f4ae70029"
|
||||||
|
}
|
5
js/src/dapps/chaindeploy/contracts/code/jg-voting.json
Normal file
5
js/src/dapps/chaindeploy/contracts/code/jg-voting.json
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