Merge branch 'master' into client-provider
This commit is contained in:
commit
6e1a1f9dec
175
.gitlab-ci.yml
175
.gitlab-ci.yml
@ -8,7 +8,6 @@ variables:
|
|||||||
RUST_BACKTRACE: "1"
|
RUST_BACKTRACE: "1"
|
||||||
RUSTFLAGS: ""
|
RUSTFLAGS: ""
|
||||||
CARGOFLAGS: ""
|
CARGOFLAGS: ""
|
||||||
NIGHTLY: "nigtly"
|
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
|
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
|
||||||
untracked: true
|
untracked: true
|
||||||
@ -21,7 +20,7 @@ linux-stable:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
- md5sum target/release/parity > parity.md5
|
- md5sum target/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh amd64
|
- sh scripts/deb-build.sh amd64
|
||||||
@ -31,10 +30,12 @@ linux-stable:
|
|||||||
- md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5"
|
- md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5"
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- aws configure set aws_secret_access_key $s3_secret
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity --body target/release/parity
|
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity.md5 --body parity.md5
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity --body target/release/parity
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity.md5 --body parity.md5
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-stable
|
- rust-stable
|
||||||
@ -51,7 +52,7 @@ linux-beta:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
@ -70,7 +71,7 @@ linux-nightly:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
@ -91,11 +92,13 @@ linux-centos:
|
|||||||
script:
|
script:
|
||||||
- export CXX="g++"
|
- export CXX="g++"
|
||||||
- export CC="gcc"
|
- export CC="gcc"
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||||
- strip target/release/parity
|
- strip target/release/parity
|
||||||
- md5sum target/release/parity > parity.md5
|
- md5sum target/release/parity > parity.md5
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- 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
|
||||||
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity --body target/release/parity
|
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity --body target/release/parity
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity.md5 --body parity.md5
|
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity.md5 --body parity.md5
|
||||||
tags:
|
tags:
|
||||||
@ -116,7 +119,7 @@ linux-i686:
|
|||||||
script:
|
script:
|
||||||
- export HOST_CC=gcc
|
- export HOST_CC=gcc
|
||||||
- export HOST_CXX=g++
|
- export HOST_CXX=g++
|
||||||
- cargo build --target i686-unknown-linux-gnu --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target i686-unknown-linux-gnu --release $CARGOFLAGS
|
||||||
- strip target/i686-unknown-linux-gnu/release/parity
|
- strip target/i686-unknown-linux-gnu/release/parity
|
||||||
- md5sum target/i686-unknown-linux-gnu/release/parity > parity.md5
|
- md5sum target/i686-unknown-linux-gnu/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh i386
|
- sh scripts/deb-build.sh i386
|
||||||
@ -126,10 +129,12 @@ linux-i686:
|
|||||||
- md5sum "parity_"$VER"_i386.deb" > "parity_"$VER"_i386.deb.md5"
|
- md5sum "parity_"$VER"_i386.deb" > "parity_"$VER"_i386.deb.md5"
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- aws configure set aws_secret_access_key $s3_secret
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity --body target/i686-unknown-linux-gnu/release/parity
|
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity.md5 --body parity.md5
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/i686-unknown-linux-gnu
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb" --body "parity_"$VER"_i386.deb"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity --body target/i686-unknown-linux-gnu/release/parity
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb.md5" --body "parity_"$VER"_i386.deb.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity.md5 --body parity.md5
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb" --body "parity_"$VER"_i386.deb"
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb.md5" --body "parity_"$VER"_i386.deb.md5"
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-i686
|
- rust-i686
|
||||||
@ -156,7 +161,7 @@ linux-armv7:
|
|||||||
- echo "[target.armv7-unknown-linux-gnueabihf]" >> .cargo/config
|
- echo "[target.armv7-unknown-linux-gnueabihf]" >> .cargo/config
|
||||||
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target armv7-unknown-linux-gnueabihf --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target armv7-unknown-linux-gnueabihf --release $CARGOFLAGS
|
||||||
- arm-linux-gnueabihf-strip target/armv7-unknown-linux-gnueabihf/release/parity
|
- arm-linux-gnueabihf-strip target/armv7-unknown-linux-gnueabihf/release/parity
|
||||||
- md5sum target/armv7-unknown-linux-gnueabihf/release/parity > parity.md5
|
- md5sum target/armv7-unknown-linux-gnueabihf/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh armhf
|
- sh scripts/deb-build.sh armhf
|
||||||
@ -166,10 +171,12 @@ linux-armv7:
|
|||||||
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
|
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- aws configure set aws_secret_access_key $s3_secret
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/parity --body target/armv7-unknown-linux-gnueabihf/release/parity
|
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/parity.md5 --body parity.md5
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb" --body "parity_"$VER"_armhf.deb"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/parity --body target/armv7-unknown-linux-gnueabihf/release/parity
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/parity.md5 --body parity.md5
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb" --body "parity_"$VER"_armhf.deb"
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-arm
|
- rust-arm
|
||||||
@ -196,7 +203,7 @@ linux-arm:
|
|||||||
- echo "[target.arm-unknown-linux-gnueabihf]" >> .cargo/config
|
- echo "[target.arm-unknown-linux-gnueabihf]" >> .cargo/config
|
||||||
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
- echo "linker= \"arm-linux-gnueabihf-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target arm-unknown-linux-gnueabihf --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target arm-unknown-linux-gnueabihf --release $CARGOFLAGS
|
||||||
- arm-linux-gnueabihf-strip target/arm-unknown-linux-gnueabihf/release/parity
|
- arm-linux-gnueabihf-strip target/arm-unknown-linux-gnueabihf/release/parity
|
||||||
- md5sum target/arm-unknown-linux-gnueabihf/release/parity > parity.md5
|
- md5sum target/arm-unknown-linux-gnueabihf/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh armhf
|
- sh scripts/deb-build.sh armhf
|
||||||
@ -206,10 +213,12 @@ linux-arm:
|
|||||||
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
|
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- aws configure set aws_secret_access_key $s3_secret
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/parity --body target/arm-unknown-linux-gnueabihf/release/parity
|
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/parity.md5 --body parity.md5
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb" --body "parity_"$VER"_armhf.deb"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/parity --body target/arm-unknown-linux-gnueabihf/release/parity
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/parity.md5 --body parity.md5
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb" --body "parity_"$VER"_armhf.deb"
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-arm
|
- rust-arm
|
||||||
@ -222,9 +231,9 @@ linux-armv6:
|
|||||||
stage: build
|
stage: build
|
||||||
image: ethcore/rust-armv6:latest
|
image: ethcore/rust-armv6:latest
|
||||||
only:
|
only:
|
||||||
- beta
|
# - beta
|
||||||
- tags
|
# - tags
|
||||||
- stable
|
# - stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- export CC=arm-linux-gnueabi-gcc
|
- export CC=arm-linux-gnueabi-gcc
|
||||||
@ -236,13 +245,15 @@ linux-armv6:
|
|||||||
- echo "[target.arm-unknown-linux-gnueabi]" >> .cargo/config
|
- echo "[target.arm-unknown-linux-gnueabi]" >> .cargo/config
|
||||||
- echo "linker= \"arm-linux-gnueabi-gcc\"" >> .cargo/config
|
- echo "linker= \"arm-linux-gnueabi-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target arm-unknown-linux-gnueabi --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target arm-unknown-linux-gnueabi --release $CARGOFLAGS
|
||||||
- arm-linux-gnueabi-strip target/arm-unknown-linux-gnueabi/release/parity
|
- arm-linux-gnueabi-strip target/arm-unknown-linux-gnueabi/release/parity
|
||||||
- md5sum target/arm-unknown-linux-gnueabi/release/parity > parity.md5
|
- md5sum target/arm-unknown-linux-gnueabi/release/parity > parity.md5
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- aws configure set aws_secret_access_key $s3_secret
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity --body target/arm-unknown-linux-gnueabi/release/parity
|
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity.md5 --body parity.md5
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity --body target/arm-unknown-linux-gnueabi/release/parity
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity.md5 --body parity.md5
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-arm
|
- rust-arm
|
||||||
@ -269,7 +280,7 @@ linux-aarch64:
|
|||||||
- echo "[target.aarch64-unknown-linux-gnu]" >> .cargo/config
|
- echo "[target.aarch64-unknown-linux-gnu]" >> .cargo/config
|
||||||
- echo "linker= \"aarch64-linux-gnu-gcc\"" >> .cargo/config
|
- echo "linker= \"aarch64-linux-gnu-gcc\"" >> .cargo/config
|
||||||
- cat .cargo/config
|
- cat .cargo/config
|
||||||
- cargo build --target aarch64-unknown-linux-gnu --release $CARGOFLAGS
|
- cargo build -j $(nproc) --target aarch64-unknown-linux-gnu --release $CARGOFLAGS
|
||||||
- aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/parity
|
- aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/parity
|
||||||
- md5sum target/aarch64-unknown-linux-gnu/release/parity > parity.md5
|
- md5sum target/aarch64-unknown-linux-gnu/release/parity > parity.md5
|
||||||
- sh scripts/deb-build.sh arm64
|
- sh scripts/deb-build.sh arm64
|
||||||
@ -279,10 +290,12 @@ linux-aarch64:
|
|||||||
- md5sum "parity_"$VER"_arm64.deb" > "parity_"$VER"_arm64.deb.md5"
|
- md5sum "parity_"$VER"_arm64.deb" > "parity_"$VER"_arm64.deb.md5"
|
||||||
- aws configure set aws_access_key_id $s3_key
|
- aws configure set aws_access_key_id $s3_key
|
||||||
- aws configure set aws_secret_access_key $s3_secret
|
- aws configure set aws_secret_access_key $s3_secret
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/parity --body target/aarch64-unknown-linux-gnu/release/parity
|
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/parity.md5 --body parity.md5
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/"parity_"$VER"_arm64.deb" --body "parity_"$VER"_arm64.deb"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/parity --body target/aarch64-unknown-linux-gnu/release/parity
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/"parity_"$VER"_arm64.deb.md5" --body "parity_"$VER"_arm64.deb.md5"
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/parity.md5 --body parity.md5
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/"parity_"$VER"_arm64.deb" --body "parity_"$VER"_arm64.deb"
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/"parity_"$VER"_arm64.deb.md5" --body "parity_"$VER"_arm64.deb.md5"
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-arm
|
- rust-arm
|
||||||
@ -299,13 +312,22 @@ darwin:
|
|||||||
- stable
|
- stable
|
||||||
- triggers
|
- triggers
|
||||||
script:
|
script:
|
||||||
- cargo build --release $CARGOFLAGS
|
- cargo build -j 8 --release -p ethstore #$CARGOFLAGS
|
||||||
|
- cargo build -j 8 --release #$CARGOFLAGS
|
||||||
- rm -rf parity.md5
|
- rm -rf parity.md5
|
||||||
- md5sum target/release/parity > parity.md5
|
- md5sum target/release/parity > parity.md5
|
||||||
|
- packagesbuild -v mac/Parity.pkgproj
|
||||||
|
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||||
|
- mv target/release/Parity\ Ethereum.pkg "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
||||||
|
- md5sum "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg" >> "parity-"$VER"-osx-installer-EXPERIMENTAL.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
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity --body target/release/parity
|
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||||
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity.md5 --body parity.md5
|
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-apple-darwin
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity --body target/release/parity
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity.md5 --body parity.md5
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg"
|
||||||
|
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/"parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5" --body "parity-"$VER"-osx-installer-EXPERIMENTAL.pkg.md5"
|
||||||
tags:
|
tags:
|
||||||
- osx
|
- osx
|
||||||
artifacts:
|
artifacts:
|
||||||
@ -328,7 +350,7 @@ windows:
|
|||||||
- set RUST_BACKTRACE=1
|
- set RUST_BACKTRACE=1
|
||||||
- set RUSTFLAGS=%RUSTFLAGS%
|
- set RUSTFLAGS=%RUSTFLAGS%
|
||||||
- rustup default stable-x86_64-pc-windows-msvc
|
- rustup default stable-x86_64-pc-windows-msvc
|
||||||
- cargo build --release %CARGOFLAGS%
|
- cargo build -j 8 --release #%CARGOFLAGS%
|
||||||
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll
|
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll
|
||||||
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe
|
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe
|
||||||
- signtool sign /f %keyfile% /p %certpass% target\release\parity.exe
|
- signtool sign /f %keyfile% /p %certpass% target\release\parity.exe
|
||||||
@ -349,14 +371,20 @@ windows:
|
|||||||
- cd ..\..
|
- cd ..\..
|
||||||
- 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%
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe --body target\release\parity.exe
|
- echo %CI_BUILD_REF_NAME%
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe.md5 --body target\release\parity.exe.md5
|
- echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.zip --body target\release\parity.zip
|
- echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.zip.md5 --body target\release\parity.zip.md5
|
- echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe --body nsis\InstallParity.exe
|
- echo %S3_BUCKET%
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe.md5 --body nsis\InstallParity.exe.md5
|
- aws s3 rm --recursive s3://%S3_BUCKET%/%CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip --body nsis\win-installer.zip
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe --body target\release\parity.exe
|
||||||
- aws s3api put-object --bucket builds-parity --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip.md5 --body nsis\win-installer.zip.md5
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe.md5 --body target\release\parity.exe.md5
|
||||||
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.zip --body target\release\parity.zip
|
||||||
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.zip.md5 --body target\release\parity.zip.md5
|
||||||
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe --body nsis\InstallParity.exe
|
||||||
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/InstallParity.exe.md5 --body nsis\InstallParity.exe.md5
|
||||||
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip --body nsis\win-installer.zip
|
||||||
|
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/win-installer.zip.md5 --body nsis\win-installer.zip.md5
|
||||||
tags:
|
tags:
|
||||||
- rust-windows
|
- rust-windows
|
||||||
artifacts:
|
artifacts:
|
||||||
@ -385,7 +413,7 @@ test-windows:
|
|||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
script:
|
script:
|
||||||
- set RUST_BACKTRACE=1
|
- set RUST_BACKTRACE=1
|
||||||
- cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release
|
- cargo -j 8 test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release
|
||||||
tags:
|
tags:
|
||||||
- rust-windows
|
- rust-windows
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
@ -394,13 +422,28 @@ test-rust-stable:
|
|||||||
image: ethcore/rust:stable
|
image: ethcore/rust:stable
|
||||||
before_script:
|
before_script:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only CI_BUILD_REF CI_BUILD_REF@{1} | grep \.js | wc -l)
|
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep \.js | wc -l)
|
||||||
- echo $JS_FILES_MODIFIED
|
- echo $JS_FILES_MODIFIED
|
||||||
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; fi
|
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js test"; else ./js/scripts/install-deps.sh;fi
|
||||||
script:
|
script:
|
||||||
- export RUST_BACKTRACE=1
|
- export RUST_BACKTRACE=1
|
||||||
- echo $JS_FILES_MODIFIED
|
- echo $JS_FILES_MODIFIED
|
||||||
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; else ./test.sh $CARGOFLAGS --no-release; fi
|
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js test"&./test.sh $CARGOFLAGS --no-release; else echo "skip rust test"&./js/scripts/lint.sh&./js/scripts/test.sh&./js/scripts/build.sh; fi
|
||||||
|
tags:
|
||||||
|
- rust
|
||||||
|
- rust-stable
|
||||||
|
js-test:
|
||||||
|
stage: test
|
||||||
|
image: ethcore/rust:stable
|
||||||
|
before_script:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep \.js | wc -l)
|
||||||
|
- echo $JS_FILES_MODIFIED
|
||||||
|
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js test"; else ./js/scripts/install-deps.sh;fi
|
||||||
|
script:
|
||||||
|
- export RUST_BACKTRACE=1
|
||||||
|
- echo $JS_FILES_MODIFIED
|
||||||
|
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js test"; else echo "skip rust test"&./js/scripts/lint.sh&./js/scripts/test.sh&./js/scripts/build.sh; fi
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-stable
|
- rust-stable
|
||||||
@ -411,13 +454,10 @@ test-rust-beta:
|
|||||||
image: ethcore/rust:beta
|
image: ethcore/rust:beta
|
||||||
before_script:
|
before_script:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only CI_BUILD_REF CI_BUILD_REF@{1} | grep \.js | wc -l)
|
|
||||||
- echo $JS_FILES_MODIFIED
|
|
||||||
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; fi
|
|
||||||
script:
|
script:
|
||||||
- export RUST_BACKTRACE=1
|
- export RUST_BACKTRACE=1
|
||||||
- echo $JS_FILES_MODIFIED
|
- echo $JS_FILES_MODIFIED
|
||||||
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; else ./test.sh $CARGOFLAGS --no-release; fi
|
- ./test.sh $CARGOFLAGS --no-release
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-beta
|
- rust-beta
|
||||||
@ -429,28 +469,13 @@ test-rust-nightly:
|
|||||||
image: ethcore/rust:nightly
|
image: ethcore/rust:nightly
|
||||||
before_script:
|
before_script:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only CI_BUILD_REF CI_BUILD_REF@{1} | grep \.js | wc -l)
|
|
||||||
- echo $JS_FILES_MODIFIED
|
|
||||||
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; fi
|
|
||||||
script:
|
script:
|
||||||
- export RUST_BACKTRACE=1
|
- export RUST_BACKTRACE=1
|
||||||
- echo $JS_FILES_MODIFIED
|
- ./test.sh $CARGOFLAGS --no-release
|
||||||
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; else ./test.sh $CARGOFLAGS --no-release; fi
|
|
||||||
tags:
|
tags:
|
||||||
- rust
|
- rust
|
||||||
- rust-nightly
|
- rust-nightly
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
js-tests:
|
|
||||||
stage: test
|
|
||||||
image: ethcore/rust:stable
|
|
||||||
before_script:
|
|
||||||
- ./js/scripts/install-deps.sh
|
|
||||||
script:
|
|
||||||
- ./js/scripts/lint.sh
|
|
||||||
- ./js/scripts/test.sh
|
|
||||||
- ./js/scripts/build.sh
|
|
||||||
tags:
|
|
||||||
- javascript-test
|
|
||||||
js-release:
|
js-release:
|
||||||
stage: js-build
|
stage: js-build
|
||||||
only:
|
only:
|
||||||
@ -459,9 +484,11 @@ js-release:
|
|||||||
- stable
|
- stable
|
||||||
image: ethcore/rust:stable
|
image: ethcore/rust:stable
|
||||||
before_script:
|
before_script:
|
||||||
- if [[ $NIGHTLY != "master" ]]; then ./js/scripts/install-deps.sh; fi
|
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep \.js | wc -l)
|
||||||
|
- echo $JS_FILES_MODIFIED
|
||||||
|
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js build"; else ./js/scripts/install-deps.sh;fi
|
||||||
script:
|
script:
|
||||||
- if [[ $NIGHTLY != "master" ]]; then ./js/scripts/build.sh; fi
|
- echo $JS_FILES_MODIFIED
|
||||||
- if [[ $NIGHTLY != "master" ]]; then ./js/scripts/release.sh; fi
|
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js build"; else ./js/scripts/build.sh&&./js/scripts/release.sh; fi
|
||||||
tags:
|
tags:
|
||||||
- javascript
|
- javascript
|
||||||
|
36
Cargo.lock
generated
36
Cargo.lock
generated
@ -3,7 +3,7 @@ name = "parity"
|
|||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)",
|
"ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)",
|
||||||
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -146,15 +146,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.0.96"
|
version = "0.0.103"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy_lints 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.0.96"
|
version = "0.0.103"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -224,7 +224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "elastic-array"
|
name = "elastic-array"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/ethcore/elastic-array#70e4012e691b732c7c4cb04e9232799e6aa268bc"
|
source = "git+https://github.com/ethcore/elastic-array#346f1ba5982576dab9d0b8fa178b50e1db0a21cd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -280,7 +280,7 @@ dependencies = [
|
|||||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.4.0",
|
"ethash 1.4.0",
|
||||||
@ -334,7 +334,7 @@ dependencies = [
|
|||||||
name = "ethcore-dapps"
|
name = "ethcore-dapps"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-devtools 1.4.0",
|
"ethcore-devtools 1.4.0",
|
||||||
"ethcore-hash-fetch 1.5.0",
|
"ethcore-hash-fetch 1.5.0",
|
||||||
@ -386,7 +386,7 @@ version = "1.5.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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.6.1 (git+https://github.com/carllerche/mio)",
|
"mio 0.6.1 (git+https://github.com/ethcore/mio)",
|
||||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -476,7 +476,7 @@ dependencies = [
|
|||||||
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.16 (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.6.1 (git+https://github.com/carllerche/mio)",
|
"mio 0.6.1 (git+https://github.com/ethcore/mio)",
|
||||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.5 (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",
|
||||||
@ -491,7 +491,7 @@ dependencies = [
|
|||||||
name = "ethcore-rpc"
|
name = "ethcore-rpc"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.4.0",
|
"ethash 1.4.0",
|
||||||
"ethcore 1.5.0",
|
"ethcore 1.5.0",
|
||||||
"ethcore-devtools 1.4.0",
|
"ethcore-devtools 1.4.0",
|
||||||
@ -521,7 +521,7 @@ dependencies = [
|
|||||||
name = "ethcore-signer"
|
name = "ethcore-signer"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-devtools 1.4.0",
|
"ethcore-devtools 1.4.0",
|
||||||
"ethcore-io 1.5.0",
|
"ethcore-io 1.5.0",
|
||||||
@ -560,7 +560,7 @@ version = "1.5.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"elastic-array 0.6.0 (git+https://github.com/ethcore/elastic-array)",
|
"elastic-array 0.6.0 (git+https://github.com/ethcore/elastic-array)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
|
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
|
||||||
@ -650,7 +650,7 @@ dependencies = [
|
|||||||
name = "ethsync"
|
name = "ethsync"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.5.0",
|
"ethcore 1.5.0",
|
||||||
"ethcore-io 1.5.0",
|
"ethcore-io 1.5.0",
|
||||||
@ -1027,7 +1027,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
source = "git+https://github.com/carllerche/mio#56f8663510196fdca04bdf7c5f4d60b24297826f"
|
source = "git+https://github.com/ethcore/mio#ef182bae193a9c7457cd2cf661fcaffb226e3eef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1264,7 +1264,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#587684374a12bf715151dd987a552a3d61e42972"
|
source = "git+https://github.com/ethcore/js-precompiled.git#a5a1c15f4d125654e1d1cdcb6b7f92a606f1d2d0"
|
||||||
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)",
|
||||||
]
|
]
|
||||||
@ -2006,8 +2006,8 @@ dependencies = [
|
|||||||
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
||||||
"checksum bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)" = "<none>"
|
"checksum bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)" = "<none>"
|
||||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||||
"checksum clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)" = "6eacf01b0aad84a0817703498f72d252df7c0faf6a5b86d0be4265f1829e459f"
|
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
|
||||||
"checksum clippy_lints 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)" = "a49960c9aab544ce86b004dcb61620e8b898fea5fc0f697a028f460f48221ed6"
|
"checksum clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "ce96ec05bfe018a0d5d43da115e54850ea2217981ff0f2e462780ab9d594651a"
|
||||||
"checksum cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90266f45846f14a1e986c77d1e9c2626b8c342ed806fe60241ec38cc8697b245"
|
"checksum cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90266f45846f14a1e986c77d1e9c2626b8c342ed806fe60241ec38cc8697b245"
|
||||||
"checksum crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "fb974f835e90390c5f9dfac00f05b06dc117299f5ea4e85fbc7bb443af4911cc"
|
"checksum crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "fb974f835e90390c5f9dfac00f05b06dc117299f5ea4e85fbc7bb443af4911cc"
|
||||||
"checksum ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)" = "<none>"
|
"checksum ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)" = "<none>"
|
||||||
@ -2054,7 +2054,7 @@ dependencies = [
|
|||||||
"checksum mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)" = "<none>"
|
"checksum mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)" = "<none>"
|
||||||
"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e"
|
"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e"
|
||||||
"checksum mio 0.6.0-dev (git+https://github.com/ethcore/mio?branch=timer-fix)" = "<none>"
|
"checksum mio 0.6.0-dev (git+https://github.com/ethcore/mio?branch=timer-fix)" = "<none>"
|
||||||
"checksum mio 0.6.1 (git+https://github.com/carllerche/mio)" = "<none>"
|
"checksum mio 0.6.1 (git+https://github.com/ethcore/mio)" = "<none>"
|
||||||
"checksum miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bfc6782530ac8ace97af10a540054a37126b63b0702ddaaa243b73b5745b9a"
|
"checksum miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bfc6782530ac8ace97af10a540054a37126b63b0702ddaaa243b73b5745b9a"
|
||||||
"checksum msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c04b68cc63a8480fb2550343695f7be72effdec953a9d4508161c3e69041c7d8"
|
"checksum msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c04b68cc63a8480fb2550343695f7be72effdec953a9d4508161c3e69041c7d8"
|
||||||
"checksum nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)" = "<none>"
|
"checksum nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)" = "<none>"
|
||||||
|
@ -47,7 +47,7 @@ ethcore-hash-fetch = { path = "ethcore/hash-fetch" }
|
|||||||
rlp = { path = "util/rlp" }
|
rlp = { path = "util/rlp" }
|
||||||
ethcore-stratum = { path = "stratum" }
|
ethcore-stratum = { path = "stratum" }
|
||||||
ethcore-dapps = { path = "dapps", optional = true }
|
ethcore-dapps = { path = "dapps", optional = true }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.2"
|
winapi = "0.2"
|
||||||
|
@ -34,7 +34,7 @@ ethcore-hash-fetch = { path = "../ethcore/hash-fetch" }
|
|||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
parity-ui = { path = "./ui" }
|
parity-ui = { path = "./ui" }
|
||||||
|
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde_codegen = { version = "0.8", optional = true }
|
serde_codegen = { version = "0.8", optional = true }
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
use endpoint::EndpointInfo;
|
use endpoint::EndpointInfo;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -54,6 +55,7 @@ impl Into<EndpointInfo> for App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ApiError {
|
pub struct ApiError {
|
||||||
pub code: String,
|
pub code: String,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -11,7 +11,7 @@ build = "build.rs"
|
|||||||
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
|
||||||
|
@ -3,6 +3,7 @@ WORKDIR /build
|
|||||||
# install tools and dependencies
|
# install tools and dependencies
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y \
|
apt-get install -y \
|
||||||
|
build-essential \
|
||||||
g++ \
|
g++ \
|
||||||
curl \
|
curl \
|
||||||
git \
|
git \
|
||||||
|
@ -4,6 +4,7 @@ WORKDIR /build
|
|||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y \
|
apt-get install -y \
|
||||||
g++ \
|
g++ \
|
||||||
|
build-essential \
|
||||||
curl \
|
curl \
|
||||||
git \
|
git \
|
||||||
file \
|
file \
|
||||||
|
@ -29,7 +29,7 @@ byteorder = "0.5"
|
|||||||
transient-hashmap = "0.1"
|
transient-hashmap = "0.1"
|
||||||
linked-hash-map = "0.3.0"
|
linked-hash-map = "0.3.0"
|
||||||
evmjit = { path = "../evmjit", optional = true }
|
evmjit = { path = "../evmjit", optional = true }
|
||||||
clippy = { version = "0.0.96", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore-io = { path = "../util/io" }
|
ethcore-io = { path = "../util/io" }
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
"generic": {
|
"generic": {
|
||||||
"fields": 1,
|
"fields": 2,
|
||||||
"rlp": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
|
"rlp": "0x200"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"difficulty": "0x20000",
|
"difficulty": "0x20000",
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"difficultyBoundDivisor": "0x0800",
|
"difficultyBoundDivisor": "0x0800",
|
||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d",
|
"registrar": "0x81a4b044831c4f12ba601adb9274516939e9b8a2",
|
||||||
"homesteadTransition": 0,
|
"homesteadTransition": 0,
|
||||||
"eip150Transition": 0,
|
"eip150Transition": 0,
|
||||||
"eip155Transition": 10,
|
"eip155Transition": 10,
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 9028c4801fd39fbb71a9796979182549a24e81c8
|
Subproject commit d509c75936ec6cbba683ee1916aa0bca436bc376
|
@ -11,9 +11,9 @@
|
|||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
"ethereum": {
|
"generic": {
|
||||||
"nonce": "0x00006d6f7264656e",
|
"fields": 0,
|
||||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
|
"rlp": "0x0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"difficulty": "0x20000",
|
"difficulty": "0x20000",
|
||||||
|
@ -121,10 +121,6 @@ impl<'db> HashDB for AccountDB<'db>{
|
|||||||
fn remove(&mut self, _key: &H256) {
|
fn remove(&mut self, _key: &H256) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_aux(&self, hash: &[u8]) -> Option<DBValue> {
|
|
||||||
self.db.get_aux(hash)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DB backend wrapper for Account trie
|
/// DB backend wrapper for Account trie
|
||||||
@ -197,18 +193,6 @@ impl<'db> HashDB for AccountDBMut<'db>{
|
|||||||
let key = combine_key(&self.address_hash, key);
|
let key = combine_key(&self.address_hash, key);
|
||||||
self.db.remove(&key)
|
self.db.remove(&key)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_aux(&mut self, hash: Vec<u8>, value: Vec<u8>) {
|
|
||||||
self.db.insert_aux(hash, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_aux(&self, hash: &[u8]) -> Option<DBValue> {
|
|
||||||
self.db.get_aux(hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_aux(&mut self, hash: &[u8]) {
|
|
||||||
self.db.remove_aux(hash);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Wrapping<'db>(&'db HashDB);
|
struct Wrapping<'db>(&'db HashDB);
|
||||||
|
@ -276,14 +276,20 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the password for `account` is `password`. `false` if not.
|
/// Returns `true` if the password for `account` is `password`. `false` if not.
|
||||||
pub fn test_password(&self, account: &Address, password: String) -> Result<bool, Error> {
|
pub fn test_password(&self, account: &Address, password: &str) -> Result<bool, Error> {
|
||||||
match self.sstore.sign(account, &password, &Default::default()) {
|
match self.sstore.sign(account, password, &Default::default()) {
|
||||||
Ok(_) => Ok(true),
|
Ok(_) => Ok(true),
|
||||||
Err(SSError::InvalidPassword) => Ok(false),
|
Err(SSError::InvalidPassword) => Ok(false),
|
||||||
Err(e) => Err(Error::SStore(e)),
|
Err(e) => Err(Error::SStore(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Permanently removes an account.
|
||||||
|
pub fn kill_account(&self, account: &Address, password: &str) -> Result<(), Error> {
|
||||||
|
try!(self.sstore.remove_account(account, &password));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Changes the password of `account` from `password` to `new_password`. Fails if incorrect `password` given.
|
/// Changes the password of `account` from `password` to `new_password`. Fails if incorrect `password` given.
|
||||||
pub fn change_password(&self, account: &Address, password: String, new_password: String) -> Result<(), Error> {
|
pub fn change_password(&self, account: &Address, password: String, new_password: String) -> Result<(), Error> {
|
||||||
self.sstore.change_password(account, &password, &new_password).map_err(Error::SStore)
|
self.sstore.change_password(account, &password, &new_password).map_err(Error::SStore)
|
||||||
|
@ -594,9 +594,9 @@ mod tests {
|
|||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use views::BlockView;
|
use views::BlockView;
|
||||||
use util::Address;
|
use util::{Address, TrieFactory};
|
||||||
use util::hash::FixedHash;
|
use util::hash::FixedHash;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
@ -637,7 +637,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
@ -653,7 +653,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
|
||||||
.close_and_lock().seal(engine, vec![]).unwrap();
|
.close_and_lock().seal(engine, vec![]).unwrap();
|
||||||
@ -662,7 +662,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
||||||
|
|
||||||
assert_eq!(e.rlp_bytes(), orig_bytes);
|
assert_eq!(e.rlp_bytes(), orig_bytes);
|
||||||
@ -681,7 +681,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let mut uncle1_header = Header::new();
|
let mut uncle1_header = Header::new();
|
||||||
@ -697,7 +697,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap();
|
||||||
|
|
||||||
let bytes = e.rlp_bytes();
|
let bytes = e.rlp_bytes();
|
||||||
|
@ -140,7 +140,7 @@ pub trait BlockProvider {
|
|||||||
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockNumber, to_block: BlockNumber) -> Vec<BlockNumber>;
|
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockNumber, to_block: BlockNumber) -> Vec<BlockNumber>;
|
||||||
|
|
||||||
/// Returns logs matching given filter.
|
/// Returns logs matching given filter.
|
||||||
fn logs<F>(&self, mut blocks: Vec<BlockNumber>, matches: F, limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
fn logs<F>(&self, blocks: Vec<BlockNumber>, matches: F, limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
||||||
where F: Fn(&LogEntry) -> bool, Self: Sized;
|
where F: Fn(&LogEntry) -> bool, Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ use std::time::{Instant};
|
|||||||
use time::precise_time_ns;
|
use time::precise_time_ns;
|
||||||
|
|
||||||
// util
|
// util
|
||||||
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock};
|
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, Hashable};
|
||||||
use util::{journaldb, TrieFactory, Trie};
|
use util::{journaldb, TrieFactory, Trie};
|
||||||
use util::trie::TrieSpec;
|
use util::trie::TrieSpec;
|
||||||
use util::{U256, H256, Address, H2048, Uint, FixedHash};
|
use util::{U256, H256, Address, H2048, Uint, FixedHash};
|
||||||
@ -173,9 +173,10 @@ impl Client {
|
|||||||
false => TrieSpec::Secure,
|
false => TrieSpec::Secure,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let trie_factory = TrieFactory::new(trie_spec);
|
||||||
let journal_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
let journal_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
||||||
let mut state_db = StateDB::new(journal_db, config.state_cache_size);
|
let mut state_db = StateDB::new(journal_db, config.state_cache_size);
|
||||||
if state_db.journal_db().is_empty() && try!(spec.ensure_db_good(&mut state_db)) {
|
if state_db.journal_db().is_empty() && try!(spec.ensure_db_good(&mut state_db, &trie_factory)) {
|
||||||
let mut batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
try!(state_db.journal_under(&mut batch, 0, &spec.genesis_header().hash()));
|
try!(state_db.journal_under(&mut batch, 0, &spec.genesis_header().hash()));
|
||||||
try!(db.write(batch).map_err(ClientError::Database));
|
try!(db.write(batch).map_err(ClientError::Database));
|
||||||
@ -217,7 +218,7 @@ impl Client {
|
|||||||
|
|
||||||
let factories = Factories {
|
let factories = Factories {
|
||||||
vm: EvmFactory::new(config.vm_type.clone(), config.jump_table_size),
|
vm: EvmFactory::new(config.vm_type.clone(), config.jump_table_size),
|
||||||
trie: TrieFactory::new(trie_spec),
|
trie: trie_factory,
|
||||||
accountdb: Default::default(),
|
accountdb: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -870,8 +871,8 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn keep_alive(&self) {
|
fn keep_alive(&self) {
|
||||||
let should_wake = match &*self.mode.lock() {
|
let should_wake = match *self.mode.lock() {
|
||||||
&Mode::Dark(..) | &Mode::Passive(..) => true,
|
Mode::Dark(..) | Mode::Passive(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if should_wake {
|
if should_wake {
|
||||||
@ -953,6 +954,10 @@ impl BlockChainClient for Client {
|
|||||||
self.state_at(id).map(|s| s.nonce(address))
|
self.state_at(id).map(|s| s.nonce(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_root(&self, address: &Address, id: BlockID) -> Option<H256> {
|
||||||
|
self.state_at(id).and_then(|s| s.storage_root(address))
|
||||||
|
}
|
||||||
|
|
||||||
fn block_hash(&self, id: BlockID) -> Option<H256> {
|
fn block_hash(&self, id: BlockID) -> Option<H256> {
|
||||||
let chain = self.chain.read();
|
let chain = self.chain.read();
|
||||||
Self::block_hash(&chain, id)
|
Self::block_hash(&chain, id)
|
||||||
@ -970,7 +975,7 @@ impl BlockChainClient for Client {
|
|||||||
self.state_at(id).map(|s| s.storage_at(address, position))
|
self.state_at(id).map(|s| s.storage_at(address, position))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_accounts(&self, id: BlockID) -> Option<Vec<Address>> {
|
fn list_accounts(&self, id: BlockID, after: Option<&Address>, count: u64) -> Option<Vec<Address>> {
|
||||||
if !self.factories.trie.is_fat() {
|
if !self.factories.trie.is_fat() {
|
||||||
trace!(target: "fatdb", "list_accounts: Not a fat DB");
|
trace!(target: "fatdb", "list_accounts: Not a fat DB");
|
||||||
return None;
|
return None;
|
||||||
@ -990,18 +995,68 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let iter = match trie.iter() {
|
let mut iter = match trie.iter() {
|
||||||
Ok(iter) => iter,
|
Ok(iter) => iter,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(after) = after {
|
||||||
|
if let Err(e) = iter.seek(after) {
|
||||||
|
trace!(target: "fatdb", "list_accounts: Couldn't seek the DB: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let accounts = iter.filter_map(|item| {
|
let accounts = iter.filter_map(|item| {
|
||||||
item.ok().map(|(addr, _)| Address::from_slice(&addr))
|
item.ok().map(|(addr, _)| Address::from_slice(&addr))
|
||||||
}).collect();
|
}).take(count as usize).collect();
|
||||||
|
|
||||||
Some(accounts)
|
Some(accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn list_storage(&self, id: BlockID, account: &Address, after: Option<&H256>, count: u64) -> Option<Vec<H256>> {
|
||||||
|
if !self.factories.trie.is_fat() {
|
||||||
|
trace!(target: "fatdb", "list_stroage: Not a fat DB");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let state = match self.state_at(id) {
|
||||||
|
Some(state) => state,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let root = match state.storage_root(account) {
|
||||||
|
Some(root) => root,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (_, db) = state.drop();
|
||||||
|
let account_db = self.factories.accountdb.readonly(db.as_hashdb(), account.sha3());
|
||||||
|
let trie = match self.factories.trie.readonly(account_db.as_hashdb(), &root) {
|
||||||
|
Ok(trie) => trie,
|
||||||
|
_ => {
|
||||||
|
trace!(target: "fatdb", "list_storage: Couldn't open the DB");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut iter = match trie.iter() {
|
||||||
|
Ok(iter) => iter,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(after) = after {
|
||||||
|
if let Err(e) = iter.seek(after) {
|
||||||
|
trace!(target: "fatdb", "list_accounts: Couldn't seek the DB: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let keys = iter.filter_map(|item| {
|
||||||
|
item.ok().map(|(key, _)| H256::from_slice(&key))
|
||||||
|
}).take(count as usize).collect();
|
||||||
|
|
||||||
|
Some(keys)
|
||||||
|
}
|
||||||
|
|
||||||
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction> {
|
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction> {
|
||||||
self.transaction_address(id).and_then(|address| self.chain.read().transaction(&address))
|
self.transaction_address(id).and_then(|address| self.chain.read().transaction(&address))
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
|||||||
let genesis_header = self.spec.genesis_header();
|
let genesis_header = self.spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
self.spec.ensure_db_good(&mut db).unwrap();
|
self.spec.ensure_db_good(&mut db, &TrieFactory::default()).unwrap();
|
||||||
|
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let mut open_block = OpenBlock::new(
|
let mut open_block = OpenBlock::new(
|
||||||
@ -386,6 +386,10 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_root(&self, _address: &Address, _id: BlockID) -> Option<H256> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn latest_nonce(&self, address: &Address) -> U256 {
|
fn latest_nonce(&self, address: &Address) -> U256 {
|
||||||
self.nonce(address, BlockID::Latest).unwrap()
|
self.nonce(address, BlockID::Latest).unwrap()
|
||||||
}
|
}
|
||||||
@ -417,10 +421,13 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_accounts(&self, _id: BlockID) -> Option<Vec<Address>> {
|
fn list_accounts(&self, _id: BlockID, _after: Option<&Address>, _count: u64) -> Option<Vec<Address>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn list_storage(&self, _id: BlockID, _account: &Address, _after: Option<&H256>, _count: u64) -> Option<Vec<H256>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
fn transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
|
fn transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
|
||||||
None // Simple default.
|
None // Simple default.
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,10 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// May not fail on BlockID::Latest.
|
/// May not fail on BlockID::Latest.
|
||||||
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256>;
|
fn nonce(&self, address: &Address, id: BlockID) -> Option<U256>;
|
||||||
|
|
||||||
|
/// Attempt to get address storage root at given block.
|
||||||
|
/// May not fail on BlockID::Latest.
|
||||||
|
fn storage_root(&self, address: &Address, id: BlockID) -> Option<H256>;
|
||||||
|
|
||||||
/// Get address nonce at the latest block's state.
|
/// Get address nonce at the latest block's state.
|
||||||
fn latest_nonce(&self, address: &Address) -> U256 {
|
fn latest_nonce(&self, address: &Address) -> U256 {
|
||||||
self.nonce(address, BlockID::Latest)
|
self.nonce(address, BlockID::Latest)
|
||||||
@ -115,7 +119,12 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`.
|
/// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`.
|
||||||
fn list_accounts(&self, id: BlockID) -> Option<Vec<Address>>;
|
/// If `after` is set the list starts with the following item.
|
||||||
|
fn list_accounts(&self, id: BlockID, after: Option<&Address>, count: u64) -> Option<Vec<Address>>;
|
||||||
|
|
||||||
|
/// Get a list of all storage keys in the block `id`, if fat DB is in operation, otherwise `None`.
|
||||||
|
/// If `after` is set the list starts with the following item.
|
||||||
|
fn list_storage(&self, id: BlockID, account: &Address, after: Option<&H256>, count: u64) -> Option<Vec<H256>>;
|
||||||
|
|
||||||
/// Get transaction with given hash.
|
/// Get transaction with given hash.
|
||||||
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction>;
|
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction>;
|
||||||
|
@ -124,7 +124,7 @@ impl AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn step_proposer(&self, step: usize) -> &Address {
|
fn step_proposer(&self, step: usize) -> &Address {
|
||||||
let ref p = self.our_params;
|
let p = &self.our_params;
|
||||||
p.authorities.get(step % p.authority_n).expect("There are authority_n authorities; taking number modulo authority_n gives number in authority_n range; qed")
|
p.authorities.get(step % p.authority_n).expect("There are authority_n authorities; taking number modulo authority_n gives number in authority_n range; qed")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ impl Engine for AuthorityRound {
|
|||||||
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
|
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
|
||||||
|
|
||||||
fn is_sealer(&self, author: &Address) -> Option<bool> {
|
fn is_sealer(&self, author: &Address) -> Option<bool> {
|
||||||
let ref p = self.our_params;
|
let p = &self.our_params;
|
||||||
Some(p.authorities.contains(author))
|
Some(p.authorities.contains(author))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,8 +254,8 @@ impl Engine for AuthorityRound {
|
|||||||
|
|
||||||
/// Check if the signature belongs to the correct proposer.
|
/// Check if the signature belongs to the correct proposer.
|
||||||
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||||
let header_step = try!(header_step(header));
|
let header_step = try!(header_step(header));
|
||||||
// Give one step slack if step is lagging, double vote is still not possible.
|
// Give one step slack if step is lagging, double vote is still not possible.
|
||||||
if header_step <= self.step() + 1 {
|
if header_step <= self.step() + 1 {
|
||||||
let proposer_signature = try!(header_signature(header));
|
let proposer_signature = try!(header_signature(header));
|
||||||
let ok_sig = try!(verify_address(self.step_proposer(header_step), &proposer_signature, &header.bare_hash()));
|
let ok_sig = try!(verify_address(self.step_proposer(header_step), &proposer_signature, &header.bare_hash()));
|
||||||
@ -315,6 +315,7 @@ impl Engine for AuthorityRound {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use header::Header;
|
use header::Header;
|
||||||
use error::{Error, BlockError};
|
use error::{Error, BlockError};
|
||||||
@ -384,9 +385,9 @@ mod tests {
|
|||||||
let engine = &*spec.engine;
|
let engine = &*spec.engine;
|
||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db1 = get_temp_state_db().take();
|
let mut db1 = get_temp_state_db().take();
|
||||||
spec.ensure_db_good(&mut db1).unwrap();
|
spec.ensure_db_good(&mut db1, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let mut db2 = get_temp_state_db().take();
|
let mut db2 = get_temp_state_db().take();
|
||||||
spec.ensure_db_good(&mut db2).unwrap();
|
spec.ensure_db_good(&mut db2, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b1 = b1.close_and_lock();
|
let b1 = b1.close_and_lock();
|
||||||
@ -417,13 +418,13 @@ mod tests {
|
|||||||
let engine = Spec::new_test_round().engine;
|
let engine = Spec::new_test_round().engine;
|
||||||
|
|
||||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||||
let mut step = UNIX_EPOCH.elapsed().unwrap().as_secs();
|
let time = UNIX_EPOCH.elapsed().unwrap().as_secs();
|
||||||
|
// Two authorities.
|
||||||
|
let mut step = time - time % 2;
|
||||||
header.set_seal(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
header.set_seal(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||||
let first_ok = engine.verify_block_seal(&header).is_ok();
|
assert!(engine.verify_block_seal(&header).is_err());
|
||||||
step = step + 1;
|
step = step + 1;
|
||||||
header.set_seal(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
header.set_seal(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||||
let second_ok = engine.verify_block_seal(&header).is_ok();
|
assert!(engine.verify_block_seal(&header).is_ok());
|
||||||
|
|
||||||
assert!(first_ok ^ second_ok);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,7 @@ impl Engine for BasicAuthority {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use block::*;
|
use block::*;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use error::{BlockError, Error};
|
use error::{BlockError, Error};
|
||||||
@ -256,7 +257,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
|
@ -68,6 +68,7 @@ impl Engine for InstantSeal {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
@ -84,7 +85,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
|
@ -422,6 +422,7 @@ impl Header {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use block::*;
|
use block::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
@ -438,7 +439,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
@ -452,7 +453,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||||
let mut uncle = Header::new();
|
let mut uncle = Header::new();
|
||||||
|
@ -72,6 +72,7 @@ pub fn new_morden() -> Spec { load(include_bytes!("../../res/ethereum/morden.jso
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use state::*;
|
use state::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
@ -84,7 +85,7 @@ mod tests {
|
|||||||
let genesis_header = spec.genesis_header();
|
let genesis_header = spec.genesis_header();
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(&mut db).unwrap();
|
spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap();
|
let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap();
|
||||||
assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()), 1u64.into());
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()), 1u64.into());
|
||||||
assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()), 1u64.into());
|
assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()), 1u64.into());
|
||||||
|
@ -197,19 +197,17 @@ impl<Gas: CostType> Gasometer<Gas> {
|
|||||||
let address = u256_to_address(stack.peek(1));
|
let address = u256_to_address(stack.peek(1));
|
||||||
let is_value_transfer = !stack.peek(2).is_zero();
|
let is_value_transfer = !stack.peek(2).is_zero();
|
||||||
|
|
||||||
if instruction == instructions::CALL {
|
if instruction == instructions::CALL && (
|
||||||
if (
|
(!schedule.no_empty && !ext.exists(&address))
|
||||||
!schedule.no_empty && !ext.exists(&address)
|
||
|
||||||
) || (
|
(schedule.no_empty && is_value_transfer && !ext.exists_and_not_null(&address))
|
||||||
schedule.no_empty && is_value_transfer && !ext.exists_and_not_null(&address)
|
) {
|
||||||
) {
|
gas = overflowing!(gas.overflow_add(schedule.call_new_account_gas.into()));
|
||||||
gas = overflowing!(gas.overflow_add(schedule.call_new_account_gas.into()));
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if is_value_transfer {
|
if is_value_transfer {
|
||||||
gas = overflowing!(gas.overflow_add(schedule.call_value_transfer_gas.into()));
|
gas = overflowing!(gas.overflow_add(schedule.call_value_transfer_gas.into()));
|
||||||
};
|
}
|
||||||
|
|
||||||
let requested = *stack.peek(0);
|
let requested = *stack.peek(0);
|
||||||
|
|
||||||
@ -347,7 +345,7 @@ fn test_mem_gas_cost() {
|
|||||||
let result = gasometer.mem_gas_cost(&schedule, current_mem_size, &mem_size);
|
let result = gasometer.mem_gas_cost(&schedule, current_mem_size, &mem_size);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
if let Ok(_) = result {
|
if result.is_ok() {
|
||||||
assert!(false, "Should fail with OutOfGas");
|
assert!(false, "Should fail with OutOfGas");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ impl Ext for FakeExt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn balance(&self, address: &Address) -> U256 {
|
fn balance(&self, address: &Address) -> U256 {
|
||||||
*self.balances.get(address).unwrap()
|
self.balances[address]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blockhash(&self, number: &U256) -> H256 {
|
fn blockhash(&self, number: &U256) -> H256 {
|
||||||
|
@ -514,9 +514,11 @@ impl<'a> Executive<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::sync::Arc;
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::*;
|
use util::{H256, U256, U512, Address, Uint, FixedHash, FromHex, FromStr};
|
||||||
|
use util::bytes::BytesRef;
|
||||||
use action_params::{ActionParams, ActionValue};
|
use action_params::{ActionParams, ActionValue};
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use evm::{Factory, VMType};
|
use evm::{Factory, VMType};
|
||||||
|
@ -34,7 +34,7 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
Some(x) if x < 1_150_000 => &old_schedule,
|
Some(x) if x < 1_150_000 => &old_schedule,
|
||||||
Some(_) => &new_schedule
|
Some(_) => &new_schedule
|
||||||
};
|
};
|
||||||
let allow_network_id_of_one = number.map_or(false, |n| n >= 3_500_000);
|
let allow_network_id_of_one = number.map_or(false, |n| n >= 2_675_000);
|
||||||
|
|
||||||
let rlp: Vec<u8> = test.rlp.into();
|
let rlp: Vec<u8> = test.rlp.into();
|
||||||
let res = UntrustedRlp::new(&rlp)
|
let res = UntrustedRlp::new(&rlp)
|
||||||
|
@ -151,7 +151,7 @@ impl GasPriceCalibrator {
|
|||||||
if Instant::now() >= self.next_calibration {
|
if Instant::now() >= self.next_calibration {
|
||||||
let usd_per_tx = self.options.usd_per_tx;
|
let usd_per_tx = self.options.usd_per_tx;
|
||||||
trace!(target: "miner", "Getting price info");
|
trace!(target: "miner", "Getting price info");
|
||||||
if let Ok(_) = PriceInfo::get(move |price: PriceInfo| {
|
let price_info = PriceInfo::get(move |price: PriceInfo| {
|
||||||
trace!(target: "miner", "Price info arrived: {:?}", price);
|
trace!(target: "miner", "Price info arrived: {:?}", price);
|
||||||
let usd_per_eth = price.ethusd;
|
let usd_per_eth = price.ethusd;
|
||||||
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
||||||
@ -159,7 +159,9 @@ impl GasPriceCalibrator {
|
|||||||
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
||||||
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
||||||
set_price(U256::from(wei_per_gas as u64));
|
set_price(U256::from(wei_per_gas as u64));
|
||||||
}) {
|
});
|
||||||
|
|
||||||
|
if price_info.is_ok() {
|
||||||
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
||||||
} else {
|
} else {
|
||||||
warn!(target: "miner", "Unable to update Ether price.");
|
warn!(target: "miner", "Unable to update Ether price.");
|
||||||
@ -580,29 +582,29 @@ impl Miner {
|
|||||||
let gas_required = |tx: &SignedTransaction| tx.gas_required(&schedule).into();
|
let gas_required = |tx: &SignedTransaction| tx.gas_required(&schedule).into();
|
||||||
let best_block_header: Header = ::rlp::decode(&chain.best_block_header());
|
let best_block_header: Header = ::rlp::decode(&chain.best_block_header());
|
||||||
transactions.into_iter()
|
transactions.into_iter()
|
||||||
.filter(|tx| match self.engine.verify_transaction_basic(tx, &best_block_header) {
|
.map(|tx| {
|
||||||
Ok(()) => true,
|
match self.engine.verify_transaction_basic(&tx, &best_block_header) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!(target: "miner", "Rejected tx {:?} with invalid signature: {:?}", tx.hash(), e);
|
debug!(target: "miner", "Rejected tx {:?} with invalid signature: {:?}", tx.hash(), e);
|
||||||
false
|
Err(e)
|
||||||
}
|
},
|
||||||
}
|
Ok(()) => {
|
||||||
)
|
let origin = accounts.as_ref().and_then(|accounts| {
|
||||||
.map(|tx| {
|
tx.sender().ok().and_then(|sender| match accounts.contains(&sender) {
|
||||||
let origin = accounts.as_ref().and_then(|accounts| {
|
true => Some(TransactionOrigin::Local),
|
||||||
tx.sender().ok().and_then(|sender| match accounts.contains(&sender) {
|
false => None,
|
||||||
true => Some(TransactionOrigin::Local),
|
})
|
||||||
false => None,
|
}).unwrap_or(default_origin);
|
||||||
})
|
|
||||||
}).unwrap_or(default_origin);
|
match origin {
|
||||||
|
TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
|
||||||
match origin {
|
transaction_queue.add(tx, origin, &fetch_account, &gas_required)
|
||||||
TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
|
},
|
||||||
transaction_queue.add(tx, origin, &fetch_account, &gas_required)
|
TransactionOrigin::External => {
|
||||||
|
transaction_queue.add_with_banlist(tx, &fetch_account, &gas_required)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
TransactionOrigin::External => {
|
|
||||||
transaction_queue.add_with_banlist(tx, &fetch_account, &gas_required)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
@ -1139,15 +1141,16 @@ impl MinerService for Miner {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use super::super::{MinerService, PrioritizationStrategy};
|
use super::super::{MinerService, PrioritizationStrategy};
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::*;
|
use block::IsBlock;
|
||||||
|
use util::{U256, Uint, FromHex};
|
||||||
use ethkey::{Generator, Random};
|
use ethkey::{Generator, Random};
|
||||||
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
|
use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use types::transaction::{Transaction, SignedTransaction, Action};
|
use types::transaction::{Transaction, SignedTransaction, Action};
|
||||||
use block::*;
|
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use tests::helpers::{generate_dummy_client};
|
use tests::helpers::{generate_dummy_client};
|
||||||
|
|
||||||
|
@ -990,7 +990,7 @@ impl TransactionQueue {
|
|||||||
let mut update_last_nonce_to = None;
|
let mut update_last_nonce_to = None;
|
||||||
{
|
{
|
||||||
let by_nonce = self.future.by_address.row_mut(&address);
|
let by_nonce = self.future.by_address.row_mut(&address);
|
||||||
if let None = by_nonce {
|
if by_nonce.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut by_nonce = by_nonce.expect("None is tested in early-exit condition above; qed");
|
let mut by_nonce = by_nonce.expect("None is tested in early-exit condition above; qed");
|
||||||
@ -1212,12 +1212,12 @@ mod test {
|
|||||||
use util::table::*;
|
use util::table::*;
|
||||||
use util::*;
|
use util::*;
|
||||||
use ethkey::{Random, Generator};
|
use ethkey::{Random, Generator};
|
||||||
use transaction::*;
|
|
||||||
use error::{Error, TransactionError};
|
use error::{Error, TransactionError};
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::{TransactionSet, TransactionOrder, VerifiedTransaction};
|
use super::{TransactionSet, TransactionOrder, VerifiedTransaction};
|
||||||
use miner::local_transactions::LocalTransactionsList;
|
use miner::local_transactions::LocalTransactionsList;
|
||||||
use client::TransactionImportResult;
|
use client::TransactionImportResult;
|
||||||
|
use transaction::{SignedTransaction, Transaction, Action};
|
||||||
|
|
||||||
fn unwrap_tx_err(err: Result<TransactionImportResult, Error>) -> TransactionError {
|
fn unwrap_tx_err(err: Result<TransactionImportResult, Error>) -> TransactionError {
|
||||||
match err.unwrap_err() {
|
match err.unwrap_err() {
|
||||||
|
@ -64,13 +64,13 @@ impl PodAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Place additional data into given hash DB.
|
/// Place additional data into given hash DB.
|
||||||
pub fn insert_additional(&self, db: &mut AccountDBMut) {
|
pub fn insert_additional(&self, db: &mut AccountDBMut, factory: &TrieFactory) {
|
||||||
match self.code {
|
match self.code {
|
||||||
Some(ref c) if !c.is_empty() => { db.insert(c); }
|
Some(ref c) if !c.is_empty() => { db.insert(c); }
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
let mut r = H256::new();
|
let mut r = H256::new();
|
||||||
let mut t = SecTrieDBMut::new(db, &mut r);
|
let mut t = factory.create(db, &mut r);
|
||||||
for (k, v) in &self.storage {
|
for (k, v) in &self.storage {
|
||||||
if let Err(e) = t.insert(k, &rlp::encode(&U256::from(&**v))) {
|
if let Err(e) = t.insert(k, &rlp::encode(&U256::from(&**v))) {
|
||||||
warn!("Encountered potential DB corruption: {}", e);
|
warn!("Encountered potential DB corruption: {}", e);
|
||||||
|
@ -552,11 +552,11 @@ const POW_VERIFY_RATE: f32 = 0.02;
|
|||||||
pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &Engine, chain: &BlockChain, body: Option<&[u8]>, always: bool) -> Result<(), ::error::Error> {
|
pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &Engine, chain: &BlockChain, body: Option<&[u8]>, always: bool) -> Result<(), ::error::Error> {
|
||||||
if always || rng.gen::<f32>() <= POW_VERIFY_RATE {
|
if always || rng.gen::<f32>() <= POW_VERIFY_RATE {
|
||||||
match chain.block_header(header.parent_hash()) {
|
match chain.block_header(header.parent_hash()) {
|
||||||
Some(parent) => engine.verify_block_family(&header, &parent, body),
|
Some(parent) => engine.verify_block_family(header, &parent, body),
|
||||||
None => engine.verify_block_seal(&header),
|
None => engine.verify_block_seal(header),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
engine.verify_block_basic(&header, body)
|
engine.verify_block_basic(header, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,13 +244,13 @@ impl Spec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
||||||
pub fn ensure_db_good(&self, db: &mut StateDB) -> Result<bool, Box<TrieError>> {
|
pub fn ensure_db_good(&self, db: &mut StateDB, factory: &TrieFactory) -> Result<bool, Box<TrieError>> {
|
||||||
if !db.as_hashdb().contains(&self.state_root()) {
|
if !db.as_hashdb().contains(&self.state_root()) {
|
||||||
trace!(target: "spec", "ensure_db_good: Fresh database? Cannot find state root {}", self.state_root());
|
trace!(target: "spec", "ensure_db_good: Fresh database? Cannot find state root {}", self.state_root());
|
||||||
let mut root = H256::new();
|
let mut root = H256::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut t = SecTrieDBMut::new(db.as_hashdb_mut(), &mut root);
|
let mut t = factory.create(db.as_hashdb_mut(), &mut root);
|
||||||
for (address, account) in self.genesis_state.get().iter() {
|
for (address, account) in self.genesis_state.get().iter() {
|
||||||
try!(t.insert(&**address, &account.rlp()));
|
try!(t.insert(&**address, &account.rlp()));
|
||||||
}
|
}
|
||||||
@ -258,7 +258,7 @@ impl Spec {
|
|||||||
trace!(target: "spec", "ensure_db_good: Populated sec trie; root is {}", root);
|
trace!(target: "spec", "ensure_db_good: Populated sec trie; root is {}", root);
|
||||||
for (address, account) in self.genesis_state.get().iter() {
|
for (address, account) in self.genesis_state.get().iter() {
|
||||||
db.note_non_null_account(address);
|
db.note_non_null_account(address);
|
||||||
account.insert_additional(&mut AccountDBMut::new(db.as_hashdb_mut(), address));
|
account.insert_additional(&mut AccountDBMut::new(db.as_hashdb_mut(), address), factory);
|
||||||
}
|
}
|
||||||
assert!(db.as_hashdb().contains(&self.state_root()));
|
assert!(db.as_hashdb().contains(&self.state_root()));
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
@ -314,11 +314,10 @@ impl Account {
|
|||||||
self.code_hash == SHA3_EMPTY
|
self.code_hash == SHA3_EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
/// Return the storage root associated with this account or None if it has been altered via the overlay.
|
||||||
/// return the storage root associated with this account or None if it has been altered via the overlay.
|
|
||||||
pub fn storage_root(&self) -> Option<&H256> { if self.storage_is_clean() {Some(&self.storage_root)} else {None} }
|
pub fn storage_root(&self) -> Option<&H256> { if self.storage_is_clean() {Some(&self.storage_root)} else {None} }
|
||||||
|
|
||||||
/// return the storage overlay.
|
/// Return the storage overlay.
|
||||||
pub fn storage_changes(&self) -> &HashMap<H256, H256> { &self.storage_changes }
|
pub fn storage_changes(&self) -> &HashMap<H256, H256> { &self.storage_changes }
|
||||||
|
|
||||||
/// Increment the nonce of the account by one.
|
/// Increment the nonce of the account by one.
|
||||||
@ -466,11 +465,10 @@ impl fmt::Debug for Account {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use rlp::{UntrustedRlp, RlpType, View, Compressible};
|
||||||
use util::*;
|
use util::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use account_db::*;
|
use account_db::*;
|
||||||
use rlp::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn account_compress() {
|
fn account_compress() {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -57,6 +57,7 @@ impl Substate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the cleanup mode object from this.
|
/// Get the cleanup mode object from this.
|
||||||
|
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
||||||
pub fn to_cleanup_mode(&mut self, schedule: &Schedule) -> CleanupMode {
|
pub fn to_cleanup_mode(&mut self, schedule: &Schedule) -> CleanupMode {
|
||||||
match (schedule.no_empty, schedule.kill_empty) {
|
match (schedule.no_empty, schedule.kill_empty) {
|
||||||
(false, _) => CleanupMode::ForceCreate,
|
(false, _) => CleanupMode::ForceCreate,
|
||||||
|
@ -397,6 +397,7 @@ impl StateDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get cached code based on hash.
|
/// Get cached code based on hash.
|
||||||
|
#[cfg_attr(feature="dev", allow(map_clone))]
|
||||||
pub fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>> {
|
pub fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>> {
|
||||||
let mut cache = self.code_cache.lock();
|
let mut cache = self.code_cache.lock();
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ fn should_return_registrar() {
|
|||||||
&db_config
|
&db_config
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let params = client.additional_params();
|
let params = client.additional_params();
|
||||||
let address = params.get("registrar").unwrap();
|
let address = ¶ms["registrar"];
|
||||||
|
|
||||||
assert_eq!(address.len(), 40);
|
assert_eq!(address.len(), 40);
|
||||||
assert!(U256::from_str(address).is_ok());
|
assert!(U256::from_str(address).is_ok());
|
||||||
@ -93,7 +93,7 @@ fn imports_good_block() {
|
|||||||
&db_config
|
&db_config
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let good_block = get_good_dummy_block();
|
let good_block = get_good_dummy_block();
|
||||||
if let Err(_) = client.import_block(good_block) {
|
if client.import_block(good_block).is_err() {
|
||||||
panic!("error importing block being good by definition");
|
panic!("error importing block being good by definition");
|
||||||
}
|
}
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
@ -203,18 +203,18 @@ fn can_collect_garbage() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_generate_gas_price_median() {
|
fn can_generate_gas_price_median() {
|
||||||
let client_result = generate_dummy_client_with_data(3, 1, &vec_into![1, 2, 3]);
|
let client_result = generate_dummy_client_with_data(3, 1, slice_into![1, 2, 3]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
assert_eq!(Some(U256::from(2)), client.gas_price_median(3));
|
assert_eq!(Some(U256::from(2)), client.gas_price_median(3));
|
||||||
|
|
||||||
let client_result = generate_dummy_client_with_data(4, 1, &vec_into![1, 4, 3, 2]);
|
let client_result = generate_dummy_client_with_data(4, 1, slice_into![1, 4, 3, 2]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
assert_eq!(Some(U256::from(3)), client.gas_price_median(4));
|
assert_eq!(Some(U256::from(3)), client.gas_price_median(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_generate_gas_price_histogram() {
|
fn can_generate_gas_price_histogram() {
|
||||||
let client_result = generate_dummy_client_with_data(20, 1, &vec_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]);
|
let client_result = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
|
|
||||||
let hist = client.gas_price_histogram(20, 5).unwrap();
|
let hist = client.gas_price_histogram(20, 5).unwrap();
|
||||||
@ -224,7 +224,7 @@ fn can_generate_gas_price_histogram() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_gas_price_histogram() {
|
fn empty_gas_price_histogram() {
|
||||||
let client_result = generate_dummy_client_with_data(20, 0, &vec_into![]);
|
let client_result = generate_dummy_client_with_data(20, 0, slice_into![]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
|
|
||||||
assert!(client.gas_price_histogram(20, 5).is_none());
|
assert!(client.gas_price_histogram(20, 5).is_none());
|
||||||
|
@ -18,6 +18,7 @@ use ethkey::KeyPair;
|
|||||||
use io::*;
|
use io::*;
|
||||||
use client::{BlockChainClient, Client, ClientConfig};
|
use client::{BlockChainClient, Client, ClientConfig};
|
||||||
use util::*;
|
use util::*;
|
||||||
|
use util::trie::TrieSpec;
|
||||||
use spec::*;
|
use spec::*;
|
||||||
use state_db::StateDB;
|
use state_db::StateDB;
|
||||||
use block::{OpenBlock, Drain};
|
use block::{OpenBlock, Drain};
|
||||||
@ -157,7 +158,7 @@ pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_numbe
|
|||||||
|
|
||||||
let mut db_result = get_temp_state_db();
|
let mut db_result = get_temp_state_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
test_spec.ensure_db_good(&mut db).unwrap();
|
test_spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap();
|
||||||
let genesis_header = test_spec.genesis_header();
|
let genesis_header = test_spec.genesis_header();
|
||||||
|
|
||||||
let mut rolling_timestamp = 40;
|
let mut rolling_timestamp = 40;
|
||||||
@ -262,7 +263,7 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<
|
|||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
for block in &blocks {
|
for block in &blocks {
|
||||||
if let Err(_) = client.import_block(block.clone()) {
|
if client.import_block(block.clone()).is_err() {
|
||||||
panic!("panic importing block which is well-formed");
|
panic!("panic importing block which is well-formed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,9 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
|||||||
/// Creates new instance of `TraceDB`.
|
/// Creates new instance of `TraceDB`.
|
||||||
pub fn new(config: Config, tracesdb: Arc<Database>, extras: Arc<T>) -> Self {
|
pub fn new(config: Config, tracesdb: Arc<Database>, extras: Arc<T>) -> Self {
|
||||||
let mut batch = DBTransaction::new(&tracesdb);
|
let mut batch = DBTransaction::new(&tracesdb);
|
||||||
|
let genesis = extras.block_hash(0)
|
||||||
|
.expect("Genesis block is always inserted upon extras db creation qed");
|
||||||
|
batch.write(db::COL_TRACE, &genesis, &FlatBlockTraces::default());
|
||||||
batch.put(db::COL_TRACE, b"version", TRACE_DB_VER);
|
batch.put(db::COL_TRACE, b"version", TRACE_DB_VER);
|
||||||
tracesdb.write(batch).expect("failed to update version");
|
tracesdb.write(batch).expect("failed to update version");
|
||||||
|
|
||||||
@ -413,8 +416,12 @@ mod tests {
|
|||||||
struct NoopExtras;
|
struct NoopExtras;
|
||||||
|
|
||||||
impl DatabaseExtras for NoopExtras {
|
impl DatabaseExtras for NoopExtras {
|
||||||
fn block_hash(&self, _block_number: BlockNumber) -> Option<H256> {
|
fn block_hash(&self, block_number: BlockNumber) -> Option<H256> {
|
||||||
unimplemented!();
|
if block_number == 0 {
|
||||||
|
Some(H256::default())
|
||||||
|
} else {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_hash(&self, _block_number: BlockNumber, _tx_position: usize) -> Option<H256> {
|
fn transaction_hash(&self, _block_number: BlockNumber, _tx_position: usize) -> Option<H256> {
|
||||||
@ -581,35 +588,21 @@ mod tests {
|
|||||||
let db = Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), temp.as_str()).unwrap());
|
let db = Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), temp.as_str()).unwrap());
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.enabled = true;
|
config.enabled = true;
|
||||||
let block_0 = H256::from(0xa1);
|
let block_1 = H256::from(0xa1);
|
||||||
let block_1 = H256::from(0xa2);
|
let block_2 = H256::from(0xa2);
|
||||||
let tx_0 = H256::from(0xff);
|
let tx_1 = H256::from(0xff);
|
||||||
let tx_1 = H256::from(0xaf);
|
let tx_2 = H256::from(0xaf);
|
||||||
|
|
||||||
let mut extras = Extras::default();
|
let mut extras = Extras::default();
|
||||||
extras.block_hashes.insert(0, block_0.clone());
|
extras.block_hashes.insert(0, H256::default());
|
||||||
|
|
||||||
extras.block_hashes.insert(1, block_1.clone());
|
extras.block_hashes.insert(1, block_1.clone());
|
||||||
extras.transaction_hashes.insert(0, vec![tx_0.clone()]);
|
extras.block_hashes.insert(2, block_2.clone());
|
||||||
extras.transaction_hashes.insert(1, vec![tx_1.clone()]);
|
extras.transaction_hashes.insert(1, vec![tx_1.clone()]);
|
||||||
|
extras.transaction_hashes.insert(2, vec![tx_2.clone()]);
|
||||||
|
|
||||||
let tracedb = TraceDB::new(config, db.clone(), Arc::new(extras));
|
let tracedb = TraceDB::new(config, db.clone(), Arc::new(extras));
|
||||||
|
|
||||||
// import block 0
|
|
||||||
let request = create_simple_import_request(0, block_0.clone());
|
|
||||||
let mut batch = DBTransaction::new(&db);
|
|
||||||
tracedb.import(&mut batch, request);
|
|
||||||
db.write(batch).unwrap();
|
|
||||||
|
|
||||||
let filter = Filter {
|
|
||||||
range: (0..0),
|
|
||||||
from_address: AddressesFilter::from(vec![Address::from(1)]),
|
|
||||||
to_address: AddressesFilter::from(vec![]),
|
|
||||||
};
|
|
||||||
|
|
||||||
let traces = tracedb.filter(&filter);
|
|
||||||
assert_eq!(traces.len(), 1);
|
|
||||||
assert_eq!(traces[0], create_simple_localized_trace(0, block_0.clone(), tx_0.clone()));
|
|
||||||
|
|
||||||
// import block 1
|
// import block 1
|
||||||
let request = create_simple_import_request(1, block_1.clone());
|
let request = create_simple_import_request(1, block_1.clone());
|
||||||
let mut batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
@ -617,38 +610,56 @@ mod tests {
|
|||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
let filter = Filter {
|
let filter = Filter {
|
||||||
range: (0..1),
|
range: (1..1),
|
||||||
|
from_address: AddressesFilter::from(vec![Address::from(1)]),
|
||||||
|
to_address: AddressesFilter::from(vec![]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let traces = tracedb.filter(&filter);
|
||||||
|
assert_eq!(traces.len(), 1);
|
||||||
|
assert_eq!(traces[0], create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
||||||
|
|
||||||
|
// import block 2
|
||||||
|
let request = create_simple_import_request(2, block_2.clone());
|
||||||
|
let mut batch = DBTransaction::new(&db);
|
||||||
|
tracedb.import(&mut batch, request);
|
||||||
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
|
let filter = Filter {
|
||||||
|
range: (1..2),
|
||||||
from_address: AddressesFilter::from(vec![Address::from(1)]),
|
from_address: AddressesFilter::from(vec![Address::from(1)]),
|
||||||
to_address: AddressesFilter::from(vec![]),
|
to_address: AddressesFilter::from(vec![]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let traces = tracedb.filter(&filter);
|
let traces = tracedb.filter(&filter);
|
||||||
assert_eq!(traces.len(), 2);
|
assert_eq!(traces.len(), 2);
|
||||||
assert_eq!(traces[0], create_simple_localized_trace(0, block_0.clone(), tx_0.clone()));
|
assert_eq!(traces[0], create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
||||||
assert_eq!(traces[1], create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
assert_eq!(traces[1], create_simple_localized_trace(2, block_2.clone(), tx_2.clone()));
|
||||||
|
|
||||||
let traces = tracedb.block_traces(0).unwrap();
|
assert!(tracedb.block_traces(0).is_some(), "Genesis trace should be always present.");
|
||||||
assert_eq!(traces.len(), 1);
|
|
||||||
assert_eq!(traces[0], create_simple_localized_trace(0, block_0.clone(), tx_0.clone()));
|
|
||||||
|
|
||||||
let traces = tracedb.block_traces(1).unwrap();
|
let traces = tracedb.block_traces(1).unwrap();
|
||||||
assert_eq!(traces.len(), 1);
|
assert_eq!(traces.len(), 1);
|
||||||
assert_eq!(traces[0], create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
assert_eq!(traces[0], create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
||||||
|
|
||||||
assert_eq!(None, tracedb.block_traces(2));
|
let traces = tracedb.block_traces(2).unwrap();
|
||||||
|
|
||||||
let traces = tracedb.transaction_traces(0, 0).unwrap();
|
|
||||||
assert_eq!(traces.len(), 1);
|
assert_eq!(traces.len(), 1);
|
||||||
assert_eq!(traces[0], create_simple_localized_trace(0, block_0.clone(), tx_0.clone()));
|
assert_eq!(traces[0], create_simple_localized_trace(2, block_2.clone(), tx_2.clone()));
|
||||||
|
|
||||||
|
assert_eq!(None, tracedb.block_traces(3));
|
||||||
|
|
||||||
let traces = tracedb.transaction_traces(1, 0).unwrap();
|
let traces = tracedb.transaction_traces(1, 0).unwrap();
|
||||||
assert_eq!(traces.len(), 1);
|
assert_eq!(traces.len(), 1);
|
||||||
assert_eq!(traces[0], create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
assert_eq!(traces[0], create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
||||||
|
|
||||||
assert_eq!(None, tracedb.transaction_traces(1, 1));
|
let traces = tracedb.transaction_traces(2, 0).unwrap();
|
||||||
|
assert_eq!(traces.len(), 1);
|
||||||
|
assert_eq!(traces[0], create_simple_localized_trace(2, block_2.clone(), tx_2.clone()));
|
||||||
|
|
||||||
|
assert_eq!(None, tracedb.transaction_traces(2, 1));
|
||||||
|
|
||||||
assert_eq!(tracedb.trace(0, 0, vec![]).unwrap(), create_simple_localized_trace(0, block_0.clone(), tx_0.clone()));
|
|
||||||
assert_eq!(tracedb.trace(1, 0, vec![]).unwrap(), create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
assert_eq!(tracedb.trace(1, 0, vec![]).unwrap(), create_simple_localized_trace(1, block_1.clone(), tx_1.clone()));
|
||||||
|
assert_eq!(tracedb.trace(2, 0, vec![]).unwrap(), create_simple_localized_trace(2, block_2.clone(), tx_2.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -660,8 +671,10 @@ mod tests {
|
|||||||
let block_0 = H256::from(0xa1);
|
let block_0 = H256::from(0xa1);
|
||||||
let tx_0 = H256::from(0xff);
|
let tx_0 = H256::from(0xff);
|
||||||
|
|
||||||
extras.block_hashes.insert(0, block_0.clone());
|
extras.block_hashes.insert(0, H256::default());
|
||||||
extras.transaction_hashes.insert(0, vec![tx_0.clone()]);
|
extras.transaction_hashes.insert(0, vec![]);
|
||||||
|
extras.block_hashes.insert(1, block_0.clone());
|
||||||
|
extras.transaction_hashes.insert(1, vec![tx_0.clone()]);
|
||||||
|
|
||||||
// set tracing on
|
// set tracing on
|
||||||
config.enabled = true;
|
config.enabled = true;
|
||||||
@ -669,8 +682,8 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let tracedb = TraceDB::new(config.clone(), db.clone(), Arc::new(extras.clone()));
|
let tracedb = TraceDB::new(config.clone(), db.clone(), Arc::new(extras.clone()));
|
||||||
|
|
||||||
// import block 0
|
// import block 1
|
||||||
let request = create_simple_import_request(0, block_0.clone());
|
let request = create_simple_import_request(1, block_0.clone());
|
||||||
let mut batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
tracedb.import(&mut batch, request);
|
tracedb.import(&mut batch, request);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
@ -678,8 +691,28 @@ mod tests {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let tracedb = TraceDB::new(config.clone(), db.clone(), Arc::new(extras));
|
let tracedb = TraceDB::new(config.clone(), db.clone(), Arc::new(extras));
|
||||||
let traces = tracedb.transaction_traces(0, 0);
|
let traces = tracedb.transaction_traces(1, 0);
|
||||||
assert_eq!(traces.unwrap(), vec![create_simple_localized_trace(0, block_0, tx_0)]);
|
assert_eq!(traces.unwrap(), vec![create_simple_localized_trace(1, block_0, tx_0)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn query_genesis() {
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let db = new_db(temp.as_str());
|
||||||
|
let mut config = Config::default();
|
||||||
|
let mut extras = Extras::default();
|
||||||
|
let block_0 = H256::from(0xa1);
|
||||||
|
|
||||||
|
extras.block_hashes.insert(0, block_0.clone());
|
||||||
|
extras.transaction_hashes.insert(0, vec![]);
|
||||||
|
|
||||||
|
// set tracing on
|
||||||
|
config.enabled = true;
|
||||||
|
|
||||||
|
let tracedb = TraceDB::new(config.clone(), db.clone(), Arc::new(extras.clone()));
|
||||||
|
let traces = tracedb.block_traces(0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(traces.len(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,16 +19,16 @@
|
|||||||
pub use std::time::Duration;
|
pub use std::time::Duration;
|
||||||
use client::Mode as ClientMode;
|
use client::Mode as ClientMode;
|
||||||
|
|
||||||
/// IPC-capable shadow-type for client::config::Mode
|
/// IPC-capable shadow-type for `client::config::Mode`
|
||||||
#[derive(Clone, Binary, Debug)]
|
#[derive(Clone, Binary, Debug)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
/// Same as ClientMode::Off.
|
/// Same as `ClientMode::Off`.
|
||||||
Off,
|
Off,
|
||||||
/// Same as ClientMode::Dark; values in seconds.
|
/// Same as `ClientMode::Dark`; values in seconds.
|
||||||
Dark(u64),
|
Dark(u64),
|
||||||
/// Same as ClientMode::Passive; values in seconds.
|
/// Same as `ClientMode::Passive`; values in seconds.
|
||||||
Passive(u64, u64),
|
Passive(u64, u64),
|
||||||
/// Same as ClientMode::Active.
|
/// Same as `ClientMode::Active`.
|
||||||
Active,
|
Active,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ impl Into<Vec<FlatTrace>> for FlatTransactionTraces {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents all traces produced by transactions in a single block.
|
/// Represents all traces produced by transactions in a single block.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Default)]
|
||||||
pub struct FlatBlockTraces(Vec<FlatTransactionTraces>);
|
pub struct FlatBlockTraces(Vec<FlatTransactionTraces>);
|
||||||
|
|
||||||
impl HeapSizeOf for FlatBlockTraces {
|
impl HeapSizeOf for FlatBlockTraces {
|
||||||
|
@ -73,7 +73,7 @@ pub struct Transaction {
|
|||||||
impl Transaction {
|
impl Transaction {
|
||||||
/// Append object with a without signature into RLP stream
|
/// Append object with a without signature into RLP stream
|
||||||
pub fn rlp_append_unsigned_transaction(&self, s: &mut RlpStream, network_id: Option<u8>) {
|
pub fn rlp_append_unsigned_transaction(&self, s: &mut RlpStream, network_id: Option<u8>) {
|
||||||
s.begin_list(if let None = network_id { 6 } else { 9 });
|
s.begin_list(if network_id.is_none() { 6 } else { 9 });
|
||||||
s.append(&self.nonce);
|
s.append(&self.nonce);
|
||||||
s.append(&self.gas_price);
|
s.append(&self.gas_price);
|
||||||
s.append(&self.gas);
|
s.append(&self.gas);
|
||||||
|
@ -35,6 +35,9 @@ pub mod kind;
|
|||||||
const MIN_MEM_LIMIT: usize = 16384;
|
const MIN_MEM_LIMIT: usize = 16384;
|
||||||
const MIN_QUEUE_LIMIT: usize = 512;
|
const MIN_QUEUE_LIMIT: usize = 512;
|
||||||
|
|
||||||
|
// maximum possible number of verification threads.
|
||||||
|
const MAX_VERIFIERS: usize = 8;
|
||||||
|
|
||||||
/// Type alias for block queue convenience.
|
/// Type alias for block queue convenience.
|
||||||
pub type BlockQueue = VerificationQueue<self::kind::Blocks>;
|
pub type BlockQueue = VerificationQueue<self::kind::Blocks>;
|
||||||
|
|
||||||
@ -61,6 +64,37 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct VerifierHandle {
|
||||||
|
deleting: Arc<AtomicBool>,
|
||||||
|
sleep: Arc<AtomicBool>,
|
||||||
|
thread: JoinHandle<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VerifierHandle {
|
||||||
|
// signal to the verifier thread that it should sleep.
|
||||||
|
fn sleep(&self) {
|
||||||
|
self.sleep.store(true, AtomicOrdering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// signal to the verifier thread that it should wake up.
|
||||||
|
fn wake_up(&self) {
|
||||||
|
self.sleep.store(false, AtomicOrdering::SeqCst);
|
||||||
|
self.thread.thread().unpark();
|
||||||
|
}
|
||||||
|
|
||||||
|
// signal to the verifier thread that it should conclude its
|
||||||
|
// operations.
|
||||||
|
fn conclude(&self) {
|
||||||
|
self.wake_up();
|
||||||
|
self.deleting.store(true, AtomicOrdering::Release);
|
||||||
|
}
|
||||||
|
|
||||||
|
// join the verifier thread.
|
||||||
|
fn join(self) {
|
||||||
|
self.thread.join().expect("Verifier thread panicked");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An item which is in the process of being verified.
|
/// An item which is in the process of being verified.
|
||||||
pub struct Verifying<K: Kind> {
|
pub struct Verifying<K: Kind> {
|
||||||
hash: H256,
|
hash: H256,
|
||||||
@ -97,11 +131,12 @@ pub struct VerificationQueue<K: Kind> {
|
|||||||
engine: Arc<Engine>,
|
engine: Arc<Engine>,
|
||||||
more_to_verify: Arc<SCondvar>,
|
more_to_verify: Arc<SCondvar>,
|
||||||
verification: Arc<Verification<K>>,
|
verification: Arc<Verification<K>>,
|
||||||
verifiers: Vec<JoinHandle<()>>,
|
verifiers: Mutex<(Vec<VerifierHandle>, usize)>,
|
||||||
deleting: Arc<AtomicBool>,
|
deleting: Arc<AtomicBool>,
|
||||||
ready_signal: Arc<QueueSignal>,
|
ready_signal: Arc<QueueSignal>,
|
||||||
empty: Arc<SCondvar>,
|
empty: Arc<SCondvar>,
|
||||||
processing: RwLock<HashSet<H256>>,
|
processing: RwLock<HashSet<H256>>,
|
||||||
|
ticks_since_adjustment: AtomicUsize,
|
||||||
max_queue_size: usize,
|
max_queue_size: usize,
|
||||||
max_mem_use: usize,
|
max_mem_use: usize,
|
||||||
}
|
}
|
||||||
@ -157,6 +192,7 @@ struct Verification<K: Kind> {
|
|||||||
more_to_verify: SMutex<()>,
|
more_to_verify: SMutex<()>,
|
||||||
empty: SMutex<()>,
|
empty: SMutex<()>,
|
||||||
sizes: Sizes,
|
sizes: Sizes,
|
||||||
|
check_seal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Kind> VerificationQueue<K> {
|
impl<K: Kind> VerificationQueue<K> {
|
||||||
@ -173,7 +209,8 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
unverified: AtomicUsize::new(0),
|
unverified: AtomicUsize::new(0),
|
||||||
verifying: AtomicUsize::new(0),
|
verifying: AtomicUsize::new(0),
|
||||||
verified: AtomicUsize::new(0),
|
verified: AtomicUsize::new(0),
|
||||||
}
|
},
|
||||||
|
check_seal: check_seal,
|
||||||
});
|
});
|
||||||
let more_to_verify = Arc::new(SCondvar::new());
|
let more_to_verify = Arc::new(SCondvar::new());
|
||||||
let deleting = Arc::new(AtomicBool::new(false));
|
let deleting = Arc::new(AtomicBool::new(false));
|
||||||
@ -185,44 +222,82 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
let empty = Arc::new(SCondvar::new());
|
let empty = Arc::new(SCondvar::new());
|
||||||
let panic_handler = PanicHandler::new_in_arc();
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
|
|
||||||
let mut verifiers: Vec<JoinHandle<()>> = Vec::new();
|
let max_verifiers = min(::num_cpus::get(), MAX_VERIFIERS);
|
||||||
let thread_count = max(::num_cpus::get(), 3) - 2;
|
let default_amount = max(::num_cpus::get(), 3) - 2;
|
||||||
for i in 0..thread_count {
|
let mut verifiers = Vec::with_capacity(max_verifiers);
|
||||||
let verification = verification.clone();
|
|
||||||
let engine = engine.clone();
|
debug!(target: "verification", "Allocating {} verifiers, {} initially active", max_verifiers, default_amount);
|
||||||
let more_to_verify = more_to_verify.clone();
|
|
||||||
let ready_signal = ready_signal.clone();
|
for i in 0..max_verifiers {
|
||||||
let empty = empty.clone();
|
debug!(target: "verification", "Adding verification thread #{}", i);
|
||||||
|
|
||||||
let deleting = deleting.clone();
|
let deleting = deleting.clone();
|
||||||
let panic_handler = panic_handler.clone();
|
let panic_handler = panic_handler.clone();
|
||||||
verifiers.push(
|
let verification = verification.clone();
|
||||||
thread::Builder::new()
|
let engine = engine.clone();
|
||||||
.name(format!("Verifier #{}", i))
|
let wait = more_to_verify.clone();
|
||||||
.spawn(move || {
|
let ready = ready_signal.clone();
|
||||||
panic_handler.catch_panic(move || {
|
let empty = empty.clone();
|
||||||
VerificationQueue::verify(verification, engine, more_to_verify, ready_signal, deleting, empty, check_seal)
|
|
||||||
}).unwrap()
|
// enable only the first few verifiers.
|
||||||
})
|
let sleep = if i < default_amount {
|
||||||
.expect("Error starting block verification thread")
|
Arc::new(AtomicBool::new(false))
|
||||||
);
|
} else {
|
||||||
|
Arc::new(AtomicBool::new(true))
|
||||||
|
};
|
||||||
|
|
||||||
|
verifiers.push(VerifierHandle {
|
||||||
|
deleting: deleting.clone(),
|
||||||
|
sleep: sleep.clone(),
|
||||||
|
thread: thread::Builder::new()
|
||||||
|
.name(format!("Verifier #{}", i))
|
||||||
|
.spawn(move || {
|
||||||
|
panic_handler.catch_panic(move || {
|
||||||
|
VerificationQueue::verify(verification, engine, wait, ready, deleting, empty, sleep)
|
||||||
|
}).unwrap()
|
||||||
|
})
|
||||||
|
.expect("Failed to create verifier thread.")
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
VerificationQueue {
|
VerificationQueue {
|
||||||
engine: engine,
|
engine: engine,
|
||||||
panic_handler: panic_handler,
|
panic_handler: panic_handler,
|
||||||
ready_signal: ready_signal.clone(),
|
ready_signal: ready_signal,
|
||||||
more_to_verify: more_to_verify.clone(),
|
more_to_verify: more_to_verify,
|
||||||
verification: verification.clone(),
|
verification: verification,
|
||||||
verifiers: verifiers,
|
verifiers: Mutex::new((verifiers, default_amount)),
|
||||||
deleting: deleting.clone(),
|
deleting: deleting,
|
||||||
processing: RwLock::new(HashSet::new()),
|
processing: RwLock::new(HashSet::new()),
|
||||||
empty: empty.clone(),
|
empty: empty,
|
||||||
|
ticks_since_adjustment: AtomicUsize::new(0),
|
||||||
max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT),
|
max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT),
|
||||||
max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT),
|
max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(verification: Arc<Verification<K>>, engine: Arc<Engine>, wait: Arc<SCondvar>, ready: Arc<QueueSignal>, deleting: Arc<AtomicBool>, empty: Arc<SCondvar>, check_seal: bool) {
|
fn verify(
|
||||||
|
verification: Arc<Verification<K>>,
|
||||||
|
engine: Arc<Engine>,
|
||||||
|
wait: Arc<SCondvar>,
|
||||||
|
ready: Arc<QueueSignal>,
|
||||||
|
deleting: Arc<AtomicBool>,
|
||||||
|
empty: Arc<SCondvar>,
|
||||||
|
sleep: Arc<AtomicBool>,
|
||||||
|
) {
|
||||||
while !deleting.load(AtomicOrdering::Acquire) {
|
while !deleting.load(AtomicOrdering::Acquire) {
|
||||||
|
{
|
||||||
|
while sleep.load(AtomicOrdering::SeqCst) {
|
||||||
|
trace!(target: "verification", "Verifier sleeping");
|
||||||
|
::std::thread::park();
|
||||||
|
trace!(target: "verification", "Verifier waking up");
|
||||||
|
|
||||||
|
if deleting.load(AtomicOrdering::Acquire) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut more_to_verify = verification.more_to_verify.lock().unwrap();
|
let mut more_to_verify = verification.more_to_verify.lock().unwrap();
|
||||||
|
|
||||||
@ -255,7 +330,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let hash = item.hash();
|
let hash = item.hash();
|
||||||
let is_ready = match K::verify(item, &*engine, check_seal) {
|
let is_ready = match K::verify(item, &*engine, verification.check_seal) {
|
||||||
Ok(verified) => {
|
Ok(verified) => {
|
||||||
let mut verifying = verification.verifying.lock();
|
let mut verifying = verification.verifying.lock();
|
||||||
let mut idx = None;
|
let mut idx = None;
|
||||||
@ -302,9 +377,15 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drain_verifying(verifying: &mut VecDeque<Verifying<K>>, verified: &mut VecDeque<K::Verified>, bad: &mut HashSet<H256>, sizes: &Sizes) {
|
fn drain_verifying(
|
||||||
|
verifying: &mut VecDeque<Verifying<K>>,
|
||||||
|
verified: &mut VecDeque<K::Verified>,
|
||||||
|
bad: &mut HashSet<H256>,
|
||||||
|
sizes: &Sizes,
|
||||||
|
) {
|
||||||
let mut removed_size = 0;
|
let mut removed_size = 0;
|
||||||
let mut inserted_size = 0;
|
let mut inserted_size = 0;
|
||||||
|
|
||||||
while let Some(output) = verifying.front_mut().and_then(|x| x.output.take()) {
|
while let Some(output) = verifying.front_mut().and_then(|x| x.output.take()) {
|
||||||
assert!(verifying.pop_front().is_some());
|
assert!(verifying.pop_front().is_some());
|
||||||
let size = output.heap_size_of_children();
|
let size = output.heap_size_of_children();
|
||||||
@ -487,14 +568,85 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Optimise memory footprint of the heap fields.
|
/// Optimise memory footprint of the heap fields, and adjust the number of threads
|
||||||
|
/// to better suit the workload.
|
||||||
pub fn collect_garbage(&self) {
|
pub fn collect_garbage(&self) {
|
||||||
{
|
// number of ticks to average queue stats over
|
||||||
self.verification.unverified.lock().shrink_to_fit();
|
// when deciding whether to change the number of verifiers.
|
||||||
|
#[cfg(not(test))]
|
||||||
|
const READJUSTMENT_PERIOD: usize = 12;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
const READJUSTMENT_PERIOD: usize = 1;
|
||||||
|
|
||||||
|
let (u_len, v_len) = {
|
||||||
|
let u_len = {
|
||||||
|
let mut q = self.verification.unverified.lock();
|
||||||
|
q.shrink_to_fit();
|
||||||
|
q.len()
|
||||||
|
};
|
||||||
self.verification.verifying.lock().shrink_to_fit();
|
self.verification.verifying.lock().shrink_to_fit();
|
||||||
self.verification.verified.lock().shrink_to_fit();
|
|
||||||
}
|
let v_len = {
|
||||||
|
let mut q = self.verification.verified.lock();
|
||||||
|
q.shrink_to_fit();
|
||||||
|
q.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
(u_len as isize, v_len as isize)
|
||||||
|
};
|
||||||
|
|
||||||
self.processing.write().shrink_to_fit();
|
self.processing.write().shrink_to_fit();
|
||||||
|
|
||||||
|
if self.ticks_since_adjustment.fetch_add(1, AtomicOrdering::SeqCst) + 1 >= READJUSTMENT_PERIOD {
|
||||||
|
self.ticks_since_adjustment.store(0, AtomicOrdering::SeqCst);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current = self.verifiers.lock().1;
|
||||||
|
|
||||||
|
let diff = (v_len - u_len).abs();
|
||||||
|
let total = v_len + u_len;
|
||||||
|
|
||||||
|
self.scale_verifiers(
|
||||||
|
if u_len < 20 {
|
||||||
|
1
|
||||||
|
} else if diff <= total / 10 {
|
||||||
|
current
|
||||||
|
} else if v_len > u_len {
|
||||||
|
current - 1
|
||||||
|
} else {
|
||||||
|
current + 1
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wake up or sleep verifiers to get as close to the target as
|
||||||
|
// possible, never going over the amount of initially allocated threads
|
||||||
|
// or below 1.
|
||||||
|
fn scale_verifiers(&self, target: usize) {
|
||||||
|
let mut verifiers = self.verifiers.lock();
|
||||||
|
let &mut (ref mut verifiers, ref mut verifier_count) = &mut *verifiers;
|
||||||
|
|
||||||
|
let target = min(verifiers.len(), target);
|
||||||
|
let target = max(1, target);
|
||||||
|
|
||||||
|
debug!(target: "verification", "Scaling from {} to {} verifiers", verifier_count, target);
|
||||||
|
|
||||||
|
// scaling up
|
||||||
|
for i in *verifier_count..target {
|
||||||
|
debug!(target: "verification", "Waking up verifier {}", i);
|
||||||
|
verifiers[i].wake_up();
|
||||||
|
}
|
||||||
|
|
||||||
|
// scaling down.
|
||||||
|
for i in target..*verifier_count {
|
||||||
|
debug!(target: "verification", "Putting verifier {} to sleep", i);
|
||||||
|
verifiers[i].sleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
*verifier_count = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,10 +661,23 @@ impl<K: Kind> Drop for VerificationQueue<K> {
|
|||||||
trace!(target: "shutdown", "[VerificationQueue] Closing...");
|
trace!(target: "shutdown", "[VerificationQueue] Closing...");
|
||||||
self.clear();
|
self.clear();
|
||||||
self.deleting.store(true, AtomicOrdering::Release);
|
self.deleting.store(true, AtomicOrdering::Release);
|
||||||
self.more_to_verify.notify_all();
|
|
||||||
for t in self.verifiers.drain(..) {
|
let mut verifiers = self.verifiers.get_mut();
|
||||||
t.join().unwrap();
|
let mut verifiers = &mut verifiers.0;
|
||||||
|
|
||||||
|
// first pass to signal conclusion. must be done before
|
||||||
|
// notify or deadlock possible.
|
||||||
|
for handle in verifiers.iter() {
|
||||||
|
handle.conclude();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.more_to_verify.notify_all();
|
||||||
|
|
||||||
|
// second pass to join.
|
||||||
|
for handle in verifiers.drain(..) {
|
||||||
|
handle.join();
|
||||||
|
}
|
||||||
|
|
||||||
trace!(target: "shutdown", "[VerificationQueue] Closed.");
|
trace!(target: "shutdown", "[VerificationQueue] Closed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -611,4 +776,56 @@ mod tests {
|
|||||||
}
|
}
|
||||||
assert!(queue.queue_info().is_full());
|
assert!(queue.queue_info().is_full());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn scaling_limits() {
|
||||||
|
use super::MAX_VERIFIERS;
|
||||||
|
|
||||||
|
let queue = get_test_queue();
|
||||||
|
queue.scale_verifiers(MAX_VERIFIERS + 1);
|
||||||
|
|
||||||
|
assert!(queue.verifiers.lock().1 < MAX_VERIFIERS + 1);
|
||||||
|
|
||||||
|
queue.scale_verifiers(0);
|
||||||
|
|
||||||
|
assert!(queue.verifiers.lock().1 == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn readjust_verifiers() {
|
||||||
|
let queue = get_test_queue();
|
||||||
|
|
||||||
|
// put all the verifiers to sleep to ensure
|
||||||
|
// the test isn't timing sensitive.
|
||||||
|
let num_verifiers = {
|
||||||
|
let verifiers = queue.verifiers.lock();
|
||||||
|
for i in 0..verifiers.1 {
|
||||||
|
verifiers.0[i].sleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
verifiers.1
|
||||||
|
};
|
||||||
|
|
||||||
|
for block in get_good_dummy_block_seq(5000) {
|
||||||
|
queue.import(Unverified::new(block)).expect("Block good by definition; qed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// almost all unverified == bump verifier count.
|
||||||
|
queue.collect_garbage();
|
||||||
|
assert_eq!(queue.verifiers.lock().1, num_verifiers + 1);
|
||||||
|
|
||||||
|
// wake them up again and verify everything.
|
||||||
|
{
|
||||||
|
let verifiers = queue.verifiers.lock();
|
||||||
|
for i in 0..verifiers.1 {
|
||||||
|
verifiers.0[i].wake_up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.flush();
|
||||||
|
|
||||||
|
// nothing to verify == use minimum number of verifiers.
|
||||||
|
queue.collect_garbage();
|
||||||
|
assert_eq!(queue.verifiers.lock().1, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ use header::{BlockNumber, Header};
|
|||||||
use rlp::{UntrustedRlp, View};
|
use rlp::{UntrustedRlp, View};
|
||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
use views::BlockView;
|
use views::BlockView;
|
||||||
|
use time::get_time;
|
||||||
|
|
||||||
/// Preprocessed block data gathered in `verify_block_unordered` call
|
/// Preprocessed block data gathered in `verify_block_unordered` call
|
||||||
pub struct PreverifiedBlock {
|
pub struct PreverifiedBlock {
|
||||||
@ -209,6 +210,10 @@ pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Erro
|
|||||||
if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size {
|
if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size {
|
||||||
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
|
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
|
||||||
}
|
}
|
||||||
|
let max_time = get_time().sec as u64 + 30;
|
||||||
|
if header.timestamp() > max_time {
|
||||||
|
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +263,7 @@ mod tests {
|
|||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use types::log_entry::{LogEntry, LocalizedLogEntry};
|
use types::log_entry::{LogEntry, LocalizedLogEntry};
|
||||||
use rlp::View;
|
use rlp::View;
|
||||||
|
use time::get_time;
|
||||||
|
|
||||||
fn check_ok(result: Result<(), Error>) {
|
fn check_ok(result: Result<(), Error>) {
|
||||||
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
|
||||||
@ -271,6 +277,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_fail_timestamp(result: Result<(), Error>) {
|
||||||
|
match result {
|
||||||
|
Err(Error::Block(BlockError::InvalidTimestamp(_))) => (),
|
||||||
|
Err(other) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: {:?}", other),
|
||||||
|
Ok(_) => panic!("Block verification failed.\nExpected: InvalidTimestamp\nGot: Ok"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct TestBlockChain {
|
struct TestBlockChain {
|
||||||
blocks: HashMap<H256, Bytes>,
|
blocks: HashMap<H256, Bytes>,
|
||||||
numbers: HashMap<BlockNumber, H256>,
|
numbers: HashMap<BlockNumber, H256>,
|
||||||
@ -515,6 +529,14 @@ mod tests {
|
|||||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
||||||
InvalidTimestamp(OutOfBounds { max: None, min: Some(parent.timestamp() + 1), found: header.timestamp() }));
|
InvalidTimestamp(OutOfBounds { max: None, min: Some(parent.timestamp() + 1), found: header.timestamp() }));
|
||||||
|
|
||||||
|
header = good.clone();
|
||||||
|
header.set_timestamp(2450000000);
|
||||||
|
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||||
|
|
||||||
|
header = good.clone();
|
||||||
|
header.set_timestamp(get_time().sec as u64 + 40);
|
||||||
|
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||||
|
|
||||||
header = good.clone();
|
header = good.clone();
|
||||||
header.set_number(9);
|
header.set_number(9);
|
||||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
||||||
|
@ -47,7 +47,7 @@ impl Random for [u8; 32] {
|
|||||||
pub fn random_phrase(words: usize) -> String {
|
pub fn random_phrase(words: usize) -> String {
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref WORDS: Vec<String> = String::from_utf8_lossy(include_bytes!("../res/wordlist.txt"))
|
static ref WORDS: Vec<String> = String::from_utf8_lossy(include_bytes!("../res/wordlist.txt"))
|
||||||
.split("\n")
|
.lines()
|
||||||
.map(|s| s.to_owned())
|
.map(|s| s.to_owned())
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
@ -55,8 +55,19 @@ pub fn random_phrase(words: usize) -> String {
|
|||||||
(0..words).map(|_| rng.choose(&WORDS).unwrap()).join(" ")
|
(0..words).map(|_| rng.choose(&WORDS).unwrap()).join(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn should_produce_right_number_of_words() {
|
mod tests {
|
||||||
let p = random_phrase(10);
|
use super::random_phrase;
|
||||||
assert_eq!(p.split(" ").count(), 10);
|
|
||||||
|
#[test]
|
||||||
|
fn should_produce_right_number_of_words() {
|
||||||
|
let p = random_phrase(10);
|
||||||
|
assert_eq!(p.split(" ").count(), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_not_include_carriage_return() {
|
||||||
|
let p = random_phrase(10);
|
||||||
|
assert!(!p.contains('\r'), "Carriage return should be trimmed.");
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"presets": ["es2017", "es2016", "es2015", "stage-0", "react"],
|
"presets": [
|
||||||
|
"es2017", "es2016", "es2015",
|
||||||
|
"stage-0", "react"
|
||||||
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"transform-runtime",
|
"transform-runtime",
|
||||||
"transform-decorators-legacy",
|
"transform-decorators-legacy",
|
||||||
@ -10,6 +13,9 @@
|
|||||||
"env": {
|
"env": {
|
||||||
"production": {
|
"production": {
|
||||||
"plugins": ["transform-react-remove-prop-types"]
|
"plugins": ["transform-react-remove-prop-types"]
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"plugins": ["react-hot-loader/babel"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"no-debugger": "error",
|
"no-debugger": "error",
|
||||||
"no-alert": "error",
|
"no-alert": "error",
|
||||||
"jsx-quotes": ["error", "prefer-single"],
|
"jsx-quotes": ["error", "prefer-single"],
|
||||||
"react/jsx-curly-spacing": ["error", "always"]
|
"react/jsx-curly-spacing": ["error", "always"],
|
||||||
|
"object-property-newline": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
js/assets/images/certifications/unknown.svg
Normal file
4
js/assets/images/certifications/unknown.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle fill="#4A90E2" cx="50" cy="50" r="50"/>
|
||||||
|
<path d="M20 45 L10 55 L35 85 L90 35 L80 25 L36 65 z" fill="#FFF"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 213 B |
229
js/package.json
229
js/package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "0.2.58",
|
"version": "0.2.84",
|
||||||
"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>",
|
||||||
@ -26,16 +26,16 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:lib && npm run build:dll && npm run build:app",
|
"build": "npm run build:lib && npm run build:dll && npm run build:app",
|
||||||
"build:app": "webpack --progress",
|
"build:app": "webpack --config webpack/app --progress",
|
||||||
"build:lib": "webpack --config webpack.libraries --progress",
|
"build:lib": "webpack --config webpack/libraries --progress",
|
||||||
"build:dll": "webpack --config webpack.vendor --progress",
|
"build:dll": "webpack --config webpack/vendor --progress",
|
||||||
"ci:build": "npm run ci:build:lib && npm run ci:build:dll && npm run ci:build:app",
|
"ci:build": "npm run ci:build:lib && npm run ci:build:dll && npm run ci:build:app",
|
||||||
"ci:build:app": "NODE_ENV=production webpack",
|
"ci:build:app": "NODE_ENV=production webpack --config webpack/app",
|
||||||
"ci:build:lib": "NODE_ENV=production webpack --config webpack.libraries",
|
"ci:build:lib": "NODE_ENV=production webpack --config webpack/libraries",
|
||||||
"ci:build:dll": "NODE_ENV=production webpack --config webpack.vendor",
|
"ci:build:dll": "NODE_ENV=production webpack --config webpack/vendor",
|
||||||
"ci:build:npm": "NODE_ENV=production webpack --config webpack.npm",
|
"ci:build:npm": "NODE_ENV=production webpack --config webpack/npm",
|
||||||
"start": "npm install && npm run build:lib && npm run build:dll && npm run start:app",
|
"start": "npm install && npm run build:lib && npm run build:dll && npm run start:app",
|
||||||
"start:app": "webpack-dev-server -d --history-api-fallback --open --hot --inline --progress --colors --port 3000",
|
"start:app": "node webpack/dev.server",
|
||||||
"clean": "rm -rf ./build ./coverage",
|
"clean": "rm -rf ./build ./coverage",
|
||||||
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
||||||
"lint": "eslint --ignore-path .gitignore ./src/",
|
"lint": "eslint --ignore-path .gitignore ./src/",
|
||||||
@ -47,126 +47,133 @@
|
|||||||
"prepush": "npm run lint:cached"
|
"prepush": "npm run lint:cached"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-cli": "^6.10.1",
|
"babel-cli": "~6.18.0",
|
||||||
"babel-core": "^6.10.4",
|
"babel-core": "~6.18.2",
|
||||||
"babel-eslint": "^7.1.0",
|
"babel-eslint": "~7.1.0",
|
||||||
"babel-loader": "^6.2.3",
|
"babel-loader": "~6.2.3",
|
||||||
"babel-plugin-lodash": "^3.2.2",
|
"babel-plugin-lodash": "~3.2.2",
|
||||||
"babel-plugin-transform-class-properties": "^6.11.5",
|
"babel-plugin-transform-class-properties": "~6.19.0",
|
||||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
"babel-plugin-transform-decorators-legacy": "~1.3.4",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "^0.2.9",
|
"babel-plugin-transform-react-remove-prop-types": "~0.2.9",
|
||||||
"babel-plugin-transform-runtime": "^6.9.0",
|
"babel-plugin-transform-runtime": "~6.15.0",
|
||||||
"babel-polyfill": "^6.13.0",
|
"babel-polyfill": "~6.16.0",
|
||||||
"babel-preset-es2015": "^6.9.0",
|
"babel-preset-es2015": "~6.18.0",
|
||||||
"babel-preset-es2015-rollup": "^1.1.1",
|
"babel-preset-es2015-rollup": "~1.2.0",
|
||||||
"babel-preset-es2016": "^6.11.3",
|
"babel-preset-es2016": "~6.16.0",
|
||||||
"babel-preset-es2017": "^6.14.0",
|
"babel-preset-es2017": "~6.16.0",
|
||||||
"babel-preset-react": "^6.5.0",
|
"babel-preset-react": "~6.16.0",
|
||||||
"babel-preset-stage-0": "^6.5.0",
|
"babel-preset-stage-0": "~6.16.0",
|
||||||
"babel-register": "6.9.0",
|
"babel-register": "6.18.0",
|
||||||
"babel-runtime": "^6.9.2",
|
"babel-runtime": "~6.18.0",
|
||||||
"chai": "^3.5.0",
|
"chai": "~3.5.0",
|
||||||
"chai-enzyme": "0.4.2",
|
"chai-enzyme": "0.4.2",
|
||||||
"cheerio": "0.20.0",
|
"cheerio": "0.20.0",
|
||||||
"copy-webpack-plugin": "^4.0.0",
|
"copy-webpack-plugin": "~4.0.0",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "~2.4.1",
|
||||||
"coveralls": "^2.11.11",
|
"coveralls": "~2.11.11",
|
||||||
"css-loader": "^0.23.1",
|
"css-loader": "~0.26.0",
|
||||||
|
"ejs-loader": "~0.3.0",
|
||||||
"enzyme": "2.3.0",
|
"enzyme": "2.3.0",
|
||||||
"eslint": "^3.1.0",
|
"eslint": "~3.10.2",
|
||||||
"eslint-config-semistandard": "^6.0.2",
|
"eslint-config-semistandard": "~7.0.0",
|
||||||
"eslint-config-standard": "^5.3.5",
|
"eslint-config-standard": "~6.2.1",
|
||||||
"eslint-config-standard-react": "^3.0.0",
|
"eslint-config-standard-react": "~4.2.0",
|
||||||
"eslint-plugin-promise": "^2.0.0",
|
"eslint-plugin-promise": "~3.4.0",
|
||||||
"eslint-plugin-react": "^5.1.1",
|
"eslint-plugin-react": "~6.7.1",
|
||||||
"eslint-plugin-standard": "^2.0.0",
|
"eslint-plugin-standard": "~2.0.0",
|
||||||
"extract-loader": "0.0.2",
|
"express": "~4.14.0",
|
||||||
"extract-text-webpack-plugin": "^1.0.1",
|
"extract-loader": "0.1.0",
|
||||||
"file-loader": "^0.8.5",
|
"extract-text-webpack-plugin": "~2.0.0-beta.4",
|
||||||
"fs-extra": "^0.30.0",
|
"file-loader": "~0.9.0",
|
||||||
"happypack": "^2.2.1",
|
"fs-extra": "~0.30.0",
|
||||||
"history": "^2.0.0",
|
"happypack": "~3.0.0",
|
||||||
"html-loader": "^0.4.4",
|
"history": "~2.0.0",
|
||||||
"husky": "^0.11.9",
|
"html-loader": "~0.4.4",
|
||||||
|
"html-webpack-plugin": "~2.24.1",
|
||||||
|
"http-proxy-middleware": "~0.17.2",
|
||||||
|
"husky": "~0.11.9",
|
||||||
"ignore-styles": "2.0.0",
|
"ignore-styles": "2.0.0",
|
||||||
"image-webpack-loader": "^1.8.0",
|
"image-webpack-loader": "~3.0.0",
|
||||||
"istanbul": "^1.0.0-alpha.2",
|
"istanbul": "~1.0.0-alpha.2",
|
||||||
"jsdom": "9.2.1",
|
"jsdom": "9.2.1",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "~0.5.4",
|
||||||
"mocha": "^3.0.0-1",
|
"mocha": "~3.0.0-1",
|
||||||
"mock-local-storage": "1.0.2",
|
"mock-local-storage": "1.0.2",
|
||||||
"mock-socket": "^3.0.1",
|
"mock-socket": "~3.0.1",
|
||||||
"nock": "^8.0.0",
|
"nock": "~8.0.0",
|
||||||
"postcss-import": "^8.1.2",
|
"postcss-import": "8.1.0",
|
||||||
"postcss-loader": "^0.8.1",
|
"postcss-loader": "~1.1.1",
|
||||||
"postcss-nested": "^1.0.0",
|
"postcss-nested": "~1.0.0",
|
||||||
"postcss-simple-vars": "^3.0.0",
|
"postcss-simple-vars": "~3.0.0",
|
||||||
"raw-loader": "^0.5.1",
|
"progress": "~1.1.8",
|
||||||
|
"raw-loader": "~0.5.1",
|
||||||
|
"react-addons-perf": "~15.3.2",
|
||||||
"react-addons-test-utils": "~15.3.2",
|
"react-addons-test-utils": "~15.3.2",
|
||||||
"react-copy-to-clipboard": "^4.2.3",
|
|
||||||
"react-dom": "~15.3.2",
|
"react-dom": "~15.3.2",
|
||||||
"react-hot-loader": "~1.3.0",
|
"react-hot-loader": "~3.0.0-beta.6",
|
||||||
"rucksack-css": "^0.8.6",
|
"rucksack-css": "~0.8.6",
|
||||||
"sinon": "^1.17.4",
|
"sinon": "~1.17.4",
|
||||||
"sinon-as-promised": "^4.0.2",
|
"sinon-as-promised": "~4.0.2",
|
||||||
"sinon-chai": "^2.8.0",
|
"sinon-chai": "~2.8.0",
|
||||||
"style-loader": "^0.13.0",
|
"style-loader": "~0.13.0",
|
||||||
"url-loader": "^0.5.7",
|
"url-loader": "~0.5.7",
|
||||||
"webpack": "^1.13.2",
|
"webpack": "~2.1.0-beta.27",
|
||||||
"webpack-dev-server": "^1.15.2",
|
"webpack-dev-middleware": "~1.8.4",
|
||||||
"webpack-error-notification": "0.1.6",
|
"webpack-error-notification": "0.1.6",
|
||||||
"webpack-hot-middleware": "~2.13.2",
|
"webpack-hot-middleware": "~2.13.2",
|
||||||
"websocket": "^1.0.23"
|
"websocket": "~1.0.23"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bignumber.js": "^2.3.0",
|
"bignumber.js": "~2.3.0",
|
||||||
"blockies": "0.0.2",
|
"blockies": "0.0.2",
|
||||||
"brace": "^0.9.0",
|
"brace": "~0.9.0",
|
||||||
"bytes": "^2.4.0",
|
"bytes": "~2.4.0",
|
||||||
"chart.js": "^2.3.0",
|
"chart.js": "~2.3.0",
|
||||||
"es6-error": "^4.0.0",
|
"es6-error": "~4.0.0",
|
||||||
"es6-promise": "^3.2.1",
|
"es6-promise": "~3.2.1",
|
||||||
"ethereumjs-tx": "^1.1.2",
|
"ethereumjs-tx": "~1.1.2",
|
||||||
"file-saver": "^1.3.3",
|
"eventemitter3": "~2.0.2",
|
||||||
"format-json": "^1.0.3",
|
"file-saver": "~1.3.3",
|
||||||
"format-number": "^2.0.1",
|
"format-json": "~1.0.3",
|
||||||
"geopattern": "^1.2.3",
|
"format-number": "~2.0.1",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"geopattern": "~1.2.3",
|
||||||
"js-sha3": "^0.5.2",
|
"isomorphic-fetch": "~2.2.1",
|
||||||
"lodash": "^4.11.1",
|
"js-sha3": "~0.5.2",
|
||||||
"marked": "^0.3.6",
|
"lodash": "~4.11.1",
|
||||||
|
"marked": "~0.3.6",
|
||||||
"material-ui": "0.16.1",
|
"material-ui": "0.16.1",
|
||||||
"material-ui-chip-input": "^0.8.0",
|
"material-ui-chip-input": "~0.8.0",
|
||||||
"mobx": "^2.6.1",
|
"mobx": "~2.6.1",
|
||||||
"mobx-react": "^3.5.8",
|
"mobx-react": "~3.5.8",
|
||||||
"mobx-react-devtools": "^4.2.9",
|
"mobx-react-devtools": "~4.2.9",
|
||||||
"moment": "^2.14.1",
|
"moment": "~2.14.1",
|
||||||
"phoneformat.js": "^1.0.3",
|
"phoneformat.js": "~1.0.3",
|
||||||
"qs": "^6.3.0",
|
"qs": "~6.3.0",
|
||||||
"react": "~15.3.2",
|
"react": "~15.3.2",
|
||||||
"react-ace": "^4.0.0",
|
"react-ace": "~4.0.0",
|
||||||
"react-addons-css-transition-group": "~15.3.2",
|
"react-addons-css-transition-group": "~15.3.2",
|
||||||
"react-chartjs-2": "^1.5.0",
|
"react-chartjs-2": "~1.5.0",
|
||||||
|
"react-copy-to-clipboard": "~4.2.3",
|
||||||
"react-dom": "~15.3.2",
|
"react-dom": "~15.3.2",
|
||||||
"react-dropzone": "^3.7.3",
|
"react-dropzone": "~3.7.3",
|
||||||
"react-redux": "^4.4.5",
|
"react-redux": "~4.4.5",
|
||||||
"react-router": "^2.6.1",
|
"react-router": "~2.6.1",
|
||||||
"react-router-redux": "^4.0.5",
|
"react-router-redux": "~4.0.5",
|
||||||
"react-tap-event-plugin": "~1.0.0",
|
"react-tap-event-plugin": "~1.0.0",
|
||||||
"react-tooltip": "^2.0.3",
|
"react-tooltip": "~2.0.3",
|
||||||
"recharts": "^0.15.2",
|
"recharts": "~0.15.2",
|
||||||
"redux": "^3.5.2",
|
"redux": "~3.5.2",
|
||||||
"redux-actions": "^0.10.1",
|
"redux-actions": "~0.10.1",
|
||||||
"redux-thunk": "^2.1.0",
|
"redux-thunk": "~2.1.0",
|
||||||
"rlp": "^2.0.0",
|
"rlp": "~2.0.0",
|
||||||
"scryptsy": "^2.0.0",
|
"scryptsy": "~2.0.0",
|
||||||
"solc": "ngotchac/solc-js",
|
"solc": "ngotchac/solc-js",
|
||||||
"store": "^1.3.20",
|
"store": "~1.3.20",
|
||||||
"utf8": "^2.1.1",
|
"utf8": "~2.1.1",
|
||||||
"valid-url": "^1.0.9",
|
"valid-url": "~1.0.9",
|
||||||
"validator": "^5.7.0",
|
"validator": "~5.7.0",
|
||||||
"web3": "^0.17.0-beta",
|
"web3": "~0.17.0-beta",
|
||||||
"whatwg-fetch": "^1.0.0",
|
"whatwg-fetch": "~1.0.0",
|
||||||
"worker-loader": "^0.7.1"
|
"worker-loader": "~0.7.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
js/src/3rdparty/shapeshift/shapeshift.js
vendored
26
js/src/3rdparty/shapeshift/shapeshift.js
vendored
@ -15,7 +15,8 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
export default function (rpc) {
|
export default function (rpc) {
|
||||||
const subscriptions = [];
|
let subscriptions = [];
|
||||||
|
let pollStatusIntervalId = null;
|
||||||
|
|
||||||
function getCoins () {
|
function getCoins () {
|
||||||
return rpc.get('getcoins');
|
return rpc.get('getcoins');
|
||||||
@ -45,6 +46,24 @@ export default function (rpc) {
|
|||||||
callback,
|
callback,
|
||||||
idx
|
idx
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Only poll if there are subscriptions...
|
||||||
|
if (!pollStatusIntervalId) {
|
||||||
|
pollStatusIntervalId = setInterval(_pollStatus, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function unsubscribe (depositAddress) {
|
||||||
|
const newSubscriptions = []
|
||||||
|
.concat(subscriptions)
|
||||||
|
.filter((sub) => sub.depositAddress !== depositAddress);
|
||||||
|
|
||||||
|
subscriptions = newSubscriptions;
|
||||||
|
|
||||||
|
if (subscriptions.length === 0) {
|
||||||
|
clearInterval(pollStatusIntervalId);
|
||||||
|
pollStatusIntervalId = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getSubscriptionStatus (subscription) {
|
function _getSubscriptionStatus (subscription) {
|
||||||
@ -81,13 +100,12 @@ export default function (rpc) {
|
|||||||
subscriptions.forEach(_getSubscriptionStatus);
|
subscriptions.forEach(_getSubscriptionStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(_pollStatus, 2000);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getCoins,
|
getCoins,
|
||||||
getMarketInfo,
|
getMarketInfo,
|
||||||
getStatus,
|
getStatus,
|
||||||
shift,
|
shift,
|
||||||
subscribe
|
subscribe,
|
||||||
|
unsubscribe
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { stringify } from 'querystring';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export default (
|
export const termsOfService = (
|
||||||
<ul>
|
<ul>
|
||||||
<li>This privacy notice relates to your use of the Parity SMS verification service. We take your privacy seriously and deal in an honest, direct and transparent way when it comes to your data.</li>
|
<li>This privacy notice relates to your use of the Parity SMS verification service. We take your privacy seriously and deal in an honest, direct and transparent way when it comes to your data.</li>
|
||||||
<li>We collect your phone number when you use this service. This is temporarily kept in memory, and then encrypted and stored in our EU servers. We only retain the cryptographic hash of the number to prevent duplicated accounts. You consent to this use.</li>
|
<li>We collect your phone number when you use this service. This is temporarily kept in memory, and then encrypted and stored in our EU servers. We only retain the cryptographic hash of the number to prevent duplicated accounts. You consent to this use.</li>
|
||||||
@ -25,3 +26,19 @@ export default (
|
|||||||
<li><i>Parity Technology Limited</i> is registered in England and Wales under company number <code>09760015</code> and complies with the Data Protection Act 1998 (UK). You may contact us via email at <a href={ 'mailto:admin@parity.io' }>admin@parity.io</a>. Our general privacy policy can be found here: <a href={ 'https://ethcore.io/legal.html' }>https://ethcore.io/legal.html</a>.</li>
|
<li><i>Parity Technology Limited</i> is registered in England and Wales under company number <code>09760015</code> and complies with the Data Protection Act 1998 (UK). You may contact us via email at <a href={ 'mailto:admin@parity.io' }>admin@parity.io</a>. Our general privacy policy can be found here: <a href={ 'https://ethcore.io/legal.html' }>https://ethcore.io/legal.html</a>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const postToServer = (query, isTestnet = false) => {
|
||||||
|
const port = isTestnet ? 8443 : 443;
|
||||||
|
query = stringify(query);
|
||||||
|
return fetch(`https://sms-verification.parity.io:${port}/?` + query, {
|
||||||
|
method: 'POST', mode: 'cors', cache: 'no-store'
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json().then((data) => {
|
||||||
|
if (res.ok) {
|
||||||
|
return data.message;
|
||||||
|
}
|
||||||
|
throw new Error(data.message || 'unknown error');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
@ -15,16 +15,16 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import Abi from '../../abi';
|
import Abi from '../../abi';
|
||||||
import Api from '../api';
|
|
||||||
import { isInstanceOf } from '../util/types';
|
|
||||||
|
|
||||||
let nextSubscriptionId = 0;
|
let nextSubscriptionId = 0;
|
||||||
|
|
||||||
export default class Contract {
|
export default class Contract {
|
||||||
constructor (api, abi) {
|
constructor (api, abi) {
|
||||||
if (!isInstanceOf(api, Api)) {
|
if (!api) {
|
||||||
throw new Error('API instance needs to be provided to Contract');
|
throw new Error('API instance needs to be provided to Contract');
|
||||||
} else if (!abi) {
|
}
|
||||||
|
|
||||||
|
if (!abi) {
|
||||||
throw new Error('ABI needs to be provided to Contract instance');
|
throw new Error('ABI needs to be provided to Contract instance');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,11 @@ export default class Contract {
|
|||||||
this._instance[fn.signature] = fn;
|
this._instance[fn.signature] = fn;
|
||||||
});
|
});
|
||||||
|
|
||||||
this._sendSubscriptionChanges();
|
this._subscribedToPendings = false;
|
||||||
|
this._pendingsSubscriptionId = null;
|
||||||
|
|
||||||
|
this._subscribedToBlock = false;
|
||||||
|
this._blockSubscriptionId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get address () {
|
get address () {
|
||||||
@ -239,44 +243,71 @@ export default class Contract {
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe (eventName = null, options = {}, callback) {
|
_findEvent (eventName = null) {
|
||||||
return new Promise((resolve, reject) => {
|
const event = eventName
|
||||||
let event = null;
|
? this._events.find((evt) => evt.name === eventName)
|
||||||
|
: null;
|
||||||
|
|
||||||
if (eventName) {
|
if (eventName && !event) {
|
||||||
event = this._events.find((evt) => evt.name === eventName);
|
const events = this._events.map((evt) => evt.name).join(', ');
|
||||||
|
throw new Error(`${eventName} is not a valid eventName, subscribe using one of ${events} (or null to include all)`);
|
||||||
|
}
|
||||||
|
|
||||||
if (!event) {
|
return event;
|
||||||
const events = this._events.map((evt) => evt.name).join(', ');
|
}
|
||||||
reject(new Error(`${eventName} is not a valid eventName, subscribe using one of ${events} (or null to include all)`));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._subscribe(event, options, callback).then(resolve).catch(reject);
|
_createEthFilter (event = null, _options) {
|
||||||
|
const optionTopics = _options.topics || [];
|
||||||
|
const signature = event && event.signature || null;
|
||||||
|
|
||||||
|
// If event provided, remove the potential event signature
|
||||||
|
// as the first element of the topics
|
||||||
|
const topics = signature
|
||||||
|
? [ signature ].concat(optionTopics.filter((t, idx) => idx > 0 || t !== signature))
|
||||||
|
: optionTopics;
|
||||||
|
|
||||||
|
const options = Object.assign({}, _options, {
|
||||||
|
address: this._address,
|
||||||
|
topics
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this._api.eth.newFilter(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe (eventName = null, options = {}, callback) {
|
||||||
|
try {
|
||||||
|
const event = this._findEvent(eventName);
|
||||||
|
return this._subscribe(event, options, callback);
|
||||||
|
} catch (e) {
|
||||||
|
return Promise.reject(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_subscribe (event = null, _options, callback) {
|
_subscribe (event = null, _options, callback) {
|
||||||
const subscriptionId = nextSubscriptionId++;
|
const subscriptionId = nextSubscriptionId++;
|
||||||
const options = Object.assign({}, _options, {
|
const { skipInitFetch } = _options;
|
||||||
address: this._address,
|
delete _options['skipInitFetch'];
|
||||||
topics: [event ? event.signature : null]
|
|
||||||
});
|
|
||||||
|
|
||||||
return this._api.eth
|
return this
|
||||||
.newFilter(options)
|
._createEthFilter(event, _options)
|
||||||
.then((filterId) => {
|
.then((filterId) => {
|
||||||
|
this._subscriptions[subscriptionId] = {
|
||||||
|
options: _options,
|
||||||
|
callback,
|
||||||
|
filterId
|
||||||
|
};
|
||||||
|
|
||||||
|
if (skipInitFetch) {
|
||||||
|
this._subscribeToChanges();
|
||||||
|
return subscriptionId;
|
||||||
|
}
|
||||||
|
|
||||||
return this._api.eth
|
return this._api.eth
|
||||||
.getFilterLogs(filterId)
|
.getFilterLogs(filterId)
|
||||||
.then((logs) => {
|
.then((logs) => {
|
||||||
callback(null, this.parseEventLogs(logs));
|
callback(null, this.parseEventLogs(logs));
|
||||||
this._subscriptions[subscriptionId] = {
|
|
||||||
options,
|
|
||||||
callback,
|
|
||||||
filterId
|
|
||||||
};
|
|
||||||
|
|
||||||
|
this._subscribeToChanges();
|
||||||
return subscriptionId;
|
return subscriptionId;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -285,19 +316,89 @@ export default class Contract {
|
|||||||
unsubscribe (subscriptionId) {
|
unsubscribe (subscriptionId) {
|
||||||
return this._api.eth
|
return this._api.eth
|
||||||
.uninstallFilter(this._subscriptions[subscriptionId].filterId)
|
.uninstallFilter(this._subscriptions[subscriptionId].filterId)
|
||||||
.then(() => {
|
|
||||||
delete this._subscriptions[subscriptionId];
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('unsubscribe', error);
|
console.error('unsubscribe', error);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
delete this._subscriptions[subscriptionId];
|
||||||
|
this._unsubscribeFromChanges();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_sendSubscriptionChanges = () => {
|
_subscribeToChanges = () => {
|
||||||
const subscriptions = Object.values(this._subscriptions);
|
const subscriptions = Object.values(this._subscriptions);
|
||||||
const timeout = () => setTimeout(this._sendSubscriptionChanges, 1000);
|
|
||||||
|
|
||||||
Promise
|
const pendingSubscriptions = subscriptions
|
||||||
|
.filter((s) => s.options.toBlock && s.options.toBlock === 'pending');
|
||||||
|
|
||||||
|
const otherSubscriptions = subscriptions
|
||||||
|
.filter((s) => !(s.options.toBlock && s.options.toBlock === 'pending'));
|
||||||
|
|
||||||
|
if (pendingSubscriptions.length > 0 && !this._subscribedToPendings) {
|
||||||
|
this._subscribedToPendings = true;
|
||||||
|
this._subscribeToPendings();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (otherSubscriptions.length > 0 && !this._subscribedToBlock) {
|
||||||
|
this._subscribedToBlock = true;
|
||||||
|
this._subscribeToBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_unsubscribeFromChanges = () => {
|
||||||
|
const subscriptions = Object.values(this._subscriptions);
|
||||||
|
|
||||||
|
const pendingSubscriptions = subscriptions
|
||||||
|
.filter((s) => s.options.toBlock && s.options.toBlock === 'pending');
|
||||||
|
|
||||||
|
const otherSubscriptions = subscriptions
|
||||||
|
.filter((s) => !(s.options.toBlock && s.options.toBlock === 'pending'));
|
||||||
|
|
||||||
|
if (pendingSubscriptions.length === 0 && this._subscribedToPendings) {
|
||||||
|
this._subscribedToPendings = false;
|
||||||
|
clearTimeout(this._pendingsSubscriptionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (otherSubscriptions.length === 0 && this._subscribedToBlock) {
|
||||||
|
this._subscribedToBlock = false;
|
||||||
|
this._api.unsubscribe(this._blockSubscriptionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_subscribeToBlock = () => {
|
||||||
|
this._api
|
||||||
|
.subscribe('eth_blockNumber', (error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error('::_subscribeToBlock', error, error && error.stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
const subscriptions = Object.values(this._subscriptions)
|
||||||
|
.filter((s) => !(s.options.toBlock && s.options.toBlock === 'pending'));
|
||||||
|
|
||||||
|
this._sendSubscriptionChanges(subscriptions);
|
||||||
|
})
|
||||||
|
.then((blockSubId) => {
|
||||||
|
this._blockSubscriptionId = blockSubId;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error('::_subscribeToBlock', e, e && e.stack);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_subscribeToPendings = () => {
|
||||||
|
const subscriptions = Object.values(this._subscriptions)
|
||||||
|
.filter((s) => s.options.toBlock && s.options.toBlock === 'pending');
|
||||||
|
|
||||||
|
const timeout = () => setTimeout(() => this._subscribeToPendings(), 1000);
|
||||||
|
|
||||||
|
this._sendSubscriptionChanges(subscriptions)
|
||||||
|
.then(() => {
|
||||||
|
this._pendingsSubscriptionId = timeout();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendSubscriptionChanges = (subscriptions) => {
|
||||||
|
return Promise
|
||||||
.all(
|
.all(
|
||||||
subscriptions.map((subscription) => {
|
subscriptions.map((subscription) => {
|
||||||
return this._api.eth.getFilterChanges(subscription.filterId);
|
return this._api.eth.getFilterChanges(subscription.filterId);
|
||||||
@ -315,12 +416,9 @@ export default class Contract {
|
|||||||
console.error('_sendSubscriptionChanges', error);
|
console.error('_sendSubscriptionChanges', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
timeout();
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('_sendSubscriptionChanges', error);
|
console.error('_sendSubscriptionChanges', error);
|
||||||
timeout();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,6 +437,7 @@ describe('api/contract/Contract', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const logs = [{
|
const logs = [{
|
||||||
address: '0x22bff18ec62281850546a664bb63a5c06ac5f76c',
|
address: '0x22bff18ec62281850546a664bb63a5c06ac5f76c',
|
||||||
blockHash: '0xa9280530a3b47bee2fc80f2862fd56502ae075350571d724d6442ea4c597347b',
|
blockHash: '0xa9280530a3b47bee2fc80f2862fd56502ae075350571d724d6442ea4c597347b',
|
||||||
@ -450,6 +451,7 @@ describe('api/contract/Contract', () => {
|
|||||||
transactionHash: '0xca16f537d761d13e4e80953b754e2b15541f267d6cad9381f750af1bae1e4917',
|
transactionHash: '0xca16f537d761d13e4e80953b754e2b15541f267d6cad9381f750af1bae1e4917',
|
||||||
transactionIndex: '0x0'
|
transactionIndex: '0x0'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const parsed = [{
|
const parsed = [{
|
||||||
address: '0x22bfF18ec62281850546a664bb63a5C06AC5F76C',
|
address: '0x22bfF18ec62281850546a664bb63a5C06AC5F76C',
|
||||||
blockHash: '0xa9280530a3b47bee2fc80f2862fd56502ae075350571d724d6442ea4c597347b',
|
blockHash: '0xa9280530a3b47bee2fc80f2862fd56502ae075350571d724d6442ea4c597347b',
|
||||||
@ -466,11 +468,13 @@ describe('api/contract/Contract', () => {
|
|||||||
sender: { type: 'address', value: '0x63Cf90D3f0410092FC0fca41846f596223979195' }
|
sender: { type: 'address', value: '0x63Cf90D3f0410092FC0fca41846f596223979195' }
|
||||||
},
|
},
|
||||||
topics: [
|
topics: [
|
||||||
'0x954ba6c157daf8a26539574ffa64203c044691aa57251af95f4b48d85ec00dd5', '0x0000000000000000000000000000000000000000000000000001000000004fe0'
|
'0x954ba6c157daf8a26539574ffa64203c044691aa57251af95f4b48d85ec00dd5',
|
||||||
|
'0x0000000000000000000000000000000000000000000000000001000000004fe0'
|
||||||
],
|
],
|
||||||
transactionHash: '0xca16f537d761d13e4e80953b754e2b15541f267d6cad9381f750af1bae1e4917',
|
transactionHash: '0xca16f537d761d13e4e80953b754e2b15541f267d6cad9381f750af1bae1e4917',
|
||||||
transactionIndex: new BigNumber(0)
|
transactionIndex: new BigNumber(0)
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let contract;
|
let contract;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -496,18 +500,19 @@ describe('api/contract/Contract', () => {
|
|||||||
scope = mockHttp([
|
scope = mockHttp([
|
||||||
{ method: 'eth_newFilter', reply: { result: '0x123' } },
|
{ method: 'eth_newFilter', reply: { result: '0x123' } },
|
||||||
{ method: 'eth_getFilterLogs', reply: { result: logs } },
|
{ method: 'eth_getFilterLogs', reply: { result: logs } },
|
||||||
|
{ method: 'eth_getFilterChanges', reply: { result: logs } },
|
||||||
{ method: 'eth_newFilter', reply: { result: '0x123' } },
|
{ method: 'eth_newFilter', reply: { result: '0x123' } },
|
||||||
{ method: 'eth_getFilterLogs', reply: { result: logs } }
|
{ method: 'eth_getFilterLogs', reply: { result: logs } }
|
||||||
]);
|
]);
|
||||||
cbb = sinon.stub();
|
cbb = sinon.stub();
|
||||||
cbe = sinon.stub();
|
cbe = sinon.stub();
|
||||||
|
|
||||||
return contract.subscribe('Message', {}, cbb);
|
return contract.subscribe('Message', { toBlock: 'pending' }, cbb);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets the subscriptionId returned', () => {
|
it('sets the subscriptionId returned', () => {
|
||||||
return contract
|
return contract
|
||||||
.subscribe('Message', {}, cbe)
|
.subscribe('Message', { toBlock: 'pending' }, cbe)
|
||||||
.then((subscriptionId) => {
|
.then((subscriptionId) => {
|
||||||
expect(subscriptionId).to.equal(1);
|
expect(subscriptionId).to.equal(1);
|
||||||
});
|
});
|
||||||
@ -515,7 +520,7 @@ describe('api/contract/Contract', () => {
|
|||||||
|
|
||||||
it('creates a new filter and retrieves the logs on it', () => {
|
it('creates a new filter and retrieves the logs on it', () => {
|
||||||
return contract
|
return contract
|
||||||
.subscribe('Message', {}, cbe)
|
.subscribe('Message', { toBlock: 'pending' }, cbe)
|
||||||
.then((subscriptionId) => {
|
.then((subscriptionId) => {
|
||||||
expect(scope.isDone()).to.be.true;
|
expect(scope.isDone()).to.be.true;
|
||||||
});
|
});
|
||||||
@ -523,7 +528,7 @@ describe('api/contract/Contract', () => {
|
|||||||
|
|
||||||
it('returns the logs to the callback', () => {
|
it('returns the logs to the callback', () => {
|
||||||
return contract
|
return contract
|
||||||
.subscribe('Message', {}, cbe)
|
.subscribe('Message', { toBlock: 'pending' }, cbe)
|
||||||
.then((subscriptionId) => {
|
.then((subscriptionId) => {
|
||||||
expect(cbe).to.have.been.calledWith(null, parsed);
|
expect(cbe).to.have.been.calledWith(null, parsed);
|
||||||
});
|
});
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
import { isArray, isHex, isInstanceOf, isString } from '../util/types';
|
import { isArray, isHex, isInstanceOf, isString } from '../util/types';
|
||||||
|
import { padLeft, toHex } from '../util/format';
|
||||||
|
|
||||||
export function inAddress (address) {
|
export function inAddress (address) {
|
||||||
// TODO: address validation if we have upper-lower addresses
|
// TODO: address validation if we have upper-lower addresses
|
||||||
@ -52,12 +53,18 @@ export function inHash (hash) {
|
|||||||
|
|
||||||
export function inTopics (_topics) {
|
export function inTopics (_topics) {
|
||||||
let topics = (_topics || [])
|
let topics = (_topics || [])
|
||||||
.filter((topic) => topic)
|
.filter((topic) => topic === null || topic)
|
||||||
.map(inHex);
|
.map((topic) => {
|
||||||
|
if (topic === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
while (topics.length < 4) {
|
if (Array.isArray(topic)) {
|
||||||
topics.push(null);
|
return inTopics(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return padLeft(topic, 32);
|
||||||
|
});
|
||||||
|
|
||||||
return topics;
|
return topics;
|
||||||
}
|
}
|
||||||
@ -93,15 +100,7 @@ export function inFilter (options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function inHex (str) {
|
export function inHex (str) {
|
||||||
if (str && str.toString) {
|
return toHex(str);
|
||||||
str = str.toString(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str && str.substr(0, 2) === '0x') {
|
|
||||||
return str.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
return `0x${(str || '').toLowerCase()}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inNumber10 (number) {
|
export function inNumber10 (number) {
|
||||||
|
@ -144,7 +144,8 @@ export function outSignerRequest (request) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'payload':
|
case 'payload':
|
||||||
request[key].transaction = outTransaction(request[key].transaction);
|
request[key].signTransaction = outTransaction(request[key].signTransaction);
|
||||||
|
request[key].sendTransaction = outTransaction(request[key].sendTransaction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -123,6 +123,11 @@ export default class Parity {
|
|||||||
.then((accounts) => (accounts || []).map(outAddress));
|
.then((accounts) => (accounts || []).map(outAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
killAccount (account, password) {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_killAccount', inAddress(account), password);
|
||||||
|
}
|
||||||
|
|
||||||
listGethAccounts () {
|
listGethAccounts () {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_listGethAccounts')
|
.execute('parity_listGethAccounts')
|
||||||
|
@ -59,6 +59,7 @@ export default class Personal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (data.method) {
|
switch (data.method) {
|
||||||
|
case 'parity_killAccount':
|
||||||
case 'parity_importGethAccounts':
|
case 'parity_importGethAccounts':
|
||||||
case 'personal_newAccount':
|
case 'personal_newAccount':
|
||||||
case 'parity_newAccountFromPhrase':
|
case 'parity_newAccountFromPhrase':
|
||||||
|
@ -36,7 +36,8 @@ export const ERROR_CODES = {
|
|||||||
REQUEST_NOT_FOUND: -32042,
|
REQUEST_NOT_FOUND: -32042,
|
||||||
COMPILATION_ERROR: -32050,
|
COMPILATION_ERROR: -32050,
|
||||||
ENCRYPTION_ERROR: -32055,
|
ENCRYPTION_ERROR: -32055,
|
||||||
FETCH_ERROR: -32060
|
FETCH_ERROR: -32060,
|
||||||
|
INVALID_PARAMS: -32602
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class TransportError extends ExtendableError {
|
export default class TransportError extends ExtendableError {
|
||||||
|
@ -29,21 +29,33 @@ export default class Ws extends JsonRpcBase {
|
|||||||
this._token = token;
|
this._token = token;
|
||||||
this._messages = {};
|
this._messages = {};
|
||||||
|
|
||||||
this._connecting = true;
|
this._connecting = false;
|
||||||
|
this._connected = false;
|
||||||
this._lastError = null;
|
this._lastError = null;
|
||||||
this._autoConnect = false;
|
this._autoConnect = true;
|
||||||
|
this._retries = 0;
|
||||||
|
this._reconnectTimeoutId = null;
|
||||||
|
|
||||||
this._connect();
|
this._connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateToken (token) {
|
updateToken (token) {
|
||||||
this._token = token;
|
this._token = token;
|
||||||
this._autoConnect = false;
|
this._autoConnect = true;
|
||||||
|
|
||||||
this._connect();
|
this._connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
_connect () {
|
_connect () {
|
||||||
|
if (this._connecting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._reconnectTimeoutId) {
|
||||||
|
window.clearTimeout(this._reconnectTimeoutId);
|
||||||
|
this._reconnectTimeoutId = null;
|
||||||
|
}
|
||||||
|
|
||||||
const time = parseInt(new Date().getTime() / 1000, 10);
|
const time = parseInt(new Date().getTime() / 1000, 10);
|
||||||
const sha3 = keccak_256(`${this._token}:${time}`);
|
const sha3 = keccak_256(`${this._token}:${time}`);
|
||||||
const hash = `${sha3}_${time}`;
|
const hash = `${sha3}_${time}`;
|
||||||
@ -53,6 +65,7 @@ export default class Ws extends JsonRpcBase {
|
|||||||
this._ws.onopen = null;
|
this._ws.onopen = null;
|
||||||
this._ws.onclose = null;
|
this._ws.onclose = null;
|
||||||
this._ws.onmessage = null;
|
this._ws.onmessage = null;
|
||||||
|
this._ws.close();
|
||||||
this._ws = null;
|
this._ws = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +78,32 @@ export default class Ws extends JsonRpcBase {
|
|||||||
this._ws.onopen = this._onOpen;
|
this._ws.onopen = this._onOpen;
|
||||||
this._ws.onclose = this._onClose;
|
this._ws.onclose = this._onClose;
|
||||||
this._ws.onmessage = this._onMessage;
|
this._ws.onmessage = this._onMessage;
|
||||||
|
|
||||||
|
// Get counts in dev mode only
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
this._count = 0;
|
||||||
|
this._lastCount = {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
count: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
window.setInterval(() => {
|
||||||
|
const n = this._count - this._lastCount.count;
|
||||||
|
const t = (Date.now() - this._lastCount.timestamp) / 1000;
|
||||||
|
const s = Math.round(1000 * n / t) / 1000;
|
||||||
|
|
||||||
|
if (this._debug) {
|
||||||
|
console.log('::parityWS', `speed: ${s} req/s`, `count: ${this._count}`, `(+${n})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._lastCount = {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
count: this._count
|
||||||
|
};
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
window._parityWS = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onOpen = (event) => {
|
_onOpen = (event) => {
|
||||||
@ -72,6 +111,7 @@ export default class Ws extends JsonRpcBase {
|
|||||||
this._connected = true;
|
this._connected = true;
|
||||||
this._connecting = false;
|
this._connecting = false;
|
||||||
this._autoConnect = true;
|
this._autoConnect = true;
|
||||||
|
this._retries = 0;
|
||||||
|
|
||||||
Object.keys(this._messages)
|
Object.keys(this._messages)
|
||||||
.filter((id) => this._messages[id].queued)
|
.filter((id) => this._messages[id].queued)
|
||||||
@ -79,18 +119,42 @@ export default class Ws extends JsonRpcBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onClose = (event) => {
|
_onClose = (event) => {
|
||||||
console.log('ws:onClose', event);
|
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
this._connecting = false;
|
this._connecting = false;
|
||||||
|
|
||||||
|
event.timestamp = Date.now();
|
||||||
|
this._lastError = event;
|
||||||
|
|
||||||
if (this._autoConnect) {
|
if (this._autoConnect) {
|
||||||
setTimeout(() => this._connect(), 500);
|
const timeout = this.retryTimeout;
|
||||||
|
|
||||||
|
const time = timeout < 1000
|
||||||
|
? Math.round(timeout) + 'ms'
|
||||||
|
: (Math.round(timeout / 10) / 100) + 's';
|
||||||
|
|
||||||
|
console.log('ws:onClose', `trying again in ${time}...`);
|
||||||
|
|
||||||
|
this._reconnectTimeoutId = setTimeout(() => {
|
||||||
|
this._connect();
|
||||||
|
}, timeout);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('ws:onClose', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onError = (event) => {
|
_onError = (event) => {
|
||||||
console.error('ws:onError', event);
|
// Only print error if the WS is connected
|
||||||
this._lastError = event;
|
// ie. don't print if error == closed
|
||||||
|
window.setTimeout(() => {
|
||||||
|
if (this._connected) {
|
||||||
|
console.error('ws:onError', event);
|
||||||
|
|
||||||
|
event.timestamp = Date.now();
|
||||||
|
this._lastError = event;
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMessage = (event) => {
|
_onMessage = (event) => {
|
||||||
@ -127,11 +191,16 @@ export default class Ws extends JsonRpcBase {
|
|||||||
_send = (id) => {
|
_send = (id) => {
|
||||||
const message = this._messages[id];
|
const message = this._messages[id];
|
||||||
|
|
||||||
message.queued = !this._connected;
|
|
||||||
|
|
||||||
if (this._connected) {
|
if (this._connected) {
|
||||||
this._ws.send(message.json);
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
this._count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._ws.send(message.json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.queued = !this._connected;
|
||||||
|
message.timestamp = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
execute (method, ...params) {
|
execute (method, ...params) {
|
||||||
@ -159,4 +228,27 @@ export default class Ws extends JsonRpcBase {
|
|||||||
get lastError () {
|
get lastError () {
|
||||||
return this._lastError;
|
return this._lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exponential Timeout for Retries
|
||||||
|
*
|
||||||
|
* @see http://dthain.blogspot.de/2009/02/exponential-backoff-in-distributed.html
|
||||||
|
*/
|
||||||
|
get retryTimeout () {
|
||||||
|
// R between 1 and 2
|
||||||
|
const R = Math.random() + 1;
|
||||||
|
// Initial timeout (100ms)
|
||||||
|
const T = 100;
|
||||||
|
// Exponential Factor
|
||||||
|
const F = 2;
|
||||||
|
// Max timeout (4s)
|
||||||
|
const M = 4000;
|
||||||
|
// Current number of retries
|
||||||
|
const N = this._retries;
|
||||||
|
|
||||||
|
// Increase retries number
|
||||||
|
this._retries++;
|
||||||
|
|
||||||
|
return Math.min(R * T * Math.pow(F, N), M);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { range } from 'lodash';
|
||||||
|
|
||||||
export function bytesToHex (bytes) {
|
export function bytesToHex (bytes) {
|
||||||
return '0x' + bytes.map((b) => ('0' + b.toString(16)).slice(-2)).join('');
|
return '0x' + bytes.map((b) => ('0' + b.toString(16)).slice(-2)).join('');
|
||||||
}
|
}
|
||||||
@ -29,3 +31,29 @@ export function hex2Ascii (_hex) {
|
|||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function asciiToHex (string) {
|
||||||
|
return '0x' + string.split('').map((s) => s.charCodeAt(0).toString(16)).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function padRight (input, length) {
|
||||||
|
const value = toHex(input).substr(2, length * 2);
|
||||||
|
return '0x' + value + range(length * 2 - value.length).map(() => '0').join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function padLeft (input, length) {
|
||||||
|
const value = toHex(input).substr(2, length * 2);
|
||||||
|
return '0x' + range(length * 2 - value.length).map(() => '0').join('') + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toHex (str) {
|
||||||
|
if (str && str.toString) {
|
||||||
|
str = str.toString(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str && str.substr(0, 2) === '0x') {
|
||||||
|
return str.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return `0x${(str || '').toLowerCase()}`;
|
||||||
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
|
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
|
||||||
import { decodeCallData, decodeMethodInput, methodToAbi } from './decode';
|
import { decodeCallData, decodeMethodInput, methodToAbi } from './decode';
|
||||||
import { bytesToHex, hex2Ascii } from './format';
|
import { bytesToHex, hex2Ascii, asciiToHex } from './format';
|
||||||
import { fromWei, toWei } from './wei';
|
import { fromWei, toWei } from './wei';
|
||||||
import { sha3 } from './sha3';
|
import { sha3 } from './sha3';
|
||||||
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
|
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
|
||||||
@ -31,6 +31,7 @@ export default {
|
|||||||
isString,
|
isString,
|
||||||
bytesToHex,
|
bytesToHex,
|
||||||
hex2Ascii,
|
hex2Ascii,
|
||||||
|
asciiToHex,
|
||||||
createIdentityImg,
|
createIdentityImg,
|
||||||
decodeCallData,
|
decodeCallData,
|
||||||
decodeMethodInput,
|
decodeMethodInput,
|
||||||
|
1
js/src/contracts/abi/badgereg.json
Normal file
1
js/src/contracts/abi/badgereg.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"fromName","outputs":[{"name":"id","type":"uint256"},{"name":"addr","type":"address"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"badgeCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"}],"name":"meta","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"}],"name":"unregister","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"fromAddress","outputs":[{"name":"id","type":"uint256"},{"name":"name","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"badge","outputs":[{"name":"addr","type":"address"},{"name":"name","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"},{"name":"_value","type":"bytes32"}],"name":"setMeta","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_name","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"registerAs","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"addr","type":"address"}],"name":"Registered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"id","type":"uint256"}],"name":"Unregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":true,"name":"key","type":"bytes32"},{"indexed":false,"name":"value","type":"bytes32"}],"name":"MetaChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]
|
1
js/src/contracts/abi/certifier.json
Normal file
1
js/src/contracts/abi/certifier.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"certified","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Confirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Revoked","type":"event"}]
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import badgereg from './badgereg.json';
|
||||||
import basiccoin from './basiccoin.json';
|
import basiccoin from './basiccoin.json';
|
||||||
import basiccoinmanager from './basiccoinmanager.json';
|
import basiccoinmanager from './basiccoinmanager.json';
|
||||||
import dappreg from './dappreg.json';
|
import dappreg from './dappreg.json';
|
||||||
@ -28,6 +29,7 @@ import tokenreg from './tokenreg.json';
|
|||||||
import wallet from './wallet.json';
|
import wallet from './wallet.json';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
badgereg,
|
||||||
basiccoin,
|
basiccoin,
|
||||||
basiccoinmanager,
|
basiccoinmanager,
|
||||||
dappreg,
|
dappreg,
|
||||||
|
@ -1 +1 @@
|
|||||||
[{"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":false,"inputs":[],"name":"request","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"},{"name":"_puzzle","type":"bytes32"}],"name":"puzzle","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":"_new","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"bytes32"}],"name":"confirm","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"type":"function"},{"constant":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":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Requested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":false,"name":"puzzle","type":"bytes32"}],"name":"Puzzled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Confirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Revoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]
|
[{"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":false,"inputs":[],"name":"request","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"},{"name":"_puzzle","type":"bytes32"}],"name":"puzzle","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":"_new","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"bytes32"}],"name":"confirm","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"type":"function"},{"constant":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":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Requested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":false,"name":"puzzle","type":"bytes32"}],"name":"Puzzled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Confirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Revoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]
|
||||||
|
66
js/src/contracts/badgereg.js
Normal file
66
js/src/contracts/badgereg.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { bytesToHex, hex2Ascii } from '../api/util/format';
|
||||||
|
|
||||||
|
import ABI from './abi/certifier.json';
|
||||||
|
|
||||||
|
const ZERO = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||||
|
|
||||||
|
export default class BadgeReg {
|
||||||
|
constructor (api, registry) {
|
||||||
|
this._api = api;
|
||||||
|
this._registry = registry;
|
||||||
|
|
||||||
|
registry.getContract('badgereg');
|
||||||
|
this.certifiers = {}; // by name
|
||||||
|
this.contracts = {}; // by name
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchCertifier (name) {
|
||||||
|
if (this.certifiers[name]) {
|
||||||
|
return Promise.resolve(this.certifiers[name]);
|
||||||
|
}
|
||||||
|
return this._registry.getContract('badgereg')
|
||||||
|
.then((badgeReg) => {
|
||||||
|
return badgeReg.instance.fromName.call({}, [name])
|
||||||
|
.then(([ id, address ]) => {
|
||||||
|
return Promise.all([
|
||||||
|
badgeReg.instance.meta.call({}, [id, 'TITLE']),
|
||||||
|
badgeReg.instance.meta.call({}, [id, 'IMG'])
|
||||||
|
])
|
||||||
|
.then(([ title, img ]) => {
|
||||||
|
title = bytesToHex(title);
|
||||||
|
title = title === ZERO ? null : hex2Ascii(title);
|
||||||
|
if (bytesToHex(img) === ZERO) img = null;
|
||||||
|
|
||||||
|
const data = { address, name, title, icon: img };
|
||||||
|
this.certifiers[name] = data;
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIfCertified (certifier, address) {
|
||||||
|
if (!this.contracts[certifier]) {
|
||||||
|
this.contracts[certifier] = this._api.newContract(ABI, certifier);
|
||||||
|
}
|
||||||
|
const contract = this.contracts[certifier];
|
||||||
|
|
||||||
|
return contract.instance.certified.call({}, [address]);
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,8 @@ import Registry from './registry';
|
|||||||
import SignatureReg from './signaturereg';
|
import SignatureReg from './signaturereg';
|
||||||
import TokenReg from './tokenreg';
|
import TokenReg from './tokenreg';
|
||||||
import GithubHint from './githubhint';
|
import GithubHint from './githubhint';
|
||||||
import smsVerification from './sms-verification';
|
import * as smsVerification from './sms-verification';
|
||||||
|
import BadgeReg from './badgereg';
|
||||||
|
|
||||||
let instance = null;
|
let instance = null;
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ export default class Contracts {
|
|||||||
this._signaturereg = new SignatureReg(api, this._registry);
|
this._signaturereg = new SignatureReg(api, this._registry);
|
||||||
this._tokenreg = new TokenReg(api, this._registry);
|
this._tokenreg = new TokenReg(api, this._registry);
|
||||||
this._githubhint = new GithubHint(api, this._registry);
|
this._githubhint = new GithubHint(api, this._registry);
|
||||||
|
this.badgeReg = new BadgeReg(api, this._registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
get registry () {
|
get registry () {
|
||||||
|
@ -21,25 +21,39 @@ export default class Registry {
|
|||||||
this._api = api;
|
this._api = api;
|
||||||
this._contracts = [];
|
this._contracts = [];
|
||||||
this._instance = null;
|
this._instance = null;
|
||||||
|
this._fetching = false;
|
||||||
|
this._queue = [];
|
||||||
|
|
||||||
this.getInstance();
|
this.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
getInstance () {
|
getInstance () {
|
||||||
return new Promise((resolve, reject) => {
|
if (this._instance) {
|
||||||
if (this._instance) {
|
return Promise.resolve(this._instance);
|
||||||
resolve(this._instance);
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._api.parity
|
if (this._fetching) {
|
||||||
.registryAddress()
|
return new Promise((resolve) => {
|
||||||
.then((address) => {
|
this._queue.push({ resolve });
|
||||||
this._instance = this._api.newContract(abis.registry, address).instance;
|
});
|
||||||
resolve(this._instance);
|
}
|
||||||
})
|
|
||||||
.catch(reject);
|
this._fetching = true;
|
||||||
});
|
|
||||||
|
return this._api.parity
|
||||||
|
.registryAddress()
|
||||||
|
.then((address) => {
|
||||||
|
this._fetching = false;
|
||||||
|
this._instance = this._api.newContract(abis.registry, address).instance;
|
||||||
|
|
||||||
|
this._queue.forEach((queued) => {
|
||||||
|
queued.resolve(this._instance);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._queue = [];
|
||||||
|
|
||||||
|
return this._instance;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getContract (_name) {
|
getContract (_name) {
|
||||||
|
@ -14,39 +14,74 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { stringify } from 'querystring';
|
import subscribeToEvent from '../util/subscribe-to-event';
|
||||||
|
|
||||||
export const checkIfVerified = (contract, account) => {
|
export const checkIfVerified = (contract, account) => {
|
||||||
return contract.instance.certified.call({}, [account]);
|
return contract.instance.certified.call({}, [account]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkIfRequested = (contract, account) => {
|
export const checkIfRequested = (contract, account) => {
|
||||||
|
let subId = null;
|
||||||
|
let resolved = false;
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
contract.subscribe('Requested', {
|
contract
|
||||||
fromBlock: 0, toBlock: 'pending'
|
.subscribe('Requested', {
|
||||||
}, (err, logs) => {
|
fromBlock: 0, toBlock: 'pending'
|
||||||
if (err) {
|
}, (err, logs) => {
|
||||||
return reject(err);
|
if (err) {
|
||||||
}
|
return reject(err);
|
||||||
const e = logs.find((l) => {
|
}
|
||||||
return l.type === 'mined' && l.params.who && l.params.who.value === account;
|
const e = logs.find((l) => {
|
||||||
|
return l.type === 'mined' && l.params.who && l.params.who.value === account;
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve(e ? e.transactionHash : false);
|
||||||
|
resolved = true;
|
||||||
|
|
||||||
|
if (subId) {
|
||||||
|
contract.unsubscribe(subId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((_subId) => {
|
||||||
|
subId = _subId;
|
||||||
|
|
||||||
|
if (resolved) {
|
||||||
|
contract.unsubscribe(subId);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
resolve(e ? e.transactionHash : false);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const postToServer = (query) => {
|
const blockNumber = (api) => {
|
||||||
query = stringify(query);
|
return new Promise((resolve, reject) => {
|
||||||
return fetch('https://sms-verification.parity.io/?' + query, {
|
api.subscribe('eth_blockNumber', (err, block) => {
|
||||||
method: 'POST', mode: 'cors', cache: 'no-store'
|
if (err) {
|
||||||
})
|
return reject(err);
|
||||||
.then((res) => {
|
|
||||||
return res.json().then((data) => {
|
|
||||||
if (res.ok) {
|
|
||||||
return data.message;
|
|
||||||
}
|
}
|
||||||
throw new Error(data.message || 'unknown error');
|
resolve(block);
|
||||||
});
|
})
|
||||||
|
.then((subscription) => {
|
||||||
|
api.unsubscribe(subscription);
|
||||||
|
})
|
||||||
|
.catch(reject);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const awaitPuzzle = (api, contract, account) => {
|
||||||
|
return blockNumber(api)
|
||||||
|
.then((block) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const subscription = subscribeToEvent(contract, 'Puzzled', {
|
||||||
|
from: block.toNumber(),
|
||||||
|
filter: (log) => log.params.who.value === account
|
||||||
|
});
|
||||||
|
subscription.once('error', reject);
|
||||||
|
subscription.once('log', subscription.unsubscribe);
|
||||||
|
subscription.once('log', resolve);
|
||||||
|
subscription.once('timeout', () => {
|
||||||
|
reject(new Error('Timed out waiting for the puzzle.'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<link rel="icon" href="/parity-logo-black-no-text.png" type="image/png">
|
|
||||||
<title>Basic Token Deployment</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="container"></div>
|
|
||||||
<script src="vendor.js"></script>
|
|
||||||
<script src="commons.js"></script>
|
|
||||||
<script src="/parity-utils/parity.js"></script>
|
|
||||||
<script src="basiccoin.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -32,7 +32,6 @@ const routerHistory = useRouterHistory(createHashHistory)({});
|
|||||||
import '../../assets/fonts/Roboto/font.css';
|
import '../../assets/fonts/Roboto/font.css';
|
||||||
import '../../assets/fonts/RobotoMono/font.css';
|
import '../../assets/fonts/RobotoMono/font.css';
|
||||||
import './style.css';
|
import './style.css';
|
||||||
import './basiccoin.html';
|
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Router history={ routerHistory }>
|
<Router history={ routerHistory }>
|
||||||
|
@ -105,7 +105,7 @@ export function attachInstances () {
|
|||||||
])
|
])
|
||||||
.then(([registryAddress, netChain]) => {
|
.then(([registryAddress, netChain]) => {
|
||||||
const registry = api.newContract(abis.registry, registryAddress).instance;
|
const registry = api.newContract(abis.registry, registryAddress).instance;
|
||||||
isTest = netChain === 'morden' || netChain === 'testnet';
|
isTest = ['morden', 'ropsten', 'testnet'].includes(netChain);
|
||||||
|
|
||||||
console.log(`contract was found at registry=${registryAddress}`);
|
console.log(`contract was found at registry=${registryAddress}`);
|
||||||
console.log(`running on ${netChain}, isTest=${isTest}`);
|
console.log(`running on ${netChain}, isTest=${isTest}`);
|
||||||
|
32
js/src/dapps/dappreg.js
Normal file
32
js/src/dapps/dappreg.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import injectTapEventPlugin from 'react-tap-event-plugin';
|
||||||
|
|
||||||
|
injectTapEventPlugin();
|
||||||
|
|
||||||
|
import Application from './dappreg/Application';
|
||||||
|
|
||||||
|
import '../../assets/fonts/Roboto/font.css';
|
||||||
|
import '../../assets/fonts/RobotoMono/font.css';
|
||||||
|
import './style.css';
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Application />,
|
||||||
|
document.querySelector('#container')
|
||||||
|
);
|
58
js/src/dapps/dappreg/Application/application.css
Normal file
58
js/src/dapps/dappreg/Application/application.css
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.body {
|
||||||
|
color: #333;
|
||||||
|
background: #eee;
|
||||||
|
padding: 4.5em 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 980px;
|
||||||
|
padding: 1.5em;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
font-size: 0.75em;
|
||||||
|
margin: 1em;
|
||||||
|
padding: 1.5em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: #44e;
|
||||||
|
border-radius: 0 0 0.25em 0.25em;
|
||||||
|
color: #fff;
|
||||||
|
left: 0;
|
||||||
|
padding: 1em;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 5em;
|
||||||
|
font-size: 2em;
|
||||||
|
color: #999;
|
||||||
|
}
|
64
js/src/dapps/dappreg/Application/application.js
Normal file
64
js/src/dapps/dappreg/Application/application.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import DappsStore from '../dappsStore';
|
||||||
|
|
||||||
|
import ButtonBar from '../ButtonBar';
|
||||||
|
import Dapp from '../Dapp';
|
||||||
|
import ModalDelete from '../ModalDelete';
|
||||||
|
import ModalRegister from '../ModalRegister';
|
||||||
|
import ModalUpdate from '../ModalUpdate';
|
||||||
|
import SelectDapp from '../SelectDapp';
|
||||||
|
import Warning from '../Warning';
|
||||||
|
import styles from './application.css';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class Application extends Component {
|
||||||
|
dappsStore = DappsStore.instance();
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if (this.dappsStore.isLoading) {
|
||||||
|
return (
|
||||||
|
<div className={ styles.loading }>
|
||||||
|
Loading application
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.body }>
|
||||||
|
<div className={ styles.header }>
|
||||||
|
DAPP REGISTRY, a global view of distributed applications available on the network. Putting the puzzle together.
|
||||||
|
</div>
|
||||||
|
<div className={ styles.apps }>
|
||||||
|
<SelectDapp />
|
||||||
|
<ButtonBar />
|
||||||
|
<Dapp />
|
||||||
|
</div>
|
||||||
|
<div className={ styles.footer }>
|
||||||
|
{ this.dappsStore.count } applications registered, { this.dappsStore.ownedCount } owned by user
|
||||||
|
</div>
|
||||||
|
<Warning />
|
||||||
|
<ModalDelete />
|
||||||
|
<ModalRegister />
|
||||||
|
<ModalUpdate />
|
||||||
|
</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 './transaction';
|
export default from './application';
|
38
js/src/dapps/dappreg/Button/button.css
Normal file
38
js/src/dapps/dappreg/Button/button.css
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: #44e;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.25em;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 1em 0.375em;
|
||||||
|
opacity: 0.85;
|
||||||
|
padding: 0.75em 2em;
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: default;
|
||||||
|
background: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-warning="true"] {
|
||||||
|
background: #e44;
|
||||||
|
}
|
||||||
|
}
|
52
js/src/dapps/dappreg/Button/button.js
Normal file
52
js/src/dapps/dappreg/Button/button.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import styles from './button.css';
|
||||||
|
|
||||||
|
export default class Button extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
label: PropTypes.string.isRequired,
|
||||||
|
warning: PropTypes.bool,
|
||||||
|
onClick: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { className, disabled, label, warning } = this.props;
|
||||||
|
const classes = `${styles.button} ${className}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={ classes }
|
||||||
|
data-warning={ warning }
|
||||||
|
disabled={ disabled }
|
||||||
|
onClick={ this.onClick }>
|
||||||
|
{ label }
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick = (event) => {
|
||||||
|
if (this.props.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.onClick(event);
|
||||||
|
}
|
||||||
|
}
|
@ -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 './RequestPendingWeb3';
|
export default from './button';
|
21
js/src/dapps/dappreg/ButtonBar/buttonBar.css
Normal file
21
js/src/dapps/dappreg/ButtonBar/buttonBar.css
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.buttonbar {
|
||||||
|
text-align: center;
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
}
|
101
js/src/dapps/dappreg/ButtonBar/buttonBar.js
Normal file
101
js/src/dapps/dappreg/ButtonBar/buttonBar.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import DappsStore from '../dappsStore';
|
||||||
|
import ModalStore from '../modalStore';
|
||||||
|
|
||||||
|
import Button from '../Button';
|
||||||
|
import styles from './buttonBar.css';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class ButtonBar extends Component {
|
||||||
|
dappsStore = DappsStore.instance();
|
||||||
|
modalStore = ModalStore.instance();
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let buttons = [];
|
||||||
|
|
||||||
|
if (this.dappsStore.isEditing || this.dappsStore.isNew) {
|
||||||
|
buttons = [
|
||||||
|
<Button
|
||||||
|
key='cancel'
|
||||||
|
label='Cancel'
|
||||||
|
warning
|
||||||
|
onClick={ this.onCancelClick } />,
|
||||||
|
<Button
|
||||||
|
key='save'
|
||||||
|
label={ this.dappsStore.isNew ? 'Register' : 'Update' }
|
||||||
|
disabled={ !this.dappsStore.canSave }
|
||||||
|
onClick={ this.onSaveClick } />
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
buttons = [
|
||||||
|
<Button
|
||||||
|
key='delete'
|
||||||
|
label='Delete'
|
||||||
|
warning
|
||||||
|
disabled={ !this.dappsStore.currentApp || (!this.dappsStore.currentApp.isOwner && !this.dappsStore.isContractOwner) }
|
||||||
|
onClick={ this.onDeleteClick } />,
|
||||||
|
<Button
|
||||||
|
key='edit'
|
||||||
|
label='Edit'
|
||||||
|
disabled={ !this.dappsStore.currentApp || !this.dappsStore.currentApp.isOwner }
|
||||||
|
onClick={ this.onEditClick } />,
|
||||||
|
<Button
|
||||||
|
key='new'
|
||||||
|
label='New'
|
||||||
|
onClick={ this.onNewClick } />
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.buttonbar }>
|
||||||
|
{ buttons }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancelClick = () => {
|
||||||
|
if (this.dappsStore.isEditing) {
|
||||||
|
this.dappsStore.setEditing(false);
|
||||||
|
} else {
|
||||||
|
this.dappsStore.setNew(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeleteClick = () => {
|
||||||
|
this.modalStore.showDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditClick = () => {
|
||||||
|
this.dappsStore.setEditing(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
onNewClick = () => {
|
||||||
|
this.dappsStore.setNew(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSaveClick = () => {
|
||||||
|
if (this.dappsStore.isEditing) {
|
||||||
|
this.modalStore.showUpdate();
|
||||||
|
} else {
|
||||||
|
this.modalStore.showRegister();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 './RequestFinishedWeb3';
|
export default from './buttonBar';
|
19
js/src/dapps/dappreg/Dapp/dapp.css
Normal file
19
js/src/dapps/dappreg/Dapp/dapp.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.app {
|
||||||
|
}
|
166
js/src/dapps/dappreg/Dapp/dapp.js
Normal file
166
js/src/dapps/dappreg/Dapp/dapp.js
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import { api } from '../parity';
|
||||||
|
import DappsStore from '../dappsStore';
|
||||||
|
|
||||||
|
import Input from '../Input';
|
||||||
|
import SelectAccount from '../SelectAccount';
|
||||||
|
import styles from './dapp.css';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class Dapp extends Component {
|
||||||
|
dappsStore = DappsStore.instance();
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const app = this.dappsStore.isNew || this.dappsStore.isEditing
|
||||||
|
? this.dappsStore.wipApp
|
||||||
|
: this.dappsStore.currentApp;
|
||||||
|
|
||||||
|
if (!app) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.app }>
|
||||||
|
{ this.dappsStore.isNew ? this.renderOwnerSelect(app) : this.renderOwnerStatic(app) }
|
||||||
|
{ this.renderInputs(app) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderInputs (app) {
|
||||||
|
if (this.dappsStore.isNew) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
this.renderHashInput(app, 'image', 'Image hash, as generated by Githubhint', true),
|
||||||
|
this.renderHashInput(app, 'manifest', 'Manifest hash, as generated by Githubhint'),
|
||||||
|
this.renderHashInput(app, 'content', 'Content hash, as generated by Githubhint')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
renderOwnerSelect (app) {
|
||||||
|
const overlayImage = (
|
||||||
|
<img
|
||||||
|
className={ styles.overlayImage }
|
||||||
|
src={ api.util.createIdentityImg(this.dappsStore.currentAccount.address, 4) } />
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
hint={ this.dappsStore.currentAccount.address }
|
||||||
|
label='Owner, select the application owner and editor'
|
||||||
|
overlay={ overlayImage }>
|
||||||
|
<SelectAccount />
|
||||||
|
</Input>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderOwnerStatic (app) {
|
||||||
|
const overlayImage = (
|
||||||
|
<img
|
||||||
|
className={ styles.overlayImage }
|
||||||
|
src={ api.util.createIdentityImg(app.owner, 4) } />
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
hint={ app.owner }
|
||||||
|
label='Owner, the application owner and editor'
|
||||||
|
overlay={ overlayImage }>
|
||||||
|
<input value={ app.ownerName } readOnly />
|
||||||
|
</Input>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderHashInput (app, type, label, withImage = false) {
|
||||||
|
const onChange = (event) => this.onChangeHash(event, type);
|
||||||
|
const hash = app[`${type}Hash`];
|
||||||
|
|
||||||
|
let overlayImage = null;
|
||||||
|
if (withImage && hash) {
|
||||||
|
overlayImage = (
|
||||||
|
<img
|
||||||
|
className={ styles.overlayImage }
|
||||||
|
src={ `/api/content/${hash.substr(2)}` } />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
hint={ app[`${type}Error`] || app[`${type}Url`] || '...' }
|
||||||
|
label={ label }
|
||||||
|
key={ `${type}Edit` }
|
||||||
|
overlay={ overlayImage }>
|
||||||
|
<input
|
||||||
|
value={ app[`${type}Hash`] || '' }
|
||||||
|
data-dirty={ app[`${type}Changed`] }
|
||||||
|
data-error={ !!app[`${type}Error`] }
|
||||||
|
readOnly={ !this.dappsStore.isEditing && !this.dappsStore.isNew }
|
||||||
|
onChange={ onChange } />
|
||||||
|
</Input>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeHash (event, type) {
|
||||||
|
if (!this.dappsStore.isNew && !this.dappsStore.isEditing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = event.target.value;
|
||||||
|
let changed = false;
|
||||||
|
let url = null;
|
||||||
|
|
||||||
|
if (this.dappsStore.isNew) {
|
||||||
|
if (hash && hash.length) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.dappsStore.currentApp[`${type}Hash`] !== hash) {
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
url = this.dappsStore.currentApp[`${type}Url`];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dappsStore.editWip({
|
||||||
|
[`${type}Changed`]: changed,
|
||||||
|
[`${type}Error`]: null,
|
||||||
|
[`${type}Hash`]: hash,
|
||||||
|
[`${type}Url`]: changed ? 'Resolving url from hash' : url
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
if (hash.length) {
|
||||||
|
this.dappsStore
|
||||||
|
.lookupHash(hash)
|
||||||
|
.then((url) => {
|
||||||
|
this.dappsStore.editWip({
|
||||||
|
[`${type}Error`]: url ? null : 'Unable to resolve url',
|
||||||
|
[`${type}Url`]: url
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.dappsStore.editWip({ [`${type}Url`]: null });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
js/src/dapps/dappreg/Dapp/index.js
Normal file
17
js/src/dapps/dappreg/Dapp/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './dapp';
|
17
js/src/dapps/dappreg/Input/index.js
Normal file
17
js/src/dapps/dappreg/Input/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './input';
|
92
js/src/dapps/dappreg/Input/input.css
Normal file
92
js/src/dapps/dappreg/Input/input.css
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.input {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
input, select {
|
||||||
|
background: rgba(255, 255, 255, 0.85);
|
||||||
|
border: 4px solid rgba(223, 223, 223, 0.85);
|
||||||
|
border-radius: 0.25em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #333;
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 0.25em 0 0.25em 0;
|
||||||
|
padding: 0.5em 0.5em 1.5em 0.5em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding-bottom: 1.5em;
|
||||||
|
|
||||||
|
&[data-dirty="true"] {
|
||||||
|
background: rgba(255, 255, 203, 0.85);
|
||||||
|
border-color: rgba(203, 203, 151, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-error="true"] {
|
||||||
|
background: rgba(255, 223, 223, 0.85) !important;
|
||||||
|
border-color: rgba(223, 191, 191, 0.85) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[readonly] {
|
||||||
|
background: rgba(239, 239, 239, 0.85);
|
||||||
|
border-color: rgba(223, 223, 223, 0.85);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
color: #888;
|
||||||
|
display: block;
|
||||||
|
font-size: 0.75em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
-moz-appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
height: 58px;
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
background: rgba(239, 239, 239, 0.85);
|
||||||
|
border-color: rgba(223, 223, 223, 0.85);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
color: #888;
|
||||||
|
display: block;
|
||||||
|
font-size: 0.75em;
|
||||||
|
position: absolute;
|
||||||
|
right: 52px;
|
||||||
|
text-align: right;
|
||||||
|
top: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
right: 10px;
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
js/src/dapps/dappreg/Input/input.js
Normal file
47
js/src/dapps/dappreg/Input/input.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import styles from './input.css';
|
||||||
|
|
||||||
|
export default class Input extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
hint: PropTypes.string,
|
||||||
|
label: PropTypes.string.isRequired,
|
||||||
|
overlay: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { children, hint, label, overlay } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.input }>
|
||||||
|
<label>
|
||||||
|
{ label }
|
||||||
|
</label>
|
||||||
|
{ children }
|
||||||
|
<div className={ styles.hint }>
|
||||||
|
{ hint }
|
||||||
|
</div>
|
||||||
|
<div className={ styles.overlay }>
|
||||||
|
{ overlay }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
js/src/dapps/dappreg/Modal/index.js
Normal file
17
js/src/dapps/dappreg/Modal/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './modal';
|
116
js/src/dapps/dappreg/Modal/modal.css
Normal file
116
js/src/dapps/dappreg/Modal/modal.css
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
.body {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 50;
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 0 0 0.25em 0.25em;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 840px;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
line-height: 1.5em;
|
||||||
|
padding: 2em;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
color: #f44;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section+.section {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
padding: 0.5em 1.625em;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: #44e;
|
||||||
|
color: #fff;
|
||||||
|
opacity: 0.85;
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
background: #e44;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
background: rgba(204, 204, 204, 0.7);
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 49;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
div {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
display: block !important;
|
||||||
|
color: #888;
|
||||||
|
font-size: 0.75em;
|
||||||
|
margin-top: -0.5em;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
color: #888;
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light {
|
||||||
|
color: #888;
|
||||||
|
}
|
66
js/src/dapps/dappreg/Modal/modal.js
Normal file
66
js/src/dapps/dappreg/Modal/modal.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import styles from './modal.css';
|
||||||
|
|
||||||
|
export default class Modal extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
buttons: PropTypes.node,
|
||||||
|
children: PropTypes.node,
|
||||||
|
error: PropTypes.object,
|
||||||
|
header: PropTypes.string
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { children, buttons, error, header } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.modal }>
|
||||||
|
<div className={ styles.overlay } />
|
||||||
|
<div className={ styles.body }>
|
||||||
|
<div className={ styles.dialog }>
|
||||||
|
<div className={ `${styles.header} ${error ? styles.error : ''}` }>
|
||||||
|
{ header }
|
||||||
|
</div>
|
||||||
|
<div className={ styles.content }>
|
||||||
|
{ error ? this.renderError() : children }
|
||||||
|
</div>
|
||||||
|
<div className={ styles.footer }>
|
||||||
|
{ buttons }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderError () {
|
||||||
|
const { error } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
Your operation failed to complete sucessfully. The following error was returned:
|
||||||
|
</div>
|
||||||
|
<div className={ `${styles.section} ${styles.error}` }>
|
||||||
|
{ error.toString() }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
js/src/dapps/dappreg/ModalDelete/index.js
Normal file
17
js/src/dapps/dappreg/ModalDelete/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './modalDelete';
|
159
js/src/dapps/dappreg/ModalDelete/modalDelete.js
Normal file
159
js/src/dapps/dappreg/ModalDelete/modalDelete.js
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import { api } from '../parity';
|
||||||
|
import DappsStore from '../dappsStore';
|
||||||
|
import ModalStore from '../modalStore';
|
||||||
|
|
||||||
|
import Button from '../Button';
|
||||||
|
import Modal from '../Modal';
|
||||||
|
|
||||||
|
import styles from '../Modal/modal.css';
|
||||||
|
|
||||||
|
const HEADERS = [
|
||||||
|
'Error During Deletion',
|
||||||
|
'Confirm Application Deletion',
|
||||||
|
'Waiting for Signer Confirmation',
|
||||||
|
'Waiting for Transaction Receipt',
|
||||||
|
'Deletion Completed'
|
||||||
|
];
|
||||||
|
const STEP_ERROR = 0;
|
||||||
|
const STEP_CONFIRM = 1;
|
||||||
|
const STEP_SIGNER = 2;
|
||||||
|
const STEP_TXRECEIPT = 3;
|
||||||
|
const STEP_DONE = 4;
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class ModalDelete extends Component {
|
||||||
|
dappsStore = DappsStore.instance();
|
||||||
|
modalStore = ModalStore.instance();
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if (!this.modalStore.showingDelete) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
buttons={ this.renderButtons() }
|
||||||
|
error={ this.modalStore.errorDelete }
|
||||||
|
header={ HEADERS[this.modalStore.stepDelete] }>
|
||||||
|
{ this.renderStep() }
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons () {
|
||||||
|
switch (this.modalStore.stepDelete) {
|
||||||
|
case STEP_ERROR:
|
||||||
|
case STEP_DONE:
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
key='close'
|
||||||
|
label='Close'
|
||||||
|
onClick={ this.onClickClose } />
|
||||||
|
];
|
||||||
|
case STEP_CONFIRM:
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
key='cancel'
|
||||||
|
label='No, Cancel'
|
||||||
|
onClick={ this.onClickClose } />,
|
||||||
|
<Button
|
||||||
|
key='delete'
|
||||||
|
label='Yes, Delete'
|
||||||
|
warning
|
||||||
|
onClick={ this.onClickYes } />
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStep () {
|
||||||
|
switch (this.modalStore.stepDelete) {
|
||||||
|
case STEP_CONFIRM:
|
||||||
|
return this.renderStepConfirm();
|
||||||
|
case STEP_SIGNER:
|
||||||
|
return this.renderStepWait('Waiting for transaction confirmation in the Parity secure signer');
|
||||||
|
case STEP_TXRECEIPT:
|
||||||
|
return this.renderStepWait('Waiting for the transaction receipt from the network');
|
||||||
|
case STEP_DONE:
|
||||||
|
return this.renderStepCompleted();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepCompleted () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
Your application has been removed from the registry.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepConfirm () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
You are about to remove a distributed application from the registry, the details of this application is given below. Removal does not return any fees, however the application will not be available to users anymore.
|
||||||
|
</div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
<div className={ styles.heading }>
|
||||||
|
Owner account
|
||||||
|
</div>
|
||||||
|
<div className={ styles.account }>
|
||||||
|
<img src={ api.util.createIdentityImg(this.dappsStore.currentApp.owner, 3) } />
|
||||||
|
<div>{ this.dappsStore.currentApp.ownerName }</div>
|
||||||
|
<div className={ styles.address }>{ this.dappsStore.currentApp.owner }</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
<div className={ styles.heading }>
|
||||||
|
Application identifier
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{ this.dappsStore.currentApp.id }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepWait (waitingFor) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
{ waitingFor }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickClose = () => {
|
||||||
|
this.modalStore.hideDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickYes = () => {
|
||||||
|
this.modalStore.doDelete();
|
||||||
|
}
|
||||||
|
}
|
17
js/src/dapps/dappreg/ModalRegister/index.js
Normal file
17
js/src/dapps/dappreg/ModalRegister/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './modalRegister';
|
159
js/src/dapps/dappreg/ModalRegister/modalRegister.js
Normal file
159
js/src/dapps/dappreg/ModalRegister/modalRegister.js
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import { api } from '../parity';
|
||||||
|
import DappsStore from '../dappsStore';
|
||||||
|
import ModalStore from '../modalStore';
|
||||||
|
|
||||||
|
import Button from '../Button';
|
||||||
|
import Modal from '../Modal';
|
||||||
|
|
||||||
|
import styles from '../Modal/modal.css';
|
||||||
|
|
||||||
|
const HEADERS = [
|
||||||
|
'Error During Registration',
|
||||||
|
'Confirm Application Registration',
|
||||||
|
'Waiting for Signer Confirmation',
|
||||||
|
'Waiting for Transaction Receipt',
|
||||||
|
'Registration Completed'
|
||||||
|
];
|
||||||
|
const STEP_ERROR = 0;
|
||||||
|
const STEP_CONFIRM = 1;
|
||||||
|
const STEP_SIGNER = 2;
|
||||||
|
const STEP_TXRECEIPT = 3;
|
||||||
|
const STEP_DONE = 4;
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class ModalRegister extends Component {
|
||||||
|
dappsStore = DappsStore.instance();
|
||||||
|
modalStore = ModalStore.instance();
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if (!this.modalStore.showingRegister) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
buttons={ this.renderButtons() }
|
||||||
|
error={ this.modalStore.errorRegister }
|
||||||
|
header={ HEADERS[this.modalStore.stepRegister] }>
|
||||||
|
{ this.renderStep() }
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons () {
|
||||||
|
switch (this.modalStore.stepRegister) {
|
||||||
|
case STEP_ERROR:
|
||||||
|
case STEP_DONE:
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
key='close'
|
||||||
|
label='Close'
|
||||||
|
onClick={ this.onClickClose } />
|
||||||
|
];
|
||||||
|
case STEP_CONFIRM:
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
key='cancel'
|
||||||
|
label='No, Cancel'
|
||||||
|
onClick={ this.onClickClose } />,
|
||||||
|
<Button
|
||||||
|
key='register'
|
||||||
|
label='Yes, Register'
|
||||||
|
warning
|
||||||
|
onClick={ this.onClickConfirmYes } />
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStep () {
|
||||||
|
switch (this.modalStore.stepRegister) {
|
||||||
|
case STEP_CONFIRM:
|
||||||
|
return this.renderStepConfirm();
|
||||||
|
case STEP_SIGNER:
|
||||||
|
return this.renderStepWait('Waiting for transaction confirmation in the Parity secure signer');
|
||||||
|
case STEP_TXRECEIPT:
|
||||||
|
return this.renderStepWait('Waiting for the transaction receipt from the network');
|
||||||
|
case STEP_DONE:
|
||||||
|
return this.renderStepCompleted();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepCompleted () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
Your application has been registered in the registry.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepConfirm () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
You are about to register a new distributed application on the network, the details of this application is given below. This will require a non-refundable fee of { api.util.fromWei(this.dappsStore.fee).toFormat(3) }<small>ETH</small>.
|
||||||
|
</div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
<div className={ styles.heading }>
|
||||||
|
Selected owner account
|
||||||
|
</div>
|
||||||
|
<div className={ styles.account }>
|
||||||
|
<img src={ api.util.createIdentityImg(this.dappsStore.currentAccount.address, 3) } />
|
||||||
|
<div>{ this.dappsStore.currentAccount.name }</div>
|
||||||
|
<div className={ styles.hint }>{ this.dappsStore.currentAccount.address }</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
<div className={ styles.heading }>
|
||||||
|
Unique assigned application identifier
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{ this.dappsStore.wipApp.id }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepWait (waitingFor) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
{ waitingFor }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickClose = () => {
|
||||||
|
this.modalStore.hideRegister();
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickConfirmYes = () => {
|
||||||
|
this.modalStore.doRegister();
|
||||||
|
}
|
||||||
|
}
|
17
js/src/dapps/dappreg/ModalUpdate/index.js
Normal file
17
js/src/dapps/dappreg/ModalUpdate/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './modalUpdate';
|
169
js/src/dapps/dappreg/ModalUpdate/modalUpdate.js
Normal file
169
js/src/dapps/dappreg/ModalUpdate/modalUpdate.js
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import DappsStore from '../dappsStore';
|
||||||
|
import ModalStore from '../modalStore';
|
||||||
|
|
||||||
|
import Button from '../Button';
|
||||||
|
import Modal from '../Modal';
|
||||||
|
|
||||||
|
import styles from '../Modal/modal.css';
|
||||||
|
|
||||||
|
const HEADERS = [
|
||||||
|
'Error During Update',
|
||||||
|
'Confirm Application Update',
|
||||||
|
'Waiting for Signer Confirmation',
|
||||||
|
'Waiting for Transaction Receipt',
|
||||||
|
'Update Completed'
|
||||||
|
];
|
||||||
|
const STEP_ERROR = 0;
|
||||||
|
const STEP_CONFIRM = 1;
|
||||||
|
const STEP_SIGNER = 2;
|
||||||
|
const STEP_TXRECEIPT = 3;
|
||||||
|
const STEP_DONE = 4;
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export default class ModalUpdate extends Component {
|
||||||
|
dappsStore = DappsStore.instance();
|
||||||
|
modalStore = ModalStore.instance();
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if (!this.modalStore.showingUpdate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
buttons={ this.renderButtons() }
|
||||||
|
error={ this.modalStore.errorUpdate }
|
||||||
|
header={ HEADERS[this.modalStore.stepUpdate] }>
|
||||||
|
{ this.renderStep() }
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons () {
|
||||||
|
switch (this.modalStore.stepUpdate) {
|
||||||
|
case STEP_ERROR:
|
||||||
|
case STEP_DONE:
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
key='close'
|
||||||
|
label='Close'
|
||||||
|
onClick={ this.onClickClose } />
|
||||||
|
];
|
||||||
|
case STEP_CONFIRM:
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
key='cancel'
|
||||||
|
label='No, Cancel'
|
||||||
|
onClick={ this.onClickClose } />,
|
||||||
|
<Button
|
||||||
|
key='delete'
|
||||||
|
label='Yes, Update'
|
||||||
|
warning
|
||||||
|
onClick={ this.onClickYes } />
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStep () {
|
||||||
|
switch (this.modalStore.stepUpdate) {
|
||||||
|
case STEP_CONFIRM:
|
||||||
|
return this.renderStepConfirm();
|
||||||
|
case STEP_SIGNER:
|
||||||
|
return this.renderStepWait('Waiting for transaction confirmation in the Parity secure signer');
|
||||||
|
case STEP_TXRECEIPT:
|
||||||
|
return this.renderStepWait('Waiting for the transaction receipt from the network');
|
||||||
|
case STEP_DONE:
|
||||||
|
return this.renderStepCompleted();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepCompleted () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
Your application metadata has been updated in the registry.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepConfirm () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
You are about to update the application details in the registry, the details of these updates are given below. Please note that each update will generate a seperate transaction.
|
||||||
|
</div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
<div className={ styles.heading }>
|
||||||
|
Application identifier
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{ this.dappsStore.wipApp.id }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{ this.renderChanges() }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderChanges () {
|
||||||
|
return ['content', 'image', 'manifest']
|
||||||
|
.filter((type) => this.dappsStore.wipApp[`${type}Changed`])
|
||||||
|
.map((type) => {
|
||||||
|
return (
|
||||||
|
<div className={ styles.section } key={ `${type}Update` }>
|
||||||
|
<div className={ styles.heading }>
|
||||||
|
Updates to { type } hash
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>{ this.dappsStore.wipApp[`${type}Hash`] || '(removed)' }</div>
|
||||||
|
<div className={ styles.hint }>
|
||||||
|
{ this.dappsStore.wipApp[`${type}Url`] || 'current url to be removed from registry' }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepWait (waitingFor) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ styles.section }>
|
||||||
|
{ waitingFor }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickClose = () => {
|
||||||
|
this.modalStore.hideUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickYes = () => {
|
||||||
|
this.modalStore.doUpdate();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user