Merge branch 'master' into lightsync
This commit is contained in:
		
						commit
						01b494ca2c
					
				@ -166,27 +166,30 @@ linux-armv7:
 | 
				
			|||||||
    - export CXX=arm-linux-gnueabihf-g++
 | 
					    - export CXX=arm-linux-gnueabihf-g++
 | 
				
			||||||
    - export HOST_CC=gcc
 | 
					    - export HOST_CC=gcc
 | 
				
			||||||
    - export HOST_CXX=g++
 | 
					    - export HOST_CXX=g++
 | 
				
			||||||
 | 
					    - export PLATFORM=armv7-unknown-linux-gnueabihf
 | 
				
			||||||
    - rm -rf .cargo
 | 
					    - rm -rf .cargo
 | 
				
			||||||
    - mkdir -p .cargo
 | 
					    - mkdir -p .cargo
 | 
				
			||||||
    - echo "[target.armv7-unknown-linux-gnueabihf]" >> .cargo/config
 | 
					    - echo "[target.$PLATFORM]" >> .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 -j $(nproc) --target armv7-unknown-linux-gnueabihf --features final --release $CARGOFLAGS
 | 
					    - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
 | 
				
			||||||
    - arm-linux-gnueabihf-strip target/armv7-unknown-linux-gnueabihf/release/parity
 | 
					    - arm-linux-gnueabihf-strip target/$PLATFORM/release/parity
 | 
				
			||||||
    - md5sum target/armv7-unknown-linux-gnueabihf/release/parity > parity.md5
 | 
					    - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h)
 | 
				
			||||||
 | 
					    - md5sum target/$PLATFORM/release/parity > parity.md5
 | 
				
			||||||
    - sh scripts/deb-build.sh armhf
 | 
					    - sh scripts/deb-build.sh armhf
 | 
				
			||||||
    - cp target/armv7-unknown-linux-gnueabihf/release/parity deb/usr/bin/parity
 | 
					    - cp target/$PLATFORM/release/parity deb/usr/bin/parity
 | 
				
			||||||
    - export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
 | 
					    - export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
 | 
				
			||||||
    - dpkg-deb -b deb "parity_"$VER"_armhf.deb"
 | 
					    - dpkg-deb -b deb "parity_"$VER"_armhf.deb"
 | 
				
			||||||
    - 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
 | 
				
			||||||
    - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
 | 
					    - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
 | 
				
			||||||
    - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf
 | 
					    - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
    - 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 $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/$PLATFORM/release/parity
 | 
				
			||||||
    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/parity.md5 --body parity.md5
 | 
					    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
 | 
				
			||||||
    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/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/$PLATFORM/"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"
 | 
					    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
 | 
				
			||||||
 | 
					    - curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
  tags:
 | 
					  tags:
 | 
				
			||||||
    - rust
 | 
					    - rust
 | 
				
			||||||
    - rust-arm
 | 
					    - rust-arm
 | 
				
			||||||
@ -208,27 +211,30 @@ linux-arm:
 | 
				
			|||||||
    - export CXX=arm-linux-gnueabihf-g++
 | 
					    - export CXX=arm-linux-gnueabihf-g++
 | 
				
			||||||
    - export HOST_CC=gcc
 | 
					    - export HOST_CC=gcc
 | 
				
			||||||
    - export HOST_CXX=g++
 | 
					    - export HOST_CXX=g++
 | 
				
			||||||
 | 
					    - export PLATFORM=arm-unknown-linux-gnueabihf
 | 
				
			||||||
    - rm -rf .cargo
 | 
					    - rm -rf .cargo
 | 
				
			||||||
    - mkdir -p .cargo
 | 
					    - mkdir -p .cargo
 | 
				
			||||||
    - echo "[target.arm-unknown-linux-gnueabihf]" >> .cargo/config
 | 
					    - echo "[target.$PLATFORM]" >> .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 -j $(nproc) --target arm-unknown-linux-gnueabihf --features final --release $CARGOFLAGS
 | 
					    - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
 | 
				
			||||||
    - arm-linux-gnueabihf-strip target/arm-unknown-linux-gnueabihf/release/parity
 | 
					    - arm-linux-gnueabihf-strip target/$PLATFORM/release/parity
 | 
				
			||||||
    - md5sum target/arm-unknown-linux-gnueabihf/release/parity > parity.md5
 | 
					    - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h)
 | 
				
			||||||
 | 
					    - md5sum target/$PLATFORM/release/parity > parity.md5
 | 
				
			||||||
    - sh scripts/deb-build.sh armhf
 | 
					    - sh scripts/deb-build.sh armhf
 | 
				
			||||||
    - cp target/arm-unknown-linux-gnueabihf/release/parity deb/usr/bin/parity
 | 
					    - cp target/$PLATFORM/release/parity deb/usr/bin/parity
 | 
				
			||||||
    - export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
 | 
					    - export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
 | 
				
			||||||
    - dpkg-deb -b deb "parity_"$VER"_armhf.deb"
 | 
					    - dpkg-deb -b deb "parity_"$VER"_armhf.deb"
 | 
				
			||||||
    - 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
 | 
				
			||||||
    - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
 | 
					    - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
 | 
				
			||||||
    - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf
 | 
					    - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
    - 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 $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/$PLATFORM/release/parity
 | 
				
			||||||
    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/parity.md5 --body parity.md5
 | 
					    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
 | 
				
			||||||
    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/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/$PLATFORM/"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"
 | 
					    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_armhf.deb.md5" --body "parity_"$VER"_armhf.deb.md5"
 | 
				
			||||||
 | 
					    - curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
  tags:
 | 
					  tags:
 | 
				
			||||||
    - rust
 | 
					    - rust
 | 
				
			||||||
    - rust-arm
 | 
					    - rust-arm
 | 
				
			||||||
@ -250,20 +256,23 @@ linux-armv6:
 | 
				
			|||||||
    - export CXX=arm-linux-gnueabi-g++
 | 
					    - export CXX=arm-linux-gnueabi-g++
 | 
				
			||||||
    - export HOST_CC=gcc
 | 
					    - export HOST_CC=gcc
 | 
				
			||||||
    - export HOST_CXX=g++
 | 
					    - export HOST_CXX=g++
 | 
				
			||||||
 | 
					    - export PLATFORM=arm-unknown-linux-gnueabi
 | 
				
			||||||
    - rm -rf .cargo
 | 
					    - rm -rf .cargo
 | 
				
			||||||
    - mkdir -p .cargo
 | 
					    - mkdir -p .cargo
 | 
				
			||||||
    - echo "[target.arm-unknown-linux-gnueabi]" >> .cargo/config
 | 
					    - echo "[target.$PLATFORM]" >> .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 -j $(nproc) --target arm-unknown-linux-gnueabi --features final --release $CARGOFLAGS
 | 
					    - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
 | 
				
			||||||
    - arm-linux-gnueabi-strip target/arm-unknown-linux-gnueabi/release/parity
 | 
					    - arm-linux-gnueabi-strip target/$PLATFORM/release/parity
 | 
				
			||||||
    - md5sum target/arm-unknown-linux-gnueabi/release/parity > parity.md5
 | 
					    - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h)
 | 
				
			||||||
 | 
					    - md5sum target/$PLATFORM/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
 | 
					    - 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/arm-unknown-linux-gnueabi
 | 
					    - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
    - 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/$PLATFORM/parity --body target/$PLATFORM/release/parity
 | 
				
			||||||
    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity.md5 --body parity.md5
 | 
					    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5
 | 
				
			||||||
 | 
					    - curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
  tags:
 | 
					  tags:
 | 
				
			||||||
    - rust
 | 
					    - rust
 | 
				
			||||||
    - rust-arm
 | 
					    - rust-arm
 | 
				
			||||||
@ -285,26 +294,29 @@ linux-aarch64:
 | 
				
			|||||||
    - export CXX=aarch64-linux-gnu-g++
 | 
					    - export CXX=aarch64-linux-gnu-g++
 | 
				
			||||||
    - export HOST_CC=gcc
 | 
					    - export HOST_CC=gcc
 | 
				
			||||||
    - export HOST_CXX=g++
 | 
					    - export HOST_CXX=g++
 | 
				
			||||||
 | 
					    - export PLATFORM=aarch64-unknown-linux-gnu
 | 
				
			||||||
    - rm -rf .cargo
 | 
					    - rm -rf .cargo
 | 
				
			||||||
    - mkdir -p .cargo
 | 
					    - mkdir -p .cargo
 | 
				
			||||||
    - echo "[target.aarch64-unknown-linux-gnu]" >> .cargo/config
 | 
					    - echo "[target.$PLATFORM]" >> .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 -j $(nproc) --target aarch64-unknown-linux-gnu --features final --release $CARGOFLAGS
 | 
					    - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS
 | 
				
			||||||
    - aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/parity
 | 
					    - aarch64-linux-gnu-strip target/$PLATFORM/release/parity
 | 
				
			||||||
    - md5sum target/aarch64-unknown-linux-gnu/release/parity > parity.md5
 | 
					    - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h)
 | 
				
			||||||
 | 
					    - md5sum target/$PLATFORM/release/parity > parity.md5
 | 
				
			||||||
    - sh scripts/deb-build.sh arm64
 | 
					    - sh scripts/deb-build.sh arm64
 | 
				
			||||||
    - cp target/aarch64-unknown-linux-gnu/release/parity deb/usr/bin/parity
 | 
					    - cp target/$PLATFORM/release/parity deb/usr/bin/parity
 | 
				
			||||||
    - export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
 | 
					    - export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
 | 
				
			||||||
    - dpkg-deb -b deb "parity_"$VER"_arm64.deb"
 | 
					    - dpkg-deb -b deb "parity_"$VER"_arm64.deb"
 | 
				
			||||||
    - 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
 | 
				
			||||||
    - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
 | 
					    - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
 | 
				
			||||||
    - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu
 | 
					    - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
    - 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/$PLATFORM/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/$PLATFORM/"parity_"$VER"_arm64.deb" --body "parity_"$VER"_arm64.deb"
 | 
				
			||||||
    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/"parity_"$VER"_arm64.deb.md5" --body "parity_"$VER"_arm64.deb.md5"
 | 
					    - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_arm64.deb.md5" --body "parity_"$VER"_arm64.deb.md5"
 | 
				
			||||||
 | 
					    - curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://icarus.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$PLATFORM
 | 
				
			||||||
  tags:
 | 
					  tags:
 | 
				
			||||||
    - rust
 | 
					    - rust
 | 
				
			||||||
    - rust-arm
 | 
					    - rust-arm
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -1368,7 +1368,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#e3e33f97c0f3b3d788a859b5bd10f5ca1ee45871"
 | 
					source = "git+https://github.com/ethcore/js-precompiled.git#c8eb24c13e6fa57bf3b85b16209d281d89b31cbf"
 | 
				
			||||||
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)",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ environment:
 | 
				
			|||||||
  certpass:
 | 
					  certpass:
 | 
				
			||||||
    secure: 0BgXJqxq9Ei34/hZ7121FQ==
 | 
					    secure: 0BgXJqxq9Ei34/hZ7121FQ==
 | 
				
			||||||
  keyfile: C:\users\appveyor\Certificates.p12
 | 
					  keyfile: C:\users\appveyor\Certificates.p12
 | 
				
			||||||
  RUSTFLAGS: -Zorbit=off -D warnings
 | 
					  RUSTFLAGS: -D warnings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
branches:
 | 
					branches:
 | 
				
			||||||
  only:
 | 
					  only:
 | 
				
			||||||
 | 
				
			|||||||
@ -215,31 +215,31 @@ impl Provider for Client {
 | 
				
			|||||||
		None
 | 
							None
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn block_headers(&self, _req: request::Headers) -> Vec<Bytes> {
 | 
						fn block_header(&self, id: BlockId) -> Option<Bytes> {
 | 
				
			||||||
 | 
							self.chain.get_header(id)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn block_body(&self, _id: BlockId) -> Option<Bytes> {
 | 
				
			||||||
 | 
							None
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn block_receipts(&self, _hash: &H256) -> Option<Bytes> {
 | 
				
			||||||
 | 
							None
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn state_proof(&self, _req: request::StateProof) -> Vec<Bytes> {
 | 
				
			||||||
		Vec::new()
 | 
							Vec::new()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn block_bodies(&self, _req: request::Bodies) -> Vec<Bytes> {
 | 
						fn contract_code(&self, _req: request::ContractCode) -> Bytes {
 | 
				
			||||||
		Vec::new()
 | 
							Vec::new()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn receipts(&self, _req: request::Receipts) -> Vec<Bytes> {
 | 
						fn header_proof(&self, _req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)> {
 | 
				
			||||||
		Vec::new()
 | 
							None
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn proofs(&self, _req: request::StateProofs) -> Vec<Bytes> {
 | 
					 | 
				
			||||||
		Vec::new()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn contract_code(&self, _req: request::ContractCodes) -> Vec<Bytes> {
 | 
					 | 
				
			||||||
		Vec::new()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn header_proofs(&self, _req: request::HeaderProofs) -> Vec<Bytes> {
 | 
					 | 
				
			||||||
		Vec::new()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		Client::ready_transactions(self)
 | 
							Vec::new()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -264,7 +264,7 @@ impl LightProtocol {
 | 
				
			|||||||
	/// Check the maximum amount of requests of a specific type
 | 
						/// Check the maximum amount of requests of a specific type
 | 
				
			||||||
	/// which a peer would be able to serve. Returns zero if the
 | 
						/// which a peer would be able to serve. Returns zero if the
 | 
				
			||||||
	/// peer is unknown or has no buffer flow parameters.
 | 
						/// peer is unknown or has no buffer flow parameters.
 | 
				
			||||||
	pub fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize {
 | 
						fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize {
 | 
				
			||||||
		self.peers.read().get(&peer).and_then(|peer| {
 | 
							self.peers.read().get(&peer).and_then(|peer| {
 | 
				
			||||||
			let mut peer = peer.lock();
 | 
								let mut peer = peer.lock();
 | 
				
			||||||
			let idle = peer.idle;
 | 
								let idle = peer.idle;
 | 
				
			||||||
@ -989,7 +989,7 @@ impl LightProtocol {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Codes, req.code_requests.len()));
 | 
							let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Codes, req.code_requests.len()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let response = self.provider.contract_code(req);
 | 
							let response = self.provider.contract_codes(req);
 | 
				
			||||||
		let response_len = response.iter().filter(|x| !x.is_empty()).count();
 | 
							let response_len = response.iter().filter(|x| !x.is_empty()).count();
 | 
				
			||||||
		let actual_cost = self.flow_params.compute_cost(request::Kind::Codes, response_len);
 | 
							let actual_cost = self.flow_params.compute_cost(request::Kind::Codes, response_len);
 | 
				
			||||||
		assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
 | 
							assert!(max_cost >= actual_cost, "Actual cost exceeded maximum computed cost.");
 | 
				
			||||||
 | 
				
			|||||||
@ -94,79 +94,36 @@ impl Provider for TestProvider {
 | 
				
			|||||||
		None
 | 
							None
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn block_headers(&self, req: request::Headers) -> Vec<Bytes> {
 | 
						fn block_header(&self, id: BlockId) -> Option<Bytes> {
 | 
				
			||||||
		use request::HashOrNumber;
 | 
							self.0.client.block_header(id)
 | 
				
			||||||
		use ethcore::views::HeaderView;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		let best_num = self.chain_info().best_block_number;
 | 
					 | 
				
			||||||
		let start_num = match req.start {
 | 
					 | 
				
			||||||
			HashOrNumber::Number(start_num) => start_num,
 | 
					 | 
				
			||||||
			HashOrNumber::Hash(hash) => match self.0.client.block_header(BlockId::Hash(hash)) {
 | 
					 | 
				
			||||||
				None => {
 | 
					 | 
				
			||||||
					return Vec::new();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				Some(header) => {
 | 
					 | 
				
			||||||
					let num = HeaderView::new(&header).number();
 | 
					 | 
				
			||||||
					if req.max == 1 || self.0.client.block_hash(BlockId::Number(num)) != Some(hash) {
 | 
					 | 
				
			||||||
						// Non-canonical header or single header requested.
 | 
					 | 
				
			||||||
						return vec![header];
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					num
 | 
						fn block_body(&self, id: BlockId) -> Option<Bytes> {
 | 
				
			||||||
				}
 | 
							self.0.client.block_body(id)
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		(0u64..req.max as u64)
 | 
					 | 
				
			||||||
			.map(|x: u64| x.saturating_mul(req.skip + 1))
 | 
					 | 
				
			||||||
			.take_while(|x| if req.reverse { x < &start_num } else { best_num - start_num >= *x })
 | 
					 | 
				
			||||||
			.map(|x| if req.reverse { start_num - x } else { start_num + x })
 | 
					 | 
				
			||||||
			.map(|x| self.0.client.block_header(BlockId::Number(x)))
 | 
					 | 
				
			||||||
			.take_while(|x| x.is_some())
 | 
					 | 
				
			||||||
			.flat_map(|x| x)
 | 
					 | 
				
			||||||
			.collect()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> {
 | 
						fn block_receipts(&self, hash: &H256) -> Option<Bytes> {
 | 
				
			||||||
		req.block_hashes.into_iter()
 | 
							self.0.client.block_receipts(&hash)
 | 
				
			||||||
			.map(|hash| self.0.client.block_body(BlockId::Hash(hash)))
 | 
					 | 
				
			||||||
			.map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec()))
 | 
					 | 
				
			||||||
			.collect()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn receipts(&self, req: request::Receipts) -> Vec<Bytes> {
 | 
						fn state_proof(&self, req: request::StateProof) -> Vec<Bytes> {
 | 
				
			||||||
		req.block_hashes.into_iter()
 | 
					 | 
				
			||||||
			.map(|hash| self.0.client.block_receipts(&hash))
 | 
					 | 
				
			||||||
			.map(|receipts| receipts.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec()))
 | 
					 | 
				
			||||||
			.collect()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn proofs(&self, req: request::StateProofs) -> Vec<Bytes> {
 | 
					 | 
				
			||||||
		req.requests.into_iter()
 | 
					 | 
				
			||||||
			.map(|req| {
 | 
					 | 
				
			||||||
		match req.key2 {
 | 
							match req.key2 {
 | 
				
			||||||
					Some(_) => ::util::sha3::SHA3_NULL_RLP.to_vec(),
 | 
								Some(_) => vec![::util::sha3::SHA3_NULL_RLP.to_vec()],
 | 
				
			||||||
			None => {
 | 
								None => {
 | 
				
			||||||
				// sort of a leaf node
 | 
									// sort of a leaf node
 | 
				
			||||||
				let mut stream = RlpStream::new_list(2);
 | 
									let mut stream = RlpStream::new_list(2);
 | 
				
			||||||
				stream.append(&req.key1).append_empty_data();
 | 
									stream.append(&req.key1).append_empty_data();
 | 
				
			||||||
						stream.out()
 | 
									vec![stream.out()]
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
			.collect()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> {
 | 
						fn contract_code(&self, req: request::ContractCode) -> Bytes {
 | 
				
			||||||
		req.code_requests.into_iter()
 | 
					 | 
				
			||||||
			.map(|req| {
 | 
					 | 
				
			||||||
		req.account_key.iter().chain(req.account_key.iter()).cloned().collect()
 | 
							req.account_key.iter().chain(req.account_key.iter()).cloned().collect()
 | 
				
			||||||
			 })
 | 
					 | 
				
			||||||
			.collect()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes> {
 | 
						fn header_proof(&self, _req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)> {
 | 
				
			||||||
		req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect()
 | 
							None
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
@ -455,8 +412,8 @@ fn get_state_proofs() {
 | 
				
			|||||||
	let request_body = encode_request(&request, req_id);
 | 
						let request_body = encode_request(&request, req_id);
 | 
				
			||||||
	let response = {
 | 
						let response = {
 | 
				
			||||||
		let proofs = vec![
 | 
							let proofs = vec![
 | 
				
			||||||
			{ let mut stream = RlpStream::new_list(2); stream.append(&key1).append_empty_data(); stream.out() },
 | 
								{ let mut stream = RlpStream::new_list(2); stream.append(&key1).append_empty_data(); vec![stream.out()] },
 | 
				
			||||||
			::util::sha3::SHA3_NULL_RLP.to_vec(),
 | 
								vec![::util::sha3::SHA3_NULL_RLP.to_vec()],
 | 
				
			||||||
		];
 | 
							];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::StateProofs, 2);
 | 
							let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::StateProofs, 2);
 | 
				
			||||||
@ -465,7 +422,10 @@ fn get_state_proofs() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		response_stream.append(&req_id).append(&new_buf).begin_list(2);
 | 
							response_stream.append(&req_id).append(&new_buf).begin_list(2);
 | 
				
			||||||
		for proof in proofs {
 | 
							for proof in proofs {
 | 
				
			||||||
			response_stream.append_raw(&proof, 1);
 | 
								response_stream.begin_list(proof.len());
 | 
				
			||||||
 | 
								for node in proof {
 | 
				
			||||||
 | 
									response_stream.append_raw(&node, 1);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		response_stream.out()
 | 
							response_stream.out()
 | 
				
			||||||
 | 
				
			|||||||
@ -52,54 +52,12 @@ pub trait Provider: Send + Sync {
 | 
				
			|||||||
	///
 | 
						///
 | 
				
			||||||
	/// The returned vector may have any length in the range [0, `max`], but the
 | 
						/// The returned vector may have any length in the range [0, `max`], but the
 | 
				
			||||||
	/// results within must adhere to the `skip` and `reverse` parameters.
 | 
						/// results within must adhere to the `skip` and `reverse` parameters.
 | 
				
			||||||
	fn block_headers(&self, req: request::Headers) -> Vec<Bytes>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// Provide as many as possible of the requested blocks (minus the headers) encoded
 | 
					 | 
				
			||||||
	/// in RLP format.
 | 
					 | 
				
			||||||
	fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// Provide the receipts as many as possible of the requested blocks.
 | 
					 | 
				
			||||||
	/// Returns a vector of RLP-encoded lists of receipts.
 | 
					 | 
				
			||||||
	fn receipts(&self, req: request::Receipts) -> Vec<Bytes>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// Provide a set of merkle proofs, as requested. Each request is a
 | 
					 | 
				
			||||||
	/// block hash and request parameters.
 | 
					 | 
				
			||||||
	///
 | 
					 | 
				
			||||||
	/// Returns a vector of RLP-encoded lists satisfying the requests.
 | 
					 | 
				
			||||||
	fn proofs(&self, req: request::StateProofs) -> Vec<Bytes>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// Provide contract code for the specified (block_hash, account_hash) pairs.
 | 
					 | 
				
			||||||
	/// Each item in the resulting vector is either the raw bytecode or empty.
 | 
					 | 
				
			||||||
	fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// Provide header proofs from the Canonical Hash Tries as well as the headers 
 | 
					 | 
				
			||||||
	/// they correspond to -- each element in the returned vector is a 2-tuple.
 | 
					 | 
				
			||||||
	/// The first element is a block header and the second a merkle proof of 
 | 
					 | 
				
			||||||
	/// the header in a requested CHT.
 | 
					 | 
				
			||||||
	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// Provide pending transactions.
 | 
					 | 
				
			||||||
	fn ready_transactions(&self) -> Vec<PendingTransaction>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Implementation of a light client data provider for a client.
 | 
					 | 
				
			||||||
impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
					 | 
				
			||||||
	fn chain_info(&self) -> BlockChainInfo {
 | 
					 | 
				
			||||||
		BlockChainClient::chain_info(self)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn reorg_depth(&self, a: &H256, b: &H256) -> Option<u64> {
 | 
					 | 
				
			||||||
		self.tree_route(a, b).map(|route| route.index as u64)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn earliest_state(&self) -> Option<u64> {
 | 
					 | 
				
			||||||
		Some(self.pruning_info().earliest_state)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn block_headers(&self, req: request::Headers) -> Vec<Bytes> {
 | 
						fn block_headers(&self, req: request::Headers) -> Vec<Bytes> {
 | 
				
			||||||
		use request::HashOrNumber;
 | 
							use request::HashOrNumber;
 | 
				
			||||||
		use ethcore::views::HeaderView;
 | 
							use ethcore::views::HeaderView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if req.max == 0 { return Vec::new() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let best_num = self.chain_info().best_block_number;
 | 
							let best_num = self.chain_info().best_block_number;
 | 
				
			||||||
		let start_num = match req.start {
 | 
							let start_num = match req.start {
 | 
				
			||||||
			HashOrNumber::Number(start_num) => start_num,
 | 
								HashOrNumber::Number(start_num) => start_num,
 | 
				
			||||||
@ -110,7 +68,10 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
				Some(header) => {
 | 
									Some(header) => {
 | 
				
			||||||
					let num = HeaderView::new(&header).number();
 | 
										let num = HeaderView::new(&header).number();
 | 
				
			||||||
					if req.max == 1 || self.block_hash(BlockId::Number(num)) != Some(hash) {
 | 
										let canon_hash = self.block_header(BlockId::Number(num))
 | 
				
			||||||
 | 
											.map(|h| HeaderView::new(&h).hash());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if req.max == 1 || canon_hash != Some(hash) {
 | 
				
			||||||
						// Non-canonical header or single header requested.
 | 
											// Non-canonical header or single header requested.
 | 
				
			||||||
						return vec![header];
 | 
											return vec![header];
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
@ -130,6 +91,11 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
				
			|||||||
			.collect()
 | 
								.collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Get a block header by id.
 | 
				
			||||||
 | 
						fn block_header(&self, id: BlockId) -> Option<Bytes>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Provide as many as possible of the requested blocks (minus the headers) encoded
 | 
				
			||||||
 | 
						/// in RLP format.
 | 
				
			||||||
	fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> {
 | 
						fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> {
 | 
				
			||||||
		req.block_hashes.into_iter()
 | 
							req.block_hashes.into_iter()
 | 
				
			||||||
			.map(|hash| self.block_body(BlockId::Hash(hash)))
 | 
								.map(|hash| self.block_body(BlockId::Hash(hash)))
 | 
				
			||||||
@ -137,6 +103,11 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
				
			|||||||
			.collect()
 | 
								.collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Get a block body by id.
 | 
				
			||||||
 | 
						fn block_body(&self, id: BlockId) -> Option<Bytes>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Provide the receipts as many as possible of the requested blocks.
 | 
				
			||||||
 | 
						/// Returns a vector of RLP-encoded lists of receipts.
 | 
				
			||||||
	fn receipts(&self, req: request::Receipts) -> Vec<Bytes> {
 | 
						fn receipts(&self, req: request::Receipts) -> Vec<Bytes> {
 | 
				
			||||||
		req.block_hashes.into_iter()
 | 
							req.block_hashes.into_iter()
 | 
				
			||||||
			.map(|hash| self.block_receipts(&hash))
 | 
								.map(|hash| self.block_receipts(&hash))
 | 
				
			||||||
@ -144,16 +115,20 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
				
			|||||||
			.collect()
 | 
								.collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Get a block's receipts as an RLP-encoded list by block hash.
 | 
				
			||||||
 | 
						fn block_receipts(&self, hash: &H256) -> Option<Bytes>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Provide a set of merkle proofs, as requested. Each request is a
 | 
				
			||||||
 | 
						/// block hash and request parameters.
 | 
				
			||||||
 | 
						///
 | 
				
			||||||
 | 
						/// Returns a vector of RLP-encoded lists satisfying the requests.
 | 
				
			||||||
	fn proofs(&self, req: request::StateProofs) -> Vec<Bytes> {
 | 
						fn proofs(&self, req: request::StateProofs) -> Vec<Bytes> {
 | 
				
			||||||
		use rlp::{RlpStream, Stream};
 | 
							use rlp::{RlpStream, Stream};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let mut results = Vec::with_capacity(req.requests.len());
 | 
							let mut results = Vec::with_capacity(req.requests.len());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for request in req.requests {
 | 
							for request in req.requests {
 | 
				
			||||||
			let proof = match request.key2 {
 | 
								let proof = self.state_proof(request);
 | 
				
			||||||
				Some(key2) => self.prove_storage(request.key1, key2, request.from_level, BlockId::Hash(request.block)),
 | 
					 | 
				
			||||||
				None => self.prove_account(request.key1, request.from_level, BlockId::Hash(request.block)),
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let mut stream = RlpStream::new_list(proof.len());
 | 
								let mut stream = RlpStream::new_list(proof.len());
 | 
				
			||||||
			for node in proof {
 | 
								for node in proof {
 | 
				
			||||||
@ -166,16 +141,94 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
				
			|||||||
		results
 | 
							results
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> {
 | 
						/// Get a state proof from a request. Each proof should be a vector
 | 
				
			||||||
 | 
						/// of rlp-encoded trie nodes, in ascending order by distance from the root.
 | 
				
			||||||
 | 
						fn state_proof(&self, req: request::StateProof) -> Vec<Bytes>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Provide contract code for the specified (block_hash, account_hash) pairs.
 | 
				
			||||||
 | 
						/// Each item in the resulting vector is either the raw bytecode or empty.
 | 
				
			||||||
 | 
						fn contract_codes(&self, req: request::ContractCodes) -> Vec<Bytes> {
 | 
				
			||||||
		req.code_requests.into_iter()
 | 
							req.code_requests.into_iter()
 | 
				
			||||||
			.map(|req| {
 | 
								.map(|req| self.contract_code(req))
 | 
				
			||||||
				self.code_by_hash(req.account_key, BlockId::Hash(req.block_hash))
 | 
								.collect()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Get contract code by request. Either the raw bytecode or empty.
 | 
				
			||||||
 | 
						fn contract_code(&self, req: request::ContractCode) -> Bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Provide header proofs from the Canonical Hash Tries as well as the headers
 | 
				
			||||||
 | 
						/// they correspond to -- each element in the returned vector is a 2-tuple.
 | 
				
			||||||
 | 
						/// The first element is a block header and the second a merkle proof of
 | 
				
			||||||
 | 
						/// the header in a requested CHT.
 | 
				
			||||||
 | 
						fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes> {
 | 
				
			||||||
 | 
							use rlp::{self, RlpStream, Stream};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							req.requests.into_iter()
 | 
				
			||||||
 | 
								.map(|req| self.header_proof(req))
 | 
				
			||||||
 | 
								.map(|maybe_proof| match maybe_proof {
 | 
				
			||||||
 | 
									None => rlp::EMPTY_LIST_RLP.to_vec(),
 | 
				
			||||||
 | 
									Some((header, proof)) => {
 | 
				
			||||||
 | 
										let mut stream = RlpStream::new_list(2);
 | 
				
			||||||
 | 
										stream.append_raw(&header, 1).begin_list(proof.len());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										for node in proof {
 | 
				
			||||||
 | 
											stream.append_raw(&node, 1);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										stream.out()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
			.collect()
 | 
								.collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes> {
 | 
						/// Provide a header proof from a given Canonical Hash Trie as well as the
 | 
				
			||||||
		req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect()
 | 
						/// corresponding header. The first element is the block header and the
 | 
				
			||||||
 | 
						/// second is a merkle proof of the CHT.
 | 
				
			||||||
 | 
						fn header_proof(&self, req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Provide pending transactions.
 | 
				
			||||||
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Implementation of a light client data provider for a client.
 | 
				
			||||||
 | 
					impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
				
			||||||
 | 
						fn chain_info(&self) -> BlockChainInfo {
 | 
				
			||||||
 | 
							BlockChainClient::chain_info(self)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn reorg_depth(&self, a: &H256, b: &H256) -> Option<u64> {
 | 
				
			||||||
 | 
							self.tree_route(a, b).map(|route| route.index as u64)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn earliest_state(&self) -> Option<u64> {
 | 
				
			||||||
 | 
							Some(self.pruning_info().earliest_state)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn block_header(&self, id: BlockId) -> Option<Bytes> {
 | 
				
			||||||
 | 
							BlockChainClient::block_header(self, id)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn block_body(&self, id: BlockId) -> Option<Bytes> {
 | 
				
			||||||
 | 
							BlockChainClient::block_body(self, id)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn block_receipts(&self, hash: &H256) -> Option<Bytes> {
 | 
				
			||||||
 | 
							BlockChainClient::block_receipts(self, hash)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn state_proof(&self, req: request::StateProof) -> Vec<Bytes> {
 | 
				
			||||||
 | 
							match req.key2 {
 | 
				
			||||||
 | 
								Some(key2) => self.prove_storage(req.key1, key2, req.from_level, BlockId::Hash(req.block)),
 | 
				
			||||||
 | 
								None => self.prove_account(req.key1, req.from_level, BlockId::Hash(req.block)),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn contract_code(&self, req: request::ContractCode) -> Bytes {
 | 
				
			||||||
 | 
							self.code_by_hash(req.account_key, BlockId::Hash(req.block_hash))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn header_proof(&self, _req: request::HeaderProof) -> Option<(Bytes, Vec<Bytes>)> {
 | 
				
			||||||
 | 
							None
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
 | 
				
			|||||||
@ -687,8 +687,12 @@ impl<K: Kind> Drop for VerificationQueue<K> {
 | 
				
			|||||||
		*self.state.0.lock() = State::Exit;
 | 
							*self.state.0.lock() = State::Exit;
 | 
				
			||||||
		self.state.1.notify_all();
 | 
							self.state.1.notify_all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// wake up all threads waiting for more work.
 | 
							// acquire this lock to force threads to reach the waiting point
 | 
				
			||||||
 | 
							// if they're in-between the exit check and the more_to_verify wait.
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								let _more = self.verification.more_to_verify.lock().unwrap();
 | 
				
			||||||
			self.more_to_verify.notify_all();
 | 
								self.more_to_verify.notify_all();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// wait for all verifier threads to join.
 | 
							// wait for all verifier threads to join.
 | 
				
			||||||
		for thread in self.verifier_handles.drain(..) {
 | 
							for thread in self.verifier_handles.drain(..) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "parity.js",
 | 
					  "name": "parity.js",
 | 
				
			||||||
  "version": "0.2.130",
 | 
					  "version": "0.2.131",
 | 
				
			||||||
  "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>",
 | 
				
			||||||
@ -117,6 +117,7 @@
 | 
				
			|||||||
    "react-hot-loader": "3.0.0-beta.6",
 | 
					    "react-hot-loader": "3.0.0-beta.6",
 | 
				
			||||||
    "react-intl-aggregate-webpack-plugin": "0.0.1",
 | 
					    "react-intl-aggregate-webpack-plugin": "0.0.1",
 | 
				
			||||||
    "rucksack-css": "0.9.1",
 | 
					    "rucksack-css": "0.9.1",
 | 
				
			||||||
 | 
					    "serviceworker-webpack-plugin": "0.1.7",
 | 
				
			||||||
    "sinon": "1.17.6",
 | 
					    "sinon": "1.17.6",
 | 
				
			||||||
    "sinon-as-promised": "4.0.2",
 | 
					    "sinon-as-promised": "4.0.2",
 | 
				
			||||||
    "sinon-chai": "2.8.0",
 | 
					    "sinon-chai": "2.8.0",
 | 
				
			||||||
@ -156,6 +157,7 @@
 | 
				
			|||||||
    "mobx-react-devtools": "4.2.10",
 | 
					    "mobx-react-devtools": "4.2.10",
 | 
				
			||||||
    "moment": "2.17.0",
 | 
					    "moment": "2.17.0",
 | 
				
			||||||
    "phoneformat.js": "1.0.3",
 | 
					    "phoneformat.js": "1.0.3",
 | 
				
			||||||
 | 
					    "promise-worker": "1.1.1",
 | 
				
			||||||
    "push.js": "0.0.11",
 | 
					    "push.js": "0.0.11",
 | 
				
			||||||
    "qs": "6.3.0",
 | 
					    "qs": "6.3.0",
 | 
				
			||||||
    "react": "15.4.1",
 | 
					    "react": "15.4.1",
 | 
				
			||||||
@ -182,7 +184,6 @@
 | 
				
			|||||||
    "valid-url": "1.0.9",
 | 
					    "valid-url": "1.0.9",
 | 
				
			||||||
    "validator": "6.2.0",
 | 
					    "validator": "6.2.0",
 | 
				
			||||||
    "web3": "0.17.0-beta",
 | 
					    "web3": "0.17.0-beta",
 | 
				
			||||||
    "whatwg-fetch": "2.0.1",
 | 
					    "whatwg-fetch": "2.0.1"
 | 
				
			||||||
    "worker-loader": "0.7.1"
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,26 @@
 | 
				
			|||||||
// 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 CompilerWorker from 'worker-loader!./compilerWorker.js';
 | 
					import PromiseWorker from 'promise-worker';
 | 
				
			||||||
 | 
					import runtime from 'serviceworker-webpack-plugin/lib/runtime';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let workerRegistration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Setup the Service Worker
 | 
				
			||||||
 | 
					if ('serviceWorker' in navigator) {
 | 
				
			||||||
 | 
					  workerRegistration = runtime
 | 
				
			||||||
 | 
					    .register()
 | 
				
			||||||
 | 
					    .then(() => navigator.serviceWorker.ready)
 | 
				
			||||||
 | 
					    .then((registration) => {
 | 
				
			||||||
 | 
					      const _worker = registration.active;
 | 
				
			||||||
 | 
					      _worker.controller = registration.active;
 | 
				
			||||||
 | 
					      const worker = new PromiseWorker(_worker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return worker;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					} else {
 | 
				
			||||||
 | 
					  workerRegistration = Promise.reject('Service Worker is not available in your browser.');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function setWorker (worker) {
 | 
					export function setWorker (worker) {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
@ -23,6 +42,13 @@ export function setWorker (worker) {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function setError (error) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: 'setError',
 | 
				
			||||||
 | 
					    error
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function setupWorker () {
 | 
					export function setupWorker () {
 | 
				
			||||||
  return (dispatch, getState) => {
 | 
					  return (dispatch, getState) => {
 | 
				
			||||||
    const state = getState();
 | 
					    const state = getState();
 | 
				
			||||||
@ -31,7 +57,13 @@ export function setupWorker () {
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const worker = new CompilerWorker();
 | 
					    workerRegistration
 | 
				
			||||||
 | 
					      .then((worker) => {
 | 
				
			||||||
        dispatch(setWorker(worker));
 | 
					        dispatch(setWorker(worker));
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((error) => {
 | 
				
			||||||
 | 
					        console.error('sw', error);
 | 
				
			||||||
 | 
					        dispatch(setWorker(null));
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -17,13 +17,18 @@
 | 
				
			|||||||
import { handleActions } from 'redux-actions';
 | 
					import { handleActions } from 'redux-actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initialState = {
 | 
					const initialState = {
 | 
				
			||||||
  worker: null
 | 
					  worker: undefined,
 | 
				
			||||||
 | 
					  error: null
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default handleActions({
 | 
					export default handleActions({
 | 
				
			||||||
  setWorker (state, action) {
 | 
					  setWorker (state, action) {
 | 
				
			||||||
    const { worker } = action;
 | 
					    const { worker } = action;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return Object.assign({}, state, { worker });
 | 
					    return Object.assign({}, state, { worker });
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setError (state, action) {
 | 
				
			||||||
 | 
					    const { error } = action;
 | 
				
			||||||
 | 
					    return Object.assign({}, state, { error });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}, initialState);
 | 
					}, initialState);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,177 +0,0 @@
 | 
				
			|||||||
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
 | 
					 | 
				
			||||||
// This file is part of Parity.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Parity is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
// it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
// the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
// (at your option) any later version.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Parity is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
// GNU General Public License for more details.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import solc from 'solc/browser-wrapper';
 | 
					 | 
				
			||||||
import { isWebUri } from 'valid-url';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
self.solcVersions = {};
 | 
					 | 
				
			||||||
self.files = {};
 | 
					 | 
				
			||||||
self.lastCompile = {
 | 
					 | 
				
			||||||
  sourcecode: '',
 | 
					 | 
				
			||||||
  result: '',
 | 
					 | 
				
			||||||
  version: ''
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// eslint-disable-next-line no-undef
 | 
					 | 
				
			||||||
onmessage = (event) => {
 | 
					 | 
				
			||||||
  const message = JSON.parse(event.data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (message.action) {
 | 
					 | 
				
			||||||
    case 'compile':
 | 
					 | 
				
			||||||
      compile(message.data);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case 'load':
 | 
					 | 
				
			||||||
      load(message.data);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case 'setFiles':
 | 
					 | 
				
			||||||
      setFiles(message.data);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case 'close':
 | 
					 | 
				
			||||||
      close();
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function setFiles (files) {
 | 
					 | 
				
			||||||
  const prevFiles = self.files;
 | 
					 | 
				
			||||||
  const nextFiles = files.reduce((obj, file) => {
 | 
					 | 
				
			||||||
    obj[file.name] = file.sourcecode;
 | 
					 | 
				
			||||||
    return obj;
 | 
					 | 
				
			||||||
  }, {});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  self.files = {
 | 
					 | 
				
			||||||
    ...prevFiles,
 | 
					 | 
				
			||||||
    ...nextFiles
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function findImports (path) {
 | 
					 | 
				
			||||||
  if (self.files[path]) {
 | 
					 | 
				
			||||||
    if (self.files[path].error) {
 | 
					 | 
				
			||||||
      return { error: self.files[path].error };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return { contents: self.files[path] };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (isWebUri(path)) {
 | 
					 | 
				
			||||||
    console.log('[worker] fetching', path);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fetch(path)
 | 
					 | 
				
			||||||
      .then((r) => r.text())
 | 
					 | 
				
			||||||
      .then((c) => {
 | 
					 | 
				
			||||||
        console.log('[worker]', 'got content at ' + path);
 | 
					 | 
				
			||||||
        self.files[path] = c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        postMessage(JSON.stringify({
 | 
					 | 
				
			||||||
          event: 'try-again'
 | 
					 | 
				
			||||||
        }));
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
      .catch((e) => {
 | 
					 | 
				
			||||||
        console.error('[worker]', 'fetching', path, e);
 | 
					 | 
				
			||||||
        self.files[path] = { error: e };
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return { error: '__parity_tryAgain' };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  console.log(`[worker] path ${path} not found...`);
 | 
					 | 
				
			||||||
  return { error: 'File not found' };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function compile (data, optimized = 1) {
 | 
					 | 
				
			||||||
  const { sourcecode, build } = data;
 | 
					 | 
				
			||||||
  const { longVersion } = build;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (self.lastCompile.sourcecode === sourcecode && self.lastCompile.longVersion === longVersion) {
 | 
					 | 
				
			||||||
    return postMessage(JSON.stringify({
 | 
					 | 
				
			||||||
      event: 'compiled',
 | 
					 | 
				
			||||||
      data: self.lastCompile.result
 | 
					 | 
				
			||||||
    }));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fetchSolc(build)
 | 
					 | 
				
			||||||
    .then((compiler) => {
 | 
					 | 
				
			||||||
      const input = {
 | 
					 | 
				
			||||||
        '': sourcecode
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const compiled = compiler.compile({ sources: input }, optimized, findImports);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      self.lastCompile = {
 | 
					 | 
				
			||||||
        version: longVersion, result: compiled,
 | 
					 | 
				
			||||||
        sourcecode
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      postMessage(JSON.stringify({
 | 
					 | 
				
			||||||
        event: 'compiled',
 | 
					 | 
				
			||||||
        data: compiled
 | 
					 | 
				
			||||||
      }));
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function load (build) {
 | 
					 | 
				
			||||||
  postMessage(JSON.stringify({
 | 
					 | 
				
			||||||
    event: 'loading',
 | 
					 | 
				
			||||||
    data: true
 | 
					 | 
				
			||||||
  }));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fetchSolc(build)
 | 
					 | 
				
			||||||
    .then(() => {
 | 
					 | 
				
			||||||
      postMessage(JSON.stringify({
 | 
					 | 
				
			||||||
        event: 'loading',
 | 
					 | 
				
			||||||
        data: false
 | 
					 | 
				
			||||||
      }));
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .catch(() => {
 | 
					 | 
				
			||||||
      postMessage(JSON.stringify({
 | 
					 | 
				
			||||||
        event: 'loading',
 | 
					 | 
				
			||||||
        data: false
 | 
					 | 
				
			||||||
      }));
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function fetchSolc (build) {
 | 
					 | 
				
			||||||
  const { path, longVersion } = build;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (self.solcVersions[path]) {
 | 
					 | 
				
			||||||
    return Promise.resolve(self.solcVersions[path]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const URL = `https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/${path}`;
 | 
					 | 
				
			||||||
  console.log(`[worker] fetching solc-bin ${longVersion} at ${URL}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return fetch(URL)
 | 
					 | 
				
			||||||
    .then((r) => r.text())
 | 
					 | 
				
			||||||
    .then((code) => {
 | 
					 | 
				
			||||||
      const solcCode = code.replace(/^var Module;/, 'var Module=self.__solcModule;');
 | 
					 | 
				
			||||||
      self.__solcModule = {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      console.log(`[worker] evaluating ${longVersion}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // eslint-disable-next-line no-eval
 | 
					 | 
				
			||||||
      eval(solcCode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      console.log(`[worker] done evaluating ${longVersion}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const compiler = solc(self.__solcModule);
 | 
					 | 
				
			||||||
      self.solcVersions[path] = compiler;
 | 
					 | 
				
			||||||
      return compiler;
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .catch((e) => {
 | 
					 | 
				
			||||||
      console.error('fetching solc', e);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										144
									
								
								js/src/serviceWorker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								js/src/serviceWorker.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,144 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
 | 
				
			||||||
 | 
					// This file is part of Parity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import registerPromiseWorker from 'promise-worker/register';
 | 
				
			||||||
 | 
					import SolidityUtils from '~/util/solidity';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CACHE_NAME = 'parity-cache-v1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					registerPromiseWorker((msg) => {
 | 
				
			||||||
 | 
					  return handleMessage(msg);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					self.addEventListener('install', (event) => {
 | 
				
			||||||
 | 
					  event.waitUntil(self.skipWaiting());
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					self.addEventListener('activate', (event) => {
 | 
				
			||||||
 | 
					  event.waitUntil(self.clients.claim());
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					self.addEventListener('fetch', (event) => {
 | 
				
			||||||
 | 
					  const { url } = event.request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (/raw.githubusercontent.com\/ethereum\/solc-bin(.+)list\.json$/.test(url)) {
 | 
				
			||||||
 | 
					    // Return the cached version, but still update it in background
 | 
				
			||||||
 | 
					    return event.respondWith(cachedFetcher(event.request, true));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (/raw.githubusercontent.com\/ethereum\/solc-bin(.+)soljson(.+)\.js$/.test(url)) {
 | 
				
			||||||
 | 
					    return event.respondWith(cachedFetcher(event.request));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					self.solc = {};
 | 
				
			||||||
 | 
					self.files = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function cachedFetcher (request, update = false) {
 | 
				
			||||||
 | 
					  return caches
 | 
				
			||||||
 | 
					    .match(request)
 | 
				
			||||||
 | 
					    .then((response) => {
 | 
				
			||||||
 | 
					      // Return cached response if exists and no
 | 
				
			||||||
 | 
					      // updates needed
 | 
				
			||||||
 | 
					      if (response && !update) {
 | 
				
			||||||
 | 
					        return response;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const fetcher = fetch(request.clone())
 | 
				
			||||||
 | 
					        .then((response) => {
 | 
				
			||||||
 | 
					          // Check if we received a valid response
 | 
				
			||||||
 | 
					          if (!response || response.status !== 200) {
 | 
				
			||||||
 | 
					            return response;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return caches
 | 
				
			||||||
 | 
					            .open(CACHE_NAME)
 | 
				
			||||||
 | 
					            .then((cache) => {
 | 
				
			||||||
 | 
					              cache.put(request, response.clone());
 | 
				
			||||||
 | 
					              return response;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Cache hit - return response
 | 
				
			||||||
 | 
					      // Still want to perform the fetch (update)
 | 
				
			||||||
 | 
					      if (response) {
 | 
				
			||||||
 | 
					        return response;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return fetcher;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function handleMessage (message) {
 | 
				
			||||||
 | 
					  switch (message.action) {
 | 
				
			||||||
 | 
					    case 'compile':
 | 
				
			||||||
 | 
					      return compile(message.data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case 'load':
 | 
				
			||||||
 | 
					      return getCompiler(message.data).then(() => 'ok');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case 'setFiles':
 | 
				
			||||||
 | 
					      return setFiles(message.data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      console.warn(`unknown action "${message.action}"`);
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function compile (data) {
 | 
				
			||||||
 | 
					  const { build } = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return getCompiler(build)
 | 
				
			||||||
 | 
					    .then((compiler) => {
 | 
				
			||||||
 | 
					      return SolidityUtils.compile(data, compiler);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function setFiles (files) {
 | 
				
			||||||
 | 
					  const prevFiles = self.files;
 | 
				
			||||||
 | 
					  const nextFiles = files.reduce((obj, file) => {
 | 
				
			||||||
 | 
					    obj[file.name] = file.sourcecode;
 | 
				
			||||||
 | 
					    return obj;
 | 
				
			||||||
 | 
					  }, {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  self.files = {
 | 
				
			||||||
 | 
					    ...prevFiles,
 | 
				
			||||||
 | 
					    ...nextFiles
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 'ok';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getCompiler (build) {
 | 
				
			||||||
 | 
					  const { longVersion } = build;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const fetcher = (url) => {
 | 
				
			||||||
 | 
					    const request = new Request(url);
 | 
				
			||||||
 | 
					    return cachedFetcher(request);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!self.solc[longVersion]) {
 | 
				
			||||||
 | 
					    self.solc[longVersion] = SolidityUtils
 | 
				
			||||||
 | 
					      .getCompiler(build, fetcher)
 | 
				
			||||||
 | 
					      .then((compiler) => {
 | 
				
			||||||
 | 
					        self.solc[longVersion] = compiler;
 | 
				
			||||||
 | 
					        return compiler;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return self.solc[longVersion];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										89
									
								
								js/src/util/solidity.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								js/src/util/solidity.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
 | 
				
			||||||
 | 
					// This file is part of Parity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import solc from 'solc/browser-wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class SolidityUtils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static compile (data, compiler) {
 | 
				
			||||||
 | 
					    const { sourcecode, build, optimize, files } = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const start = Date.now();
 | 
				
			||||||
 | 
					    console.log('[solidity] compiling...');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const input = {
 | 
				
			||||||
 | 
					      '': sourcecode
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const findFiles = (path) => {
 | 
				
			||||||
 | 
					      const file = files.find((f) => f.name === path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (file) {
 | 
				
			||||||
 | 
					        return { contents: file.sourcecode };
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return { error: 'File not found' };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const compiled = compiler.compile({ sources: input }, optimize ? 1 : 0, findFiles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const time = Math.round((Date.now() - start) / 100) / 10;
 | 
				
			||||||
 | 
					    console.log(`[solidity] done compiling in ${time}s`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    compiled.version = build.longVersion;
 | 
				
			||||||
 | 
					    compiled.sourcecode = sourcecode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return compiled;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static getCompiler (build, _fetcher) {
 | 
				
			||||||
 | 
					    const { longVersion, path } = build;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const URL = `https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/${path}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const fetcher = typeof _fetcher === 'function'
 | 
				
			||||||
 | 
					      ? _fetcher
 | 
				
			||||||
 | 
					      : (url) => fetch(url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const isWorker = typeof window !== 'object';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return fetcher(URL)
 | 
				
			||||||
 | 
					      .then((r) => r.text())
 | 
				
			||||||
 | 
					      .then((code) => {
 | 
				
			||||||
 | 
					        // `window` for main thread, `self` for workers
 | 
				
			||||||
 | 
					        const _self = isWorker ? self : window;
 | 
				
			||||||
 | 
					        _self.Module = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const solcCode = code.replace('var Module;', `var Module=${isWorker ? 'self' : 'window'}.Module;`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log(`[solidity] evaluating ${longVersion}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					          // eslint-disable-next-line no-eval
 | 
				
			||||||
 | 
					          eval(solcCode);
 | 
				
			||||||
 | 
					        } catch (e) {
 | 
				
			||||||
 | 
					          return Promise.reject(e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console.log(`[solidity] done evaluating ${longVersion}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const compiler = solc(_self.Module);
 | 
				
			||||||
 | 
					        delete _self.Module;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return compiler;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -26,6 +26,16 @@
 | 
				
			|||||||
  color: #ccc;
 | 
					  color: #ccc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.toggles {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-direction: row;
 | 
				
			||||||
 | 
					  margin: 1em 0 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  > * {
 | 
				
			||||||
 | 
					    flex: 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.container {
 | 
					.container {
 | 
				
			||||||
  padding: 1em 0;
 | 
					  padding: 1em 0;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
@ -45,6 +55,14 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.error {
 | 
				
			||||||
 | 
					  background-color: rgba(200, 0, 0, 0.25);
 | 
				
			||||||
 | 
					  padding: 1em 0.5em;
 | 
				
			||||||
 | 
					  margin-top: -0.5em;
 | 
				
			||||||
 | 
					  font-family: monospace;
 | 
				
			||||||
 | 
					  font-size: 0.9em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mainEditor {
 | 
					.mainEditor {
 | 
				
			||||||
  &:global(.ace-solarized-dark) {
 | 
					  &:global(.ace-solarized-dark) {
 | 
				
			||||||
    background-color: rgba(0, 0, 0, 0.5);
 | 
					    background-color: rgba(0, 0, 0, 0.5);
 | 
				
			||||||
@ -87,13 +105,13 @@
 | 
				
			|||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  margin-right: 0.5em;
 | 
					  margin-right: 0.5em;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  .panel {
 | 
					  .panel {
 | 
				
			||||||
    background-color: rgba(0, 0, 0, 0.5);
 | 
					    background-color: rgba(0, 0, 0, 0.5);
 | 
				
			||||||
    padding: 1em;
 | 
					    padding: 1em;
 | 
				
			||||||
    flex: 1;
 | 
					    flex: 1;
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    flex-direction: column;
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    box-sizing: border-box;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .compilation {
 | 
					  .compilation {
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import React, { PropTypes, Component } from 'react';
 | 
					import React, { PropTypes, Component } from 'react';
 | 
				
			||||||
import { observer } from 'mobx-react';
 | 
					import { observer } from 'mobx-react';
 | 
				
			||||||
import { MenuItem } from 'material-ui';
 | 
					import { MenuItem, Toggle } from 'material-ui';
 | 
				
			||||||
import { connect } from 'react-redux';
 | 
					import { connect } from 'react-redux';
 | 
				
			||||||
import { bindActionCreators } from 'redux';
 | 
					import { bindActionCreators } from 'redux';
 | 
				
			||||||
import CircularProgress from 'material-ui/CircularProgress';
 | 
					import CircularProgress from 'material-ui/CircularProgress';
 | 
				
			||||||
@ -42,10 +42,11 @@ class WriteContract extends Component {
 | 
				
			|||||||
  static propTypes = {
 | 
					  static propTypes = {
 | 
				
			||||||
    accounts: PropTypes.object.isRequired,
 | 
					    accounts: PropTypes.object.isRequired,
 | 
				
			||||||
    setupWorker: PropTypes.func.isRequired,
 | 
					    setupWorker: PropTypes.func.isRequired,
 | 
				
			||||||
    worker: PropTypes.object
 | 
					    worker: PropTypes.object,
 | 
				
			||||||
 | 
					    workerError: PropTypes.any
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  store = new WriteContractStore();
 | 
					  store = WriteContractStore.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  state = {
 | 
					  state = {
 | 
				
			||||||
    resizing: false,
 | 
					    resizing: false,
 | 
				
			||||||
@ -56,23 +57,32 @@ class WriteContract extends Component {
 | 
				
			|||||||
    const { setupWorker, worker } = this.props;
 | 
					    const { setupWorker, worker } = this.props;
 | 
				
			||||||
    setupWorker();
 | 
					    setupWorker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (worker) {
 | 
					    if (worker !== undefined) {
 | 
				
			||||||
      this.store.setCompiler(worker);
 | 
					      this.store.setWorker(worker);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidMount () {
 | 
					  componentDidMount () {
 | 
				
			||||||
    this.store.setEditor(this.refs.editor);
 | 
					    this.store.setEditor(this.refs.editor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.props.workerError) {
 | 
				
			||||||
 | 
					      this.store.setWorkerError(this.props.workerError);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Wait for editor to be loaded
 | 
					    // Wait for editor to be loaded
 | 
				
			||||||
    window.setTimeout(() => {
 | 
					    window.setTimeout(() => {
 | 
				
			||||||
      this.store.resizeEditor();
 | 
					      this.store.resizeEditor();
 | 
				
			||||||
    }, 2000);
 | 
					    }, 2000);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set the worker if not set before (eg. first page loading)
 | 
				
			||||||
  componentWillReceiveProps (nextProps) {
 | 
					  componentWillReceiveProps (nextProps) {
 | 
				
			||||||
    if (!this.props.worker && nextProps.worker) {
 | 
					    if (this.props.worker === undefined && nextProps.worker !== undefined) {
 | 
				
			||||||
      this.store.setCompiler(nextProps.worker);
 | 
					      this.store.setWorker(nextProps.worker);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.props.workerError !== nextProps.workerError) {
 | 
				
			||||||
 | 
					      this.store.setWorkerError(nextProps.workerError);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -217,7 +227,18 @@ class WriteContract extends Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  renderParameters () {
 | 
					  renderParameters () {
 | 
				
			||||||
    const { compiling, contract, selectedBuild, loading } = this.store;
 | 
					    const { compiling, contract, selectedBuild, loading, workerError } = this.store;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (workerError) {
 | 
				
			||||||
 | 
					      return (
 | 
				
			||||||
 | 
					        <div className={ styles.panel }>
 | 
				
			||||||
 | 
					          <div className={ styles.centeredMessage }>
 | 
				
			||||||
 | 
					            <p>Unfortuantely, an error occurred...</p>
 | 
				
			||||||
 | 
					            <div className={ styles.error }>{ workerError.toString() }</div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (selectedBuild < 0) {
 | 
					    if (selectedBuild < 0) {
 | 
				
			||||||
      return (
 | 
					      return (
 | 
				
			||||||
@ -262,6 +283,24 @@ class WriteContract extends Component {
 | 
				
			|||||||
            : null
 | 
					            : null
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div className={ styles.toggles }>
 | 
				
			||||||
 | 
					          <div>
 | 
				
			||||||
 | 
					            <Toggle
 | 
				
			||||||
 | 
					              label='Optimize'
 | 
				
			||||||
 | 
					              labelPosition='right'
 | 
				
			||||||
 | 
					              onToggle={ this.store.handleOptimizeToggle }
 | 
				
			||||||
 | 
					              toggled={ this.store.optimize }
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div>
 | 
				
			||||||
 | 
					            <Toggle
 | 
				
			||||||
 | 
					              label='Auto-Compile'
 | 
				
			||||||
 | 
					              labelPosition='right'
 | 
				
			||||||
 | 
					              onToggle={ this.store.handleAutocompileToggle }
 | 
				
			||||||
 | 
					              toggled={ this.store.autocompile }
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
        { this.renderSolidityVersions() }
 | 
					        { this.renderSolidityVersions() }
 | 
				
			||||||
        { this.renderCompilation() }
 | 
					        { this.renderCompilation() }
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@ -485,8 +524,8 @@ class WriteContract extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function mapStateToProps (state) {
 | 
					function mapStateToProps (state) {
 | 
				
			||||||
  const { accounts } = state.personal;
 | 
					  const { accounts } = state.personal;
 | 
				
			||||||
  const { worker } = state.compiler;
 | 
					  const { worker, error } = state.compiler;
 | 
				
			||||||
  return { accounts, worker };
 | 
					  return { accounts, worker, workerError: error };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mapDispatchToProps (dispatch) {
 | 
					function mapDispatchToProps (dispatch) {
 | 
				
			||||||
 | 
				
			|||||||
@ -14,10 +14,13 @@
 | 
				
			|||||||
// 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 { action, observable } from 'mobx';
 | 
					import { action, observable, transaction } from 'mobx';
 | 
				
			||||||
import store from 'store';
 | 
					import store from 'store';
 | 
				
			||||||
import { debounce } from 'lodash';
 | 
					import { debounce } from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { sha3 } from '~/api/util/sha3';
 | 
				
			||||||
 | 
					import SolidityUtils from '~/util/solidity';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const WRITE_CONTRACT_STORE_KEY = '_parity::writeContractStore';
 | 
					const WRITE_CONTRACT_STORE_KEY = '_parity::writeContractStore';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SNIPPETS = {
 | 
					const SNIPPETS = {
 | 
				
			||||||
@ -43,6 +46,8 @@ const SNIPPETS = {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let instance = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class WriteContractStore {
 | 
					export default class WriteContractStore {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @observable sourcecode = '';
 | 
					  @observable sourcecode = '';
 | 
				
			||||||
@ -61,6 +66,9 @@ export default class WriteContractStore {
 | 
				
			|||||||
  @observable builds = [];
 | 
					  @observable builds = [];
 | 
				
			||||||
  @observable selectedBuild = -1;
 | 
					  @observable selectedBuild = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @observable autocompile = false;
 | 
				
			||||||
 | 
					  @observable optimize = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @observable showDeployModal = false;
 | 
					  @observable showDeployModal = false;
 | 
				
			||||||
  @observable showSaveModal = false;
 | 
					  @observable showSaveModal = false;
 | 
				
			||||||
  @observable showLoadModal = false;
 | 
					  @observable showLoadModal = false;
 | 
				
			||||||
@ -68,45 +76,55 @@ export default class WriteContractStore {
 | 
				
			|||||||
  @observable savedContracts = {};
 | 
					  @observable savedContracts = {};
 | 
				
			||||||
  @observable selectedContract = {};
 | 
					  @observable selectedContract = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @observable workerError = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  loadingSolidity = false;
 | 
				
			||||||
 | 
					  lastCompilation = {};
 | 
				
			||||||
  snippets = SNIPPETS;
 | 
					  snippets = SNIPPETS;
 | 
				
			||||||
 | 
					  worker = undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useWorker = true;
 | 
				
			||||||
 | 
					  solc = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
    this.reloadContracts();
 | 
					 | 
				
			||||||
    this.fetchSolidityVersions();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.debouncedCompile = debounce(this.handleCompile, 1000);
 | 
					    this.debouncedCompile = debounce(this.handleCompile, 1000);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static get () {
 | 
				
			||||||
 | 
					    if (!instance) {
 | 
				
			||||||
 | 
					      instance = new WriteContractStore();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return instance;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @action setWorkerError (error) {
 | 
				
			||||||
 | 
					    this.workerError = error;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action setEditor (editor) {
 | 
					  @action setEditor (editor) {
 | 
				
			||||||
    this.editor = editor;
 | 
					    this.editor = editor;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action setCompiler (compiler) {
 | 
					  @action setWorker (worker) {
 | 
				
			||||||
    this.compiler = compiler;
 | 
					    if (this.worker !== undefined) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
    this.compiler.onmessage = (event) => {
 | 
					 | 
				
			||||||
      const message = JSON.parse(event.data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      switch (message.event) {
 | 
					 | 
				
			||||||
        case 'compiled':
 | 
					 | 
				
			||||||
          this.parseCompiled(message.data);
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 'loading':
 | 
					 | 
				
			||||||
          this.parseLoading(message.data);
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 'try-again':
 | 
					 | 
				
			||||||
          this.handleCompile();
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    };
 | 
					
 | 
				
			||||||
 | 
					    this.worker = worker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this
 | 
				
			||||||
 | 
					      .fetchSolidityVersions()
 | 
				
			||||||
 | 
					      .then(() => this.reloadContracts());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fetchSolidityVersions () {
 | 
					  fetchSolidityVersions () {
 | 
				
			||||||
    fetch('https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/list.json')
 | 
					    return fetch('https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/list.json')
 | 
				
			||||||
      .then((r) => r.json())
 | 
					      .then((r) => r.json())
 | 
				
			||||||
      .then((data) => {
 | 
					      .then((data) => {
 | 
				
			||||||
        const { builds, releases, latestRelease } = data;
 | 
					        const { builds, releases, latestRelease } = data;
 | 
				
			||||||
        let latestIndex = -1;
 | 
					        let latestIndex = -1;
 | 
				
			||||||
 | 
					        let promise = Promise.resolve();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.builds = builds.reverse().map((build, index) => {
 | 
					        this.builds = builds.reverse().map((build, index) => {
 | 
				
			||||||
          if (releases[build.version] === build.path) {
 | 
					          if (releases[build.version] === build.path) {
 | 
				
			||||||
@ -114,7 +132,7 @@ export default class WriteContractStore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (build.version === latestRelease) {
 | 
					            if (build.version === latestRelease) {
 | 
				
			||||||
              build.latest = true;
 | 
					              build.latest = true;
 | 
				
			||||||
              this.loadSolidityVersion(build);
 | 
					              promise = promise.then(() => this.loadSolidityVersion(build));
 | 
				
			||||||
              latestIndex = index;
 | 
					              latestIndex = index;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@ -123,29 +141,93 @@ export default class WriteContractStore {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.selectedBuild = latestIndex;
 | 
					        this.selectedBuild = latestIndex;
 | 
				
			||||||
 | 
					        return promise;
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((error) => {
 | 
				
			||||||
 | 
					        this.setWorkerError(error);
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action closeWorker = () => {
 | 
					 | 
				
			||||||
    this.compiler.postMessage(JSON.stringify({
 | 
					 | 
				
			||||||
      action: 'close'
 | 
					 | 
				
			||||||
    }));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @action handleImport = (sourcecode) => {
 | 
					  @action handleImport = (sourcecode) => {
 | 
				
			||||||
    this.reloadContracts(-1, sourcecode);
 | 
					    this.reloadContracts(-1, sourcecode);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action handleSelectBuild = (_, index, value) => {
 | 
					  @action handleSelectBuild = (_, index, value) => {
 | 
				
			||||||
    this.selectedBuild = value;
 | 
					    this.selectedBuild = value;
 | 
				
			||||||
    this.loadSolidityVersion(this.builds[value]);
 | 
					    return this
 | 
				
			||||||
 | 
					      .loadSolidityVersion(this.builds[value])
 | 
				
			||||||
 | 
					      .then(() => this.handleCompile());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getCompiler (build) {
 | 
				
			||||||
 | 
					    const { longVersion } = build;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!this.solc[longVersion]) {
 | 
				
			||||||
 | 
					      this.solc[longVersion] = SolidityUtils
 | 
				
			||||||
 | 
					        .getCompiler(build)
 | 
				
			||||||
 | 
					        .then((compiler) => {
 | 
				
			||||||
 | 
					          this.solc[longVersion] = compiler;
 | 
				
			||||||
 | 
					          return compiler;
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          this.setWorkerError(error);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Promise.resolve(this.solc[longVersion]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action loadSolidityVersion = (build) => {
 | 
					  @action loadSolidityVersion = (build) => {
 | 
				
			||||||
    this.compiler.postMessage(JSON.stringify({
 | 
					    if (this.worker === undefined) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    } else if (this.worker === null) {
 | 
				
			||||||
 | 
					      this.useWorker = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.loadingSolidity) {
 | 
				
			||||||
 | 
					      return this.loadingSolidity;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.loading = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.useWorker) {
 | 
				
			||||||
 | 
					      this.loadingSolidity = this.worker
 | 
				
			||||||
 | 
					        .postMessage({
 | 
				
			||||||
          action: 'load',
 | 
					          action: 'load',
 | 
				
			||||||
          data: build
 | 
					          data: build
 | 
				
			||||||
    }));
 | 
					        })
 | 
				
			||||||
 | 
					        .then((result) => {
 | 
				
			||||||
 | 
					          if (result !== 'ok') {
 | 
				
			||||||
 | 
					            throw new Error('error while loading solidity: ' + result);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          this.loadingSolidity = false;
 | 
				
			||||||
 | 
					          this.loading = false;
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          console.warn('error while loading solidity', error);
 | 
				
			||||||
 | 
					          this.useWorker = false;
 | 
				
			||||||
 | 
					          this.loadingSolidity = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return this.loadSolidityVersion(build);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.loadingSolidity = this
 | 
				
			||||||
 | 
					        .getCompiler(build)
 | 
				
			||||||
 | 
					        .then(() => {
 | 
				
			||||||
 | 
					          this.loadingSolidity = false;
 | 
				
			||||||
 | 
					          this.loading = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return 'ok';
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          this.setWorkerError(error);
 | 
				
			||||||
 | 
					          this.loadingSolidity = false;
 | 
				
			||||||
 | 
					          this.loading = false;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.loadingSolidity;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action handleOpenDeployModal = () => {
 | 
					  @action handleOpenDeployModal = () => {
 | 
				
			||||||
@ -177,23 +259,120 @@ export default class WriteContractStore {
 | 
				
			|||||||
    this.contract = this.contracts[Object.keys(this.contracts)[value]];
 | 
					    this.contract = this.contracts[Object.keys(this.contracts)[value]];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  compile = (data) => {
 | 
				
			||||||
 | 
					    if (this.useWorker) {
 | 
				
			||||||
 | 
					      return this.worker.postMessage({
 | 
				
			||||||
 | 
					        action: 'compile',
 | 
				
			||||||
 | 
					        data
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					      window.setTimeout(() => {
 | 
				
			||||||
 | 
					        this
 | 
				
			||||||
 | 
					          .getCompiler(data.build)
 | 
				
			||||||
 | 
					          .then((compiler) => {
 | 
				
			||||||
 | 
					            return SolidityUtils.compile(data, compiler);
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					          .then(resolve)
 | 
				
			||||||
 | 
					          .catch(reject);
 | 
				
			||||||
 | 
					      }, 0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action handleCompile = () => {
 | 
					  @action handleCompile = () => {
 | 
				
			||||||
 | 
					    transaction(() => {
 | 
				
			||||||
      this.compiled = false;
 | 
					      this.compiled = false;
 | 
				
			||||||
      this.compiling = true;
 | 
					      this.compiling = true;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const build = this.builds[this.selectedBuild];
 | 
					    const build = this.builds[this.selectedBuild];
 | 
				
			||||||
 | 
					    const version = build.longVersion;
 | 
				
			||||||
 | 
					    const sourcecode = this.sourcecode.replace(/\n+/g, '\n').replace(/\s(\s+)/g, ' ');
 | 
				
			||||||
 | 
					    const hash = sha3(JSON.stringify({ version, sourcecode, optimize: this.optimize }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.compiler && typeof this.compiler.postMessage === 'function') {
 | 
					    let promise = Promise.resolve(null);
 | 
				
			||||||
      this.sendFilesToWorker();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.compiler.postMessage(JSON.stringify({
 | 
					    if (hash === this.lastCompilation.hash) {
 | 
				
			||||||
        action: 'compile',
 | 
					      promise = new Promise((resolve) => {
 | 
				
			||||||
        data: {
 | 
					        window.setTimeout(() => {
 | 
				
			||||||
          sourcecode: this.sourcecode,
 | 
					          resolve(this.lastCompilation);
 | 
				
			||||||
          build: build
 | 
					        }, 500);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      promise = this
 | 
				
			||||||
 | 
					        .compile({
 | 
				
			||||||
 | 
					          sourcecode: sourcecode,
 | 
				
			||||||
 | 
					          build: build,
 | 
				
			||||||
 | 
					          optimize: this.optimize,
 | 
				
			||||||
 | 
					          files: this.files
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .then((data) => {
 | 
				
			||||||
 | 
					          const result = this.parseCompiled(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          this.lastCompilation = {
 | 
				
			||||||
 | 
					            result: result,
 | 
				
			||||||
 | 
					            date: new Date(),
 | 
				
			||||||
 | 
					            version: data.version,
 | 
				
			||||||
 | 
					            hash
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return this.lastCompilation;
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          this.setWorkerError(error);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
      }));
 | 
					
 | 
				
			||||||
 | 
					    return promise.then((data = null) => {
 | 
				
			||||||
 | 
					      if (data) {
 | 
				
			||||||
 | 
					        const {
 | 
				
			||||||
 | 
					          contract, contractIndex,
 | 
				
			||||||
 | 
					          annotations, contracts, errors
 | 
				
			||||||
 | 
					        } = data.result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.contract = contract;
 | 
				
			||||||
 | 
					        this.contractIndex = contractIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.annotations = annotations;
 | 
				
			||||||
 | 
					        this.contracts = contracts;
 | 
				
			||||||
 | 
					        this.errors = errors;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this.compiled = true;
 | 
				
			||||||
 | 
					      this.compiling = false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @action handleAutocompileToggle = () => {
 | 
				
			||||||
 | 
					    this.autocompile = !this.autocompile;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @action handleOptimizeToggle = () => {
 | 
				
			||||||
 | 
					    this.optimize = !this.optimize;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @action parseCompiled = (data) => {
 | 
				
			||||||
 | 
					    const { contracts } = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const { errors = [] } = data;
 | 
				
			||||||
 | 
					    const errorAnnotations = this.parseErrors(errors);
 | 
				
			||||||
 | 
					    const formalAnnotations = this.parseErrors(data.formal && data.formal.errors, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const annotations = [].concat(
 | 
				
			||||||
 | 
					      errorAnnotations,
 | 
				
			||||||
 | 
					      formalAnnotations
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const contractKeys = Object.keys(contracts || {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const contract = contractKeys.length ? contracts[contractKeys[0]] : null;
 | 
				
			||||||
 | 
					    const contractIndex = contractKeys.length ? 0 : -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      contract, contractIndex,
 | 
				
			||||||
 | 
					      contracts, errors, annotations
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  parseErrors = (data, formal = false) => {
 | 
					  parseErrors = (data, formal = false) => {
 | 
				
			||||||
@ -220,43 +399,6 @@ export default class WriteContractStore {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action parseCompiled = (data) => {
 | 
					 | 
				
			||||||
    const { contracts } = data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { errors = [] } = data;
 | 
					 | 
				
			||||||
    const errorAnnotations = this.parseErrors(errors);
 | 
					 | 
				
			||||||
    const formalAnnotations = this.parseErrors(data.formal && data.formal.errors, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const annotations = [].concat(
 | 
					 | 
				
			||||||
      errorAnnotations,
 | 
					 | 
				
			||||||
      formalAnnotations
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (annotations.findIndex((a) => /__parity_tryAgain/.test(a.text)) > -1) {
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const contractKeys = Object.keys(contracts || {});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.contract = contractKeys.length ? contracts[contractKeys[0]] : null;
 | 
					 | 
				
			||||||
    this.contractIndex = contractKeys.length ? 0 : -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.contracts = contracts;
 | 
					 | 
				
			||||||
    this.errors = errors;
 | 
					 | 
				
			||||||
    this.annotations = annotations;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.compiled = true;
 | 
					 | 
				
			||||||
    this.compiling = false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @action parseLoading = (isLoading) => {
 | 
					 | 
				
			||||||
    this.loading = isLoading;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!isLoading) {
 | 
					 | 
				
			||||||
      this.handleCompile();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @action handleEditSourcecode = (value, compile = false) => {
 | 
					  @action handleEditSourcecode = (value, compile = false) => {
 | 
				
			||||||
    this.sourcecode = value;
 | 
					    this.sourcecode = value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -268,7 +410,7 @@ export default class WriteContractStore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (compile) {
 | 
					    if (compile) {
 | 
				
			||||||
      this.handleCompile();
 | 
					      this.handleCompile();
 | 
				
			||||||
    } else {
 | 
					    } else if (this.autocompile) {
 | 
				
			||||||
      this.debouncedCompile();
 | 
					      this.debouncedCompile();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -327,8 +469,9 @@ export default class WriteContractStore {
 | 
				
			|||||||
      current: this.sourcecode
 | 
					      current: this.sourcecode
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.handleCompile();
 | 
					 | 
				
			||||||
    this.resizeEditor();
 | 
					    this.resizeEditor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.handleCompile();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @action handleLoadContract = (contract) => {
 | 
					  @action handleLoadContract = (contract) => {
 | 
				
			||||||
@ -363,16 +506,13 @@ export default class WriteContractStore {
 | 
				
			|||||||
    } catch (e) {}
 | 
					    } catch (e) {}
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sendFilesToWorker = () => {
 | 
					  get files () {
 | 
				
			||||||
    const files = [].concat(
 | 
					    const files = [].concat(
 | 
				
			||||||
      Object.values(this.snippets),
 | 
					      Object.values(this.snippets),
 | 
				
			||||||
      Object.values(this.savedContracts)
 | 
					      Object.values(this.savedContracts)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.compiler.postMessage(JSON.stringify({
 | 
					    return files;
 | 
				
			||||||
      action: 'setFiles',
 | 
					 | 
				
			||||||
      data: files
 | 
					 | 
				
			||||||
    }));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,6 +22,7 @@ const WebpackErrorNotificationPlugin = require('webpack-error-notification');
 | 
				
			|||||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
					const CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
				
			||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
 | 
					const HtmlWebpackPlugin = require('html-webpack-plugin');
 | 
				
			||||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
 | 
					const ExtractTextPlugin = require('extract-text-webpack-plugin');
 | 
				
			||||||
 | 
					const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Shared = require('./shared');
 | 
					const Shared = require('./shared');
 | 
				
			||||||
const DAPPS = require('../src/dapps');
 | 
					const DAPPS = require('../src/dapps');
 | 
				
			||||||
@ -50,7 +51,7 @@ module.exports = {
 | 
				
			|||||||
    rules: [
 | 
					    rules: [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        test: /\.js$/,
 | 
					        test: /\.js$/,
 | 
				
			||||||
        exclude: /node_modules/,
 | 
					        exclude: /(node_modules)/,
 | 
				
			||||||
        // use: [ 'happypack/loader?id=js' ]
 | 
					        // use: [ 'happypack/loader?id=js' ]
 | 
				
			||||||
        use: isProd ? ['babel-loader'] : [
 | 
					        use: isProd ? ['babel-loader'] : [
 | 
				
			||||||
          'babel-loader?cacheDirectory=true'
 | 
					          'babel-loader?cacheDirectory=true'
 | 
				
			||||||
@ -136,7 +137,18 @@ module.exports = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  plugins: (function () {
 | 
					  plugins: (function () {
 | 
				
			||||||
    const plugins = Shared.getPlugins().concat([
 | 
					    const DappsHTMLInjection = DAPPS.map((dapp) => {
 | 
				
			||||||
 | 
					      return new HtmlWebpackPlugin({
 | 
				
			||||||
 | 
					        title: dapp.title,
 | 
				
			||||||
 | 
					        filename: dapp.name + '.html',
 | 
				
			||||||
 | 
					        template: './dapps/index.ejs',
 | 
				
			||||||
 | 
					        favicon: FAVICON,
 | 
				
			||||||
 | 
					        secure: dapp.secure,
 | 
				
			||||||
 | 
					        chunks: [ isProd ? null : 'commons', dapp.name ]
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const plugins = Shared.getPlugins().concat(
 | 
				
			||||||
      new CopyWebpackPlugin([{ from: './error_pages.css', to: 'styles.css' }], {}),
 | 
					      new CopyWebpackPlugin([{ from: './error_pages.css', to: 'styles.css' }], {}),
 | 
				
			||||||
      new WebpackErrorNotificationPlugin(),
 | 
					      new WebpackErrorNotificationPlugin(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -151,17 +163,14 @@ module.exports = {
 | 
				
			|||||||
        template: './index.ejs',
 | 
					        template: './index.ejs',
 | 
				
			||||||
        favicon: FAVICON,
 | 
					        favicon: FAVICON,
 | 
				
			||||||
        chunks: [ isProd ? null : 'commons', 'index' ]
 | 
					        chunks: [ isProd ? null : 'commons', 'index' ]
 | 
				
			||||||
      })
 | 
					      }),
 | 
				
			||||||
    ], DAPPS.map((dapp) => {
 | 
					
 | 
				
			||||||
      return new HtmlWebpackPlugin({
 | 
					      new ServiceWorkerWebpackPlugin({
 | 
				
			||||||
        title: dapp.title,
 | 
					        entry: path.join(__dirname, '../src/serviceWorker.js')
 | 
				
			||||||
        filename: dapp.name + '.html',
 | 
					      }),
 | 
				
			||||||
        template: './dapps/index.ejs',
 | 
					
 | 
				
			||||||
        favicon: FAVICON,
 | 
					      DappsHTMLInjection
 | 
				
			||||||
        secure: dapp.secure,
 | 
					    );
 | 
				
			||||||
        chunks: [ isProd ? null : 'commons', dapp.name ]
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!isProd) {
 | 
					    if (!isProd) {
 | 
				
			||||||
      const DEST_I18N = path.join(__dirname, '..', DEST, 'i18n');
 | 
					      const DEST_I18N = path.join(__dirname, '..', DEST, 'i18n');
 | 
				
			||||||
 | 
				
			|||||||
@ -139,9 +139,7 @@ fn file_exists(path: &Path) -> bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn upgrade_key_location(from: &PathBuf, to: &PathBuf) {
 | 
					pub fn upgrade_key_location(from: &PathBuf, to: &PathBuf) {
 | 
				
			||||||
	let mut parent = to.clone();
 | 
						match fs::create_dir_all(&to).and_then(|()| fs::read_dir(from)) {
 | 
				
			||||||
	parent.pop();
 | 
					 | 
				
			||||||
	match fs::create_dir_all(&parent).and_then(|()| fs::read_dir(from)) {
 | 
					 | 
				
			||||||
		Ok(entries) => {
 | 
							Ok(entries) => {
 | 
				
			||||||
			let files: Vec<_> = entries.filter_map(|f| f.ok().and_then(|f| if f.file_type().ok().map_or(false, |f| f.is_file()) { f.file_name().to_str().map(|s| s.to_owned()) } else { None })).collect();
 | 
								let files: Vec<_> = entries.filter_map(|f| f.ok().and_then(|f| if f.file_type().ok().map_or(false, |f| f.is_file()) { f.file_name().to_str().map(|s| s.to_owned()) } else { None })).collect();
 | 
				
			||||||
			let mut num: usize = 0;
 | 
								let mut num: usize = 0;
 | 
				
			||||||
@ -165,7 +163,7 @@ pub fn upgrade_key_location(from: &PathBuf, to: &PathBuf) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Err(e) => {
 | 
							Err(e) => {
 | 
				
			||||||
			warn!("Error moving keys from {:?} to {:?}: {:?}", from, to, e);
 | 
								debug!("Error moving keys from {:?} to {:?}: {:?}", from, to, e);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user