diff --git a/.gitignore b/.gitignore index f31145039..994559bb1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,10 @@ # mac stuff .DS_Store +# npm stuff +npm-debug.log +node_modules + # gdb files .gdb_history diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d90c5d4e..353941ae0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,7 +42,7 @@ linux-stable: - md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5" - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity --body target/release/parity - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity.md5 --body parity.md5 @@ -60,9 +60,27 @@ linux-stable: - target/release/ethstore - target/release/ethkey name: "stable-x86_64-unknown-linux-gnu_parity" +linux-snap: + stage: build + image: parity/snapcraft:gitlab-ci + only: + - snap + - beta + script: + - rm -rf *snap + - cd scripts + - snapcraft + tags: + - rust + - rust-stable + artifacts: + paths: + - scripts/parity_master_amd64.snap + name: "stable-x86_64-unknown-linux-gnu_parity-snap" + allow_failure: true linux-stable-debian: stage: build - image: ethcore/rust-debian:latest + image: parity/rust-debian:gitlab-ci only: - beta - tags @@ -89,7 +107,7 @@ linux-stable-debian: - md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5" - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/parity --body target/release/parity - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/parity.md5 --body parity.md5 @@ -146,7 +164,7 @@ linux-nightly: allow_failure: true linux-centos: stage: build - image: ethcore/rust-centos:latest + image: parity/rust-centos:gitlab-ci only: - beta - tags @@ -162,7 +180,7 @@ linux-centos: - export SHA3=$(target/release/parity tools hash target/release/parity) - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu - aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity --body target/release/parity - aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity.md5 --body parity.md5 @@ -177,7 +195,7 @@ linux-centos: name: "x86_64-unknown-centos-gnu_parity" linux-i686: stage: build - image: ethcore/rust-i686:latest + image: parity/rust-i686:gitlab-ci only: - beta - tags @@ -199,7 +217,7 @@ linux-i686: - md5sum "parity_"$VER"_i386.deb" > "parity_"$VER"_i386.deb.md5" - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM - aws 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/$PLATFORM/parity.md5 --body parity.md5 @@ -217,7 +235,7 @@ linux-i686: allow_failure: true linux-armv7: stage: build - image: ethcore/rust-armv7:latest + image: parity/rust-armv7:gitlab-ci only: - beta - tags @@ -236,7 +254,7 @@ linux-armv7: - cat .cargo/config - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS - arm-linux-gnueabihf-strip target/$PLATFORM/release/parity - - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h) + - export SHA3=$(rhash --sha3-256 target/$PLATFORM/release/parity -p %h) - md5sum target/$PLATFORM/release/parity > parity.md5 - sh scripts/deb-build.sh armhf - cp target/$PLATFORM/release/parity deb/usr/bin/parity @@ -245,7 +263,7 @@ linux-armv7: - md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5" - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM - aws 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/$PLATFORM/parity.md5 --body parity.md5 @@ -263,7 +281,7 @@ linux-armv7: allow_failure: true linux-arm: stage: build - image: ethcore/rust-arm:latest + image: parity/rust-arm:gitlab-ci only: - beta - tags @@ -282,7 +300,7 @@ linux-arm: - cat .cargo/config - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS - arm-linux-gnueabihf-strip target/$PLATFORM/release/parity - - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h) + - export SHA3=$(rhash --sha3-256 target/$PLATFORM/release/parity -p %h) - md5sum target/$PLATFORM/release/parity > parity.md5 - sh scripts/deb-build.sh armhf - cp target/$PLATFORM/release/parity deb/usr/bin/parity @@ -291,7 +309,7 @@ linux-arm: - md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5" - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM - aws 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/$PLATFORM/parity.md5 --body parity.md5 @@ -328,11 +346,11 @@ linux-armv6: - cat .cargo/config - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS - arm-linux-gnueabi-strip target/$PLATFORM/release/parity - - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h) + - export SHA3=$(rhash --sha3-256 target/$PLATFORM/release/parity -p %h) - md5sum target/$PLATFORM/release/parity > parity.md5 - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM - aws 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/$PLATFORM/parity.md5 --body parity.md5 @@ -348,7 +366,7 @@ linux-armv6: allow_failure: true linux-aarch64: stage: build - image: ethcore/rust-aarch64:latest + image: parity/rust-arm64:gitlab-ci only: - beta - tags @@ -367,7 +385,7 @@ linux-aarch64: - cat .cargo/config - cargo build -j $(nproc) --target $PLATFORM --features final --release $CARGOFLAGS - aarch64-linux-gnu-strip target/$PLATFORM/release/parity - - export SHA3=$(rhash --sha3-256 ~/Core/parity/target/release/parity -p %h) + - export SHA3=$(rhash --sha3-256 target/$PLATFORM/release/parity -p %h) - md5sum target/$PLATFORM/release/parity > parity.md5 - sh scripts/deb-build.sh arm64 - cp target/$PLATFORM/release/parity deb/usr/bin/parity @@ -376,7 +394,7 @@ linux-aarch64: - md5sum "parity_"$VER"_arm64.deb" > "parity_"$VER"_arm64.deb.md5" - aws configure set aws_access_key_id $s3_key - aws configure set aws_secret_access_key $s3_secret - - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi + - if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi - aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5 - aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/"parity_"$VER"_arm64.deb" --body "parity_"$VER"_arm64.deb" @@ -416,7 +434,7 @@ darwin: md5sum "parity-"$VER"-macos-installer.pkg" >> "parity-"$VER"-macos-installer.pkg.md5" aws configure set aws_access_key_id $s3_key aws configure set aws_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|nightly)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/$PLATFORM aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity --body target/release/parity aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/$PLATFORM/parity.md5 --body parity.md5 @@ -470,9 +488,10 @@ windows: - aws configure set aws_access_key_id %s3_key% - aws configure set aws_secret_access_key %s3_secret% - echo %CI_BUILD_REF_NAME% - - echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity - - echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity - - echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity + - echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity + - echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity + - echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity + - echo %CI_BUILD_REF_NAME% | findstr /R "nightly" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity - echo %S3_BUCKET% - aws s3 rm --recursive s3://%S3_BUCKET%/%CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc - aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe --body target\release\parity.exe @@ -503,7 +522,11 @@ docker-build: script: - if [ "$CI_BUILD_REF_NAME" == "beta-release" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi - docker login -u $Docker_Hub_User -p $Docker_Hub_Pass - - sh scripts/docker-build.sh $DOCKER_TAG + - sh scripts/docker-build.sh $DOCKER_TAG ethcore + - docker logout + - docker login -u $Docker_Hub_User_Parity -p $Docker_Hub_Pass_Parity + - sh scripts/docker-build.sh $DOCKER_TAG parity + - docker logout tags: - docker test-coverage: @@ -541,7 +564,7 @@ test-windows: - git submodule update --init --recursive script: - set RUST_BACKTRACE=1 - - echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release + - echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p parity-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release tags: - rust-windows allow_failure: true @@ -560,7 +583,7 @@ test-rust-stable: - rust-stable js-test: stage: test - image: ethcore/rust:stable + image: parity/rust:gitlab-ci before_script: - git submodule update --init --recursive - export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l) @@ -574,11 +597,12 @@ test-rust-beta: stage: test only: - triggers - image: ethcore/rust:beta + image: parity/rust:gitlab-ci before_script: - git submodule update --init --recursive - export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l) script: + - rustup default beta - export RUST_BACKTRACE=1 - if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi tags: @@ -589,11 +613,12 @@ test-rust-nightly: stage: test only: - triggers - image: ethcore/rust:nightly + image: parity/rust:gitlab-ci before_script: - git submodule update --init --recursive - export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l) script: + - rustup default nightly - export RUST_BACKTRACE=1 - if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi tags: @@ -607,12 +632,13 @@ js-release: - beta - stable - tags - image: ethcore/rust:stable + image: parity/rust:gitlab-ci before_script: - export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l) - echo $JS_FILES_MODIFIED - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi script: + - rustup default stable - echo $JS_FILES_MODIFIED - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi tags: @@ -621,8 +647,9 @@ push-release: stage: push-release only: - tags - image: ethcore/rust:stable + image: parity/rust:gitlab-ci script: + - rustup default stable - curl --data "secret=$RELEASES_SECRET" http://update.parity.io:1337/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF - curl --data "secret=$RELEASES_SECRET" http://update.parity.io:1338/push-release/$CI_BUILD_REF_NAME/$CI_BUILD_REF tags: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..b52c4e1f3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3842 @@ +## Parity [v1.6.6](https://github.com/paritytech/parity/releases/tag/v1.6.6) (2017-04-11) + +This release brings warp sync support for kovan network. + +- Beta Backports [#5434](https://github.com/paritytech/parity/pull/5434) + - Bump to v1.6.6 + - Strict validation transitions [#4988](https://github.com/paritytech/parity/pull/4988) + - Ability to make validation stricter + - Fix consensus + - Remove logger + - Fix eth_sign showing as wallet account [#5309](https://github.com/paritytech/parity/pull/5309) + - DefaultProps for account + - Pass signing account + - Update tests for Connect(...) + - Add new seed nodes [#5345](https://github.com/paritytech/parity/pull/5345) + - Kovan warp sync fixed +- Aura eip155 validation transition [#5363](https://github.com/paritytech/parity/pull/5363) + - Add eip155 validation + - Add transition block +- Default eip155 validation [#5350](https://github.com/paritytech/parity/pull/5350) +- Backport syntax libs update [#5316](https://github.com/paritytech/parity/pull/5316) + +## Parity [v1.6.5](https://github.com/paritytech/parity/releases/tag/v1.6.5) (2017-03-28) + +This release contains the following changes: + +- Warp sync snapshot format improvements. +- Fix for Firefox UI issues. +- Fix for restoring from a file snapshot. +- Fix for auto-updater error handling. +- Updated configuration for [Ropsten revival](https://github.com/ethereum/ropsten/blob/master/revival.md). Make sure to delete old Ropsten blockchain first with `parity db kill --chain ropsten`. After that you can sync normally with `parity --chain ropsten`. + +Full changes: + +- Beta Backports [#5299](https://github.com/paritytech/parity/pull/5299) + - Fix FireFox overflows [#5000](https://github.com/paritytech/parity/pull/5000) + - Max width for container + - Set min-width + - Switching ValidatorSet [#4961](https://github.com/paritytech/parity/pull/4961) + - Add multi validator set + - Nicer comment + - Validate in constructor + - Reporting + - Avoid clogging up tmp when updater dir has bad permissions. [#5024](https://github.com/paritytech/parity/pull/5024) + - Force earliest era set in snapshot restore [#5021](https://github.com/paritytech/parity/pull/5021) + - Bumb to v1.6.5 + - Fine grained snapshot chunking + - Ropsten revival +- Fix validator contract syncing [#4789](https://github.com/paritytech/parity/pull/4789) [#5011](https://github.com/paritytech/parity/pull/5011) + - Make validator set aware of various states + - Fix updater build + - Clean up contract call + - Failing sync test + - Adjust tests + - Nicer indent + - Revert bound divisor + +## Parity [v1.5.12](https://github.com/paritytech/parity/releases/tag/v1.5.12) (2017-03-27) + +Stable release that adds support for a new warp sync snapshot format. + +- Stable Backports [#5297](https://github.com/paritytech/parity/pull/5297) + - Bump to v1.5.12 + - Fine grained snapshot chunking + +## Parity [v1.6.4](https://github.com/paritytech/parity/releases/tag/v1.6.4) (2017-03-22) + +A number of issues fixed in this release: + +- Ledger device connectivity issues for some users on Windows. +- Improved vault usability. +- Stratum mining no longer requires `--force-sealing`. +- `evm` binary has been renamed to `parity-evm` to avoid conflict with cpp-ethereum package. + +Full Changes: + +- Backporting to beta [#4995](https://github.com/paritytech/parity/pull/4995) + - Bump to v1.6.4 + - Ensure sealing work enabled if notifier registed + - Fix condition check + - Always send full chunks [#4960](https://github.com/paritytech/parity/pull/4960) + - Bump nanomsg [#4965](https://github.com/paritytech/parity/pull/4965) + - Renaming evm binary to avoid conflicts. [#4899](https://github.com/paritytech/parity/pull/4899) +- Beta UI backports [#4993](https://github.com/paritytech/parity/pull/4993) + - Update js-precompiled 20170314-121823 + - Attach hardware wallets already in addressbook [#4912](https://github.com/paritytech/parity/pull/4912) + - Attach hardware wallets already in addressbook + - Only set values changed + - Add Vaults logic to First Run [#4894](https://github.com/paritytech/parity/issues/4894) [#4914](https://github.com/paritytech/parity/pull/4914) + - Add ability to configure Secure API (for [#4885](https://github.com/paritytech/parity/issues/4885)) [#4922](https://github.com/paritytech/parity/pull/4922) + - Add z-index to small modals as well [#4923](https://github.com/paritytech/parity/pull/4923) + - Eth_sign where account === undefined [#4964](https://github.com/paritytech/parity/pull/4964) + - Update for case where account === undefined + - Update tests to not mask account === undefined + - Default account = {} where undefined (thanks [@tomusdrw](https://github.com/tomusdrw)) + - Fix Password Dialog forms style issue [#4968](https://github.com/paritytech/parity/pull/4968) + + +## Parity [v1.6.3](https://github.com/paritytech/parity/releases/tag/v1.6.3) (2017-03-14) + +This release fixes issue compatibility with Safari on MacOS. + +- Safari fixes [#4902](https://github.com/paritytech/parity/pull/4902) + - Add intitial max-width to sections + - Move background z-index to -1 + +## Parity [v1.5.11](https://github.com/paritytech/parity/releases/tag/v1.5.11) (2017-03-14) + +Parity 1.5.11 Includes a patch for a more comprehensive block verification. + +- Bump to v1.5.11 +- Additional kovan params +- Recalculate receipt roots in close_and_lock +- Bump to v1.5.10 + +## Parity [v1.6.2](https://github.com/paritytech/parity/releases/tag/v1.6.2) (2017-03-13) + +A major release introducing a few new features: + +- Revamped UI. +- Account Vaults. +- Support for Ledger hardware wallet devices. +- Stratum protocol for PoW mining. +- A new MacOS installer. Parity for MacOS now includes a Menu Bar icon that allows controlling Parity service. +- Disk backed transaction store. Pending transactions are now saved to disk and won't get lost when Parity is restarted. +- Improved memory management. + +See the [blog post](https://blog.parity.io/announcing-parity-1-6/) for more details. + +Full Changes: + +- Fix auto-updater beta [#4868](https://github.com/paritytech/parity/pull/4868) +- Beta UI backports [#4855](https://github.com/paritytech/parity/pull/4855) + - Added React Hot Reload to dapps + TokenDeplpoy fix ([#4846](https://github.com/paritytech/parity/pull/4846)) + - Fix method decoding ([#4845](https://github.com/paritytech/parity/pull/4845)) + - Fix contract deployment method decoding in Signer + - Linting + - Fix TxViewer when no `to` (contract deployment) ([#4847](https://github.com/paritytech/parity/pull/4847)) + - Added React Hot Reload to dapps + TokenDeplpoy fix + - Fixes to the LocalTx dapp + - Don't send the nonce for mined transactions + - Don't encode empty to values for options + - Pull steps from actual available steps ([#4848](https://github.com/paritytech/parity/pull/4848)) + - Wait for the value to have changed in the input ([#4844](https://github.com/paritytech/parity/pull/4844)) + - Backport Regsirty changes from [#4589](https://github.com/paritytech/parity/pull/4589) + - Test fixes for [#4589](https://github.com/paritytech/parity/pull/4589) +- Beta Simple score [#4852](https://github.com/paritytech/parity/pull/4852) + - Simple score + - Ignore part of a test +- Backporting to beta [#4840](https://github.com/paritytech/parity/pull/4840) + - Fixes to the Registry dapp ([#4838](https://github.com/paritytech/parity/pull/4838)) + - Fix wrong ABI methods + - Fix comparison + - Bump to v1.6.1 +- Show token icons on list summary pages ([#4826](https://github.com/paritytech/parity/pull/4826)) [#4827](https://github.com/paritytech/parity/pull/4827) + - Adjust balance overlay margins (no jumps) + - Img only balances, small verifications + - Invalid tests removed + - Always wrap display (Thanks [@ngotchac](https://github.com/ngotchac)) + - Update tests to reflect reality +- Beta Engine backports [#4806](https://github.com/paritytech/parity/pull/4806) + - Calibrate before rejection + - Change flag name + - Add eip155 + - Make network_id default +- Beta UI backports [#4823](https://github.com/paritytech/parity/pull/4823) + - Better logic for contract deployments ([#4821](https://github.com/paritytech/parity/pull/4821)) +- Beta UI backports [#4818](https://github.com/paritytech/parity/pull/4818) + - Update the key ([#4817](https://github.com/paritytech/parity/pull/4817)) + - Adjust selection colours/display ([#4811](https://github.com/paritytech/parity/pull/4811)) + - Adjust selection colours to match with mui + - allow -> disable (simplify selections) + - Only use top-border + - Overlay selection line + - Slightly more muted unselected + - Restore address icon + - Fix default values for contract queries +- Beta UI backports [#4809](https://github.com/paritytech/parity/pull/4809) + - Update Wallet to new Wallet Code ([#4805](https://github.com/paritytech/parity/pull/4805)) + - Update Wallet Version + - Update Wallet Library + - Update Wallets Bytecodes + - Typo + - Separate Deploy in Contract API + - Use the new Wallet ABI // Update wallet code + - WIP .// Deploy from Wallet + - Update Wallet contract + - Contract Deployment for Wallet + - Working deployments for Single Owned Wallet contracts + - Linting + - Create a Wallet from a Wallet + - Linting + - Fix Signer transactions // Add Gas Used for transactions + - Deploy wallet contract fix + - Fix too high gas estimate for Wallet Contract Deploys + - Final piece ; deploying from Wallet owned by wallet + - Update Wallet Code + - Updated the Wallet Codes + - Fixing Wallet Deployments + - Add Support for older wallets + - Linting + - SMS Faucet ([#4774](https://github.com/paritytech/parity/pull/4774)) + - Faucet + - Remove flakey button-index testing + - Only display faucet when sms verified (mainnet) + - Simplify availability checks + - WIP + - Resuest from verified -> verified + - Update endpoint, display response text + - Error icon on errors + - Parse hash text response + - Use /api/:address endpoint + - Hash -> data + - Adjust sms-certified message + - Fix SectionList hovering issue ([#4749](https://github.com/paritytech/parity/pull/4749)) + - Fix SectionList Items hover when <3 items + - Even easier... + - Lint (new) +- Update ETC bootnodes [#4794](https://github.com/paritytech/parity/pull/4794) +- Update comments and reg ABI [#4787](https://github.com/paritytech/parity/pull/4787) +- Optimize signature for fallback function. [#4780](https://github.com/paritytech/parity/pull/4780) +- Rephrasing token generation screen. [#4777](https://github.com/paritytech/parity/pull/4777) +- Etherscan links based on netVersion identifier [#4772](https://github.com/paritytech/parity/pull/4772) +- Update README.md [#4762](https://github.com/paritytech/parity/pull/4762) +- Fix invalid props to verification code [#4766](https://github.com/paritytech/parity/pull/4766) +- Extend authority round consensus test [#4756](https://github.com/paritytech/parity/pull/4756) +- Revert last hyper "fix" [#4752](https://github.com/paritytech/parity/pull/4752) +- Vault Management UI (round 3) [#4652](https://github.com/paritytech/parity/pull/4652) +- Update SelectionList indicators [#4736](https://github.com/paritytech/parity/pull/4736) +- Update testnet detection [#4746](https://github.com/paritytech/parity/pull/4746) +- Fix Portal in Portal ESC issue [#4745](https://github.com/paritytech/parity/pull/4745) +- Update wiki [#4743](https://github.com/paritytech/parity/pull/4743) +- Account selector close operations [#4728](https://github.com/paritytech/parity/pull/4728) +- Fix Account Selection in Signer [#4744](https://github.com/paritytech/parity/pull/4744) +- Support both V1 & V2 DataChanged events in registry [#4734](https://github.com/paritytech/parity/pull/4734) +- Add info on forks. [#4733](https://github.com/paritytech/parity/pull/4733) +- Add registry addr [#4732](https://github.com/paritytech/parity/pull/4732) +- UI support for hardware wallets [#4539](https://github.com/paritytech/parity/pull/4539) +- S/delete/forget/ for wallets [#4729](https://github.com/paritytech/parity/pull/4729) +- New chains [#4720](https://github.com/paritytech/parity/pull/4720) +- Enable --warp by default [#4719](https://github.com/paritytech/parity/pull/4719) +- Update Uglify (fix to 2.8.2) to fix binary builds [#4723](https://github.com/paritytech/parity/pull/4723) +- Extract i18n strings in modals/* [#4706](https://github.com/paritytech/parity/pull/4706) +- Provide uncle size where available in RPC [#4713](https://github.com/paritytech/parity/pull/4713) +- EC math functions [#4696](https://github.com/paritytech/parity/pull/4696) +- Add registrar fields [#4716](https://github.com/paritytech/parity/pull/4716) +- Extract i18n strings in views/* [#4695](https://github.com/paritytech/parity/pull/4695) +- Removing network=disable from config files [#4715](https://github.com/paritytech/parity/pull/4715) +- Fast in-place migration for adding and removing column families [#4687](https://github.com/paritytech/parity/pull/4687) +- Display badges on summary view [#4689](https://github.com/paritytech/parity/pull/4689) +- Consistent file uploads [#4699](https://github.com/paritytech/parity/pull/4699) +- Rename https://mkr.market -> https://oasisdex.com [#4701](https://github.com/paritytech/parity/pull/4701) +- Stop copy & clickthrough from list summaries [#4700](https://github.com/paritytech/parity/pull/4700) +- Display ... for address summary overflows [#4691](https://github.com/paritytech/parity/pull/4691) +- Less agressive grayscale/opacity in SelectionList [#4688](https://github.com/paritytech/parity/pull/4688) +- Propagate trie errors upwards from State [#4655](https://github.com/paritytech/parity/pull/4655) +- Generic state backend [#4632](https://github.com/paritytech/parity/pull/4632) +- Enhance dialog layouts (round 1) [#4637](https://github.com/paritytech/parity/pull/4637) +- Vault Management UI (round 2) [#4631](https://github.com/paritytech/parity/pull/4631) +- Fix Portal broad event stopper [#4674](https://github.com/paritytech/parity/pull/4674) +- Custom dev chain presets [#4671](https://github.com/paritytech/parity/pull/4671) +- Max gas limit and min gas price [#4661](https://github.com/paritytech/parity/pull/4661) +- Align list displays with SectionList (UI consistency) [#4621](https://github.com/paritytech/parity/pull/4621) +- Add SelectionList component to DRY up [#4639](https://github.com/paritytech/parity/pull/4639) +- I18n NL linting updates [#4662](https://github.com/paritytech/parity/pull/4662) +- Misc. small UI fixes [#4657](https://github.com/paritytech/parity/pull/4657) +- More CLI settings for IPFS API [#4608](https://github.com/paritytech/parity/pull/4608) +- Fix Tendermint deadlock [#4654](https://github.com/paritytech/parity/pull/4654) +- Nl translations [#4649](https://github.com/paritytech/parity/pull/4649) +- Update transaction condition documentation [#4659](https://github.com/paritytech/parity/pull/4659) +- Bump hyper versions [#4645](https://github.com/paritytech/parity/pull/4645) +- Sane updater [#4658](https://github.com/paritytech/parity/pull/4658) +- Remainder of RPC APIs implemented for the light client [#4594](https://github.com/paritytech/parity/pull/4594) +- Preserve vault meta when changing pwd [#4650](https://github.com/paritytech/parity/pull/4650) +- Fix Geth account import [#4641](https://github.com/paritytech/parity/pull/4641) +- Tweak some checks. [#4633](https://github.com/paritytech/parity/pull/4633) +- Attempt to fix subscribeToEvents test [#4638](https://github.com/paritytech/parity/pull/4638) +- Fix selection value from RadioButtons [#4636](https://github.com/paritytech/parity/pull/4636) +- Convert all remaining Modals to use Portal (UI consistency) [#4625](https://github.com/paritytech/parity/pull/4625) +- Default account selection update [#4609](https://github.com/paritytech/parity/pull/4609) +- Display ETH balance in overlay account selector [#4588](https://github.com/paritytech/parity/pull/4588) +- Fixed minor grammar mistake in readme [#4627](https://github.com/paritytech/parity/pull/4627) +- Extract newly available i18n strings [#4623](https://github.com/paritytech/parity/pull/4623) +- Save pending local transactions in the database [#4566](https://github.com/paritytech/parity/pull/4566) +- Bump CID version to allow compilation on all platforms [#4614](https://github.com/paritytech/parity/pull/4614) +- Vault Management UI (first round) [#4446](https://github.com/paritytech/parity/pull/4446) +- Let Engine decide if it seals internally [#4613](https://github.com/paritytech/parity/pull/4613) +- Show only known accounts/wallets/addresses on Home [#4612](https://github.com/paritytech/parity/pull/4612) +- Proper default accounts RPCs [#4580](https://github.com/paritytech/parity/pull/4580) +- Hash-fetch errors in case upstream returns non-200 [#4599](https://github.com/paritytech/parity/pull/4599) +- Added pending transaction info to eth_getTransactionByHash [#4570](https://github.com/paritytech/parity/pull/4570) +- Secret store - initial version [#4567](https://github.com/paritytech/parity/pull/4567) +- Handle invalid ABI retrieved from address_book gracefully [#4606](https://github.com/paritytech/parity/pull/4606) +- Optimize key directory reloads [#4583](https://github.com/paritytech/parity/pull/4583) +- Revert Double Click on Accounts to close in Signer Bar [#4590](https://github.com/paritytech/parity/pull/4590) +- IPFS MVP [#4545](https://github.com/paritytech/parity/pull/4545) +- Networking fixes [#4563](https://github.com/paritytech/parity/pull/4563) +- Remove eth_compile* RPCs [#4577](https://github.com/paritytech/parity/pull/4577) +- Ledger wallet signing fixed [#4578](https://github.com/paritytech/parity/pull/4578) +- Remove vertx from Webpack config [#4576](https://github.com/paritytech/parity/pull/4576) +- Better display of tags [#4564](https://github.com/paritytech/parity/pull/4564) +- Added vaults support to `ethstore-cli` [#4532](https://github.com/paritytech/parity/pull/4532) +- Fixed font URLs [#4579](https://github.com/paritytech/parity/pull/4579) +- Explicitly set seconds to 0 from selector [#4559](https://github.com/paritytech/parity/pull/4559) +- Fixes evmbin compilation and adding to standard build. [#4561](https://github.com/paritytech/parity/pull/4561) +- Alias for personal_sendTransaction [#4554](https://github.com/paritytech/parity/pull/4554) +- Key derivation in ethstore & rpc [#4515](https://github.com/paritytech/parity/pull/4515) +- Skip OOG check for simple transfers [#4558](https://github.com/paritytech/parity/pull/4558) +- Light Client transaction queue, initial LightDispatcher [#4501](https://github.com/paritytech/parity/pull/4501) +- Fixes BadgeReg Middleware [#4556](https://github.com/paritytech/parity/pull/4556) +- Fix pasting of value in Input fields [#4555](https://github.com/paritytech/parity/pull/4555) +- Tooltips with react-intl [#4549](https://github.com/paritytech/parity/pull/4549) +- Close on double-click for Signer Account selection [#4540](https://github.com/paritytech/parity/pull/4540) +- Signer provenance [#4477](https://github.com/paritytech/parity/pull/4477) +- Fix console dapp [#4544](https://github.com/paritytech/parity/pull/4544) +- Extract i18n string into i18n/_defaults (base of translations) [#4514](https://github.com/paritytech/parity/pull/4514) +- Fix contract queries bug [#4534](https://github.com/paritytech/parity/pull/4534) +- Fixing namespace of couple methods in console. [#4538](https://github.com/paritytech/parity/pull/4538) +- Home landing page [#4178](https://github.com/paritytech/parity/pull/4178) +- Bump JSON RPC crates versions [#4530](https://github.com/paritytech/parity/pull/4530) +- Update rust version in README [#4531](https://github.com/paritytech/parity/pull/4531) +- Lower default pruning history and memory [#4528](https://github.com/paritytech/parity/pull/4528) +- Serde 0.9 [#4508](https://github.com/paritytech/parity/pull/4508) +- Fixes to Token Deploy dapp [#4513](https://github.com/paritytech/parity/pull/4513) +- Fixed receipt decoding [#4521](https://github.com/paritytech/parity/pull/4521) +- Several fixes to the Wallet in general [#4504](https://github.com/paritytech/parity/pull/4504) +- Use the current contract name for Solidity compilation [#4510](https://github.com/paritytech/parity/pull/4510) +- Preparation for Light client RPC [#4485](https://github.com/paritytech/parity/pull/4485) +- Fix Dutch translation [#4509](https://github.com/paritytech/parity/pull/4509) +- Fixed a warning and bumped libusb-sys [#4507](https://github.com/paritytech/parity/pull/4507) +- Fix TnC overflows on small screens [#4505](https://github.com/paritytech/parity/pull/4505) +- Fix no data sent in TxQueue dapp [#4502](https://github.com/paritytech/parity/pull/4502) +- Ledger wallet support [#4486](https://github.com/paritytech/parity/pull/4486) +- Add new Componennt for Token Images [#4498](https://github.com/paritytech/parity/pull/4498) +- Fix address and accounts links [#4491](https://github.com/paritytech/parity/pull/4491) +- Fix Token Reg Dapp issues in Firefox [#4489](https://github.com/paritytech/parity/pull/4489) +- Parity.js interfaces for vaults [#4497](https://github.com/paritytech/parity/pull/4497) +- Initial Dutch translations [#4484](https://github.com/paritytech/parity/pull/4484) +- Fix key.meta.vault for root dir keys && read vault.meta without vault key [#4482](https://github.com/paritytech/parity/pull/4482) +- Arbitrary labels for extended keys (u32, H256 built-in) [#4438](https://github.com/paritytech/parity/pull/4438) +- Fix ethstore build [#4492](https://github.com/paritytech/parity/pull/4492) +- Fixed compilation of ethstore-cli [#4493](https://github.com/paritytech/parity/pull/4493) +- Build embedded Parity JS properly and separatly [#4426](https://github.com/paritytech/parity/pull/4426) +- Static link for snappy [#4487](https://github.com/paritytech/parity/pull/4487) +- Work with string numbers in contract (Fixes #4472) [#4478](https://github.com/paritytech/parity/pull/4478) +- Metadata support for vaults [#4475](https://github.com/paritytech/parity/pull/4475) +- Sort gas price corpus when hitting genesis [#4470](https://github.com/paritytech/parity/pull/4470) +- Fixing CORS headers for parity.web3.site [#4461](https://github.com/paritytech/parity/pull/4461) +- Make signing compatible with geth. [#4468](https://github.com/paritytech/parity/pull/4468) +- Handle registry not found errors [#4465](https://github.com/paritytech/parity/pull/4465) +- Fix Portal scrolling getting stuck [#4455](https://github.com/paritytech/parity/pull/4455) +- Fix AccountCard stretch to 100% [#4450](https://github.com/paritytech/parity/pull/4450) +- Include total difficulty in CHTs and hide implementation details from consumers [#4428](https://github.com/paritytech/parity/pull/4428) +- Fix RLP encoding for types recursively calling `RlpStream::append` [#4362](https://github.com/paritytech/parity/pull/4362) +- Open popup without attempting inline [#4440](https://github.com/paritytech/parity/pull/4440) +- Fixing histogram again ([#4464](https://github.com/paritytech/parity/issues/4464)) port from beta [#4467](https://github.com/paritytech/parity/pull/4467) +- Vaults RPCs [#4366](https://github.com/paritytech/parity/pull/4366) +- Ethkey - extended keys [#4377](https://github.com/paritytech/parity/pull/4377) +- Use secure websocket from HTTPS clients [#4436](https://github.com/paritytech/parity/pull/4436) +- RPC middleware: Informant & Client.keep_alive [#4384](https://github.com/paritytech/parity/pull/4384) +- Fix eth_sign/parity_postSign [#4432](https://github.com/paritytech/parity/pull/4432) +- Web view with web3.site support [#4313](https://github.com/paritytech/parity/pull/4313) +- Extend Portal component with title, buttons & steps (as per Modal) [#4392](https://github.com/paritytech/parity/pull/4392) +- Extension installation overlay [#4423](https://github.com/paritytech/parity/pull/4423) +- Add block & timestamp conditions to Signer [#4411](https://github.com/paritytech/parity/pull/4411) +- Transaction timestamp condition [#4419](https://github.com/paritytech/parity/pull/4419) +- Poll for defaultAccount to update dapp & overlay subscriptions [#4417](https://github.com/paritytech/parity/pull/4417) +- Validate dapps accounts with address book [#4407](https://github.com/paritytech/parity/pull/4407) +- Dapps use defaultAccount instead of own selectors [#4386](https://github.com/paritytech/parity/pull/4386) +- Fix lock and rename tracing [#4403](https://github.com/paritytech/parity/pull/4403) +- Restarting fetch client every now and then [#4399](https://github.com/paritytech/parity/pull/4399) +- Perform a sync between Rust and JS when generating markdown instead of in spec tests [#4408](https://github.com/paritytech/parity/pull/4408) +- Registry dapp: make lookup use lower case [#4409](https://github.com/paritytech/parity/pull/4409) +- Available Dapp selection alignment with Permissions (Portal) [#4374](https://github.com/paritytech/parity/pull/4374) +- More permissive verification process [#4317](https://github.com/paritytech/parity/pull/4317) +- Fix ParityBar account selection overflows [#4405](https://github.com/paritytech/parity/pull/4405) +- Mac binaries signing [#4397](https://github.com/paritytech/parity/pull/4397) +- Revert "remove [ci skip]" [#4398](https://github.com/paritytech/parity/pull/4398) +- Registry, s/a the owner/the owner/ [#4391](https://github.com/paritytech/parity/pull/4391) +- Fixing invalid address in docs [#4388](https://github.com/paritytech/parity/pull/4388) +- Remove [ci skip] [#4381](https://github.com/paritytech/parity/pull/4381) +- Fixing estimate gas in case histogram is not available [#4387](https://github.com/paritytech/parity/pull/4387) +- Default Account selector in Signer overlay [#4375](https://github.com/paritytech/parity/pull/4375) +- Fixing web3 in console [#4382](https://github.com/paritytech/parity/pull/4382) +- Add parity_defaultAccount RPC (with subscription) [#4383](https://github.com/paritytech/parity/pull/4383) +- Full JSON-RPC docs + sync tests. [#4335](https://github.com/paritytech/parity/pull/4335) +- Expose util as Api.util [#4372](https://github.com/paritytech/parity/pull/4372) +- Dapp Account Selection & Defaults [#4355](https://github.com/paritytech/parity/pull/4355) +- Publish @parity/jsonrpc [#4365](https://github.com/paritytech/parity/pull/4365) +- Fix signing [#4363](https://github.com/paritytech/parity/pull/4363) +- Fixing embedded bar not closing in chrome extension [#4367](https://github.com/paritytech/parity/pull/4367) +- Update AccountCard for re-use [#4350](https://github.com/paritytech/parity/pull/4350) +- Add proper event listener to Portal [#4359](https://github.com/paritytech/parity/pull/4359) +- Optional from field in Transaction Requests [#4332](https://github.com/paritytech/parity/pull/4332) +- Rust 1.14 in README [ci-skip] [#4361](https://github.com/paritytech/parity/pull/4361) +- Fix JournalDB::earliest_era on empty database [#4316](https://github.com/paritytech/parity/pull/4316) +- Fixed race condition deadlock on fetching enode URL [#4354](https://github.com/paritytech/parity/pull/4354) +- Allow Portal to be used as top-level modal [#4338](https://github.com/paritytech/parity/pull/4338) +- Fix postsign [#4347](https://github.com/paritytech/parity/pull/4347) +- Renaming signAndSendTransaction to sendTransaction [#4351](https://github.com/paritytech/parity/pull/4351) +- Add api.util.encodeMethodCall to parity.js [#4330](https://github.com/paritytech/parity/pull/4330) +- Initial commit for vaults [#4312](https://github.com/paritytech/parity/pull/4312) +- Returning default account as coinbase + allow altering sender in signer [#4323](https://github.com/paritytech/parity/pull/4323) +- Persistent tracking of dapps [#4302](https://github.com/paritytech/parity/pull/4302) +- Exposing all RPCs over dapps port as CLI option [#4346](https://github.com/paritytech/parity/pull/4346) +- New macOS App [#4345](https://github.com/paritytech/parity/pull/4345) +- Display QrCode for accounts, addresses & contracts [#4329](https://github.com/paritytech/parity/pull/4329) +- Add QrCode & Copy to ShapeShift [#4322](https://github.com/paritytech/parity/pull/4322) +- Parity.js api.parity.chainStatus should handle { blockGap: null } [#4327](https://github.com/paritytech/parity/pull/4327) +- DeleteAccount & LoadContract modal updates [#4320](https://github.com/paritytech/parity/pull/4320) +- Split Tab from TabBar [#4318](https://github.com/paritytech/parity/pull/4318) +- Contracts interface expansion [#4307](https://github.com/paritytech/parity/pull/4307) +- HistoryStore for tracking relevant routes [#4305](https://github.com/paritytech/parity/pull/4305) +- Split Dapp icon into ui/DappIcon (re-use) [#4308](https://github.com/paritytech/parity/pull/4308) +- Add a Playground for the UI Components [#4301](https://github.com/paritytech/parity/pull/4301) +- Update CreateWallet with FormattedMessage [#4298](https://github.com/paritytech/parity/pull/4298) +- Update dates for new PRs missed [#4306](https://github.com/paritytech/parity/pull/4306) +- EIP-98: Optional transaction state root [#4296](https://github.com/paritytech/parity/pull/4296) +- Fix whitespace [#4299](https://github.com/paritytech/parity/pull/4299) +- Attempt to fix console. [#4294](https://github.com/paritytech/parity/pull/4294) +- Ui/SectionList component [#4292](https://github.com/paritytech/parity/pull/4292) +- Stratum up [#4233](https://github.com/paritytech/parity/pull/4233) +- Logging transaction duration [#4297](https://github.com/paritytech/parity/pull/4297) +- Generic engine utilities [#4258](https://github.com/paritytech/parity/pull/4258) +- JSON-RPC interfaces with documentation [#4276](https://github.com/paritytech/parity/pull/4276) +- Dont decode seal fields [#4263](https://github.com/paritytech/parity/pull/4263) +- Skip misbehaving test until properly fixed [#4283](https://github.com/paritytech/parity/pull/4283) +- Additional logs for own transactions [#4278](https://github.com/paritytech/parity/pull/4278) +- Ensure write lock isn't held when calling handlers [#4285](https://github.com/paritytech/parity/pull/4285) +- Feature selector [#4074](https://github.com/paritytech/parity/pull/4074) +- AccountCreate updates [#3988](https://github.com/paritytech/parity/pull/3988) +- Extended JS interface -> Markdown generator [#4275](https://github.com/paritytech/parity/pull/4275) +- Added 3 warpnodes for ropsten [#4289](https://github.com/paritytech/parity/pull/4289) +- Ledger Communication JS toolkit [#4268](https://github.com/paritytech/parity/pull/4268) +- ValidatorSet reporting [#4208](https://github.com/paritytech/parity/pull/4208) +- Add support for api.subscribe('parity_accountsInfo') [#4273](https://github.com/paritytech/parity/pull/4273) +- Display AccountCard name via IdentityName [#4235](https://github.com/paritytech/parity/pull/4235) +- Dapp visibility save/load tests [#4150](https://github.com/paritytech/parity/pull/4150) +- Fix wrong output format of peers [#4270](https://github.com/paritytech/parity/pull/4270) +- Chain scoring [#4218](https://github.com/paritytech/parity/pull/4218) +- Rust 1.14 for windows builds [#4269](https://github.com/paritytech/parity/pull/4269) +- Eslint formatting updates [#4234](https://github.com/paritytech/parity/pull/4234) +- Embeddable ParityBar [#4222](https://github.com/paritytech/parity/pull/4222) +- Update deb-build.sh to fix libssl dependency [#4260](https://github.com/paritytech/parity/pull/4260) +- Integration with zgp whitelist contract [#4215](https://github.com/paritytech/parity/pull/4215) +- Adjust the location of the signer snippet [#4155](https://github.com/paritytech/parity/pull/4155) +- Fix wrong token handling [#4254](https://github.com/paritytech/parity/pull/4254) +- Additional building-block UI components [#4239](https://github.com/paritytech/parity/pull/4239) +- Bump package.json to 0.3.0 (1.6 track) [#4244](https://github.com/paritytech/parity/pull/4244) +- Disable incoming ETH notifications [#4243](https://github.com/paritytech/parity/pull/4243) +- Memory-based pruning history size [#4114](https://github.com/paritytech/parity/pull/4114) +- Common EngineSigner [#4189](https://github.com/paritytech/parity/pull/4189) +- Verification: don't request a code twice [#4221](https://github.com/paritytech/parity/pull/4221) +- S/Delete Contract/Forget Contract/ [#4237](https://github.com/paritytech/parity/pull/4237) +- Light protocol syncing improvements [#4212](https://github.com/paritytech/parity/pull/4212) +- LES Peer Info [#4195](https://github.com/paritytech/parity/pull/4195) +- Don't panic on uknown git commit hash [#4231](https://github.com/paritytech/parity/pull/4231) +- Cache registry reverses in local storage [#4182](https://github.com/paritytech/parity/pull/4182) +- Update version numbers in README [#4223](https://github.com/paritytech/parity/pull/4223) +- CHT calculations for full nodes [#4181](https://github.com/paritytech/parity/pull/4181) +- Use single source of info for dapp meta (build & display) [#4217](https://github.com/paritytech/parity/pull/4217) +- Non-secure API for DappReg [#4216](https://github.com/paritytech/parity/pull/4216) +- Console now has admin [#4220](https://github.com/paritytech/parity/pull/4220) +- Verification: add mainnet BadgeReg ids [#4190](https://github.com/paritytech/parity/pull/4190) +- Fixing minimal transaction queue price [#4204](https://github.com/paritytech/parity/pull/4204) +- Remove unnecessary Engine method [#4184](https://github.com/paritytech/parity/pull/4184) +- Fixed --base-path on windows [#4193](https://github.com/paritytech/parity/pull/4193) +- Fixing etherscan price parsing [#4202](https://github.com/paritytech/parity/pull/4202) +- LES: Better timeouts + Track failed requests [#4093](https://github.com/paritytech/parity/pull/4093) +- ESLint additional rules [#4186](https://github.com/paritytech/parity/pull/4186) +- JsonRPC bump for IPC fix [#4200](https://github.com/paritytech/parity/pull/4200) +- Poll for upgrades as part of global status (long) [#4197](https://github.com/paritytech/parity/pull/4197) +- Updater fixes [#4196](https://github.com/paritytech/parity/pull/4196) +- Prevent duplicate incoming connections [#4180](https://github.com/paritytech/parity/pull/4180) +- Minor typo to ensure it updates only when synced. [#4188](https://github.com/paritytech/parity/pull/4188) +- Minor refactor for clarity [#4174](https://github.com/paritytech/parity/pull/4174) +- Secret - from hash function, also validate data [#4159](https://github.com/paritytech/parity/pull/4159) +- Gas_limit for blocks, mined by Parity will be divisible by 37 [#4154](https://github.com/paritytech/parity/pull/4154) +- Support HTML5-routed dapps [#4173](https://github.com/paritytech/parity/pull/4173) +- Fix subscribeToEvents test [#4166](https://github.com/paritytech/parity/pull/4166) +- Fix dapps not loading [#4170](https://github.com/paritytech/parity/pull/4170) +- Fix broken token images [#4169](https://github.com/paritytech/parity/pull/4169) +- Bumping hyper [#4167](https://github.com/paritytech/parity/pull/4167) +- Icarus -> update, increase web timeout. [#4165](https://github.com/paritytech/parity/pull/4165) +- Add a password strength component [#4153](https://github.com/paritytech/parity/pull/4153) +- Stop flickering + added loader in AddressSelector [#4149](https://github.com/paritytech/parity/pull/4149) +- On demand LES request [#4036](https://github.com/paritytech/parity/pull/4036) +- Ropsten fork detection [#4163](https://github.com/paritytech/parity/pull/4163) +- Pull in console dapp as builtin [#4145](https://github.com/paritytech/parity/pull/4145) +- Optimized hash lookups [#4144](https://github.com/paritytech/parity/pull/4144) +- UnverifiedTransaction type [#4134](https://github.com/paritytech/parity/pull/4134) +- Verification: check if server is running [#4140](https://github.com/paritytech/parity/pull/4140) +- Remove onSubmit of current (no auto-change on password edit) [#4151](https://github.com/paritytech/parity/pull/4151) +- Trim spaces from InputAddress [#4126](https://github.com/paritytech/parity/pull/4126) +- Don't pop-up notifications after network switch [#4076](https://github.com/paritytech/parity/pull/4076) +- Use estimateGas error (as per updated implementation) [#4131](https://github.com/paritytech/parity/pull/4131) +- Improvements and optimisations to estimate_gas [#4142](https://github.com/paritytech/parity/pull/4142) +- New jsonrpc-core with futures and metadata support [#3859](https://github.com/paritytech/parity/pull/3859) +- Reenable mainnet update server. [#4137](https://github.com/paritytech/parity/pull/4137) +- Temporarily skip failing test [#4138](https://github.com/paritytech/parity/pull/4138) +- Refactor VoteCollector [#4101](https://github.com/paritytech/parity/pull/4101) +- Another minor estimation fix [#4133](https://github.com/paritytech/parity/pull/4133) +- Add proper label to method decoding inputs [#4136](https://github.com/paritytech/parity/pull/4136) +- Remove bindActionCreators({}, dispatch) (empty, unneeded) [#4135](https://github.com/paritytech/parity/pull/4135) +- Better contract error log reporting & handling [#4128](https://github.com/paritytech/parity/pull/4128) +- Fix broken Transfer : total account balance [#4127](https://github.com/paritytech/parity/pull/4127) +- Test harness for lightsync [#4109](https://github.com/paritytech/parity/pull/4109) +- Fix call/estimate_gas [#4121](https://github.com/paritytech/parity/pull/4121) +- Fixing decoding ABI with signatures in names [#4125](https://github.com/paritytech/parity/pull/4125) +- Get rid of unsafe code in ethkey, propagate incorrect Secret errors. [#4119](https://github.com/paritytech/parity/pull/4119) +- Basic tests for subscribeToEvents [#4115](https://github.com/paritytech/parity/pull/4115) +- Auto-detect hex encoded bytes in sha3 [#4108](https://github.com/paritytech/parity/pull/4108) +- Use binary chop to estimate gas accurately [#4100](https://github.com/paritytech/parity/pull/4100) +- V1.6 in master [#4113](https://github.com/paritytech/parity/pull/4113) +- Ignore get_price_info test by default. [#4112](https://github.com/paritytech/parity/pull/4112) +- Fix wrong information logging [#4106](https://github.com/paritytech/parity/pull/4106) +- Avoid comms with not-yet-active release update server. [#4111](https://github.com/paritytech/parity/pull/4111) +- Update Transfer logic + Better logging [#4098](https://github.com/paritytech/parity/pull/4098) +- Fix Signer : wrong account on reload [#4104](https://github.com/paritytech/parity/pull/4104) +- Cache registry reverses, completion in address selector [#4066](https://github.com/paritytech/parity/pull/4066) +- Validator/authority contract [#3937](https://github.com/paritytech/parity/pull/3937) +- No reorg limit for ancient blocks [#4099](https://github.com/paritytech/parity/pull/4099) +- Update registration after every write [#4102](https://github.com/paritytech/parity/pull/4102) +- Default to no auto-update. [#4092](https://github.com/paritytech/parity/pull/4092) +- Don't remove out of date local transactions [#4094](https://github.com/paritytech/parity/pull/4094) + +## Parity [v1.5.9](https://github.com/paritytech/parity/releases/tag/v1.5.9) (2017-03-11) + +First stable release of 1.5.x series. This release enables EIP-161 transaction replay protection for PoA networks. + +- Bump to v1.5.9 +- Fix auto-updater stable [#4869](https://github.com/paritytech/parity/pull/4869) +- Fixing windows build script +- Bump js-precompiled 20170308-152339 +- Force js update +- Stable Engine backports [#4807](https://github.com/paritytech/parity/pull/4807) + - Calibrate before rejection + - Change flag name + - Add eip155 + - Fix build + - Make network_id default +- Switch js branch to stable +- Bump to v1.5.8 + +## Parity [v1.5.7](https://github.com/paritytech/parity/releases/tag/v1.5.7) (2017-03-07) + +This release resolves a single issue with failing auto-updates. + +- Update ETC bootnodes [#4794](https://github.com/paritytech/parity/pull/4794) +- Bump to v1.5.7 +- Sane updater [#4658](https://github.com/paritytech/parity/pull/4658) + - Disable if files can't be moved. + - Make updater avoid downloading earlier versions. + +## Parity [v1.5.6](https://github.com/paritytech/parity/releases/tag/v1.5.6) (2017-03-06) + +This release among various stability fixes adds support for a new [Kovan](https://github.com/kovan-testnet/proposal) testnet. + +See [full list of changes.](https://github.com/paritytech/parity/compare/v1.5.4...v1.5.6): + +- Beta Update comments and reg ABI [#4788](https://github.com/paritytech/parity/pull/4788) + - Update comments. + - Fix up new ABI. +- Bump to v1.5.6 in beta [#4786](https://github.com/paritytech/parity/pull/4786) +- Beta Optimize signature for fallback function. ([#4780](https://github.com/paritytech/parity/pull/4780)) [#4784](https://github.com/paritytech/parity/pull/4784) +- Beta Add registrar fields ([#4716](https://github.com/paritytech/parity/pull/4716)) [#4781](https://github.com/paritytech/parity/pull/4781) +- Beta Etherscan links ([#4772](https://github.com/paritytech/parity/pull/4772)) [#4778](https://github.com/paritytech/parity/pull/4778) + - Etherscan links [#4772](https://github.com/paritytech/parity/pull/4772) + - Use netVersion to determine external links + - Update additional isTest references + - Port tests + - Update address links + - Signer accountlink isTest +- Beta Fix invalid props [#4767](https://github.com/paritytech/parity/pull/4767) +- Backporting to beta [#4741](https://github.com/paritytech/parity/pull/4741) + - New chains [#4720](https://github.com/paritytech/parity/pull/4720) + - Add Kovan chain. + - Fix up --testnet. + - Fix tests. + - Fix to UglifyJS 2.8.2 to fix app build issues [#4723](https://github.com/paritytech/parity/pull/4723) + - Update classic bootnodes, ref #4717 [#4735](https://github.com/paritytech/parity/pull/4735) + - Allow failure docker beta + - Adjust pruning history default to 64 [#4709](https://github.com/paritytech/parity/pull/4709) + - Backporting from master + - Update docker-build.sh + - Update gitlab.ci + - Fix docker hub build + - Update gitlab + - Docker beta-release->latest + - Add registry. + - Add info on forks. + - Fixed spec file + - Support both V1 & V2 DataChanged events in registry [#4734](https://github.com/paritytech/parity/pull/4734) + - Add info on forks. + - Add new registry ABI + - Import registry2 & fix exports + - Select ABI based on code hash + - Render new event types (owner not available) + - New registry. + - Rename old chain. + - Fix test. + - Another fix. + - Finish rename. + - Fixed fonts URLs [#4579](https://github.com/paritytech/parity/pull/4579) + - Fix Token Reg Dapp issues in Firefox [#4489](https://github.com/paritytech/parity/pull/4489) + - Fix overflow issues in Firefox [#4348](https://github.com/paritytech/parity/issues/4348) + - Fix wrong Promise inferance + - Revert "Add new Componennt for Token Images [#4496](https://github.com/paritytech/parity/issues/4496)" + - Add new Componennt for Token Images [#4496](https://github.com/paritytech/parity/issues/4496) + - Add StackEventListener [#4745](https://github.com/paritytech/parity/pull/4745) + - Update testnet detection [#4746](https://github.com/paritytech/parity/pull/4746) + - Fix Account Selection in Signer [#4744](https://github.com/paritytech/parity/pull/4744) + - Can pass FormattedMessage to Input (eg. Status // RPC Enabled) + - Simple fixed-width fix for Accoutn Selection in Parity Signer +- Beta backports [#4763](https://github.com/paritytech/parity/pull/4763) + - Https://mkr-market -> https://oasisdex.com [#4701](https://github.com/paritytech/parity/pull/4701) + - Wallet s/delete/forget/ [#4741](https://github.com/paritytech/parity/pull/4741) +- Update classic bootnodes [#4735](https://github.com/paritytech/parity/pull/4735) +- Engine backports [#4718](https://github.com/paritytech/parity/pull/4718) + - Custom dev presets + - Add registrar field + - Use constructor for dev registrar + - Fix test +- Beta Adjust pruning history default to 64 [#4709](https://github.com/paritytech/parity/pull/4709) +- Bump to v1.5.5 + +## Parity [v1.5.4](https://github.com/paritytech/parity/releases/tag/v1.5.4) (2017-02-23) + +A couple of issue fixed in this release: + +- Parity now allows uncles headers to have timestamp set to arbitrary future value. +- Importing keys from geth is now working again. + +Changes: + +- Beta Fix Geth account import [#4643](https://github.com/paritytech/parity/pull/4643) + - Fix Geth import - actually pass addresses through + - Fix geth accounts not displayed + - Port saving of returned addresses (master MobX, beta state) + - Log result -> importGethAccounts +- Beta Backporting ([#4633](https://github.com/paritytech/parity/pull/4633)) [#4640](https://github.com/paritytech/parity/pull/4640) + - Tweak some checks. + - Fixed build and added a difficulty test + - Bump to v1.5.4 + +## Parity [v1.4.12](https://github.com/paritytech/parity/releases/tag/v1.4.12) (2017-02-22) + +This stable release fixes an issue with block uncle validation. Parity now allows uncle headers to have timestamp set to arbitrary future value. + +- Stable Backporting ([#4633](https://github.com/paritytech/parity/pull/4633)) [#4642](https://github.com/paritytech/parity/pull/4642) + - Tweak some checks. + - Fixed build and added a difficulty test + - Bump to v1.4.12 +- Add missing maxCodeSize [#4585](https://github.com/paritytech/parity/pull/4585) + +## Parity [v1.5.3](https://github.com/paritytech/parity/releases/tag/v1.5.3) (2017-02-20) + +This is a maintenance release that fixes a number of stability issues. Notably this resolves an issue where Parity would allow a pre EIP-155 transaction into the sealed block. + +See [full list of changes](https://github.com/paritytech/parity/compare/v1.5.2...v1.5.3): + +- Bump to v1.5.3 [#4611](https://github.com/paritytech/parity/pull/4611) +- Handle invalid ABI retrieved from address_book gracefully ([#4606](https://github.com/paritytech/parity/pull/4606)) [#4610](https://github.com/paritytech/parity/pull/4610) + - Handle invalid ABI gracefully + - Also include failed abi in log +- Backporting to beta [#4602](https://github.com/paritytech/parity/pull/4602) + - Static link for snappy + - added 3 warpnodes for ropsten ([#4289](https://github.com/paritytech/parity/pull/4289)) + - Fixed indentation +- Validate transaction before adding to the queue [#4600](https://github.com/paritytech/parity/pull/4600) +- Beta backports [#4569](https://github.com/paritytech/parity/pull/4569) + - Fixing evmbin compilation and added standard build. ([#4561](https://github.com/paritytech/parity/pull/4561)) + - Alias for personal_sendTransaction ([#4554](https://github.com/paritytech/parity/pull/4554)) + - Fix console dapp ([#4544](https://github.com/paritytech/parity/pull/4544)) + - Fixing linting issues. Better support for console as secure app + - Fixing linting issues + - Fix no data sent in TxQueue dapp ([#4502](https://github.com/paritytech/parity/pull/4502)) + - Fix wrong PropType req for Embedded Signer + - Fix wrong data for tx #4499 +- Explicitly set seconds to 0 from selector ([#4559](https://github.com/paritytech/parity/pull/4559)) [#4571](https://github.com/paritytech/parity/pull/4571) + - Explicitly set seconds/milli to 0 + - Use condition time & block setters consistently + - Fix failing test + - test for 0 ms & sec + - It cannot hurt, clone date before setting + - Prettier date test constants (OCD) +- Remove invalid expectation [#4542](https://github.com/paritytech/parity/pull/4542) +- Skip OOG check for simple transfers [#4558](https://github.com/paritytech/parity/pull/4558) [#4560](https://github.com/paritytech/parity/pull/4560) + - Skip OOG check for simple transfers [#4558](https://github.com/paritytech/parity/pull/4558) + - Fix failing test + +## Parity [v1.4.11](https://github.com/paritytech/parity/releases/tag/v1.4.11) (2017-02-17) + +This release corrects the Ropsten chain specification file. + +- Bump to v1.4.11 [#4587](https://github.com/paritytech/parity/pull/4587) +- Fixing etherscan price parsing ([#4202](https://github.com/paritytech/parity/pull/4202)) [#4209](https://github.com/paritytech/parity/pull/4209) + - Fixing etherscan price parsing + - Handling all errors +- Removed pdbs +- Add missing maxCodeSize [#4585](https://github.com/paritytech/parity/pull/4585) + +## Parity [v1.5.2](https://github.com/paritytech/parity/releases/tag/v1.5.2) (2017-02-08) + +This release brings a few stability fixes along with a feature that allows queuing transactions that are activated and send out on selected date or block number. +- Debian packages have been updated to require `libssl1.0.0` for better compatibility. +- eth_sign (and parity_postSign) used to return concatenated r ++ s ++ v with v being 0 or 1. it now agrees with geth as v ++ r ++ s with v being 27 or 28. + +Parity Wallet +- Accounts & ShapeShift integration now displays QR code for scanning from mobile wallets +- Dapp integration now allows for the selection of available accounts and the setting of the default account +- Transaction creation now allows for the selection of future blocks or timestamps after which the transaction is released + +Parity Extension +- First release of the Parity Extension, allowing for Parity integration from web-based dapps + +See [full list of changes](https://github.com/paritytech/parity/compare/v1.5.0...v1.5.2): +- Work with string numbers in contract (Fixes #4472) ([#4478](https://github.com/paritytech/parity/pull/4478)) [#4480](https://github.com/paritytech/parity/pull/4480) +- Eth_sign improvements backport [#4473](https://github.com/paritytech/parity/pull/4473) + - Fix postsign ([#4347](https://github.com/paritytech/parity/pull/4347)) + - Fix whitespace. + - Fix post sign. + - Fix message. + - Fix tests. + - Rest of the problems. + - All hail the linter and its omniscience. + - ...and its divine omniscience. + - Grumbles and wording. + - Make signing compatible with geth. ([#4468](https://github.com/paritytech/parity/pull/4468)) +- Sort gas price corpus when hitting genesis [#4471](https://github.com/paritytech/parity/pull/4471) +- Wallet dev chain fix [#4466](https://github.com/paritytech/parity/pull/4466) +- Fixing histogram again [#4464](https://github.com/paritytech/parity/pull/4464) +- Beta backports [#4462](https://github.com/paritytech/parity/pull/4462) + - Support HTML5-routed dapps ([#4173](https://github.com/paritytech/parity/pull/4173)) + - Fix compilation on latest nightly + - Updating precompiled +- Fix Portal scrolling getting stuck [#4456](https://github.com/paritytech/parity/pull/4456) + - Fix Portal scrolling getting stuck + - DappCard container flex + - Container height to 100% +- Fix AccountCard stretch to 100% [#4451](https://github.com/paritytech/parity/pull/4451) +- Fix wrong output format of peers ([#4270](https://github.com/paritytech/parity/pull/4270)) [#4442](https://github.com/paritytech/parity/pull/4442) + - Fix wrong output format of peers + - Add outPeer tests +- Opening extension page without inline installation [#4441](https://github.com/paritytech/parity/pull/4441) + - Open popup without attempting inline + - Cater for all .web3.site addresses +- Fix svg extension image webpack inlining [#4437](https://github.com/paritytech/parity/pull/4437) +- Backporting to beta [#4434](https://github.com/paritytech/parity/pull/4434) + - Bump to v1.5.2 + - Fix eth_sign/parity_postSign ([#4432](https://github.com/paritytech/parity/pull/4432)) + - Fix dispatch for signing. + - Remove console log + - Fix signing & tests. +- Returning default account as coinbase [#4431](https://github.com/paritytech/parity/pull/4431) + - Returning first address as coinbase + - Allowing sender alteration in signer + - Adding default account RPC +- UI updates for 1.5.1 [#4429](https://github.com/paritytech/parity/pull/4429) + - S/Delete Contract/Forget Contract/ ([#4237](https://github.com/paritytech/parity/pull/4237)) + - Adjust the location of the signer snippet ([#4155](https://github.com/paritytech/parity/pull/4155)) + - Additional building-block UI components ([#4239](https://github.com/paritytech/parity/pull/4239)) + - Currency WIP + - Expand tests + - Pass className + - Add QrCode + - Export new components in ~/ui + - S/this.props.netSymbol/netSymbol/ + - Fix import case + - Ui/SectionList component ([#4292](https://github.com/paritytech/parity/pull/4292)) + - Array chunking utility + - Add SectionList component + - Add TODOs to indicate possible future work + - Add missing overlay style (as used in dapps at present) + - Add a Playground for the UI Components ([#4301](https://github.com/paritytech/parity/pull/4301)) + - Playground // WIP + - Linting + - Add Examples with code + - CSS Linting + - Linting + - Add Connected Currency Symbol + - 2015-2017 + - Added `renderSymbol` tests + - PR grumbles + - Add Eth and Btc QRCode examples + - 2015-2017 + - Add tests for playground + - Fixing tests + - Split Dapp icon into ui/DappIcon ([#4308](https://github.com/paritytech/parity/pull/4308)) + - Add QrCode & Copy to ShapeShift ([#4322](https://github.com/paritytech/parity/pull/4322)) + - Extract CopyIcon to ~/ui/Icons + - Add copy & QrCode address + - Default size 4 + - Add bitcoin: link + - Use protocol links applicable to coin exchanged + - Remove .only + - Display QrCode for accounts, addresses & contracts ([#4329](https://github.com/paritytech/parity/pull/4329)) + - Allow Portal to be used as top-level modal ([#4338](https://github.com/paritytech/parity/pull/4338)) + - Portal + - Allow Portal to be used in as both top-level and popover + - Modal/popover variable naming + - Export Portal in ~/ui + - Properly handle optional onKeyDown + - Add simple Playground Example + - Add proper event listener to Portal ([#4359](https://github.com/paritytech/parity/pull/4359)) + - Display AccountCard name via IdentityName ([#4235](https://github.com/paritytech/parity/pull/4235)) + - Fix signing ([#4363](https://github.com/paritytech/parity/pull/4363)) + - Dapp Account Selection & Defaults ([#4355](https://github.com/paritytech/parity/pull/4355)) + - Add parity_defaultAccount RPC (with subscription) ([#4383](https://github.com/paritytech/parity/pull/4383)) + - Default Account selector in Signer overlay ([#4375](https://github.com/paritytech/parity/pull/4375)) + - Typo, fixes #4271 ([#4391](https://github.com/paritytech/parity/pull/4391)) + - Fix ParityBar account selection overflows ([#4405](https://github.com/paritytech/parity/pull/4405)) + - Available Dapp selection alignment with Permissions (Portal) ([#4374](https://github.com/paritytech/parity/pull/4374)) + - Registry dapp: make lookup use lower case ([#4409](https://github.com/paritytech/parity/pull/4409)) + - Dapps use defaultAccount instead of own selectors ([#4386](https://github.com/paritytech/parity/pull/4386)) + - Poll for defaultAccount to update dapp & overlay subscriptions ([#4417](https://github.com/paritytech/parity/pull/4417)) + - Poll for defaultAccount (Fixes #4413) + - Fix nextTimeout on catch + - Store timers + - Re-enable default updates on change detection + - Add block & timestamp conditions to Signer ([#4411](https://github.com/paritytech/parity/pull/4411)) + - Extension installation overlay ([#4423](https://github.com/paritytech/parity/pull/4423)) + - Extension installation overlay + - Pr gumbles + - Spelling + - Update Chrome URL + - Fix for non-included jsonrpc + - Extend Portal component (as per Modal) [#4392](https://github.com/paritytech/parity/pull/4392) +- Transaction timestamp condition [#4427](https://github.com/paritytech/parity/pull/4427) +- Fixing embedded bar not closing in chrome extension [#4421](https://github.com/paritytech/parity/pull/4421) +- Backporting to beta [#4418](https://github.com/paritytech/parity/pull/4418) + - Bump to 1.5.1 + - Disable notifications ([#4243](https://github.com/paritytech/parity/pull/4243)) + - Fix wrong token handling ([#4254](https://github.com/paritytech/parity/pull/4254)) + - Fixing wrong token displayed + - Linting + - Revert filtering out + - Revert the revert + - Don't panic on uknown git commit hash ([#4231](https://github.com/paritytech/parity/pull/4231)) + - Additional logs for own transactions ([#4278](https://github.com/paritytech/parity/pull/4278)) + - Integration with zgp whitelist contract ([#4215](https://github.com/paritytech/parity/pull/4215)) + - Zgp-transactions checker + - Polishing + - Rename + refactor + - Refuse-service-transactions cl option + - Fixed tests compilation + - Renaming signAndSendTransaction to sendTransaction ([#4351](https://github.com/paritytech/parity/pull/4351)) + - Fixed deadlock in external_url ([#4354](https://github.com/paritytech/parity/pull/4354)) + - Fixing web3 in console ([#4382](https://github.com/paritytech/parity/pull/4382)) + - Fixing estimate gas in case histogram is not available ([#4387](https://github.com/paritytech/parity/pull/4387)) + - Restarting fetch client every now and then ([#4399](https://github.com/paritytech/parity/pull/4399)) +- Embeddable ParityBar ([#4222](https://github.com/paritytech/parity/pull/4222)) [#4287](https://github.com/paritytech/parity/pull/4287) + - Embeddable ParityBar + - Replacing storage with store + - Fixing references. + - Addressing style issues + - Supporting parity background + +## Parity [v1.5.0: "Nativity"](https://github.com/paritytech/parity/releases/tag/v1.5.0) (2017-01-19) + +Major feature release including _Tendermint_ consensus engine, _Multisig wallet_ support, _badge/certification_ UI integration and _automatic updates_. + +Directories: + +- New XDG-informed Parity data directory structure. Base dir (`--base-path` or `-d`) that defaulted to `$HOME/.parity` is changed to: + - `/Users/You/AppData/Roaming/Parity/Ethereum` on Windows + - `/Users/you/Library/Application Support/io.parity.ethereum` on MacOS + - `/home/you/.local/share/parity` on Linux/Unix +- Keys are now stored in chain-specific directories . On first run of 1.5, all keys will be moved into the key's directory of the chain you run. You'll need to move the wallet files between directories manually if you wish to split them between testnet/mainnet. +- `--db-path` option now controls the path just for the databases, not for keys (`--keys-path`) or dapps (`--dapps-path`). + +Basics: + +- Version tracking, consensus-protection, hypervised auto-updating: + - Parity will ensure syncing is paused if its version cannot support an upcoming hard-fork (disable with `--no-consensus`). + - Parity will automatically download the latest version and may be updated through Parity Wallet (disable with `--no-download`) + - Parity can automatically update and seamlessly restart to later versions in the same release track (enable with `--auto-update=all` or `--auto-update=critical`). + - Parity hypervisor will automatically run the latest version (disable with `--force-direct`). +- Fat database; to enable, sync the chain with the option `--fat-db`. + - Accounts and storage entries can be enumerated. + - Chain state can be exported to JSON for analysis with `parity export state`. +- CLI and config options renamed: all variants of `--signer` are renamed to `--ui`. +- Log files are appended by default rather than truncated (useful for daemon deployments). + +Parity Wallet: + +- Multisig wallet support: "New Wallet" button in the "Accounts" section allows you to create a new multisig wallet or import an existing one. +- Solidity compiler: "Develop Contract" button in the "Contracts" section allows you to write, edit, compile and deploy contracts. +- SMS & e-mail verification: Accounts can now be certified as verified using Parity's SMS and e-Mail verification/registration oracle. +- Badge/certification integration: The `BadgeReg` contract can be used to deploy additional certifications. +- Local transaction propagation tracking: "TxQueue Viewer" in the "Applications" section allows you to track and resubmit previously sent transactions. +- Contract executions can now have gas and gas-price configured. +- Signer can now alter the gas and gas-price of transactions at password-entry. +- The deprecated Chrome "Signer" extension is now incompatible. + +[Proof of Authority](https://github.com/paritytech/parity/wiki/Proof-of-Authority-Chains): + +- Authority Round consensus engine: `engine: authorityRound {...}`; this is a high-performance Proof-of-Authority consensus engine. It is not BFT under normal circumstances (however the `--force-sealing` flag can be used to ensure consensus even with Byzantine nodes). +- Tendermint Engine: `engine: tendermint {...}`; this is an experimental Proof-of-Authority consensus engine. BFT up to one third of the authorities and falling back to delayed finalization chain ordering (50% fault tolerant). +- Generic seal JSON spec includes engine-specific types (`seal: { generic: { rlp: "0x..." } }` becomes `seal: { authority_round { step: 0, signature: "0x..." } }`. +- To set a node as authority either `--engine-signer ADDRESS` should be used with `--password` or `parity_setEngineSigner(address, password)` RPC should be called. Unlocking the account permanently or using `--author` is now unnecessary. +- Set of authorities can now be specified using a [list or a contract](https://github.com/paritytech/parity/wiki/Consensus-Engines#validator-engines). + +Chains: + +- Dev chain: `--chain=dev`; instant seal engine (no mining needed). Great for development work. +- Ropsten chain (`--chain=ropsten` or `--chain=testnet`) configures for Ropsten, the new test net. +- Morden chain (`--chain=morden`) changed to "Classic" rules and stays as the Ethereum Classic test net. + +RPCs/APIs: + +- All JSON-RPC interfaces have strict JSON deserialization - no extra fields are allowed. +- `eth_sign` RPC now hashes given data instead of getting the hash. +- `signer_confirmRequestWithToken`: additional RPC for signing transactions with a rotating token, alleviating the need for keeping an account password in memory. +- `eth_signTransaction` now conforms to the specification, `eth_submitTransaction` is introduced. + +Full changes: + +- Backporting to beta [#4211](https://github.com/paritytech/parity/pull/4211) + - JsonRPC bump for IPC fix + - Fixing etherscan price parsing ([#4202](https://github.com/paritytech/parity/pull/4202)) + - Handling all errors + - Fixed --base-path on windows ([#4193](https://github.com/paritytech/parity/pull/4193)) + - Add support for optional args with default text + - Fixing minimal transaction queue price ([#4204](https://github.com/paritytech/parity/pull/4204)) + - Fixing tests + - verification: add mainnet BadgeReg ids ([#4190](https://github.com/paritytech/parity/pull/4190)) + - verification: fetch contracts by name + - verification: better wording + - typo + - reregistered badges + - Console now has admin ([#4220](https://github.com/paritytech/parity/pull/4220)) + - Fixes [#4210](https://github.com/paritytech/parity/pull/4210) + - Non-secure for DappReg ([#4216](https://github.com/paritytech/parity/pull/4216)) +- Backporting to beta [#4203](https://github.com/paritytech/parity/pull/4203) + - Minor typo to ensure it updates only when synced. ([#4188](https://github.com/paritytech/parity/pull/4188)) + - Updater fixes ([#4196](https://github.com/paritytech/parity/pull/4196)) + - Minor typo to ensure it updates only when synced. + - Fix deadlock. + - Skip unneeded arg in making list. + - Allow auto-restart even when not running an update. + - Fix trace. + - Update update info on each loop. + - Fix build. + - Shutdown all sockets + - Remove superfluous use. + - Poll for upgrades as part of global status (long) ([#4197](https://github.com/paritytech/parity/pull/4197)) + - Fix path + - Prevent duplicate incoming connections ([#4180](https://github.com/paritytech/parity/pull/4180)) +- Gas_limit for blocks, mined by Parity will be divisible by 37 ([#4154](https://github.com/paritytech/parity/pull/4154)) [#4176](https://github.com/paritytech/parity/pull/4176) + - gas_limit for new blocks will divide evenly by 13 + - increased PARITY_GAS_LIMIT_DETERMINANT to 37 + - separate method for marking mined block + - debug_asserts(gas_limit within protocol range) + - round_block_gas_limit method is now static + - made round_block_gas_limit free-function + - multiplier->multiple +- Backporting to beta [#4175](https://github.com/paritytech/parity/pull/4175) + - verification: check if server is running ([#4140](https://github.com/paritytech/parity/pull/4140)) + - verification: check if server is running + - See also ethcore/email-verification#67c6466 and ethcore/sms-verification#a585e42. + - verification: show in the UI if server is running + - verification: code style ✨, more i18n + - fix i18n key + - Optimized hash lookups ([#4144](https://github.com/paritytech/parity/pull/4144)) + - Optimize hash comparison + - Use libc + - Ropsten fork detection ([#4163](https://github.com/paritytech/parity/pull/4163)) + - Stop flickering + added loader in AddressSelector ([#4149](https://github.com/paritytech/parity/pull/4149)) + - Stop UI flickering + added loader to AddressSelector [#4103](https://github.com/paritytech/parity/pull/4103) + - PR Grumbles + - Add a password strength component ([#4153](https://github.com/paritytech/parity/pull/4153)) + - Added new PasswordStrength Component + - Added tests + - PR Grumbles + - icarus -> update, increase web timeout. ([#4165](https://github.com/paritytech/parity/pull/4165)) + - Fix estimate gas + - Fix token images // Error in Contract Queries ([#4169](https://github.com/paritytech/parity/pull/4169)) + - Fix dapps not loading ([#4170](https://github.com/paritytech/parity/pull/4170)) + - Add secure to dappsreg + - Remove trailing slash // fix dapps +- Bumping hyper [#4168](https://github.com/paritytech/parity/pull/4168) + - Bumping hyper + - Bumping again +- Backporting to beta [#4158](https://github.com/paritytech/parity/pull/4158) + - Remove onSubmit of current (no auto-change on password edit) ([#4151](https://github.com/paritytech/parity/pull/4151)) + - Remove onSubmit from current password + - Remove onSubmit from hint + - Pull in console dapp as builtin ([#4145](https://github.com/paritytech/parity/pull/4145)) + - Copy static dapps from static (no build) + - Console sources + - Add console to builtins + - Remove console assets + - Disable eslint on console.js + - Enable eslint after disable + - Webpack copy +- Backporting to beta [#4152](https://github.com/paritytech/parity/pull/4152) + - Fix broken transfer total balance ([#4127](https://github.com/paritytech/parity/pull/4127)) + - Add proper label to method decoding inputs ([#4136](https://github.com/paritytech/parity/pull/4136)) + - Another minor estimation fix ([#4133](https://github.com/paritytech/parity/pull/4133)) + - Return 0 instead of error with out of gas on estimate_gas + - Fix stuff up. + - Another estimate gas fix. + - Alter balance to maximum possible rather than GP=0. + - Only increase to amount strictly necessary. + - Get rid of unsafe code in ethkey, propagate incorrect Secret errors. ([#4119](https://github.com/paritytech/parity/pull/4119)) + - Implementing secret + - Fixing tests + - Refactor VoteCollector ([#4101](https://github.com/paritytech/parity/pull/4101)) + - dir + - simple validator list + - stub validator contract + - make the engine hold Weak instead of IoChannel + - validator set factory + - register weak client with ValidatorContract + - check chain security + - add address array to generator + - register provider contract + - update validator set on notify + - add validator contract spec + - simple list test + - split update and contract test + - contract change + - use client in tendermint + - fix deadlock + - step duration in params + - adapt tendermint tests + - add storage fields to test spec + - constructor spec + - execute under wrong address + - create under correct address + - revert + - validator contract constructor + - move genesis block lookup + - add removal ability to contract + - validator contract adding validators + - fix basic authority + - validator changing test + - more docs + - update sync tests + - remove env_logger + - another env_logger + - cameltoe + - hold EngineClient instead of Client + - return error on misbehaviour + - nicer return + - sprinkle docs + - Reenable mainnet update server. ([#4137](https://github.com/paritytech/parity/pull/4137)) + - basic tests for subscribeToEvents ([#4115](https://github.com/paritytech/parity/pull/4115)) + - subscribeToEvent fixtures ✅ + - subscribeToEvent tests ✅ + - temporarily skip failing test ([#4138](https://github.com/paritytech/parity/pull/4138)) + - Improvements and optimisations to estimate_gas ([#4142](https://github.com/paritytech/parity/pull/4142)) + - Return 0 instead of error with out of gas on estimate_gas + - Fix stuff up. + - Another estimate gas fix. + - Alter balance to maximum possible rather than GP=0. + - Only increase to amount strictly necessary. + - Improvements and optimisations to estimate_gas. + - Introduce proper error type + - Avoid building costly traces + - Fix tests. + - Actually fix testsActually fix tests + - Use estimateGas error (as per updated implementation) ([#4131](https://github.com/paritytech/parity/pull/4131)) + - EXCEPTION_ERROR as per #4142 + - Better error log reporting & handling ([#4128](https://github.com/paritytech/parity/pull/4128)) + - Don't pop-up notifications after network switch ([#4076](https://github.com/paritytech/parity/pull/4076)) + - Better notifications + - Don't pollute with notifs if switched networks + - Better connection close/open events / No more notifs on change network + - PR Grumbles + - Add close and open events to HTTP // Add tests + - Fix tests + - WIP Signer Fix + - Fix Signer // Better reconnection handling + - PR Grumbles + - PR Grumbles + - Fixes wrong fetching of balances + Notifications + - Secure API WIP + - Updated Secure API Connection + Status + - Linting + - Updated Secure API Logic + - Proper handling of token updates // Fixing poping notifications + - PR Grumbles + - Fixing tests + - Trim spaces from InputAddress ([#4126](https://github.com/paritytech/parity/pull/4126)) + - Trim spaces for addresses + - onSubmit has only value, not event + - onSubmit (again) + - Length check on trimmed value + - Remove bindActionCreators({}, dispatch) (empty) ([#4135](https://github.com/paritytech/parity/pull/4135)) +- Backporting to beta [#4118](https://github.com/paritytech/parity/pull/4118) + - Ignore get_price_info test by default. ([#4112](https://github.com/paritytech/parity/pull/4112)) + - Auto-detect hex encoded bytes in sha3 ([#4108](https://github.com/paritytech/parity/pull/4108)) + - Using types/isHex + - Removing unused imports + - Use binary chop to estimate gas accurately ([#4100](https://github.com/paritytech/parity/pull/4100)) + - Initial sketch. + - Building. + - Fix a few things. + - Fix issue, add tracing. + - Address grumbles + - Raise upper limit if needed + - Fix test. + - Fixing decoding API with signatures in names ([#4125](https://github.com/paritytech/parity/pull/4125)) + - Fix call/estimate_gas ([#4121](https://github.com/paritytech/parity/pull/4121)) + - Return 0 instead of error with out of gas on estimate_gas + - Fix stuff up. +- Current release: 1.3 -> 1.4 [#4183](https://github.com/paritytech/parity/pull/4183) +- Fix rebroadcast panic [#4084](https://github.com/paritytech/parity/pull/4084) +- Use shallow-only rendering in all tests [#4087](https://github.com/paritytech/parity/pull/4087) +- Sending transactions in chunks [#4089](https://github.com/paritytech/parity/pull/4089) +- Move to new auto-update server. [#4091](https://github.com/paritytech/parity/pull/4091) +- Fixing compilation without dapps. [#4088](https://github.com/paritytech/parity/pull/4088) +- Fix balances update [#4077](https://github.com/paritytech/parity/pull/4077) +- Key derivation in Worker [#4071](https://github.com/paritytech/parity/pull/4071) +- Display contract block creation [#4069](https://github.com/paritytech/parity/pull/4069) +- Improving logs for transactions sync and disable re-broadcasting while syncing [#4065](https://github.com/paritytech/parity/pull/4065) +- Passwords are valid by default [#4075](https://github.com/paritytech/parity/pull/4075) +- Show Origin label to events table [#4073](https://github.com/paritytech/parity/pull/4073) +- Fix tags not working [#4070](https://github.com/paritytech/parity/pull/4070) +- Zero-alloc trie lookups [#3998](https://github.com/paritytech/parity/pull/3998) +- Opening local dapp [#4041](https://github.com/paritytech/parity/pull/4041) +- Bringing back `js-sha3` to fix in-browser signing [#4063](https://github.com/paritytech/parity/pull/4063) +- Fix wrong transaction input for contract deployments [#4052](https://github.com/paritytech/parity/pull/4052) +- Re-broadcast transactions to few random peers on each new block. [#4054](https://github.com/paritytech/parity/pull/4054) +- Removing old transactions from the queue [#4046](https://github.com/paritytech/parity/pull/4046) +- Add block rewards to more Engines [#4055](https://github.com/paritytech/parity/pull/4055) +- Return old trie values on insert and remove [#4053](https://github.com/paritytech/parity/pull/4053) +- Let users open urls from dapps view [#4042](https://github.com/paritytech/parity/pull/4042) +- Util/validation update [#4051](https://github.com/paritytech/parity/pull/4051) +- Convert ShapeShift modal to store [#4035](https://github.com/paritytech/parity/pull/4035) +- Using local path on Windows [#4017](https://github.com/paritytech/parity/pull/4017) +- Fixing minGasLimit > ceil limit mining issue [#4018](https://github.com/paritytech/parity/pull/4018) +- Naive light client synchronization [#3892](https://github.com/paritytech/parity/pull/3892) +- Starting on homestead shows reload snackbar [#4043](https://github.com/paritytech/parity/pull/4043) +- Show contract parameters in MethodDecoding [#4024](https://github.com/paritytech/parity/pull/4024) +- UI component updates [#4010](https://github.com/paritytech/parity/pull/4010) +- Account view updates [#4008](https://github.com/paritytech/parity/pull/4008) +- Better error messages for PoA chains [#4034](https://github.com/paritytech/parity/pull/4034) +- Make some spec fields optional [#4019](https://github.com/paritytech/parity/pull/4019) +- Basic account type [#4021](https://github.com/paritytech/parity/pull/4021) +- Fix wallet in main net [#4038](https://github.com/paritytech/parity/pull/4038) +- Removing orphaned Cargo.toml [#4032](https://github.com/paritytech/parity/pull/4032) +- Address selector: support reverse lookup [#4033](https://github.com/paritytech/parity/pull/4033) +- Only fetch App when necessary [#4023](https://github.com/paritytech/parity/pull/4023) +- Connection UI cleanups & tests for prior PR [#4020](https://github.com/paritytech/parity/pull/4020) +- Unsubscribe error on ShapeShift modal close [#4005](https://github.com/paritytech/parity/pull/4005) +- Add ownership checks the Registry dApp [#4001](https://github.com/paritytech/parity/pull/4001) +- Refresh balances of contacts & contracts when syncing [#4022](https://github.com/paritytech/parity/pull/4022) +- Show message on new chain [#4016](https://github.com/paritytech/parity/pull/4016) +- Use TypedInputs in Contracts view [#4015](https://github.com/paritytech/parity/pull/4015) +- Fix focus on Modal [#4014](https://github.com/paritytech/parity/pull/4014) +- Fix newError noops when not bound to dispacher [#4013](https://github.com/paritytech/parity/pull/4013) +- Parse testnet chain as ropsten [#4004](https://github.com/paritytech/parity/pull/4004) +- Work on Portal Style [#4003](https://github.com/paritytech/parity/pull/4003) +- Make Wallet first-class citizens [#3990](https://github.com/paritytech/parity/pull/3990) +- Don't slice non-existent tags [#4000](https://github.com/paritytech/parity/pull/4000) +- Update dev dependencies and make Webpack less verbose [#3997](https://github.com/paritytech/parity/pull/3997) +- Correct log index in transaction receipt [#3995](https://github.com/paritytech/parity/pull/3995) +- Add Email and Registry lookups to Address Selector [#3992](https://github.com/paritytech/parity/pull/3992) +- Remove node journal: dead code [#3994](https://github.com/paritytech/parity/pull/3994) +- Cleanup AddContract with store [#3981](https://github.com/paritytech/parity/pull/3981) +- Store for EditPassword Modal [#3979](https://github.com/paritytech/parity/pull/3979) +- Additional fetch tests [#3983](https://github.com/paritytech/parity/pull/3983) +- Owning views of blockchain data [#3982](https://github.com/paritytech/parity/pull/3982) +- Make test network generic over peer type [#3974](https://github.com/paritytech/parity/pull/3974) +- Fetch tests (first batch) [#3977](https://github.com/paritytech/parity/pull/3977) +- Fetch certifiers only when needed [#3978](https://github.com/paritytech/parity/pull/3978) +- Visible accounts for dapps (default whitelist) [#3898](https://github.com/paritytech/parity/pull/3898) +- Remove some old (unused/duplicate) files [#3975](https://github.com/paritytech/parity/pull/3975) +- Port `try` macro to new `?` operator. [#3962](https://github.com/paritytech/parity/pull/3962) +- Small UI fixes [#3966](https://github.com/paritytech/parity/pull/3966) +- Fix wrong use of Icons [#3973](https://github.com/paritytech/parity/pull/3973) +- Updating dependencies [#3968](https://github.com/paritytech/parity/pull/3968) +- Web Based Dapps [#3956](https://github.com/paritytech/parity/pull/3956) +- Contract query: render false as false [#3971](https://github.com/paritytech/parity/pull/3971) +- Email verification: add Terms of Service [#3970](https://github.com/paritytech/parity/pull/3970) +- Fix method decoding [#3967](https://github.com/paritytech/parity/pull/3967) +- Store for EditMeta modal [#3959](https://github.com/paritytech/parity/pull/3959) +- Registry dapp: cleanup, support reverse entries [#3933](https://github.com/paritytech/parity/pull/3933) +- New Address Selector Component [#3829](https://github.com/paritytech/parity/pull/3829) +- Limiting accounts returned by parity_accountInfo [#3931](https://github.com/paritytech/parity/pull/3931) +- Unknown block error for RPC [#3965](https://github.com/paritytech/parity/pull/3965) +- Remove unused fields in informant [#3963](https://github.com/paritytech/parity/pull/3963) +- Allow contract constructors in chain spec [#3932](https://github.com/paritytech/parity/pull/3932) +- Sync reorg up to history size [#3874](https://github.com/paritytech/parity/pull/3874) +- Rising the limit for fetch [#3964](https://github.com/paritytech/parity/pull/3964) +- Bring integer arithmetic up to crates.io [#3943](https://github.com/paritytech/parity/pull/3943) +- Eslint rule for block curlies [#3955](https://github.com/paritytech/parity/pull/3955) +- Gas exception warnings on deployment [#3938](https://github.com/paritytech/parity/pull/3938) +- Move verification store into modal [#3951](https://github.com/paritytech/parity/pull/3951) +- Allow setting of minBlock on sending [#3921](https://github.com/paritytech/parity/pull/3921) +- Allow empty address [#3961](https://github.com/paritytech/parity/pull/3961) +- Fix default import [#3960](https://github.com/paritytech/parity/pull/3960) +- Display 0x00..00 as null [#3950](https://github.com/paritytech/parity/pull/3950) +- Global Fetch Service [#3915](https://github.com/paritytech/parity/pull/3915) +- Update babel-loader for WebPack 2.2-rc [#3953](https://github.com/paritytech/parity/pull/3953) +- Fix Webpack build [#3946](https://github.com/paritytech/parity/pull/3946) +- Fix manual input token [#3945](https://github.com/paritytech/parity/pull/3945) +- Update Webpack [#3952](https://github.com/paritytech/parity/pull/3952) +- Add missing Ethcore -> Parity headers [#3948](https://github.com/paritytech/parity/pull/3948) +- Code example: do start before register_protocol [#3947](https://github.com/paritytech/parity/pull/3947) +- Set CHAIN_ID for Classic [#3934](https://github.com/paritytech/parity/pull/3934) +- Fixed compile error. [#3940](https://github.com/paritytech/parity/pull/3940) +- Fix dapps not loading [#3935](https://github.com/paritytech/parity/pull/3935) +- Fix Secure API hangs [#3927](https://github.com/paritytech/parity/pull/3927) +- Parity_chainStatus RPC for block gap info [#3899](https://github.com/paritytech/parity/pull/3899) +- Custom attribute for binary serialization [#3922](https://github.com/paritytech/parity/pull/3922) +- Split intermediate stage into two. [#3926](https://github.com/paritytech/parity/pull/3926) +- Move release-registering to intermediate stage. [#3920](https://github.com/paritytech/parity/pull/3920) +- Blocktime format rounding [#3894](https://github.com/paritytech/parity/pull/3894) +- Ignore dapps_policy.json [#3919](https://github.com/paritytech/parity/pull/3919) +- Fixing Contract Development [#3912](https://github.com/paritytech/parity/pull/3912) +- Use rhash for non-native CI platforms and submit build. [#3911](https://github.com/paritytech/parity/pull/3911) +- Remove -Zorbit=off from rustflags on windows [#3907](https://github.com/paritytech/parity/pull/3907) +- Fixed upgrading keys on the first run [#3904](https://github.com/paritytech/parity/pull/3904) +- Fix deadlock in queue drop [#3903](https://github.com/paritytech/parity/pull/3903) +- Require only simpler methods on Provider [#3897](https://github.com/paritytech/parity/pull/3897) +- Fix grammar ("you try" -> "you tried" + article) [#3902](https://github.com/paritytech/parity/pull/3902) +- Remove light server capability temporarily [#3872](https://github.com/paritytech/parity/pull/3872) +- Allow retry for future blocks [#3896](https://github.com/paritytech/parity/pull/3896) +- Consistent engine and seal names [#3895](https://github.com/paritytech/parity/pull/3895) +- Update email certification ABI [#3893](https://github.com/paritytech/parity/pull/3893) +- Remove existence & length checks on passwords & phrases [#3854](https://github.com/paritytech/parity/pull/3854) +- Refresh certifications automatically [#3878](https://github.com/paritytech/parity/pull/3878) +- Fix Wallet Settings Modal [#3856](https://github.com/paritytech/parity/pull/3856) +- Fix difficulty adjustment. [#3884](https://github.com/paritytech/parity/pull/3884) +- Final fixups for updater [#3883](https://github.com/paritytech/parity/pull/3883) +- Attempt to fix windows CI. [#3882](https://github.com/paritytech/parity/pull/3882) +- Fixing racy test [#3881](https://github.com/paritytech/parity/pull/3881) +- Fix updater permissions [#3880](https://github.com/paritytech/parity/pull/3880) +- Delayed transactions [#3865](https://github.com/paritytech/parity/pull/3865) +- Don't log auth token [#3853](https://github.com/paritytech/parity/pull/3853) +- Loading default config from default path [#3875](https://github.com/paritytech/parity/pull/3875) +- New paths [#3877](https://github.com/paritytech/parity/pull/3877) +- Update tests, gitlabci [#3876](https://github.com/paritytech/parity/pull/3876) +- Base directory option [#3868](https://github.com/paritytech/parity/pull/3868) +- Auto-updating [#3505](https://github.com/paritytech/parity/pull/3505) +- Fix naming collision [#3873](https://github.com/paritytech/parity/pull/3873) +- Get rid of unecessary redirection while fetching content [#3858](https://github.com/paritytech/parity/pull/3858) +- Fix verification stores [#3864](https://github.com/paritytech/parity/pull/3864) +- Store subscriptionId, align with main subscription model [#3863](https://github.com/paritytech/parity/pull/3863) +- Additional RPCs for dapps accounts management [#3792](https://github.com/paritytech/parity/pull/3792) +- Add Ws Json rpc client and command line utils (take 2) [#3830](https://github.com/paritytech/parity/pull/3830) +- Fix typo in method call (broken contract interface) [#3862](https://github.com/paritytech/parity/pull/3862) +- Fix flaky test [#3860](https://github.com/paritytech/parity/pull/3860) +- Converting traces API to AutoArgs [#3844](https://github.com/paritytech/parity/pull/3844) +- Get certifications from BadgeReg, show them in accounts overview [#3768](https://github.com/paritytech/parity/pull/3768) +- New directory structure [#3828](https://github.com/paritytech/parity/pull/3828) +- First run: skip account creation if they already have accounts [#3827](https://github.com/paritytech/parity/pull/3827) +- Tendermint seal [#3857](https://github.com/paritytech/parity/pull/3857) +- Tendermint Engine [#3759](https://github.com/paritytech/parity/pull/3759) +- Expand lint to catch css issues [#3852](https://github.com/paritytech/parity/pull/3852) +- Inject exports both partiy & web3 [#3851](https://github.com/paritytech/parity/pull/3851) +- Let Webpack talk again [#3848](https://github.com/paritytech/parity/pull/3848) +- AuthorityRound seal and simplify Generic seal Spec [#3843](https://github.com/paritytech/parity/pull/3843) +- Signing transactions with rotating token [#3691](https://github.com/paritytech/parity/pull/3691) +- Bump dev chain [#3835](https://github.com/paritytech/parity/pull/3835) +- Spelling [#3839](https://github.com/paritytech/parity/pull/3839) +- Email verification [#3766](https://github.com/paritytech/parity/pull/3766) +- Network configuration for Ethereum Classic [#3812](https://github.com/paritytech/parity/pull/3812) +- Using jsonrpc-macros [#3831](https://github.com/paritytech/parity/pull/3831) +- Fixed bool dropdown in contract execution [#3823](https://github.com/paritytech/parity/pull/3823) +- Avoid broadcasting transactions to peers that send them [#3796](https://github.com/paritytech/parity/pull/3796) +- Eth_sign RPC now hashes given data instead of getting the hash [#3800](https://github.com/paritytech/parity/pull/3800) +- Add store for MethodDecoding [#3821](https://github.com/paritytech/parity/pull/3821) +- Add store for AddAddress [#3819](https://github.com/paritytech/parity/pull/3819) +- Fix React-Router in i18n locale change [#3815](https://github.com/paritytech/parity/pull/3815) +- Cache fetched Dapps [#3804](https://github.com/paritytech/parity/pull/3804) +- Authors & homepage => Parity [#3818](https://github.com/paritytech/parity/pull/3818) +- Rename Ethcore -> Parity Technologies [#3817](https://github.com/paritytech/parity/pull/3817) +- Allow editing of gasPrice & gas in Signer [#3777](https://github.com/paritytech/parity/pull/3777) +- I18n string dictionaries [#3532](https://github.com/paritytech/parity/pull/3532) +- Fix padding in App [#3813](https://github.com/paritytech/parity/pull/3813) +- Light server improvements and protocol adjustments [#3801](https://github.com/paritytech/parity/pull/3801) +- Tolerate errors in user_defaults [#3810](https://github.com/paritytech/parity/pull/3810) +- Block: enforce gas limit falls within engine bounds [#3809](https://github.com/paritytech/parity/pull/3809) +- Target Babel to latest Chrome Versions in dev [#3806](https://github.com/paritytech/parity/pull/3806) +- Lowercase npm packages [#3807](https://github.com/paritytech/parity/pull/3807) +- Extended publishing of libraries to npm [#3786](https://github.com/paritytech/parity/pull/3786) +- Several Fixes to the UI [#3799](https://github.com/paritytech/parity/pull/3799) +- Remove "s [#3805](https://github.com/paritytech/parity/pull/3805) +- Extract CSS to file in production builds [#3783](https://github.com/paritytech/parity/pull/3783) +- Notify user on transaction received [#3782](https://github.com/paritytech/parity/pull/3782) +- Removing all old entries from transaction queue [#3772](https://github.com/paritytech/parity/pull/3772) +- Status page updates [#3774](https://github.com/paritytech/parity/pull/3774) +- Allow modifications of gas when confirming in signer [#3798](https://github.com/paritytech/parity/pull/3798) +- Network connectivity fixes [#3794](https://github.com/paritytech/parity/pull/3794) +- Make *ID names consistent with std Rust (Id) [#3781](https://github.com/paritytech/parity/pull/3781) +- Update CI builds [#3780](https://github.com/paritytech/parity/pull/3780) +- Update AuthorityRound tests to new spec [#3790](https://github.com/paritytech/parity/pull/3790) +- Fixes to the Wallet UI [#3787](https://github.com/paritytech/parity/pull/3787) +- Add support for wallets without getOwner() interface [#3779](https://github.com/paritytech/parity/pull/3779) +- Update Material-UI [#3785](https://github.com/paritytech/parity/pull/3785) +- Fixes error in Transfer modal [#3788](https://github.com/paritytech/parity/pull/3788) +- LES Part 3: Event handlers and handling responses [#3755](https://github.com/paritytech/parity/pull/3755) +- Basic UI rendering tests [#3743](https://github.com/paritytech/parity/pull/3743) +- Network: process packets only after connection handler finishes [#3776](https://github.com/paritytech/parity/pull/3776) +- AuthorityRound network simulation test [#3778](https://github.com/paritytech/parity/pull/3778) +- GasPrice selection for contract execution [#3770](https://github.com/paritytech/parity/pull/3770) +- Reject existing transactions [#3762](https://github.com/paritytech/parity/pull/3762) +- Allow autoRemove from api.subscribe based on callback return values [#3752](https://github.com/paritytech/parity/pull/3752) +- Replace misplaced & with && in gitlab-ci.yml [#3753](https://github.com/paritytech/parity/pull/3753) +- Lower gas usage for creating a Multisig Wallet [#3773](https://github.com/paritytech/parity/pull/3773) +- Added IO service explicit stop [#3761](https://github.com/paritytech/parity/pull/3761) +- Be lenient around invalid owners map [#3764](https://github.com/paritytech/parity/pull/3764) +- GasEditor component [#3750](https://github.com/paritytech/parity/pull/3750) +- Cleanups [#3742](https://github.com/paritytech/parity/pull/3742) +- Update babel, fix CI build due to breaking changes [#3754](https://github.com/paritytech/parity/pull/3754) +- Small fixes to contract [#3751](https://github.com/paritytech/parity/pull/3751) +- Make engine hold AccountProvider [#3725](https://github.com/paritytech/parity/pull/3725) +- Properly delete addresses/contracts in addressbook [#3739](https://github.com/paritytech/parity/pull/3739) +- Display Wallet Owners Icons in Accounts list [#3741](https://github.com/paritytech/parity/pull/3741) +- Edit Multisig Wallet settings [#3740](https://github.com/paritytech/parity/pull/3740) +- Replace build directory completely [#3748](https://github.com/paritytech/parity/pull/3748) +- Add existing release files before merge [#3747](https://github.com/paritytech/parity/pull/3747) +- Release script back to using fetch/merge [#3746](https://github.com/paritytech/parity/pull/3746) +- Update with -X only for merge [#3745](https://github.com/paritytech/parity/pull/3745) +- Give accounts precedence over address_book entries [#3732](https://github.com/paritytech/parity/pull/3732) +- Enable Panic=abort [#3423](https://github.com/paritytech/parity/pull/3423) +- Cleanups on js-precompiled [#3738](https://github.com/paritytech/parity/pull/3738) +- Add parity_removeAddress RPC [#3735](https://github.com/paritytech/parity/pull/3735) +- Fix up the transaction JSON serialisation for RPC. [#3633](https://github.com/paritytech/parity/pull/3633) +- Queue: CLI for auto-scaling and num verifiers [#3709](https://github.com/paritytech/parity/pull/3709) +- Add functionalities to multi-sig wallet [#3729](https://github.com/paritytech/parity/pull/3729) +- PropTypes as function call [#3731](https://github.com/paritytech/parity/pull/3731) +- Unify proptypes in util/proptypes.js [#3728](https://github.com/paritytech/parity/pull/3728) +- Bump jsonrpc-ipc-server to fix windows build [#3730](https://github.com/paritytech/parity/pull/3730) +- LES Part 2 [#3527](https://github.com/paritytech/parity/pull/3527) +- First draft of the MultiSig Wallet [#3700](https://github.com/paritytech/parity/pull/3700) +- Engine block ordering [#3719](https://github.com/paritytech/parity/pull/3719) +- Use fdlimit utility crate from crates.io [#3716](https://github.com/paritytech/parity/pull/3716) +- Move decoding for contract deployment logic earlier [#3714](https://github.com/paritytech/parity/pull/3714) +- Possible fix for queue drop deadlock [#3702](https://github.com/paritytech/parity/pull/3702) +- Encode networkid as a u64. [#3713](https://github.com/paritytech/parity/pull/3713) +- Use valid RLP in generic genesis seal spec [#3717](https://github.com/paritytech/parity/pull/3717) +- Update JS dependencies [#3710](https://github.com/paritytech/parity/pull/3710) +- Use Webpack Aliases [#3711](https://github.com/paritytech/parity/pull/3711) +- Dapps-specific accounts [#3627](https://github.com/paritytech/parity/pull/3627) +- Signer method parameter decoding & destination info [#3671](https://github.com/paritytech/parity/pull/3671) +- Remove invalid slice test [#3712](https://github.com/paritytech/parity/pull/3712) +- React library update [#3704](https://github.com/paritytech/parity/pull/3704) +- New Loading Component for the UI [#3707](https://github.com/paritytech/parity/pull/3707) +- Refactoring Transfer Modal [#3705](https://github.com/paritytech/parity/pull/3705) +- Fix extra scrollbars in dapps [#3706](https://github.com/paritytech/parity/pull/3706) +- Indent state tests [#3431](https://github.com/paritytech/parity/pull/3431) +- Filter null transactions for display (not available on node) [#3698](https://github.com/paritytech/parity/pull/3698) +- Move recovery phrase print button [#3697](https://github.com/paritytech/parity/pull/3697) +- Fix padding bottom needed after fixed status [#3701](https://github.com/paritytech/parity/pull/3701) +- Don't share the snapshot while downloading old blocks [#3695](https://github.com/paritytech/parity/pull/3695) +- Button to print recovery phrase [#3694](https://github.com/paritytech/parity/pull/3694) +- Fix status bar to bottom of the screen [#3692](https://github.com/paritytech/parity/pull/3692) +- Splitting serialization of signTransaction and sendTransaction confirmation requests [#3642](https://github.com/paritytech/parity/pull/3642) +- Implement basic badges/certifications/flair [#3665](https://github.com/paritytech/parity/pull/3665) +- Simplify Container title rendering [#3680](https://github.com/paritytech/parity/pull/3680) +- Update loading splash to fit in with l&f [#3685](https://github.com/paritytech/parity/pull/3685) +- Safari UI fixes [#3678](https://github.com/paritytech/parity/pull/3678) +- Remove strict mode for DappReg (work-around for package upgrade) [#3681](https://github.com/paritytech/parity/pull/3681) +- Bumping clippy [#3654](https://github.com/paritytech/parity/pull/3654) +- Return of the Fat DB [#3636](https://github.com/paritytech/parity/pull/3636) +- Invalidate blocks from future [#3652](https://github.com/paritytech/parity/pull/3652) +- Make Modal always scrollable [#3667](https://github.com/paritytech/parity/pull/3667) +- Display local/completed transactions [#3630](https://github.com/paritytech/parity/pull/3630) +- Added build-essential dep to dockerfiles [#3666](https://github.com/paritytech/parity/pull/3666) +- Strict config parsing (uknown keys are rejected) [#3663](https://github.com/paritytech/parity/pull/3663) +- Strict deserialization [#3662](https://github.com/paritytech/parity/pull/3662) +- Disable peer if no common block found [#3655](https://github.com/paritytech/parity/pull/3655) +- Show snackbar on password change [#3661](https://github.com/paritytech/parity/pull/3661) +- Bring back PV62 support [#3660](https://github.com/paritytech/parity/pull/3660) +- Unlock expecting quantity [#3659](https://github.com/paritytech/parity/pull/3659) +- Update Webpack => v2 [#3643](https://github.com/paritytech/parity/pull/3643) +- Update SMS verification [#3579](https://github.com/paritytech/parity/pull/3579) +- Simplify tx confirmations display [#3559](https://github.com/paritytech/parity/pull/3559) +- Fixes overflow in Signer tx data [#3657](https://github.com/paritytech/parity/pull/3657) +- Fixed tab bar not updating [#3653](https://github.com/paritytech/parity/pull/3653) +- Set default min tx price to $0.0025 [#3617](https://github.com/paritytech/parity/pull/3617) +- Use accountsInfo instead of eth_accounts for first check [#3618](https://github.com/paritytech/parity/pull/3618) +- Fix Copy to Clipboard Snackbar [#3619](https://github.com/paritytech/parity/pull/3619) +- Manually add \r to Windows phrases pre 1.4.5 [#3615](https://github.com/paritytech/parity/pull/3615) +- Signer layouts to flexbox [#3600](https://github.com/paritytech/parity/pull/3600) +- Fixing wrong tokens type in Redux store [#3621](https://github.com/paritytech/parity/pull/3621) +- Add dappreg link to apps list [#3568](https://github.com/paritytech/parity/pull/3568) +- Smarter balance fetching [#3605](https://github.com/paritytech/parity/pull/3605) +- Dapp iframe allow forms, allow target=_blank [#3597](https://github.com/paritytech/parity/pull/3597) +- Align copy button to input field [#3604](https://github.com/paritytech/parity/pull/3604) +- Appending logs by default [#3609](https://github.com/paritytech/parity/pull/3609) +- Update test, fix number. [#3612](https://github.com/paritytech/parity/pull/3612) +- Fixing phrases generated on windows [#3614](https://github.com/paritytech/parity/pull/3614) +- Check for network ID for live/test matching [#3602](https://github.com/paritytech/parity/pull/3602) +- Always insert traces for genesis. [#3603](https://github.com/paritytech/parity/pull/3603) +- Real deleting accounts [#3540](https://github.com/paritytech/parity/pull/3540) +- Trim whitespace from input recovery phrase [#3599](https://github.com/paritytech/parity/pull/3599) +- Fix local tx requests [#3589](https://github.com/paritytech/parity/pull/3589) +- Fix CPU usage when idle [#3592](https://github.com/paritytech/parity/pull/3592) +- Don't fetch balances on every new block if syncing [#3591](https://github.com/paritytech/parity/pull/3591) +- Work around WS in UI [#3587](https://github.com/paritytech/parity/pull/3587) +- CLI option to disable ancient block downloading [#3573](https://github.com/paritytech/parity/pull/3573) +- Move Signer balance queries to store for component-wide re-use [#3531](https://github.com/paritytech/parity/pull/3531) +- Fix wrong method name in `contract.js` [#3580](https://github.com/paritytech/parity/pull/3580) +- Smarter Tokens fetching [#3546](https://github.com/paritytech/parity/pull/3546) +- Fix panic on importing own invalid transaction [#3550](https://github.com/paritytech/parity/pull/3550) +- Use an adaptive number of threads in the verification queue [#2445](https://github.com/paritytech/parity/pull/2445) +- Faster UI - React Tweaks [#3555](https://github.com/paritytech/parity/pull/3555) +- Send value & contract execute gas limit warnings [#3512](https://github.com/paritytech/parity/pull/3512) +- Add TxQueue visibility specifier (not added between merges) [#3566](https://github.com/paritytech/parity/pull/3566) +- DappRegistry [#3405](https://github.com/paritytech/parity/pull/3405) +- Import account message [#3552](https://github.com/paritytech/parity/pull/3552) +- --testnet set to ropsten [#3551](https://github.com/paritytech/parity/pull/3551) +- Fix flaky test [#3547](https://github.com/paritytech/parity/pull/3547) +- Sms verification code style [#3564](https://github.com/paritytech/parity/pull/3564) +- [Registry] Clear input and working buttons [#3563](https://github.com/paritytech/parity/pull/3563) +- Fix peers not displaying [#3561](https://github.com/paritytech/parity/pull/3561) +- New registry contract address for ropsten [#3549](https://github.com/paritytech/parity/pull/3549) +- Use contract Registry fee, not a hard-coded value [#3554](https://github.com/paritytech/parity/pull/3554) +- Don't query chain in Signer, use Redux isTest [#3524](https://github.com/paritytech/parity/pull/3524) +- Moving fetching of hash-addressed dapps/content to separate crate. [#3543](https://github.com/paritytech/parity/pull/3543) +- Ropsten network [#3539](https://github.com/paritytech/parity/pull/3539) +- Add simple one-line installer to README.md [#3534](https://github.com/paritytech/parity/pull/3534) +- Propagations & local transactions tracking [#3491](https://github.com/paritytech/parity/pull/3491) +- Correct format of eth_signTransaction [#3503](https://github.com/paritytech/parity/pull/3503) +- ABI can be empty and auto-fill contract name [#3518](https://github.com/paritytech/parity/pull/3518) +- Fix versions for NPM [#3516](https://github.com/paritytech/parity/pull/3516) +- Better GHH event display & tracking [#3498](https://github.com/paritytech/parity/pull/3498) +- Dapp section & visibility changes [#3438](https://github.com/paritytech/parity/pull/3438) +- Fix parity.js badly built [#3526](https://github.com/paritytech/parity/pull/3526) +- Updated the european warp bootnode addresses [#3528](https://github.com/paritytech/parity/pull/3528) +- Limit sync reorg to 20 blocks [#3519](https://github.com/paritytech/parity/pull/3519) +- Revert "Limit sync reorganization to 20 blocks" [#3517](https://github.com/paritytech/parity/pull/3517) +- Check transaction signature when adding to the queue [#3508](https://github.com/paritytech/parity/pull/3508) +- Limit sync reorganization to 20 blocks [#3509](https://github.com/paritytech/parity/pull/3509) +- Keep track of block gasLimit [#3506](https://github.com/paritytech/parity/pull/3506) +- Smarter Status Polling [#3504](https://github.com/paritytech/parity/pull/3504) +- Handle solc combined output [#3496](https://github.com/paritytech/parity/pull/3496) +- Wallet names shouldn't use UUID [#3481](https://github.com/paritytech/parity/pull/3481) +- Make parity.js usable by Node and Browser [#3475](https://github.com/paritytech/parity/pull/3475) +- Sms verification modal [#3336](https://github.com/paritytech/parity/pull/3336) +- Sudo -c is not supported on Mac [#3488](https://github.com/paritytech/parity/pull/3488) +- Add trace_{call, rawTransaction, replayTransaction} [#3492](https://github.com/paritytech/parity/pull/3492) +- Check for possible panics in scrypt key derivation [#3490](https://github.com/paritytech/parity/pull/3490) +- Sync traffic optimization [#3477](https://github.com/paritytech/parity/pull/3477) +- Wallet files shouldn't give away the address [#3378](https://github.com/paritytech/parity/pull/3378) +- Fixing tests, fixing refreshing precompiled [#3483](https://github.com/paritytech/parity/pull/3483) +- Better Errors Snackbar in UI [#3478](https://github.com/paritytech/parity/pull/3478) +- Handle Signer Rejection [#3476](https://github.com/paritytech/parity/pull/3476) +- Enhanced MethodDecoding in Transactions list [#3454](https://github.com/paritytech/parity/pull/3454) +- Signer new-token generates a link and opens browser [#3379](https://github.com/paritytech/parity/pull/3379) +- Make tokenreg dapp fast again [#3474](https://github.com/paritytech/parity/pull/3474) +- Build fix [#3470](https://github.com/paritytech/parity/pull/3470) +- Display deployed Basic token addresses [#3447](https://github.com/paritytech/parity/pull/3447) +- Export accounts as JSON or CSV [#2866](https://github.com/paritytech/parity/pull/2866) +- Set HF2 block number [#3466](https://github.com/paritytech/parity/pull/3466) +- Better word list for secret phrase generation [#3461](https://github.com/paritytech/parity/pull/3461) +- Drop spec when no longer useful [#3460](https://github.com/paritytech/parity/pull/3460) +- Add fallback check in ABI validation [#3459](https://github.com/paritytech/parity/pull/3459) +- Save sort order in LocalStorage [#3457](https://github.com/paritytech/parity/pull/3457) +- Adds onPaste event to Inputs [#3456](https://github.com/paritytech/parity/pull/3456) +- Update signer to take care of text overflows [#3450](https://github.com/paritytech/parity/pull/3450) +- Authority round consensus engine [#3426](https://github.com/paritytech/parity/pull/3426) +- Fix transfer token decimal calculation [#3445](https://github.com/paritytech/parity/pull/3445) +- Restrict max code size for EIP-150 and after. [#3363](https://github.com/paritytech/parity/pull/3363) +- Contract queries should display IdentityIcons [#3453](https://github.com/paritytech/parity/pull/3453) +- Use Babel in vendor when needed [#3451](https://github.com/paritytech/parity/pull/3451) +- Use signature of functions instead of names [#3448](https://github.com/paritytech/parity/pull/3448) +- Handle contract constructor inputs [#3430](https://github.com/paritytech/parity/pull/3430) +- Use Contract owner for unregistering Token [#3446](https://github.com/paritytech/parity/pull/3446) +- Create directories only if feature is enabled [#3442](https://github.com/paritytech/parity/pull/3442) +- Import AddresBook from exported JSON [#3433](https://github.com/paritytech/parity/pull/3433) +- Scrollable accounts in autocomplete [#3427](https://github.com/paritytech/parity/pull/3427) +- Bump ws-rs [#3428](https://github.com/paritytech/parity/pull/3428) +- Swap TokenReg dapp from base to decimals [#3425](https://github.com/paritytech/parity/pull/3425) +- Change beta builds to stable on Travis [#3421](https://github.com/paritytech/parity/pull/3421) +- Refactor copy to clipboard functionality [#3420](https://github.com/paritytech/parity/pull/3420) +- Dev chain [#3385](https://github.com/paritytech/parity/pull/3385) +- Fetch known code from the database during restoration [#3377](https://github.com/paritytech/parity/pull/3377) +- Fixing benches [#3422](https://github.com/paritytech/parity/pull/3422) +- Fix chainspec storage field. [#3406](https://github.com/paritytech/parity/pull/3406) +- Abort snapshot restoration faster [#3356](https://github.com/paritytech/parity/pull/3356) +- Remove addresses, display non-refundable warning on registries [#3403](https://github.com/paritytech/parity/pull/3403) +- Don't auto-unsubscribe when subscriber callback throws [#3401](https://github.com/paritytech/parity/pull/3401) +- Fix dapp account selection [#3399](https://github.com/paritytech/parity/pull/3399) +- Fix travis build: remove unused import [#3381](https://github.com/paritytech/parity/pull/3381) +- Optimize memory footprint [#3376](https://github.com/paritytech/parity/pull/3376) +- Fixing parsing passwords from file [#3367](https://github.com/paritytech/parity/pull/3367) +- Remove some unwraps from parity/helpers [#3364](https://github.com/paritytech/parity/pull/3364) +- Load external, builtin & local apps in parallel [#3340](https://github.com/paritytech/parity/pull/3340) +- Solidity Compiler in UI [#3279](https://github.com/paritytech/parity/pull/3279) +- Determine real-time HTTP connected status [#3335](https://github.com/paritytech/parity/pull/3335) +- Clarify error message about disabled Signer [#3359](https://github.com/paritytech/parity/pull/3359) +- Cater for home.parity hostname in dappsUrl [#3341](https://github.com/paritytech/parity/pull/3341) +- Make sure Token is ECR20 [#3347](https://github.com/paritytech/parity/pull/3347) +- [TokenReg dApp] Fixed Unregister for Contract Owner only [#3346](https://github.com/paritytech/parity/pull/3346) +- LES Part 1 [#3322](https://github.com/paritytech/parity/pull/3322) +- Make transactions load [#3348](https://github.com/paritytech/parity/pull/3348) +- Manual bump package.json [#3345](https://github.com/paritytech/parity/pull/3345) +- Windows app and installer fixes [#3338](https://github.com/paritytech/parity/pull/3338) +- Fix JS API test [#3342](https://github.com/paritytech/parity/pull/3342) +- Git pre-push checks for UI [#3072](https://github.com/paritytech/parity/pull/3072) +- Disarm the HF and add more bootnodes [#3323](https://github.com/paritytech/parity/pull/3323) +- Default contract type on UI [#3310](https://github.com/paritytech/parity/pull/3310) +- In-browser signing support [#3231](https://github.com/paritytech/parity/pull/3231) +- Handle redirects from /api/content on manifest.json gracefully [#3315](https://github.com/paritytech/parity/pull/3315) +- Dapps interface RPC [#3311](https://github.com/paritytech/parity/pull/3311) +- Additional snapshot sync checks [#3318](https://github.com/paritytech/parity/pull/3318) +- Fix spurious signer tests failures [#3312](https://github.com/paritytech/parity/pull/3312) +- Fix signer token updates [#3302](https://github.com/paritytech/parity/pull/3302) +- Update account recovery phrase hint [#3316](https://github.com/paritytech/parity/pull/3316) +- New transaction tests [#3313](https://github.com/paritytech/parity/pull/3313) +- Remove 127.0.0.1 references [#3303](https://github.com/paritytech/parity/pull/3303) +- Fix for opening UI after installation on mac [#3300](https://github.com/paritytech/parity/pull/3300) +- Fixed uncle query [#3299](https://github.com/paritytech/parity/pull/3299) +- Updated blance display with max decimals [#3266](https://github.com/paritytech/parity/pull/3266) +- Refactoring Signer to auto_args + eth_signTransaction [#3261](https://github.com/paritytech/parity/pull/3261) +- Fix typo [#3298](https://github.com/paritytech/parity/pull/3298) +- Change to more common focused spelling [#3264](https://github.com/paritytech/parity/pull/3264) +- Manual bump of package.json (recovery) [#3295](https://github.com/paritytech/parity/pull/3295) +- Fix initial token generation [#3289](https://github.com/paritytech/parity/pull/3289) +- Fixed IO service shutdown [#3286](https://github.com/paritytech/parity/pull/3286) +- Autostart setting for windows tray app [#3269](https://github.com/paritytech/parity/pull/3269) +- Fixes for 1.4 [#3260](https://github.com/paritytech/parity/pull/3260) +- Build tray app for x64 [#3255](https://github.com/paritytech/parity/pull/3255) +- Add secure flag back [#3244](https://github.com/paritytech/parity/pull/3244) +- Verify chunk hashes in cli restore [#3241](https://github.com/paritytech/parity/pull/3241) +- Load network apps manifests as contentHash (no coding) [#3235](https://github.com/paritytech/parity/pull/3235) +- Fixed some typos [#3236](https://github.com/paritytech/parity/pull/3236) +- Rename cli and config options signer->ui [#3232](https://github.com/paritytech/parity/pull/3232) +- Add store for dapps state [#3211](https://github.com/paritytech/parity/pull/3211) +- Fix first-time tagging of contracts [#3222](https://github.com/paritytech/parity/pull/3222) +- Fix /parity-utils/{web3,parity}.js webpack errors [#3221](https://github.com/paritytech/parity/pull/3221) +- Improve 'invalid raw key' error msg [#3219](https://github.com/paritytech/parity/pull/3219) +- Cleaning up polluted namespaces [#3143](https://github.com/paritytech/parity/pull/3143) +- Set passive mode for first run only [#3214](https://github.com/paritytech/parity/pull/3214) +- Parity configuration settings, i.e. mode [#3212](https://github.com/paritytech/parity/pull/3212) +- Ethash unsafety cleanup [#3210](https://github.com/paritytech/parity/pull/3210) +- Mode improvements for UI [#3109](https://github.com/paritytech/parity/pull/3109) +- Delay bomb for Classic (ECIP-1010) [#3179](https://github.com/paritytech/parity/pull/3179) +- Use ethcore_dappsPort when constructing URLs [#3139](https://github.com/paritytech/parity/pull/3139) +- Add copy address button to Contract deploy [#3199](https://github.com/paritytech/parity/pull/3199) +- Expose Parity api as window.secureApi [#3207](https://github.com/paritytech/parity/pull/3207) +- Add error for sendRawTransaction and estimateGas [#3194](https://github.com/paritytech/parity/pull/3194) +- Exposing engine extra info in block RPC [#3169](https://github.com/paritytech/parity/pull/3169) +- V1.5 [#3195](https://github.com/paritytech/parity/pull/3195) +- Remove dapp logos (GHH points to dapp-assets) [#3192](https://github.com/paritytech/parity/pull/3192) +- Fixing possible race in ethcore_hashContent [#3191](https://github.com/paritytech/parity/pull/3191) +- Bump package.json version (1.5 is master) [#3193](https://github.com/paritytech/parity/pull/3193) + +## Parity [v1.4.10](https://github.com/paritytech/parity/releases/tag/v1.4.10) (2017-01-18) + +Parity 1.4.10 is a first stable release of 1.4.x series. It includes a few minor networking fixes. + +- Gas_limit for blocks, mined by Parity will be divisible by 37 (#4154) [#4179](https://github.com/paritytech/parity/pull/4179) + - gas_limit for new blocks will divide evenly by 13 + - increased PARITY_GAS_LIMIT_DETERMINANT to 37 + - separate method for marking mined block + - debug_asserts(gas_limit within protocol range) + - round_block_gas_limit method is now static + - made round_block_gas_limit free-function + - multiplier->multiple +- Backporing to 1.4.10-stable [#4110](https://github.com/paritytech/parity/pull/4110) + - Bump to v1.4.10 + - No reorg limit for ancient blocks + - Update registration after every write + +## Parity [v1.4.9](https://github.com/paritytech/parity/releases/tag/v1.4.9) (2017-01-09) + +This fixes an issue introduced in 1.4.8 that causes Parity to panic on propagating transactions in some cases. + +- v1.4.9 in beta [#4097](https://github.com/paritytech/parity/pull/4097) + - Bump to v1.4.9 + - Disable armv6 build +- beta Fix queue deadlock [#4095](https://github.com/paritytech/parity/pull/4095) +- Fix rebroadcast panic beta [#4085](https://github.com/paritytech/parity/pull/4085) + - fix compile + - fix backport + - clean up old method + - remove unnecessary reference + - simplify + - Fixing 'simplify' + +## Parity [v1.4.8](https://github.com/paritytech/parity/releases/tag/v1.4.8) (2017-01-06) + +Ethereum Classic Hard Fork ready release containing various bugfixes: + +- Fix for excessive transactions propagation +- Fix for inconsistent `logIndex` in transaction receipts + +See [full list of changes](https://github.com/paritytech/parity/compare/v1.4.7...v1.4.8): + +- Beta backports [#4067](https://github.com/paritytech/parity/pull/4067) +- Re-broadcast transactions to few random peers on each new block. (#4054) [#4061](https://github.com/paritytech/parity/pull/4061) +- Tolerate errors in user_defaults [#4060](https://github.com/paritytech/parity/pull/4060) +- ETC Config change backport [#4056](https://github.com/paritytech/parity/pull/4056) +- [beta] Avoid re-broadcasting transactions on each block [#4047](https://github.com/paritytech/parity/pull/4047) +- Beta Backports [#4012](https://github.com/paritytech/parity/pull/4012) + +## Parity [v1.4.7](https://github.com/paritytech/parity/releases/tag/v1.4.7) (2016-12-27) + +This maintenance release fixes an issue with sync falling behind occasionally. + +- Backporting to beta [#3980](https://github.com/paritytech/parity/pull/3980) +- [beta] enforce gas limit falls within engine bounds [#3816](https://github.com/paritytech/parity/pull/3816) + + +## Parity [v1.3.15](https://github.com/paritytech/parity/releases/tag/v1.3.15) (2016-12-10) + +This patch release fixes an issue with syncing on the Ropsten test network. + +- Backporting to stable [#3793](https://github.com/paritytech/parity/pull/3793) + +## Parity [v1.4.6](https://github.com/paritytech/parity/releases/tag/v1.4.6) (2016-12-05) + +This patch release fixes an issue with syncing on the Ropsten test network. + +- Backporting to beta [#3718](https://github.com/paritytech/parity/pull/3718) +- [beta] scrollable contract deploy & execute modals [#3656](https://github.com/paritytech/parity/pull/3656) + +## Parity [v1.4.5](https://github.com/paritytech/parity/releases/tag/v1.4.5) (2016-11-26) + +1.4.5 release fixes a number of issues, notably: +- High CPU usage when idle. +- Key recovery phrases generated on windows now can be imported. + +#### Configuration changes +- `--usd-per-tx` is now set to 0.0025 by default. + +#### New features +- Support for Ropsten test network is introduced with `--chain=ropsten` or `--testnet`. Morden network is still available via `--chain=morden` + +#### Full changes +- [beta] Pin package versions for React [#3628](https://github.com/paritytech/parity/pull/3628) +- Backporting to beta [#3623](https://github.com/paritytech/parity/pull/3623) +- [beta] Ropsten chain for UI [#3622](https://github.com/paritytech/parity/pull/3622) + +## Parity [v1.3.14](https://github.com/paritytech/parity/releases/tag/v1.3.14) (2016-11-25) + +Parity 1.3.14 fixes a few stability issues and adds support for the Ropsten testnet. + +- Backporting to stable [#3616](https://github.com/paritytech/parity/pull/3616) + +## Parity [v1.4.4](https://github.com/paritytech/parity/releases/tag/v1.4.4) (2016-11-18) + +This is a maintenance release that fixes an issue with EIP-155 transactions being added to the transaction pool. It also improves syncing stability and resolved a number of UI issues. +Full changelog is available [here.](https://github.com/paritytech/parity/commit/3e0d033eaf789cfdf517f4a97effc500f1f9263b) + +- [beta] apps typo fix [#3533](https://github.com/paritytech/parity/pull/3533) +- Backporting to beta [#3525](https://github.com/paritytech/parity/pull/3525) + +## Parity [v1.3.13](https://github.com/paritytech/parity/releases/tag/v1.3.13) (2016-11-18) + +This release fixes an issue with EIP-155 transactions being allowed into the transaction pool. + +- [stable] Check tx signatures before adding to the queue. [#3521](https://github.com/paritytech/parity/pull/3521) +- Fix Stable Docker Build [#3479](https://github.com/paritytech/parity/pull/3479) + +## Parity [v1.4.3](https://github.com/paritytech/parity/releases/tag/v1.4.3) (2016-11-16) + +This release includes memory footprint optimization as well as a few fixes in the UI. +EIP-155/160/161/170 hardfork is enabled at block 2675000 (1885000 for test network). +Full changelog is available [here.](https://github.com/paritytech/parity/compare/v1.4.2...v1.4.3) + +- [beta] EIP-170 [#3464](https://github.com/paritytech/parity/pull/3464) +- Backports to beta [#3465](https://github.com/paritytech/parity/pull/3465) +- Backport: additional fields on transaction and receipt [#3463](https://github.com/paritytech/parity/pull/3463) +- v1.4.3 in beta [#3424](https://github.com/paritytech/parity/pull/3424) + + +## Parity [v1.3.12](https://github.com/paritytech/parity/releases/tag/v1.3.12) (2016-11-16) + +This stable release enables EIP-155/160/161/170 hardfork at block 2675000 (1885000 for test network). + +- [stable] EIP-170 [#3462](https://github.com/paritytech/parity/pull/3462) +- #3035 Backport to stable [#3441](https://github.com/paritytech/parity/pull/3441) + +## Parity [v1.3.11](https://github.com/paritytech/parity/releases/tag/v1.3.11) (2016-11-11) + +This is a maintenance release for the stable series to delay the EIP-155/160/161 hard fork transition. **Update from 1.3.10 is mandatory**. It also deprecates and disables the old Parity UI. + +- [stable] Disable HF and UI [#3372](https://github.com/paritytech/parity/pull/3372) +- [stable] EIP-155 update with Vitalik's new test vectors (#3166) [#3190](https://github.com/paritytech/parity/pull/3190) +- Backport EIP-150 to stable [#2672](https://github.com/paritytech/parity/pull/2672) +- Create gitlab-ci.yml for stable [#2517](https://github.com/paritytech/parity/pull/2517) + +## Parity [v1.4.2](https://github.com/paritytech/parity/releases/tag/v1.4.2) (2016-11-10) + +This release fixes a few additional issues: +- Parity now correctly handles external `--dapps-interface` and `--ui-interface` in the UI. +- Crash in `eth_getUncle*` has been fixed. +- macOS installer now includes an uninstall script. +- Security token input UI has been fixed. +- Correct display for tokens with minimum decimals. + +And some additional minor changes. Full changelog is [available](https://github.com/paritytech/parity/compare/v1.4.1...v1.4.2) +- Backporting to beta [#3344](https://github.com/paritytech/parity/pull/3344) +- Backporting to beta [#3324](https://github.com/paritytech/parity/pull/3324) + +## Parity [v1.4.1](https://github.com/paritytech/parity/releases/tag/v1.4.1) (2016-11-09) + +This is a hotfix release to address a couple of issues with 1.4.0: + +- UI token is requested instead of being supplied automatically. +- Running with `--geth` results in an error. + +- Backporting to beta [#3293](https://github.com/paritytech/parity/pull/3293) + +## Parity [v1.4.0](https://github.com/paritytech/parity/releases/tag/v1.4.0) (2016-11-07) + +First beta release of the 1.4 series. + +This includes the new Parity Wallet and Warp-Sync synchronisation as well as several optimisations and fixes. + +- Add secure flag back [#3246](https://github.com/paritytech/parity/pull/3246) +- [BETA] verify chunk hashes in cli restore [#3242](https://github.com/paritytech/parity/pull/3242) +- Backporting to beta [#3239](https://github.com/paritytech/parity/pull/3239) +- UI fixes backporting [#3234](https://github.com/paritytech/parity/pull/3234) +- Backporting to beta [#3229](https://github.com/paritytech/parity/pull/3229) +- Beta branch cleanup [#3226](https://github.com/paritytech/parity/pull/3226) +- [beta] Set passive mode for first run only (#3214) [#3216](https://github.com/paritytech/parity/pull/3216) +- Mode configuration backported to beta [#3213](https://github.com/paritytech/parity/pull/3213) +- Backporting [#3198](https://github.com/paritytech/parity/pull/3198) +- [beta] EIP-155 update with Vitalik's new test vectors (#3166) [#3189](https://github.com/paritytech/parity/pull/3189) +- Backporting to beta [#3176](https://github.com/paritytech/parity/pull/3176) +- parity-ui-precompiled pinned to beta [#3168](https://github.com/paritytech/parity/pull/3168) +- EIP-155 update with Vitalik's new test vectors [#3166](https://github.com/paritytech/parity/pull/3166) +- Push precompiled for beta/stable, npm only master [#3163](https://github.com/paritytech/parity/pull/3163) +- Back to real root after npm publish [#3178](https://github.com/paritytech/parity/pull/3178) +- Remove extra cd js [#3177](https://github.com/paritytech/parity/pull/3177) +- Fixes Gas price selection bug [#3175](https://github.com/paritytech/parity/pull/3175) +- Exposing state root and logsBloom in RPC receipts [#3174](https://github.com/paritytech/parity/pull/3174) +- Exposing v,r,s from transaction signature in RPC [#3172](https://github.com/paritytech/parity/pull/3172) +- Enabling personal RPC over IPC by default [#3165](https://github.com/paritytech/parity/pull/3165) +- Gitlab CI badge [#3164](https://github.com/paritytech/parity/pull/3164) +- Dependencies in README [#3162](https://github.com/paritytech/parity/pull/3162) +- Make the footer a bit less ugly. [#3160](https://github.com/paritytech/parity/pull/3160) +- Linux build case sensitivity fix [#3161](https://github.com/paritytech/parity/pull/3161) +- abbreviated enode, `CopyToClipboard` component [#3131](https://github.com/paritytech/parity/pull/3131) +- EIPs 155, 160, 161 [#2976](https://github.com/paritytech/parity/pull/2976) +- beta reset to 1.4.0 [#3157](https://github.com/paritytech/parity/pull/3157) +- Fix histogram [#3150](https://github.com/paritytech/parity/pull/3150) +- Remove network label from TabBar [#3142](https://github.com/paritytech/parity/pull/3142) +- Speed up unresponsive Contract events & Account transactions [#3145](https://github.com/paritytech/parity/pull/3145) +- Better windows shortcut [#3147](https://github.com/paritytech/parity/pull/3147) +- Redirect content to the same address as requested [#3133](https://github.com/paritytech/parity/pull/3133) +- Fixed peer ping timeout [#3137](https://github.com/paritytech/parity/pull/3137) +- Fix for windows build [#3125](https://github.com/paritytech/parity/pull/3125) +- Fix AddessInput icon position [#3132](https://github.com/paritytech/parity/pull/3132) +- Fixed not scrollable accounts in tokenreg dapp [#3128](https://github.com/paritytech/parity/pull/3128) +- Returning cache headers for network content [#3123](https://github.com/paritytech/parity/pull/3123) +- Optimise contract events display [#3120](https://github.com/paritytech/parity/pull/3120) +- Add basic validation for contract execute values [#3118](https://github.com/paritytech/parity/pull/3118) +- Dapps errors embeddable on signer [#3115](https://github.com/paritytech/parity/pull/3115) +- Use enode RPC in UI [#3108](https://github.com/paritytech/parity/pull/3108) +- Windows tray app [#3103](https://github.com/paritytech/parity/pull/3103) +- Displaying CLI errors on stderr [#3116](https://github.com/paritytech/parity/pull/3116) +- new InputAddressSelect component [#3071](https://github.com/paritytech/parity/pull/3071) +- Bump mio [#3117](https://github.com/paritytech/parity/pull/3117) +- Minor typo fixed. [#3110](https://github.com/paritytech/parity/pull/3110) +- Sort by ETH balance and contract by date [#3107](https://github.com/paritytech/parity/pull/3107) +- Add RPC enode lookup [#3096](https://github.com/paritytech/parity/pull/3096) +- Initializing logger for each command [#3090](https://github.com/paritytech/parity/pull/3090) +- Allow registration of content bundles in GitHubHint [#3094](https://github.com/paritytech/parity/pull/3094) +- Add read-only inputs to UI plus Copy to Clipboard buttons [#3095](https://github.com/paritytech/parity/pull/3095) +- Allow boolean dropdowns for contract deploy [#3077](https://github.com/paritytech/parity/pull/3077) +- Add mac installer files [#2995](https://github.com/paritytech/parity/pull/2995) +- Fixing dapps sorting [#3086](https://github.com/paritytech/parity/pull/3086) +- Add a Gitter chat badge to README.md [#3092](https://github.com/paritytech/parity/pull/3092) +- Fixes webpack HTML loader [#3089](https://github.com/paritytech/parity/pull/3089) +- Redirecting /home to new UI [#3084](https://github.com/paritytech/parity/pull/3084) +- Allow GitHubHint content owner to update url [#3083](https://github.com/paritytech/parity/pull/3083) +- Remove token assets (moved to ethcore/dapps-assets) [#3082](https://github.com/paritytech/parity/pull/3082) +- Goodbye Gavcoin, Hello Gavcoin [#3080](https://github.com/paritytech/parity/pull/3080) +- Load network dapps [#3078](https://github.com/paritytech/parity/pull/3078) +- Swap account phrase input to normal (non-multiline) [#3060](https://github.com/paritytech/parity/pull/3060) +- Fix minor typo in informant [#3056](https://github.com/paritytech/parity/pull/3056) +- Warp sync status display [#3045](https://github.com/paritytech/parity/pull/3045) +- Enhance address input [#3065](https://github.com/paritytech/parity/pull/3065) +- Go to Accounts Page if Tooltips are displayed [#3063](https://github.com/paritytech/parity/pull/3063) +- Change contract Execute bool values & query bool value display [#3024](https://github.com/paritytech/parity/pull/3024) +- Update Parity logo [#3036](https://github.com/paritytech/parity/pull/3036) +- settings: replace background patterns (inline) [#3047](https://github.com/paritytech/parity/pull/3047) +- Multiple line description for dapps [#3058](https://github.com/paritytech/parity/pull/3058) +- Fix status log order [#3062](https://github.com/paritytech/parity/pull/3062) +- Graphical gas price selection [#2898](https://github.com/paritytech/parity/pull/2898) +- [Registry dApp] Actions not available before selecting accounts [#3032](https://github.com/paritytech/parity/pull/3032) +- apply post-consolidation migrations after consolidating [#3020](https://github.com/paritytech/parity/pull/3020) +- fix chain badge padding [#3046](https://github.com/paritytech/parity/pull/3046) +- Don't delete Tags input on blur (eg. tab) [#3044](https://github.com/paritytech/parity/pull/3044) +- Fixing last hashes for ethcall [#3043](https://github.com/paritytech/parity/pull/3043) +- Remove signer icons [#3039](https://github.com/paritytech/parity/pull/3039) +- execute periodic snapshot in new thread [#3029](https://github.com/paritytech/parity/pull/3029) +- fix background of embedded signer [#3026](https://github.com/paritytech/parity/pull/3026) +- registry dapp: fix reducer [#3028](https://github.com/paritytech/parity/pull/3028) +- Replace Execute by Query in contract button [#3031](https://github.com/paritytech/parity/pull/3031) +- Fixing GavCoin dApp overflow issues [#3030](https://github.com/paritytech/parity/pull/3030) +- execute contract function: validate address [#3013](https://github.com/paritytech/parity/pull/3013) +- Align tag inputs with other input boxes [#2965](https://github.com/paritytech/parity/pull/2965) +- Sweep panickers from IO and network [#3018](https://github.com/paritytech/parity/pull/3018) +- Terms & Conditions [#3019](https://github.com/paritytech/parity/pull/3019) +- open column families after reparing db corruption [#3017](https://github.com/paritytech/parity/pull/3017) +- Snapshot sync and block gap info in `eth_syncing` [#2948](https://github.com/paritytech/parity/pull/2948) +- personal_ RPCs to AutoArgs [#3000](https://github.com/paritytech/parity/pull/3000) +- RPCs for mode change [#3002](https://github.com/paritytech/parity/pull/3002) +- Fix a test sensitive to slow execution. [#3014](https://github.com/paritytech/parity/pull/3014) +- Fixes search filtering issues [#3011](https://github.com/paritytech/parity/pull/3011) +- Restart sync if no more peers with snapshots [#3007](https://github.com/paritytech/parity/pull/3007) +- Allow empty/non-existant input arrays for ABIs in contract view [#3001](https://github.com/paritytech/parity/pull/3001) +- Allow operation when no registry is available [#2980](https://github.com/paritytech/parity/pull/2980) +- Make JS lint & test run on Travis [#2894](https://github.com/paritytech/parity/pull/2894) +- Update account dropdowns [#2959](https://github.com/paritytech/parity/pull/2959) +- Modify gas price statistics [#2947](https://github.com/paritytech/parity/pull/2947) +- Fixes pending/mined transactions in registry dApp [#3004](https://github.com/paritytech/parity/pull/3004) +- Prevent connecting to self [#2997](https://github.com/paritytech/parity/pull/2997) +- Disable verbose in gitlab CI [#2999](https://github.com/paritytech/parity/pull/2999) +- Allow warnings in gitlab [#2998](https://github.com/paritytech/parity/pull/2998) +- Fix the brainwallet functionality. [#2994](https://github.com/paritytech/parity/pull/2994) +- Provided gas description update [#2993](https://github.com/paritytech/parity/pull/2993) +- Print messages to stderr [#2991](https://github.com/paritytech/parity/pull/2991) +- Networking and syncing tweaks [#2990](https://github.com/paritytech/parity/pull/2990) +- Allow build warnings [#2985](https://github.com/paritytech/parity/pull/2985) +- Display network status for finished Signer requests [#2983](https://github.com/paritytech/parity/pull/2983) +- Fixed rejecting transactions [#2984](https://github.com/paritytech/parity/pull/2984) +- mio version bump [#2982](https://github.com/paritytech/parity/pull/2982) +- Publish parity.js to npmjs registry [#2978](https://github.com/paritytech/parity/pull/2978) +- Import raw private key [#2945](https://github.com/paritytech/parity/pull/2945) +- refactor etherscan.io links [#2896](https://github.com/paritytech/parity/pull/2896) +- Use separate lock for code cache [#2977](https://github.com/paritytech/parity/pull/2977) +- Add favicon [#2974](https://github.com/paritytech/parity/pull/2974) +- Align password change dialog with create dialog ordering [#2970](https://github.com/paritytech/parity/pull/2970) +- WS bump [#2973](https://github.com/paritytech/parity/pull/2973) +- Discovery performance optimization [#2972](https://github.com/paritytech/parity/pull/2972) +- Pass gas & gasPrice to token transfers [#2964](https://github.com/paritytech/parity/pull/2964) +- Updating ws-rs [#2962](https://github.com/paritytech/parity/pull/2962) +- Run cargo with verbose flag when testing [#2943](https://github.com/paritytech/parity/pull/2943) +- Fixing clippy warnings take two [#2961](https://github.com/paritytech/parity/pull/2961) +- Snapshot sync improvements [#2960](https://github.com/paritytech/parity/pull/2960) +- Gavcoin event display updates [#2956](https://github.com/paritytech/parity/pull/2956) +- Eslint fixes [#2957](https://github.com/paritytech/parity/pull/2957) +- Add import of raw private key RPCs [#2942](https://github.com/paritytech/parity/pull/2942) +- Bring in styling queues from original Gavcoin [#2936](https://github.com/paritytech/parity/pull/2936) +- Validating minimal required gas for a transaction [#2937](https://github.com/paritytech/parity/pull/2937) +- Even more snapshot validity checks [#2935](https://github.com/paritytech/parity/pull/2935) +- Shared code cache [#2921](https://github.com/paritytech/parity/pull/2921) +- Updating bootnodes for ETC [#2938](https://github.com/paritytech/parity/pull/2938) +- More bootnodes [#2926](https://github.com/paritytech/parity/pull/2926) +- Revert hash updates until testable [#2925](https://github.com/paritytech/parity/pull/2925) +- Release.sh verbose output [#2924](https://github.com/paritytech/parity/pull/2924) +- additional release.sh debugging info [#2922](https://github.com/paritytech/parity/pull/2922) +- Pass the js-precompiled commit hash to cargo update [#2920](https://github.com/paritytech/parity/pull/2920) +- Next nonce RPC [#2917](https://github.com/paritytech/parity/pull/2917) +- Get rid of duplicated code in EVM [#2915](https://github.com/paritytech/parity/pull/2915) +- Transaction Queue banning [#2524](https://github.com/paritytech/parity/pull/2524) +- Revert to gas price ordering [#2919](https://github.com/paritytech/parity/pull/2919) +- Personal split [#2879](https://github.com/paritytech/parity/pull/2879) +- Fixing config values for pruning_history [#2918](https://github.com/paritytech/parity/pull/2918) +- Apply pending block details on commit [#2254](https://github.com/paritytech/parity/pull/2254) +- Fixed GetNodeData output [#2892](https://github.com/paritytech/parity/pull/2892) +- New sync protocol ID [#2912](https://github.com/paritytech/parity/pull/2912) +- Clippy bump [#2877](https://github.com/paritytech/parity/pull/2877) +- iconomi token images [#2906](https://github.com/paritytech/parity/pull/2906) +- Fixes too long description and Token balance value in Dapps/Accounts [#2902](https://github.com/paritytech/parity/pull/2902) +- Add missing images for local dapps [#2890](https://github.com/paritytech/parity/pull/2890) +- Fix Webpack, again [#2895](https://github.com/paritytech/parity/pull/2895) +- Enable suicide json test [#2893](https://github.com/paritytech/parity/pull/2893) +- More snapshot fixes and optimizations [#2883](https://github.com/paritytech/parity/pull/2883) +- Fixes CI JS precompiled build [#2886](https://github.com/paritytech/parity/pull/2886) +- Fix empty tags modification [#2884](https://github.com/paritytech/parity/pull/2884) +- Fix up informant. [#2865](https://github.com/paritytech/parity/pull/2865) +- Get rid of MemoryDB denote [#2881](https://github.com/paritytech/parity/pull/2881) +- Add inject to "bundle everything" list [#2871](https://github.com/paritytech/parity/pull/2871) +- Fixes signer and MUI errors throwing [#2876](https://github.com/paritytech/parity/pull/2876) +- Fix failing tests after log parsing updates [#2878](https://github.com/paritytech/parity/pull/2878) +- Sweep some more panics [#2848](https://github.com/paritytech/parity/pull/2848) +- Make GitLab js-precompiled really update Cargo.toml in main repo [#2869](https://github.com/paritytech/parity/pull/2869) +- IPC version bump [#2870](https://github.com/paritytech/parity/pull/2870) +- Snapshot sync fixes and optimizations [#2863](https://github.com/paritytech/parity/pull/2863) +- Add Check and Change Password for an Account [#2861](https://github.com/paritytech/parity/pull/2861) +- Output git fetch/push to log files [#2862](https://github.com/paritytech/parity/pull/2862) +- Align contract event log l&f with transactions [#2812](https://github.com/paritytech/parity/pull/2812) +- Nicer port in use errors [#2859](https://github.com/paritytech/parity/pull/2859) +- Remove personal_* calls from dapps [#2860](https://github.com/paritytech/parity/pull/2860) +- Token sorting, zero-ETH transfer & token decimals [#2805](https://github.com/paritytech/parity/pull/2805) +- Don't fail badly when no transactions in last 100 blocks. [#2856](https://github.com/paritytech/parity/pull/2856) +- Fixing home.parity address for new signer [#2851](https://github.com/paritytech/parity/pull/2851) +- Enabling UI build back [#2853](https://github.com/paritytech/parity/pull/2853) +- Remove eventName in unsubscribe API arguments [#2844](https://github.com/paritytech/parity/pull/2844) +- Don't return empty names as clickable titles [#2809](https://github.com/paritytech/parity/pull/2809) +- Auto-bump js-precompiled on release [#2828](https://github.com/paritytech/parity/pull/2828) +- Remove ethcore::common re-export module [#2792](https://github.com/paritytech/parity/pull/2792) +- Prevent database corruption on OOM [#2832](https://github.com/paritytech/parity/pull/2832) +- Download/Export Addressbook [#2847](https://github.com/paritytech/parity/pull/2847) +- Snapshot and blockchain stability improvements [#2843](https://github.com/paritytech/parity/pull/2843) +- Extended network options [#2845](https://github.com/paritytech/parity/pull/2845) +- fix failing master test build [#2846](https://github.com/paritytech/parity/pull/2846) +- Local dapps embeddable on signer port [#2815](https://github.com/paritytech/parity/pull/2815) +- Trigger accounts/contracts search on search input change [#2838](https://github.com/paritytech/parity/pull/2838) +- Move snapshot sync to a subprotocol [#2820](https://github.com/paritytech/parity/pull/2820) +- fix node log being reversed [#2839](https://github.com/paritytech/parity/pull/2839) +- Fixes currency symbol font size in Shapeshift modal [#2840](https://github.com/paritytech/parity/pull/2840) +- Disable personal APIs by default for security reasons [#2834](https://github.com/paritytech/parity/pull/2834) +- Clear cached content [#2833](https://github.com/paritytech/parity/pull/2833) +- Add ethcore_[dapps|signer]Port APIs [#2821](https://github.com/paritytech/parity/pull/2821) +- CLI option to skip seal check when importing [#2842](https://github.com/paritytech/parity/pull/2842) +- Fix case error in Dapps import [#2837](https://github.com/paritytech/parity/pull/2837) +- Double click on address in account detail view should select it [#2841](https://github.com/paritytech/parity/pull/2841) +- Bump js-precompiled to 20161022-223915 UTC [#2826](https://github.com/paritytech/parity/pull/2826) +- Adjust paths to handle CORS changes [#2816](https://github.com/paritytech/parity/pull/2816) +- RPC for dapps port and signer port [#2819](https://github.com/paritytech/parity/pull/2819) +- Update build to working version on pre-compiled repo [#2825](https://github.com/paritytech/parity/pull/2825) +- Adjust network name badge colours (darker) [#2823](https://github.com/paritytech/parity/pull/2823) +- Removing submodule in favour of rust crate [#2756](https://github.com/paritytech/parity/pull/2756) +- Return old-ish content even when syncing [#2757](https://github.com/paritytech/parity/pull/2757) +- fix Signer UI [#2750](https://github.com/paritytech/parity/pull/2750) +- USG, GBP, Euro & Yuan updates [#2818](https://github.com/paritytech/parity/pull/2818) +- Make locally installed apps available again (Fixes #2771) [#2808](https://github.com/paritytech/parity/pull/2808) +- Additional RPCs for password management [#2779](https://github.com/paritytech/parity/pull/2779) +- flush DB changes on drop [#2795](https://github.com/paritytech/parity/pull/2795) +- rename State::snapshot to checkpoint to avoid confusion [#2796](https://github.com/paritytech/parity/pull/2796) +- Missing changes required to make new UI work [#2793](https://github.com/paritytech/parity/pull/2793) +- Cleanup method decoding (Fixes #2811) [#2810](https://github.com/paritytech/parity/pull/2810) +- Use trace API for decentralized transaction list [#2784](https://github.com/paritytech/parity/pull/2784) +- Automatic compaction selection on Linux [#2785](https://github.com/paritytech/parity/pull/2785) +- Update token images [#2804](https://github.com/paritytech/parity/pull/2804) +- Hackergold token images [#2801](https://github.com/paritytech/parity/pull/2801) +- Additional token images [#2800](https://github.com/paritytech/parity/pull/2800) +- Additional token images [#2798](https://github.com/paritytech/parity/pull/2798) +- Resolve morden fork [#2773](https://github.com/paritytech/parity/pull/2773) +- Using SipHashes from crates.io [#2778](https://github.com/paritytech/parity/pull/2778) +- Fixed issues on Searchable Addresses [#2790](https://github.com/paritytech/parity/pull/2790) +- Currency icons [#2788](https://github.com/paritytech/parity/pull/2788) +- Update token images [#2783](https://github.com/paritytech/parity/pull/2783) +- Fix warning in master [#2775](https://github.com/paritytech/parity/pull/2775) +- Add empty account existence test from beta. [#2769](https://github.com/paritytech/parity/pull/2769) +- Update name of basiccoin manager [#2768](https://github.com/paritytech/parity/pull/2768) +- sweep most unwraps from ethcore crate, dapps crate [#2762](https://github.com/paritytech/parity/pull/2762) +- Check queue to determine major importing [#2763](https://github.com/paritytech/parity/pull/2763) +- Trace filtering fix [#2760](https://github.com/paritytech/parity/pull/2760) +- Update js precompiled to 20161020-141636 [#2761](https://github.com/paritytech/parity/pull/2761) +- Incrementally calculate verification queue heap size [#2749](https://github.com/paritytech/parity/pull/2749) +- Don't add empty accounts to bloom [#2753](https://github.com/paritytech/parity/pull/2753) +- fix contract deployments not showing up [#2759](https://github.com/paritytech/parity/pull/2759) +- Fixes a positioning issue in Address Selection component [#2754](https://github.com/paritytech/parity/pull/2754) +- fix linting issues [#2758](https://github.com/paritytech/parity/pull/2758) +- Making Trie.iter non-recursive [#2733](https://github.com/paritytech/parity/pull/2733) +- Block import optimization [#2748](https://github.com/paritytech/parity/pull/2748) +- Update js-precompiled to 20161020-110858 [#2752](https://github.com/paritytech/parity/pull/2752) +- Fixing small files fetching [#2742](https://github.com/paritytech/parity/pull/2742) +- Fixing stalled sync [#2747](https://github.com/paritytech/parity/pull/2747) +- refactor signer components [#2691](https://github.com/paritytech/parity/pull/2691) +- Png images with backgrounds (original svg) [#2740](https://github.com/paritytech/parity/pull/2740) +- Make address selection searchable [#2739](https://github.com/paritytech/parity/pull/2739) +- very basic dapp add/remove interface [#2721](https://github.com/paritytech/parity/pull/2721) +- Frontport commits from beta to master [#2743](https://github.com/paritytech/parity/pull/2743) +- Implements Trace API Formatter [#2732](https://github.com/paritytech/parity/pull/2732) +- bump parking_lot to 0.3.x series [#2702](https://github.com/paritytech/parity/pull/2702) +- Unify major syncing detection [#2699](https://github.com/paritytech/parity/pull/2699) +- Fixes gas/gasPrice change not reflected in transaction modal [#2735](https://github.com/paritytech/parity/pull/2735) +- Fixing build UI stuff along with Rust [#2726](https://github.com/paritytech/parity/pull/2726) +- Fixed Snackbar not showing and/or behind transactions (#2730) [#2731](https://github.com/paritytech/parity/pull/2731) +- Updating json tests to latest develop commit [#2728](https://github.com/paritytech/parity/pull/2728) +- dapps: show errors [#2727](https://github.com/paritytech/parity/pull/2727) +- node logs: break lines [#2722](https://github.com/paritytech/parity/pull/2722) +- Bumping JSON-RPC http server [#2714](https://github.com/paritytech/parity/pull/2714) +- Add ability to copy address to the clipboard [#2716](https://github.com/paritytech/parity/pull/2716) +- Sort tags when displaying ; use AND for search results [#2720](https://github.com/paritytech/parity/pull/2720) +- allow-same-origin for iframe [#2711](https://github.com/paritytech/parity/pull/2711) +- Update Registry address (mainnet) [#2713](https://github.com/paritytech/parity/pull/2713) +- Allow tags for Accounts, Addresses and Contracts [#2712](https://github.com/paritytech/parity/pull/2712) +- Correct parameters for eth_sign [#2703](https://github.com/paritytech/parity/pull/2703) +- Bump js-precompiled to 20161018-161705 [#2698](https://github.com/paritytech/parity/pull/2698) +- Add inject.js (for web3 exposed) [#2692](https://github.com/paritytech/parity/pull/2692) +- Remove obsolete dapps and update security headers [#2694](https://github.com/paritytech/parity/pull/2694) +- Snapshot sync part 2 [#2098](https://github.com/paritytech/parity/pull/2098) +- Fix issues with no ethereum test dir present (2382) [#2659](https://github.com/paritytech/parity/pull/2659) +- Apply UI PRs after master merge [#2690](https://github.com/paritytech/parity/pull/2690) +- Fix importing traces for non-canon blocks [#2683](https://github.com/paritytech/parity/pull/2683) +- Fixing random test failures [#2577](https://github.com/paritytech/parity/pull/2577) +- Disable IPC in default build for 1.4 [#2657](https://github.com/paritytech/parity/pull/2657) +- use pruning history in CLI snapshots [#2658](https://github.com/paritytech/parity/pull/2658) +- Fixing --no-default-features again and evmbin [#2670](https://github.com/paritytech/parity/pull/2670) +- Settings > Proxy for proxy.pac setup instructions [#2678](https://github.com/paritytech/parity/pull/2678) +- Re-instate transaitions to allow updating busy indicator [#2682](https://github.com/paritytech/parity/pull/2682) +- signer: remove reject counter [#2685](https://github.com/paritytech/parity/pull/2685) +- Initial new UI source code import [#2607](https://github.com/paritytech/parity/pull/2607) +- Additional dapp logo images [#2677](https://github.com/paritytech/parity/pull/2677) +- Redirect from :8080 to :8180 [#2676](https://github.com/paritytech/parity/pull/2676) +- script to update js-precompiled [#2673](https://github.com/paritytech/parity/pull/2673) +- Styling in FF is not 100% [#2669](https://github.com/paritytech/parity/pull/2669) +- Don't allow gavcoin transfer with no balances [#2667](https://github.com/paritytech/parity/pull/2667) +- fix signer rejections [#2666](https://github.com/paritytech/parity/pull/2666) +- better text on unique background pattern [#2664](https://github.com/paritytech/parity/pull/2664) +- Adjust z-index for error overlay [#2662](https://github.com/paritytech/parity/pull/2662) +- Fix address selection for contract deployment [#2660](https://github.com/paritytech/parity/pull/2660) +- Add additional contract images [#2655](https://github.com/paritytech/parity/pull/2655) +- Update /api/* to point to :8080/api/* (first generation interface) [#2612](https://github.com/paritytech/parity/pull/2612) +- Initial import of new UI (compiled JS code) [#2220](https://github.com/paritytech/parity/pull/2220) +- Fixing evmbin compilation [#2652](https://github.com/paritytech/parity/pull/2652) +- Fix up ETC EIP-150 transition to 2,500,000. [#2636](https://github.com/paritytech/parity/pull/2636) +- Fixing compilation without default features [#2638](https://github.com/paritytech/parity/pull/2638) +- [frontport] CLI to specify queue ordering strategy (#2494) [#2623](https://github.com/paritytech/parity/pull/2623) +- Support for decryption in Signer [#2421](https://github.com/paritytech/parity/pull/2421) +- EIP150.1c [#2591](https://github.com/paritytech/parity/pull/2591) +- Release merge with origin with ours strategy [#2631](https://github.com/paritytech/parity/pull/2631) +- Adjust build output directories [#2630](https://github.com/paritytech/parity/pull/2630) +- cater for txhash returning null/empty object [#2629](https://github.com/paritytech/parity/pull/2629) +- snapshot: single byte for empty accounts [#2625](https://github.com/paritytech/parity/pull/2625) +- Configurable history size in master [#2606](https://github.com/paritytech/parity/pull/2606) +- Database performance tweaks [#2619](https://github.com/paritytech/parity/pull/2619) +- Enable suicide json test [#2626](https://github.com/paritytech/parity/pull/2626) +- Split journaldb commit into two functions: journal_under and mark_canonical [#2329](https://github.com/paritytech/parity/pull/2329) +- Fixed tx queue limit for local transactions [#2616](https://github.com/paritytech/parity/pull/2616) +- Additional logs when transactions is removed from queue [#2617](https://github.com/paritytech/parity/pull/2617) +- mitigate refcell conflict in state diffing [#2601](https://github.com/paritytech/parity/pull/2601) +- Fix tests [#2611](https://github.com/paritytech/parity/pull/2611) +- small styling updates [#2610](https://github.com/paritytech/parity/pull/2610) +- Remove web3 from Signer, bring in parity.js API [#2604](https://github.com/paritytech/parity/pull/2604) +- Mostly configurable canonical cache size [#2516](https://github.com/paritytech/parity/pull/2516) +- Added peers details to ethcore_netPeers RPC [#2580](https://github.com/paritytech/parity/pull/2580) +- Display account password hint when available [#2596](https://github.com/paritytech/parity/pull/2596) +- Fix gas estimation on transfer when data supplied [#2593](https://github.com/paritytech/parity/pull/2593) +- remove unused npm packages [#2590](https://github.com/paritytech/parity/pull/2590) +- Bundle fonts as part of the build process [#2588](https://github.com/paritytech/parity/pull/2588) +- Contract constructor params [#2586](https://github.com/paritytech/parity/pull/2586) +- Update json test suite [#2574](https://github.com/paritytech/parity/pull/2574) +- Filter apps that has been replaced for the local list [#2583](https://github.com/paritytech/parity/pull/2583) +- Display local apps listed by Parity [#2581](https://github.com/paritytech/parity/pull/2581) +- Network-specific nodes file [#2569](https://github.com/paritytech/parity/pull/2569) +- Dont close when block is known to be invalid [#2572](https://github.com/paritytech/parity/pull/2572) +- deny compiler warnings in CI [#2570](https://github.com/paritytech/parity/pull/2570) +- adjust alignment of queries [#2573](https://github.com/paritytech/parity/pull/2573) +- update ethcore-bigint crate to 0.1.1 [#2562](https://github.com/paritytech/parity/pull/2562) +- Registry dapp uses setAddress to actually set addresses now [#2568](https://github.com/paritytech/parity/pull/2568) +- Add the new EIP150 test. [#2563](https://github.com/paritytech/parity/pull/2563) +- fix failing tests [#2567](https://github.com/paritytech/parity/pull/2567) +- ΞTH -> ETH [#2566](https://github.com/paritytech/parity/pull/2566) +- Ensure polling is only done when connected [#2565](https://github.com/paritytech/parity/pull/2565) +- Fixed race condition in trace import [#2555](https://github.com/paritytech/parity/pull/2555) +- Disable misbehaving peers while seeking for best block [#2537](https://github.com/paritytech/parity/pull/2537) +- TX queue gas limit config and allow local transactions over the gas limit [#2553](https://github.com/paritytech/parity/pull/2553) +- standard component for address -> name mappings (consistent use everywhere) [#2557](https://github.com/paritytech/parity/pull/2557) +- Remove unwrap from client module [#2554](https://github.com/paritytech/parity/pull/2554) +- Removing panickers from sync module [#2551](https://github.com/paritytech/parity/pull/2551) +- Address images (tokens, dapps) as registered via contentHash (when available) [#2526](https://github.com/paritytech/parity/pull/2526) +- TokenReg set & get images working [#2540](https://github.com/paritytech/parity/pull/2540) +- adjust app_id where /api/content/ is called, fixes #2541 [#2543](https://github.com/paritytech/parity/pull/2543) +- connection dialog now shows up in dapps as well, closes #2538 [#2550](https://github.com/paritytech/parity/pull/2550) +- display account uuid (where available), closes #2546 [#2549](https://github.com/paritytech/parity/pull/2549) +- create accounts via recovery phrase [#2545](https://github.com/paritytech/parity/pull/2545) +- Build ethcore/js-precompiled on GitLab [#2522](https://github.com/paritytech/parity/pull/2522) +- Return errors from eth_call RPC [#2498](https://github.com/paritytech/parity/pull/2498) +- registry dapp: manage records [#2323](https://github.com/paritytech/parity/pull/2323) +- Print backtrace on panic [#2535](https://github.com/paritytech/parity/pull/2535) +- GitHubHint dapp [#2531](https://github.com/paritytech/parity/pull/2531) +- Backports to master [#2530](https://github.com/paritytech/parity/pull/2530) +- Handle reorganizations in the state cache [#2490](https://github.com/paritytech/parity/pull/2490) +- Hypervisor: terminate hanging modules [#2513](https://github.com/paritytech/parity/pull/2513) +- signer & node connection prompts/indicators [#2504](https://github.com/paritytech/parity/pull/2504) +- Using pending block only if is not old [#2514](https://github.com/paritytech/parity/pull/2514) +- More caching optimizations [#2505](https://github.com/paritytech/parity/pull/2505) +- Fixed possible panic in the networking [#2495](https://github.com/paritytech/parity/pull/2495) +- Trim password from file [#2503](https://github.com/paritytech/parity/pull/2503) +- Fixing RPC Filter conversion to EthFilter [#2500](https://github.com/paritytech/parity/pull/2500) +- Fixing error message for transactions [#2496](https://github.com/paritytech/parity/pull/2496) +- Adjustable stack size for EVM [#2483](https://github.com/paritytech/parity/pull/2483) +- [master] Fixing penalization in future [#2499](https://github.com/paritytech/parity/pull/2499) +- Preserve cache on reverting the snapshot [#2488](https://github.com/paritytech/parity/pull/2488) +- RocksDB version bump [#2492](https://github.com/paritytech/parity/pull/2492) +- Increase default size of transaction queue [#2489](https://github.com/paritytech/parity/pull/2489) +- basiccoin v1 available [#2491](https://github.com/paritytech/parity/pull/2491) +- Small EVM optimization [#2487](https://github.com/paritytech/parity/pull/2487) +- Track dirty accounts in the state [#2461](https://github.com/paritytech/parity/pull/2461) +- fix signature lookup address [#2480](https://github.com/paritytech/parity/pull/2480) +- update registrar test with generic non-empty test [#2476](https://github.com/paritytech/parity/pull/2476) +- Derive IPC interface only when ipc feature is on [#2463](https://github.com/paritytech/parity/pull/2463) +- Fix ethstore opening all key files in the directory at once [#2471](https://github.com/paritytech/parity/pull/2471) +- contract api event log fixes [#2469](https://github.com/paritytech/parity/pull/2469) +- basiccoin base functionality in-place [#2468](https://github.com/paritytech/parity/pull/2468) +- Merge IPC codegen attributes into one [#2460](https://github.com/paritytech/parity/pull/2460) +- Close after importing keys from geth [#2464](https://github.com/paritytech/parity/pull/2464) +- Port a couple more RPC APIs to the new auto args [#2325](https://github.com/paritytech/parity/pull/2325) +- update rustc for appveyor to 1.12.0 [#2423](https://github.com/paritytech/parity/pull/2423) +- dapp basiccoin send operations [#2456](https://github.com/paritytech/parity/pull/2456) +- Better EVM informant & Slow transactions warning [#2436](https://github.com/paritytech/parity/pull/2436) +- Fixing Signer token RPC API [#2437](https://github.com/paritytech/parity/pull/2437) +- Fixed FatDB check [#2443](https://github.com/paritytech/parity/pull/2443) +- dapp basiccoin structure [#2444](https://github.com/paritytech/parity/pull/2444) +- Accounts bloom in master [#2426](https://github.com/paritytech/parity/pull/2426) +- Polishing Actually enable fat db pr (#1974) [#2048](https://github.com/paritytech/parity/pull/2048) +- Jumptable cache [#2427](https://github.com/paritytech/parity/pull/2427) +- signaturereg registered, remove hardcoding [#2431](https://github.com/paritytech/parity/pull/2431) +- tokenreg dapp fixes for non-null returns [#2430](https://github.com/paritytech/parity/pull/2430) +- update ABI json to latest deployed versions [#2428](https://github.com/paritytech/parity/pull/2428) +- update Morden registry address [#2417](https://github.com/paritytech/parity/pull/2417) +- Make migration api more friendly [#2420](https://github.com/paritytech/parity/pull/2420) +- Journaling bloom filter crate in util [#2395](https://github.com/paritytech/parity/pull/2395) +- move abis from js/json to contracts/abi [#2418](https://github.com/paritytech/parity/pull/2418) +- Fixing logs-receipt matching [#2403](https://github.com/paritytech/parity/pull/2403) +- fix broken beta compilation [#2405](https://github.com/paritytech/parity/pull/2405) +- registry dapp: transfer names [#2335](https://github.com/paritytech/parity/pull/2335) +- manage firstRun better [#2398](https://github.com/paritytech/parity/pull/2398) +- render contract deployment address [#2397](https://github.com/paritytech/parity/pull/2397) +- Transaction Queue fix [#2392](https://github.com/paritytech/parity/pull/2392) +- contracts abi types & execute value [#2394](https://github.com/paritytech/parity/pull/2394) +- update styling with ParityBar overlay [#2390](https://github.com/paritytech/parity/pull/2390) +- application Signer popup window [#2388](https://github.com/paritytech/parity/pull/2388) +- Fixing Delegate Call in JIT [#2378](https://github.com/paritytech/parity/pull/2378) +- Prioritizing re-imported transactions [#2372](https://github.com/paritytech/parity/pull/2372) +- Revert #2172, pretty much. [#2387](https://github.com/paritytech/parity/pull/2387) +- correct sync memory usage calculation [#2385](https://github.com/paritytech/parity/pull/2385) +- fix migration system for post-consolidation migrations, better errors [#2334](https://github.com/paritytech/parity/pull/2334) +- Fix the traceAddress field in transaction traces. [#2373](https://github.com/paritytech/parity/pull/2373) +- Gavcoin utilises the popup box [#2381](https://github.com/paritytech/parity/pull/2381) +- registry dapp: support dropping names [#2328](https://github.com/paritytech/parity/pull/2328) +- settings view, set background & store views [#2380](https://github.com/paritytech/parity/pull/2380) +- Removing extras data from retracted blocks. [#2375](https://github.com/paritytech/parity/pull/2375) +- fixed #2263, geth keys with ciphertext shorter than 32 bytes [#2318](https://github.com/paritytech/parity/pull/2318) +- Expanse compatibility [#2369](https://github.com/paritytech/parity/pull/2369) +- Allow queries of constant functions on contracts [#2360](https://github.com/paritytech/parity/pull/2360) +- Auto Open/Close the Signer window on new transaction request [#2362](https://github.com/paritytech/parity/pull/2362) +- Specify column cache sizes explicitly; default fallback of 2MB [#2358](https://github.com/paritytech/parity/pull/2358) +- Canonical state cache (master) [#2311](https://github.com/paritytech/parity/pull/2311) +- method signature lookups, parameter decoding & management [#2313](https://github.com/paritytech/parity/pull/2313) +- make block queue into a more generic verification queue and fix block heap size calculation [#2095](https://github.com/paritytech/parity/pull/2095) +- Hash Content RPC method [#2355](https://github.com/paritytech/parity/pull/2355) +- registry dapp: show reserved events by default [#2359](https://github.com/paritytech/parity/pull/2359) +- Display timestamp in Signer requests details [#2324](https://github.com/paritytech/parity/pull/2324) +- Reorder transaction_by_hash to favour canon search [#2332](https://github.com/paritytech/parity/pull/2332) +- Optimize DIV for some common divisors [#2327](https://github.com/paritytech/parity/pull/2327) +- Return error when deserializing invalid hex [#2339](https://github.com/paritytech/parity/pull/2339) +- Changed http:// to https:// on some links [#2349](https://github.com/paritytech/parity/pull/2349) +- user defaults [#2014](https://github.com/paritytech/parity/pull/2014) +- Fixing jit feature compilation [#2310](https://github.com/paritytech/parity/pull/2310) +- Tx Queue improvements [#2292](https://github.com/paritytech/parity/pull/2292) +- Removing PropTypes on build [#2322](https://github.com/paritytech/parity/pull/2322) +- Lenient bytes deserialization [#2036](https://github.com/paritytech/parity/pull/2036) +- reverse call data decoding given transaction data & method [#2312](https://github.com/paritytech/parity/pull/2312) +- add missing gpl headers to gavcoin dapp [#2317](https://github.com/paritytech/parity/pull/2317) +- contract Events, Functions & Queries sub-components as well as Event log visual updates [#2306](https://github.com/paritytech/parity/pull/2306) +- webpack config updates (really include babel-polyfill, rename npm steps) [#2305](https://github.com/paritytech/parity/pull/2305) +- remove unneeded Form from Account header [#2302](https://github.com/paritytech/parity/pull/2302) +- edit of metadata across accounts, addresses & contracts [#2300](https://github.com/paritytech/parity/pull/2300) +- Adjust all modals for consistency & css DRY-ness [#2301](https://github.com/paritytech/parity/pull/2301) +- update container spacing [#2296](https://github.com/paritytech/parity/pull/2296) +- local cache of generated background (no allocation on each re-render) [#2298](https://github.com/paritytech/parity/pull/2298) +- fix failing tests [#2290](https://github.com/paritytech/parity/pull/2290) +- Respecting standards for tokenreg dapp [#2287](https://github.com/paritytech/parity/pull/2287) +- Separate RPC serialization from implementation [#2072](https://github.com/paritytech/parity/pull/2072) +- Webpack optimisations - Using DLL [#2264](https://github.com/paritytech/parity/pull/2264) +- header background, theme adjustments (not that harsh) [#2273](https://github.com/paritytech/parity/pull/2273) +- contract view (developer-centric) [#2259](https://github.com/paritytech/parity/pull/2259) +- Add hash as CLI function [#1995](https://github.com/paritytech/parity/pull/1995) +- registry: fix mined events showing as pending [#2267](https://github.com/paritytech/parity/pull/2267) +- Dapp - Tokereg ; Query Tokens from TLA or Address [#2266](https://github.com/paritytech/parity/pull/2266) +- Fixes to the Token Registration dApp [#2250](https://github.com/paritytech/parity/pull/2250) +- remove abi *.json duplication, provide a single version of the truth [#2253](https://github.com/paritytech/parity/pull/2253) +- Separate path for ext code size [#2251](https://github.com/paritytech/parity/pull/2251) +- Snapshot format changes [#2234](https://github.com/paritytech/parity/pull/2234) +- Serving content at /api/content/ [#2248](https://github.com/paritytech/parity/pull/2248) +- Fails when deserializing non-hex uints [#2247](https://github.com/paritytech/parity/pull/2247) +- registry dapp: add GPL headers [#2252](https://github.com/paritytech/parity/pull/2252) +- registry dapp: user-friendly lookup [#2229](https://github.com/paritytech/parity/pull/2229) +- registry dapp: show DataChanged events [#2242](https://github.com/paritytech/parity/pull/2242) +- fixups for deploys [#2249](https://github.com/paritytech/parity/pull/2249) +- Fixing output of eth_call and Bytes deserialization [#2230](https://github.com/paritytech/parity/pull/2230) +- Encryption, decryption and public key RPCs. [#1946](https://github.com/paritytech/parity/pull/1946) +- limit number of event logs returned [#2231](https://github.com/paritytech/parity/pull/2231) +- babel-polyfill [#2239](https://github.com/paritytech/parity/pull/2239) +- procedurally generate background based on signer key [#2233](https://github.com/paritytech/parity/pull/2233) +- UI fixes [#2238](https://github.com/paritytech/parity/pull/2238) +- expose isConnected() from transport [#2225](https://github.com/paritytech/parity/pull/2225) +- registry dapp: rename event log [#2227](https://github.com/paritytech/parity/pull/2227) +- registry dapp: show pending events [#2223](https://github.com/paritytech/parity/pull/2223) +- Handle RLP to string UTF-8 decoding errors [#2217](https://github.com/paritytech/parity/pull/2217) +- Use WebSocket transport for all built-in calls [#2216](https://github.com/paritytech/parity/pull/2216) +- Remove panickers from trie iterators [#2209](https://github.com/paritytech/parity/pull/2209) +- Limit for logs filter. [#2180](https://github.com/paritytech/parity/pull/2180) +- Various state copy optimizations [#2172](https://github.com/paritytech/parity/pull/2172) +- New signer token RPC & Initial signer connection without token. [#2096](https://github.com/paritytech/parity/pull/2096) +- signer ui fixes [#2219](https://github.com/paritytech/parity/pull/2219) +- contract deploy ui [#2212](https://github.com/paritytech/parity/pull/2212) +- registry dapp: fix propTypes [#2218](https://github.com/paritytech/parity/pull/2218) +- registry: fix IdentityIcon in events log [#2206](https://github.com/paritytech/parity/pull/2206) +- Fixing evm-debug [#2161](https://github.com/paritytech/parity/pull/2161) +- Fix syncing with pv63 peers [#2204](https://github.com/paritytech/parity/pull/2204) +- registry: show shortened hashes [#2205](https://github.com/paritytech/parity/pull/2205) +- registry dapp: remove owner [#2203](https://github.com/paritytech/parity/pull/2203) +- webpack proxy updates for /api* [#2175](https://github.com/paritytech/parity/pull/2175) +- simplify personal event publishing, fix delete refresh issues [#2183](https://github.com/paritytech/parity/pull/2183) +- fix global & initial states [#2160](https://github.com/paritytech/parity/pull/2160) +- Allow selection & saving of available views [#2131](https://github.com/paritytech/parity/pull/2131) +- global/contract events with promisy subscribe/unsubscribe [#2136](https://github.com/paritytech/parity/pull/2136) +- Token Registry dApp [#2178](https://github.com/paritytech/parity/pull/2178) +- re-usable bytesToHex exposed in api.util [#2174](https://github.com/paritytech/parity/pull/2174) +- Webpack optimisations [#2179](https://github.com/paritytech/parity/pull/2179) +- cleanup on contract event subscriptions [#2104](https://github.com/paritytech/parity/pull/2104) +- move utility functions to api.util [#2105](https://github.com/paritytech/parity/pull/2105) +- registry dapp [#2077](https://github.com/paritytech/parity/pull/2077) +- mui/FlatButton to ui/Button [#2129](https://github.com/paritytech/parity/pull/2129) +- address delete functionality [#2128](https://github.com/paritytech/parity/pull/2128) +- contract deployment updates [#2106](https://github.com/paritytech/parity/pull/2106) +- contract events, indexed string fix [#2108](https://github.com/paritytech/parity/pull/2108) +- Bumping jsonrpc-core & jsonrpc-http-server [#2162](https://github.com/paritytech/parity/pull/2162) +- gitlab testing & build processes [#2090](https://github.com/paritytech/parity/pull/2090) +- Misc small UI fixes (recently broken) [#2101](https://github.com/paritytech/parity/pull/2101) +- Bump clippy & Fix warnings [#2109](https://github.com/paritytech/parity/pull/2109) +- Import command summary [#2102](https://github.com/paritytech/parity/pull/2102) +- check for existence of deprecated ethash file before attempting delete [#2103](https://github.com/paritytech/parity/pull/2103) +- shapeshift Promise API library [#2088](https://github.com/paritytech/parity/pull/2088) +- fund account via ShapeShift [#2099](https://github.com/paritytech/parity/pull/2099) +- Get bigint on crates.io [#2078](https://github.com/paritytech/parity/pull/2078) +- Enable sealing if Engine provides internal sealing given author [#2084](https://github.com/paritytech/parity/pull/2084) +- Config files [#2070](https://github.com/paritytech/parity/pull/2070) +- re-add lodash plugin to babel config [#2092](https://github.com/paritytech/parity/pull/2092) +- Remove old cache data [#2081](https://github.com/paritytech/parity/pull/2081) +- Logs limit & log_index bug [#2073](https://github.com/paritytech/parity/pull/2073) +- flatten store, muiTheme & api providers [#2087](https://github.com/paritytech/parity/pull/2087) +- add babel es2016 & es2017 presets [#2083](https://github.com/paritytech/parity/pull/2083) +- remove all '/index' imports in API [#2089](https://github.com/paritytech/parity/pull/2089) +- add missing GPL headers to all files [#2086](https://github.com/paritytech/parity/pull/2086) +- readme cleanups [#2085](https://github.com/paritytech/parity/pull/2085) +- gavcoin global import of parity api [#2082](https://github.com/paritytech/parity/pull/2082) +- Fixing removal from gas price when moving future->current [#2076](https://github.com/paritytech/parity/pull/2076) +- Split internal sealing from work preparation [#2071](https://github.com/paritytech/parity/pull/2071) +- ensure the target folder doesn't exist before renaming [#2074](https://github.com/paritytech/parity/pull/2074) +- Get rid of 'Dapp is being downloaded' page [#2055](https://github.com/paritytech/parity/pull/2055) +- fix failing master build: update tests to new init_restore signature. [#2069](https://github.com/paritytech/parity/pull/2069) +- Local snapshot restore [#2058](https://github.com/paritytech/parity/pull/2058) +- import: keep informant going until finished [#2065](https://github.com/paritytech/parity/pull/2065) +- Add a few tests for the snapshot service [#2059](https://github.com/paritytech/parity/pull/2059) +- IPC tweaks [#2046](https://github.com/paritytech/parity/pull/2046) +- Update arm* Docker [#2064](https://github.com/paritytech/parity/pull/2064) +- Fetching any content-addressed content [#2050](https://github.com/paritytech/parity/pull/2050) +- Use proper database configuration in snapshots. [#2052](https://github.com/paritytech/parity/pull/2052) +- periodic snapshot tweaks [#2054](https://github.com/paritytech/parity/pull/2054) +- ethkey-cli [#2057](https://github.com/paritytech/parity/pull/2057) +- Forward ethstore-cli feature [#2056](https://github.com/paritytech/parity/pull/2056) +- handling invalid spec jsons properly, additional tests, closes #1840 [#2049](https://github.com/paritytech/parity/pull/2049) +- Periodic snapshots [#2044](https://github.com/paritytech/parity/pull/2044) +- Snapshot sync [#2047](https://github.com/paritytech/parity/pull/2047) +- Nice error pages for Dapps & Signer [#2033](https://github.com/paritytech/parity/pull/2033) +- Add a few small snapshot tests [#2038](https://github.com/paritytech/parity/pull/2038) +- facelift for traces, added errors [#2042](https://github.com/paritytech/parity/pull/2042) +- Fetching content from HTTPS using `rustls` [#2024](https://github.com/paritytech/parity/pull/2024) +- Skipping log when there are no transactions were sent [#2045](https://github.com/paritytech/parity/pull/2045) +- rlp as separate crate [#2034](https://github.com/paritytech/parity/pull/2034) +- Fixing uint serialization [#2037](https://github.com/paritytech/parity/pull/2037) +- Fixing new transactions propagation [#2039](https://github.com/paritytech/parity/pull/2039) +- Propagating transactions to peers on timer. [#2035](https://github.com/paritytech/parity/pull/2035) +- Remove Populatable and BytesConvertable traits [#2019](https://github.com/paritytech/parity/pull/2019) +- fixed #1933 [#1979](https://github.com/paritytech/parity/pull/1979) +- Synchronization tweaks for IPC services [#2028](https://github.com/paritytech/parity/pull/2028) +- Asynchronous RPC support [#2017](https://github.com/paritytech/parity/pull/2017) +- Disable ArchiveDB counter check [#2016](https://github.com/paritytech/parity/pull/2016) +- always process trie death row on commit, add more tracing [#2025](https://github.com/paritytech/parity/pull/2025) +- fixed transaction addresses mapping, fixes #1971 [#2026](https://github.com/paritytech/parity/pull/2026) +- Adding tests for dapps server. [#2021](https://github.com/paritytech/parity/pull/2021) +- builtin trait refactoring [#2018](https://github.com/paritytech/parity/pull/2018) +- Start parity with systemd [#1967](https://github.com/paritytech/parity/pull/1967) +- Control service for IPC [#2013](https://github.com/paritytech/parity/pull/2013) +- LRU cache for dapps [#2006](https://github.com/paritytech/parity/pull/2006) +- CLI for valid hosts for dapps server [#2005](https://github.com/paritytech/parity/pull/2005) +- Make the block header struct's internals private [#2000](https://github.com/paritytech/parity/pull/2000) +- Take control of recovered snapshots, start restoration asynchronously [#2010](https://github.com/paritytech/parity/pull/2010) +- remove internal locking from DBTransaction [#2003](https://github.com/paritytech/parity/pull/2003) +- Snapshot optimizations [#1991](https://github.com/paritytech/parity/pull/1991) +- Revert removing ecies [#2009](https://github.com/paritytech/parity/pull/2009) +- small blooms optimization [#1998](https://github.com/paritytech/parity/pull/1998) +- protection from adding empty traces && assertion in traces db [#1994](https://github.com/paritytech/parity/pull/1994) +- Stratum IPC service [#1959](https://github.com/paritytech/parity/pull/1959) +- Signature cleanup [#1921](https://github.com/paritytech/parity/pull/1921) +- Fixed discovery skipping some nodes [#1996](https://github.com/paritytech/parity/pull/1996) +- Trie query recording and AccountDB factory for no mangling [#1944](https://github.com/paritytech/parity/pull/1944) +- Validating sha3 of a dapp bundle [#1993](https://github.com/paritytech/parity/pull/1993) +- Improve eth_getWork timeout test rpc_get_work_should_timeout [#1992](https://github.com/paritytech/parity/pull/1992) +- Resolving URLs from contract [#1964](https://github.com/paritytech/parity/pull/1964) +- Add timeout for eth_getWork call [#1975](https://github.com/paritytech/parity/pull/1975) +- CLI for Signer interface [#1980](https://github.com/paritytech/parity/pull/1980) +- IPC timeout multiplied [#1990](https://github.com/paritytech/parity/pull/1990) +- Use relative path for IPC sockets [#1983](https://github.com/paritytech/parity/pull/1983) +- Market-orientated transaction pricing [#1963](https://github.com/paritytech/parity/pull/1963) +- Bump clippy [#1982](https://github.com/paritytech/parity/pull/1982) +- Fixing mutual recursive types serialization [#1977](https://github.com/paritytech/parity/pull/1977) +- Fix open on FreeBSD [#1984](https://github.com/paritytech/parity/pull/1984) +- Upgrade hyper dependency to 0.9 [#1973](https://github.com/paritytech/parity/pull/1973) +- Create network-specific nodes files [#1970](https://github.com/paritytech/parity/pull/1970) +- Getting rid of syntex [#1965](https://github.com/paritytech/parity/pull/1965) +- Remove binary specification from hypervisor [#1960](https://github.com/paritytech/parity/pull/1960) +- Stratum protocol general [#1954](https://github.com/paritytech/parity/pull/1954) +- keep track of first block in blockchain [#1937](https://github.com/paritytech/parity/pull/1937) +- introduce ethcore/state module [#1953](https://github.com/paritytech/parity/pull/1953) +- Apply settings to column families [#1956](https://github.com/paritytech/parity/pull/1956) +- move column family constants into db module [#1955](https://github.com/paritytech/parity/pull/1955) +- ECIES without MAC [#1948](https://github.com/paritytech/parity/pull/1948) +- Fix canny warnings [#1951](https://github.com/paritytech/parity/pull/1951) +- Fetchable dapps [#1949](https://github.com/paritytech/parity/pull/1949) +- remove impossible panickers related to infallible db transaction [#1947](https://github.com/paritytech/parity/pull/1947) +- Minor optimizations [#1943](https://github.com/paritytech/parity/pull/1943) +- remove randomness from bigint benches, fix warnings [#1945](https://github.com/paritytech/parity/pull/1945) +- Fix several RPCs [#1926](https://github.com/paritytech/parity/pull/1926) +- Bump clippy, fix warnings [#1939](https://github.com/paritytech/parity/pull/1939) +- DB WAL size limit [#1935](https://github.com/paritytech/parity/pull/1935) +- Use explicit global namespaces in codegen [#1928](https://github.com/paritytech/parity/pull/1928) +- Fix build on master [#1934](https://github.com/paritytech/parity/pull/1934) +- IPC on by default [#1927](https://github.com/paritytech/parity/pull/1927) +- fix util benches compilation [#1931](https://github.com/paritytech/parity/pull/1931) +- Update gitlab-ci [#1929](https://github.com/paritytech/parity/pull/1929) +- ethkey and ethstore use hash structures from bigint [#1851](https://github.com/paritytech/parity/pull/1851) + +## Parity [v1.3.10](https://github.com/paritytech/parity/releases/tag/v1.3.10) (2016-11-04) + +The latest 1.3 series release, now considered stable. + +This includes several additional optimisations and fixes together with provisional support for the upcoming hard fork for EIP155/160/161. + +- Stable branch reset to 1.3.10 [#3156](https://github.com/paritytech/parity/pull/3156) +- Backporting to beta [#3149](https://github.com/paritytech/parity/pull/3149) +- apply post-consolidation migrations after consolidating (BETA) [#3048](https://github.com/paritytech/parity/pull/3048) +- [beta] Fix the brainwallet functionality. (#2994) [#3005](https://github.com/paritytech/parity/pull/3005) +- Bumping json-ipc-server [#2989](https://github.com/paritytech/parity/pull/2989) +- Backports for 1.3.10 [#2987](https://github.com/paritytech/parity/pull/2987) + +## Parity [v1.3.9](https://github.com/paritytech/parity/releases/tag/v1.3.9) (2016-10-21) + +This release enables EIP-150 hard fork for Ethereum Classic chain and resolves a few stability and performance issues, such as: +- Interrupted syncing on the test network. +- Block import delays caused by a large number of incoming transactions. A full re-sync is recommended for performance improvement to take effect. + +Full changes: +- [beta] Resolve morden fork [#2776](https://github.com/paritytech/parity/pull/2776) +- Fixing botched merge [#2767](https://github.com/paritytech/parity/pull/2767) +- Backports for beta [#2764](https://github.com/paritytech/parity/pull/2764) +- Introduce EIP150 hardfork block for ETC [#2736](https://github.com/paritytech/parity/pull/2736) +- [beta] fix issues with no test dir present (#2659) [#2724](https://github.com/paritytech/parity/pull/2724) +- [beta] Bumping jsonrpc-http-server [#2715](https://github.com/paritytech/parity/pull/2715) +- [beta] Fix migration system, better errors [#2661](https://github.com/paritytech/parity/pull/2661) + +## Parity [v1.3.8](https://github.com/paritytech/parity/releases/tag/v1.3.8) (2016-10-15) + +Parity 1.3.8 is our EIP150 hard-fork compliant release. + +Running this will enact a mild change of the protocol at block number 2,463,000 which should occur on Tuesday 18th October 2016 at approximately 12:20 London time (BST). This change alters the gas prices for a number of operations, mainly centring around i/o intensive Merkle trie lookups (`BALANCE`, `EXTCODESIZE` &c.) and state-trie polluters (`SUICIDE`, `CREATE` and `CALL`). These operations were heavily underpriced, an oversight which lead to the recent degradation of network service. The full details of the alteration are specified in [EIP-150](https://github.com/ethereum/EIPs/issues/150). + +Additionally several issues have been fixed including: +- a transaction queue limitation leading to dropped transactions; +- a synchronisation issue leading to stalls when syncing; + +And some small features including database performance improvements and additional logging. + +#### Upgrading private chain specification files. + +All the chain specification files now have EIP-150 rules enabled by default. To continue using the chain add the `eip150Transition` key under `Engine/ethash/params` and set it to a future transition block as shown in [this example](https://github.com/paritytech/parity/blob/85eeb3ea6e5e21ad8e5644241edf82eb8069f536/ethcore/res/ethereum/morden.json#L13). + +The key related to homestead transition has been renamed from `frontierCompatibilityModeLimit` to `homesteadTransition`. + +#### Full changes + +- [beta] EIP150.1c [#2599](https://github.com/paritytech/parity/pull/2599) +- Remove count limit for local transactions [#2634](https://github.com/paritytech/parity/pull/2634) +- Tweak DB and mining defaults [#2598](https://github.com/paritytech/parity/pull/2598) +- Revert "Bloom upgrade in beta" [#2635](https://github.com/paritytech/parity/pull/2635) +- Bloom upgrade in beta [#2609](https://github.com/paritytech/parity/pull/2609) +- Backports to beta [#2628](https://github.com/paritytech/parity/pull/2628) + +## Parity [v1.3.7](https://github.com/paritytech/parity/releases/tag/v1.3.7) (2016-10-12) + +This release contains fixes to reduce memory usage under the DoS attack and improve transaction relay. + +- Configurable history size in beta [#2587](https://github.com/paritytech/parity/pull/2587) +- Backports to beta [#2592](https://github.com/paritytech/parity/pull/2592) + + +## Parity [v1.3.6](https://github.com/paritytech/parity/releases/tag/v1.3.6) (2016-10-11) + +Parity 1.3.6 is another hotfix release to address transaction spam and deal with stability issues. With this release transaction pool gas limit no longer applies to local transactions. Full list of changes is available here: + +- Backports to beta v1.3.6 [#2571](https://github.com/paritytech/parity/pull/2571) +- Use global state cache when mining [#2529](https://github.com/paritytech/parity/pull/2529) +- Transaction queue limited by gas [#2528](https://github.com/paritytech/parity/pull/2528) + +## Parity [v1.3.5](https://github.com/paritytech/parity/releases/tag/v1.3.5) (2016-10-08) + +1.3.5 is a hotfix release for the transaction propagation issue. Transaction pool limit is now calculated based on the block gas limit. + +- Update appveyor rustc [beta] [#2521](https://github.com/paritytech/parity/pull/2521) +- Increase size of transaction queue by default [#2519](https://github.com/paritytech/parity/pull/2519) + +## Parity [v1.3.4](https://github.com/paritytech/parity/releases/tag/v1.3.4) (2016-10-07) + +Parity 1.3.4 release contains more optimizations to internal caching as well as stability improvements. + +It also introduces an ability for miners to choose a transaction ordering strategy: + + --tx-queue-strategy S Prioritization strategy used to order transactions + in the queue. S may be: + gas - Prioritize txs with low gas limit; + gas_price - Prioritize txs with high gas price; + gas_factor - Prioritize txs using gas price + and gas limit ratio [default: gas_factor]. + +- Backport to beta [#2518](https://github.com/paritytech/parity/pull/2518) +- [beta] Fixing RPC Filter conversion to EthFilter [#2501](https://github.com/paritytech/parity/pull/2501) +- [beta] Using pending block only if is not old [#2515](https://github.com/paritytech/parity/pull/2515) +- Backports into beta [#2512](https://github.com/paritytech/parity/pull/2512) +- CLI to specify queue ordering strategy [#2494](https://github.com/paritytech/parity/pull/2494) +- Fix ethstore opening all key files in the directory at once (BETA) [#2472](https://github.com/paritytech/parity/pull/2472) +- Beta backports [#2465](https://github.com/paritytech/parity/pull/2465) +- IPC-library dependency fork & bump for beta [#2455](https://github.com/paritytech/parity/pull/2455) + +## Parity [v1.3.3](https://github.com/paritytech/parity/releases/tag/v1.3.3) (2016-10-04) + +1.3.3 is another hotfix release for the DoS attack + +- Jumptable cache [#2435](https://github.com/paritytech/parity/pull/2435) +- fix broken beta compilation (backport to beta) [#2414](https://github.com/paritytech/parity/pull/2414) +- Run inplace upgrades after version update [#2411](https://github.com/paritytech/parity/pull/2411) + +## Parity [v1.3.2](https://github.com/paritytech/parity/releases/tag/v1.3.2) (2016-09-29) + +This is a hotfix release to address stability and performance issues uncovered during the network DoS attack. Full list of changes is available [here](https://github.com/paritytech/parity/compare/v1.3.1...v1.3.2) + +- Beta Backports [#2396](https://github.com/paritytech/parity/pull/2396) +- Fixing penalization in future [#2493](https://github.com/paritytech/parity/pull/2493) +- A quick fix for missing tree route blocks [#2400](https://github.com/paritytech/parity/pull/2400) +- Cache the fork block header after snapshot restoration [#2391](https://github.com/paritytech/parity/pull/2391) +- correct sync memory usage calculation (BETA) [#2386](https://github.com/paritytech/parity/pull/2386) +- Accounts bloom [#2357](https://github.com/paritytech/parity/pull/2357) +- Disable colors when generating signer token. [#2379](https://github.com/paritytech/parity/pull/2379) +- Fixing jit feature compilation [#2376](https://github.com/paritytech/parity/pull/2376) +- Clear state cache on sealed block import [#2377](https://github.com/paritytech/parity/pull/2377) +- DIV optimization (beta) [#2353](https://github.com/paritytech/parity/pull/2353) +- Canonical state cache [#2308](https://github.com/paritytech/parity/pull/2308) +- Reorder transaction_by_hash to favour canon search [#2331](https://github.com/paritytech/parity/pull/2331) +- Lenient bytes deserialization [#2340](https://github.com/paritytech/parity/pull/2340) +- Penalize transactions with gas above gas limit [#2271](https://github.com/paritytech/parity/pull/2271) +- Peek transaction queue via RPC [#2270](https://github.com/paritytech/parity/pull/2270) +- Handle RLP to string UTF-8 decoding errors (#2217) [#2226](https://github.com/paritytech/parity/pull/2226) +- Fixing compilation without default features [beta] [#2207](https://github.com/paritytech/parity/pull/2207) +- Avoid cloning clean stuff [beta backport] [#2173](https://github.com/paritytech/parity/pull/2173) +- v1.3.2 in beta [#2200](https://github.com/paritytech/parity/pull/2200) + +## Parity [v1.3.1](https://github.com/paritytech/parity/releases/tag/v1.3.1) (2016-09-11) + +1.3.1 includes many [bugfixes](https://github.com/paritytech/parity/commit/2a82fa0a47b00bedfec520a2fdd3cc31aa4ccd8c). Critical ones: +- **Chain reorganisation fix** Transaction receipts / traces were sometimes linked with incorrect block hash. Fixed in https://github.com/paritytech/parity/commit/a9587f8965a32c84973c35ce1c8d51d07044143f +- **Trace overflow fix** Overflow which occurred during tracing. Fixed in https://github.com/paritytech/parity/pull/1979 + +- Backports to beta [#2068](https://github.com/paritytech/parity/pull/2068) +- Fixing serde overflow error (#1977) [#2030](https://github.com/paritytech/parity/pull/2030) +- Simplified db pruning detection in beta [#1924](https://github.com/paritytech/parity/pull/1924) +- Backports to beta [#1919](https://github.com/paritytech/parity/pull/1919) + +## Parity [v1.3.0: "Acuity"](https://github.com/paritytech/parity/releases/tag/v1.3.0) (2016-08-12) + +As well as many bug fixes, 1.3.0 includes a number of important improvements including: +- **Optimisations** Heavily optimised block/transaction processing core - up to 2x faster than 1.2 series. +- **Database compression** Databases take as much as 30% less storage than before. +- **State snapshotting** An installation synchronised from scratch in 1-2 minutes can be made after downloading the 140MB state snapshot. See [the wiki](https://github.com/paritytech/parity/wiki/Getting-Synced) for more information. +- **Process isolation** The networking/chain-synchronisation is now a fully independent process. + +Incremental improvements include: +- Additional [RPCs](https://github.com/paritytech/parity/wiki/JSONRPC) for transaction tracing, state diffing, VM tracing, asynchronous transaction posting, accounts metadata and message signing. +- Improved logging, including for chain reorganisations. +- Added a `--fast-and-loose` option for additional speed-ups which can compromise integrity on a dirty shutdown. +- Column families to ensure maximal inter-database integrity. +- Key naming includes date/time of creation. +- Various improvements to networking robustness and performance. +- Solidity compilation supported through RPC if `solc` is available. +- Various improvements to the miner including [HTTP push work notification](https://github.com/ethcoreparitytech/parity/wiki/Mining#starting-it). + +Full changes: +- Bumping Parity UI [#1920](https://github.com/paritytech/parity/pull/1920) +- Adding entrypoints to docker images [#1909](https://github.com/paritytech/parity/pull/1909) +- Save nodes removed from backing_overlay until commit [#1917](https://github.com/paritytech/parity/pull/1917) +- RPC for importing geth keys [#1916](https://github.com/paritytech/parity/pull/1916) +- Peers RPC + UI displaying active/connected/max peers [#1915](https://github.com/paritytech/parity/pull/1915) +- RPC for deriving address from phrase. [#1912](https://github.com/paritytech/parity/pull/1912) +- adjust polling & connection timeouts for ipc [#1910](https://github.com/paritytech/parity/pull/1910) +- Don't return deleted nodes that are not yet flushed [#1908](https://github.com/paritytech/parity/pull/1908) +- Wallet rpcs [#1898](https://github.com/paritytech/parity/pull/1898) +- Fix binary serialization bug [#1907](https://github.com/paritytech/parity/pull/1907) +- fixed #1889, .DS_Store is no longer treated as key file [#1892](https://github.com/paritytech/parity/pull/1892) +- Purging .derefs, fixing clippy warnings. [#1890](https://github.com/paritytech/parity/pull/1890) +- RocksDB version bump [#1904](https://github.com/paritytech/parity/pull/1904) +- Fix ipc compilation and add ipc feature to test targets [#1902](https://github.com/paritytech/parity/pull/1902) +- Autocreating geth dir if none and geth mode on [#1896](https://github.com/paritytech/parity/pull/1896) +- v1.4.0 in master [#1886](https://github.com/paritytech/parity/pull/1886) +- Adding more details to miner log [#1891](https://github.com/paritytech/parity/pull/1891) +- moved hash.rs to bigint library [#1827](https://github.com/paritytech/parity/pull/1827) +- fixed cache_manager lock order [#1877](https://github.com/paritytech/parity/pull/1877) +- Fixing miner deadlock [#1885](https://github.com/paritytech/parity/pull/1885) +- Updating WS + Increasing token validity [#1882](https://github.com/paritytech/parity/pull/1882) +- take snapshot at specified block and slightly better informants [#1873](https://github.com/paritytech/parity/pull/1873) +- RPC errors & logs [#1845](https://github.com/paritytech/parity/pull/1845) +- Reduce max open files [#1876](https://github.com/paritytech/parity/pull/1876) +- Send new block hashes to all peers [#1875](https://github.com/paritytech/parity/pull/1875) +- Use UntrustedRlp for block verification [#1872](https://github.com/paritytech/parity/pull/1872) +- Update cache usage on commiting block info [#1871](https://github.com/paritytech/parity/pull/1871) +- Validating conversion U256->usize when doing gas calculation (for 32bits) [#1870](https://github.com/paritytech/parity/pull/1870) +- Sync to peers with confirmed fork block only [#1863](https://github.com/paritytech/parity/pull/1863) +- miner and client take spec reference [#1853](https://github.com/paritytech/parity/pull/1853) +- Unlock account with timeout for geth compatibility [#1854](https://github.com/paritytech/parity/pull/1854) +- Fixed reported max height and transaction propagation [#1852](https://github.com/paritytech/parity/pull/1852) +- Snapshot creation and restoration [#1679](https://github.com/paritytech/parity/pull/1679) +- fix deprecated typo [#1850](https://github.com/paritytech/parity/pull/1850) +- Split IO and network crates [#1828](https://github.com/paritytech/parity/pull/1828) +- updated classic JSON spec with classic bootnodes, fixes #1842 [#1847](https://github.com/paritytech/parity/pull/1847) +- protect unsafety in plainhasher; get more unique hashes [#1841](https://github.com/paritytech/parity/pull/1841) +- use mutex in dbtransaction [#1843](https://github.com/paritytech/parity/pull/1843) +- Fix state not using "account_starting_nonce" [#1830](https://github.com/paritytech/parity/pull/1830) +- Supporting blockid in eth_call and trace_call/trace_raw [#1837](https://github.com/paritytech/parity/pull/1837) +- eth_checkTransaction renamed to eth_checkRequest [#1817](https://github.com/paritytech/parity/pull/1817) +- Bump json-ipc-server again [#1839](https://github.com/paritytech/parity/pull/1839) +- Fixing another deadlock in trace db [#1833](https://github.com/paritytech/parity/pull/1833) +- Fix up the VM trace. [#1829](https://github.com/paritytech/parity/pull/1829) +- fixed parsing export params, fixes #1826 [#1834](https://github.com/paritytech/parity/pull/1834) +- More performance optimizations [#1814](https://github.com/paritytech/parity/pull/1814) +- Bumping clippy & fixing warnings [#1823](https://github.com/paritytech/parity/pull/1823) +- removed unused code from util and unnecessary dependency of FixedHash [#1824](https://github.com/paritytech/parity/pull/1824) +- Remove (almost all) panickers from trie module [#1776](https://github.com/paritytech/parity/pull/1776) +- Fixing account naming [#1810](https://github.com/paritytech/parity/pull/1810) +- JournalDB inject [#1806](https://github.com/paritytech/parity/pull/1806) +- No block number in get work while in geth-compat mode. [#1821](https://github.com/paritytech/parity/pull/1821) +- Import wallet fix [#1820](https://github.com/paritytech/parity/pull/1820) +- Supporting eth_sign in Signer [#1787](https://github.com/paritytech/parity/pull/1787) +- Fixing cache update after chain reorg [#1816](https://github.com/paritytech/parity/pull/1816) +- Development mode for Signer UI [#1788](https://github.com/paritytech/parity/pull/1788) +- Miner tweaks [#1797](https://github.com/paritytech/parity/pull/1797) +- Util & ipc clenup [#1807](https://github.com/paritytech/parity/pull/1807) +- Fixing unlock parsing [#1802](https://github.com/paritytech/parity/pull/1802) +- fixed importing presale wallet with encseed longer than 96 bytes [#1801](https://github.com/paritytech/parity/pull/1801) +- DRYing build scripts [#1795](https://github.com/paritytech/parity/pull/1795) +- Allow code from spec json [#1790](https://github.com/paritytech/parity/pull/1790) +- nano-tests (ipc transport) to the CI [#1793](https://github.com/paritytech/parity/pull/1793) +- Commit best block after closing transaction [#1791](https://github.com/paritytech/parity/pull/1791) +- Place thread name in the log output [#1792](https://github.com/paritytech/parity/pull/1792) +- Fix ipc tests and bring to CI [#1789](https://github.com/paritytech/parity/pull/1789) +- dynamic keys pickup [#1779](https://github.com/paritytech/parity/pull/1779) +- ipc version bump [#1783](https://github.com/paritytech/parity/pull/1783) +- Prevent deadlock on trace GC [#1780](https://github.com/paritytech/parity/pull/1780) +- fixed trace_transaction crash when block contained suicide [#1781](https://github.com/paritytech/parity/pull/1781) +- Fix block body migration [#1777](https://github.com/paritytech/parity/pull/1777) +- cache manager and clearing tracing cache [#1769](https://github.com/paritytech/parity/pull/1769) +- Return storage as H256 from RPC. [#1774](https://github.com/paritytech/parity/pull/1774) +- Instant sealing engine [#1767](https://github.com/paritytech/parity/pull/1767) +- fix state unsafety with a mostly-guaranteed handle [#1755](https://github.com/paritytech/parity/pull/1755) +- Gas for mem optimization [#1768](https://github.com/paritytech/parity/pull/1768) +- Min and Max peers setting [#1771](https://github.com/paritytech/parity/pull/1771) +- Disable WAL [#1765](https://github.com/paritytech/parity/pull/1765) +- Add new line when printing start strings [#1766](https://github.com/paritytech/parity/pull/1766) +- Log tweak [#1764](https://github.com/paritytech/parity/pull/1764) +- Remove update_sealing call on importing own block [#1762](https://github.com/paritytech/parity/pull/1762) +- Single DB [#1741](https://github.com/paritytech/parity/pull/1741) +- Tweak format of log so it's not so verbose. [#1758](https://github.com/paritytech/parity/pull/1758) +- Combine mining queue and enabled into single locked datum [#1749](https://github.com/paritytech/parity/pull/1749) +- Collect consensus/null engines into a single module [#1754](https://github.com/paritytech/parity/pull/1754) +- Fix failing deserialization test [#1756](https://github.com/paritytech/parity/pull/1756) +- Stackoverflow fix [#1742](https://github.com/paritytech/parity/pull/1742) +- compaction profile used during migration, fixes #1750 [#1751](https://github.com/paritytech/parity/pull/1751) +- Splitting documentation into separate build job [#1752](https://github.com/paritytech/parity/pull/1752) +- handle keys deserialization errors, fixes #1592 [#1701](https://github.com/paritytech/parity/pull/1701) +- add gitlab-ci yaml [#1753](https://github.com/paritytech/parity/pull/1753) +- Better handling of multiple migrations [#1747](https://github.com/paritytech/parity/pull/1747) +- Disconnect peers on a fork [#1738](https://github.com/paritytech/parity/pull/1738) +- Add RPC & client call to replay a transaction. [#1734](https://github.com/paritytech/parity/pull/1734) +- another version bump for jsonrpc-ipc [#1744](https://github.com/paritytech/parity/pull/1744) +- Trace other types of calls [#1727](https://github.com/paritytech/parity/pull/1727) +- Fixing compilation on latest nightly [#1736](https://github.com/paritytech/parity/pull/1736) +- Blocks and snapshot compression [#1687](https://github.com/paritytech/parity/pull/1687) +- bump json-ipc-server version [#1739](https://github.com/paritytech/parity/pull/1739) +- Use std::sync::Condvar [#1732](https://github.com/paritytech/parity/pull/1732) +- Bump json-ipc-server version [#1733](https://github.com/paritytech/parity/pull/1733) +- bump json-ipc-server version [#1731](https://github.com/paritytech/parity/pull/1731) +- Fixing some clippy warnings [#1728](https://github.com/paritytech/parity/pull/1728) +- Bumping Parity UI [#1682](https://github.com/paritytech/parity/pull/1682) +- Various improvements to tracing & diagnostics. [#1707](https://github.com/paritytech/parity/pull/1707) +- Fixed reading chunked EIP8 handshake [#1712](https://github.com/paritytech/parity/pull/1712) +- Fix for importing blocks from a pipe file [#1724](https://github.com/paritytech/parity/pull/1724) +- Proper errors for binary serializer [#1714](https://github.com/paritytech/parity/pull/1714) +- Use a transaction for writing blocks [#1718](https://github.com/paritytech/parity/pull/1718) +- Exclude generated code from coverage [#1720](https://github.com/paritytech/parity/pull/1720) +- Use single binary for ipc modules [#1710](https://github.com/paritytech/parity/pull/1710) +- Log a chain-reorg. [#1715](https://github.com/paritytech/parity/pull/1715) +- Restore new block informant message [#1716](https://github.com/paritytech/parity/pull/1716) +- Parallel block body download [#1659](https://github.com/paritytech/parity/pull/1659) +- Rotate blockchain cache [#1709](https://github.com/paritytech/parity/pull/1709) +- Fix broken internal names. [#1711](https://github.com/paritytech/parity/pull/1711) +- cli overhaul [#1600](https://github.com/paritytech/parity/pull/1600) +- Key files include timestamp in name. [#1700](https://github.com/paritytech/parity/pull/1700) +- Fixing warnings [#1705](https://github.com/paritytech/parity/pull/1705) +- Ethereum classic [#1706](https://github.com/paritytech/parity/pull/1706) +- Docker Arguments [#1703](https://github.com/paritytech/parity/pull/1703) +- Informant tidyup. [#1699](https://github.com/paritytech/parity/pull/1699) +- Name and meta in accounts [#1695](https://github.com/paritytech/parity/pull/1695) +- Stackoverflow #1686 [#1698](https://github.com/paritytech/parity/pull/1698) +- filtering transactions toAddress includes contract creation [#1697](https://github.com/paritytech/parity/pull/1697) +- Prevent syncing to ancient blocks [#1693](https://github.com/paritytech/parity/pull/1693) +- Enable WAL and disable DB repair [#1696](https://github.com/paritytech/parity/pull/1696) +- Returning error when transaction is rejected (for consistency) [#1667](https://github.com/paritytech/parity/pull/1667) +- Disabling signer when in geth-compatibility mode [#1676](https://github.com/paritytech/parity/pull/1676) +- Suicides tracing [#1688](https://github.com/paritytech/parity/pull/1688) +- small cleanup of substate.rs [#1685](https://github.com/paritytech/parity/pull/1685) +- resolve #411: remove install scripts [#1684](https://github.com/paritytech/parity/pull/1684) +- IPC (feature-gated) [#1654](https://github.com/paritytech/parity/pull/1654) +- Bumping JSONRPC-http-server [#1678](https://github.com/paritytech/parity/pull/1678) +- Fixing hash deserialisation [#1674](https://github.com/paritytech/parity/pull/1674) +- Ping discovery nodes gradually [#1671](https://github.com/paritytech/parity/pull/1671) +- Fixing the deadlock on incoming connection [#1672](https://github.com/paritytech/parity/pull/1672) +- Fixing errors returned by sendTransaction* method family [#1665](https://github.com/paritytech/parity/pull/1665) +- Moved syncing log out of the client [#1670](https://github.com/paritytech/parity/pull/1670) +- Host validation (again) [#1666](https://github.com/paritytech/parity/pull/1666) +- Update install-deps.sh [ci skip] [#1664](https://github.com/paritytech/parity/pull/1664) +- fix typos [#1644](https://github.com/paritytech/parity/pull/1644) +- Size for blocks [#1668](https://github.com/paritytech/parity/pull/1668) +- Revert "Validating Host headers in RPC requests" [#1663](https://github.com/paritytech/parity/pull/1663) +- Validating Host headers in RPC requests [#1658](https://github.com/paritytech/parity/pull/1658) +- fixed failing master [#1662](https://github.com/paritytech/parity/pull/1662) +- Fixing clippy warnings [#1660](https://github.com/paritytech/parity/pull/1660) +- Don't ping all nodes on start [#1656](https://github.com/paritytech/parity/pull/1656) +- More performance optimizations [#1649](https://github.com/paritytech/parity/pull/1649) +- Removing unused client code [#1645](https://github.com/paritytech/parity/pull/1645) +- Asynchronous transactions (polling based for now). [#1652](https://github.com/paritytech/parity/pull/1652) +- Sync stand-alone binary and feature-gated dependencies refactoring [#1637](https://github.com/paritytech/parity/pull/1637) +- Re-enabling Parity UI [#1627](https://github.com/paritytech/parity/pull/1627) +- Blockchain repair on missing state root [#1646](https://github.com/paritytech/parity/pull/1646) +- Multi-mode logging. [#1643](https://github.com/paritytech/parity/pull/1643) +- Pro paths [#1650](https://github.com/paritytech/parity/pull/1650) +- Performance optimizations [#1642](https://github.com/paritytech/parity/pull/1642) +- Removed DAO soft fork traces [#1639](https://github.com/paritytech/parity/pull/1639) +- Compiler version update for windows [#1638](https://github.com/paritytech/parity/pull/1638) +- Delete values immediately from DB overlay [#1631](https://github.com/paritytech/parity/pull/1631) +- DAO hard-fork [#1483](https://github.com/paritytech/parity/pull/1483) +- fix network_start regression [#1629](https://github.com/paritytech/parity/pull/1629) +- Die if the DB is newer than the one supported. [#1630](https://github.com/paritytech/parity/pull/1630) +- Cleanup of colour code. Use is_a_tty. [#1621](https://github.com/paritytech/parity/pull/1621) +- don't batch best block for branches [#1623](https://github.com/paritytech/parity/pull/1623) +- In-memory trie operations [#1408](https://github.com/paritytech/parity/pull/1408) +- Fix "pending" parameter on RPC block requests [#1602](https://github.com/paritytech/parity/pull/1602) +- Allow RPC to use solc to compile solidity [#1607](https://github.com/paritytech/parity/pull/1607) +- IPC RPC deriving for traits [#1599](https://github.com/paritytech/parity/pull/1599) +- Utilize cached kcov if exists [#1619](https://github.com/paritytech/parity/pull/1619) +- Fixing no-ui feature [#1618](https://github.com/paritytech/parity/pull/1618) +- Couple of rocksdb optimizations [#1614](https://github.com/paritytech/parity/pull/1614) +- Miner tests [#1597](https://github.com/paritytech/parity/pull/1597) +- Sync IPC interface [#1584](https://github.com/paritytech/parity/pull/1584) +- Make sure reserved peers are in the node table [#1616](https://github.com/paritytech/parity/pull/1616) +- Fix bloomchain on blockchain repair [#1610](https://github.com/paritytech/parity/pull/1610) +- fixed broken tracing [#1615](https://github.com/paritytech/parity/pull/1615) +- fix benchmark compilation [#1612](https://github.com/paritytech/parity/pull/1612) +- Updating jsonrpc-http-server [#1611](https://github.com/paritytech/parity/pull/1611) +- replace synchronization primitives with those from parking_lot [#1593](https://github.com/paritytech/parity/pull/1593) +- ui compilation feature [#1604](https://github.com/paritytech/parity/pull/1604) +- is_zero() and pow() optimisations for uint [#1608](https://github.com/paritytech/parity/pull/1608) +- Optimizing & Cleaning the build [#1591](https://github.com/paritytech/parity/pull/1591) +- Fix logging [#1590](https://github.com/paritytech/parity/pull/1590) +- remove unnecessary mutex in logging [#1601](https://github.com/paritytech/parity/pull/1601) +- Using streamlined parity-ui repository [#1566](https://github.com/paritytech/parity/pull/1566) +- Optimizing InstructionInfo access. [#1595](https://github.com/paritytech/parity/pull/1595) +- V7 Migration progress indicator [#1594](https://github.com/paritytech/parity/pull/1594) +- bring snapshotting work into master [#1577](https://github.com/paritytech/parity/pull/1577) +- Bump clippy [#1587](https://github.com/paritytech/parity/pull/1587) +- refactoring of handshake messages serialization in ipc [#1586](https://github.com/paritytech/parity/pull/1586) +- expunge &Vec pattern [#1579](https://github.com/paritytech/parity/pull/1579) +- EVM gas for memory tiny optimization [#1578](https://github.com/paritytech/parity/pull/1578) +- cleaned up parity/signer [#1551](https://github.com/paritytech/parity/pull/1551) +- Major sync <-> client interactions refactoring [#1572](https://github.com/paritytech/parity/pull/1572) +- failing test with overlayrecent pruning [#1567](https://github.com/paritytech/parity/pull/1567) +- Enable state queries for OverlayRecent DB [#1575](https://github.com/paritytech/parity/pull/1575) +- have AccountDB use address hash for uniqueness [#1533](https://github.com/paritytech/parity/pull/1533) +- Very basic EVM binary. [#1574](https://github.com/paritytech/parity/pull/1574) +- Some obvious evm & uint optimizations [#1576](https://github.com/paritytech/parity/pull/1576) +- Fixing clippy warnings [#1568](https://github.com/paritytech/parity/pull/1568) +- Miner's gas price gets updated dynamically [#1570](https://github.com/paritytech/parity/pull/1570) +- bringing hypervisor as a crate in ipc dir [#1565](https://github.com/paritytech/parity/pull/1565) +- Init public interface with IO message [#1573](https://github.com/paritytech/parity/pull/1573) +- Uncommenting simple Miner tests [#1571](https://github.com/paritytech/parity/pull/1571) +- Kill lock unwraps [#1558](https://github.com/paritytech/parity/pull/1558) +- Fixing deadlock in miner [#1569](https://github.com/paritytech/parity/pull/1569) +- Idealpeers in log [#1563](https://github.com/paritytech/parity/pull/1563) +- Simple style fix. [#1561](https://github.com/paritytech/parity/pull/1561) +- Enum variants serialisation test&fix [#1559](https://github.com/paritytech/parity/pull/1559) +- Supporting /api/ping for dapps server [#1543](https://github.com/paritytech/parity/pull/1543) +- Client IPC Interface [#1493](https://github.com/paritytech/parity/pull/1493) +- Kill timers when removing IO handler [#1554](https://github.com/paritytech/parity/pull/1554) +- Fix and add info messages [#1552](https://github.com/paritytech/parity/pull/1552) +- Fix indent of #1541 [#1555](https://github.com/paritytech/parity/pull/1555) +- Update sealing just once when externally importing many blocks [#1541](https://github.com/paritytech/parity/pull/1541) +- Remove soft-fork stuff. [#1548](https://github.com/paritytech/parity/pull/1548) +- fix codegen warning [#1550](https://github.com/paritytech/parity/pull/1550) +- Extend migration framework [#1546](https://github.com/paritytech/parity/pull/1546) +- Refactoring dapps to support API endpoints. [#1542](https://github.com/paritytech/parity/pull/1542) +- serde is no longer util dependency [#1534](https://github.com/paritytech/parity/pull/1534) +- mention wiki in README [#1549](https://github.com/paritytech/parity/pull/1549) +- Skipping transactions with invalid nonces when pushing to block. [#1545](https://github.com/paritytech/parity/pull/1545) +- Silent running operating modes [#1477](https://github.com/paritytech/parity/pull/1477) +- util cleanup [#1474](https://github.com/paritytech/parity/pull/1474) +- Calculating gas using usize (if supplied gaslimit fits in usize) [#1518](https://github.com/paritytech/parity/pull/1518) +- add owning NibbleVec [#1536](https://github.com/paritytech/parity/pull/1536) +- Attempt to fix blochchain/extras DBs sync [#1538](https://github.com/paritytech/parity/pull/1538) +- Client API refactoring - limiting errors to crate-level error types [#1525](https://github.com/paritytech/parity/pull/1525) +- IPC codegen enhancement - allow void methods [#1540](https://github.com/paritytech/parity/pull/1540) +- Fixing serving nested files for dapps. [#1539](https://github.com/paritytech/parity/pull/1539) +- Fixed public address config [#1537](https://github.com/paritytech/parity/pull/1537) +- Fixing compilation&clippy warnings [#1531](https://github.com/paritytech/parity/pull/1531) +- creating ethereum dir while in geth mode [#1530](https://github.com/paritytech/parity/pull/1530) +- Bumping clippy [#1532](https://github.com/paritytech/parity/pull/1532) +- Make signer default as long as --unlock isn't used. [#1524](https://github.com/paritytech/parity/pull/1524) +- add client timeout when requesting usd price for gas [#1526](https://github.com/paritytech/parity/pull/1526) +- Fix gitter-url link in README.md [#1528](https://github.com/paritytech/parity/pull/1528) +- Fix error message. [#1527](https://github.com/paritytech/parity/pull/1527) +- BTreeMap binary serialization [#1489](https://github.com/paritytech/parity/pull/1489) +- Save block reference in the queue on notification [#1501](https://github.com/paritytech/parity/pull/1501) +- bigint tests to run on CI [#1522](https://github.com/paritytech/parity/pull/1522) +- Client api cleaning - uncles are returned as rlp [#1516](https://github.com/paritytech/parity/pull/1516) +- Fatdb integration with CLI [#1464](https://github.com/paritytech/parity/pull/1464) +- Optimizing/simplifying shr [#1517](https://github.com/paritytech/parity/pull/1517) +- change IPC codegen to allow attributes [#1500](https://github.com/paritytech/parity/pull/1500) +- Fix warnings [#1514](https://github.com/paritytech/parity/pull/1514) +- FatDB [#1452](https://github.com/paritytech/parity/pull/1452) +- Fix the reseal mechanism. [#1513](https://github.com/paritytech/parity/pull/1513) +- Update Dockerfile ubuntu-aarch64 [#1509](https://github.com/paritytech/parity/pull/1509) +- Update Ubuntu-arm Dockerfile [#1510](https://github.com/paritytech/parity/pull/1510) +- Update Ubuntu-jit Dockerfile [#1511](https://github.com/paritytech/parity/pull/1511) +- Update Ubuntu Dockerfile [#1512](https://github.com/paritytech/parity/pull/1512) +- Update CentOS Dockerfile [#1508](https://github.com/paritytech/parity/pull/1508) +- bump status page v0.5.1 [#1502](https://github.com/paritytech/parity/pull/1502) +- Update CentOS Dockerfile [#1507](https://github.com/paritytech/parity/pull/1507) +- Update Dockerfile ubuntu-aarch64 [#1506](https://github.com/paritytech/parity/pull/1506) +- Update Ubuntu-arm Dockerfile [#1505](https://github.com/paritytech/parity/pull/1505) +- Update Ubuntu-jit Dockerfile [#1504](https://github.com/paritytech/parity/pull/1504) +- Update Ubuntu Dockerfile [#1503](https://github.com/paritytech/parity/pull/1503) +- Optionally clone block behind work-package [#1497](https://github.com/paritytech/parity/pull/1497) +- Fix no colour on windows. [#1498](https://github.com/paritytech/parity/pull/1498) +- Workaround for hyper panic [#1495](https://github.com/paritytech/parity/pull/1495) +- Colourful notification on mine [#1488](https://github.com/paritytech/parity/pull/1488) +- Quick fix for max open files error [#1494](https://github.com/paritytech/parity/pull/1494) +- Work notification over HTTP [#1491](https://github.com/paritytech/parity/pull/1491) +- Sealed block importing and propagation optimization [#1478](https://github.com/paritytech/parity/pull/1478) +- vm factory to mining client [#1487](https://github.com/paritytech/parity/pull/1487) +- topbar dialog fix [#1479](https://github.com/paritytech/parity/pull/1479) +- Minor additions to allow resetting of code. [#1482](https://github.com/paritytech/parity/pull/1482) +- Introduce options for fine-grained management of work queue. [#1484](https://github.com/paritytech/parity/pull/1484) +- Snapshot state restoration [#1308](https://github.com/paritytech/parity/pull/1308) +- Merge master into pv64 branch [#1486](https://github.com/paritytech/parity/pull/1486) +- Ensure we don't reject our own transactions for gasprice. [#1485](https://github.com/paritytech/parity/pull/1485) +- Signing parity executable & windows installer in appveyor [#1481](https://github.com/paritytech/parity/pull/1481) +- Rearrange fork CLI options. [#1476](https://github.com/paritytech/parity/pull/1476) +- give appveyor some breath [#1475](https://github.com/paritytech/parity/pull/1475) +- Ensure we always get the latest work when mining on submitted. [#1469](https://github.com/paritytech/parity/pull/1469) +- Tests for views [#1471](https://github.com/paritytech/parity/pull/1471) +- json ipc version bump [#1470](https://github.com/paritytech/parity/pull/1470) +- verifier is no longer a template type of client [#1467](https://github.com/paritytech/parity/pull/1467) +- Allow configuration of when to reseal blocks. [#1460](https://github.com/paritytech/parity/pull/1460) +- removed unsafe code [#1466](https://github.com/paritytech/parity/pull/1466) +- WS bump + Adding default for value [#1465](https://github.com/paritytech/parity/pull/1465) +- Attempt DB repair if corrupted [#1461](https://github.com/paritytech/parity/pull/1461) +- Database configuration extended [#1454](https://github.com/paritytech/parity/pull/1454) +- Updating WS-RS server [#1459](https://github.com/paritytech/parity/pull/1459) +- Reduced IO messages; removed panics on IO notifications [#1457](https://github.com/paritytech/parity/pull/1457) +- Handle errors when starting parity --signer [#1451](https://github.com/paritytech/parity/pull/1451) +- Fixed losing queued blocks on error [#1453](https://github.com/paritytech/parity/pull/1453) +- Updated to latest hyper with patched mio [#1450](https://github.com/paritytech/parity/pull/1450) +- Retweak BASE and MULTIPLIER in rocksdb config. [#1445](https://github.com/paritytech/parity/pull/1445) +- Removing Miner::default. [#1410](https://github.com/paritytech/parity/pull/1410) +- Don't mine without --author [#1436](https://github.com/paritytech/parity/pull/1436) +- Revert the rescuedao extradata. [#1437](https://github.com/paritytech/parity/pull/1437) +- More conservative settings for rocksdb. [#1440](https://github.com/paritytech/parity/pull/1440) +- v1.3.0 in master [#1421](https://github.com/paritytech/parity/pull/1421) +- Update Ubuntu-arm Dockerfile [#1429](https://github.com/paritytech/parity/pull/1429) +- Create Dockerfile ubuntu-aarch64 [#1430](https://github.com/paritytech/parity/pull/1430) +- Update CentOS Dockerfile [#1424](https://github.com/paritytech/parity/pull/1424) +- Update Ubuntu Dockerfile [#1426](https://github.com/paritytech/parity/pull/1426) +- Update Ubuntu-jit Dockerfile [#1427](https://github.com/paritytech/parity/pull/1427) +- Update SF blocknumber to 1800000. [#1418](https://github.com/paritytech/parity/pull/1418) + +## Parity [v1.2.4](https://github.com/paritytech/parity/releases/tag/v1.2.4) (2016-08-09) + +Parity 1.2.4 Is a maintenance release that fixes a [few](https://github.com/paritytech/parity/pull/1888/commits) issues related to mining and peer synchronization. +This release is marked as stable. + +- Backports for beta [#1888](https://github.com/paritytech/parity/pull/1888) +- BETA: fixed trace_transaction crash when block contained suicide [#1782](https://github.com/paritytech/parity/pull/1782) + +## Parity [v1.2.3](https://github.com/paritytech/parity/releases/tag/v1.2.3) (2016-07-31) + +Parity 1.2.3 is a patch release that addresses network stability issues for both Ethereum HF and Ethereum classic chains and brings a few changes to the transaction tracing API. + +#### Tracing API changes +- Added tracing for `CALLCODE`, `DELEGATECALL` and `SUICIDE` +- `trace_call` returns traces in flat format +- Added 2 new methods: `trace_rawTransaction` and `trace_replayTransaction` + +Note that to continue using tracing features in this version you need to re-sync the blockchain. This can be done by using `parity export $HOME/ethereum-chain-backup.rlp` , deleting the database usually located at `~/.parity/906a34e69aec8c0d` followed by `parity import $HOME/ethereum-chain-backup.rlp`. + +- [beta] Updating UI [#1778](https://github.com/paritytech/parity/pull/1778) +- tracing backport [#1770](https://github.com/paritytech/parity/pull/1770) +- Backport commits to beta [#1763](https://github.com/paritytech/parity/pull/1763) +- Deadlock on incoming connection (#1672) [#1675](https://github.com/paritytech/parity/pull/1675) +- [BETA] Removed DAO soft fork traces [#1640](https://github.com/paritytech/parity/pull/1640) + + +## Parity [v1.2.2](https://github.com/paritytech/parity/releases/tag/v1.2.2) (2016-07-16) + +#### New +- DAO hard-fork. + +DAO hard-fork implementation conforms to the [specification](https://blog.slock.it/hard-fork-specification-24b889e70703) and is enabled by default. + +#### Changed +- `--reseal-on-txs` defaults to `own`. +- DAO soft-fork support has been removed along with related command line options. + +#### Resolved issues +- `--db-cache-size` consuming too much memory. + `eth_getWork` RPC response additionally includes the block number. +- Skipping transactions with invalid nonces when pushing to block. +- Update sealing just once when externally importing many blocks (#1541). +- Transaction tracing skipping simple transactions (#1606). +- Other small fixes and improvements. + +Full changelog + +- DAO hard-fork (#1483) [#1636](https://github.com/paritytech/parity/pull/1636) +- Backports for beta [#1628](https://github.com/paritytech/parity/pull/1628) +- don't batch best block for branches (#1623) [#1626](https://github.com/paritytech/parity/pull/1626) +- Merge bugfixes from master to beta [#1605](https://github.com/paritytech/parity/pull/1605) +- (BETA) using block options cache instead of general cache for rocksdb [#1613](https://github.com/paritytech/parity/pull/1613) +- Backport sealing fixes to beta [#1583](https://github.com/paritytech/parity/pull/1583) +- v1.2.2 in beta [#1581](https://github.com/paritytech/parity/pull/1581) +- Skipping transactions with invalid nonces when pushing to block. (#1545) [#1547](https://github.com/paritytech/parity/pull/1547) + + +## Parity [v1.2.1](https://github.com/paritytech/parity/releases/tag/v1.2.1) (2016-07-01) + +#### New +- Options for more precise mining tuning (see below). +- Informative notification when block mined. +- HTTP signal on new work-package. +- Optimised database insertion for self-mined blocks. +- Short-circuit for local transaction gas-price approval. +- A number of issues related to mining have been fixed. + +##### Mining options +- `--author` is now required for mining. +- `--reseal-on-txs` Specify which transactions should force the node to reseal a block. By default parity updates the seal on incoming transactions to reduce transaction latency. Set this option to `none` to force updates on new blocks only. +- `--reseal-min-period` Can be used to control how often a new pending block is generated if `none` is not selected on prior option. +- `--work-queue-size` Controls how many pending blocks to keep in memory. +- `--relay-set` Can be used to enable more strict transaction verification. +- `--remove-solved` Move solved blocks from the work package queue instead of cloning them. This gives a slightly faster import speed, but means that extra solutions submitted for the same work package will go unused. +- `--notify-work` Accepts a list of URLs that will receive a POST request when new work package is available. The body of the POST message is JSON encoded and has the same format as `eth_getWork` RPC response. + +##### RPC + +`eth_getWork` RPC response additionally includes the block number. + +##### DAO soft-fork + +DAO soft-fork control options have been replaced by the single `--fork` option which disables the soft-fork by default. + +#### Changes + +- v1.2.1 in beta [#1492](https://github.com/paritytech/parity/pull/1492) +- (BETA) add artifacts [#1420](https://github.com/paritytech/parity/pull/1420) + +## Parity [v1.2.0: "Security"](https://github.com/paritytech/parity/releases/tag/v1.2.0) (2016-06-24) + +[Blog post](https://blog.parity.io/announcing-parity-1-2/) + +#### New + +- Transaction signing UI. +- IPC/RPC module. +- Optimised mining support. +- Windows build. +- DAO soft-fork support. + +##### Transaction signing UI + +This is a new framework for signing transactions. It fulfills three requirements: +- You should never have to type your passwords into a Dapp. +- No Javascript code should ever hold a secret. +- No transaction should ever be signed without the consent of the user. + +The feature is enabled through the `--signer` flag. When enabled, the user must ensure at least one "Signer UI" is set-up for managing transaction confirmation. There are two such UIs available; one through a Google Chrome Extension, separately installable and the second through a special web page hosted locally. Set-up must be done once for each such UI, through copying and pasting a token from the output console of Parity into the UI. Specific instructions are given in the UI. + +From this point on, no transaction may ever be signed by Parity except through one of these allowed Signer UIs, and no password should ever be entered anywhere else. + +##### IPC/RPC module and Mist/Geth compatibility + +Should be started with `--geth` to ensure Mist compatibility. + +##### Optimised mining support + +Numerous improvements and optimisations have been added to our mining implementation. A large "active queue" ensures that late-included transactions are included in the mined block without sacrificing older results from latent-reported `ethminer` results. + +##### Windows build + +We're happy to announce full Windows support with 1.2! + +##### Soft-fork + +This release includes support for the proposed [DAO soft-fork](https://docs.google.com/document/d/10RktunzjKNfp6Y8Cu4EhR5V9IqxEZq42LU126EYhWY4/pub). Upon upgrade, all mining nodes can vote for or against the soft fork (this is done through altering the block gas limit; a gas limit of at most 4M results in the soft-fork being triggered). + +By default, nodes vote "for" the DAO soft-fork (and try to reduce the gas limit to 3.1M). To vote against the soft-fork (keeping it at 4.7M), run with `--dont-help-rescue-dao`. Not upgrading is not recommended; if the majority votes with a soft-fork, an upgrade will be necessary to mine on the correct chain. + +#### Changed +- Fast pruning method is now default for a fresh sync. +- Web UI renamed to Dapps UI. +- JSONRPC and Dapps UI enabled by default. +- CLI options ending `-off` renamed to GNU-consistent prefix `--no-`. +- Dynamic gas-pricing (data feed and statistical techniques used to determine optimum gas prices). + +Full changes: + +- Signer enabled by default for UI [#1417](https://github.com/paritytech/parity/pull/1417) +- Remove experimental pruning options. [#1415](https://github.com/paritytech/parity/pull/1415) +- Fixing interface and port for parity ui [#1414](https://github.com/paritytech/parity/pull/1414) +- Configurable gas limit cap. [#1405](https://github.com/paritytech/parity/pull/1405) +- Bumping TopBar, Minimal SignerUI and wallet [#1413](https://github.com/paritytech/parity/pull/1413) +- Sync: Update highest block for progress reporting [#1411](https://github.com/paritytech/parity/pull/1411) +- Tweaked CLI options for the release [#1407](https://github.com/paritytech/parity/pull/1407) +- Further rocksdb tuning [#1409](https://github.com/paritytech/parity/pull/1409) +- Fixing jit compilation [#1406](https://github.com/paritytech/parity/pull/1406) +- Bump clippy [#1403](https://github.com/paritytech/parity/pull/1403) +- Shortcut SF condition when canon known [#1401](https://github.com/paritytech/parity/pull/1401) +- Additional assertions for internal state of queue [#1402](https://github.com/paritytech/parity/pull/1402) +- Replace deprecated hashdb trait names [#1394](https://github.com/paritytech/parity/pull/1394) +- rpc api by default for ipc [#1400](https://github.com/paritytech/parity/pull/1400) +- Ensure judging the SF trigger by relative branch [#1399](https://github.com/paritytech/parity/pull/1399) +- Signer with unlocked account working as expected. [#1398](https://github.com/paritytech/parity/pull/1398) +- Make --signer default. [#1392](https://github.com/paritytech/parity/pull/1392) +- Presale wallet [#1376](https://github.com/paritytech/parity/pull/1376) +- Removing signer connection limit [#1396](https://github.com/paritytech/parity/pull/1396) +- Optional gas price in transactions come from statistics [#1388](https://github.com/paritytech/parity/pull/1388) +- Update README.md with cargo install [ci-skip] [#1389](https://github.com/paritytech/parity/pull/1389) +- Fixing possible overflow during multiplication [#1381](https://github.com/paritytech/parity/pull/1381) +- Update SF to latest spec [#1386](https://github.com/paritytech/parity/pull/1386) +- Sync optimization [#1385](https://github.com/paritytech/parity/pull/1385) +- Fixing order of if statements to avoid overflows. [#1384](https://github.com/paritytech/parity/pull/1384) +- New topbar & signer UI [#1383](https://github.com/paritytech/parity/pull/1383) +- Install trigger for DAO-rescue soft-fork. [#1329](https://github.com/paritytech/parity/pull/1329) +- Rocksdb flush/compact limit [#1375](https://github.com/paritytech/parity/pull/1375) +- CentOS Dockerfile [#1377](https://github.com/paritytech/parity/pull/1377) +- RPC method to return number of unconfirmed transactions... [#1371](https://github.com/paritytech/parity/pull/1371) +- bump jsonrpc-http-server [#1369](https://github.com/paritytech/parity/pull/1369) +- Fix lock order when updating sealing [#1364](https://github.com/paritytech/parity/pull/1364) +- Update sealing on new transactions [#1365](https://github.com/paritytech/parity/pull/1365) +- Fixed panic on aborted connection [#1370](https://github.com/paritytech/parity/pull/1370) +- importing presale wallet [#1368](https://github.com/paritytech/parity/pull/1368) +- Set default database file size large enough [#1363](https://github.com/paritytech/parity/pull/1363) +- Reserved peers rpc API [#1360](https://github.com/paritytech/parity/pull/1360) +- Fixing replacing transaction with lower gas_price result. [#1343](https://github.com/paritytech/parity/pull/1343) +- fixed migration of empty pruning dir [#1362](https://github.com/paritytech/parity/pull/1362) +- Transaction processing queue [#1335](https://github.com/paritytech/parity/pull/1335) +- Fixing last nonce values in case transaction is replaced [#1359](https://github.com/paritytech/parity/pull/1359) +- docopt is an optional dependency of ethkey and ethstore [#1358](https://github.com/paritytech/parity/pull/1358) +- Fixing clippy warnings [#1354](https://github.com/paritytech/parity/pull/1354) +- Reduce locking when syncing [#1357](https://github.com/paritytech/parity/pull/1357) +- removed unnecessary logs [#1356](https://github.com/paritytech/parity/pull/1356) +- Updating parity-dapps [#1353](https://github.com/paritytech/parity/pull/1353) +- moved keystore tests files from util to ethstore [#1352](https://github.com/paritytech/parity/pull/1352) +- removed redundant bigint deps [#1351](https://github.com/paritytech/parity/pull/1351) +- Reopen "reserved peers and reserved-only flag" [#1350](https://github.com/paritytech/parity/pull/1350) +- Configurable rocksdb cache size [#1348](https://github.com/paritytech/parity/pull/1348) +- Fixing future order and errors when reaching limit. [#1346](https://github.com/paritytech/parity/pull/1346) +- Removing priority on local transactions [#1342](https://github.com/paritytech/parity/pull/1342) +- Revert "Reserved peers, reserved-only flag" [#1349](https://github.com/paritytech/parity/pull/1349) +- Sync attack defense: Deactivate peers on invalid block bodies [#1345](https://github.com/paritytech/parity/pull/1345) +- Reserved peers, reserved-only flag [#1347](https://github.com/paritytech/parity/pull/1347) +- CI for ethkey and ethstore [#1341](https://github.com/paritytech/parity/pull/1341) +- Fixed empty block body composition [#1340](https://github.com/paritytech/parity/pull/1340) +- Provide a signer UI token by default. [#1334](https://github.com/paritytech/parity/pull/1334) +- docker uses rustup, fixes #1337 [#1344](https://github.com/paritytech/parity/pull/1344) +- Fixed network service dispose [#1339](https://github.com/paritytech/parity/pull/1339) +- Sync: Cache last sync round block parents [#1331](https://github.com/paritytech/parity/pull/1331) +- secret store separated from util [#1304](https://github.com/paritytech/parity/pull/1304) +- --geth prevent getTransactionReceipt from using pending. [#1325](https://github.com/paritytech/parity/pull/1325) +- Fixing locks order in miner. [#1328](https://github.com/paritytech/parity/pull/1328) +- Update default gas limit, rename field [#1324](https://github.com/paritytech/parity/pull/1324) +- Use constants for DatabaseConfig [#1318](https://github.com/paritytech/parity/pull/1318) +- Fixing clippy warnings [#1321](https://github.com/paritytech/parity/pull/1321) +- Bumping topbar. Fixing ws server closing when suspending [#1312](https://github.com/paritytech/parity/pull/1312) +- Syncing fix [#1320](https://github.com/paritytech/parity/pull/1320) +- Filling-in optional fields of TransactionRequest... [#1305](https://github.com/paritytech/parity/pull/1305) +- Removing MakerOTC and DAO dapps [#1319](https://github.com/paritytech/parity/pull/1319) +- Disabling ethcore_set* APIs by default (+ Status page update) [#1315](https://github.com/paritytech/parity/pull/1315) +- fixed #1180 [#1282](https://github.com/paritytech/parity/pull/1282) +- Network start/stop [#1313](https://github.com/paritytech/parity/pull/1313) +- Additional logging for own transactions in queue [#1311](https://github.com/paritytech/parity/pull/1311) +- DAO Rescue soft fork [#1309](https://github.com/paritytech/parity/pull/1309) +- Appveyor config for windows build+installer [#1302](https://github.com/paritytech/parity/pull/1302) +- Key load avoid warning [#1303](https://github.com/paritytech/parity/pull/1303) +- More meaningful errors when sending transaction [#1290](https://github.com/paritytech/parity/pull/1290) +- Gas price statistics. [#1291](https://github.com/paritytech/parity/pull/1291) +- Fix read-ahead bug. [#1298](https://github.com/paritytech/parity/pull/1298) +- firewall rules for windows installer [#1297](https://github.com/paritytech/parity/pull/1297) +- x64 program files path for installer [#1296](https://github.com/paritytech/parity/pull/1296) +- Fixed loosing peers on incoming connections. [#1293](https://github.com/paritytech/parity/pull/1293) +- fixed #1261, overflow when calculating work [#1283](https://github.com/paritytech/parity/pull/1283) +- snappy and minor block compression [#1286](https://github.com/paritytech/parity/pull/1286) +- clarify build instructions [#1287](https://github.com/paritytech/parity/pull/1287) +- fixed #1255 [#1280](https://github.com/paritytech/parity/pull/1280) +- bump rust-crypto [#1289](https://github.com/paritytech/parity/pull/1289) +- Security audit issues fixed [#1279](https://github.com/paritytech/parity/pull/1279) +- Fixing origin/host validation [#1273](https://github.com/paritytech/parity/pull/1273) +- windows installer + parity start ui cli option [#1284](https://github.com/paritytech/parity/pull/1284) +- ipc lib version bump [#1285](https://github.com/paritytech/parity/pull/1285) +- Syncing improvements [#1274](https://github.com/paritytech/parity/pull/1274) +- removed redundant if condition [#1270](https://github.com/paritytech/parity/pull/1270) +- Naive chunk creation, snapshotting [#1263](https://github.com/paritytech/parity/pull/1263) +- Fixing generating new token while another parity instance is running. [#1272](https://github.com/paritytech/parity/pull/1272) +- README: rustup and windows instructions [#1266](https://github.com/paritytech/parity/pull/1266) +- Windows build [#1253](https://github.com/paritytech/parity/pull/1253) +- removed try_seal from MiningBlockChainClient [#1262](https://github.com/paritytech/parity/pull/1262) +- simplified block opening [#1232](https://github.com/paritytech/parity/pull/1232) +- Clippy bump [#1259](https://github.com/paritytech/parity/pull/1259) +- Fixing uint ASM macros compilation [#1258](https://github.com/paritytech/parity/pull/1258) +- Signer port returned from RPC + Topbar showing count of unconfirmed transactions. [#1252](https://github.com/paritytech/parity/pull/1252) +- codegen - avoid unwraps leading to compilation crash [#1250](https://github.com/paritytech/parity/pull/1250) +- Dapps bump [#1257](https://github.com/paritytech/parity/pull/1257) +- Windows named pipes [#1254](https://github.com/paritytech/parity/pull/1254) +- remove unsafety from util/hash.rs and util/bigint/uint.rs [#1236](https://github.com/paritytech/parity/pull/1236) +- Fixing CORS settings for special values: * & null. [#1247](https://github.com/paritytech/parity/pull/1247) +- JSONRPC test strings avoid using \ char [#1246](https://github.com/paritytech/parity/pull/1246) +- Tests for JSON serialisation of statediff/vmtrace [#1241](https://github.com/paritytech/parity/pull/1241) +- Bumping Dapps & TopBar to newest version. [#1245](https://github.com/paritytech/parity/pull/1245) +- keys import [#1240](https://github.com/paritytech/parity/pull/1240) +- Splitting RPC Apis into more fine-grained sets [#1234](https://github.com/paritytech/parity/pull/1234) +- Refactor triedb constructors to error on invalid state root [#1230](https://github.com/paritytech/parity/pull/1230) +- Signer RPC method to check if signer is enabled [#1238](https://github.com/paritytech/parity/pull/1238) +- Fixing signer behaviour when confirming transaction with wrong password. [#1237](https://github.com/paritytech/parity/pull/1237) +- SystemUIs authorization [#1233](https://github.com/paritytech/parity/pull/1233) +- IPC path for tesetnet with --geth compatibility [#1231](https://github.com/paritytech/parity/pull/1231) +- Transaction tracing for eth_call [#1210](https://github.com/paritytech/parity/pull/1210) +- Removing compilation warnings [#1227](https://github.com/paritytech/parity/pull/1227) +- Allowing connections only from chrome-extension and self-hosted client [#1226](https://github.com/paritytech/parity/pull/1226) +- Clippy bump & fixing warnings [#1219](https://github.com/paritytech/parity/pull/1219) +- Bumping serde & syntex [#1216](https://github.com/paritytech/parity/pull/1216) +- Minimal Signer UI (System UI) exposed over websockets. [#1211](https://github.com/paritytech/parity/pull/1211) +- Switch RPC namespace form ethcore_ to trace_ [#1208](https://github.com/paritytech/parity/pull/1208) +- Verify the state root exists before creating a State [#1217](https://github.com/paritytech/parity/pull/1217) +- Integrate state diffing into the ethcore JSONRPC [#1206](https://github.com/paritytech/parity/pull/1206) +- Updating topbar to latest version [#1220](https://github.com/paritytech/parity/pull/1220) +- Loading local Dapps from FS. [#1214](https://github.com/paritytech/parity/pull/1214) +- Ipc serialization & protocol fixes [#1188](https://github.com/paritytech/parity/pull/1188) +- Have Ext::ret take self by value [#1187](https://github.com/paritytech/parity/pull/1187) +- Simple WebSockets notification about new request [#1202](https://github.com/paritytech/parity/pull/1202) +- Removing leftovers of ethminer [#1207](https://github.com/paritytech/parity/pull/1207) +- fixed #1204 [#1205](https://github.com/paritytech/parity/pull/1205) +- VM tracing and JSON RPC endpoint for it. [#1169](https://github.com/paritytech/parity/pull/1169) +- devtools helpers extended [#1186](https://github.com/paritytech/parity/pull/1186) +- Networking refactoring [#1172](https://github.com/paritytech/parity/pull/1172) +- Client & Miner refactoring [#1195](https://github.com/paritytech/parity/pull/1195) +- update readme [#1201](https://github.com/paritytech/parity/pull/1201) +- Simple signing queue, confirmation APIs exposed in signer WebSockets. [#1182](https://github.com/paritytech/parity/pull/1182) +- Using ordered hashmap to keep the order of dapps on home screen [#1199](https://github.com/paritytech/parity/pull/1199) +- Disabling `ethcore` by default, adding x-frame-options header to dapps. [#1197](https://github.com/paritytech/parity/pull/1197) +- transaction count verifier tests [#1196](https://github.com/paritytech/parity/pull/1196) +- expunge x! and xx! from the codebase [#1192](https://github.com/paritytech/parity/pull/1192) +- Database service upgrade (from the ipc branch) [#1185](https://github.com/paritytech/parity/pull/1185) +- stop eth_syncing from returning true forever [#1181](https://github.com/paritytech/parity/pull/1181) +- Sync fixes and tweaks [#1164](https://github.com/paritytech/parity/pull/1164) +- Exposing RPC over Signer WebSockets [#1167](https://github.com/paritytech/parity/pull/1167) +- implement missing rpc methods and tests [#1171](https://github.com/paritytech/parity/pull/1171) +- json ipc server version bump [#1170](https://github.com/paritytech/parity/pull/1170) +- Updated dependencies for windows build [#1173](https://github.com/paritytech/parity/pull/1173) +- Framework for improved RPC unit tests [#1141](https://github.com/paritytech/parity/pull/1141) +- remove all possible unsafe code in crypto [#1168](https://github.com/paritytech/parity/pull/1168) +- Base for Signer Websockets server [#1158](https://github.com/paritytech/parity/pull/1158) +- Write queue to speed-up db ipc [#1160](https://github.com/paritytech/parity/pull/1160) +- Fixing few clippy warnings [#1163](https://github.com/paritytech/parity/pull/1163) +- Change eth_signAndSendTransaction to personal_SignAndSendTransaction [#1154](https://github.com/paritytech/parity/pull/1154) +- Support "earliest" and specific block parameters in RPC where possible [#1149](https://github.com/paritytech/parity/pull/1149) +- migration fixes [#1155](https://github.com/paritytech/parity/pull/1155) +- Empty trusted signer crate with it's general purpose described. [#1150](https://github.com/paritytech/parity/pull/1150) +- More bootnodes for morden. [#1153](https://github.com/paritytech/parity/pull/1153) +- move existing rpc tests into mocked module [#1151](https://github.com/paritytech/parity/pull/1151) +- Bloomchain [#1014](https://github.com/paritytech/parity/pull/1014) +- Renaming dapps repos. Updating dapps [#1142](https://github.com/paritytech/parity/pull/1142) +- fixed pending transactions [#1147](https://github.com/paritytech/parity/pull/1147) +- Basic benches to provide metrics for ipc optimizations [#1145](https://github.com/paritytech/parity/pull/1145) +- Fixing clippy warnings [#1148](https://github.com/paritytech/parity/pull/1148) +- correct signature of SecTrieDB::raw_mut [#1143](https://github.com/paritytech/parity/pull/1143) +- Merge to master and start hypervisor for import/export [#1138](https://github.com/paritytech/parity/pull/1138) +- Bumping clippy. Fixing warnings [#1139](https://github.com/paritytech/parity/pull/1139) +- Display progress when importing [#1136](https://github.com/paritytech/parity/pull/1136) +- foundation of simple db migration [#1128](https://github.com/paritytech/parity/pull/1128) +- Fixpending [#1074](https://github.com/paritytech/parity/pull/1074) +- Sync: Propagate uncles and fix status reporting [#1134](https://github.com/paritytech/parity/pull/1134) +- Coloured, padding logging. [#1133](https://github.com/paritytech/parity/pull/1133) +- Importing [#1132](https://github.com/paritytech/parity/pull/1132) +- Have `die_with_error` use `fmt::Display` rather than Debug [#1116](https://github.com/paritytech/parity/pull/1116) +- Exporting [#1129](https://github.com/paritytech/parity/pull/1129) +- Sign and send transaction [#1124](https://github.com/paritytech/parity/pull/1124) +- Fixing unused imports warnings [#1125](https://github.com/paritytech/parity/pull/1125) +- Adding info messages on mined blocks [#1127](https://github.com/paritytech/parity/pull/1127) +- Fix styling - don't mix spaces with tabs!!! [#1123](https://github.com/paritytech/parity/pull/1123) +- Fix is_syncing so it's false as long as the update is trivial. [#1122](https://github.com/paritytech/parity/pull/1122) +- Relock unlocked accounts after first use [#1120](https://github.com/paritytech/parity/pull/1120) +- Avoid importing keys into wrong place. [#1119](https://github.com/paritytech/parity/pull/1119) +- Implement receipt's gasUsed field [#1118](https://github.com/paritytech/parity/pull/1118) +- New dapps & query parameter handling [#1113](https://github.com/paritytech/parity/pull/1113) +- pretty print trace error [#1098](https://github.com/paritytech/parity/pull/1098) +- New syncing strategy [#1095](https://github.com/paritytech/parity/pull/1095) +- ethcore-db crate [#1097](https://github.com/paritytech/parity/pull/1097) +- Fix the default for pruning. [#1107](https://github.com/paritytech/parity/pull/1107) +- Make Id/ID and db/Db/DB usage consistent [#1105](https://github.com/paritytech/parity/pull/1105) +- Miner holds it's own copy of spec/engine [#1091](https://github.com/paritytech/parity/pull/1091) +- Apps listing API & Home webapp. [#1101](https://github.com/paritytech/parity/pull/1101) +- CLI option for using JITEVM [#1103](https://github.com/paritytech/parity/pull/1103) +- Fix up the seal fields in RPC output [#1096](https://github.com/paritytech/parity/pull/1096) +- Fixing some warnings [#1102](https://github.com/paritytech/parity/pull/1102) +- fixed incorrect decoding of header seal_fields. added tests. #1090 [#1094](https://github.com/paritytech/parity/pull/1094) +- Bumping Clippy [#1093](https://github.com/paritytech/parity/pull/1093) +- Injectable topbar support. [#1092](https://github.com/paritytech/parity/pull/1092) +- New syncing part 1: Block collection [#1088](https://github.com/paritytech/parity/pull/1088) +- Moving all Client public API types to separate mod & binary serialization codegen for that mod [#1051](https://github.com/paritytech/parity/pull/1051) +- Subdomains support in content server (webapps server). [#1082](https://github.com/paritytech/parity/pull/1082) +- Fix uncle getter [#1087](https://github.com/paritytech/parity/pull/1087) +- Provide fallback for usd-per-eth option when offline. [#1085](https://github.com/paritytech/parity/pull/1085) +- path centralized [#1083](https://github.com/paritytech/parity/pull/1083) +- Limiting result of the execution to execution-specific errors [#1071](https://github.com/paritytech/parity/pull/1071) +- Configurable keys security [#1080](https://github.com/paritytech/parity/pull/1080) +- comma delimeting multiple cors headers [#1078](https://github.com/paritytech/parity/pull/1078) +- Update error message [#1081](https://github.com/paritytech/parity/pull/1081) +- Updating dapp-wallet [#1076](https://github.com/paritytech/parity/pull/1076) +- Fixed connecting to local nodes on startup [#1070](https://github.com/paritytech/parity/pull/1070) +- Validate signature in Tx queue [#1068](https://github.com/paritytech/parity/pull/1068) +- moving deps to ethcore/hyper and bumping jsonrpc-http-server version [#1067](https://github.com/paritytech/parity/pull/1067) +- Updating status page. Bringing back wallet [#1064](https://github.com/paritytech/parity/pull/1064) +- Fix --geth IPC for MacOS. [#1062](https://github.com/paritytech/parity/pull/1062) +- Fixing formatter for defaultExtraData [#1060](https://github.com/paritytech/parity/pull/1060) +- --geth IPC compatibility [#1059](https://github.com/paritytech/parity/pull/1059) +- Moving dependencies to ethcore & uniforming syntax libs through all crates [#1050](https://github.com/paritytech/parity/pull/1050) +- update hyper branch mio [#1054](https://github.com/paritytech/parity/pull/1054) +- IPC lib update [#1047](https://github.com/paritytech/parity/pull/1047) +- Updating hyper-mio revision [#1048](https://github.com/paritytech/parity/pull/1048) +- Bump ipc-lib version [#1046](https://github.com/paritytech/parity/pull/1046) +- Tidy up CLI options and make JSONRPC & webapps on by default. [#1045](https://github.com/paritytech/parity/pull/1045) +- Fixing clippy warnings [#1044](https://github.com/paritytech/parity/pull/1044) +- Fixing RPC modules compatibility [#1041](https://github.com/paritytech/parity/pull/1041) +- Fixing hyper-mio revision [#1043](https://github.com/paritytech/parity/pull/1043) +- Updating locations of webapp stuff [#1040](https://github.com/paritytech/parity/pull/1040) +- JSON-RPC over IPC [#1039](https://github.com/paritytech/parity/pull/1039) +- Update nix/mio for ARM [#1036](https://github.com/paritytech/parity/pull/1036) +- Basic Authority [#991](https://github.com/paritytech/parity/pull/991) +- Prioritizing of local transaction [#1023](https://github.com/paritytech/parity/pull/1023) +- Version 1.2 [#1030](https://github.com/paritytech/parity/pull/1030) +- Bumping status page [#1033](https://github.com/paritytech/parity/pull/1033) + +## Parity [v1.1.0](https://github.com/paritytech/parity/releases/tag/v1.1.0) (2016-05-02) + +Parity 1.1.0 introduces: + +- Transaction tracing. Parity now optionally indexes & stores message-call/"internal transaction" information and provides additional RPC for querying. +- Web interface for logs, status & JSON RPC. +- Improved JSON RPC compatibility. +- Reduced memory footprint. +- Optimized EVM interpreter performance. + +Full Changes: + +- Exposing default extra data via ethcore RPC [#1032](https://github.com/paritytech/parity/pull/1032) +- Net etiquette [#1028](https://github.com/paritytech/parity/pull/1028) +- Bumping clippy & fixing warnings [#1024](https://github.com/paritytech/parity/pull/1024) +- Tracedb interface && cli [#997](https://github.com/paritytech/parity/pull/997) +- Switching to geth-attach supporting version of rpc core and server [#1022](https://github.com/paritytech/parity/pull/1022) +- Fixing status page displaying homestead [#1020](https://github.com/paritytech/parity/pull/1020) +- Core tracedb functionality. [#996](https://github.com/paritytech/parity/pull/996) +- RPC method for supported modules [#1019](https://github.com/paritytech/parity/pull/1019) +- Updating status page [#1015](https://github.com/paritytech/parity/pull/1015) +- Disabling wallet [#1017](https://github.com/paritytech/parity/pull/1017) +- More detailed fatal error reporting [#1016](https://github.com/paritytech/parity/pull/1016) +- Support 'pending' block in RPC [#1007](https://github.com/paritytech/parity/pull/1007) +- Enable pending block when there is local transaction pending. [#1005](https://github.com/paritytech/parity/pull/1005) +- updating key files permissions on save [#1010](https://github.com/paritytech/parity/pull/1010) +- IPC JSON RPC (for external interface) [#1009](https://github.com/paritytech/parity/pull/1009) +- Fixing Firefox authorization issues [#1013](https://github.com/paritytech/parity/pull/1013) +- cargo update [#1012](https://github.com/paritytech/parity/pull/1012) +- Switching to rust-url@1.0.0 [#1011](https://github.com/paritytech/parity/pull/1011) +- Exception handling in RPC & WebApps [#988](https://github.com/paritytech/parity/pull/988) +- Fixed uint deserialization from hex [#1008](https://github.com/paritytech/parity/pull/1008) +- Tweak timeout and packet size to handle slow networks better [#1004](https://github.com/paritytech/parity/pull/1004) +- db key is generic and can be made smaller [#1006](https://github.com/paritytech/parity/pull/1006) +- IPC with new serialization [#998](https://github.com/paritytech/parity/pull/998) +- make jsonrpc api engine agnostic [#1001](https://github.com/paritytech/parity/pull/1001) +- updated cargo.lock [#1002](https://github.com/paritytech/parity/pull/1002) +- updated parity dependencies [#993](https://github.com/paritytech/parity/pull/993) +- Auto (with codegen) binary serializer [#980](https://github.com/paritytech/parity/pull/980) +- Fixing transaction queue last_nonces update [#995](https://github.com/paritytech/parity/pull/995) +- import route contains ommited blocks [#994](https://github.com/paritytech/parity/pull/994) +- fixed encoding 0u8 [#992](https://github.com/paritytech/parity/pull/992) +- Use latest netstats [#989](https://github.com/paritytech/parity/pull/989) +- RPC shared external miner [#984](https://github.com/paritytech/parity/pull/984) +- Additional RPC methods for settings [#983](https://github.com/paritytech/parity/pull/983) +- Fixing transaction_queue deadlock [#985](https://github.com/paritytech/parity/pull/985) +- Refactoring of `parity/main.rs` [#981](https://github.com/paritytech/parity/pull/981) +- Fixing clippy warnings. [#982](https://github.com/paritytech/parity/pull/982) +- Bumping status page [#977](https://github.com/paritytech/parity/pull/977) +- querying extras separated to its own module [#972](https://github.com/paritytech/parity/pull/972) +- Exposing application logs via RPC. [#976](https://github.com/paritytech/parity/pull/976) +- Addressing binary serialization for db types [#966](https://github.com/paritytech/parity/pull/966) +- removed redundant unwraps [#935](https://github.com/paritytech/parity/pull/935) +- fixed transaction queue merge conflict [#975](https://github.com/paritytech/parity/pull/975) +- Configurable limit for transaction queue (CLI & Ethcore-RPC) [#974](https://github.com/paritytech/parity/pull/974) +- Enforce limit caused `last_nonce` to return incorrect values. [#973](https://github.com/paritytech/parity/pull/973) +- Even more detailed errors for transaction queue [#969](https://github.com/paritytech/parity/pull/969) +- temporary fix of panic in blockchain garbage collection [#970](https://github.com/paritytech/parity/pull/970) +- IPC codegen - some minor fixes & enhancements [#967](https://github.com/paritytech/parity/pull/967) +- Additional logging for transactions [#968](https://github.com/paritytech/parity/pull/968) +- refactored blockchain extras keys building [#963](https://github.com/paritytech/parity/pull/963) +- Using hyper-mio branch in webapps. [#957](https://github.com/paritytech/parity/pull/957) +- Remove nanomsg from build-dependencies [#965](https://github.com/paritytech/parity/pull/965) +- Fix build for --target=armv7-unknown-linux-gnueabihf [#964](https://github.com/paritytech/parity/pull/964) +- IPC RPC codegen extra feature [#962](https://github.com/paritytech/parity/pull/962) +- IPC RPC codegen for generic implementation [#961](https://github.com/paritytech/parity/pull/961) +- using db_path directory when upgrading [#960](https://github.com/paritytech/parity/pull/960) +- IPC hypervisor [#958](https://github.com/paritytech/parity/pull/958) +- Removing a transaction from queue now removes all from this sender with lower nonces. [#950](https://github.com/paritytech/parity/pull/950) +- bump status page version 0.1.7 [#955](https://github.com/paritytech/parity/pull/955) +- Changing cors header to be optional [#956](https://github.com/paritytech/parity/pull/956) +- Update ARM Dockerfile [#959](https://github.com/paritytech/parity/pull/959) +- Sensible gas limits for eth_sendTransaction [#953](https://github.com/paritytech/parity/pull/953) +- Fix upgrade script and make parity run when no .parity dir. [#954](https://github.com/paritytech/parity/pull/954) +- Tracing and docs for --pruning=auto. [#952](https://github.com/paritytech/parity/pull/952) +- IPC serialization for custom parameters [#946](https://github.com/paritytech/parity/pull/946) +- default filter from block should be Latest, not Earliest [#948](https://github.com/paritytech/parity/pull/948) +- README.md: removes sudo from multirust installation [#943](https://github.com/paritytech/parity/pull/943) +- Disable long lines formatting + ethash example. [#939](https://github.com/paritytech/parity/pull/939) +- Ethcore-specific RPC methods for altering miner parameters. [#934](https://github.com/paritytech/parity/pull/934) +- Use ethcore nanomsg bindings [#941](https://github.com/paritytech/parity/pull/941) +- Update IPC codegen to latest syntax libs [#938](https://github.com/paritytech/parity/pull/938) +- IPC documentation [#937](https://github.com/paritytech/parity/pull/937) +- Bumping clippy and fixing warnings. [#936](https://github.com/paritytech/parity/pull/936) +- Pruning auto [#927](https://github.com/paritytech/parity/pull/927) +- IPC persistent client link [#933](https://github.com/paritytech/parity/pull/933) +- IPC persistent client link [#930](https://github.com/paritytech/parity/pull/930) +- IPC handshake (negotiating protocol/api version) [#928](https://github.com/paritytech/parity/pull/928) +- Upgrade logic between versions [#914](https://github.com/paritytech/parity/pull/914) +- executive tracing cleanup [#903](https://github.com/paritytech/parity/pull/903) +- Ethcore-specific RPC methods [#923](https://github.com/paritytech/parity/pull/923) +- Parameter to allow user to force the sealing mechanism [#918](https://github.com/paritytech/parity/pull/918) +- updated dependencies [#921](https://github.com/paritytech/parity/pull/921) +- Fixed send transaction deadlock [#920](https://github.com/paritytech/parity/pull/920) +- --unlock is comma-delimited. [#916](https://github.com/paritytech/parity/pull/916) +- fixed eth_getLogs [#915](https://github.com/paritytech/parity/pull/915) +- create provided custom dir for keys if none [#912](https://github.com/paritytech/parity/pull/912) +- spec loading cleanup [#858](https://github.com/paritytech/parity/pull/858) +- WebApps HTTP Basic Auth Support [#906](https://github.com/paritytech/parity/pull/906) +- Removing match on constant [#888](https://github.com/paritytech/parity/pull/888) +- Update auth.rs [#907](https://github.com/paritytech/parity/pull/907) +- Enabling webapps compilation by default [#904](https://github.com/paritytech/parity/pull/904) +- fixed #895 [#898](https://github.com/paritytech/parity/pull/898) +- Support for compile-time included WebApplications. [#899](https://github.com/paritytech/parity/pull/899) +- Propagate transaction queue [#894](https://github.com/paritytech/parity/pull/894) +- Use new json RPC server [#901](https://github.com/paritytech/parity/pull/901) +- Gracefully dying when trying to enable RPC and app is compiled without it. [#900](https://github.com/paritytech/parity/pull/900) +- Additional logging and friendlier error messages [#893](https://github.com/paritytech/parity/pull/893) +- Avoid signalling readiness when app is about to be closed. [#897](https://github.com/paritytech/parity/pull/897) +- fixed #875 and added tests for eth_sendTransaction [#890](https://github.com/paritytech/parity/pull/890) +- passing key path to all invocations [#891](https://github.com/paritytech/parity/pull/891) +- Fixed eth_call nonce and gas handling [#892](https://github.com/paritytech/parity/pull/892) +- ipc rpc with nano transport (simple duplex) [#886](https://github.com/paritytech/parity/pull/886) +- Bumping clippy and fixing warnings [#889](https://github.com/paritytech/parity/pull/889) +- More descriptive expectations to transaction queue consistency. [#878](https://github.com/paritytech/parity/pull/878) +- uint bug - replace add with or [#879](https://github.com/paritytech/parity/pull/879) +- Fixing typo in bigint [#877](https://github.com/paritytech/parity/pull/877) +- update misleading cli help msg for author [#874](https://github.com/paritytech/parity/pull/874) +- Find geth data store cross-platform. [#871](https://github.com/paritytech/parity/pull/871) +- Import geth 1.4.0 keys [#872](https://github.com/paritytech/parity/pull/872) +- Syntax helpers for IPC RPC (part 2) [#854](https://github.com/paritytech/parity/pull/854) +- Fixed bootnode URL and error message [#870](https://github.com/paritytech/parity/pull/870) +- replace popcnt with mov (861) [#867](https://github.com/paritytech/parity/pull/867) +- weekly dependencies update [#865](https://github.com/paritytech/parity/pull/865) +- Remove unused mut [#866](https://github.com/paritytech/parity/pull/866) +- fixed #855 [#864](https://github.com/paritytech/parity/pull/864) +- simplified trace from functions, removed clippy warnings [#862](https://github.com/paritytech/parity/pull/862) +- Update deprecated HashDB methods in docs. [#857](https://github.com/paritytech/parity/pull/857) +- refactored loading transaction json tests [#853](https://github.com/paritytech/parity/pull/853) +- reorganised price info lookup [#852](https://github.com/paritytech/parity/pull/852) +- Publish locally-made transactions to peers. [#850](https://github.com/paritytech/parity/pull/850) +- Add generalbeck's token [#847](https://github.com/paritytech/parity/pull/847) +- Fix response for mining. [#846](https://github.com/paritytech/parity/pull/846) +- USD-based pricing of gas. [#843](https://github.com/paritytech/parity/pull/843) +- Parity can accept older work packages [#811](https://github.com/paritytech/parity/pull/811) +- Caching for computing seed hashes (#541) [#841](https://github.com/paritytech/parity/pull/841) +- checking transaction queue for pending transaction [#838](https://github.com/paritytech/parity/pull/838) +- refactored loading of state tests [#817](https://github.com/paritytech/parity/pull/817) +- tests for deserialization of transaction from issue #835 [#837](https://github.com/paritytech/parity/pull/837) +- unlocks with no expiration [on top of 833] [#834](https://github.com/paritytech/parity/pull/834) +- Unlock accounts on CLI. [#833](https://github.com/paritytech/parity/pull/833) +- Make BlockNumber optional, fix eth_call [#829](https://github.com/paritytech/parity/pull/829) +- Test socket to common test code (ethcore-devtools) [#831](https://github.com/paritytech/parity/pull/831) +- Use network id for the web3_net_version return. [#822](https://github.com/paritytech/parity/pull/822) +- json-rpc web3_sha3 [#824](https://github.com/paritytech/parity/pull/824) +- remove some unused files [#819](https://github.com/paritytech/parity/pull/819) +- debug symbols for master/beta [#818](https://github.com/paritytech/parity/pull/818) +- Syntax helpers for IPC RPC [#809](https://github.com/paritytech/parity/pull/809) +- refactored loading of execution tests [#803](https://github.com/paritytech/parity/pull/803) +- Rustfmt.toml [#805](https://github.com/paritytech/parity/pull/805) +- install-partiy runs brew reinstall parity on osx [#810](https://github.com/paritytech/parity/pull/810) +- Fix mining from spinning [#807](https://github.com/paritytech/parity/pull/807) + +## Parity [v1.0.2](https://github.com/paritytech/parity/releases/tag/v1.0.2) (2016-04-11) + +Parity 1.0.2 release improves Json RPC compatibility and fixes a number of stability issues. + +- Flush password prompt [#1031](https://github.com/paritytech/parity/pull/1031) +- [beta] dependencies update [#949](https://github.com/paritytech/parity/pull/949) +- Master to beta v1.0.2 [#922](https://github.com/paritytech/parity/pull/922) +- Master to beta 1.0.2 [#908](https://github.com/paritytech/parity/pull/908) + +## Parity [v1.0.1](https://github.com/paritytech/parity/releases/tag/v1.0.1) (2016-03-28) + +Parity 1.0.1 update fixes a number of issues with Json RPC, transaction propagation and syncing. + +- Imporved sync error handling [#905](https://github.com/paritytech/parity/pull/905) +- Publish locally-made transactions to peers. [#851](https://github.com/paritytech/parity/pull/851) +- Merge fixes from master to beta [#845](https://github.com/paritytech/parity/pull/845) +- Full sync restart on bad block [#844](https://github.com/paritytech/parity/pull/844) +- Make BlockNumber optional, fix eth_call [#828](https://github.com/paritytech/parity/pull/828) +- Web3sha3 beta [#826](https://github.com/paritytech/parity/pull/826) +- Use network id for the web3_net_version return. [#821](https://github.com/paritytech/parity/pull/821) +- Fix mining from spinning [#806](https://github.com/paritytech/parity/pull/806) +- Merge master to beta [#796](https://github.com/paritytech/parity/pull/796) + +## Parity [v1.0.0](https://github.com/paritytech/parity/releases/tag/v1.0.0) (2016-03-24) + +Parity 1.0.0 release adds the following features: + +- Standard JsonRPC interface. +- Full Homestead compatibility. +- Transaction management. +- Mining with external miner. +- Account management. +- Geth key chain compatibility. +- Additional command line options. +- State trie pruning. +- Cache and queue footprint. +- Network discovery & NAT traversal. +- Custom chain specification files. + +Note that in this release the state database is in archive (full) mode by default. Run with one of the `--pruning` options to enable pruning. + +- First part of multi-mining support [#804](https://github.com/paritytech/parity/pull/804) +- Fixing future-current transactions clash [#802](https://github.com/paritytech/parity/pull/802) +- Increase threads to num_cpus & fix author reporting [#800](https://github.com/paritytech/parity/pull/800) +- another batch of rpc improvements [#798](https://github.com/paritytech/parity/pull/798) +- Avoid tracing DELEGATECALL and CALLCODE. Plus tests for it. [#794](https://github.com/paritytech/parity/pull/794) +- complete getting started steps for OS X [#793](https://github.com/paritytech/parity/pull/793) +- Auto detect available port (with fixed test) [#788](https://github.com/paritytech/parity/pull/788) +- eth_getTransactionReceipt [#792](https://github.com/paritytech/parity/pull/792) +- Comprehensive tests for tracing transactions [#791](https://github.com/paritytech/parity/pull/791) +- Disable preparing work package if miners don't ask for it. [#771](https://github.com/paritytech/parity/pull/771) +- Listen on all interfaces for JSONRPC by default. [#786](https://github.com/paritytech/parity/pull/786) +- eth_call [#783](https://github.com/paritytech/parity/pull/783) +- Revert "Auto detect available port" [#789](https://github.com/paritytech/parity/pull/789) +- added output to execution result [#777](https://github.com/paritytech/parity/pull/777) +- Auto detect available port [#782](https://github.com/paritytech/parity/pull/782) +- Allow 0x prefix for --author. [#785](https://github.com/paritytech/parity/pull/785) +- updated dependencies, moved rpctest to its own submodule [#784](https://github.com/paritytech/parity/pull/784) +- use ethjson module to load chain json tests [#778](https://github.com/paritytech/parity/pull/778) +- Tracing implemented. [#772](https://github.com/paritytech/parity/pull/772) +- test ethjson module on travis [#780](https://github.com/paritytech/parity/pull/780) +- batch of rpc fixes [#775](https://github.com/paritytech/parity/pull/775) +- rpctest executable [#757](https://github.com/paritytech/parity/pull/757) +- Refactoring error transaction_queue error handling and `update_sealing` method. [#753](https://github.com/paritytech/parity/pull/753) +- Avoid importing transactions with gas above 1.1*block_gas_limit to transaction queue [#760](https://github.com/paritytech/parity/pull/760) +- Removing transactions that failed to be pushed to block. [#752](https://github.com/paritytech/parity/pull/752) +- Updating clippy [#766](https://github.com/paritytech/parity/pull/766) +- Attempting to add all transactions to mined block [#754](https://github.com/paritytech/parity/pull/754) +- Prettier version w/o git dir; Use rustc compile time version [#761](https://github.com/paritytech/parity/pull/761) +- Stop adding transactions to queue while not fully synced [#751](https://github.com/paritytech/parity/pull/751) +- Verify sender's balance before importing transaction to queue [#746](https://github.com/paritytech/parity/pull/746) +- Returning number of transactions pending in block not queue [#750](https://github.com/paritytech/parity/pull/750) +- Speeding up build [#733](https://github.com/paritytech/parity/pull/733) +- adding check for a sync when giving work to miner [#742](https://github.com/paritytech/parity/pull/742) +- json deserialization module [#745](https://github.com/paritytech/parity/pull/745) +- Update install-parity.sh [#749](https://github.com/paritytech/parity/pull/749) +- Restart sync on getting old unknown header [#747](https://github.com/paritytech/parity/pull/747) +- Missing return for #737 [#744](https://github.com/paritytech/parity/pull/744) +- Enact block with uncles test [#741](https://github.com/paritytech/parity/pull/741) +- Fix outdated libc version on dependency [#740](https://github.com/paritytech/parity/pull/740) +- Fixing possible race in transaction queue [#735](https://github.com/paritytech/parity/pull/735) +- Sync fixed again [#737](https://github.com/paritytech/parity/pull/737) +- Don't change best block until extras is committed. [#734](https://github.com/paritytech/parity/pull/734) +- stable only until travis speedup [#736](https://github.com/paritytech/parity/pull/736) +- Optimizing uint operations (architecture independent) [#629](https://github.com/paritytech/parity/pull/629) +- Add RLP, not a data item. [#725](https://github.com/paritytech/parity/pull/725) +- PV63 receipts response [#687](https://github.com/paritytech/parity/pull/687) +- another batch of rpc tests [#723](https://github.com/paritytech/parity/pull/723) +- dockerfiles update [#726](https://github.com/paritytech/parity/pull/726) +- Lock reports to avoid out of order badness. [#721](https://github.com/paritytech/parity/pull/721) +- Fixed handshake leak [#722](https://github.com/paritytech/parity/pull/722) +- Allow configuration of target gas limit. [#719](https://github.com/paritytech/parity/pull/719) +- Version 1.1 in master [#714](https://github.com/paritytech/parity/pull/714) +- Silence UDP warnings [#720](https://github.com/paritytech/parity/pull/720) +- Rpc personal tests [#715](https://github.com/paritytech/parity/pull/715) +- Fixing warnings [#704](https://github.com/paritytech/parity/pull/704) +- docopts cleanups [#713](https://github.com/paritytech/parity/pull/713) +- Removed rocksdb build dependency [#717](https://github.com/paritytech/parity/pull/717) +- Fixed splitting Neighbours packet [#710](https://github.com/paritytech/parity/pull/710) +- management of account expiration & memory [#701](https://github.com/paritytech/parity/pull/701) +- Remove EarlyMerge from user docs. [#708](https://github.com/paritytech/parity/pull/708) +- Fixes and traces for refcountdb. [#705](https://github.com/paritytech/parity/pull/705) +- Check for NULL_RLP in AccountDB [#706](https://github.com/paritytech/parity/pull/706) +- ethminer as crate [#700](https://github.com/paritytech/parity/pull/700) +- Old ref-counted DB code [#692](https://github.com/paritytech/parity/pull/692) +- next batch of rpc tests and fixes [#699](https://github.com/paritytech/parity/pull/699) +- implemented eth_geStorageAt rpc method, added more tests for rpc [#695](https://github.com/paritytech/parity/pull/695) +- Fix JournalDB era marker [#690](https://github.com/paritytech/parity/pull/690) +- More sync fixes [#685](https://github.com/paritytech/parity/pull/685) +- mark some key tests as heavy [#694](https://github.com/paritytech/parity/pull/694) +- Limit incoming connections [#693](https://github.com/paritytech/parity/pull/693) +- Updating clippy [#688](https://github.com/paritytech/parity/pull/688) +- eth_accounts, eth_getBalance rpc functions && tests [#691](https://github.com/paritytech/parity/pull/691) +- state query for archive jdb [#683](https://github.com/paritytech/parity/pull/683) +- Fix for option 1 of JournalDB [#658](https://github.com/paritytech/parity/pull/658) +- Rename into something that is a little more descriptive. [#689](https://github.com/paritytech/parity/pull/689) +- JournalDB with in-memory overlay (option2) [#634](https://github.com/paritytech/parity/pull/634) +- additional (failing) SecretStore test [#682](https://github.com/paritytech/parity/pull/682) +- Updating clippy & fixing warnings. [#670](https://github.com/paritytech/parity/pull/670) +- rpc web3 tests [#681](https://github.com/paritytech/parity/pull/681) +- Making personal json-rpc configurable via cli [#677](https://github.com/paritytech/parity/pull/677) +- RPC Pending Transactions Filter [#661](https://github.com/paritytech/parity/pull/661) +- Rearrange journaldb infrastructure to make more extensible [#678](https://github.com/paritytech/parity/pull/678) +- JournalDB -> Box, and it's a trait. [#673](https://github.com/paritytech/parity/pull/673) +- fix warning for transaction_queue.add usage [#676](https://github.com/paritytech/parity/pull/676) +- Adding std::mem back (only for asm) [#680](https://github.com/paritytech/parity/pull/680) +- update readme to exclude beta step (stable is ok) [#679](https://github.com/paritytech/parity/pull/679) +- fixed U256 and transaction request deserialization [#675](https://github.com/paritytech/parity/pull/675) +- More geth compatibility. [#666](https://github.com/paritytech/parity/pull/666) +- Removing running clippy by default on nightly. [#671](https://github.com/paritytech/parity/pull/671) +- rpc net submodule tests [#667](https://github.com/paritytech/parity/pull/667) +- Client module overhaul [#665](https://github.com/paritytech/parity/pull/665) +- Rpc transaction signing [#587](https://github.com/paritytech/parity/pull/587) +- Transaction queue exposed via JSON rpc. [#652](https://github.com/paritytech/parity/pull/652) +- Remove unneeded locking [#499](https://github.com/paritytech/parity/pull/499) +- extend sync status interface to sync provider [#664](https://github.com/paritytech/parity/pull/664) +- --archive is default. --pruning is option. [#663](https://github.com/paritytech/parity/pull/663) +- jsonrpc uses client and sync interfaces [#641](https://github.com/paritytech/parity/pull/641) +- Expose transaction insertion in sync lib [#609](https://github.com/paritytech/parity/pull/609) +- Removing get prefix from poll_info [#660](https://github.com/paritytech/parity/pull/660) +- Tx queue update height bug [#657](https://github.com/paritytech/parity/pull/657) +- Tx_queue_docs -> To master [#651](https://github.com/paritytech/parity/pull/651) +- blockchain import_route [#645](https://github.com/paritytech/parity/pull/645) +- Stop workers before stopping event loop [#655](https://github.com/paritytech/parity/pull/655) +- Validate sender before importing to queue [#650](https://github.com/paritytech/parity/pull/650) +- Gas price threshold for transactions [#640](https://github.com/paritytech/parity/pull/640) +- `dev` feature enabled when compiling without `--release` [#627](https://github.com/paritytech/parity/pull/627) +- Don't call mark_as_bad needlessly [#648](https://github.com/paritytech/parity/pull/648) +- Fixed sync handling large forks [#647](https://github.com/paritytech/parity/pull/647) +- Additional documentation for transaction queue [#631](https://github.com/paritytech/parity/pull/631) +- Transaction Queue Integration [#607](https://github.com/paritytech/parity/pull/607) +- Keys cli [#639](https://github.com/paritytech/parity/pull/639) +- fix build warning [#643](https://github.com/paritytech/parity/pull/643) +- updated jsonrpc-core and http-server libs [#642](https://github.com/paritytech/parity/pull/642) +- jsonrpc panics gracefully shutdown client [#638](https://github.com/paritytech/parity/pull/638) +- Fixing CLI parameters [#633](https://github.com/paritytech/parity/pull/633) +- Normal CLI options with geth. [#628](https://github.com/paritytech/parity/pull/628) +- Do not remove the peer immediatelly on send error [#626](https://github.com/paritytech/parity/pull/626) +- Jsonrpc block behind [#622](https://github.com/paritytech/parity/pull/622) +- Remove println!s. [#624](https://github.com/paritytech/parity/pull/624) +- JournalDB option 1 fix [#613](https://github.com/paritytech/parity/pull/613) +- Network tracing cleanup [#611](https://github.com/paritytech/parity/pull/611) +- Revert "Transaction Queue integration" [#602](https://github.com/paritytech/parity/pull/602) +- fix benches compilation [#601](https://github.com/paritytech/parity/pull/601) +- Transaction Queue integration [#595](https://github.com/paritytech/parity/pull/595) +- verifier trait improvements [#597](https://github.com/paritytech/parity/pull/597) +- build on rust stable [#600](https://github.com/paritytech/parity/pull/600) +- Geth import silent if no geth [#599](https://github.com/paritytech/parity/pull/599) +- Additional journaldb logging and assert [#593](https://github.com/paritytech/parity/pull/593) +- Uncle inclusion in block authoring. [#578](https://github.com/paritytech/parity/pull/578) +- Fixed potential deadlock on startup [#592](https://github.com/paritytech/parity/pull/592) +- Fixing an overflow panic [#591](https://github.com/paritytech/parity/pull/591) +- Fixed one more case of sync stalling [#590](https://github.com/paritytech/parity/pull/590) +- JournalDB can now operate in "archive" mode [#589](https://github.com/paritytech/parity/pull/589) +- Secret store integration with client [#586](https://github.com/paritytech/parity/pull/586) +- fix build on nightly rust [#588](https://github.com/paritytech/parity/pull/588) +- deserialization for uint generic [#585](https://github.com/paritytech/parity/pull/585) +- TransactionsQueue implementation [#559](https://github.com/paritytech/parity/pull/559) +- JSON-RPC personal service (follows #582) [#583](https://github.com/paritytech/parity/pull/583) +- making key directory thread-safe [#582](https://github.com/paritytech/parity/pull/582) +- verifier trait [#581](https://github.com/paritytech/parity/pull/581) +- shrink_to_fit after removing hashes. [#580](https://github.com/paritytech/parity/pull/580) +- support for rpc polling [#504](https://github.com/paritytech/parity/pull/504) +- limit serde codegen only to rpc types submodule [#569](https://github.com/paritytech/parity/pull/569) +- fork test for Issue test/568 [#573](https://github.com/paritytech/parity/pull/573) +- Fixing clippy warnings = small refactoring of `request_blocks` [#560](https://github.com/paritytech/parity/pull/560) +- Improved journaldb logging [#571](https://github.com/paritytech/parity/pull/571) +- Additional check to ancient enactments. [#570](https://github.com/paritytech/parity/pull/570) +- chainfilter shouldnt exclude to_block from results [#564](https://github.com/paritytech/parity/pull/564) +- Fix coverage test run [#567](https://github.com/paritytech/parity/pull/567) +- Mining [#547](https://github.com/paritytech/parity/pull/547) +- fix uint warnings [#565](https://github.com/paritytech/parity/pull/565) +- Finished blockchain generator. [#562](https://github.com/paritytech/parity/pull/562) +- fixed broken master [#563](https://github.com/paritytech/parity/pull/563) +- uint to separate crate [#544](https://github.com/paritytech/parity/pull/544) +- improved test chain generator [#554](https://github.com/paritytech/parity/pull/554) +- Fixing spelling in propagade->propagate [#558](https://github.com/paritytech/parity/pull/558) +- Changing RefCell to Cell in transaction. [#557](https://github.com/paritytech/parity/pull/557) +- Fix for morden consensus. [#556](https://github.com/paritytech/parity/pull/556) +- blockchain generator [#550](https://github.com/paritytech/parity/pull/550) +- Sparse Table Implementation (Row, Col) -> Val [#545](https://github.com/paritytech/parity/pull/545) +- fixup install script [#548](https://github.com/paritytech/parity/pull/548) +- Fixing clippy warnings [#546](https://github.com/paritytech/parity/pull/546) +- ignore out directory [#543](https://github.com/paritytech/parity/pull/543) +- u256 full multiplication [#539](https://github.com/paritytech/parity/pull/539) +- Fix panic when downloading stales, update homestead transition [#537](https://github.com/paritytech/parity/pull/537) +- changing x64 asm config [#534](https://github.com/paritytech/parity/pull/534) +- uncomment state transition tests [#533](https://github.com/paritytech/parity/pull/533) +- jsonrpc uses weak pointers to client [#532](https://github.com/paritytech/parity/pull/532) +- Morden switch to Homestead rules at #494,000. [#531](https://github.com/paritytech/parity/pull/531) +- Blockchain module cleanup [#524](https://github.com/paritytech/parity/pull/524) +- Multiplication issue + very exhaustive tests for it [#528](https://github.com/paritytech/parity/pull/528) +- EIP-8 [#498](https://github.com/paritytech/parity/pull/498) +- Make "random" trie tests fully deterministic. [#527](https://github.com/paritytech/parity/pull/527) +- udpated serde to version 0.7.0 [#526](https://github.com/paritytech/parity/pull/526) +- Better memory management [#516](https://github.com/paritytech/parity/pull/516) +- Typo [#523](https://github.com/paritytech/parity/pull/523) +- U512 add/sub optimize [#521](https://github.com/paritytech/parity/pull/521) +- Account management + geth keystore import (no utility crate added) [#509](https://github.com/paritytech/parity/pull/509) +- Delayed UPnP initialization [#505](https://github.com/paritytech/parity/pull/505) +- Fixing marking blocks as bad & SyncMessage bugs + small client refactoring. [#503](https://github.com/paritytech/parity/pull/503) +- optimization of U256 [#515](https://github.com/paritytech/parity/pull/515) +- Removed rocksdb from build scripts and instructions [#520](https://github.com/paritytech/parity/pull/520) +- RocksDB abstraction layer + Hash index for state DB [#464](https://github.com/paritytech/parity/pull/464) +- bloomfilter [#418](https://github.com/paritytech/parity/pull/418) +- Fixed a race condition when connecting peer disconnects immediately [#519](https://github.com/paritytech/parity/pull/519) +- ignore intellij idea project files as well [#518](https://github.com/paritytech/parity/pull/518) +- updated version of unicase [#517](https://github.com/paritytech/parity/pull/517) +- jsonrpc security, cors headers, fixed #359 [#493](https://github.com/paritytech/parity/pull/493) +- Rust implementations to replace data tables (#161) [#482](https://github.com/paritytech/parity/pull/482) +- fix issue with starting requested block number was not included itself [#512](https://github.com/paritytech/parity/pull/512) +- fixed travis --org GH_TOKEN [#510](https://github.com/paritytech/parity/pull/510) +- Improved log format [#506](https://github.com/paritytech/parity/pull/506) +- Log address on failed connection attempt [#502](https://github.com/paritytech/parity/pull/502) +- Bumping clippy and fixing warnings. [#501](https://github.com/paritytech/parity/pull/501) +- Bumping versions. Fixes #496 [#500](https://github.com/paritytech/parity/pull/500) +- Manage final user-input errors. [#494](https://github.com/paritytech/parity/pull/494) +- Remove unneeded code, fix minor potential issue with length. [#495](https://github.com/paritytech/parity/pull/495) +- Remove "unknown" from version string. [#488](https://github.com/paritytech/parity/pull/488) +- Include git commit date & hash. [#486](https://github.com/paritytech/parity/pull/486) +- Use proper version string. [#485](https://github.com/paritytech/parity/pull/485) +- Networking fixes [#480](https://github.com/paritytech/parity/pull/480) +- Fix potential deadlock on node table update [#484](https://github.com/paritytech/parity/pull/484) +- Squash more warnings [#481](https://github.com/paritytech/parity/pull/481) +- dev/test/build tools to separate crate [#477](https://github.com/paritytech/parity/pull/477) +- Back to original slab crate [#479](https://github.com/paritytech/parity/pull/479) +- Better user errors. [#476](https://github.com/paritytech/parity/pull/476) +- UDP Discovery [#440](https://github.com/paritytech/parity/pull/440) +- update readme with rust override [#475](https://github.com/paritytech/parity/pull/475) +- fixed warnings on rust beta [#474](https://github.com/paritytech/parity/pull/474) +- Secret store (part2 - encrypted key/value svc) [#449](https://github.com/paritytech/parity/pull/449) +- Kill bad test. [#473](https://github.com/paritytech/parity/pull/473) +- Make clippy an optional dependency [#422](https://github.com/paritytech/parity/pull/422) +- parity compiling fine [#469](https://github.com/paritytech/parity/pull/469) +- compiling ethcore on beta [#468](https://github.com/paritytech/parity/pull/468) +- Utils compiling in beta [#467](https://github.com/paritytech/parity/pull/467) +- Get rid of lru_cache dependency [#466](https://github.com/paritytech/parity/pull/466) +- Add daemonization. [#459](https://github.com/paritytech/parity/pull/459) +- Master upgrade [#448](https://github.com/paritytech/parity/pull/448) +- Remove contributing stuff now that we have CLA bot. [#447](https://github.com/paritytech/parity/pull/447) +- Add Morden bootnode. [#446](https://github.com/paritytech/parity/pull/446) +- beta fixes to master [#441](https://github.com/paritytech/parity/pull/441) +- Secret store (part1 - key management) [#423](https://github.com/paritytech/parity/pull/423) +- Use 1100000 as the homestead transition, fix build instructions. [#438](https://github.com/paritytech/parity/pull/438) +- More sync and propagation fixes [#420](https://github.com/paritytech/parity/pull/420) +- back to cargo crates [#436](https://github.com/paritytech/parity/pull/436) +- Fixing clippy warnings [#435](https://github.com/paritytech/parity/pull/435) +- preserving root cargo lock [#434](https://github.com/paritytech/parity/pull/434) +- Nightly fix [#432](https://github.com/paritytech/parity/pull/432) +- nightly fixes [#431](https://github.com/paritytech/parity/pull/431) +- Delay Homestead transition from 1,000,000. [#429](https://github.com/paritytech/parity/pull/429) +- Nightly fix effort (still should fail) [#428](https://github.com/paritytech/parity/pull/428) +- clippy version update, docopt-macro moving to fork [#425](https://github.com/paritytech/parity/pull/425) +- Network/Sync fixes and optimizations [#416](https://github.com/paritytech/parity/pull/416) +- Use latest era instead of end era as journal marker [#414](https://github.com/paritytech/parity/pull/414) +- api changes [#402](https://github.com/paritytech/parity/pull/402) +- Option for no init nodes. [#408](https://github.com/paritytech/parity/pull/408) +- Fixed block_bodies not returning a list [#406](https://github.com/paritytech/parity/pull/406) +- Fix test. [#405](https://github.com/paritytech/parity/pull/405) +- Allow path to be configured. [#404](https://github.com/paritytech/parity/pull/404) +- Upnp [#400](https://github.com/paritytech/parity/pull/400) +- eth_syncing, fixed #397 [#398](https://github.com/paritytech/parity/pull/398) +- Using modified version of ctrlc that catches SIGTERM [#399](https://github.com/paritytech/parity/pull/399) +- Catching panics. [#396](https://github.com/paritytech/parity/pull/396) +- jsonrpc [#391](https://github.com/paritytech/parity/pull/391) +- Externalities tests (still clumsy) [#394](https://github.com/paritytech/parity/pull/394) +- excluding test code itself from coverage [#395](https://github.com/paritytech/parity/pull/395) +- Additional tweaks to options. [#390](https://github.com/paritytech/parity/pull/390) +- --chain option for setting which network to go on. [#388](https://github.com/paritytech/parity/pull/388) +- Ethash unit tests final [#387](https://github.com/paritytech/parity/pull/387) +- jsonrpc [#374](https://github.com/paritytech/parity/pull/374) +- Editorconfig file. [#384](https://github.com/paritytech/parity/pull/384) +- Coverage effort [in progress] [#382](https://github.com/paritytech/parity/pull/382) +- making root kcov runner simular to the one running on CI [#380](https://github.com/paritytech/parity/pull/380) +- add gcc as a dependency to dockerfiles [#381](https://github.com/paritytech/parity/pull/381) +- Check for handshake expiration before attempting connection replace [#375](https://github.com/paritytech/parity/pull/375) +- Blocks propagation [#364](https://github.com/paritytech/parity/pull/364) +- Network params. [#376](https://github.com/paritytech/parity/pull/376) +- Add parity-node-zero to bootnodes. [#373](https://github.com/paritytech/parity/pull/373) +- kcov uses travis_job_id instead of coveralls token [#370](https://github.com/paritytech/parity/pull/370) +- Add parity-node-zero.ethcore.io to boot nodes. [#371](https://github.com/paritytech/parity/pull/371) + +## Parity [v1.0.0-rc1](https://github.com/paritytech/parity/releases/tag/v1.0.0-rc1) (2016-03-15) + +First Parity 1.0.0 release candidate. + +- Version 1.0 in beta [#712](https://github.com/paritytech/parity/pull/712) +- Fix test for beta [#617](https://github.com/paritytech/parity/pull/617) +- JournalDB fix option 1 for beta [#614](https://github.com/paritytech/parity/pull/614) +- Failing test. [#606](https://github.com/paritytech/parity/pull/606) +- Fix transition points [#604](https://github.com/paritytech/parity/pull/604) +- (BETA) Update README.md [#549](https://github.com/paritytech/parity/pull/549) +- (BETA) instructions for beta release channel [#456](https://github.com/paritytech/parity/pull/456) +- (BETA) fix nightly - remerge [#454](https://github.com/paritytech/parity/pull/454) +- (BETA) fixing nightly version for beta [#452](https://github.com/paritytech/parity/pull/452) + +## Parity [beta-0.9.1](https://github.com/paritytech/parity/releases/tag/beta-0.9.1) (2016-02-16) + +Homestead transition block changed to 1100000. + +- Beta patch to 0.9.1 [#445](https://github.com/paritytech/parity/pull/445) +- Delay homestead transition [#430](https://github.com/paritytech/parity/pull/430) +- (BETA) https link in the installer (?) [#392](https://github.com/paritytech/parity/pull/392) +- beta: Check for handshake expiration before attempting replace [#377](https://github.com/paritytech/parity/pull/377) + +## Parity [beta-0.9](https://github.com/paritytech/parity/releases/tag/beta-0.9) (2016-02-08) + +First Parity Beta 0.9 released. + +- Panic on missing counters; Client cleanup [#368](https://github.com/paritytech/parity/pull/368) +- Update README for new PPAs. [#369](https://github.com/paritytech/parity/pull/369) +- block_queue::clear should be more thorough [#365](https://github.com/paritytech/parity/pull/365) +- Fixed an issue with forked counters [#363](https://github.com/paritytech/parity/pull/363) +- Install parity [#362](https://github.com/paritytech/parity/pull/362) +- DB directory versioning [#358](https://github.com/paritytech/parity/pull/358) +- Raise FD limit for MacOS [#357](https://github.com/paritytech/parity/pull/357) +- Travis slack integration. [#356](https://github.com/paritytech/parity/pull/356) +- SignedTransaction structure [#350](https://github.com/paritytech/parity/pull/350) +- License [#354](https://github.com/paritytech/parity/pull/354) +- Performance optimizations [#353](https://github.com/paritytech/parity/pull/353) +- Gitter in README. [#355](https://github.com/paritytech/parity/pull/355) +- test efforts, receipt requests [#352](https://github.com/paritytech/parity/pull/352) +- sync tests setup & local module coverage [#348](https://github.com/paritytech/parity/pull/348) +- install parity script [#347](https://github.com/paritytech/parity/pull/347) +- evmjit homestead merge [#342](https://github.com/paritytech/parity/pull/342) +- Fixed sync stalling on fork [#343](https://github.com/paritytech/parity/pull/343) +- Remerge 264 [#334](https://github.com/paritytech/parity/pull/334) +- Ethsync tests bfix [#339](https://github.com/paritytech/parity/pull/339) +- Fix default options. [#335](https://github.com/paritytech/parity/pull/335) +- sync queue limit hotfix [#338](https://github.com/paritytech/parity/pull/338) +- Network tests, separate local coverage for utils [#333](https://github.com/paritytech/parity/pull/333) +- fix parity version so netstats can parse it [#332](https://github.com/paritytech/parity/pull/332) +- reveal surprise [#331](https://github.com/paritytech/parity/pull/331) +- Revert removal of `new_code`. [#330](https://github.com/paritytech/parity/pull/330) +- Network mod tests first part [#329](https://github.com/paritytech/parity/pull/329) +- Look ma no `dead_code` [#323](https://github.com/paritytech/parity/pull/323) +- Fixing JIT, Updating hook to run `ethcore` tests. [#326](https://github.com/paritytech/parity/pull/326) +- Final docs [#327](https://github.com/paritytech/parity/pull/327) +- update install-deps.sh [#316](https://github.com/paritytech/parity/pull/316) +- Finish all my docs. Fix previous test compilation. [#320](https://github.com/paritytech/parity/pull/320) +- Additional evm tests (extops, call, jumps) and some docs [#317](https://github.com/paritytech/parity/pull/317) +- More documentation. [#318](https://github.com/paritytech/parity/pull/318) +- Additional documentation. [#315](https://github.com/paritytech/parity/pull/315) +- unused functions cleanup [#310](https://github.com/paritytech/parity/pull/310) +- update ethcore.github.io documentation automatically [#311](https://github.com/paritytech/parity/pull/311) +- Another try with travis ci credentials [#314](https://github.com/paritytech/parity/pull/314) +- Document some stuff. [#309](https://github.com/paritytech/parity/pull/309) +- Check block parent on import; Peer timeouts [#303](https://github.com/paritytech/parity/pull/303) +- Increasing coverage for evm. [#306](https://github.com/paritytech/parity/pull/306) +- ethcore docs [#301](https://github.com/paritytech/parity/pull/301) +- Replacing secure token for deployment [#305](https://github.com/paritytech/parity/pull/305) +- doc.sh [#299](https://github.com/paritytech/parity/pull/299) +- Building beta-* and stable-* tags [#302](https://github.com/paritytech/parity/pull/302) +- Deploying artifacts for tags (release/beta) [#300](https://github.com/paritytech/parity/pull/300) +- cov.sh to show coverage locally [#298](https://github.com/paritytech/parity/pull/298) +- benchmark fixes [#297](https://github.com/paritytech/parity/pull/297) +- Include JSONRPC CLI options. [#296](https://github.com/paritytech/parity/pull/296) +- travis.yml fixes [#293](https://github.com/paritytech/parity/pull/293) +- Improve version string. [#295](https://github.com/paritytech/parity/pull/295) +- Fixed block queue test [#294](https://github.com/paritytech/parity/pull/294) +- Util docs [#292](https://github.com/paritytech/parity/pull/292) +- fixed building docs [#289](https://github.com/paritytech/parity/pull/289) +- update travis to build PRs only against master [#290](https://github.com/paritytech/parity/pull/290) +- Coverage effort [#272](https://github.com/paritytech/parity/pull/272) +- updated docker containers [#288](https://github.com/paritytech/parity/pull/288) +- rpc module fixes [#287](https://github.com/paritytech/parity/pull/287) +- Test for Receipt RLP. [#282](https://github.com/paritytech/parity/pull/282) +- Building from source guide [#284](https://github.com/paritytech/parity/pull/284) +- Fixed neted empty list RLP encoding [#283](https://github.com/paritytech/parity/pull/283) +- Fix CALLDATACOPY (and bonus CODECOPY, too!). [#279](https://github.com/paritytech/parity/pull/279) +- added travis && coveralls badge to README.md [#280](https://github.com/paritytech/parity/pull/280) +- coveralls coverage [#277](https://github.com/paritytech/parity/pull/277) +- Travis [in progress] [#257](https://github.com/paritytech/parity/pull/257) +- Travis on reorganized repo [#276](https://github.com/paritytech/parity/pull/276) +- umbrella project [#275](https://github.com/paritytech/parity/pull/275) +- Ethash disk cache [#273](https://github.com/paritytech/parity/pull/273) +- Parity executable name and version [#274](https://github.com/paritytech/parity/pull/274) +- Dockerfile [#195](https://github.com/paritytech/parity/pull/195) +- Garbage collection test fix [#267](https://github.com/paritytech/parity/pull/267) +- Fix stCallCreateCallCodeTest, add more tests [#271](https://github.com/paritytech/parity/pull/271) +- Moved sync out of ethcore crate; Added block validation [#265](https://github.com/paritytech/parity/pull/265) +- RLP encoder refactoring [#252](https://github.com/paritytech/parity/pull/252) +- Chain sync tests and minor refactoring [#264](https://github.com/paritytech/parity/pull/264) +- Common log init function [#263](https://github.com/paritytech/parity/pull/263) +- changed max vm depth from 128 to 64, change homestead block to 1_000_000 [#262](https://github.com/paritytech/parity/pull/262) +- fixed blockchain tests crash on log init [#261](https://github.com/paritytech/parity/pull/261) +- Blockchain tests and some helpers for guarding temp directory [#256](https://github.com/paritytech/parity/pull/256) +- Fix logging and random tests. [#260](https://github.com/paritytech/parity/pull/260) +- Fix difficulty calculation algo. [#259](https://github.com/paritytech/parity/pull/259) +- fix submodule version [#258](https://github.com/paritytech/parity/pull/258) +- temp dir spawn refactoring [#246](https://github.com/paritytech/parity/pull/246) +- fixed tests submodule branch [#254](https://github.com/paritytech/parity/pull/254) +- rpc net methods returns real peer count && protocol version [#253](https://github.com/paritytech/parity/pull/253) +- Add homestead & random tests. [#245](https://github.com/paritytech/parity/pull/245) +- Fixing suicide with self-refund to be consistent with CPP. [#247](https://github.com/paritytech/parity/pull/247) +- stubs for rpc methods [#251](https://github.com/paritytech/parity/pull/251) +- clippy, missing docs, renaming etc. [#244](https://github.com/paritytech/parity/pull/244) +- impl missing methods in tests [#243](https://github.com/paritytech/parity/pull/243) +- General tests and some helpers [#239](https://github.com/paritytech/parity/pull/239) +- Note additional tests are fixed, fix doc test. [#242](https://github.com/paritytech/parity/pull/242) +- jsonrpc http server [#193](https://github.com/paritytech/parity/pull/193) +- Ethash nonce is H64 not a u64 [#240](https://github.com/paritytech/parity/pull/240) +- Fix import for bcMultiChainTest [#236](https://github.com/paritytech/parity/pull/236) +- Client basic tests [#232](https://github.com/paritytech/parity/pull/232) +- Fix ensure_db_good() and flush_queue(), block refactoring, check block format, be strict. [#231](https://github.com/paritytech/parity/pull/231) +- Rlp [#207](https://github.com/paritytech/parity/pull/207) +- Schedule documentation [#219](https://github.com/paritytech/parity/pull/219) +- U256<->H256 Conversion [#206](https://github.com/paritytech/parity/pull/206) +- Spawning new thread when we are reaching stack limit [#217](https://github.com/paritytech/parity/pull/217) +- Blockchain tests [#211](https://github.com/paritytech/parity/pull/211) +- fixed failing sync test [#218](https://github.com/paritytech/parity/pull/218) +- Removing println [#216](https://github.com/paritytech/parity/pull/216) +- Cleaning readme [#212](https://github.com/paritytech/parity/pull/212) +- Fixing delegatecall [#196](https://github.com/paritytech/parity/pull/196) +- Autogenerate the Args from the docopt macro. [#205](https://github.com/paritytech/parity/pull/205) +- Networking fixes [#202](https://github.com/paritytech/parity/pull/202) +- Argument parsing from CLI [#204](https://github.com/paritytech/parity/pull/204) +- Removed wildcard from clippy version [#203](https://github.com/paritytech/parity/pull/203) +- Fixed tests and tweaked sync progress report [#201](https://github.com/paritytech/parity/pull/201) +- Heavy tests [#199](https://github.com/paritytech/parity/pull/199) +- Mutithreaded IO [#198](https://github.com/paritytech/parity/pull/198) +- Populating last_hashes [#197](https://github.com/paritytech/parity/pull/197) +- Fixing clippy stuff [#170](https://github.com/paritytech/parity/pull/170) +- basic .travis.yml [#194](https://github.com/paritytech/parity/pull/194) +- Generating coverage reports. [#190](https://github.com/paritytech/parity/pull/190) +- Adding doc requests comments [#192](https://github.com/paritytech/parity/pull/192) +- moved src/bin/client.rs -> src/bin/client/main.rs [#185](https://github.com/paritytech/parity/pull/185) +- removed overflowing_shr [#188](https://github.com/paritytech/parity/pull/188) +- fixed wrapping ops on latest nightly [#187](https://github.com/paritytech/parity/pull/187) +- Pruned state DB [#176](https://github.com/paritytech/parity/pull/176) +- Memory management for cache [#180](https://github.com/paritytech/parity/pull/180) +- Implement signs having low-s. [#183](https://github.com/paritytech/parity/pull/183) +- Introduce sha3 crate and use it in ethash [#178](https://github.com/paritytech/parity/pull/178) +- Multithreaded block queue [#173](https://github.com/paritytech/parity/pull/173) +- Iterator for NibbleSlice and TrieDB. [#171](https://github.com/paritytech/parity/pull/171) +- Handling all possible overflows [#145](https://github.com/paritytech/parity/pull/145) +- Global secp256k1 context [#164](https://github.com/paritytech/parity/pull/164) +- Ethash [#152](https://github.com/paritytech/parity/pull/152) +- Move util into here [#153](https://github.com/paritytech/parity/pull/153) +- EVM Interpreter [#103](https://github.com/paritytech/parity/pull/103) +- Homestead transition support, maybe. [#141](https://github.com/paritytech/parity/pull/141) +- externalities refactor [#131](https://github.com/paritytech/parity/pull/131) +- More open files. [#140](https://github.com/paritytech/parity/pull/140) +- Single array for logs output. [#133](https://github.com/paritytech/parity/pull/133) +- Client app event handler [#132](https://github.com/paritytech/parity/pull/132) +- Various consensus fixes. [#130](https://github.com/paritytech/parity/pull/130) +- callcode builtins tests pass [#127](https://github.com/paritytech/parity/pull/127) +- Client state syncing [#119](https://github.com/paritytech/parity/pull/119) +- Split externalities from executive. [#126](https://github.com/paritytech/parity/pull/126) +- executive error on not enoguh base gas [#124](https://github.com/paritytech/parity/pull/124) +- Gav [#125](https://github.com/paritytech/parity/pull/125) +- builtin sets excepted to true [#123](https://github.com/paritytech/parity/pull/123) +- More state tests. [#122](https://github.com/paritytech/parity/pull/122) +- updated to rocksdb wrapper version 0.3 [#121](https://github.com/paritytech/parity/pull/121) +- out_of_gas -> excepted [#120](https://github.com/paritytech/parity/pull/120) +- Parametrizing evm::Factory [#111](https://github.com/paritytech/parity/pull/111) +- stLogs tests passing [#118](https://github.com/paritytech/parity/pull/118) +- Fix executive. [#117](https://github.com/paritytech/parity/pull/117) +- Fixes for marek's shooting from the hip. [#116](https://github.com/paritytech/parity/pull/116) +- Executive revert fix [#115](https://github.com/paritytech/parity/pull/115) +- Fix storage/account and add butress test. [#114](https://github.com/paritytech/parity/pull/114) +- Refactored Pod & Diff types into separate files, JSON infrastructure revamp. [#113](https://github.com/paritytech/parity/pull/113) +- Fix storage stuff and introduce per-item dirty-tracking. [#112](https://github.com/paritytech/parity/pull/112) +- Check logs in state tests. [#109](https://github.com/paritytech/parity/pull/109) +- executive gas calculation fixes [#108](https://github.com/paritytech/parity/pull/108) +- proper gas calculation in executive [#107](https://github.com/paritytech/parity/pull/107) +- Fixing MaxDepth param for executive [#105](https://github.com/paritytech/parity/pull/105) +- Fix determination of state roots. [#106](https://github.com/paritytech/parity/pull/106) +- transact substracts tx_gas [#104](https://github.com/paritytech/parity/pull/104) +- Pretty-print and fix for state. [#102](https://github.com/paritytech/parity/pull/102) +- Tier step price. [#101](https://github.com/paritytech/parity/pull/101) +- Refactor Diff datastructures. [#100](https://github.com/paritytech/parity/pull/100) +- externalities use u256 instead of u64 for gas calculation [#99](https://github.com/paritytech/parity/pull/99) +- Executive tests [#97](https://github.com/paritytech/parity/pull/97) +- State conensus tests now print mismatching diff on fail. [#98](https://github.com/paritytech/parity/pull/98) +- State testing framework. First test is failing. [#96](https://github.com/paritytech/parity/pull/96) +- executive tests [#95](https://github.com/paritytech/parity/pull/95) +- Use U512s for ether cost calculation, complete transaction API [#94](https://github.com/paritytech/parity/pull/94) +- Utils for consensus test decoding and better layout. [#93](https://github.com/paritytech/parity/pull/93) +- executive fixes + tests [#89](https://github.com/paritytech/parity/pull/89) +- All transaction tests pass. Nicer testing framework. [#92](https://github.com/paritytech/parity/pull/92) +- Block verification tests; BlockProvider blockchain trait for testing [#88](https://github.com/paritytech/parity/pull/88) +- State::exists, docs and tests. [#87](https://github.com/paritytech/parity/pull/87) +- Add tests module, add two more transaction tests. [#86](https://github.com/paritytech/parity/pull/86) +- bring back removed tests, removed build warnings [#82](https://github.com/paritytech/parity/pull/82) +- Nicer transaction validation API. Nicer OutOfBounds API in general. [#85](https://github.com/paritytech/parity/pull/85) +- Transaction fixes and consensus tests (all passing) [#84](https://github.com/paritytech/parity/pull/84) +- fixed getting block info in evmjit + tests [#81](https://github.com/paritytech/parity/pull/81) +- evm tests cleanup [#80](https://github.com/paritytech/parity/pull/80) +- renamed VmFactory -> Factory [#77](https://github.com/paritytech/parity/pull/77) +- fixed rust-evmjit description of improper_ctypes usage [#76](https://github.com/paritytech/parity/pull/76) +- jit feature enabled by default [#75](https://github.com/paritytech/parity/pull/75) +- evm [#52](https://github.com/paritytech/parity/pull/52) +- state clone [#74](https://github.com/paritytech/parity/pull/74) +- Block Verification (no tests yet) [#72](https://github.com/paritytech/parity/pull/72) +- Improvements to LogEntry and Transaction [#73](https://github.com/paritytech/parity/pull/73) +- Use getter in header in preparation for a Header trait; additional testing in enact_block(). [#64](https://github.com/paritytech/parity/pull/64) +- BlockChain sync and Client app [#55](https://github.com/paritytech/parity/pull/55) +- Block enactment (including test) [#63](https://github.com/paritytech/parity/pull/63) +- Block complete. Needs tests. [#62](https://github.com/paritytech/parity/pull/62) +- More on OpenBlock::close; State::kill_account added [#61](https://github.com/paritytech/parity/pull/61) +- Remove genesis module, add more chain specs and separate out ethereum-specific stuff [#60](https://github.com/paritytech/parity/pull/60) +- State::new_contract, camelCase engine params, missing param [#59](https://github.com/paritytech/parity/pull/59) +- Use reorganisation [#58](https://github.com/paritytech/parity/pull/58) +- Initial Ethash/Block skeleton implementations. [#57](https://github.com/paritytech/parity/pull/57) +- Spec with tested Morden genesis decoder and builtins. [#54](https://github.com/paritytech/parity/pull/54) +- Move all chain parameters into `engine_params` [#50](https://github.com/paritytech/parity/pull/50) +- jit ffi improvements [please review] [#51](https://github.com/paritytech/parity/pull/51) +- blockchain [please review] [#34](https://github.com/paritytech/parity/pull/34) +- Move information from networkparams.rs into spec.rs [#48](https://github.com/paritytech/parity/pull/48) +- Move bulking out in Engine/Params. [#47](https://github.com/paritytech/parity/pull/47) +- Removed need for mutation in State. [#46](https://github.com/paritytech/parity/pull/46) +- State::code and State::storage_at + tests. [#45](https://github.com/paritytech/parity/pull/45) +- State functions for balance and nonce operations [#44](https://github.com/paritytech/parity/pull/44) +- Account::storage_at, Account::ensure_cached and tests. [#43](https://github.com/paritytech/parity/pull/43) +- Additional tests. [#42](https://github.com/paritytech/parity/pull/42) +- seal todo done [#41](https://github.com/paritytech/parity/pull/41) +- missing rustc_serialize crate && rlp `as_list` function [#40](https://github.com/paritytech/parity/pull/40) +- More methods in Account, documentation and tests. [#39](https://github.com/paritytech/parity/pull/39) +- Minor reworking of Account. [#38](https://github.com/paritytech/parity/pull/38) +- Add Account and State classes. [#37](https://github.com/paritytech/parity/pull/37) +- Revert regressions [#36](https://github.com/paritytech/parity/pull/36) diff --git a/Cargo.lock b/Cargo.lock index d8561cd11..472e11fe5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,7 +18,6 @@ dependencies = [ "ethcore-ipc-tests 0.1.0", "ethcore-light 1.7.0", "ethcore-logger 1.7.0", - "ethcore-rpc 1.7.0", "ethcore-secretstore 1.0.0", "ethcore-signer 1.7.0", "ethcore-stratum 1.7.0", @@ -38,6 +37,7 @@ dependencies = [ "parity-ipfs-api 1.7.0", "parity-local-store 0.1.0", "parity-reactor 0.1.0", + "parity-rpc 1.7.0", "parity-rpc-client 1.4.0", "parity-updater 1.7.0", "path 0.1.0", @@ -181,8 +181,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bn" -version = "0.4.3" -source = "git+https://github.com/paritytech/bn#59d848e642ad1ff0d60e39348576a6f11ee123b8" +version = "0.4.4" +source = "git+https://github.com/paritytech/bn#b97e95a45f4484a41a515338c4f0e093bf6675e0" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -201,7 +201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -339,8 +339,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "elastic-array" -version = "0.6.0" -source = "git+https://github.com/paritytech/elastic-array#346f1ba5982576dab9d0b8fa178b50e1db0a21cd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -394,7 +394,7 @@ version = "1.7.0" dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bn 0.4.3 (git+https://github.com/paritytech/bn)", + "bn 0.4.4 (git+https://github.com/paritytech/bn)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -592,49 +592,6 @@ dependencies = [ "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ethcore-rpc" -version = "1.7.0" -dependencies = [ - "cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "ethash 1.7.0", - "ethcore 1.7.0", - "ethcore-devtools 1.7.0", - "ethcore-io 1.7.0", - "ethcore-ipc 1.7.0", - "ethcore-light 1.7.0", - "ethcore-logger 1.7.0", - "ethcore-util 1.7.0", - "ethcrypto 0.1.0", - "ethjson 0.1.0", - "ethkey 0.2.0", - "ethstore 0.1.0", - "ethsync 1.7.0", - "fetch 0.1.0", - "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", - "jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", - "jsonrpc-ipc-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", - "jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", - "jsonrpc-minihttp-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", - "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-reactor 0.1.0", - "parity-updater 1.7.0", - "rlp 0.1.0", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", - "stats 0.1.0", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ethcore-secretstore" version = "1.0.0" @@ -646,6 +603,7 @@ dependencies = [ "ethcore-ipc 1.7.0", "ethcore-ipc-codegen 1.7.0", "ethcore-ipc-nano 1.7.0", + "ethcore-logger 1.7.0", "ethcore-util 1.7.0", "ethcrypto 0.1.0", "ethkey 0.2.0", @@ -660,7 +618,7 @@ dependencies = [ "serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -674,12 +632,12 @@ dependencies = [ "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-devtools 1.7.0", "ethcore-io 1.7.0", - "ethcore-rpc 1.7.0", "ethcore-util 1.7.0", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-rpc 1.7.0", "parity-ui 1.7.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -713,7 +671,7 @@ version = "1.7.0" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "elastic-array 0.6.0 (git+https://github.com/paritytech/elastic-array)", + "elastic-array 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)", "ethcore-bigint 0.1.2", @@ -1080,7 +1038,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jsonrpc-core" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1092,7 +1050,7 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1105,19 +1063,20 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-tokio-ipc 0.1.0 (git+https://github.com/nikvolf/parity-tokio-ipc)", + "parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-macros" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1127,7 +1086,7 @@ dependencies = [ [[package]] name = "jsonrpc-minihttp-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1141,7 +1100,7 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1151,19 +1110,20 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-tcp-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#32c1c083139db50db6a5d532ccfc2004236dbfc3" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" dependencies = [ + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1172,6 +1132,17 @@ dependencies = [ "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "jsonrpc-ws-server" +version = "7.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#8ed20d6e094e88f707045fca2d0959f46bfd23f9" +dependencies = [ + "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.6.0 (git+https://github.com/tomusdrw/ws-rs)", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -1708,16 +1679,64 @@ dependencies = [ "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-rpc" +version = "1.7.0" +dependencies = [ + "cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "ethash 1.7.0", + "ethcore 1.7.0", + "ethcore-devtools 1.7.0", + "ethcore-io 1.7.0", + "ethcore-ipc 1.7.0", + "ethcore-light 1.7.0", + "ethcore-logger 1.7.0", + "ethcore-util 1.7.0", + "ethcrypto 0.1.0", + "ethjson 0.1.0", + "ethkey 0.2.0", + "ethstore 0.1.0", + "ethsync 1.7.0", + "fetch 0.1.0", + "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-ipc-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-minihttp-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "jsonrpc-ws-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-reactor 0.1.0", + "parity-updater 1.7.0", + "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.1.0", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", + "stats 0.1.0", + "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parity-rpc-client" version = "1.4.0" dependencies = [ - "ethcore-rpc 1.7.0", "ethcore-signer 1.7.0", "ethcore-util 1.7.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-rpc 1.7.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1728,18 +1747,19 @@ dependencies = [ [[package]] name = "parity-tokio-ipc" -version = "0.1.0" -source = "git+https://github.com/nikvolf/parity-tokio-ipc#3d4234de6bdc78688ef803935111003080fd5375" +version = "0.1.5" +source = "git+https://github.com/nikvolf/parity-tokio-ipc#d6c5b3cfcc913a1b9cf0f0562a10b083ceb9fb7c" dependencies = [ + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-line 0.1.0 (git+https://github.com/tokio-rs/tokio-line)", - "tokio-named-pipes 0.1.0 (git+https://github.com/alexcrichton/tokio-named-pipes)", - "tokio-uds 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-named-pipes 0.1.0 (git+https://github.com/nikvolf/tokio-named-pipes)", + "tokio-uds 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1761,7 +1781,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/paritytech/js-precompiled.git#fb346e5f2925d1b2d533eb986bd2cefb962c7a88" +source = "git+https://github.com/paritytech/js-precompiled.git#cff0aec1877a4b75f51de3facee9fe439a41a90d" dependencies = [ "parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2018,7 +2038,7 @@ name = "rlp" version = "0.1.0" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "elastic-array 0.6.0 (git+https://github.com/paritytech/elastic-array)", + "elastic-array 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.1.2", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2027,7 +2047,7 @@ dependencies = [ [[package]] name = "rocksdb" version = "0.4.5" -source = "git+https://github.com/paritytech/rust-rocksdb#8579e896a98cdeff086392236d411dd4aa141774" +source = "git+https://github.com/paritytech/rust-rocksdb#acd192f6ee017a3e8be704958617349d20ee783b" dependencies = [ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb-sys 0.3.0 (git+https://github.com/paritytech/rust-rocksdb)", @@ -2036,7 +2056,7 @@ dependencies = [ [[package]] name = "rocksdb-sys" version = "0.3.0" -source = "git+https://github.com/paritytech/rust-rocksdb#8579e896a98cdeff086392236d411dd4aa141774" +source = "git+https://github.com/paritytech/rust-rocksdb#acd192f6ee017a3e8be704958617349d20ee783b" dependencies = [ "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2081,9 +2101,9 @@ name = "rpc-cli" version = "1.4.0" dependencies = [ "ethcore-bigint 0.1.2", - "ethcore-rpc 1.7.0", "ethcore-util 1.7.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-rpc 1.7.0", "parity-rpc-client 1.4.0", "rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2449,37 +2469,26 @@ name = "tokio-core" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-io" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-line" -version = "0.1.0" -source = "git+https://github.com/tokio-rs/tokio-line#482614ae0c82daf584727ae65a80d854fe861f81" -dependencies = [ - "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-minihttp" version = "0.1.0" @@ -2498,11 +2507,13 @@ dependencies = [ [[package]] name = "tokio-named-pipes" version = "0.1.0" -source = "git+https://github.com/alexcrichton/tokio-named-pipes#3a22f8fc9a441b548aec25bd5df3b1e0ab99fabe" +source = "git+https://github.com/nikvolf/tokio-named-pipes#0b9b728eaeb0a6673c287ac7692be398fd651752" dependencies = [ + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)", "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2546,15 +2557,28 @@ dependencies = [ ] [[package]] -name = "tokio-uds" -version = "0.1.2" +name = "tokio-timer" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2700,7 +2724,7 @@ name = "ws" version = "0.5.3" source = "git+https://github.com/paritytech/ws-rs.git?branch=parity-1.7#30415c17f1bec53b2dcabae5b8b887df75dcbe34" dependencies = [ - "bytes 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.1 (git+https://github.com/paritytech/mio)", @@ -2710,6 +2734,21 @@ dependencies = [ "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ws" +version = "0.6.0" +source = "git+https://github.com/tomusdrw/ws-rs#3259e7ca906c848beae109eb32e492871f8f397d" +dependencies = [ + "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -2770,10 +2809,10 @@ dependencies = [ "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum blastfig 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09640e0509d97d5cdff03a9f5daf087a8e04c735c3b113a75139634a19cfc7b2" "checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d" -"checksum bn 0.4.3 (git+https://github.com/paritytech/bn)" = "" +"checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "" "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" "checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" -"checksum bytes 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46112a0060ae15e3a3f9a445428a53e082b91215b744fa27a1948842f4a64b96" +"checksum bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9edb851115d67d1f18680f9326901768a91d37875b87015518357c6ce22b553" "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e53e6cdfa5ca294863e8c8a32a7cdb4dc0a442c8971d47a0e75b6c27ea268a6a" "checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32" @@ -2790,7 +2829,7 @@ dependencies = [ "checksum docopt 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab32ea6e284d87987066f21a9e809a73c14720571ef34516f0890b3d355ccfd8" "checksum dtoa 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5edd69c67b2f8e0911629b7e6b8a34cb3956613cd7c6e6414966dee349c2db4f" "checksum either 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2b503c86dad62aaf414ecf2b8c527439abedb3f8d812537f0b12bfd6f32a91" -"checksum elastic-array 0.6.0 (git+https://github.com/paritytech/elastic-array)" = "" +"checksum elastic-array 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71a64decd4b8cd06654a4e643c45cb558ad554abbffd82a7e16e34f45f51b605" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" "checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "" "checksum ethabi 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63df67d0af5e3cb906b667ca1a6e00baffbed87d0d8f5f78468a1f5eb3a66345" @@ -2824,6 +2863,7 @@ dependencies = [ "checksum jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "" "checksum jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "" "checksum jsonrpc-tcp-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "" +"checksum jsonrpc-ws-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f" @@ -2873,7 +2913,7 @@ dependencies = [ "checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1d06f6ee0fda786df3784a96ee3f0629f529b91cbfb7d142f6410e6bcd1ce2c" -"checksum parity-tokio-ipc 0.1.0 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "" +"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "" "checksum parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git)" = "" "checksum parity-wordlist 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07779ab11d958acbee30fcf644c99d3fae132d8fcb41282a25e1ee284097bdd2" "checksum parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aebb68eebde2c99f89592d925288600fde220177e46b5c9a91ca218d245aeedf" @@ -2952,14 +2992,14 @@ dependencies = [ "checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" "checksum tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7aef43048292ca0bae4ab32180e85f6202cf2816c2a210c396a84b99dab9270" "checksum tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e958104a67877907c1454386d5482fe8e965a55d60be834a15a44328e7dc76" -"checksum tokio-io 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a278fde45f1be68e44995227d426aaa4841e0980bb0a21b981092f28c3c8473" -"checksum tokio-line 0.1.0 (git+https://github.com/tokio-rs/tokio-line)" = "" +"checksum tokio-io 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "48f55df1341bb92281f229a6030bc2abffde2c7a44c6d6b802b7687dd8be0775" "checksum tokio-minihttp 0.1.0 (git+https://github.com/tomusdrw/tokio-minihttp)" = "" -"checksum tokio-named-pipes 0.1.0 (git+https://github.com/alexcrichton/tokio-named-pipes)" = "" +"checksum tokio-named-pipes 0.1.0 (git+https://github.com/nikvolf/tokio-named-pipes)" = "" "checksum tokio-proto 0.1.0 (git+https://github.com/tomusdrw/tokio-proto)" = "" "checksum tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c0d6031f94d78d7b4d509d4a7c5e1cdf524a17e7b08d1c188a83cf720e69808" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" -"checksum tokio-uds 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc7b5fc8e19e220b29566d1750949224a518478eab9cebc8df60583242ca30a" +"checksum tokio-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86f33def658c14724fc13ec6289b3875a8152ee8ae767a5b1ccbded363b03db8" +"checksum tokio-uds 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bd209039933255ea77c6d7a1d18abc20b997d161acb900acca6eb74cdd049f31" "checksum toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "fcd27a04ca509aff336ba5eb2abc58d456f52c4ff64d9724d88acb85ead560b6" "checksum toml 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a442dfc13508e603c3f763274361db7f79d7469a0e95c411cde53662ab30fc72" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" @@ -2981,6 +3021,7 @@ dependencies = [ "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum ws 0.5.3 (git+https://github.com/paritytech/ws-rs.git?branch=parity-1.7)" = "" +"checksum ws 0.6.0 (git+https://github.com/tomusdrw/ws-rs)" = "" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77b831a5ba77110f438f0ac5583aafeb087f70432998ba6b7dcb1d32185db453" "checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef" diff --git a/Cargo.toml b/Cargo.toml index 09af66e09..37effabb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ ethcore = { path = "ethcore" } ethcore-util = { path = "util" } ethcore-io = { path = "util/io" } ethcore-devtools = { path = "devtools" } -ethcore-rpc = { path = "rpc" } ethcore-signer = { path = "signer" } ethcore-ipc = { path = "ipc/rpc" } ethcore-ipc-nano = { path = "ipc/nano" } @@ -45,12 +44,13 @@ ethkey = { path = "ethkey" } evmbin = { path = "evmbin" } rlp = { path = "util/rlp" } rpc-cli = { path = "rpc_cli" } -parity-rpc-client = { path = "rpc_client" } parity-hash-fetch = { path = "hash-fetch" } parity-ipfs-api = { path = "ipfs" } -parity-updater = { path = "updater" } -parity-reactor = { path = "util/reactor" } parity-local-store = { path = "local-store" } +parity-reactor = { path = "util/reactor" } +parity-rpc = { path = "rpc" } +parity-rpc-client = { path = "rpc_client" } +parity-updater = { path = "updater" } path = { path = "util/path" } parity-dapps = { path = "dapps", optional = true } @@ -85,7 +85,7 @@ ui-precompiled = [ dapps = ["parity-dapps"] ipc = ["ethcore/ipc", "ethsync/ipc"] jit = ["ethcore/jit"] -dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "parity-dapps/dev", "ethcore-signer/dev"] +dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "parity-rpc/dev", "parity-dapps/dev", "ethcore-signer/dev"] json-tests = ["ethcore/json-tests"] test-heavy = ["ethcore/test-heavy"] ethkey-cli = ["ethcore/ethkey-cli"] diff --git a/README.md b/README.md index f668f3218..a21e6eeb9 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# [Parity](https://ethcore.io/parity.html) +# [Parity](https://parity.io/parity.html) ### Fast, light, and robust Ethereum implementation ### [Download latest release](https://github.com/paritytech/parity/releases) -[![build status](https://gitlab.ethcore.io/parity/parity/badges/master/build.svg)](https://gitlab.ethcore.io/parity/parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![GPLv3][license-image]][license-url] +[![build status](https://gitlab.parity.io/parity/parity/badges/master/build.svg)](https://gitlab.parity.io/parity/parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![GPLv3][license-image]][license-url] ### Join the chat! @@ -33,7 +33,7 @@ Be sure to check out [our wiki][wiki-url] for more information. Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs. -Parity comes with a built-in wallet. To access [Parity Wallet](http://127.0.0.1:8080/) simply go to http://127.0.0.1:8080/. It +Parity comes with a built-in wallet. To access [Parity Wallet](http://web3.site/) simply go to http://web3.site/ (if you don't have access to the internet, but still want to use the service, you can also use http://127.0.0.1:8180/). It includes various functionality allowing you to: - create and manage your Ethereum accounts; - manage your Ether and any Ethereum tokens; diff --git a/dapps/src/rpc.rs b/dapps/src/rpc.rs index b743408dc..74c6d8d89 100644 --- a/dapps/src/rpc.rs +++ b/dapps/src/rpc.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use hyper; -use ethcore_rpc::{Metadata, Origin}; +use parity_rpc::{Metadata, Origin}; use jsonrpc_core::{Middleware, MetaIoHandler}; use jsonrpc_http_server::{self as http, AccessControlAllowOrigin, HttpMetaExtractor}; use jsonrpc_http_server::tokio_core::reactor::Remote; diff --git a/docker/centos/Dockerfile b/docker/centos/Dockerfile index d765c1516..a4b98e9d6 100644 --- a/docker/centos/Dockerfile +++ b/docker/centos/Dockerfile @@ -6,7 +6,7 @@ RUN yum -y update&& \ # install rustup RUN curl -sSf https://static.rust-lang.org/rustup.sh -o rustup.sh &&\ ls&&\ - sh rustup.sh -s -- --disable-sudo + sh rustup.sh --disable-sudo # show backtraces ENV RUST_BACKTRACE 1 # set compiler diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index 69a46308d..992578041 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -123,7 +123,7 @@ impl Light { return Err(io::Error::new(io::ErrorKind::Other, "Cache file size mismatch")); } let num_nodes = cache_size / NODE_BYTES; - let mut nodes: Vec = Vec::new(); + let mut nodes: Vec = Vec::with_capacity(num_nodes); nodes.resize(num_nodes, unsafe { mem::uninitialized() }); let buf = unsafe { slice::from_raw_parts_mut(nodes.as_mut_ptr() as *mut u8, cache_size) }; file.read_exact(buf)?; @@ -342,7 +342,6 @@ fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node { } fn light_new(block_number: u64) -> Light { - let seed_compute = SeedHashCompute::new(); let seedhash = seed_compute.get_seedhash(block_number); let cache_size = get_cache_size(block_number); diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index 6d241f7fd..7e6213273 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -106,6 +106,9 @@ pub trait LightChainClient: Send + Sync { /// Get the `i`th CHT root. fn cht_root(&self, i: usize) -> Option; + + /// Get the EIP-86 transition block number. + fn eip86_transition(&self) -> u64; } /// Something which can be treated as a `LightChainClient`. @@ -384,4 +387,8 @@ impl LightChainClient for Client { fn cht_root(&self, i: usize) -> Option { Client::cht_root(self, i) } + + fn eip86_transition(&self) -> u64 { + self.engine().params().eip86_transition + } } diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index e74ab1c70..3632783ca 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -258,7 +258,7 @@ impl Provider for T { }.fake_sign(req.from); self.prove_transaction(transaction, id) - .map(|proof| ::request::ExecutionResponse { items: proof }) + .map(|(_, proof)| ::request::ExecutionResponse { items: proof }) } fn ready_transactions(&self) -> Vec { diff --git a/ethcore/native_contracts/build.rs b/ethcore/native_contracts/build.rs index 91eaa86cd..9c6fb85c4 100644 --- a/ethcore/native_contracts/build.rs +++ b/ethcore/native_contracts/build.rs @@ -22,9 +22,17 @@ use std::io::Write; // TODO: `include!` these from files where they're pretty-printed? const REGISTRY_ABI: &'static str = r#"[{"constant":true,"inputs":[{"name":"_data","type":"address"}],"name":"canReverse","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"bytes32"}],"name":"setData","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"confirmReverse","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[{"name":"success","type":"bool"}],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"drop","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"setFee","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_to","type":"address"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getData","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserved","outputs":[{"name":"reserved","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_who","type":"address"}],"name":"proposeReverse","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"hasReverse","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"getReverse","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_data","type":"address"}],"name":"reverse","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"uint256"}],"name":"setUint","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_who","type":"address"}],"name":"confirmReverseAs","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"removeReverse","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"address"}],"name":"setAddress","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"}]"#; + const SERVICE_TRANSACTION_ABI: &'static str = r#"[{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"}],"name":"certify","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"delegate","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setDelegate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"certified","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"}]"#; + const SECRETSTORE_ACL_STORAGE_ABI: &'static str = r#"[{"constant":true,"inputs":[{"name":"user","type":"address"},{"name":"document","type":"bytes32"}],"name":"checkPermissions","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}]"#; +// be very careful changing these: ensure `ethcore/engines` validator sets have corresponding +// changes. +const VALIDATOR_SET_ABI: &'static str = r#"[{"constant":true,"inputs":[],"name":"transitionNonce","outputs":[{"name":"nonce","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"validators","type":"address[]"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_parent_hash","type":"bytes32"},{"indexed":true,"name":"_nonce","type":"uint256"},{"indexed":false,"name":"_new_set","type":"address[]"}],"name":"ValidatorsChanged","type":"event"}]"#; + +const VALIDATOR_REPORT_ABI: &'static str = r#"[{"constant":false,"inputs":[{"name":"validator","type":"address"},{"name":"blockNumber","type":"uint256"},{"name":"proof","type":"bytes"}],"name":"reportMalicious","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"validator","type":"address"},{"name":"blockNumber","type":"uint256"}],"name":"reportBenign","outputs":[],"payable":false,"type":"function"}]"#; + fn build_file(name: &str, abi: &str, filename: &str) { let code = ::native_contract_generator::generate_module(name, abi).unwrap(); @@ -39,4 +47,6 @@ fn main() { build_file("Registry", REGISTRY_ABI, "registry.rs"); build_file("ServiceTransactionChecker", SERVICE_TRANSACTION_ABI, "service_transaction.rs"); build_file("SecretStoreAclStorage", SECRETSTORE_ACL_STORAGE_ABI, "secretstore_acl_storage.rs"); + build_file("ValidatorSet", VALIDATOR_SET_ABI, "validator_set.rs"); + build_file("ValidatorReport", VALIDATOR_REPORT_ABI, "validator_report.rs"); } diff --git a/ethcore/native_contracts/generator/src/lib.rs b/ethcore/native_contracts/generator/src/lib.rs index f49caf227..76985e682 100644 --- a/ethcore/native_contracts/generator/src/lib.rs +++ b/ethcore/native_contracts/generator/src/lib.rs @@ -46,8 +46,8 @@ pub fn generate_module(struct_name: &str, abi: &str) -> Result { Ok(format!(r##" use byteorder::{{BigEndian, ByteOrder}}; -use futures::{{future, Future, BoxFuture}}; -use ethabi::{{Contract, Interface, Token}}; +use futures::{{future, Future, IntoFuture, BoxFuture}}; +use ethabi::{{Contract, Interface, Token, Event}}; use util::{{self, Uint}}; pub struct {name} {{ @@ -70,6 +70,11 @@ impl {name} {{ }} }} + /// Access the underlying `ethabi` contract. + pub fn contract(this: &Self) -> &Contract {{ + &this.contract + }} + {functions} }} "##, @@ -99,7 +104,10 @@ fn generate_functions(contract: &Contract) -> Result { /// Inputs: {abi_inputs:?} /// Outputs: {abi_outputs:?} pub fn {snake_name}(&self, call: F, {params}) -> BoxFuture<{output_type}, String> - where F: Fn(util::Address, Vec) -> U, U: Future, Error=String> + Send + 'static + where + F: Fn(util::Address, Vec) -> U, + U: IntoFuture, Error=String>, + U::Future: Send + 'static {{ let function = self.contract.function(r#"{abi_name}"#.to_string()) .expect("function existence checked at compile-time; qed"); @@ -111,6 +119,7 @@ pub fn {snake_name}(&self, call: F, {params}) -> BoxFuture<{output_type}, }}; call_future + .into_future() .and_then(move |out| function.decode_output(out).map_err(|e| format!("{{:?}}", e))) .map(::std::collections::VecDeque::from) .and_then(|mut outputs| {decode_outputs}) @@ -299,10 +308,10 @@ fn detokenize(name: &str, output_type: ParamType) -> String { ParamType::Bool => format!("{}.to_bool()", name), ParamType::String => format!("{}.to_string()", name), ParamType::Array(kind) => { - let read_array = format!("x.into_iter().map(|a| {{ {} }}).collect::>()", + let read_array = format!("x.into_iter().map(|a| {{ {} }}).collect::>>()", detokenize("a", *kind)); - format!("{}.to_array().and_then(|x| {})", + format!("{}.to_array().and_then(|x| {{ {} }})", name, read_array) } ParamType::FixedArray(_, _) => panic!("Fixed-length arrays not supported.") diff --git a/ethcore/native_contracts/src/lib.rs b/ethcore/native_contracts/src/lib.rs index e894a636f..1aaaf07b1 100644 --- a/ethcore/native_contracts/src/lib.rs +++ b/ethcore/native_contracts/src/lib.rs @@ -26,7 +26,11 @@ extern crate ethcore_util as util; mod registry; mod service_transaction; mod secretstore_acl_storage; +mod validator_set; +mod validator_report; pub use self::registry::Registry; pub use self::service_transaction::ServiceTransactionChecker; pub use self::secretstore_acl_storage::SecretStoreAclStorage; +pub use self::validator_set::ValidatorSet; +pub use self::validator_report::ValidatorReport; diff --git a/ethcore/native_contracts/src/validator_report.rs b/ethcore/native_contracts/src/validator_report.rs new file mode 100644 index 000000000..d77b07c71 --- /dev/null +++ b/ethcore/native_contracts/src/validator_report.rs @@ -0,0 +1,22 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +#![allow(unused_mut, unused_variables, unused_imports)] + +//! Validator reporting. +// TODO: testing. + +include!(concat!(env!("OUT_DIR"), "/validator_report.rs")); diff --git a/ethcore/native_contracts/src/validator_set.rs b/ethcore/native_contracts/src/validator_set.rs new file mode 100644 index 000000000..0a69913e0 --- /dev/null +++ b/ethcore/native_contracts/src/validator_set.rs @@ -0,0 +1,22 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +#![allow(unused_mut, unused_variables, unused_imports)] + +//! Validator set contract. +// TODO: testing. + +include!(concat!(env!("OUT_DIR"), "/validator_set.rs")); diff --git a/ethcore/res/ethereum/classic.json b/ethcore/res/ethereum/classic.json index f6d30c4d6..f7cb4daca 100644 --- a/ethcore/res/ethereum/classic.json +++ b/ethcore/res/ethereum/classic.json @@ -30,7 +30,8 @@ "chainID": "0x3d", "forkBlock": "0x1d4c00", "forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/eip150_test.json b/ethcore/res/ethereum/eip150_test.json index 8331c8fc2..3091ee27b 100644 --- a/ethcore/res/ethereum/eip150_test.json +++ b/ethcore/res/ethereum/eip150_test.json @@ -24,7 +24,8 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", - "eip98Transition": "0x7fffffffffffffff" + "eip98Transition": "0x7fffffffffffffff", + "eip86Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/eip161_test.json b/ethcore/res/ethereum/eip161_test.json index 00885bae1..e6e8bf3bb 100644 --- a/ethcore/res/ethereum/eip161_test.json +++ b/ethcore/res/ethereum/eip161_test.json @@ -24,7 +24,8 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", - "eip98Transition": "0x7fffffffffffffff" + "eip98Transition": "0x7fffffffffffffff", + "eip86Transition": "0x7fffffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/ethereum/expanse.json index 3ec04052b..b7d22ac3e 100644 --- a/ethcore/res/ethereum/expanse.json +++ b/ethcore/res/ethereum/expanse.json @@ -30,7 +30,8 @@ "networkID": "0x1", "chainID": "0x2", "subprotocolName": "exp", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 54f10b70c..a77b39934 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -147,7 +147,8 @@ "networkID" : "0x1", "forkBlock": "0x1d4c00", "forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { @@ -192,6 +193,7 @@ "0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x7fffffffffffff", "pricing": { "modexp": { "divisor": 20 } } } }, "0000000000000000000000000000000000000006": { "builtin": { "name": "bn128_add", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 999999, "word": 0 } } } }, "0000000000000000000000000000000000000007": { "builtin": { "name": "bn128_mul", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 999999, "word": 0 } } } }, + "0000000000000000000000000000000000000008": { "builtin": { "name": "bn128_pairing", "activate_at": "0x7fffffffffffff", "pricing": { "linear": { "base": 999999, "word": 0 } } } }, "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { "balance": "1337000000000000000000" }, diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index 7b73faa30..aab433033 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -143,7 +143,8 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index bf79729ba..6761c79f3 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -23,7 +23,8 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index 95bd85a94..25b061857 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -23,7 +23,8 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x1", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index 22f253bf8..495849daf 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -30,7 +30,8 @@ "chainID": "0x3e", "forkBlock": "0x1b34d8", "forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index baf1c7d05..3d2e7baf9 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -23,7 +23,8 @@ "maximumExtraDataSize": "0x0400", "minGasLimit": "125000", "networkID" : "0x0", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/ropsten.json b/ethcore/res/ethereum/ropsten.json index 539168279..1e350d636 100644 --- a/ethcore/res/ethereum/ropsten.json +++ b/ethcore/res/ethereum/ropsten.json @@ -27,7 +27,8 @@ "networkID" : "0x3", "forkBlock": 641350, "forkCanonHash": "0x8033403e9fe5811a7b6d6b469905915de1c59207ce2172cbcf5d6ff14fa6a2eb", - "eip98Transition": "0x7fffffffffffff" + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/ethereum/tests b/ethcore/res/ethereum/tests index d52059307..ef191fdc6 160000 --- a/ethcore/res/ethereum/tests +++ b/ethcore/res/ethereum/tests @@ -1 +1 @@ -Subproject commit d520593078fa0849dcd1f907e44ed0a616892e33 +Subproject commit ef191fdc61cf76cdb9cdc147465fb447304b0ed2 diff --git a/ethcore/res/ethereum/transition_test.json b/ethcore/res/ethereum/transition_test.json index 1b502f087..41251dc8c 100644 --- a/ethcore/res/ethereum/transition_test.json +++ b/ethcore/res/ethereum/transition_test.json @@ -139,11 +139,12 @@ } }, "params": { - "eip98Transition": "0x7fffffffffffffff", "accountStartNonce": "0x00", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", - "networkID" : "0x1" + "networkID" : "0x1", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/null.json b/ethcore/res/null.json index 3ec7ce75e..ffb0ea061 100644 --- a/ethcore/res/null.json +++ b/ethcore/res/null.json @@ -7,7 +7,8 @@ "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", - "networkID" : "0x2" + "networkID" : "0x2", + "eip86Transition": "0x7fffffffffffff" }, "genesis": { "seal": { diff --git a/ethcore/res/validator_contract.json b/ethcore/res/validator_contract.json index 6c2f87758..4ef27e30e 100644 --- a/ethcore/res/validator_contract.json +++ b/ethcore/res/validator_contract.json @@ -36,7 +36,7 @@ "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000005": { "balance": "1", - "constructor": "6060604052604060405190810160405280737d577a597b2742b498cb5cf0c26cdcd726d39e6e73ffffffffffffffffffffffffffffffffffffffff1681526020017382a978b3f5962a5b0957d9ee9eef472ee55b42f173ffffffffffffffffffffffffffffffffffffffff1681525060009060028280548282559060005260206000209081019282156100ec579160200282015b828111156100eb5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190610093565b5b50905061012f91905b8082111561012b57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016100f5565b5090565b505034610000575b6000600090505b6000805490508110156101d5578060016000600084815481101561000057906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b808060010191505061013e565b5b505b6105f2806101e76000396000f30060606040523615610076576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806335aa2e441461007b5780634d238c8e146100d8578063b7ab4db51461010b578063bfc708a01461017d578063d8f2e0bf146101b0578063fd6e1b50146101ff575b610000565b34610000576100966004808035906020019091905050610232565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3461000057610109600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061026f565b005b346100005761011861030f565b604051808060200182810382528381815181526020019150805190602001906020028083836000831461016a575b80518252602083111561016a57602082019150602081019050602083039250610146565b5050509050019250505060405180910390f35b34610000576101ae600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506103ad565b005b34610000576101bd61055b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3461000057610230600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610581565b005b600081815481101561000057906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080548060010182818154818355818115116102b8578183600052602060002091820191016102b791905b808211156102b357600081600090555060010161029b565b5090565b5b505050916000526020600020900160005b83909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b602060405190810160405280600081525060008054806020026020016040519081016040528092919081815260200182805480156103a257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610358575b505050505090505b90565b6000600160008054905003815481101561000057906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054815481101561000057906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600090556000600160008054905003815481101561000057906000526020600020900160005b6101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560008054809190600190038154818355818115116105535781836000526020600020918201910161055291905b8082111561054e576000816000905550600101610536565b5090565b5b505050505b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505600a165627a7a7230582063a0123d8e8f5dde980af6b47e20acc5b7a1acac3e3101fa1c933471ef4b405c0029" + "constructor": "60a06040819052737d577a597b2742b498cb5cf0c26cdcd726d39e6e60609081527382a978b3f5962a5b0957d9ee9eef472ee55b42f1608052600080546002825581805290927f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639182019291905b828111156100a25782518254600160a060020a031916600160a060020a0390911617825560209092019160019091019061006d565b5b506100cd9291505b808211156100c9578054600160a060020a03191681556001016100ab565b5090565b505034610000575b60005b60005481101561012f578060016000600084815481101561000057906000526020600020900160005b9054600160a060020a036101009290920a90041681526020810191909152604001600020555b6001016100d8565b5b505b610453806101416000396000f3006060604052361561005c5763ffffffff60e060020a60003504166335aa2e4481146100615780634d238c8e1461008d578063b7ab4db5146100a8578063c476dd4014610110578063d69f13bb14610172578063d8f2e0bf14610190575b610000565b34610000576100716004356101b9565b60408051600160a060020a039092168252519081900360200190f35b34610000576100a6600160a060020a03600435166101e9565b005b34610000576100b5610260565b60408051602080825283518183015283519192839290830191858101910280838382156100fd575b8051825260208311156100fd57601f1990920191602091820191016100dd565b5050509050019250505060405180910390f35b3461000057604080516020600460443581810135601f81018490048402850184019095528484526100a6948235600160a060020a03169460248035956064949293919092019181908401838280828437509496506102ca95505050505050565b005b34610000576100a6600160a060020a03600435166024356103eb565b005b3461000057610071610418565b60408051600160a060020a039092168252519081900360200190f35b600081815481101561000057906000526020600020900160005b915054906101000a9004600160a060020a031681565b6000805480600101828181548183558181151161022b5760008381526020902061022b9181019083015b808211156102275760008155600101610213565b5090565b5b505050916000526020600020900160005b8154600160a060020a038086166101009390930a92830292021916179055505b50565b60408051602081810183526000808352805484518184028101840190955280855292939290918301828280156102bf57602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116102a1575b505050505090505b90565b6000805460001981019081101561000057906000526020600020900160005b9054906101000a9004600160a060020a031660006001600086600160a060020a0316600160a060020a0316815260200190815260200160002054815481101561000057906000526020600020900160005b8154600160a060020a039384166101009290920a918202918402191617905583166000908152600160205260408120819055805460001981019081101561000057906000526020600020900160005b6101000a815490600160a060020a03021916905560008054809190600190038154818355818115116103e0576000838152602090206103e09181019083015b808211156102275760008155600101610213565b5090565b5b505050505b505050565b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0384161790555b5050565b600254600160a060020a0316815600a165627a7a72305820f7876e17abd5f0927fff16788b4b3c9028ed64e6db740d788b07fc5f0a8f10920029" }, "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }, "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { "balance": "1606938044258990275541962092341162602522202993782792835301376" } diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs index 3db3e3c81..34dcb9760 100644 --- a/ethcore/src/account_db.rs +++ b/ethcore/src/account_db.rs @@ -78,6 +78,7 @@ pub struct AccountDB<'db> { impl<'db> AccountDB<'db> { /// Create a new AccountDB from an address. + #[cfg(test)] pub fn new(db: &'db HashDB, address: &Address) -> Self { Self::from_hash(db, address.sha3()) } @@ -131,6 +132,7 @@ pub struct AccountDBMut<'db> { impl<'db> AccountDBMut<'db> { /// Create a new AccountDB from an address. + #[cfg(test)] pub fn new(db: &'db mut HashDB, address: &Address) -> Self { Self::from_hash(db, address.sha3()) } @@ -143,7 +145,7 @@ impl<'db> AccountDBMut<'db> { } } - #[allow(dead_code)] + #[cfg(test)] pub fn immutable(&'db self) -> AccountDB<'db> { AccountDB { db: self.db, address_hash: self.address_hash.clone() } } diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 12e77d41b..a983b229a 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -484,7 +484,11 @@ impl LockedBlock { /// Provide a valid seal in order to turn this into a `SealedBlock`. /// This does check the validity of `seal` with the engine. /// Returns the `ClosedBlock` back again if the seal is no good. - pub fn try_seal(self, engine: &Engine, seal: Vec) -> Result { + pub fn try_seal( + self, + engine: &Engine, + seal: Vec, + ) -> Result { let mut s = self; s.block.header.set_seal(seal); match engine.verify_block_seal(&s.block.header) { @@ -667,8 +671,7 @@ mod tests { use spec::*; let spec = Spec::new_test(); let genesis_header = spec.genesis_header(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); @@ -682,16 +685,14 @@ mod tests { let engine = &*spec.engine; let genesis_header = spec.genesis_header(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap() .close_and_lock().seal(engine, vec![]).unwrap(); let orig_bytes = b.rlp_bytes(); let orig_db = b.drain(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap(); assert_eq!(e.rlp_bytes(), orig_bytes); @@ -708,8 +709,7 @@ mod tests { let engine = &*spec.engine; let genesis_header = spec.genesis_header(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle1_header = Header::new(); @@ -723,8 +723,7 @@ mod tests { let orig_bytes = b.rlp_bytes(); let orig_db = b.drain(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap(); let bytes = e.rlp_bytes(); diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 8986dc6b8..21b2be4cd 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -419,6 +419,45 @@ impl<'a> Iterator for AncestryIter<'a> { } } +/// An iterator which walks all epoch transitions. +/// Returns epoch transitions. +pub struct EpochTransitionIter<'a> { + chain: &'a BlockChain, + prefix_iter: Box, Box<[u8]>)> + 'a>, +} + +impl<'a> Iterator for EpochTransitionIter<'a> { + type Item = (u64, EpochTransition); + + fn next(&mut self) -> Option { + loop { + match self.prefix_iter.next() { + Some((key, val)) => { + // iterator may continue beyond values beginning with this + // prefix. + if !key.starts_with(&EPOCH_KEY_PREFIX[..]) { return None } + + let transitions: EpochTransitions = ::rlp::decode(&val[..]); + + // if there are multiple candidates, at most one will be on the + // canon chain. + for transition in transitions.candidates.into_iter() { + let is_in_canon_chain = self.chain.block_hash(transition.block_number) + .map_or(false, |hash| hash == transition.block_hash); + + if is_in_canon_chain { + return Some((transitions.number, transition)) + } + } + + // some epochs never occurred on the main chain. + } + None => return None, + } + } + } +} + impl BlockChain { /// Create new instance of blockchain from given Genesis. pub fn new(config: Config, genesis: &[u8], db: Arc) -> BlockChain { @@ -650,12 +689,19 @@ impl BlockChain { /// ```json /// { blocks: [B4, B3, A3, A4], ancestor: A2, index: 2 } /// ``` - pub fn tree_route(&self, from: H256, to: H256) -> TreeRoute { + /// + /// If the tree route verges into pruned or unknown blocks, + /// `None` is returned. + pub fn tree_route(&self, from: H256, to: H256) -> Option { + macro_rules! otry { + ($e:expr) => { match $e { Some(x) => x, None => return None } } + } + let mut from_branch = vec![]; let mut to_branch = vec![]; - let mut from_details = self.block_details(&from).unwrap_or_else(|| panic!("0. Expected to find details for block {:?}", from)); - let mut to_details = self.block_details(&to).unwrap_or_else(|| panic!("1. Expected to find details for block {:?}", to)); + let mut from_details = otry!(self.block_details(&from)); + let mut to_details = otry!(self.block_details(&to)); let mut current_from = from; let mut current_to = to; @@ -663,13 +709,13 @@ impl BlockChain { while from_details.number > to_details.number { from_branch.push(current_from); current_from = from_details.parent.clone(); - from_details = self.block_details(&from_details.parent).unwrap_or_else(|| panic!("2. Expected to find details for block {:?}", from_details.parent)); + from_details = otry!(self.block_details(&from_details.parent)); } while to_details.number > from_details.number { to_branch.push(current_to); current_to = to_details.parent.clone(); - to_details = self.block_details(&to_details.parent).unwrap_or_else(|| panic!("3. Expected to find details for block {:?}", to_details.parent)); + to_details = otry!(self.block_details(&to_details.parent)); } assert_eq!(from_details.number, to_details.number); @@ -678,22 +724,22 @@ impl BlockChain { while current_from != current_to { from_branch.push(current_from); current_from = from_details.parent.clone(); - from_details = self.block_details(&from_details.parent).unwrap_or_else(|| panic!("4. Expected to find details for block {:?}", from_details.parent)); + from_details = otry!(self.block_details(&from_details.parent)); to_branch.push(current_to); current_to = to_details.parent.clone(); - to_details = self.block_details(&to_details.parent).unwrap_or_else(|| panic!("5. Expected to find details for block {:?}", from_details.parent)); + to_details = otry!(self.block_details(&to_details.parent)); } let index = from_branch.len(); from_branch.extend(to_branch.into_iter().rev()); - TreeRoute { + Some(TreeRoute { blocks: from_branch, ancestor: current_from, index: index - } + }) } /// Inserts a verified, known block from the canonical chain. @@ -797,6 +843,35 @@ impl BlockChain { } } + /// Insert an epoch transition. Provide an epoch number being transitioned to + /// and epoch transition object. + /// + /// The block the transition occurred at should have already been inserted into the chain. + pub fn insert_epoch_transition(&self, batch: &mut DBTransaction, epoch_num: u64, transition: EpochTransition) { + let mut transitions = match self.db.read(db::COL_EXTRA, &epoch_num) { + Some(existing) => existing, + None => EpochTransitions { + number: epoch_num, + candidates: Vec::with_capacity(1), + } + }; + + // ensure we don't write any duplicates. + if transitions.candidates.iter().find(|c| c.block_hash == transition.block_hash).is_none() { + transitions.candidates.push(transition); + batch.write(db::COL_EXTRA, &epoch_num, &transitions); + } + } + + /// Iterate over all epoch transitions. + pub fn epoch_transitions(&self) -> EpochTransitionIter { + let iter = self.db.iter_from_prefix(db::COL_EXTRA, &EPOCH_KEY_PREFIX[..]); + EpochTransitionIter { + chain: self, + prefix_iter: iter, + } + } + /// Add a child to a given block. Assumes that the block hash is in /// the chain and the child's parent is this block. /// @@ -879,7 +954,8 @@ impl BlockChain { // are moved to "canon chain" // find the route between old best block and the new one let best_hash = self.best_block_hash(); - let route = self.tree_route(best_hash, parent_hash); + let route = self.tree_route(best_hash, parent_hash) + .expect("blocks being imported always within recent history; qed"); assert_eq!(number, parent_details.number + 1); @@ -1711,52 +1787,52 @@ mod tests { assert_eq!(bc.block_hash(3).unwrap(), b3a_hash); // test trie route - let r0_1 = bc.tree_route(genesis_hash.clone(), b1_hash.clone()); + let r0_1 = bc.tree_route(genesis_hash.clone(), b1_hash.clone()).unwrap(); assert_eq!(r0_1.ancestor, genesis_hash); assert_eq!(r0_1.blocks, [b1_hash.clone()]); assert_eq!(r0_1.index, 0); - let r0_2 = bc.tree_route(genesis_hash.clone(), b2_hash.clone()); + let r0_2 = bc.tree_route(genesis_hash.clone(), b2_hash.clone()).unwrap(); assert_eq!(r0_2.ancestor, genesis_hash); assert_eq!(r0_2.blocks, [b1_hash.clone(), b2_hash.clone()]); assert_eq!(r0_2.index, 0); - let r1_3a = bc.tree_route(b1_hash.clone(), b3a_hash.clone()); + let r1_3a = bc.tree_route(b1_hash.clone(), b3a_hash.clone()).unwrap(); assert_eq!(r1_3a.ancestor, b1_hash); assert_eq!(r1_3a.blocks, [b2_hash.clone(), b3a_hash.clone()]); assert_eq!(r1_3a.index, 0); - let r1_3b = bc.tree_route(b1_hash.clone(), b3b_hash.clone()); + let r1_3b = bc.tree_route(b1_hash.clone(), b3b_hash.clone()).unwrap(); assert_eq!(r1_3b.ancestor, b1_hash); assert_eq!(r1_3b.blocks, [b2_hash.clone(), b3b_hash.clone()]); assert_eq!(r1_3b.index, 0); - let r3a_3b = bc.tree_route(b3a_hash.clone(), b3b_hash.clone()); + let r3a_3b = bc.tree_route(b3a_hash.clone(), b3b_hash.clone()).unwrap(); assert_eq!(r3a_3b.ancestor, b2_hash); assert_eq!(r3a_3b.blocks, [b3a_hash.clone(), b3b_hash.clone()]); assert_eq!(r3a_3b.index, 1); - let r1_0 = bc.tree_route(b1_hash.clone(), genesis_hash.clone()); + let r1_0 = bc.tree_route(b1_hash.clone(), genesis_hash.clone()).unwrap(); assert_eq!(r1_0.ancestor, genesis_hash); assert_eq!(r1_0.blocks, [b1_hash.clone()]); assert_eq!(r1_0.index, 1); - let r2_0 = bc.tree_route(b2_hash.clone(), genesis_hash.clone()); + let r2_0 = bc.tree_route(b2_hash.clone(), genesis_hash.clone()).unwrap(); assert_eq!(r2_0.ancestor, genesis_hash); assert_eq!(r2_0.blocks, [b2_hash.clone(), b1_hash.clone()]); assert_eq!(r2_0.index, 2); - let r3a_1 = bc.tree_route(b3a_hash.clone(), b1_hash.clone()); + let r3a_1 = bc.tree_route(b3a_hash.clone(), b1_hash.clone()).unwrap(); assert_eq!(r3a_1.ancestor, b1_hash); assert_eq!(r3a_1.blocks, [b3a_hash.clone(), b2_hash.clone()]); assert_eq!(r3a_1.index, 2); - let r3b_1 = bc.tree_route(b3b_hash.clone(), b1_hash.clone()); + let r3b_1 = bc.tree_route(b3b_hash.clone(), b1_hash.clone()).unwrap(); assert_eq!(r3b_1.ancestor, b1_hash); assert_eq!(r3b_1.blocks, [b3b_hash.clone(), b2_hash.clone()]); assert_eq!(r3b_1.index, 2); - let r3b_3a = bc.tree_route(b3b_hash.clone(), b3a_hash.clone()); + let r3b_3a = bc.tree_route(b3b_hash.clone(), b3a_hash.clone()).unwrap(); assert_eq!(r3b_3a.ancestor, b2_hash); assert_eq!(r3b_3a.blocks, [b3b_hash.clone(), b3a_hash.clone()]); assert_eq!(r3b_3a.index, 1); @@ -1791,15 +1867,13 @@ mod tests { #[test] fn can_contain_arbitrary_block_sequence() { - let bc_result = generate_dummy_blockchain(50); - let bc = bc_result.reference(); + let bc = generate_dummy_blockchain(50); assert_eq!(bc.best_block_number(), 49); } #[test] fn can_collect_garbage() { - let bc_result = generate_dummy_blockchain(3000); - let bc = bc_result.reference(); + let bc = generate_dummy_blockchain(3000); assert_eq!(bc.best_block_number(), 2999); let best_hash = bc.best_block_hash(); @@ -1818,15 +1892,13 @@ mod tests { #[test] fn can_contain_arbitrary_block_sequence_with_extra() { - let bc_result = generate_dummy_blockchain_with_extra(25); - let bc = bc_result.reference(); + let bc = generate_dummy_blockchain_with_extra(25); assert_eq!(bc.best_block_number(), 24); } #[test] fn can_contain_only_genesis_block() { - let bc_result = generate_dummy_empty_blockchain(); - let bc = bc_result.reference(); + let bc = generate_dummy_empty_blockchain(); assert_eq!(bc.best_block_number(), 0); } @@ -2110,4 +2182,58 @@ mod tests { assert_eq!(bc.rewind(), Some(genesis_hash.clone())); assert_eq!(bc.rewind(), None); } + + #[test] + fn epoch_transitions_iter() { + use blockchain::extras::EpochTransition; + + let mut canon_chain = ChainGenerator::default(); + let mut finalizer = BlockFinalizer::default(); + let genesis = canon_chain.generate(&mut finalizer).unwrap(); + + let db = new_db(); + { + let bc = new_chain(&genesis, db.clone()); + let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap(); + + let mut batch = db.transaction(); + // create a longer fork + for i in 0..5 { + let canon_block = canon_chain.generate(&mut finalizer).unwrap(); + let hash = BlockView::new(&canon_block).header_view().sha3(); + + bc.insert_block(&mut batch, &canon_block, vec![]); + bc.insert_epoch_transition(&mut batch, i, EpochTransition { + block_hash: hash, + block_number: i + 1, + proof: vec![], + state_proof: vec![], + }); + bc.commit(); + } + + assert_eq!(bc.best_block_number(), 5); + + let hash = BlockView::new(&uncle).header_view().sha3(); + bc.insert_block(&mut batch, &uncle, vec![]); + bc.insert_epoch_transition(&mut batch, 999, EpochTransition { + block_hash: hash, + block_number: 1, + proof: vec![], + state_proof: vec![] + }); + + db.write(batch).unwrap(); + bc.commit(); + + // epoch 999 not in canonical chain. + assert_eq!(bc.epoch_transitions().map(|(i, _)| i).collect::>(), vec![0, 1, 2, 3, 4]); + } + + // re-loading the blockchain should load the correct best block. + let bc = new_chain(&genesis, db); + + assert_eq!(bc.best_block_number(), 5); + assert_eq!(bc.epoch_transitions().map(|(i, _)| i).collect::>(), vec![0, 1, 2, 3, 4]); + } } diff --git a/ethcore/src/blockchain/extras.rs b/ethcore/src/blockchain/extras.rs index 0c8616a45..7de49f3bf 100644 --- a/ethcore/src/blockchain/extras.rs +++ b/ethcore/src/blockchain/extras.rs @@ -18,6 +18,7 @@ use bloomchain; use util::*; +use util::kvdb::PREFIX_LEN as DB_PREFIX_LEN; use rlp::*; use header::BlockNumber; use receipt::Receipt; @@ -37,6 +38,8 @@ pub enum ExtrasIndex { BlocksBlooms = 3, /// Block receipts index BlockReceipts = 4, + /// Epoch transition data index. + EpochTransitions = 5, } fn with_index(hash: &H256, i: ExtrasIndex) -> H264 { @@ -134,6 +137,36 @@ impl Key for H256 { } } +/// length of epoch keys. +pub const EPOCH_KEY_LEN: usize = DB_PREFIX_LEN + 16; + +/// epoch key prefix. +/// used to iterate over all epoch transitions in order from genesis. +pub const EPOCH_KEY_PREFIX: &'static [u8; DB_PREFIX_LEN] = &[ + ExtrasIndex::EpochTransitions as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +]; + +pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]); +impl Deref for EpochTransitionsKey { + type Target = [u8]; + + fn deref(&self) -> &[u8] { &self.0[..] } +} + +impl Key for u64 { + type Target = EpochTransitionsKey; + + fn key(&self) -> Self::Target { + let mut arr = [0u8; EPOCH_KEY_LEN]; + arr[..DB_PREFIX_LEN].copy_from_slice(&EPOCH_KEY_PREFIX[..]); + + write!(&mut arr[DB_PREFIX_LEN..], "{:016x}", self) + .expect("format arg is valid; no more than 16 chars will be written; qed"); + + EpochTransitionsKey(arr) + } +} + /// Familial details concerning a block #[derive(Debug, Clone)] pub struct BlockDetails { @@ -144,7 +177,7 @@ pub struct BlockDetails { /// Parent block hash pub parent: H256, /// List of children block hashes - pub children: Vec + pub children: Vec, } impl HeapSizeOf for BlockDetails { @@ -241,6 +274,63 @@ impl HeapSizeOf for BlockReceipts { } } +/// Candidate transitions to an epoch with specific number. +#[derive(Clone)] +pub struct EpochTransitions { + pub number: u64, + pub candidates: Vec, +} + +impl Encodable for EpochTransitions { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(2).append(&self.number).append_list(&self.candidates); + } +} + +impl Decodable for EpochTransitions { + fn decode(rlp: &UntrustedRlp) -> Result { + Ok(EpochTransitions { + number: rlp.val_at(0)?, + candidates: rlp.list_at(1)?, + }) + } +} + +#[derive(Debug, Clone)] +pub struct EpochTransition { + pub block_hash: H256, // block hash at which the transition occurred. + pub block_number: BlockNumber, // block number at which the tranition occurred. + pub proof: Vec, // "transition/epoch" proof from the engine. + pub state_proof: Vec, // state items necessary to regenerate proof. +} + +impl Encodable for EpochTransition { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(4) + .append(&self.block_hash) + .append(&self.block_number) + .append(&self.proof) + .begin_list(self.state_proof.len()); + + for item in &self.state_proof { + s.append(&&**item); + } + } +} + +impl Decodable for EpochTransition { + fn decode(rlp: &UntrustedRlp) -> Result { + Ok(EpochTransition { + block_hash: rlp.val_at(0)?, + block_number: rlp.val_at(1)?, + proof: rlp.val_at(2)?, + state_proof: rlp.at(3)?.iter().map(|x| { + Ok(DBValue::from_slice(x.data()?)) + }).collect::, _>>()?, + }) + } +} + #[cfg(test)] mod tests { use rlp::*; diff --git a/ethcore/src/blockchain/mod.rs b/ethcore/src/blockchain/mod.rs index 55a67e2b6..2d6d6ddb3 100644 --- a/ethcore/src/blockchain/mod.rs +++ b/ethcore/src/blockchain/mod.rs @@ -31,5 +31,6 @@ pub mod generator; pub use self::blockchain::{BlockProvider, BlockChain}; pub use self::cache::CacheSize; pub use self::config::Config; +pub use self::extras::EpochTransition; pub use types::tree_route::TreeRoute; pub use self::import_route::ImportRoute; diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index bdedd5739..12d4d9ac1 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -158,6 +158,7 @@ fn ethereum_builtin(name: &str) -> Box { "modexp" => Box::new(ModexpImpl) as Box, "bn128_add" => Box::new(Bn128AddImpl) as Box, "bn128_mul" => Box::new(Bn128MulImpl) as Box, + "bn128_pairing" => Box::new(Bn128PairingImpl) as Box, _ => panic!("invalid builtin name: {}", name), } } @@ -191,6 +192,9 @@ struct Bn128AddImpl; #[derive(Debug)] struct Bn128MulImpl; +#[derive(Debug)] +struct Bn128PairingImpl; + impl Impl for Identity { fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { output.write(0, input); @@ -393,11 +397,109 @@ impl Impl for Bn128MulImpl { } } +mod bn128_gen { + use bn::{AffineG1, AffineG2, Fq, Fq2, G1, G2, Gt, pairing}; + + lazy_static! { + pub static ref P1: G1 = G1::from(AffineG1::new( + Fq::from_str("1").expect("1 is a valid field element"), + Fq::from_str("2").expect("2 is a valid field element"), + ).expect("Generator P1(1, 2) is a valid curve point")); + } + + lazy_static! { + pub static ref P2: G2 = G2::from(AffineG2::new( + Fq2::new( + Fq::from_str("10857046999023057135944570762232829481370756359578518086990519993285655852781") + .expect("a valid field element"), + Fq::from_str("11559732032986387107991004021392285783925812861821192530917403151452391805634") + .expect("a valid field element"), + ), + Fq2::new( + Fq::from_str("8495653923123431417604973247489272438418190587263600148770280649306958101930") + .expect("a valid field element"), + Fq::from_str("4082367875863433681332203403145435568316851327593401208105741076214120093531") + .expect("a valid field element"), + ), + ).expect("the generator P2(10857046999023057135944570762232829481370756359578518086990519993285655852781 + 11559732032986387107991004021392285783925812861821192530917403151452391805634i, 8495653923123431417604973247489272438418190587263600148770280649306958101930 + 4082367875863433681332203403145435568316851327593401208105741076214120093531i) is a valid curve point")); + } + + lazy_static! { + pub static ref P1_P2_PAIRING: Gt = pairing(P1.clone(), P2.clone()); + } +} + +impl Impl for Bn128PairingImpl { + /// Can fail if: + /// - input length is not a multiple of 192 + /// - any of odd points does not belong to bn128 curve + /// - any of even points does not belong to the twisted bn128 curve over the field F_p^2 = F_p[i] / (i^2 + 1) + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + use bn::{AffineG1, AffineG2, Fq, Fq2, pairing, G1, G2, Gt}; + + let elements = input.len() / 192; // (a, b_a, b_b - each 64-byte affine coordinates) + if input.len() % 192 != 0 { + return Err("Invalid input length, must be multiple of 192 (3 * (32*2))".into()) + } + let ret_val = if input.len() == 0 { + U256::one() + } else { + let mut vals = Vec::new(); + for idx in 0..elements { + let a_x = Fq::from_slice(&input[idx*192..idx*192+32]) + .map_err(|_| Error::from("Invalid a argument x coordinate"))?; + + let a_y = Fq::from_slice(&input[idx*192+32..idx*192+64]) + .map_err(|_| Error::from("Invalid a argument y coordinate"))?; + + let b_b_x = Fq::from_slice(&input[idx*192+64..idx*192+96]) + .map_err(|_| Error::from("Invalid b argument imaginary coeff x coordinate"))?; + + let b_b_y = Fq::from_slice(&input[idx*192+96..idx*192+128]) + .map_err(|_| Error::from("Invalid b argument imaginary coeff y coordinate"))?; + + let b_a_x = Fq::from_slice(&input[idx*192+128..idx*192+160]) + .map_err(|_| Error::from("Invalid b argument real coeff x coordinate"))?; + + let b_a_y = Fq::from_slice(&input[idx*192+160..idx*192+192]) + .map_err(|_| Error::from("Invalid b argument real coeff y coordinate"))?; + + vals.push(( + G1::from( + AffineG1::new(a_x, a_y).map_err(|_| Error::from("Invalid a argument - not on curve"))? + ), + G2::from( + AffineG2::new( + Fq2::new(b_a_x, b_a_y), + Fq2::new(b_b_x, b_b_y), + ).map_err(|_| Error::from("Invalid b argument - not on curve"))? + ), + )); + }; + + let mul = vals.into_iter().fold(Gt::one(), |s, (a, b)| s * pairing(a, b)); + + if mul == *bn128_gen::P1_P2_PAIRING { + U256::one() + } else { + U256::zero() + } + }; + + let mut buf = [0u8; 32]; + ret_val.to_big_endian(&mut buf); + output.write(0, &buf); + + Ok(()) + } +} + #[cfg(test)] mod tests { use super::{Builtin, Linear, ethereum_builtin, Pricer, Modexp}; use ethjson; use util::{U256, BytesRef}; + use rustc_serialize::hex::FromHex; #[test] fn identity() { @@ -713,7 +815,82 @@ mod tests { assert!(res.is_err(), "There should be built-in error here"); } } + + fn builtin_pairing() -> Builtin { + Builtin { + pricer: Box::new(Linear { base: 0, word: 0 }), + native: ethereum_builtin("bn128_pairing"), + activate_at: 0, + } + } + + fn empty_test(f: Builtin, expected: Vec) { + let mut empty = [0u8; 0]; + let input = BytesRef::Fixed(&mut empty); + + let mut output = vec![0u8; expected.len()]; + + f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..])).expect("Builtin should not fail"); + assert_eq!(output, expected); + } + + fn error_test(f: Builtin, input: &[u8], msg_contains: Option<&str>) { + let mut output = vec![0u8; 64]; + let res = f.execute(input, &mut BytesRef::Fixed(&mut output[..])); + if let Some(msg) = msg_contains { + if let Err(e) = res { + if !e.0.contains(msg) { + panic!("There should be error containing '{}' here, but got: '{}'", msg, e.0); + } + } + } else { + assert!(res.is_err(), "There should be built-in error here"); + } + } + + fn bytes(s: &'static str) -> Vec { + FromHex::from_hex(s).expect("static str should contain valid hex bytes") + } + #[test] + fn bn128_pairing_empty() { + // should not fail, because empty input is a valid input of 0 elements + empty_test( + builtin_pairing(), + bytes("0000000000000000000000000000000000000000000000000000000000000001"), + ); + } + + #[test] + fn bn128_pairing_notcurve() { + // should fail - point not on curve + error_test( + builtin_pairing(), + &bytes("\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111" + ), + Some("not on curve"), + ); + } + + #[test] + fn bn128_pairing_fragmented() { + // should fail - input length is invalid + error_test( + builtin_pairing(), + &bytes("\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 111111111111111111111111111111" + ), + Some("Invalid input length"), + ); + } #[test] #[should_panic] diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 4bd29d100..a1f47251c 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -32,13 +32,13 @@ use util::kvdb::*; // other use basic_types::Seal; use block::*; -use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute}; +use blockchain::{BlockChain, BlockProvider, EpochTransition, TreeRoute, ImportRoute}; use blockchain::extras::TransactionAddress; use client::Error as ClientError; use client::{ BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, MiningBlockChainClient, EngineClient, TraceFilter, CallAnalytics, BlockImportError, Mode, - ChainNotify, PruningInfo, + ChainNotify, PruningInfo, ProvingBlockChainClient, }; use encoded; use engines::Engine; @@ -49,7 +49,7 @@ use evm::{Factory as EvmFactory, Schedule}; use executive::{Executive, Executed, TransactOptions, contract_address}; use factory::Factories; use futures::{future, Future}; -use header::BlockNumber; +use header::{BlockNumber, Header}; use io::*; use log_entry::LocalizedLogEntry; use miner::{Miner, MinerService, TransactionImportResult}; @@ -166,8 +166,7 @@ impl Client { db: Arc, miner: Arc, message_channel: IoChannel, - ) -> Result, ClientError> { - + ) -> Result, ::error::Error> { let trie_spec = match config.fat_db { true => TrieSpec::Fat, false => TrieSpec::Secure, @@ -247,17 +246,27 @@ impl Client { exit_handler: Mutex::new(None), }); + // prune old states. { let state_db = client.state_db.lock().boxed_clone(); let chain = client.chain.read(); client.prune_ancient(state_db, &chain)?; } + // ensure genesis epoch proof in the DB. + { + let chain = client.chain.read(); + client.generate_epoch_proof(&spec.genesis_header(), 0, &*chain); + } + if let Some(reg_addr) = client.additional_params().get("registrar").and_then(|s| Address::from_str(s).ok()) { trace!(target: "client", "Found registrar at {}", reg_addr); let registrar = Registry::new(reg_addr); *client.registrar.lock() = Some(registrar); } + + // ensure buffered changes are flushed. + client.db.read().flush().map_err(ClientError::Database)?; Ok(client) } @@ -368,7 +377,7 @@ impl Client { let chain = self.chain.read(); // Check the block isn't so old we won't be able to enact it. let best_block_number = chain.best_block_number(); - if best_block_number >= self.history && header.number() <= best_block_number - self.history { + if self.pruning_info().earliest_state > header.number() { warn!(target: "client", "Block import failed for #{} ({})\nBlock is ancient (current best block: #{}).", header.number(), header.hash(), best_block_number); return Err(()); } @@ -380,6 +389,12 @@ impl Client { return Err(()); }; + let verify_external_result = self.verifier.verify_block_external(header, &block.bytes, engine); + if let Err(e) = verify_external_result { + warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); + return Err(()); + }; + // Check if Parent is in chain let chain_has_parent = chain.block_header(header.parent_hash()); if let Some(parent) = chain_has_parent { @@ -398,7 +413,7 @@ impl Client { // Final Verification if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header()) { - warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); + warn!(target: "client", "Stage 5 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); return Err(()); } @@ -569,6 +584,22 @@ impl Client { //let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new)); let mut batch = DBTransaction::new(); + + // generate validation proof if the engine requires them. + // TODO: make conditional? + let entering_new_epoch = { + use engines::EpochChange; + match self.engine.is_epoch_end(block.header(), Some(block_data), Some(&receipts)) { + EpochChange::Yes(e, _) => Some((block.header().clone(), e)), + EpochChange::No => None, + EpochChange::Unsure(_) => { + warn!(target: "client", "Detected invalid engine implementation."); + warn!(target: "client", "Engine claims to require more block data, but everything provided."); + None + } + } + }; + // CHECK! I *think* this is fine, even if the state_root is equal to another // already-imported block of the same number. // TODO: Prove it with a test. @@ -576,6 +607,7 @@ impl Client { state.journal_under(&mut batch, number, hash).expect("DB commit failed"); let route = chain.insert_block(&mut batch, block_data, receipts); + self.tracedb.read().import(&mut batch, TraceImportRequest { traces: traces.into(), block_hash: hash.clone(), @@ -595,9 +627,58 @@ impl Client { warn!("Failed to prune ancient state data: {}", e); } + if let Some((header, epoch)) = entering_new_epoch { + self.generate_epoch_proof(&header, epoch, &chain); + } + route } + // generate an epoch transition proof at the given block, and write it into the given blockchain. + fn generate_epoch_proof(&self, header: &Header, epoch_number: u64, chain: &BlockChain) { + use std::cell::RefCell; + use std::collections::BTreeSet; + + let mut batch = DBTransaction::new(); + let hash = header.hash(); + debug!(target: "client", "Generating validation proof for block {}", hash); + + // proof is two-part. state items read in lexicographical order, + // and the secondary "proof" part. + let read_values = RefCell::new(BTreeSet::new()); + let block_id = BlockId::Hash(hash.clone()); + let proof = { + let call = |a, d| { + let tx = self.contract_call_tx(block_id, a, d); + let (result, items) = self.prove_transaction(tx, block_id) + .ok_or_else(|| format!("Unable to make call to generate epoch proof."))?; + + read_values.borrow_mut().extend(items); + Ok(result) + }; + + self.engine.epoch_proof(&header, &call) + }; + + // insert into database, using the generated proof. + match proof { + Ok(proof) => { + chain.insert_epoch_transition(&mut batch, epoch_number, EpochTransition { + block_hash: hash.clone(), + block_number: header.number(), + proof: proof, + state_proof: read_values.into_inner().into_iter().collect(), + }); + + self.db.read().write_buffered(batch); + } + Err(e) => { + warn!(target: "client", "Error generating epoch change proof for block {}: {}", hash, e); + warn!(target: "client", "Snapshots generated by this node will be incomplete."); + } + } + } + // prune ancient states until below the memory limit or only the minimum amount remain. fn prune_ancient(&self, mut state_db: StateDB, chain: &BlockChain) -> Result<(), ClientError> { let number = match state_db.journal_db().latest_era() { @@ -689,7 +770,7 @@ impl Client { let db = self.state_db.lock().boxed_clone(); // early exit for pruned blocks - if db.is_pruned() && self.chain.read().best_block_number() >= block_number + self.history { + if db.is_pruned() && self.pruning_info().earliest_state > block_number { return None; } @@ -790,7 +871,7 @@ impl Client { let best_block_number = self.chain_info().best_block_number; let block_number = self.block_number(at).ok_or(snapshot::Error::InvalidStartingBlock(at))?; - if best_block_number > self.history + block_number && db.is_pruned() { + if db.is_pruned() && self.pruning_info().earliest_state > block_number { return Err(snapshot::Error::OldBlockPrunedDB.into()); } @@ -814,7 +895,7 @@ impl Client { }, }; - snapshot::take_snapshot(&self.chain.read(), start_hash, db.as_hashdb(), writer, p)?; + snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hashdb(), writer, p)?; Ok(()) } @@ -865,6 +946,20 @@ impl Client { } } } + + // transaction for calling contracts from services like engine. + // from the null sender, with 50M gas. + fn contract_call_tx(&self, block_id: BlockId, address: Address, data: Bytes) -> SignedTransaction { + let from = Address::default(); + Transaction { + nonce: self.nonce(&from, block_id).unwrap_or_else(|| self.engine.account_start_nonce()), + action: Action::Call(address), + gas: U256::from(50_000_000), + gas_price: U256::default(), + value: U256::default(), + data: data, + }.fake_sign(from) + } } impl snapshot::DatabaseRestore for Client { @@ -960,7 +1055,7 @@ impl BlockChainClient for Client { return Err(err.into()) } } - let lower = t.gas_required(&self.engine.schedule(&env_info)).into(); + let lower = t.gas_required(&self.engine.schedule(env_info.number)).into(); if cond(lower)? { trace!(target: "estimate_gas", "estimate_gas succeeded with {}", lower); return Ok(lower) @@ -1259,7 +1354,7 @@ impl BlockChainClient for Client { .collect(); match (transaction, previous_receipts) { (Some(transaction), Some(previous_receipts)) => { - Some(transaction_receipt(transaction, previous_receipts)) + Some(transaction_receipt(self.engine(), transaction, previous_receipts)) }, _ => None, } @@ -1269,7 +1364,7 @@ impl BlockChainClient for Client { fn tree_route(&self, from: &H256, to: &H256) -> Option { let chain = self.chain.read(); match chain.is_known(from) && chain.is_known(to) { - true => Some(chain.tree_route(from.clone(), to.clone())), + true => chain.tree_route(from.clone(), to.clone()), false => None } } @@ -1455,15 +1550,7 @@ impl BlockChainClient for Client { } fn call_contract(&self, block_id: BlockId, address: Address, data: Bytes) -> Result { - let from = Address::default(); - let transaction = Transaction { - nonce: self.latest_nonce(&from), - action: Action::Call(address), - gas: U256::from(50_000_000), - gas_price: U256::default(), - value: U256::default(), - data: data, - }.fake_sign(from); + let transaction = self.contract_call_tx(block_id, address, data); self.call(&transaction, block_id, Default::default()) .map_err(|e| format!("{:?}", e)) @@ -1501,11 +1588,15 @@ impl BlockChainClient for Client { }) .and_then(|a| if a.is_zero() { None } else { Some(a) }) } + + fn eip86_transition(&self) -> u64 { + self.engine().params().eip86_transition + } } impl MiningBlockChainClient for Client { fn latest_schedule(&self) -> Schedule { - self.engine.schedule(&self.latest_env_info()) + self.engine.schedule(self.latest_env_info().number) } fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock { @@ -1615,7 +1706,7 @@ impl MayPanic for Client { } } -impl ::client::ProvingBlockChainClient for Client { +impl ProvingBlockChainClient for Client { fn prove_storage(&self, key1: H256, key2: H256, id: BlockId) -> Option<(Vec, H256)> { self.state_at(id) .and_then(move |state| state.prove_storage(key1, key2).ok()) @@ -1626,7 +1717,7 @@ impl ::client::ProvingBlockChainClient for Client { .and_then(move |state| state.prove_account(key1).ok()) } - fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option> { + fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec)> { let (state, mut env_info) = match (self.state_at(id), self.env_info(id)) { (Some(s), Some(e)) => (s, e), _ => return None, @@ -1641,8 +1732,9 @@ impl ::client::ProvingBlockChainClient for Client { let res = Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm).transact(&transaction, options); match res { - Err(ExecutionError::Internal(_)) => return None, - _ => return Some(state.drop().1.extract_proof()), + Err(ExecutionError::Internal(_)) => None, + Err(_) => Some((Vec::new(), state.drop().1.extract_proof())), + Ok(res) => Some((res.output, state.drop().1.extract_proof())), } } } @@ -1655,7 +1747,7 @@ impl Drop for Client { /// Returns `LocalizedReceipt` given `LocalizedTransaction` /// and a vector of receipts from given block up to transaction index. -fn transaction_receipt(mut tx: LocalizedTransaction, mut receipts: Vec) -> LocalizedReceipt { +fn transaction_receipt(engine: &Engine, mut tx: LocalizedTransaction, mut receipts: Vec) -> LocalizedReceipt { assert_eq!(receipts.len(), tx.transaction_index + 1, "All previous receipts are provided."); let sender = tx.sender(); @@ -1674,12 +1766,12 @@ fn transaction_receipt(mut tx: LocalizedTransaction, mut receipts: Vec) transaction_hash: transaction_hash, transaction_index: transaction_index, block_hash: block_hash, - block_number:block_number, + block_number: block_number, cumulative_gas_used: receipt.gas_used, gas_used: receipt.gas_used - prior_gas_used, contract_address: match tx.action { Action::Call(_) => None, - Action::Create => Some(contract_address(&sender, &tx.nonce)) + Action::Create => Some(contract_address(engine.create_address_scheme(block_number), &sender, &tx.nonce, &tx.data.sha3())) }, logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry { entry: log, @@ -1717,7 +1809,7 @@ mod tests { // Separate thread uncommited transaction let go = Arc::new(AtomicBool::new(false)); let go_thread = go.clone(); - let another_client = client.reference().clone(); + let another_client = client.clone(); thread::spawn(move || { let mut batch = DBTransaction::new(); another_client.chain.read().insert_block(&mut batch, &new_block, Vec::new()); @@ -1739,10 +1831,12 @@ mod tests { use receipt::{Receipt, LocalizedReceipt}; use transaction::{Transaction, LocalizedTransaction, Action}; use util::Hashable; + use tests::helpers::TestEngine; // given let key = KeyPair::from_secret_slice(&"test".sha3()).unwrap(); let secret = key.secret(); + let engine = TestEngine::new(0); let block_number = 1; let block_hash = 5.into(); @@ -1786,7 +1880,7 @@ mod tests { }]; // when - let receipt = transaction_receipt(transaction, receipts); + let receipt = transaction_receipt(&engine, transaction, receipts); // then assert_eq!(receipt, LocalizedReceipt { diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 16f38203f..bfb62d18c 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -353,7 +353,7 @@ pub fn get_temp_state_db() -> GuardedTempResult { impl MiningBlockChainClient for TestBlockChainClient { fn latest_schedule(&self) -> Schedule { - Schedule::new_post_eip150(24576, true, true, true) + Schedule::new_post_eip150(24576, true, true, true, true) } fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock { @@ -756,6 +756,8 @@ impl BlockChainClient for TestBlockChainClient { fn registrar_address(&self) -> Option
{ None } fn registry_address(&self, _name: String) -> Option
{ None } + + fn eip86_transition(&self) -> u64 { u64::max_value() } } impl ProvingBlockChainClient for TestBlockChainClient { @@ -767,7 +769,7 @@ impl ProvingBlockChainClient for TestBlockChainClient { None } - fn prove_transaction(&self, _: SignedTransaction, _: BlockId) -> Option> { + fn prove_transaction(&self, _: SignedTransaction, _: BlockId) -> Option<(Bytes, Vec)> { None } } diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index a612d8a77..d65642610 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -272,6 +272,9 @@ pub trait BlockChainClient : Sync + Send { /// Get the address of a particular blockchain service, if available. fn registry_address(&self, name: String) -> Option
; + + /// Get the EIP-86 transition block number. + fn eip86_transition(&self) -> u64; } impl IpcConfig for BlockChainClient { } @@ -324,5 +327,7 @@ pub trait ProvingBlockChainClient: BlockChainClient { fn prove_account(&self, key1: H256, id: BlockId) -> Option<(Vec, BasicAccount)>; /// Prove execution of a transaction at the given block. - fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option>; + /// Returns the output of the call and a vector of database items necessary + /// to reproduce it. + fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec)>; } diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index e6cbdb531..d2ae144d5 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -25,19 +25,18 @@ use rlp::{UntrustedRlp, encode}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; -use engines::{Engine, Seal, EngineError}; -use header::Header; +use engines::{Call, Engine, Seal, EngineError}; +use header::{Header, BlockNumber}; use error::{Error, TransactionError, BlockError}; use evm::Schedule; use ethjson; use io::{IoContext, IoHandler, TimerToken, IoService}; -use env_info::EnvInfo; use builtin::Builtin; use transaction::UnverifiedTransaction; use client::{Client, EngineClient}; use state::CleanupMode; use super::signer::EngineSigner; -use super::validator_set::{ValidatorSet, new_validator_set}; +use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; /// `AuthorityRound` params. #[derive(Debug, PartialEq)] @@ -75,27 +74,78 @@ impl From for AuthorityRoundParams { } } -/// Engine using `AuthorityRound` proof-of-work consensus algorithm, suitable for Ethereum -/// mainnet chains in the Olympic, Frontier and Homestead eras. +// Helper for managing the step. +#[derive(Debug)] +struct Step { + calibrate: bool, // whether calibration is enabled. + inner: AtomicUsize, + duration: Duration, +} + +impl Step { + fn load(&self) -> usize { self.inner.load(AtomicOrdering::SeqCst) } + fn duration_remaining(&self) -> Duration { + let now = unix_now(); + let step_end = self.duration * (self.load() as u32 + 1); + if step_end > now { + step_end - now + } else { + Duration::from_secs(0) + } + } + fn increment(&self) { + self.inner.fetch_add(1, AtomicOrdering::SeqCst); + } + fn calibrate(&self) { + if self.calibrate { + let new_step = unix_now().as_secs() / self.duration.as_secs(); + self.inner.store(new_step as usize, AtomicOrdering::SeqCst); + } + } + fn is_future(&self, given: usize) -> bool { + if given > self.load() + 1 { + // Make absolutely sure that the given step is correct. + self.calibrate(); + given > self.load() + 1 + } else { + false + } + } +} + +/// Engine using `AuthorityRound` proof-of-authority BFT consensus. pub struct AuthorityRound { params: CommonParams, gas_limit_bound_divisor: U256, block_reward: U256, registrar: Address, - step_duration: Duration, builtins: BTreeMap, transition_service: IoService<()>, - step: AtomicUsize, + step: Arc, proposed: AtomicBool, client: RwLock>>, signer: EngineSigner, validators: Box, - /// Is this Engine just for testing (prevents step calibration). - calibrate_step: bool, validate_score_transition: u64, eip155_transition: u64, } +// header-chain validator. +struct EpochVerifier { + epoch_number: u64, + step: Arc, + subchain_validators: SimpleList, +} + +impl super::EpochVerifier for EpochVerifier { + fn epoch_number(&self) -> u64 { self.epoch_number.clone() } + fn verify_light(&self, header: &Header) -> Result<(), Error> { + // always check the seal since it's fast. + // nothing heavier to do. + verify_external(header, &self.subchain_validators, &*self.step) + } +} + fn header_step(header: &Header) -> Result { UntrustedRlp::new(&header.seal().get(0).expect("was either checked with verify_block_basic or is genesis; has 2 fields; qed (Make sure the spec file has a correct genesis seal)")).as_val() } @@ -104,6 +154,26 @@ fn header_signature(header: &Header) -> Result { UntrustedRlp::new(&header.seal().get(1).expect("was checked with verify_block_basic; has 2 fields; qed")).as_val::().map(Into::into) } +fn verify_external(header: &Header, validators: &ValidatorSet, step: &Step) -> Result<(), Error> { + let header_step = header_step(header)?; + + // Give one step slack if step is lagging, double vote is still not possible. + if step.is_future(header_step) { + trace!(target: "engine", "verify_block_unordered: block from the future"); + validators.report_benign(header.author(), header.number()); + Err(BlockError::InvalidSeal)? + } else { + let proposer_signature = header_signature(header)?; + let correct_proposer = validators.get(header.parent_hash(), header_step); + if !verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())? { + trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", header_step); + Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))? + } else { + Ok(()) + } + } +} + trait AsMillis { fn as_millis(&self) -> u64; } @@ -125,15 +195,17 @@ impl AuthorityRound { gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, block_reward: our_params.block_reward, registrar: our_params.registrar, - step_duration: our_params.step_duration, builtins: builtins, transition_service: IoService::<()>::start()?, - step: AtomicUsize::new(initial_step), + step: Arc::new(Step { + inner: AtomicUsize::new(initial_step), + calibrate: our_params.start_step.is_none(), + duration: our_params.step_duration, + }), proposed: AtomicBool::new(false), client: RwLock::new(None), signer: Default::default(), validators: new_validator_set(our_params.validators), - calibrate_step: our_params.start_step.is_none(), validate_score_transition: our_params.validate_score_transition, eip155_transition: our_params.eip155_transition, }); @@ -145,22 +217,6 @@ impl AuthorityRound { Ok(engine) } - fn calibrate_step(&self) { - if self.calibrate_step { - self.step.store((unix_now().as_secs() / self.step_duration.as_secs()) as usize, AtomicOrdering::SeqCst); - } - } - - fn remaining_step_duration(&self) -> Duration { - let now = unix_now(); - let step_end = self.step_duration * (self.step.load(AtomicOrdering::SeqCst) as u32 + 1); - if step_end > now { - step_end - now - } else { - Duration::from_secs(0) - } - } - fn step_proposer(&self, bh: &H256, step: usize) -> Address { self.validators.get(bh, step) } @@ -168,16 +224,6 @@ impl AuthorityRound { fn is_step_proposer(&self, bh: &H256, step: usize, address: &Address) -> bool { self.step_proposer(bh, step) == *address } - - fn is_future_step(&self, step: usize) -> bool { - if step > self.step.load(AtomicOrdering::SeqCst) + 1 { - // Make absolutely sure that the step is correct. - self.calibrate_step(); - step > self.step.load(AtomicOrdering::SeqCst) + 1 - } else { - false - } - } } fn unix_now() -> Duration { @@ -193,7 +239,8 @@ const ENGINE_TIMEOUT_TOKEN: TimerToken = 23; impl IoHandler<()> for TransitionHandler { fn initialize(&self, io: &IoContext<()>) { if let Some(engine) = self.engine.upgrade() { - io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.remaining_step_duration().as_millis()) + let remaining = engine.step.duration_remaining(); + io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining.as_millis()) .unwrap_or_else(|e| warn!(target: "engine", "Failed to start consensus step timer: {}.", e)) } } @@ -202,7 +249,8 @@ impl IoHandler<()> for TransitionHandler { if timer == ENGINE_TIMEOUT_TOKEN { if let Some(engine) = self.engine.upgrade() { engine.step(); - io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.remaining_step_duration().as_millis()) + let remaining = engine.step.duration_remaining(); + io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining.as_millis()) .unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e)) } } @@ -224,7 +272,7 @@ impl Engine for AuthorityRound { fn builtins(&self) -> &BTreeMap { &self.builtins } fn step(&self) { - self.step.fetch_add(1, AtomicOrdering::SeqCst); + self.step.increment(); self.proposed.store(false, AtomicOrdering::SeqCst); if let Some(ref weak) = *self.client.read() { if let Some(c) = weak.upgrade() { @@ -241,13 +289,14 @@ impl Engine for AuthorityRound { ] } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { - Schedule::new_post_eip150(usize::max_value(), true, true, true) + fn schedule(&self, block_number: BlockNumber) -> Schedule { + let eip86 = block_number >= self.params.eip86_transition; + Schedule::new_post_eip150(usize::max_value(), true, true, true, eip86) } fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { // Chain scoring: total weight is sqrt(U256::max_value())*height - step - let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load(AtomicOrdering::SeqCst).into(); + let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load().into(); header.set_difficulty(new_difficulty); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); @@ -271,7 +320,7 @@ impl Engine for AuthorityRound { fn generate_seal(&self, block: &ExecutedBlock) -> Seal { if self.proposed.load(AtomicOrdering::SeqCst) { return Seal::None; } let header = block.header(); - let step = self.step.load(AtomicOrdering::SeqCst); + let step = self.step.load(); if self.is_step_proposer(header.parent_hash(), step, header.author()) { if let Ok(signature) = self.signer.sign(header.bare_hash()) { trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step); @@ -319,33 +368,20 @@ impl Engine for AuthorityRound { Ok(()) } - /// Do the validator and gas limit validation. + /// Do the step and gas limit validation. fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { let step = header_step(header)?; - // Give one step slack if step is lagging, double vote is still not possible. - if self.is_future_step(step) { - trace!(target: "engine", "verify_block_unordered: block from the future"); - self.validators.report_benign(header.author()); - Err(BlockError::InvalidSeal)? - } else { - let proposer_signature = header_signature(header)?; - let correct_proposer = self.step_proposer(header.parent_hash(), step); - if !verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())? { - trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", step); - Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))? - } - } // Do not calculate difficulty for genesis blocks. if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); } - // Check if parent is from a previous step. + // Ensure header is from the step after parent. let parent_step = header_step(parent)?; - if step == parent_step { - trace!(target: "engine", "Multiple blocks proposed for step {}.", step); - self.validators.report_malicious(header.author()); + if step <= parent_step { + trace!(target: "engine", "Multiple blocks proposed for step {}.", parent_step); + self.validators.report_malicious(header.author(), header.number(), Default::default()); Err(EngineError::DoubleVote(header.author().clone()))?; } @@ -358,6 +394,34 @@ impl Engine for AuthorityRound { Ok(()) } + // Check the validators. + fn verify_block_external(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { + verify_external(header, &*self.validators, &*self.step) + } + + // the proofs we need just allow us to get the full validator set. + fn epoch_proof(&self, header: &Header, caller: &Call) -> Result { + self.validators.epoch_proof(header, caller) + .map_err(|e| EngineError::InsufficientProof(e).into()) + } + + fn is_epoch_end(&self, header: &Header, block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> super::EpochChange + { + self.validators.is_epoch_end(header, block, receipts) + } + + fn epoch_verifier(&self, header: &Header, proof: &[u8]) -> Result, Error> { + // extract a simple list from the proof. + let (num, simple_list) = self.validators.epoch_set(header, proof)?; + + Ok(Box::new(EpochVerifier { + epoch_number: num, + step: self.step.clone(), + subchain_validators: simple_list, + })) + } + fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { t.check_low_s()?; @@ -387,7 +451,6 @@ impl Engine for AuthorityRound { #[cfg(test)] mod tests { use util::*; - use env_info::EnvInfo; use header::Header; use error::{Error, BlockError}; use ethkey::Secret; @@ -408,15 +471,7 @@ mod tests { #[test] fn can_return_schedule() { let engine = Spec::new_test_round().engine; - let schedule = engine.schedule(&EnvInfo { - number: 10000000, - author: 0.into(), - timestamp: 0, - difficulty: 0.into(), - last_hashes: Arc::new(vec![]), - gas_used: 0.into(), - gas_limit: 0.into(), - }); + let schedule = engine.schedule(10000000); assert!(schedule.stack_limit > 0); } @@ -441,7 +496,7 @@ mod tests { let mut header: Header = Header::default(); header.set_seal(vec![encode(&H520::default()).to_vec()]); - let verify_result = engine.verify_block_family(&header, &Default::default(), None); + let verify_result = engine.verify_block_external(&header, None); assert!(verify_result.is_err()); } @@ -454,8 +509,8 @@ mod tests { let spec = Spec::new_test_round(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); - let db1 = spec.ensure_db_good(get_temp_state_db().take(), &Default::default()).unwrap(); - let db2 = spec.ensure_db_good(get_temp_state_db().take(), &Default::default()).unwrap(); + let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); + let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b1 = b1.close_and_lock(); @@ -495,9 +550,11 @@ mod tests { // Two validators. // Spec starts with step 2. header.set_seal(vec![encode(&2usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); - assert!(engine.verify_block_family(&header, &parent_header, None).is_err()); + assert!(engine.verify_block_family(&header, &parent_header, None).is_ok()); + assert!(engine.verify_block_external(&header, None).is_err()); header.set_seal(vec![encode(&1usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); assert!(engine.verify_block_family(&header, &parent_header, None).is_ok()); + assert!(engine.verify_block_external(&header, None).is_ok()); } #[test] @@ -520,7 +577,33 @@ mod tests { // Spec starts with step 2. header.set_seal(vec![encode(&1usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); assert!(engine.verify_block_family(&header, &parent_header, None).is_ok()); + assert!(engine.verify_block_external(&header, None).is_ok()); header.set_seal(vec![encode(&5usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); + assert!(engine.verify_block_family(&header, &parent_header, None).is_ok()); + assert!(engine.verify_block_external(&header, None).is_err()); + } + + #[test] + fn rejects_step_backwards() { + let tap = AccountProvider::transient_provider(); + let addr = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "0").unwrap(); + + let mut parent_header: Header = Header::default(); + parent_header.set_seal(vec![encode(&4usize).to_vec()]); + parent_header.set_gas_limit(U256::from_str("222222").unwrap()); + let mut header: Header = Header::default(); + header.set_number(1); + header.set_gas_limit(U256::from_str("222222").unwrap()); + header.set_author(addr); + + let engine = Spec::new_test_round().engine; + + let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap(); + // Two validators. + // Spec starts with step 2. + header.set_seal(vec![encode(&5usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); + assert!(engine.verify_block_family(&header, &parent_header, None).is_ok()); + header.set_seal(vec![encode(&3usize).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); assert!(engine.verify_block_family(&header, &parent_header, None).is_err()); } } diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index e5a53d4e9..8de683e0a 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -23,15 +23,14 @@ use account_provider::AccountProvider; use block::*; use builtin::Builtin; use spec::CommonParams; -use engines::{Engine, Seal}; -use env_info::EnvInfo; +use engines::{Engine, EngineError, Seal, Call, EpochChange}; use error::{BlockError, Error}; use evm::Schedule; use ethjson; -use header::Header; +use header::{Header, BlockNumber}; use client::Client; use super::signer::EngineSigner; -use super::validator_set::{ValidatorSet, new_validator_set}; +use super::validator_set::{ValidatorSet, SimpleList, new_validator_set}; /// `BasicAuthority` params. #[derive(Debug, PartialEq)] @@ -51,8 +50,32 @@ impl From for BasicAuthorityParams { } } -/// Engine using `BasicAuthority` proof-of-work consensus algorithm, suitable for Ethereum -/// mainnet chains in the Olympic, Frontier and Homestead eras. +struct EpochVerifier { + epoch_number: u64, + list: SimpleList, +} + +impl super::EpochVerifier for EpochVerifier { + fn epoch_number(&self) -> u64 { self.epoch_number.clone() } + fn verify_light(&self, header: &Header) -> Result<(), Error> { + verify_external(header, &self.list) + } +} + +fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Error> { + use rlp::UntrustedRlp; + + // Check if the signature belongs to a validator, can depend on parent state. + let sig = UntrustedRlp::new(&header.seal()[0]).as_val::()?; + let signer = public_to_address(&recover(&sig.into(), &header.bare_hash())?); + + match validators.contains(header.parent_hash(), &signer) { + false => Err(BlockError::InvalidSeal.into()), + true => Ok(()) + } +} + +/// Engine using `BasicAuthority`, trivial proof-of-authority consensus. pub struct BasicAuthority { params: CommonParams, gas_limit_bound_divisor: U256, @@ -86,7 +109,7 @@ impl Engine for BasicAuthority { /// Additional engine-specific information for the user/developer concerning `header`. fn extra_info(&self, _header: &Header) -> BTreeMap { map!["signature".to_owned() => "TODO".to_owned()] } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { + fn schedule(&self, _block_number: BlockNumber) -> Schedule { Schedule::new_homestead() } @@ -138,14 +161,6 @@ impl Engine for BasicAuthority { } fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { - use rlp::UntrustedRlp; - // Check if the signature belongs to a validator, can depend on parent state. - let sig = UntrustedRlp::new(&header.seal()[0]).as_val::()?; - let signer = public_to_address(&recover(&sig.into(), &header.bare_hash())?); - if !self.validators.contains(header.parent_hash(), &signer) { - return Err(BlockError::InvalidSeal)?; - } - // Do not calculate difficulty for genesis blocks. if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); @@ -164,6 +179,32 @@ impl Engine for BasicAuthority { Ok(()) } + fn verify_block_external(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { + verify_external(header, &*self.validators) + } + + // the proofs we need just allow us to get the full validator set. + fn epoch_proof(&self, header: &Header, caller: &Call) -> Result { + self.validators.epoch_proof(header, caller) + .map_err(|e| EngineError::InsufficientProof(e).into()) + } + + fn is_epoch_end(&self, header: &Header, block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> EpochChange + { + self.validators.is_epoch_end(header, block, receipts) + } + + fn epoch_verifier(&self, header: &Header, proof: &[u8]) -> Result, Error> { + // extract a simple list from the proof. + let (num, simple_list) = self.validators.epoch_set(header, proof)?; + + Ok(Box::new(EpochVerifier { + epoch_number: num, + list: simple_list, + })) + } + fn register_client(&self, client: Weak) { self.validators.register_contract(client); } @@ -181,7 +222,6 @@ impl Engine for BasicAuthority { mod tests { use util::*; use block::*; - use env_info::EnvInfo; use error::{BlockError, Error}; use tests::helpers::*; use account_provider::AccountProvider; @@ -206,16 +246,7 @@ mod tests { #[test] fn can_return_schedule() { let engine = new_test_authority().engine; - let schedule = engine.schedule(&EnvInfo { - number: 10000000, - author: 0.into(), - timestamp: 0, - difficulty: 0.into(), - last_hashes: Arc::new(vec![]), - gas_used: 0.into(), - gas_limit: 0.into(), - }); - + let schedule = engine.schedule(10000000); assert!(schedule.stack_limit > 0); } @@ -252,8 +283,7 @@ mod tests { let engine = &*spec.engine; engine.set_signer(Arc::new(tap), addr, "".into()); let genesis_header = spec.genesis_header(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); diff --git a/ethcore/src/engines/epoch_verifier.rs b/ethcore/src/engines/epoch_verifier.rs new file mode 100644 index 000000000..0d9c87e53 --- /dev/null +++ b/ethcore/src/engines/epoch_verifier.rs @@ -0,0 +1,45 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +// Epoch verifiers. + +use error::Error; +use header::Header; + +/// Verifier for all blocks within an epoch with self-contained state. +/// +/// See docs on `Engine` relating to proving functions for more details. +pub trait EpochVerifier: Sync { + /// Get the epoch number. + fn epoch_number(&self) -> u64; + + /// Lightly verify the next block header. + /// This may not be a header belonging to a different epoch. + fn verify_light(&self, header: &Header) -> Result<(), Error>; + + /// Perform potentially heavier checks on the next block header. + fn verify_heavy(&self, header: &Header) -> Result<(), Error> { + self.verify_light(header) + } +} + +/// Special "no-op" verifier for stateless, epoch-less engines. +pub struct NoOp; + +impl EpochVerifier for NoOp { + fn epoch_number(&self) -> u64 { 0 } + fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } +} diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 45bede9f4..702afde4f 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -18,10 +18,10 @@ use std::collections::BTreeMap; use util::{Address, HashMap}; use builtin::Builtin; use engines::{Engine, Seal}; -use env_info::EnvInfo; use spec::CommonParams; use evm::Schedule; use block::ExecutedBlock; +use header::BlockNumber; /// An engine which does not provide any consensus mechanism, just seals blocks internally. pub struct InstantSeal { @@ -58,8 +58,9 @@ impl Engine for InstantSeal { &self.builtins } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { - Schedule::new_post_eip150(usize::max_value(), true, true, true) + fn schedule(&self, block_number: BlockNumber) -> Schedule { + let eip86 = block_number >= self.params.eip86_transition; + Schedule::new_post_eip150(usize::max_value(), true, true, true, eip86) } fn seals_internally(&self) -> Option { Some(true) } @@ -82,8 +83,7 @@ mod tests { fn instant_can_seal() { let spec = Spec::new_instant(); let engine = &*spec.engine; - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let genesis_header = spec.genesis_header(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap(); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 438b9bda0..7041048b8 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -16,35 +16,42 @@ //! Consensus engine specification and basic implementations. -mod transition; -mod vote_collector; -mod null_engine; -mod instant_seal; -mod basic_authority; mod authority_round; -mod tendermint; -mod validator_set; +mod basic_authority; +mod epoch_verifier; +mod instant_seal; +mod null_engine; mod signer; +mod tendermint; +mod transition; +mod validator_set; +mod vote_collector; -pub use self::null_engine::NullEngine; -pub use self::instant_seal::InstantSeal; -pub use self::basic_authority::BasicAuthority; pub use self::authority_round::AuthorityRound; +pub use self::basic_authority::BasicAuthority; +pub use self::epoch_verifier::EpochVerifier; +pub use self::instant_seal::InstantSeal; +pub use self::null_engine::NullEngine; pub use self::tendermint::Tendermint; use std::sync::Weak; -use util::*; -use ethkey::Signature; + use account_provider::AccountProvider; use block::ExecutedBlock; use builtin::Builtin; -use env_info::EnvInfo; -use error::{Error, TransactionError}; -use spec::CommonParams; -use evm::Schedule; -use header::Header; -use transaction::{UnverifiedTransaction, SignedTransaction}; use client::Client; +use env_info::EnvInfo; +use error::Error; +use evm::Schedule; +use header::{Header, BlockNumber}; +use receipt::Receipt; +use snapshot::SnapshotComponents; +use spec::CommonParams; +use transaction::{UnverifiedTransaction, SignedTransaction}; +use evm::CreateContractAddress; + +use ethkey::Signature; +use util::*; /// Voting errors. #[derive(Debug)] @@ -59,6 +66,8 @@ pub enum EngineError { UnexpectedMessage, /// Seal field has an unexpected size. BadSealFieldSize(OutOfBounds), + /// Validation proof insufficient. + InsufficientProof(String), } impl fmt::Display for EngineError { @@ -70,6 +79,7 @@ impl fmt::Display for EngineError { NotAuthorized(ref address) => format!("Signer {} is not authorized.", address), UnexpectedMessage => "This Engine should not be fed messages.".into(), BadSealFieldSize(ref oob) => format!("Seal field has an unexpected length: {}", oob), + InsufficientProof(ref msg) => format!("Insufficient validation proof: {}", msg), }; f.write_fmt(format_args!("Engine error ({})", msg)) @@ -87,6 +97,31 @@ pub enum Seal { None, } +/// Type alias for a function we can make calls through synchronously. +pub type Call<'a> = Fn(Address, Bytes) -> Result + 'a; + +/// Results of a query of whether an epoch change occurred at the given block. +#[derive(Debug, Clone, PartialEq)] +pub enum EpochChange { + /// Cannot determine until more data is passed. + Unsure(Unsure), + /// No epoch change. + No, + /// Validation proof required, and the new epoch number and expected proof. + Yes(u64, Bytes), +} + +/// More data required to determine if an epoch change occurred at a given block. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Unsure { + /// Needs the body. + NeedsBody, + /// Needs the receipts. + NeedsReceipts, + /// Needs both body and receipts. + NeedsBoth, +} + /// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. /// Provides hooks into each of the major parts of block import. pub trait Engine : Sync + Send { @@ -107,8 +142,8 @@ pub trait Engine : Sync + Send { /// Get the general parameters of the chain. fn params(&self) -> &CommonParams; - /// Get the EVM schedule for the given `env_info`. - fn schedule(&self, env_info: &EnvInfo) -> Schedule; + /// Get the EVM schedule for the given `block_number`. + fn schedule(&self, block_number: BlockNumber) -> Schedule; /// Builtin-contracts we would like to see in the chain. /// (In principle these are just hints for the engine since that has the last word on them.) @@ -152,18 +187,14 @@ pub trait Engine : Sync + Send { /// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import. fn verify_block_family(&self, _header: &Header, _parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) } + /// Phase 4 verification. Verify block header against potentially external data. + fn verify_block_external(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) } + /// Additional verification for transactions in blocks. // TODO: Add flags for which bits of the transaction to check. // TODO: consider including State in the params. fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> { - t.check_low_s()?; - - if let Some(n) = t.network_id() { - if n != self.params().chain_id { - return Err(TransactionError::InvalidNetworkId.into()); - } - } - + t.verify_basic(true, Some(self.params().network_id), true)?; Ok(()) } @@ -184,6 +215,40 @@ pub trait Engine : Sync + Send { self.verify_block_basic(header, None).and_then(|_| self.verify_block_unordered(header, None)) } + /// Generate epoch change proof. + /// + /// This will be used to generate proofs of epoch change as well as verify them. + /// Must be called on blocks that have already passed basic verification. + /// + /// Return the "epoch proof" generated. + /// This must be usable to generate a `EpochVerifier` for verifying all blocks + /// from the supplied header up to the next one where proof is required. + /// + /// For example, for PoA chains the proof will be a validator set, + /// and the corresponding `EpochVerifier` can be used to correctly validate + /// all blocks produced under that `ValidatorSet` + fn epoch_proof(&self, _header: &Header, _caller: &Call) + -> Result, Error> + { + Ok(Vec::new()) + } + + /// Whether an epoch change occurred at the given header. + /// Should not interact with state. + fn is_epoch_end(&self, _header: &Header, _block: Option<&[u8]>, _receipts: Option<&[Receipt]>) + -> EpochChange + { + EpochChange::No + } + + /// Create an epoch verifier from validation proof. + /// + /// The proof should be one generated by `epoch_proof`. + /// See docs of `epoch_proof` for description. + fn epoch_verifier(&self, _header: &Header, _proof: &[u8]) -> Result, Error> { + Ok(Box::new(self::epoch_verifier::NoOp)) + } + /// Populate a header's fields based on its parent's header. /// Usually implements the chain scoring rule based on weight. /// The gas floor target must not be lower than the engine's minimum gas limit. @@ -224,4 +289,15 @@ pub trait Engine : Sync + Send { /// Stops any services that the may hold the Engine and makes it safe to drop. fn stop(&self) {} + + /// Create a factory for building snapshot chunks and restoring from them. + /// Returning `None` indicates that this engine doesn't support snapshot creation. + fn snapshot_components(&self) -> Option> { + None + } + + /// Returns new contract address generation scheme at given block number. + fn create_address_scheme(&self, number: BlockNumber) -> CreateContractAddress { + if number >= self.params().eip86_transition { CreateContractAddress::FromCodeHash } else { CreateContractAddress::FromSenderAndNonce } + } } diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index 0611fc08e..3bdef480c 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -20,7 +20,7 @@ use builtin::Builtin; use engines::Engine; use spec::CommonParams; use evm::Schedule; -use env_info::EnvInfo; +use header::BlockNumber; /// An engine which does not provide any consensus mechanism and does not seal blocks. pub struct NullEngine { @@ -57,7 +57,11 @@ impl Engine for NullEngine { &self.builtins } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { + fn schedule(&self, _block_number: BlockNumber) -> Schedule { Schedule::new_homestead() } + + fn snapshot_components(&self) -> Option> { + Some(Box::new(::snapshot::PowSnapshot(10000))) + } } diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 8c8094117..137f70a7a 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -30,9 +30,8 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use util::*; use client::{Client, EngineClient}; use error::{Error, BlockError}; -use header::Header; +use header::{Header, BlockNumber}; use builtin::Builtin; -use env_info::EnvInfo; use rlp::UntrustedRlp; use ethkey::{recover, public_to_address, Signature}; use account_provider::AccountProvider; @@ -405,8 +404,9 @@ impl Engine for Tendermint { ] } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { - Schedule::new_post_eip150(usize::max_value(), true, true, true) + fn schedule(&self, block_number: BlockNumber) -> Schedule { + let eip86 = block_number >= self.params.eip86_transition; + Schedule::new_post_eip150(usize::max_value(), true, true, true, eip86) } fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { @@ -471,8 +471,8 @@ impl Engine for Tendermint { return Err(EngineError::NotAuthorized(sender).into()); } self.broadcast_message(rlp.as_raw().to_vec()); - if self.votes.vote(message.clone(), &sender).is_some() { - self.validators.report_malicious(&sender); + if let Some(double) = self.votes.vote(message.clone(), &sender) { + self.validators.report_malicious(&sender, message.vote_step.height as BlockNumber, ::rlp::encode(&double).to_vec()); return Err(EngineError::DoubleVote(sender).into()); } trace!(target: "engine", "Handling a valid {:?} from {}.", message, sender); @@ -560,7 +560,7 @@ impl Engine for Tendermint { let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas { - self.validators.report_malicious(header.author()); + self.validators.report_malicious(header.author(), header.number(), Default::default()); return Err(BlockError::InvalidGasLimit(OutOfBounds { min: Some(min_gas), max: Some(max_gas), found: header.gas_limit().clone() }).into()); } @@ -610,8 +610,9 @@ impl Engine for Tendermint { trace!(target: "engine", "Propose timeout."); if self.proposal.read().is_none() { // Report the proposer if no proposal was received. - let current_proposer = self.view_proposer(&*self.proposal_parent.read(), self.height.load(AtomicOrdering::SeqCst), self.view.load(AtomicOrdering::SeqCst)); - self.validators.report_benign(¤t_proposer); + let height = self.height.load(AtomicOrdering::SeqCst); + let current_proposer = self.view_proposer(&*self.proposal_parent.read(), height, self.view.load(AtomicOrdering::SeqCst)); + self.validators.report_benign(¤t_proposer, height as BlockNumber); } Step::Prevote }, @@ -658,7 +659,6 @@ mod tests { use block::*; use error::{Error, BlockError}; use header::Header; - use env_info::EnvInfo; use ethkey::Secret; use client::chain_notify::ChainNotify; use miner::MinerService; @@ -676,8 +676,8 @@ mod tests { } fn propose_default(spec: &Spec, proposer: Address) -> (ClosedBlock, Vec) { - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = get_temp_state_db(); + let db = spec.ensure_db_good(db, &Default::default()).unwrap(); let genesis_header = spec.genesis_header(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![]).unwrap(); @@ -740,15 +740,7 @@ mod tests { #[test] fn can_return_schedule() { let engine = Spec::new_test_tendermint().engine; - let schedule = engine.schedule(&EnvInfo { - number: 10000000, - author: 0.into(), - timestamp: 0, - difficulty: 0.into(), - last_hashes: Arc::new(vec![]), - gas_used: 0.into(), - gas_limit: 0.into(), - }); + let schedule = engine.schedule(10000000); assert!(schedule.stack_limit > 0); } diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index adfdd1225..dd4623023 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -19,119 +19,96 @@ use std::sync::Weak; use util::*; + +use futures::Future; +use native_contracts::ValidatorReport as Provider; + use client::{Client, BlockChainClient}; +use engines::Call; +use header::{Header, BlockNumber}; + use super::ValidatorSet; use super::safe_contract::ValidatorSafeContract; -/// The validator contract should have the following interface: -/// [{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}] +/// A validator contract with reporting. pub struct ValidatorContract { validators: ValidatorSafeContract, - provider: RwLock>, + provider: Provider, + client: RwLock>>, // TODO [keorn]: remove } impl ValidatorContract { pub fn new(contract_address: Address) -> Self { ValidatorContract { validators: ValidatorSafeContract::new(contract_address), - provider: RwLock::new(None), + provider: Provider::new(contract_address), + client: RwLock::new(None), } } } +impl ValidatorContract { + // could be `impl Trait`. + // note: dispatches transactions to network as well as execute. + // TODO [keorn]: Make more general. + fn transact(&self) -> Box { + let client = self.client.read().clone(); + Box::new(move |a, d| client.as_ref() + .and_then(Weak::upgrade) + .ok_or("No client!".into()) + .and_then(|c| c.transact_contract(a, d).map_err(|e| format!("Transaction import error: {}", e))) + .map(|_| Default::default())) + } +} + impl ValidatorSet for ValidatorContract { - fn contains(&self, bh: &H256, address: &Address) -> bool { - self.validators.contains(bh, address) + fn default_caller(&self, id: ::ids::BlockId) -> Box { + self.validators.default_caller(id) } - fn get(&self, bh: &H256, nonce: usize) -> Address { - self.validators.get(bh, nonce) + fn is_epoch_end(&self, header: &Header, block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> ::engines::EpochChange + { + self.validators.is_epoch_end(header, block, receipts) } - fn count(&self, bh: &H256) -> usize { - self.validators.count(bh) + fn epoch_proof(&self, header: &Header, caller: &Call) -> Result, String> { + self.validators.epoch_proof(header, caller) } - fn report_malicious(&self, address: &Address) { - if let Some(ref provider) = *self.provider.read() { - match provider.report_malicious(address) { - Ok(_) => warn!(target: "engine", "Reported malicious validator {}", address), - Err(s) => warn!(target: "engine", "Validator {} could not be reported {}", address, s), - } - } else { - warn!(target: "engine", "Malicious behaviour could not be reported: no provider contract.") + fn epoch_set(&self, header: &Header, proof: &[u8]) -> Result<(u64, super::SimpleList), ::error::Error> { + self.validators.epoch_set(header, proof) + } + + fn contains_with_caller(&self, bh: &H256, address: &Address, caller: &Call) -> bool { + self.validators.contains_with_caller(bh, address, caller) + } + + fn get_with_caller(&self, bh: &H256, nonce: usize, caller: &Call) -> Address { + self.validators.get_with_caller(bh, nonce, caller) + } + + fn count_with_caller(&self, bh: &H256, caller: &Call) -> usize { + self.validators.count_with_caller(bh, caller) + } + + fn report_malicious(&self, address: &Address, block: BlockNumber, proof: Bytes) { + match self.provider.report_malicious(&*self.transact(), *address, block.into(), proof).wait() { + Ok(_) => warn!(target: "engine", "Reported malicious validator {}", address), + Err(s) => warn!(target: "engine", "Validator {} could not be reported {}", address, s), } } - fn report_benign(&self, address: &Address) { - if let Some(ref provider) = *self.provider.read() { - match provider.report_benign(address) { - Ok(_) => warn!(target: "engine", "Reported benign validator misbehaviour {}", address), - Err(s) => warn!(target: "engine", "Validator {} could not be reported {}", address, s), - } - } else { - warn!(target: "engine", "Benign misbehaviour could not be reported: no provider contract.") + fn report_benign(&self, address: &Address, block: BlockNumber) { + match self.provider.report_benign(&*self.transact(), *address, block.into()).wait() { + Ok(_) => warn!(target: "engine", "Reported benign validator misbehaviour {}", address), + Err(s) => warn!(target: "engine", "Validator {} could not be reported {}", address, s), } } fn register_contract(&self, client: Weak) { self.validators.register_contract(client.clone()); - let transact = move |a, d| client - .upgrade() - .ok_or("No client!".into()) - .and_then(|c| c.transact_contract(a, d).map_err(|e| format!("Transaction import error: {}", e))) - .map(|_| Default::default()); - *self.provider.write() = Some(provider::Contract::new(self.validators.address, transact)); - } -} - -mod provider { - // Autogenerated from JSON contract definition using Rust contract convertor. - #![allow(unused_imports)] - use std::string::String; - use std::result::Result; - use std::fmt; - use {util, ethabi}; - use util::{Uint}; - - pub struct Contract { - contract: ethabi::Contract, - address: util::Address, - do_call: Box) -> Result, String> + Send + Sync + 'static>, - } - impl Contract { - pub fn new(address: util::Address, do_call: F) -> Self where F: Fn(util::Address, Vec) -> Result, String> + Send + Sync + 'static { - Contract { - contract: ethabi::Contract::new(ethabi::Interface::load(b"[{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"}],\"name\":\"reportMalicious\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"}],\"name\":\"reportBenign\",\"outputs\":[],\"payable\":false,\"type\":\"function\"}]").expect("JSON is autogenerated; qed")), - address: address, - do_call: Box::new(do_call), - } - } - fn as_string(e: T) -> String { format!("{:?}", e) } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"validator","type":"address"}],"name":"reportMalicious","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn report_malicious(&self, validator: &util::Address) -> Result<(), String> { - let call = self.contract.function("reportMalicious".into()).map_err(Self::as_string)?; - let data = call.encode_call( - vec![ethabi::Token::Address(validator.clone().0)] - ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"validator","type":"address"}],"name":"reportBenign","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn report_benign(&self, validator: &util::Address) -> Result<(), String> { - let call = self.contract.function("reportBenign".into()).map_err(Self::as_string)?; - let data = call.encode_call( - vec![ethabi::Token::Address(validator.clone().0)] - ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } + *self.client.write() = Some(client); } } @@ -180,7 +157,7 @@ mod tests { header.set_parent_hash(client.chain_info().best_block_hash); // `reportBenign` when the designated proposer releases block from the future (bad clock). - assert!(client.engine().verify_block_family(&header, &header, None).is_err()); + assert!(client.engine().verify_block_external(&header, None).is_err()); // Seal a block. client.engine().step(); assert_eq!(client.chain_info().best_block_number, 1); diff --git a/ethcore/src/engines/validator_set/mod.rs b/ethcore/src/engines/validator_set/mod.rs index cbbedfb33..f0765db5d 100644 --- a/ethcore/src/engines/validator_set/mod.rs +++ b/ethcore/src/engines/validator_set/mod.rs @@ -22,14 +22,19 @@ mod contract; mod multi; use std::sync::Weak; -use util::{Address, H256}; +use ids::BlockId; +use util::{Bytes, Address, H256}; use ethjson::spec::ValidatorSet as ValidatorSpec; use client::Client; -use self::simple_list::SimpleList; +use header::{Header, BlockNumber}; + +pub use self::simple_list::SimpleList; use self::contract::ValidatorContract; use self::safe_contract::ValidatorSafeContract; use self::multi::Multi; +use super::Call; + /// Creates a validator set from spec. pub fn new_validator_set(spec: ValidatorSpec) -> Box { match spec { @@ -42,17 +47,73 @@ pub fn new_validator_set(spec: ValidatorSpec) -> Box { } } +/// A validator set. pub trait ValidatorSet: Send + Sync { - /// Checks if a given address is a validator. - fn contains(&self, parent_block_hash: &H256, address: &Address) -> bool; + /// Get the default "Call" helper, for use in general operation. + // TODO [keorn]: this is a hack intended to migrate off of + // a strict dependency on state always being available. + fn default_caller(&self, block_id: BlockId) -> Box; + + /// Checks if a given address is a validator, + /// using underlying, default call mechanism. + fn contains(&self, parent: &H256, address: &Address) -> bool { + let default = self.default_caller(BlockId::Hash(*parent)); + self.contains_with_caller(parent, address, &*default) + } /// Draws an validator nonce modulo number of validators. - fn get(&self, parent_block_hash: &H256, nonce: usize) -> Address; + fn get(&self, parent: &H256, nonce: usize) -> Address { + let default = self.default_caller(BlockId::Hash(*parent)); + self.get_with_caller(parent, nonce, &*default) + } + /// Returns the current number of validators. - fn count(&self, parent_block_hash: &H256) -> usize; + fn count(&self, parent: &H256) -> usize { + let default = self.default_caller(BlockId::Hash(*parent)); + self.count_with_caller(parent, &*default) + } + + /// Whether this block is the last one in its epoch. + /// Usually indicates that the validator set changed at the given block. + /// + /// Should not inspect state! This is used in situations where + /// state is not generally available. + /// + /// Return `Yes` or `No` indicating whether it changed at the given header, + /// or `Unsure` indicating a need for more information. + /// + /// If block or receipts are provided, do not return `Unsure` indicating + /// need for them. + fn is_epoch_end(&self, header: &Header, block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> super::EpochChange; + + /// Generate epoch proof. + /// Must interact with state only through the given caller! + /// Otherwise, generated proofs may be wrong. + fn epoch_proof(&self, header: &Header, caller: &Call) -> Result, String>; + + /// Recover the validator set for all + /// + /// May fail if the given header doesn't kick off an epoch or + /// the proof is invalid. + /// + /// Returns the epoch number and proof. + fn epoch_set(&self, header: &Header, proof: &[u8]) -> Result<(u64, SimpleList), ::error::Error>; + + /// Checks if a given address is a validator, with the given function + /// for executing synchronous calls to contracts. + fn contains_with_caller(&self, parent_block_hash: &H256, address: &Address, caller: &Call) -> bool; + + /// Draws an validator nonce modulo number of validators. + /// + fn get_with_caller(&self, parent_block_hash: &H256, nonce: usize, caller: &Call) -> Address; + + /// Returns the current number of validators. + fn count_with_caller(&self, parent_block_hash: &H256, caller: &Call) -> usize; + /// Notifies about malicious behaviour. - fn report_malicious(&self, _validator: &Address) {} + fn report_malicious(&self, _validator: &Address, _block: BlockNumber, _proof: Bytes) {} /// Notifies about benign misbehaviour. - fn report_benign(&self, _validator: &Address) {} + fn report_benign(&self, _validator: &Address, _block: BlockNumber) {} /// Allows blockchain state access. fn register_contract(&self, _client: Weak) {} } diff --git a/ethcore/src/engines/validator_set/multi.rs b/ethcore/src/engines/validator_set/multi.rs index 5027f23cd..df3659ac3 100644 --- a/ethcore/src/engines/validator_set/multi.rs +++ b/ethcore/src/engines/validator_set/multi.rs @@ -18,13 +18,14 @@ use std::collections::BTreeMap; use std::sync::Weak; -use util::{H256, Address, RwLock}; +use engines::{Call, EpochChange}; +use util::{Bytes, H256, Address, RwLock}; use ids::BlockId; -use header::BlockNumber; +use header::{BlockNumber, Header}; use client::{Client, BlockChainClient}; use super::ValidatorSet; -type BlockNumberLookup = Box Result + Send + Sync + 'static>; +type BlockNumberLookup = Box Result + Send + Sync + 'static>; pub struct Multi { sets: BTreeMap>, @@ -40,64 +41,91 @@ impl Multi { } } - fn correct_set(&self, bh: &H256) -> Option<&Box> { - match self - .block_number - .read()(bh) - .map(|parent_block| self - .sets - .iter() - .rev() - .find(|&(block, _)| *block <= parent_block + 1) - .expect("constructor validation ensures that there is at least one validator set for block 0; - block 0 is less than any uint; - qed") - ) { - Ok((block, set)) => { - trace!(target: "engine", "Multi ValidatorSet retrieved for block {}.", block); - Some(set) - }, + fn correct_set(&self, id: BlockId) -> Option<&ValidatorSet> { + match self.block_number.read()(id).map(|parent_block| self.correct_set_by_number(parent_block)) { + Ok((_, set)) => Some(set), Err(e) => { debug!(target: "engine", "ValidatorSet could not be recovered: {}", e); None }, } } + + // get correct set by block number, along with block number at which + // this set was activated. + fn correct_set_by_number(&self, parent_block: BlockNumber) -> (BlockNumber, &ValidatorSet) { + let (block, set) = self.sets.iter() + .rev() + .find(|&(block, _)| *block <= parent_block + 1) + .expect("constructor validation ensures that there is at least one validator set for block 0; + block 0 is less than any uint; + qed"); + + trace!(target: "engine", "Multi ValidatorSet retrieved for block {}.", block); + (*block, &**set) + } } impl ValidatorSet for Multi { - fn contains(&self, bh: &H256, address: &Address) -> bool { - self.correct_set(bh).map_or(false, |set| set.contains(bh, address)) + fn default_caller(&self, block_id: BlockId) -> Box { + self.correct_set(block_id).map(|set| set.default_caller(block_id)) + .unwrap_or(Box::new(|_, _| Err("No validator set for given ID.".into()))) } - fn get(&self, bh: &H256, nonce: usize) -> Address { - self.correct_set(bh).map_or_else(Default::default, |set| set.get(bh, nonce)) - } + fn is_epoch_end(&self, header: &Header, block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> EpochChange + { + let (set_block, set) = self.correct_set_by_number(header.number()); - fn count(&self, bh: &H256) -> usize { - self.correct_set(bh).map_or_else(usize::max_value, |set| set.count(bh)) - } - - fn report_malicious(&self, validator: &Address) { - for set in self.sets.values() { - set.report_malicious(validator); + match set.is_epoch_end(header, block, receipts) { + EpochChange::Yes(num, proof) => EpochChange::Yes(set_block + num, proof), + other => other, } } - fn report_benign(&self, validator: &Address) { - for set in self.sets.values() { - set.report_benign(validator); - } + fn epoch_proof(&self, header: &Header, caller: &Call) -> Result, String> { + self.correct_set_by_number(header.number()).1.epoch_proof(header, caller) + } + + fn epoch_set(&self, header: &Header, proof: &[u8]) -> Result<(u64, super::SimpleList), ::error::Error> { + // "multi" epoch is the inner set's epoch plus the transition block to that set. + // ensures epoch increases monotonically. + let (set_block, set) = self.correct_set_by_number(header.number()); + let (inner_epoch, list) = set.epoch_set(header, proof)?; + Ok((set_block + inner_epoch, list)) + } + + fn contains_with_caller(&self, bh: &H256, address: &Address, caller: &Call) -> bool { + self.correct_set(BlockId::Hash(*bh)) + .map_or(false, |set| set.contains_with_caller(bh, address, caller)) + } + + fn get_with_caller(&self, bh: &H256, nonce: usize, caller: &Call) -> Address { + self.correct_set(BlockId::Hash(*bh)) + .map_or_else(Default::default, |set| set.get_with_caller(bh, nonce, caller)) + } + + fn count_with_caller(&self, bh: &H256, caller: &Call) -> usize { + self.correct_set(BlockId::Hash(*bh)) + .map_or_else(usize::max_value, |set| set.count_with_caller(bh, caller)) + } + + fn report_malicious(&self, validator: &Address, block: BlockNumber, proof: Bytes) { + self.correct_set_by_number(block).1.report_malicious(validator, block, proof); + } + + fn report_benign(&self, validator: &Address, block: BlockNumber) { + self.correct_set_by_number(block).1.report_benign(validator, block); } fn register_contract(&self, client: Weak) { for set in self.sets.values() { set.register_contract(client.clone()); } - *self.block_number.write() = Box::new(move |hash| client + *self.block_number.write() = Box::new(move |id| client .upgrade() .ok_or("No client!".into()) - .and_then(|c| c.block_number(BlockId::Hash(*hash)).ok_or("Unknown block".into()))); + .and_then(|c| c.block_number(id).ok_or("Unknown block".into()))); } } diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 0a0eaecfd..bfdab65b0 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -17,24 +17,45 @@ /// Validator set maintained in a contract, updated using `getValidators` method. use std::sync::Weak; -use ethabi; +use futures::Future; +use native_contracts::ValidatorSet as Provider; + use util::*; use util::cache::MemoryLruCache; -use types::ids::BlockId; + +use basic_types::LogBloom; use client::{Client, BlockChainClient}; +use engines::Call; +use header::Header; +use ids::BlockId; +use log_entry::LogEntry; + use super::ValidatorSet; use super::simple_list::SimpleList; const MEMOIZE_CAPACITY: usize = 500; -const CONTRACT_INTERFACE: &'static [u8] = b"[{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"type\":\"function\"}]"; -const GET_VALIDATORS: &'static str = "getValidators"; + +// TODO: ethabi should be able to generate this. +const EVENT_NAME: &'static [u8] = &*b"ValidatorsChanged(bytes32,uint256,address[])"; + +lazy_static! { + static ref EVENT_NAME_HASH: H256 = EVENT_NAME.sha3(); +} /// The validator contract should have the following interface: -/// [{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}] pub struct ValidatorSafeContract { pub address: Address, validators: RwLock>, - provider: RwLock>, + provider: Provider, + client: RwLock>>, // TODO [keorn]: remove +} + +fn encode_proof(nonce: U256, validators: &[Address]) -> Bytes { + use rlp::RlpStream; + + let mut stream = RlpStream::new_list(2); + stream.append(&nonce).append_list(validators); + stream.drain().to_vec() } impl ValidatorSafeContract { @@ -42,39 +63,168 @@ impl ValidatorSafeContract { ValidatorSafeContract { address: contract_address, validators: RwLock::new(MemoryLruCache::new(MEMOIZE_CAPACITY)), - provider: RwLock::new(None), + provider: Provider::new(contract_address), + client: RwLock::new(None), } } /// Queries the state and gets the set of validators. - fn get_list(&self, block_hash: H256) -> Option { - if let Some(ref provider) = *self.provider.read() { - match provider.get_validators(BlockId::Hash(block_hash)) { - Ok(new) => { - debug!(target: "engine", "Set of validators obtained: {:?}", new); - Some(SimpleList::new(new)) - }, - Err(s) => { - debug!(target: "engine", "Set of validators could not be updated: {}", s); - None - }, - } - } else { - warn!(target: "engine", "Set of validators could not be updated: no provider contract."); - None + fn get_list(&self, caller: &Call) -> Option { + match self.provider.get_validators(caller).wait() { + Ok(new) => { + debug!(target: "engine", "Set of validators obtained: {:?}", new); + Some(SimpleList::new(new)) + }, + Err(s) => { + debug!(target: "engine", "Set of validators could not be updated: {}", s); + None + }, } } + + /// Queries for the current validator set transition nonce. + fn get_nonce(&self, caller: &Call) -> Option<::util::U256> { + match self.provider.transition_nonce(caller).wait() { + Ok(nonce) => Some(nonce), + Err(s) => { + debug!(target: "engine", "Unable to fetch transition nonce: {}", s); + None + } + } + } + + // Whether the header matches the expected bloom. + // + // The expected log should have 3 topics: + // 1. ETHABI-encoded log name. + // 2. the block's parent hash. + // 3. the "nonce": n for the nth transition in history. + // + // We can only search for the first 2, since we don't have the third + // just yet. + // + // The parent hash is included to prevent + // malicious actors from brute forcing other logs that would + // produce the same bloom. + // + // The log data is an array of all new validator addresses. + fn expected_bloom(&self, header: &Header) -> LogBloom { + LogEntry { + address: self.address, + topics: vec![*EVENT_NAME_HASH, *header.parent_hash()], + data: Vec::new(), // irrelevant for bloom. + }.bloom() + } } impl ValidatorSet for ValidatorSafeContract { - fn contains(&self, block_hash: &H256, address: &Address) -> bool { + fn default_caller(&self, id: BlockId) -> Box { + let client = self.client.read().clone(); + Box::new(move |addr, data| client.as_ref() + .and_then(Weak::upgrade) + .ok_or("No client!".into()) + .and_then(|c| c.call_contract(id, addr, data))) + } + + fn is_epoch_end(&self, header: &Header, _block: Option<&[u8]>, receipts: Option<&[::receipt::Receipt]>) + -> ::engines::EpochChange + { + let bloom = self.expected_bloom(header); + let header_bloom = header.log_bloom(); + + if &bloom & header_bloom != bloom { return ::engines::EpochChange::No } + + match receipts { + None => ::engines::EpochChange::Unsure(::engines::Unsure::NeedsReceipts), + Some(receipts) => { + let check_log = |log: &LogEntry| { + log.address == self.address && + log.topics.len() == 3 && + log.topics[0] == *EVENT_NAME_HASH && + log.topics[1] == *header.parent_hash() + // don't have anything to compare nonce to yet. + }; + + let event = Provider::contract(&self.provider) + .event("ValidatorsChanged".into()) + .expect("Contract known ahead of time to have `ValidatorsChanged` event; qed"); + + // iterate in reverse because only the _last_ change in a given + // block actually has any effect. + // the contract should only increment the nonce once. + let mut decoded_events = receipts.iter() + .rev() + .filter(|r| &bloom & &r.log_bloom == bloom) + .flat_map(|r| r.logs.iter()) + .filter(move |l| check_log(l)) + .filter_map(|log| { + let topics = log.topics.iter().map(|x| x.0.clone()).collect(); + match event.decode_log(topics, log.data.clone()) { + Ok(decoded) => Some(decoded), + Err(_) => None, + } + }); + + match decoded_events.next() { + None => ::engines::EpochChange::No, + Some(matched_event) => { + // decode log manually until the native contract generator is + // good enough to do it for us. + let &(_, _, ref nonce_token) = &matched_event.params[1]; + let &(_, _, ref validators_token) = &matched_event.params[2]; + + let nonce: Option = nonce_token.clone().to_uint() + .map(H256).map(Into::into); + let validators = validators_token.clone().to_array() + .and_then(|a| a.into_iter() + .map(|x| x.to_address().map(H160)) + .collect::>>() + ); + + match (nonce, validators) { + (Some(nonce), Some(validators)) => { + let proof = encode_proof(nonce, &validators); + let new_epoch = nonce.low_u64(); + ::engines::EpochChange::Yes(new_epoch, proof) + } + _ => { + debug!(target: "engine", "Successfully decoded log turned out to be bad."); + ::engines::EpochChange::No + } + } + } + } + } + } + } + + // the proof we generate is an RLP list containing two parts. + // (nonce, validators) + fn epoch_proof(&self, _header: &Header, caller: &Call) -> Result, String> { + match (self.get_nonce(caller), self.get_list(caller)) { + (Some(nonce), Some(list)) => Ok(encode_proof(nonce, &list.into_inner())), + _ => Err("Caller insufficient to generate validator proof.".into()), + } + } + + fn epoch_set(&self, _header: &Header, proof: &[u8]) -> Result<(u64, SimpleList), ::error::Error> { + use rlp::UntrustedRlp; + + let rlp = UntrustedRlp::new(proof); + let nonce: u64 = rlp.val_at(0)?; + let validators: Vec
= rlp.list_at(1)?; + + Ok((nonce, SimpleList::new(validators))) + } + + fn contains_with_caller(&self, block_hash: &H256, address: &Address, caller: &Call) -> bool { let mut guard = self.validators.write(); let maybe_existing = guard .get_mut(block_hash) .map(|list| list.contains(block_hash, address)); maybe_existing .unwrap_or_else(|| self - .get_list(block_hash.clone()) + .get_list(caller) .map_or(false, |list| { let contains = list.contains(block_hash, address); guard.insert(block_hash.clone(), list); @@ -82,14 +232,14 @@ impl ValidatorSet for ValidatorSafeContract { })) } - fn get(&self, block_hash: &H256, nonce: usize) -> Address { + fn get_with_caller(&self, block_hash: &H256, nonce: usize, caller: &Call) -> Address { let mut guard = self.validators.write(); let maybe_existing = guard .get_mut(block_hash) .map(|list| list.get(block_hash, nonce)); maybe_existing .unwrap_or_else(|| self - .get_list(block_hash.clone()) + .get_list(caller) .map_or_else(Default::default, |list| { let address = list.get(block_hash, nonce); guard.insert(block_hash.clone(), list); @@ -97,14 +247,14 @@ impl ValidatorSet for ValidatorSafeContract { })) } - fn count(&self, block_hash: &H256) -> usize { + fn count_with_caller(&self, block_hash: &H256, caller: &Call) -> usize { let mut guard = self.validators.write(); let maybe_existing = guard .get_mut(block_hash) .map(|list| list.count(block_hash)); maybe_existing .unwrap_or_else(|| self - .get_list(block_hash.clone()) + .get_list(caller) .map_or_else(usize::max_value, |list| { let address = list.count(block_hash); guard.insert(block_hash.clone(), list); @@ -114,55 +264,7 @@ impl ValidatorSet for ValidatorSafeContract { fn register_contract(&self, client: Weak) { trace!(target: "engine", "Setting up contract caller."); - let contract = ethabi::Contract::new(ethabi::Interface::load(CONTRACT_INTERFACE).expect("JSON interface is valid; qed")); - let call = contract.function(GET_VALIDATORS.into()).expect("Method name is valid; qed"); - let data = call.encode_call(vec![]).expect("get_validators does not take any arguments; qed"); - let contract_address = self.address.clone(); - let do_call = move |id| client - .upgrade() - .ok_or("No client!".into()) - .and_then(|c| c.call_contract(id, contract_address.clone(), data.clone())) - .map(|raw_output| call.decode_output(raw_output).expect("ethabi is correct; qed")); - *self.provider.write() = Some(provider::Contract::new(do_call)); - } -} - -mod provider { - use std::string::String; - use std::result::Result; - use {util, ethabi}; - use types::ids::BlockId; - - pub struct Contract { - do_call: Box Result, String> + Send + Sync + 'static>, - } - - impl Contract { - pub fn new(do_call: F) -> Self where F: Fn(BlockId) -> Result, String> + Send + Sync + 'static { - Contract { - do_call: Box::new(do_call), - } - } - - /// Gets validators from contract with interface: `{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}` - pub fn get_validators(&self, id: BlockId) -> Result, String> { - Ok((self.do_call)(id)? - .into_iter() - .rev() - .collect::>() - .pop() - .expect("get_validators returns one argument; qed") - .to_array() - .and_then(|v| v - .into_iter() - .map(|a| a.to_address()) - .collect::>>()) - .expect("get_validators returns a list of addresses; qed") - .into_iter() - .map(util::Address::from) - .collect::>() - ) - } + *self.client.write() = Some(client); } } @@ -178,7 +280,7 @@ mod tests { use miner::MinerService; use tests::helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data}; use super::super::ValidatorSet; - use super::ValidatorSafeContract; + use super::{ValidatorSafeContract, EVENT_NAME_HASH}; #[test] fn fetches_validators() { @@ -196,6 +298,7 @@ mod tests { let s0 = Secret::from_slice(&"1".sha3()).unwrap(); let v0 = tap.insert_account(s0.clone(), "").unwrap(); let v1 = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "").unwrap(); + let network_id = Spec::new_validator_safe_contract().network_id(); let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap)); client.engine().register_client(Arc::downgrade(&client)); let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); @@ -209,7 +312,7 @@ mod tests { action: Action::Call(validator_contract), value: 0.into(), data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), - }.sign(&s0, None); + }.sign(&s0, Some(network_id)); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.update_sealing(); assert_eq!(client.chain_info().best_block_number, 1); @@ -221,7 +324,7 @@ mod tests { action: Action::Call(validator_contract), value: 0.into(), data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(), - }.sign(&s0, None); + }.sign(&s0, Some(network_id)); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.update_sealing(); // The transaction is not yet included so still unable to seal. @@ -240,7 +343,7 @@ mod tests { action: Action::Call(Address::default()), value: 0.into(), data: Vec::new(), - }.sign(&s0, None); + }.sign(&s0, Some(network_id)); client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap(); client.update_sealing(); // Able to seal again. @@ -255,4 +358,35 @@ mod tests { sync_client.flush_queue(); assert_eq!(sync_client.chain_info().best_block_number, 3); } + + #[test] + fn detects_bloom() { + use header::Header; + use engines::{EpochChange, Unsure}; + use log_entry::LogEntry; + + let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None); + let engine = client.engine().clone(); + let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); + + let last_hash = client.best_block_header().hash(); + let mut new_header = Header::default(); + new_header.set_parent_hash(last_hash); + + // first, try without the parent hash. + let mut event = LogEntry { + address: validator_contract, + topics: vec![*EVENT_NAME_HASH], + data: Vec::new(), + }; + + new_header.set_log_bloom(event.bloom()); + assert_eq!(engine.is_epoch_end(&new_header, None, None), EpochChange::No); + + // with the last hash, it should need the receipts. + event.topics.push(last_hash); + new_header.set_log_bloom(event.bloom()); + assert_eq!(engine.is_epoch_end(&new_header, None, None), + EpochChange::Unsure(Unsure::NeedsReceipts)); + } } diff --git a/ethcore/src/engines/validator_set/simple_list.rs b/ethcore/src/engines/validator_set/simple_list.rs index 2d7687979..15cf141f6 100644 --- a/ethcore/src/engines/validator_set/simple_list.rs +++ b/ethcore/src/engines/validator_set/simple_list.rs @@ -17,40 +17,67 @@ /// Preconfigured validator list. use util::{H256, Address, HeapSizeOf}; + +use engines::Call; +use header::Header; use super::ValidatorSet; -#[derive(Debug, PartialEq, Eq, Default)] +/// Validator set containing a known set of addresses. +#[derive(Clone, Debug, PartialEq, Eq, Default)] pub struct SimpleList { validators: Vec
, - validator_n: usize, } impl SimpleList { + /// Create a new `SimpleList`. pub fn new(validators: Vec
) -> Self { SimpleList { - validator_n: validators.len(), validators: validators, } } + + /// Convert into inner representation. + pub fn into_inner(self) -> Vec
{ + self.validators + } } impl HeapSizeOf for SimpleList { fn heap_size_of_children(&self) -> usize { - self.validators.heap_size_of_children() + self.validator_n.heap_size_of_children() + self.validators.heap_size_of_children() } } impl ValidatorSet for SimpleList { - fn contains(&self, _bh: &H256, address: &Address) -> bool { + fn default_caller(&self, _block_id: ::ids::BlockId) -> Box { + Box::new(|_, _| Err("Simple list doesn't require calls.".into())) + } + + fn is_epoch_end(&self, _header: &Header, _block: Option<&[u8]>, _receipts: Option<&[::receipt::Receipt]>) + -> ::engines::EpochChange + { + ::engines::EpochChange::No + } + + fn epoch_proof(&self, _header: &Header, _caller: &Call) -> Result, String> { + Ok(Vec::new()) + } + + fn epoch_set(&self, _header: &Header, _: &[u8]) -> Result<(u64, SimpleList), ::error::Error> { + Ok((0, self.clone())) + } + + fn contains_with_caller(&self, _bh: &H256, address: &Address, _: &Call) -> bool { self.validators.contains(address) } - fn get(&self, _bh: &H256, nonce: usize) -> Address { - self.validators.get(nonce % self.validator_n).expect("There are validator_n authorities; taking number modulo validator_n gives number in validator_n range; qed").clone() + fn get_with_caller(&self, _bh: &H256, nonce: usize, _: &Call) -> Address { + let validator_n = self.validators.len(); + self.validators.get(nonce % validator_n).expect("There are validator_n authorities; taking number modulo validator_n gives number in validator_n range; qed").clone() } - fn count(&self, _bh: &H256) -> usize { - self.validator_n + fn count_with_caller(&self, _bh: &H256, _: &Call) -> usize { + self.validators.len() } } diff --git a/ethcore/src/engines/vote_collector.rs b/ethcore/src/engines/vote_collector.rs index 482dd1d4b..d01d07f15 100644 --- a/ethcore/src/engines/vote_collector.rs +++ b/ethcore/src/engines/vote_collector.rs @@ -18,7 +18,7 @@ use std::fmt::Debug; use util::*; -use rlp::Encodable; +use rlp::{Encodable, RlpStream}; pub trait Message: Clone + PartialEq + Eq + Hash + Encodable + Debug { type Round: Clone + PartialEq + Eq + Hash + Default + Debug + Ord; @@ -40,25 +40,44 @@ pub struct VoteCollector { #[derive(Debug, Default)] struct StepCollector { - voted: HashSet
, + voted: HashMap, pub block_votes: HashMap, HashMap>, messages: HashSet, } +#[derive(Debug)] +pub struct DoubleVote<'a, M: Message> { + pub author: &'a Address, + vote_one: M, + vote_two: M, +} + +impl<'a, M: Message> Encodable for DoubleVote<'a, M> { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(2) + .append(&self.vote_one) + .append(&self.vote_two); + } +} + impl StepCollector { /// Returns Some(&Address) when validator is double voting. - fn insert<'a>(&mut self, message: M, address: &'a Address) -> Option<&'a Address> { + fn insert<'a>(&mut self, message: M, address: &'a Address) -> Option> { // Do nothing when message was seen. if self.messages.insert(message.clone()) { - if self.voted.insert(address.clone()) { + if let Some(previous) = self.voted.insert(address.clone(), message.clone()) { + // Bad validator sent a different message. + return Some(DoubleVote { + author: address, + vote_one: previous, + vote_two: message + }); + } else { self .block_votes .entry(message.block_hash()) .or_insert_with(HashMap::new) .insert(message.signature(), address.clone()); - } else { - // Bad validator sent a different message. - return Some(address); } } None @@ -101,7 +120,7 @@ impl Default for VoteCollector { impl VoteCollector { /// Insert vote if it is newer than the oldest one. - pub fn vote<'a>(&self, message: M, voter: &'a Address) -> Option<&'a Address> { + pub fn vote<'a>(&self, message: M, voter: &'a Address) -> Option> { self .votes .write() @@ -220,11 +239,11 @@ mod tests { } fn random_vote(collector: &VoteCollector, signature: H520, step: TestStep, block_hash: Option) -> bool { - full_vote(collector, signature, step, block_hash, &H160::random()).is_none() + full_vote(collector, signature, step, block_hash, &H160::random()) } - fn full_vote<'a>(collector: &VoteCollector, signature: H520, step: TestStep, block_hash: Option, address: &'a Address) -> Option<&'a Address> { - collector.vote(TestMessage { signature: signature, step: step, block_hash: block_hash }, address) + fn full_vote<'a>(collector: &VoteCollector, signature: H520, step: TestStep, block_hash: Option, address: &'a Address) -> bool { + collector.vote(TestMessage { signature: signature, step: step, block_hash: block_hash }, address).is_none() } #[test] @@ -319,9 +338,9 @@ mod tests { let collector = VoteCollector::default(); let round = 3; // Vote is inserted fine. - assert!(full_vote(&collector, H520::random(), round, Some("0".sha3()), &Address::default()).is_none()); + assert!(full_vote(&collector, H520::random(), round, Some("0".sha3()), &Address::default())); // Returns the double voting address. - full_vote(&collector, H520::random(), round, Some("1".sha3()), &Address::default()).unwrap(); + assert!(!full_vote(&collector, H520::random(), round, Some("1".sha3()), &Address::default())); assert_eq!(collector.count_round_votes(&round), 1); } } diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 5bc31c5d9..de53227de 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -19,8 +19,8 @@ use util::*; use block::*; use builtin::Builtin; use env_info::EnvInfo; -use error::{BlockError, TransactionError, Error}; -use header::Header; +use error::{BlockError, Error, TransactionError}; +use header::{Header, BlockNumber}; use state::CleanupMode; use spec::CommonParams; use transaction::UnverifiedTransaction; @@ -32,6 +32,10 @@ use rlp::{self, UntrustedRlp}; /// Parity tries to round block.gas_limit to multiple of this constant pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); +/// Number of blocks in an ethash snapshot. +// make dependent on difficulty incrment divisor? +const SNAPSHOT_BLOCKS: u64 = 30000; + /// Ethash params. #[derive(Debug, PartialEq)] pub struct EthashParams { @@ -139,17 +143,33 @@ pub struct Ethash { impl Ethash { /// Create a new instance of Ethash engine - pub fn new(params: CommonParams, ethash_params: EthashParams, builtins: BTreeMap) -> Self { - Ethash { + pub fn new(params: CommonParams, ethash_params: EthashParams, builtins: BTreeMap) -> Arc { + Arc::new(Ethash { params: params, ethash_params: ethash_params, builtins: builtins, pow: EthashManager::new(), - } + }) } } -impl Engine for Ethash { +// TODO [rphmeier] +// +// for now, this is different than Ethash's own epochs, and signal +// "consensus epochs". +// in this sense, `Ethash` is epochless: the same `EpochVerifier` can be used +// for any block in the chain. +// in the future, we might move the Ethash epoch +// caching onto this mechanism as well. +impl ::engines::EpochVerifier for Arc { + fn epoch_number(&self) -> u64 { 0 } + fn verify_light(&self, _header: &Header) -> Result<(), Error> { Ok(()) } + fn verify_heavy(&self, header: &Header) -> Result<(), Error> { + self.verify_block_unordered(header, None) + } +} + +impl Engine for Arc { fn name(&self) -> &str { "Ethash" } fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) } // Two fields - mix @@ -167,19 +187,20 @@ impl Engine for Ethash { map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())] } - fn schedule(&self, env_info: &EnvInfo) -> Schedule { + fn schedule(&self, block_number: BlockNumber) -> Schedule { trace!(target: "client", "Creating schedule. fCML={}, bGCML={}", self.ethash_params.homestead_transition, self.ethash_params.eip150_transition); - if env_info.number < self.ethash_params.homestead_transition { + if block_number < self.ethash_params.homestead_transition { Schedule::new_frontier() - } else if env_info.number < self.ethash_params.eip150_transition { + } else if block_number < self.ethash_params.eip150_transition { Schedule::new_homestead() } else { Schedule::new_post_eip150( self.ethash_params.max_code_size as usize, - env_info.number >= self.ethash_params.eip160_transition, - env_info.number >= self.ethash_params.eip161abc_transition, - env_info.number >= self.ethash_params.eip161d_transition + block_number >= self.ethash_params.eip160_transition, + block_number >= self.ethash_params.eip161abc_transition, + block_number >= self.ethash_params.eip161d_transition, + block_number >= self.params.eip86_transition ) } } @@ -369,22 +390,23 @@ impl Engine for Ethash { } fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> result::Result<(), Error> { - if header.number() >= self.ethash_params.homestead_transition { - t.check_low_s()?; - } - - if let Some(n) = t.network_id() { - if header.number() < self.ethash_params.eip155_transition || n != self.params().chain_id { - return Err(TransactionError::InvalidNetworkId.into()) - } - } - if header.number() >= self.ethash_params.min_gas_price_transition && t.gas_price < self.ethash_params.min_gas_price { return Err(TransactionError::InsufficientGasPrice { minimal: self.ethash_params.min_gas_price, got: t.gas_price }.into()); } + let check_low_s = header.number() >= self.ethash_params.homestead_transition; + let network_id = if header.number() >= self.ethash_params.eip155_transition { Some(self.params().chain_id) } else { None }; + t.verify_basic(check_low_s, network_id, false)?; Ok(()) } + + fn epoch_verifier(&self, _header: &Header, _proof: &[u8]) -> Result, Error> { + Ok(Box::new(self.clone())) + } + + fn snapshot_components(&self) -> Option> { + Some(Box::new(::snapshot::PowSnapshot(SNAPSHOT_BLOCKS))) + } } // Try to round gas_limit a bit so that: @@ -512,7 +534,6 @@ mod tests { use block::*; use tests::helpers::*; use engines::Engine; - use env_info::EnvInfo; use error::{BlockError, Error}; use header::Header; use super::super::{new_morden, new_homestead_test}; @@ -524,8 +545,7 @@ mod tests { let spec = new_morden(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close(); @@ -537,8 +557,7 @@ mod tests { let spec = new_morden(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle = Header::new(); @@ -561,28 +580,10 @@ mod tests { #[test] fn can_return_schedule() { let engine = new_morden().engine; - let schedule = engine.schedule(&EnvInfo { - number: 10000000, - author: 0.into(), - timestamp: 0, - difficulty: 0.into(), - last_hashes: Arc::new(vec![]), - gas_used: 0.into(), - gas_limit: 0.into(), - }); - + let schedule = engine.schedule(10000000); assert!(schedule.stack_limit > 0); - let schedule = engine.schedule(&EnvInfo { - number: 100, - author: 0.into(), - timestamp: 0, - difficulty: 0.into(), - last_hashes: Arc::new(vec![]), - gas_used: 0.into(), - gas_limit: 0.into(), - }); - + let schedule = engine.schedule(100); assert!(!schedule.have_delegate_call); } diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index ce8b84b31..af0582a36 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -94,8 +94,8 @@ mod tests { let spec = new_morden(); let engine = &spec.engine; let genesis_header = spec.genesis_header(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); + let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap(); assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()).unwrap(), 1u64.into()); assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()).unwrap(), 1u64.into()); diff --git a/ethcore/src/evm/ext.rs b/ethcore/src/evm/ext.rs index 352ffb7d9..e6b644874 100644 --- a/ethcore/src/evm/ext.rs +++ b/ethcore/src/evm/ext.rs @@ -41,6 +41,17 @@ pub enum MessageCallResult { Failed } +/// Specifies how an address is calculated for a new contract. +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum CreateContractAddress { + /// Address is calculated from nonce and sender. Pre EIP-86 (Metropolis) + FromSenderAndNonce, + /// Address is calculated from code hash. Default since EIP-86 + FromCodeHash, + /// Address is calculated from code hash and sender. Used by CREATE_P2SH instruction. + FromSenderAndCodeHash, +} + /// Externalities interface for EVMs // TODO: [rob] associated error type instead of `trie::Result`. Not all EVMs are trie powered. pub trait Ext { @@ -68,7 +79,7 @@ pub trait Ext { /// Creates new contract. /// /// Returns gas_left and contract address if contract creation was succesfull. - fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult; + fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult; /// Message call. /// diff --git a/ethcore/src/evm/instructions.rs b/ethcore/src/evm/instructions.rs index d93ddc437..eef1a9e3b 100644 --- a/ethcore/src/evm/instructions.rs +++ b/ethcore/src/evm/instructions.rs @@ -278,6 +278,7 @@ lazy_static! { arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::Zero); arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::Special); arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::Special); + arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 0, 3, 1, true, GasPriceTier::Special); arr }; } @@ -553,6 +554,8 @@ pub const CALLCODE: Instruction = 0xf2; pub const RETURN: Instruction = 0xf3; /// like CALLCODE but keeps caller's value and sender pub const DELEGATECALL: Instruction = 0xf4; +/// create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160 +pub const CREATE2: Instruction = 0xfb; /// halt execution and register account for later deletion pub const SUICIDE: Instruction = 0xff; diff --git a/ethcore/src/evm/interpreter/gasometer.rs b/ethcore/src/evm/interpreter/gasometer.rs index 9086200fa..246c93bad 100644 --- a/ethcore/src/evm/interpreter/gasometer.rs +++ b/ethcore/src/evm/interpreter/gasometer.rs @@ -223,7 +223,7 @@ impl Gasometer { Request::GasMemProvide(gas, mem, Some(requested)) }, - instructions::CREATE => { + instructions::CREATE | instructions::CREATE2 => { let gas = Gas::from(schedule.create_gas); let mem = mem_needed(stack.peek(1), stack.peek(2))?; diff --git a/ethcore/src/evm/interpreter/mod.rs b/ethcore/src/evm/interpreter/mod.rs index 79304793e..f08737d24 100644 --- a/ethcore/src/evm/interpreter/mod.rs +++ b/ethcore/src/evm/interpreter/mod.rs @@ -32,7 +32,7 @@ use std::marker::PhantomData; use action_params::{ActionParams, ActionValue}; use types::executed::CallType; use evm::instructions::{self, Instruction, InstructionInfo}; -use evm::{self, MessageCallResult, ContractCreateResult, GasLeft, CostType}; +use evm::{self, MessageCallResult, ContractCreateResult, GasLeft, CostType, CreateContractAddress}; use bit_set::BitSet; use util::*; @@ -182,7 +182,9 @@ impl Interpreter { fn verify_instruction(&self, ext: &evm::Ext, instruction: Instruction, info: &InstructionInfo, stack: &Stack) -> evm::Result<()> { let schedule = ext.schedule(); - if !schedule.have_delegate_call && instruction == instructions::DELEGATECALL { + if (instruction == instructions::DELEGATECALL && !schedule.have_delegate_call) || + (instruction == instructions::CREATE2 && !schedule.have_create2) { + return Err(evm::Error::BadInstruction { instruction: instruction }); @@ -266,10 +268,12 @@ impl Interpreter { instructions::JUMPDEST => { // ignore }, - instructions::CREATE => { + instructions::CREATE | instructions::CREATE2 => { let endowment = stack.pop_back(); let init_off = stack.pop_back(); let init_size = stack.pop_back(); + + let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash }; let create_gas = provided.expect("`provided` comes through Self::exec from `Gasometer::get_gas_cost_mem`; `gas_gas_mem_cost` guarantees `Some` when instruction is `CALL`/`CALLCODE`/`DELEGATECALL`/`CREATE`; this is `CREATE`; qed"); let contract_code = self.mem.read_slice(init_off, init_size); @@ -280,7 +284,7 @@ impl Interpreter { return Ok(InstructionResult::UnusedGas(create_gas)); } - let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code); + let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme); return match create_result { ContractCreateResult::Created(address, gas_left) => { stack.push(address_to_u256(address)); diff --git a/ethcore/src/evm/mod.rs b/ethcore/src/evm/mod.rs index cc707d6ef..7906b81ff 100644 --- a/ethcore/src/evm/mod.rs +++ b/ethcore/src/evm/mod.rs @@ -32,7 +32,7 @@ mod tests; mod benches; pub use self::evm::{Evm, Error, Finalize, GasLeft, Result, CostType}; -pub use self::ext::{Ext, ContractCreateResult, MessageCallResult}; +pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; pub use self::factory::{Factory, VMType}; pub use self::schedule::Schedule; pub use types::executed::CallType; diff --git a/ethcore/src/evm/schedule.rs b/ethcore/src/evm/schedule.rs index 70801983d..3e01f3925 100644 --- a/ethcore/src/evm/schedule.rs +++ b/ethcore/src/evm/schedule.rs @@ -22,6 +22,8 @@ pub struct Schedule { pub exceptional_failed_code_deposit: bool, /// Does it have a delegate cal pub have_delegate_call: bool, + /// Does it have a CREATE_P2SH instruction + pub have_create2: bool, /// VM stack limit pub stack_limit: usize, /// Max number of nested calls/creates @@ -113,10 +115,11 @@ impl Schedule { } /// Schedule for the post-EIP-150-era of the Ethereum main net. - pub fn new_post_eip150(max_code_size: usize, fix_exp: bool, no_empty: bool, kill_empty: bool) -> Schedule { + pub fn new_post_eip150(max_code_size: usize, fix_exp: bool, no_empty: bool, kill_empty: bool, have_metropolis_instructions: bool) -> Schedule { Schedule { exceptional_failed_code_deposit: true, have_delegate_call: true, + have_create2: have_metropolis_instructions, stack_limit: 1024, max_depth: 1024, tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], @@ -158,10 +161,16 @@ impl Schedule { } } + /// Schedule for the Metropolis of the Ethereum main net. + pub fn new_metropolis() -> Schedule { + Self::new_post_eip150(24576, true, true, true, true) + } + fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule { Schedule { exceptional_failed_code_deposit: efcd, have_delegate_call: hdc, + have_create2: false, stack_limit: 1024, max_depth: 1024, tier_step_gas: [0, 2, 3, 5, 8, 10, 20, 0], diff --git a/ethcore/src/evm/tests.rs b/ethcore/src/evm/tests.rs index 3002c170c..b5b2341aa 100644 --- a/ethcore/src/evm/tests.rs +++ b/ethcore/src/evm/tests.rs @@ -18,7 +18,7 @@ use util::*; use action_params::{ActionParams, ActionValue}; use env_info::EnvInfo; use types::executed::CallType; -use evm::{self, Ext, Schedule, Factory, GasLeft, VMType, ContractCreateResult, MessageCallResult}; +use evm::{self, Ext, Schedule, Factory, GasLeft, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress}; use std::fmt::Debug; pub struct FakeLogEntry { @@ -111,7 +111,7 @@ impl Ext for FakeExt { self.blockhashes.get(number).unwrap_or(&H256::new()).clone() } - fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { + fn create(&mut self, gas: &U256, value: &U256, code: &[u8], _address: CreateContractAddress) -> ContractCreateResult { self.calls.insert(FakeCall { call_type: FakeCallType::Create, gas: *gas, diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 4183a5005..1974a6c8d 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -22,7 +22,7 @@ use engines::Engine; use types::executed::CallType; use env_info::EnvInfo; use error::ExecutionError; -use evm::{self, Ext, Factory, Finalize}; +use evm::{self, Ext, Factory, Finalize, CreateContractAddress}; use externalities::*; use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer, VMTrace, VMTracer, ExecutiveVMTracer, NoopVMTracer}; use transaction::{Action, SignedTransaction}; @@ -34,14 +34,29 @@ pub use types::executed::{Executed, ExecutionResult}; /// Maybe something like here: `https://github.com/ethereum/libethereum/blob/4db169b8504f2b87f7d5a481819cfb959fc65f6c/libethereum/ExtVM.cpp` const STACK_SIZE_PER_DEPTH: usize = 24*1024; -/// Returns new address created from address and given nonce. -pub fn contract_address(address: &Address, nonce: &U256) -> Address { +/// Returns new address created from address, nonce, and code hash +pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address, nonce: &U256, code_hash: &H256) -> Address { use rlp::RlpStream; - let mut stream = RlpStream::new_list(2); - stream.append(address); - stream.append(nonce); - From::from(stream.out().sha3()) + match address_scheme { + CreateContractAddress::FromSenderAndNonce => { + let mut stream = RlpStream::new_list(2); + stream.append(sender); + stream.append(nonce); + From::from(stream.as_raw().sha3()) + }, + CreateContractAddress::FromCodeHash => { + let mut buffer = [0xffu8; 20 + 32]; + &mut buffer[20..].copy_from_slice(&code_hash[..]); + From::from((&buffer[..]).sha3()) + }, + CreateContractAddress::FromSenderAndCodeHash => { + let mut buffer = [0u8; 20 + 32]; + &mut buffer[..20].copy_from_slice(&sender[..]); + &mut buffer[20..].copy_from_slice(&code_hash[..]); + From::from((&buffer[..]).sha3()) + }, + } } /// Transaction execution options. @@ -125,7 +140,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { let sender = t.sender(); let nonce = self.state.nonce(&sender)?; - let schedule = self.engine.schedule(self.info); + let schedule = self.engine.schedule(self.info.number); let base_gas_required = U256::from(t.gas_required(&schedule)); if t.gas < base_gas_required { @@ -160,17 +175,20 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { } // NOTE: there can be no invalid transactions from this point. - self.state.inc_nonce(&sender)?; + if !t.is_unsigned() { + self.state.inc_nonce(&sender)?; + } self.state.sub_balance(&sender, &U256::from(gas_cost))?; let mut substate = Substate::new(); let (gas_left, output) = match t.action { Action::Create => { - let new_address = contract_address(&sender, &nonce); + let code_hash = t.data.sha3(); + let new_address = contract_address(self.engine.create_address_scheme(self.info.number), &sender, &nonce, &code_hash); let params = ActionParams { code_address: new_address.clone(), - code_hash: t.data.sha3(), + code_hash: code_hash, address: new_address, sender: sender.clone(), origin: sender.clone(), @@ -253,7 +271,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { // backup used in case of running out of gas self.state.checkpoint(); - let schedule = self.engine.schedule(self.info); + let schedule = self.engine.schedule(self.info.number); // at first, transfer value to destination if let ActionValue::Transfer(val) = params.value { @@ -365,8 +383,14 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { params: ActionParams, substate: &mut Substate, tracer: &mut T, - vm_tracer: &mut V + vm_tracer: &mut V, ) -> evm::Result where T: Tracer, V: VMTracer { + + let scheme = self.engine.create_address_scheme(self.info.number); + if scheme != CreateContractAddress::FromSenderAndNonce && self.state.exists_and_has_code(¶ms.address)? { + return Err(evm::Error::OutOfGas); + } + // backup used in case of running out of gas self.state.checkpoint(); @@ -374,7 +398,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { let mut unconfirmed_substate = Substate::new(); // create contract and transfer value to it if necessary - let schedule = self.engine.schedule(self.info); + let schedule = self.engine.schedule(self.info.number); let nonce_offset = if schedule.no_empty {1} else {0}.into(); let prev_bal = self.state.balance(¶ms.address)?; if let ActionValue::Transfer(val) = params.value { @@ -423,7 +447,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> { trace: Vec, vm_trace: Option ) -> ExecutionResult { - let schedule = self.engine.schedule(self.info); + let schedule = self.engine.schedule(self.info.number); // refunds from SSTORE nonzero -> zero let sstore_refunds = U256::from(schedule.sstore_refund_gas) * substate.sstore_clears_count; @@ -525,7 +549,7 @@ mod tests { use util::bytes::BytesRef; use action_params::{ActionParams, ActionValue}; use env_info::EnvInfo; - use evm::{Factory, VMType}; + use evm::{Factory, VMType, CreateContractAddress}; use error::ExecutionError; use state::{Substate, CleanupMode}; use tests::helpers::*; @@ -540,22 +564,21 @@ mod tests { fn test_contract_address() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let expected_address = Address::from_str("3f09c73a5ed19289fb9bdc72f1742566df146f56").unwrap(); - assert_eq!(expected_address, contract_address(&address, &U256::from(88))); + assert_eq!(expected_address, contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::from(88), &H256::default())); } // TODO: replace params with transactions! evm_test!{test_sender_balance: test_sender_balance_jit, test_sender_balance_int} fn test_sender_balance(factory: Factory) { let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let address = contract_address(&sender, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let mut params = ActionParams::default(); params.address = address.clone(); params.sender = sender.clone(); params.gas = U256::from(100_000); params.code = Some(Arc::new("3331600055".from_hex().unwrap())); params.value = ActionValue::Transfer(U256::from(0x7)); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(0x100u64), CleanupMode::NoEmpty).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(0); @@ -603,7 +626,7 @@ mod tests { let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(&sender, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); // TODO: add tests for 'callcreate' //let next_address = contract_address(&address, &U256::zero()); let mut params = ActionParams::default(); @@ -613,8 +636,7 @@ mod tests { params.gas = U256::from(100_000); params.code = Some(Arc::new(code)); params.value = ActionValue::Transfer(U256::from(100)); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(0); @@ -660,7 +682,7 @@ mod tests { let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(&sender, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); // TODO: add tests for 'callcreate' //let next_address = contract_address(&address, &U256::zero()); let mut params = ActionParams::default(); @@ -672,8 +694,7 @@ mod tests { params.code = Some(Arc::new(code)); params.value = ActionValue::Transfer(U256::from(100)); params.call_type = CallType::Call; - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(5); @@ -773,7 +794,7 @@ mod tests { let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(&sender, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); // TODO: add tests for 'callcreate' //let next_address = contract_address(&address, &U256::zero()); let mut params = ActionParams::default(); @@ -783,8 +804,7 @@ mod tests { params.gas = U256::from(100_000); params.code = Some(Arc::new(code)); params.value = ActionValue::Transfer(100.into()); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(5); @@ -861,7 +881,7 @@ mod tests { let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(&sender, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); // TODO: add tests for 'callcreate' //let next_address = contract_address(&address, &U256::zero()); let mut params = ActionParams::default(); @@ -871,8 +891,7 @@ mod tests { params.gas = U256::from(100_000); params.code = Some(Arc::new(code)); params.value = ActionValue::Transfer(U256::from(100)); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(0); @@ -914,8 +933,8 @@ mod tests { let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); - let address = contract_address(&sender, &U256::zero()); - let next_address = contract_address(&address, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); + let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &H256::default()); let mut params = ActionParams::default(); params.address = address.clone(); params.sender = sender.clone(); @@ -923,8 +942,7 @@ mod tests { params.gas = U256::from(100_000); params.code = Some(Arc::new(code)); params.value = ActionValue::Transfer(U256::from(100)); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(1024); @@ -981,8 +999,7 @@ mod tests { params.code = Some(Arc::new(code_a.clone())); params.value = ActionValue::Transfer(U256::from(100_000)); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.init_code(&address_a, code_a.clone()).unwrap(); state.init_code(&address_b, code_b.clone()).unwrap(); state.add_balance(&sender, &U256::from(100_000), CleanupMode::NoEmpty).unwrap(); @@ -1024,13 +1041,12 @@ mod tests { // 55 - sstore let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap(); - let address = contract_address(&sender, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let mut params = ActionParams::default(); params.address = address.clone(); params.gas = U256::from(100_000); params.code = Some(Arc::new(code.clone())); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.init_code(&address, code).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(0); @@ -1060,10 +1076,9 @@ mod tests { nonce: U256::zero() }.sign(keypair.secret(), None); let sender = t.sender(); - let contract = contract_address(&sender, &U256::zero()); + let contract = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap(); let mut info = EnvInfo::default(); info.gas_limit = U256::from(100_000); @@ -1100,8 +1115,7 @@ mod tests { }.sign(keypair.secret(), None); let sender = t.sender(); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); let mut info = EnvInfo::default(); info.gas_limit = U256::from(100_000); @@ -1133,8 +1147,7 @@ mod tests { }.sign(keypair.secret(), None); let sender = t.sender(); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(17), CleanupMode::NoEmpty).unwrap(); let mut info = EnvInfo::default(); info.gas_used = U256::from(20_000); @@ -1168,8 +1181,7 @@ mod tests { }.sign(keypair.secret(), None); let sender = t.sender(); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from(100_017), CleanupMode::NoEmpty).unwrap(); let mut info = EnvInfo::default(); info.gas_limit = U256::from(100_000); @@ -1193,7 +1205,7 @@ mod tests { let code = "6064640fffffffff20600055".from_hex().unwrap(); let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let address = contract_address(&sender, &U256::zero()); + let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); // TODO: add tests for 'callcreate' //let next_address = contract_address(&address, &U256::zero()); let mut params = ActionParams::default(); @@ -1203,8 +1215,7 @@ mod tests { params.gas = U256::from(0x0186a0); params.code = Some(Arc::new(code)); params.value = ActionValue::Transfer(U256::from_str("0de0b6b3a7640000").unwrap()); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap(), CleanupMode::NoEmpty).unwrap(); let info = EnvInfo::default(); let engine = TestEngine::new(0); diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 893ba03be..0b849033e 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -21,8 +21,9 @@ use state::{Backend as StateBackend, State, Substate}; use engines::Engine; use env_info::EnvInfo; use executive::*; -use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory}; +use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory, CreateContractAddress}; use types::executed::CallType; +use types::transaction::UNSIGNED_SENDER; use trace::{Tracer, VMTracer}; /// Policy for handling output data on `RETURN` opcode. @@ -97,7 +98,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B> depth: depth, origin_info: origin_info, substate: substate, - schedule: engine.schedule(env_info), + schedule: engine.schedule(env_info.number), output: output, tracer: tracer, vm_tracer: vm_tracer, @@ -147,10 +148,11 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> } } - fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { + fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address_scheme: CreateContractAddress) -> ContractCreateResult { // create new contract address + let code_hash = code.sha3(); let address = match self.state.nonce(&self.origin_info.address) { - Ok(nonce) => contract_address(&self.origin_info.address, &nonce), + Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code_hash), Err(e) => { debug!(target: "ext", "Database corruption encountered: {:?}", e); return ContractCreateResult::Failed @@ -167,14 +169,16 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B> gas_price: self.origin_info.gas_price, value: ActionValue::Transfer(*value), code: Some(Arc::new(code.to_vec())), - code_hash: code.sha3(), + code_hash: code_hash, data: None, call_type: CallType::None, }; - if let Err(e) = self.state.inc_nonce(&self.origin_info.address) { - debug!(target: "ext", "Database corruption encountered: {:?}", e); - return ContractCreateResult::Failed + if params.sender != UNSIGNED_SENDER { + if let Err(e) = self.state.inc_nonce(&self.origin_info.address) { + debug!(target: "ext", "Database corruption encountered: {:?}", e); + return ContractCreateResult::Failed + } } let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.vm_factory, self.depth); @@ -346,7 +350,6 @@ mod tests { use evm::Ext; use state::{State, Substate}; use tests::helpers::*; - use devtools::GuardedTempResult; use super::*; use trace::{NoopTracer, NoopVMTracer}; use types::executed::CallType; @@ -373,7 +376,7 @@ mod tests { } struct TestSetup { - state: GuardedTempResult>, + state: State<::state_db::StateDB>, engine: Arc, sub_state: Substate, env_info: EnvInfo @@ -399,7 +402,7 @@ mod tests { #[test] fn can_be_created() { let mut setup = TestSetup::new(); - let state = setup.state.reference_mut(); + let state = &mut setup.state; let mut tracer = NoopTracer; let mut vm_tracer = NoopVMTracer; @@ -412,7 +415,7 @@ mod tests { #[test] fn can_return_block_hash_no_env() { let mut setup = TestSetup::new(); - let state = setup.state.reference_mut(); + let state = &mut setup.state; let mut tracer = NoopTracer; let mut vm_tracer = NoopVMTracer; @@ -437,7 +440,7 @@ mod tests { last_hashes.push(test_hash.clone()); env_info.last_hashes = Arc::new(last_hashes); } - let state = setup.state.reference_mut(); + let state = &mut setup.state; let mut tracer = NoopTracer; let mut vm_tracer = NoopVMTracer; @@ -453,7 +456,7 @@ mod tests { #[should_panic] fn can_call_fail_empty() { let mut setup = TestSetup::new(); - let state = setup.state.reference_mut(); + let state = &mut setup.state; let mut tracer = NoopTracer; let mut vm_tracer = NoopVMTracer; @@ -481,7 +484,7 @@ mod tests { let log_topics = vec![H256::from("af0fa234a6af46afa23faf23bcbc1c1cb4bcb7bcbe7e7e7ee3ee2edddddddddd")]; let mut setup = TestSetup::new(); - let state = setup.state.reference_mut(); + let state = &mut setup.state; let mut tracer = NoopTracer; let mut vm_tracer = NoopVMTracer; @@ -499,7 +502,7 @@ mod tests { let refund_account = &Address::new(); let mut setup = TestSetup::new(); - let state = setup.state.reference_mut(); + let state = &mut setup.state; let mut tracer = NoopTracer; let mut vm_tracer = NoopVMTracer; diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 45a4f1d52..ccdd7d499 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -51,7 +51,7 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { ChainEra::_Eip161 => ethereum::new_eip161_test(), ChainEra::TransitionTest => ethereum::new_transition_test(), }; - spec.set_genesis_state(state); + spec.set_genesis_state(state).expect("Failed to overwrite genesis state"); spec.overwrite_genesis_params(genesis); assert!(spec.is_state_root_valid()); spec diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index 844fa08f5..c34ad69e3 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -21,7 +21,7 @@ use executive::*; use engines::Engine; use env_info::EnvInfo; use evm; -use evm::{Schedule, Ext, Factory, Finalize, VMType, ContractCreateResult, MessageCallResult}; +use evm::{Schedule, Ext, Factory, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress}; use externalities::*; use types::executed::CallType; use tests::helpers::*; @@ -56,7 +56,8 @@ struct TestExt<'a, T: 'a, V: 'a, B: 'a> { ext: Externalities<'a, T, V, B>, callcreates: Vec, - contract_address: Address + nonce: U256, + sender: Address, } impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B> @@ -76,9 +77,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B> vm_tracer: &'a mut V, ) -> trie::Result { Ok(TestExt { - contract_address: contract_address(&address, &state.nonce(&address)?), + nonce: state.nonce(&address)?, ext: Externalities::new(state, info, engine, vm_factory, depth, origin_info, substate, output, tracer, vm_tracer), - callcreates: vec![] + callcreates: vec![], + sender: address, }) } } @@ -114,14 +116,15 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B> self.ext.blockhash(number) } - fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { + fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult { self.callcreates.push(CallCreate { data: code.to_vec(), destination: None, gas_limit: *gas, value: *value }); - ContractCreateResult::Created(self.contract_address.clone(), *gas) + let contract_address = contract_address(address, &self.sender, &self.nonce, &code.sha3()); + ContractCreateResult::Created(contract_address, *gas) } fn call(&mut self, @@ -215,8 +218,7 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec { } let out_of_gas = vm.out_of_gas(); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.populate_from(From::from(vm.pre_state.clone())); let info = From::from(vm.env); let engine = TestEngine::new(1); diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index e4b9390db..c15847896 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -21,6 +21,8 @@ use ethereum; use spec::Spec; use ethjson; use ethjson::state::test::ForkSpec; +use types::transaction::SignedTransaction; +use env_info::EnvInfo; lazy_static! { pub static ref FRONTIER: Spec = ethereum::new_frontier_test(); @@ -37,7 +39,7 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec { for (name, test) in tests.into_iter() { { let multitransaction = test.transaction; - let env = test.env.into(); + let env: EnvInfo = test.env.into(); let pre: PodState = test.pre_state.into(); for (spec, states) in test.post_states { @@ -54,12 +56,15 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec { let info = format!(" - {} | {:?} ({}/{}) ...", name, spec, i + 1, total); let post_root: H256 = state.hash.into(); - let transaction = multitransaction.select(&state.indexes).into(); - - let mut state = get_temp_mem_state(); + let transaction: SignedTransaction = multitransaction.select(&state.indexes).into(); + let mut state = get_temp_state(); state.populate_from(pre.clone()); - state.commit().expect(&format!("State test {} failed due to internal error.", name)); - let _res = state.apply(&env, &**engine, &transaction, false); + if transaction.verify_basic(true, None, env.number >= engine.params().eip86_transition).is_ok() { + state.commit().expect(&format!("State test {} failed due to internal error.", name)); + let _res = state.apply(&env, &**engine, &transaction, false); + } else { + let _rest = state.commit(); + } if state.root() != &post_root { println!("{} !!! State mismatch (got: {}, expect: {}", info, state.root(), post_root); flushln!("{} fail", info); @@ -73,7 +78,9 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec { } - println!("!!! {:?} tests from failed.", failed.len()); + if !failed.is_empty() { + println!("!!! {:?} tests failed.", failed.len()); + } failed } diff --git a/ethcore/src/json_tests/transaction.rs b/ethcore/src/json_tests/transaction.rs index f400180ee..a3c3c889d 100644 --- a/ethcore/src/json_tests/transaction.rs +++ b/ethcore/src/json_tests/transaction.rs @@ -18,35 +18,37 @@ use super::test_common::*; use evm; use ethjson; use rlp::UntrustedRlp; -use transaction::{Action, UnverifiedTransaction}; -use ethstore::ethkey::public_to_address; +use transaction::{Action, UnverifiedTransaction, SignedTransaction}; fn do_json_test(json_data: &[u8]) -> Vec { let tests = ethjson::transaction::Test::load(json_data).unwrap(); let mut failed = Vec::new(); - let old_schedule = evm::Schedule::new_frontier(); - let new_schedule = evm::Schedule::new_homestead(); + let frontier_schedule = evm::Schedule::new_frontier(); + let homestead_schedule = evm::Schedule::new_homestead(); + let metropolis_schedule = evm::Schedule::new_metropolis(); for (name, test) in tests.into_iter() { let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); }; let number: Option = test.block_number.map(Into::into); let schedule = match number { - None => &old_schedule, - Some(x) if x < 1_150_000 => &old_schedule, - Some(_) => &new_schedule + None => &frontier_schedule, + Some(x) if x < 1_150_000 => &frontier_schedule, + Some(x) if x < 3_000_000 => &homestead_schedule, + Some(_) => &metropolis_schedule }; let allow_network_id_of_one = number.map_or(false, |n| n >= 2_675_000); + let allow_unsigned = number.map_or(false, |n| n >= 3_000_000); let rlp: Vec = test.rlp.into(); let res = UntrustedRlp::new(&rlp) .as_val() .map_err(From::from) - .and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one)); + .and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one, allow_unsigned)); fail_unless(test.transaction.is_none() == res.is_err(), "Validity different"); if let (Some(tx), Some(sender)) = (test.transaction, test.sender) { let t = res.unwrap(); - fail_unless(public_to_address(&t.recover_public().unwrap()) == sender.into(), "sender mismatch"); + fail_unless(SignedTransaction::new(t.clone()).unwrap().sender() == sender.into(), "sender mismatch"); let is_acceptable_network_id = match t.network_id() { None => true, Some(1) if allow_network_id_of_one => true, @@ -84,3 +86,7 @@ declare_test!{TransactionTests_Homestead_ttTransactionTestEip155VitaliksTests, " declare_test!{TransactionTests_EIP155_ttTransactionTest, "TransactionTests/EIP155/ttTransactionTest"} declare_test!{TransactionTests_EIP155_ttTransactionTestEip155VitaliksTests, "TransactionTests/EIP155/ttTransactionTestEip155VitaliksTests"} declare_test!{TransactionTests_EIP155_ttTransactionTestVRule, "TransactionTests/EIP155/ttTransactionTestVRule"} + +declare_test!{TransactionTests_Metropolis_ttMetropolisTest, "TransactionTests/Metropolis/ttMetropolisTest"} +declare_test!{TransactionTests_Metropolis_ttTransactionTest, "TransactionTests/Metropolis/ttTransactionTest"} +declare_test!{TransactionTests_Metropolis_ttTransactionTestZeroSig, "TransactionTests/Metropolis/ttTransactionTestZeroSig"} diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 8f9ed2e5f..980bdd25c 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -170,3 +170,4 @@ mod json_tests; pub use types::*; pub use executive::contract_address; +pub use evm::CreateContractAddress; diff --git a/ethcore/src/migrations/state/v7.rs b/ethcore/src/migrations/state/v7.rs index e9da80c31..174945c9b 100644 --- a/ethcore/src/migrations/state/v7.rs +++ b/ethcore/src/migrations/state/v7.rs @@ -238,7 +238,7 @@ impl Migration for OverlayRecentV7 { } let mut count = 0; - for (key, value) in source.iter(None) { + for (key, value) in source.iter(None).into_iter().flat_map(|inner| inner) { count += 1; if count == 100_000 { count = 0; diff --git a/ethcore/src/migrations/v10.rs b/ethcore/src/migrations/v10.rs index 45fc457bd..15abf4790 100644 --- a/ethcore/src/migrations/v10.rs +++ b/ethcore/src/migrations/v10.rs @@ -102,7 +102,7 @@ impl Migration for ToV10 { fn migrate(&mut self, source: Arc, config: &Config, dest: &mut Database, col: Option) -> Result<(), Error> { let mut batch = Batch::new(config, col); - for (key, value) in source.iter(col) { + for (key, value) in source.iter(col).into_iter().flat_map(|inner| inner) { self.progress.tick(); batch.insert(key.to_vec(), value.to_vec(), dest)?; } diff --git a/ethcore/src/migrations/v9.rs b/ethcore/src/migrations/v9.rs index 9a6eb5088..4ca6e3a82 100644 --- a/ethcore/src/migrations/v9.rs +++ b/ethcore/src/migrations/v9.rs @@ -59,7 +59,7 @@ impl Migration for ToV9 { fn migrate(&mut self, source: Arc, config: &Config, dest: &mut Database, col: Option) -> Result<(), Error> { let mut batch = Batch::new(config, self.column); - for (key, value) in source.iter(col) { + for (key, value) in source.iter(col).into_iter().flat_map(|inner| inner) { self.progress.tick(); match self.extract { Extract::Header => { diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index ac1695b52..38e97f683 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -163,7 +163,7 @@ impl GasPriceCalibrator { let wei_per_usd: f32 = 1.0e18 / usd_per_eth; let gas_per_tx: f32 = 21000.0; let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx; - info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas))); + info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${:.2}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas))); set_price(U256::from(wei_per_gas as u64)); }); @@ -1048,7 +1048,7 @@ impl MinerService for Miner { Action::Call(_) => None, Action::Create => { let sender = tx.sender(); - Some(contract_address(&sender, &tx.nonce)) + Some(contract_address(self.engine.create_address_scheme(pending.header().number()), &sender, &tx.nonce, &tx.data.sha3())) } }, logs: receipt.logs.clone(), @@ -1327,6 +1327,10 @@ mod tests { } fn transaction() -> SignedTransaction { + transaction_with_network_id(2) + } + + fn transaction_with_network_id(id: u64) -> SignedTransaction { let keypair = Random.generate().unwrap(); Transaction { action: Action::Create, @@ -1335,7 +1339,7 @@ mod tests { gas: U256::from(100_000), gas_price: U256::zero(), nonce: U256::zero(), - }.sign(keypair.secret(), None) + }.sign(keypair.secret(), Some(id)) } #[test] @@ -1411,21 +1415,21 @@ mod tests { #[test] fn internal_seals_without_work() { - let miner = Miner::with_spec(&Spec::new_instant()); + let spec = Spec::new_instant(); + let miner = Miner::with_spec(&spec); - let c = generate_dummy_client(2); - let client = c.reference().as_ref(); + let client = generate_dummy_client(2); - assert_eq!(miner.import_external_transactions(client, vec![transaction().into()]).pop().unwrap().unwrap(), TransactionImportResult::Current); + assert_eq!(miner.import_external_transactions(&*client, vec![transaction_with_network_id(spec.network_id()).into()]).pop().unwrap().unwrap(), TransactionImportResult::Current); - miner.update_sealing(client); + miner.update_sealing(&*client); client.flush_queue(); assert!(miner.pending_block().is_none()); assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber); - assert_eq!(miner.import_own_transaction(client, PendingTransaction::new(transaction().into(), None)).unwrap(), TransactionImportResult::Current); + assert_eq!(miner.import_own_transaction(&*client, PendingTransaction::new(transaction_with_network_id(spec.network_id()).into(), None)).unwrap(), TransactionImportResult::Current); - miner.update_sealing(client); + miner.update_sealing(&*client); client.flush_queue(); assert!(miner.pending_block().is_none()); assert_eq!(client.chain_info().best_block_number, 4 as BlockNumber); diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index 4b5dc8921..984f37bd8 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -16,7 +16,6 @@ use util::*; use state::Account; -use account_db::AccountDBMut; use ethjson; use types::account_diff::*; use rlp::{self, RlpStream}; @@ -64,7 +63,7 @@ impl PodAccount { } /// Place additional data into given hash DB. - pub fn insert_additional(&self, db: &mut AccountDBMut, factory: &TrieFactory) { + pub fn insert_additional(&self, db: &mut HashDB, factory: &TrieFactory) { match self.code { Some(ref c) if !c.is_empty() => { db.insert(c); } _ => {} diff --git a/ethcore/src/snapshot/consensus/mod.rs b/ethcore/src/snapshot/consensus/mod.rs new file mode 100644 index 000000000..4d853ca27 --- /dev/null +++ b/ethcore/src/snapshot/consensus/mod.rs @@ -0,0 +1,352 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Secondary chunk creation and restoration, implementations for different consensus +//! engines. + +use std::collections::VecDeque; +use std::io; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + +use blockchain::{BlockChain, BlockProvider}; +use engines::Engine; +use snapshot::{Error, ManifestData}; +use snapshot::block::AbridgedBlock; + +use util::{Bytes, H256}; +use util::kvdb::KeyValueDB; +use rand::OsRng; +use rlp::{RlpStream, UntrustedRlp}; + + +/// A sink for produced chunks. +pub type ChunkSink<'a> = FnMut(&[u8]) -> io::Result<()> + 'a; + +/// Components necessary for snapshot creation and restoration. +pub trait SnapshotComponents: Send { + /// Create secondary snapshot chunks; these corroborate the state data + /// in the state chunks. + /// + /// Chunks shouldn't exceed the given preferred size, and should be fed + /// uncompressed into the sink. + /// + /// This will vary by consensus engine, so it's exposed as a trait. + fn chunk_all( + &mut self, + chain: &BlockChain, + block_at: H256, + chunk_sink: &mut ChunkSink, + preferred_size: usize, + ) -> Result<(), Error>; + + /// Create a rebuilder, which will have chunks fed into it in aribtrary + /// order and then be finalized. + /// + /// The manifest, a database, and fresh `BlockChain` are supplied. + // TODO: supply anything for state? + fn rebuilder( + &self, + chain: BlockChain, + db: Arc, + manifest: &ManifestData, + ) -> Result, ::error::Error>; +} + + +/// Restore from secondary snapshot chunks. +pub trait Rebuilder: Send { + /// Feed a chunk, potentially out of order. + /// + /// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with + /// `Error::RestorationAborted`. + fn feed( + &mut self, + chunk: &[u8], + engine: &Engine, + abort_flag: &AtomicBool, + ) -> Result<(), ::error::Error>; + + /// Finalize the restoration. Will be done after all chunks have been + /// fed successfully. + /// This will apply the necessary "glue" between chunks. + fn finalize(&mut self) -> Result<(), Error>; +} + +/// Snapshot creation and restoration for PoW chains. +/// This includes blocks from the head of the chain as a +/// loose assurance that the chain is valid. +/// +/// The field is the number of blocks from the head of the chain +/// to include in the snapshot. +#[derive(Clone, Copy, PartialEq)] +pub struct PowSnapshot(pub u64); + +impl SnapshotComponents for PowSnapshot { + fn chunk_all( + &mut self, + chain: &BlockChain, + block_at: H256, + chunk_sink: &mut ChunkSink, + preferred_size: usize, + ) -> Result<(), Error> { + PowWorker { + chain: chain, + rlps: VecDeque::new(), + current_hash: block_at, + writer: chunk_sink, + preferred_size: preferred_size, + }.chunk_all(self.0) + } + + fn rebuilder( + &self, + chain: BlockChain, + db: Arc, + manifest: &ManifestData, + ) -> Result, ::error::Error> { + PowRebuilder::new(chain, db, manifest, self.0).map(|r| Box::new(r) as Box<_>) + } +} + +/// Used to build block chunks. +struct PowWorker<'a> { + chain: &'a BlockChain, + // block, receipt rlp pairs. + rlps: VecDeque, + current_hash: H256, + writer: &'a mut ChunkSink<'a>, + preferred_size: usize, +} + +impl<'a> PowWorker<'a> { + // Repeatedly fill the buffers and writes out chunks, moving backwards from starting block hash. + // Loops until we reach the first desired block, and writes out the remainder. + fn chunk_all(&mut self, snapshot_blocks: u64) -> Result<(), Error> { + let mut loaded_size = 0; + let mut last = self.current_hash; + + let genesis_hash = self.chain.genesis_hash(); + + for _ in 0..snapshot_blocks { + if self.current_hash == genesis_hash { break } + + let (block, receipts) = self.chain.block(&self.current_hash) + .and_then(|b| self.chain.block_receipts(&self.current_hash).map(|r| (b, r))) + .ok_or(Error::BlockNotFound(self.current_hash))?; + + let abridged_rlp = AbridgedBlock::from_block_view(&block.view()).into_inner(); + + let pair = { + let mut pair_stream = RlpStream::new_list(2); + pair_stream.append_raw(&abridged_rlp, 1).append(&receipts); + pair_stream.out() + }; + + let new_loaded_size = loaded_size + pair.len(); + + // cut off the chunk if too large. + + if new_loaded_size > self.preferred_size && !self.rlps.is_empty() { + self.write_chunk(last)?; + loaded_size = pair.len(); + } else { + loaded_size = new_loaded_size; + } + + self.rlps.push_front(pair); + + last = self.current_hash; + self.current_hash = block.header_view().parent_hash(); + } + + if loaded_size != 0 { + self.write_chunk(last)?; + } + + Ok(()) + } + + // write out the data in the buffers to a chunk on disk + // + // we preface each chunk with the parent of the first block's details, + // obtained from the details of the last block written. + fn write_chunk(&mut self, last: H256) -> Result<(), Error> { + trace!(target: "snapshot", "prepared block chunk with {} blocks", self.rlps.len()); + + let (last_header, last_details) = self.chain.block_header(&last) + .and_then(|n| self.chain.block_details(&last).map(|d| (n, d))) + .ok_or(Error::BlockNotFound(last))?; + + let parent_number = last_header.number() - 1; + let parent_hash = last_header.parent_hash(); + let parent_total_difficulty = last_details.total_difficulty - *last_header.difficulty(); + + trace!(target: "snapshot", "parent last written block: {}", parent_hash); + + let num_entries = self.rlps.len(); + let mut rlp_stream = RlpStream::new_list(3 + num_entries); + rlp_stream.append(&parent_number).append(parent_hash).append(&parent_total_difficulty); + + for pair in self.rlps.drain(..) { + rlp_stream.append_raw(&pair, 1); + } + + let raw_data = rlp_stream.out(); + + (self.writer)(&raw_data)?; + + Ok(()) + } +} + +/// Rebuilder for proof-of-work chains. +/// Does basic verification for all blocks, but `PoW` verification for some. +/// Blocks must be fed in-order. +/// +/// The first block in every chunk is disconnected from the last block in the +/// chunk before it, as chunks may be submitted out-of-order. +/// +/// After all chunks have been submitted, we "glue" the chunks together. +pub struct PowRebuilder { + chain: BlockChain, + db: Arc, + rng: OsRng, + disconnected: Vec<(u64, H256)>, + best_number: u64, + best_hash: H256, + best_root: H256, + fed_blocks: u64, + snapshot_blocks: u64, +} + +impl PowRebuilder { + /// Create a new PowRebuilder. + fn new(chain: BlockChain, db: Arc, manifest: &ManifestData, snapshot_blocks: u64) -> Result { + Ok(PowRebuilder { + chain: chain, + db: db, + rng: OsRng::new()?, + disconnected: Vec::new(), + best_number: manifest.block_number, + best_hash: manifest.block_hash, + best_root: manifest.state_root, + fed_blocks: 0, + snapshot_blocks: snapshot_blocks, + }) + } +} + +impl Rebuilder for PowRebuilder { + /// Feed the rebuilder an uncompressed block chunk. + /// Returns the number of blocks fed or any errors. + fn feed(&mut self, chunk: &[u8], engine: &Engine, abort_flag: &AtomicBool) -> Result<(), ::error::Error> { + use basic_types::Seal::With; + use views::BlockView; + use snapshot::verify_old_block; + use util::U256; + use util::triehash::ordered_trie_root; + + let rlp = UntrustedRlp::new(chunk); + let item_count = rlp.item_count()?; + let num_blocks = (item_count - 3) as u64; + + trace!(target: "snapshot", "restoring block chunk with {} blocks.", item_count - 3); + + if self.fed_blocks + num_blocks > self.snapshot_blocks { + return Err(Error::TooManyBlocks(self.snapshot_blocks, self.fed_blocks).into()) + } + + // todo: assert here that these values are consistent with chunks being in order. + let mut cur_number = rlp.val_at::(0)? + 1; + let mut parent_hash = rlp.val_at::(1)?; + let parent_total_difficulty = rlp.val_at::(2)?; + + for idx in 3..item_count { + if !abort_flag.load(Ordering::SeqCst) { return Err(Error::RestorationAborted.into()) } + + let pair = rlp.at(idx)?; + let abridged_rlp = pair.at(0)?.as_raw().to_owned(); + let abridged_block = AbridgedBlock::from_raw(abridged_rlp); + let receipts: Vec<::receipt::Receipt> = pair.list_at(1)?; + let receipts_root = ordered_trie_root( + pair.at(1)?.iter().map(|r| r.as_raw().to_owned()) + ); + + let block = abridged_block.to_block(parent_hash, cur_number, receipts_root)?; + let block_bytes = block.rlp_bytes(With); + let is_best = cur_number == self.best_number; + + if is_best { + if block.header.hash() != self.best_hash { + return Err(Error::WrongBlockHash(cur_number, self.best_hash, block.header.hash()).into()) + } + + if block.header.state_root() != &self.best_root { + return Err(Error::WrongStateRoot(self.best_root, *block.header.state_root()).into()) + } + } + + verify_old_block( + &mut self.rng, + &block.header, + engine, + &self.chain, + Some(&block_bytes), + is_best + )?; + + let mut batch = self.db.transaction(); + + // special-case the first block in each chunk. + if idx == 3 { + if self.chain.insert_unordered_block(&mut batch, &block_bytes, receipts, Some(parent_total_difficulty), is_best, false) { + self.disconnected.push((cur_number, block.header.hash())); + } + } else { + self.chain.insert_unordered_block(&mut batch, &block_bytes, receipts, None, is_best, false); + } + self.db.write_buffered(batch); + self.chain.commit(); + + parent_hash = BlockView::new(&block_bytes).hash(); + cur_number += 1; + } + + self.fed_blocks += num_blocks; + + Ok(()) + } + + /// Glue together any disconnected chunks and check that the chain is complete. + fn finalize(&mut self) -> Result<(), Error> { + let mut batch = self.db.transaction(); + + for (first_num, first_hash) in self.disconnected.drain(..) { + let parent_num = first_num - 1; + + // check if the parent is even in the chain. + // since we don't restore every single block in the chain, + // the first block of the first chunks has nothing to connect to. + if let Some(parent_hash) = self.chain.block_hash(parent_num) { + // if so, add the child to it. + self.chain.add_child(&mut batch, parent_hash, first_hash); + } + } + self.db.write_buffered(batch); + Ok(()) + } +} diff --git a/ethcore/src/snapshot/error.rs b/ethcore/src/snapshot/error.rs index c1391b300..7a3ffdca2 100644 --- a/ethcore/src/snapshot/error.rs +++ b/ethcore/src/snapshot/error.rs @@ -57,6 +57,8 @@ pub enum Error { VersionNotSupported(u64), /// Max chunk size is to small to fit basic account data. ChunkTooSmall, + /// Snapshots not supported by the consensus engine. + SnapshotsUnsupported, } impl fmt::Display for Error { @@ -79,6 +81,7 @@ impl fmt::Display for Error { Error::Trie(ref err) => err.fmt(f), Error::VersionNotSupported(ref ver) => write!(f, "Snapshot version {} is not supprted.", ver), Error::ChunkTooSmall => write!(f, "Chunk size is too small."), + Error::SnapshotsUnsupported => write!(f, "Snapshots unsupported by consensus engine."), } } } diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 69dbc943d..db3bebde9 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -17,9 +17,9 @@ //! Snapshot creation, restoration, and network service. //! //! Documentation of the format can be found at -//! https://github.com/paritytech/parity/wiki/%22PV64%22-Snapshot-Format +//! https://github.com/paritytech/parity/wiki/Warp-Sync-Snapshot-Format -use std::collections::{HashMap, HashSet, VecDeque}; +use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; @@ -28,7 +28,6 @@ use blockchain::{BlockChain, BlockProvider}; use engines::Engine; use header::Header; use ids::BlockId; -use views::BlockView; use util::{Bytes, Hashable, HashDB, DBValue, snappy, U256, Uint}; use util::Mutex; @@ -40,7 +39,6 @@ use util::sha3::SHA3_NULL_RLP; use rlp::{RlpStream, UntrustedRlp}; use bloom_journal::Bloom; -use self::block::AbridgedBlock; use self::io::SnapshotWriter; use super::state_db::StateDB; @@ -51,6 +49,7 @@ use rand::{Rng, OsRng}; pub use self::error::Error; +pub use self::consensus::*; pub use self::service::{Service, DatabaseRestore}; pub use self::traits::SnapshotService; pub use self::watcher::Watcher; @@ -63,6 +62,7 @@ pub mod service; mod account; mod block; +mod consensus; mod error; mod watcher; @@ -83,9 +83,6 @@ mod traits { // Try to have chunks be around 4MB (before compression) const PREFERRED_CHUNK_SIZE: usize = 4 * 1024 * 1024; -// How many blocks to include in a snapshot, starting from the head of the chain. -const SNAPSHOT_BLOCKS: u64 = 30000; - /// A progress indicator for snapshots. #[derive(Debug, Default)] pub struct Progress { @@ -122,6 +119,7 @@ impl Progress { } /// Take a snapshot using the given blockchain, starting block hash, and database, writing into the given writer. pub fn take_snapshot( + engine: &Engine, chain: &BlockChain, block_at: H256, state_db: &HashDB, @@ -136,9 +134,11 @@ pub fn take_snapshot( info!("Taking snapshot starting at block {}", number); let writer = Mutex::new(writer); + let chunker = engine.snapshot_components().ok_or(Error::SnapshotsUnsupported)?; let (state_hashes, block_hashes) = scope(|scope| { - let block_guard = scope.spawn(|| chunk_blocks(chain, block_at, &writer, p)); - let state_res = chunk_state(state_db, state_root, &writer, p); + let writer = &writer; + let block_guard = scope.spawn(move || chunk_secondary(chunker, chain, block_at, writer, p)); + let state_res = chunk_state(state_db, state_root, writer, p); state_res.and_then(|state_hashes| { block_guard.join().map(|block_hashes| (state_hashes, block_hashes)) @@ -163,128 +163,41 @@ pub fn take_snapshot( Ok(()) } -/// Used to build block chunks. -struct BlockChunker<'a> { - chain: &'a BlockChain, - // block, receipt rlp pairs. - rlps: VecDeque, - current_hash: H256, - hashes: Vec, - snappy_buffer: Vec, - writer: &'a Mutex, - progress: &'a Progress, -} - -impl<'a> BlockChunker<'a> { - // Repeatedly fill the buffers and writes out chunks, moving backwards from starting block hash. - // Loops until we reach the first desired block, and writes out the remainder. - fn chunk_all(&mut self) -> Result<(), Error> { - let mut loaded_size = 0; - let mut last = self.current_hash; - - let genesis_hash = self.chain.genesis_hash(); - - for _ in 0..SNAPSHOT_BLOCKS { - if self.current_hash == genesis_hash { break } - - let (block, receipts) = self.chain.block(&self.current_hash) - .and_then(|b| self.chain.block_receipts(&self.current_hash).map(|r| (b, r))) - .ok_or(Error::BlockNotFound(self.current_hash))?; - - let abridged_rlp = AbridgedBlock::from_block_view(&block.view()).into_inner(); - - let pair = { - let mut pair_stream = RlpStream::new_list(2); - pair_stream.append_raw(&abridged_rlp, 1).append(&receipts); - pair_stream.out() - }; - - let new_loaded_size = loaded_size + pair.len(); - - // cut off the chunk if too large. - - if new_loaded_size > PREFERRED_CHUNK_SIZE && !self.rlps.is_empty() { - self.write_chunk(last)?; - loaded_size = pair.len(); - } else { - loaded_size = new_loaded_size; - } - - self.rlps.push_front(pair); - - last = self.current_hash; - self.current_hash = block.header_view().parent_hash(); - } - - if loaded_size != 0 { - self.write_chunk(last)?; - } - - Ok(()) - } - - // write out the data in the buffers to a chunk on disk - // - // we preface each chunk with the parent of the first block's details, - // obtained from the details of the last block written. - fn write_chunk(&mut self, last: H256) -> Result<(), Error> { - trace!(target: "snapshot", "prepared block chunk with {} blocks", self.rlps.len()); - - let (last_header, last_details) = self.chain.block_header(&last) - .and_then(|n| self.chain.block_details(&last).map(|d| (n, d))) - .ok_or(Error::BlockNotFound(last))?; - - let parent_number = last_header.number() - 1; - let parent_hash = last_header.parent_hash(); - let parent_total_difficulty = last_details.total_difficulty - *last_header.difficulty(); - - trace!(target: "snapshot", "parent last written block: {}", parent_hash); - - let num_entries = self.rlps.len(); - let mut rlp_stream = RlpStream::new_list(3 + num_entries); - rlp_stream.append(&parent_number).append(parent_hash).append(&parent_total_difficulty); - - for pair in self.rlps.drain(..) { - rlp_stream.append_raw(&pair, 1); - } - - let raw_data = rlp_stream.out(); - - let size = snappy::compress_into(&raw_data, &mut self.snappy_buffer); - let compressed = &self.snappy_buffer[..size]; - let hash = compressed.sha3(); - - self.writer.lock().write_block_chunk(hash, compressed)?; - trace!(target: "snapshot", "wrote block chunk. hash: {}, size: {}, uncompressed size: {}", hash.hex(), size, raw_data.len()); - - self.progress.size.fetch_add(size, Ordering::SeqCst); - self.progress.blocks.fetch_add(num_entries, Ordering::SeqCst); - - self.hashes.push(hash); - Ok(()) - } -} - -/// Create and write out all block chunks to disk, returning a vector of all -/// the hashes of block chunks created. +/// Create and write out all secondary chunks to disk, returning a vector of all +/// the hashes of secondary chunks created. /// -/// The path parameter is the directory to store the block chunks in. -/// This function assumes the directory exists already. +/// Secondary chunks are engine-specific, but they intend to corroborate the state data +/// in the state chunks. /// Returns a list of chunk hashes, with the first having the blocks furthest from the genesis. -pub fn chunk_blocks<'a>(chain: &'a BlockChain, start_hash: H256, writer: &Mutex, progress: &'a Progress) -> Result, Error> { - let mut chunker = BlockChunker { - chain: chain, - rlps: VecDeque::new(), - current_hash: start_hash, - hashes: Vec::new(), - snappy_buffer: vec![0; snappy::max_compressed_len(PREFERRED_CHUNK_SIZE)], - writer: writer, - progress: progress, - }; +pub fn chunk_secondary<'a>(mut chunker: Box, chain: &'a BlockChain, start_hash: H256, writer: &Mutex, progress: &'a Progress) -> Result, Error> { + let mut chunk_hashes = Vec::new(); + let mut snappy_buffer = vec![0; snappy::max_compressed_len(PREFERRED_CHUNK_SIZE)]; - chunker.chunk_all()?; + { + let mut chunk_sink = |raw_data: &[u8]| { + let compressed_size = snappy::compress_into(raw_data, &mut snappy_buffer); + let compressed = &snappy_buffer[..compressed_size]; + let hash = compressed.sha3(); + let size = compressed.len(); - Ok(chunker.hashes) + writer.lock().write_block_chunk(hash, compressed)?; + trace!(target: "snapshot", "wrote secondary chunk. hash: {}, size: {}, uncompressed size: {}", + hash.hex(), size, raw_data.len()); + + progress.size.fetch_add(size, Ordering::SeqCst); + chunk_hashes.push(hash); + Ok(()) + }; + + chunker.chunk_all( + chain, + start_hash, + &mut chunk_sink, + PREFERRED_CHUNK_SIZE, + )?; + } + + Ok(chunk_hashes) } /// State trie chunker. @@ -564,158 +477,15 @@ const POW_VERIFY_RATE: f32 = 0.02; /// the fullest verification possible. If not, it will take a random sample to determine whether it will /// do heavy or light verification. pub fn verify_old_block(rng: &mut OsRng, header: &Header, engine: &Engine, chain: &BlockChain, body: Option<&[u8]>, always: bool) -> Result<(), ::error::Error> { + engine.verify_block_basic(header, body)?; + if always || rng.gen::() <= POW_VERIFY_RATE { + engine.verify_block_unordered(header, body)?; match chain.block_header(header.parent_hash()) { Some(parent) => engine.verify_block_family(header, &parent, body), - None => engine.verify_block_seal(header), + None => Ok(()), } } else { - engine.verify_block_basic(header, body) - } -} - -/// Rebuilds the blockchain from chunks. -/// -/// Does basic verification for all blocks, but `PoW` verification for some. -/// Blocks must be fed in-order. -/// -/// The first block in every chunk is disconnected from the last block in the -/// chunk before it, as chunks may be submitted out-of-order. -/// -/// After all chunks have been submitted, we "glue" the chunks together. -pub struct BlockRebuilder { - chain: BlockChain, - db: Arc, - rng: OsRng, - disconnected: Vec<(u64, H256)>, - best_number: u64, - best_hash: H256, - best_root: H256, - fed_blocks: u64, -} - -impl BlockRebuilder { - /// Create a new BlockRebuilder. - pub fn new(chain: BlockChain, db: Arc, manifest: &ManifestData) -> Result { - Ok(BlockRebuilder { - chain: chain, - db: db, - rng: OsRng::new()?, - disconnected: Vec::new(), - best_number: manifest.block_number, - best_hash: manifest.block_hash, - best_root: manifest.state_root, - fed_blocks: 0, - }) - } - - /// Feed the rebuilder an uncompressed block chunk. - /// Returns the number of blocks fed or any errors. - pub fn feed(&mut self, chunk: &[u8], engine: &Engine, abort_flag: &AtomicBool) -> Result { - use basic_types::Seal::With; - use util::U256; - use util::triehash::ordered_trie_root; - - let rlp = UntrustedRlp::new(chunk); - let item_count = rlp.item_count()?; - let num_blocks = (item_count - 3) as u64; - - trace!(target: "snapshot", "restoring block chunk with {} blocks.", item_count - 3); - - if self.fed_blocks + num_blocks > SNAPSHOT_BLOCKS { - return Err(Error::TooManyBlocks(SNAPSHOT_BLOCKS, self.fed_blocks).into()) - } - - // todo: assert here that these values are consistent with chunks being in order. - let mut cur_number = rlp.val_at::(0)? + 1; - let mut parent_hash = rlp.val_at::(1)?; - let parent_total_difficulty = rlp.val_at::(2)?; - - for idx in 3..item_count { - if !abort_flag.load(Ordering::SeqCst) { return Err(Error::RestorationAborted.into()) } - - let pair = rlp.at(idx)?; - let abridged_rlp = pair.at(0)?.as_raw().to_owned(); - let abridged_block = AbridgedBlock::from_raw(abridged_rlp); - let receipts: Vec<::receipt::Receipt> = pair.list_at(1)?; - let receipts_root = ordered_trie_root( - pair.at(1)?.iter().map(|r| r.as_raw().to_owned()) - ); - - let block = abridged_block.to_block(parent_hash, cur_number, receipts_root)?; - let block_bytes = block.rlp_bytes(With); - let is_best = cur_number == self.best_number; - - if is_best { - if block.header.hash() != self.best_hash { - return Err(Error::WrongBlockHash(cur_number, self.best_hash, block.header.hash()).into()) - } - - if block.header.state_root() != &self.best_root { - return Err(Error::WrongStateRoot(self.best_root, *block.header.state_root()).into()) - } - } - - verify_old_block( - &mut self.rng, - &block.header, - engine, - &self.chain, - Some(&block_bytes), - is_best - )?; - - let mut batch = self.db.transaction(); - - // special-case the first block in each chunk. - if idx == 3 { - if self.chain.insert_unordered_block(&mut batch, &block_bytes, receipts, Some(parent_total_difficulty), is_best, false) { - self.disconnected.push((cur_number, block.header.hash())); - } - } else { - self.chain.insert_unordered_block(&mut batch, &block_bytes, receipts, None, is_best, false); - } - self.db.write_buffered(batch); - self.chain.commit(); - - parent_hash = BlockView::new(&block_bytes).hash(); - cur_number += 1; - } - - self.fed_blocks += num_blocks; - - Ok(num_blocks) - } - - /// Glue together any disconnected chunks and check that the chain is complete. - pub fn finalize(self, canonical: HashMap) -> Result<(), Error> { - let mut batch = self.db.transaction(); - - for (first_num, first_hash) in self.disconnected { - let parent_num = first_num - 1; - - // check if the parent is even in the chain. - // since we don't restore every single block in the chain, - // the first block of the first chunks has nothing to connect to. - if let Some(parent_hash) = self.chain.block_hash(parent_num) { - // if so, add the child to it. - self.chain.add_child(&mut batch, parent_hash, first_hash); - } - } - self.db.write_buffered(batch); - - let best_number = self.best_number; - for num in (0..self.fed_blocks).map(|x| best_number - x) { - - let hash = self.chain.block_hash(num).ok_or(Error::IncompleteChain)?; - - if let Some(canon_hash) = canonical.get(&num).cloned() { - if canon_hash != hash { - return Err(Error::WrongBlockHash(num, canon_hash, hash)); - } - } - } - Ok(()) } } diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 06e659bc1..dc92b5427 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -16,14 +16,14 @@ //! Snapshot network service implementation. -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::io::ErrorKind; use std::fs; use std::path::PathBuf; use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; -use super::{ManifestData, StateRebuilder, BlockRebuilder, RestorationStatus, SnapshotService}; +use super::{ManifestData, StateRebuilder, Rebuilder, RestorationStatus, SnapshotService}; use super::io::{SnapshotReader, LooseReader, SnapshotWriter, LooseWriter}; use blockchain::BlockChain; @@ -69,12 +69,11 @@ struct Restoration { state_chunks_left: HashSet, block_chunks_left: HashSet, state: StateRebuilder, - blocks: BlockRebuilder, + secondary: Box, writer: Option, snappy_buffer: Bytes, final_state_root: H256, guard: Guard, - canonical_hashes: HashMap, db: Arc, } @@ -86,6 +85,7 @@ struct RestorationParams<'a> { writer: Option, // writer for recovered snapshot. genesis: &'a [u8], // genesis block of the chain. guard: Guard, // guard for the restoration directory. + engine: &'a Engine, } impl Restoration { @@ -100,7 +100,10 @@ impl Restoration { .map_err(UtilError::SimpleString)?); let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone()); - let blocks = BlockRebuilder::new(chain, raw_db.clone(), &manifest)?; + let components = params.engine.snapshot_components() + .ok_or_else(|| ::snapshot::Error::SnapshotsUnsupported)?; + + let secondary = components.rebuilder(chain, raw_db.clone(), &manifest)?; let root = manifest.state_root.clone(); Ok(Restoration { @@ -108,12 +111,11 @@ impl Restoration { state_chunks_left: state_chunks, block_chunks_left: block_chunks, state: StateRebuilder::new(raw_db.clone(), params.pruning), - blocks: blocks, + secondary: secondary, writer: params.writer, snappy_buffer: Vec::new(), final_state_root: root, guard: params.guard, - canonical_hashes: HashMap::new(), db: raw_db, }) } @@ -138,7 +140,7 @@ impl Restoration { if self.block_chunks_left.remove(&hash) { let len = snappy::decompress_into(chunk, &mut self.snappy_buffer)?; - self.blocks.feed(&self.snappy_buffer[..len], engine, flag)?; + self.secondary.feed(&self.snappy_buffer[..len], engine, flag)?; if let Some(ref mut writer) = self.writer.as_mut() { writer.write_block_chunk(hash, chunk)?; } @@ -147,13 +149,8 @@ impl Restoration { Ok(()) } - // note canonical hashes. - fn note_canonical(&mut self, hashes: &[(u64, H256)]) { - self.canonical_hashes.extend(hashes.iter().cloned()); - } - // finish up restoration. - fn finalize(self) -> Result<(), Error> { + fn finalize(mut self) -> Result<(), Error> { use util::trie::TrieError; if !self.is_done() { return Ok(()) } @@ -169,7 +166,7 @@ impl Restoration { self.state.finalize(self.manifest.block_number, self.manifest.block_hash)?; // connect out-of-order chunks and verify chain integrity. - self.blocks.finalize(self.canonical_hashes)?; + self.secondary.finalize()?; if let Some(writer) = self.writer { writer.finish(self.manifest)?; @@ -425,6 +422,7 @@ impl Service { writer: writer, genesis: &self.genesis_block, guard: Guard::new(rest_dir), + engine: &*self.engine, }; let state_chunks = params.manifest.state_hashes.len(); @@ -593,14 +591,6 @@ impl SnapshotService for Service { trace!("Error sending snapshot service message: {:?}", e); } } - - fn provide_canon_hashes(&self, canonical: &[(u64, H256)]) { - let mut rest = self.restoration.lock(); - - if let Some(ref mut rest) = rest.as_mut() { - rest.note_canonical(canonical); - } - } } impl Drop for Service { diff --git a/ethcore/src/snapshot/snapshot_service_trait.rs b/ethcore/src/snapshot/snapshot_service_trait.rs index 7b53ee9b9..67e96398e 100644 --- a/ethcore/src/snapshot/snapshot_service_trait.rs +++ b/ethcore/src/snapshot/snapshot_service_trait.rs @@ -48,10 +48,6 @@ pub trait SnapshotService : Sync + Send { /// Feed a raw block chunk to the service to be processed asynchronously. /// no-op if currently restoring. fn restore_block_chunk(&self, hash: H256, chunk: Bytes); - - /// Give the restoration in-progress some canonical block hashes for - /// extra verification (performed at the end) - fn provide_canon_hashes(&self, canonical: &[(u64, H256)]); } impl IpcConfig for SnapshotService { } diff --git a/ethcore/src/snapshot/tests/blocks.rs b/ethcore/src/snapshot/tests/blocks.rs index ff63afdfc..2769644e8 100644 --- a/ethcore/src/snapshot/tests/blocks.rs +++ b/ethcore/src/snapshot/tests/blocks.rs @@ -21,33 +21,32 @@ use error::Error; use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer}; use blockchain::BlockChain; -use snapshot::{chunk_blocks, BlockRebuilder, Error as SnapshotError, Progress}; +use snapshot::{chunk_secondary, Error as SnapshotError, Progress, SnapshotComponents}; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use util::{Mutex, snappy}; -use util::kvdb::{Database, DatabaseConfig}; +use util::kvdb::{self, KeyValueDB, DBTransaction}; -use std::collections::HashMap; use std::sync::Arc; use std::sync::atomic::AtomicBool; +const SNAPSHOT_MODE: ::snapshot::PowSnapshot = ::snapshot::PowSnapshot(30000); + fn chunk_and_restore(amount: u64) { let mut canon_chain = ChainGenerator::default(); let mut finalizer = BlockFinalizer::default(); let genesis = canon_chain.generate(&mut finalizer).unwrap(); - let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); let engine = Arc::new(::engines::NullEngine::default()); - let orig_path = RandomTempPath::create_dir(); let new_path = RandomTempPath::create_dir(); let mut snapshot_path = new_path.as_path().to_owned(); snapshot_path.push("SNAP"); - let old_db = Arc::new(Database::open(&db_cfg, orig_path.as_str()).unwrap()); + let old_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); let bc = BlockChain::new(Default::default(), &genesis, old_db.clone()); // build the blockchain. - let mut batch = old_db.transaction(); + let mut batch = DBTransaction::new(); for _ in 0..amount { let block = canon_chain.generate(&mut finalizer).unwrap(); bc.insert_block(&mut batch, &block, vec![]); @@ -56,12 +55,18 @@ fn chunk_and_restore(amount: u64) { old_db.write(batch).unwrap(); - let best_hash = bc.best_block_hash(); // snapshot it. let writer = Mutex::new(PackedWriter::new(&snapshot_path).unwrap()); - let block_hashes = chunk_blocks(&bc, best_hash, &writer, &Progress::default()).unwrap(); + let block_hashes = chunk_secondary( + Box::new(SNAPSHOT_MODE), + &bc, + best_hash, + &writer, + &Progress::default() + ).unwrap(); + let manifest = ::snapshot::ManifestData { version: 2, state_hashes: Vec::new(), @@ -74,9 +79,10 @@ fn chunk_and_restore(amount: u64) { writer.into_inner().finish(manifest.clone()).unwrap(); // restore it. - let new_db = Arc::new(Database::open(&db_cfg, new_path.as_str()).unwrap()); + let new_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone()); - let mut rebuilder = BlockRebuilder::new(new_chain, new_db.clone(), &manifest).unwrap(); + let mut rebuilder = SNAPSHOT_MODE.rebuilder(new_chain, new_db.clone(), &manifest).unwrap(); + let reader = PackedReader::new(&snapshot_path).unwrap().unwrap(); let flag = AtomicBool::new(true); for chunk_hash in &reader.manifest().block_hashes { @@ -85,7 +91,8 @@ fn chunk_and_restore(amount: u64) { rebuilder.feed(&chunk, engine.as_ref(), &flag).unwrap(); } - rebuilder.finalize(HashMap::new()).unwrap(); + rebuilder.finalize().unwrap(); + drop(rebuilder); // and test it. let new_chain = BlockChain::new(Default::default(), &genesis, new_db); @@ -118,10 +125,8 @@ fn checks_flag() { }; let chunk = stream.out(); - let path = RandomTempPath::create_dir(); - let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); - let db = Arc::new(Database::open(&db_cfg, path.as_str()).unwrap()); + let db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); let engine = Arc::new(::engines::NullEngine::default()); let chain = BlockChain::new(Default::default(), &genesis, db.clone()); @@ -134,7 +139,7 @@ fn checks_flag() { block_hash: H256::default(), }; - let mut rebuilder = BlockRebuilder::new(chain, db.clone(), &manifest).unwrap(); + let mut rebuilder = SNAPSHOT_MODE.rebuilder(chain, db.clone(), &manifest).unwrap(); match rebuilder.feed(&chunk, engine.as_ref(), &AtomicBool::new(false)) { Err(Error::Snapshot(SnapshotError::RestorationAborted)) => {} diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 9051bcbcf..efbfc435d 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -16,25 +16,27 @@ //! Parameters for a block chain. -use util::*; -use builtin::Builtin; -use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint}; -use factory::Factories; -use executive::Executive; -use trace::{NoopTracer, NoopVMTracer}; -use action_params::{ActionValue, ActionParams}; -use types::executed::CallType; -use state::{Backend, State, Substate}; -use env_info::EnvInfo; -use pod_state::*; -use account_db::*; -use header::{BlockNumber, Header}; -use state_db::StateDB; use super::genesis::Genesis; use super::seal::Generic as GenericSeal; + +use action_params::{ActionValue, ActionParams}; +use builtin::Builtin; +use engines::{Engine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint}; +use env_info::EnvInfo; +use error::Error; use ethereum; use ethjson; +use executive::Executive; +use factory::Factories; +use header::{BlockNumber, Header}; +use pod_state::*; use rlp::{Rlp, RlpStream}; +use state_db::StateDB; +use state::{Backend, State, Substate}; +use state::backend::Basic as BasicBackend; +use trace::{NoopTracer, NoopVMTracer}; +use types::executed::CallType; +use util::*; /// Parameters common to all engines. #[derive(Debug, PartialEq, Clone, Default)] @@ -57,6 +59,8 @@ pub struct CommonParams { pub eip98_transition: BlockNumber, /// Validate block receipts root. pub validate_receipts_transition: u64, + /// Number of first block where EIP-86 (Metropolis) rules begin. + pub eip86_transition: BlockNumber, } impl From for CommonParams { @@ -71,6 +75,7 @@ impl From for CommonParams { fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None }, eip98_transition: p.eip98_transition.map_or(0, Into::into), validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), + eip86_transition: p.eip86_transition.map_or(BlockNumber::max_value(), Into::into), } } } @@ -116,39 +121,46 @@ pub struct Spec { constructors: Vec<(Address, Bytes)>, /// May be prepopulated if we know this in advance. - state_root_memo: RwLock>, + state_root_memo: RwLock, /// Genesis state as plain old data. genesis_state: PodState, } -impl From for Spec { - fn from(s: ethjson::spec::Spec) -> Self { - let builtins = s.accounts.builtins().into_iter().map(|p| (p.0.into(), From::from(p.1))).collect(); - let g = Genesis::from(s.genesis); - let GenericSeal(seal_rlp) = g.seal.into(); - let params = CommonParams::from(s.params); - Spec { - name: s.name.clone().into(), - params: params.clone(), - engine: Spec::engine(s.engine, params, builtins), - data_dir: s.data_dir.unwrap_or(s.name).into(), - nodes: s.nodes.unwrap_or_else(Vec::new), - parent_hash: g.parent_hash, - transactions_root: g.transactions_root, - receipts_root: g.receipts_root, - author: g.author, - difficulty: g.difficulty, - gas_limit: g.gas_limit, - gas_used: g.gas_used, - timestamp: g.timestamp, - extra_data: g.extra_data, - seal_rlp: seal_rlp, - constructors: s.accounts.constructors().into_iter().map(|(a, c)| (a.into(), c.into())).collect(), - state_root_memo: RwLock::new(g.state_root), - genesis_state: From::from(s.accounts), - } +fn load_from(s: ethjson::spec::Spec) -> Result { + let builtins = s.accounts.builtins().into_iter().map(|p| (p.0.into(), From::from(p.1))).collect(); + let g = Genesis::from(s.genesis); + let GenericSeal(seal_rlp) = g.seal.into(); + let params = CommonParams::from(s.params); + + let mut s = Spec { + name: s.name.clone().into(), + params: params.clone(), + engine: Spec::engine(s.engine, params, builtins), + data_dir: s.data_dir.unwrap_or(s.name).into(), + nodes: s.nodes.unwrap_or_else(Vec::new), + parent_hash: g.parent_hash, + transactions_root: g.transactions_root, + receipts_root: g.receipts_root, + author: g.author, + difficulty: g.difficulty, + gas_limit: g.gas_limit, + gas_used: g.gas_used, + timestamp: g.timestamp, + extra_data: g.extra_data, + seal_rlp: seal_rlp, + constructors: s.accounts.constructors().into_iter().map(|(a, c)| (a.into(), c.into())).collect(), + state_root_memo: RwLock::new(Default::default()), // will be overwritten right after. + genesis_state: s.accounts.into(), + }; + + // use memoized state root if provided. + match g.state_root { + Some(root) => *s.state_root_memo.get_mut() = root, + None => { let _ = s.run_constructors(&Default::default(), BasicBackend(MemoryDB::new()))?; }, } + + Ok(s) } macro_rules! load_bundled { @@ -171,13 +183,93 @@ impl Spec { } } + // given a pre-constructor state, run all the given constructors and produce a new state and state root. + fn run_constructors(&self, factories: &Factories, mut db: T) -> Result { + let mut root = SHA3_NULL_RLP; + + // basic accounts in spec. + { + let mut t = factories.trie.create(db.as_hashdb_mut(), &mut root); + + for (address, account) in self.genesis_state.get().iter() { + t.insert(&**address, &account.rlp())?; + } + } + + for (address, account) in self.genesis_state.get().iter() { + db.note_non_null_account(address); + account.insert_additional( + &mut *factories.accountdb.create(db.as_hashdb_mut(), address.sha3()), + &factories.trie + ); + } + + let start_nonce = self.engine.account_start_nonce(); + + let (root, db) = { + let mut state = State::from_existing( + db, + root, + start_nonce, + factories.clone(), + )?; + + // Execute contract constructors. + let env_info = EnvInfo { + number: 0, + author: self.author, + timestamp: self.timestamp, + difficulty: self.difficulty, + last_hashes: Default::default(), + gas_used: U256::zero(), + gas_limit: U256::max_value(), + }; + + let from = Address::default(); + for &(ref address, ref constructor) in self.constructors.iter() { + trace!(target: "spec", "run_constructors: Creating a contract at {}.", address); + trace!(target: "spec", " .. root before = {}", state.root()); + let params = ActionParams { + code_address: address.clone(), + code_hash: constructor.sha3(), + address: address.clone(), + sender: from.clone(), + origin: from.clone(), + gas: U256::max_value(), + gas_price: Default::default(), + value: ActionValue::Transfer(Default::default()), + code: Some(Arc::new(constructor.clone())), + data: None, + call_type: CallType::None, + }; + + let mut substate = Substate::new(); + state.kill_account(&address); + + { + let mut exec = Executive::new(&mut state, &env_info, self.engine.as_ref(), &factories.vm); + if let Err(e) = exec.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) { + warn!(target: "spec", "Genesis constructor execution at {} failed: {}.", address, e); + } + } + + if let Err(e) = state.commit() { + warn!(target: "spec", "Genesis constructor trie commit at {} failed: {}.", address, e); + } + + trace!(target: "spec", " .. root after = {}", state.root()); + } + + state.drop() + }; + + *self.state_root_memo.write() = root; + Ok(db) + } + /// Return the state root for the genesis state, memoising accordingly. pub fn state_root(&self) -> H256 { - if self.state_root_memo.read().is_none() { - *self.state_root_memo.write() = Some(self.genesis_state.root()); - } - self.state_root_memo.read().as_ref().cloned() - .expect("state root memo ensured to be set at this point; qed") + self.state_root_memo.read().clone() } /// Get the known knodes of the network in enode format. @@ -240,94 +332,46 @@ impl Spec { self.timestamp = g.timestamp; self.extra_data = g.extra_data; self.seal_rlp = seal_rlp; - self.state_root_memo = RwLock::new(g.state_root); } /// Alter the value of the genesis state. - pub fn set_genesis_state(&mut self, s: PodState) { + pub fn set_genesis_state(&mut self, s: PodState) -> Result<(), Error> { self.genesis_state = s; - *self.state_root_memo.write() = None; + let _ = self.run_constructors(&Default::default(), BasicBackend(MemoryDB::new()))?; + + Ok(()) } /// Returns `false` if the memoized state root is invalid. `true` otherwise. pub fn is_state_root_valid(&self) -> bool { - self.state_root_memo.read().clone().map_or(true, |sr| sr == self.genesis_state.root()) + // TODO: get rid of this function and ensure state root always is valid. + // we're mostly there, but `self.genesis_state.root()` doesn't encompass + // post-constructor state. + *self.state_root_memo.read() == self.genesis_state.root() } /// Ensure that the given state DB has the trie nodes in for the genesis state. - pub fn ensure_db_good(&self, mut db: StateDB, factories: &Factories) -> Result> { + pub fn ensure_db_good(&self, db: StateDB, factories: &Factories) -> Result { if db.as_hashdb().contains(&self.state_root()) { return Ok(db) } - trace!(target: "spec", "ensure_db_good: Fresh database? Cannot find state root {}", self.state_root()); - let mut root = H256::new(); - { - let mut t = factories.trie.create(db.as_hashdb_mut(), &mut root); - for (address, account) in self.genesis_state.get().iter() { - t.insert(&**address, &account.rlp())?; - } - } + // TODO: could optimize so we don't re-run, but `ensure_db_good` is barely ever + // called anyway. + let db = self.run_constructors(factories, db)?; - trace!(target: "spec", "ensure_db_good: Populated sec trie; root is {}", root); - for (address, account) in self.genesis_state.get().iter() { - db.note_non_null_account(address); - account.insert_additional(&mut AccountDBMut::new(db.as_hashdb_mut(), address), &factories.trie); - } - - // Execute contract constructors. - let env_info = EnvInfo { - number: 0, - author: self.author, - timestamp: self.timestamp, - difficulty: self.difficulty, - last_hashes: Default::default(), - gas_used: U256::zero(), - gas_limit: U256::max_value(), - }; - let from = Address::default(); - let start_nonce = self.engine.account_start_nonce(); - - let mut state = State::from_existing(db, root, start_nonce, factories.clone())?; - // Mutate the state with each constructor. - for &(ref address, ref constructor) in self.constructors.iter() { - trace!(target: "spec", "ensure_db_good: Creating a contract at {}.", address); - let params = ActionParams { - code_address: address.clone(), - code_hash: constructor.sha3(), - address: address.clone(), - sender: from.clone(), - origin: from.clone(), - gas: U256::max_value(), - gas_price: Default::default(), - value: ActionValue::Transfer(Default::default()), - code: Some(Arc::new(constructor.clone())), - data: None, - call_type: CallType::None, - }; - let mut substate = Substate::new(); - { - let mut exec = Executive::new(&mut state, &env_info, self.engine.as_ref(), &factories.vm); - if let Err(e) = exec.create(params, &mut substate, &mut NoopTracer, &mut NoopVMTracer) { - warn!(target: "spec", "Genesis constructor execution at {} failed: {}.", address, e); - } - } - if let Err(e) = state.commit() { - warn!(target: "spec", "Genesis constructor trie commit at {} failed: {}.", address, e); - } - } - let (root, db) = state.drop(); - - *self.state_root_memo.write() = Some(root); Ok(db) } - /// Loads spec from json file. + /// Loads spec from json file. Provide factories for executing contracts and ensuring + /// storage goes to the right place. pub fn load(reader: R) -> Result where R: Read { - match ethjson::spec::Spec::load(reader) { - Ok(spec) => Ok(spec.into()), - Err(e) => Err(format!("Spec json is invalid: {}", e)), + fn fmt(f: F) -> String { + format!("Spec json is invalid: {}", f) } + + ethjson::spec::Spec::load(reader).map_err(fmt) + .and_then(|x| load_from(x).map_err(fmt)) } /// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus. @@ -391,9 +435,9 @@ mod tests { #[test] fn genesis_constructor() { + ::ethcore_logger::init_log(); let spec = Spec::new_test_constructor(); - let mut db_result = get_temp_state_db(); - let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let state = State::from_existing(db.boxed_clone(), spec.state_root(), spec.engine.account_start_nonce(), Default::default()).unwrap(); let expected = H256::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap(); assert_eq!(state.storage_at(&Address::from_str("0000000000000000000000000000000000000005").unwrap(), &H256::zero()).unwrap(), expected); diff --git a/ethcore/src/state/backend.rs b/ethcore/src/state/backend.rs index 5ab620b0e..ea172b5af 100644 --- a/ethcore/src/state/backend.rs +++ b/ethcore/src/state/backend.rs @@ -206,7 +206,8 @@ impl Proving { } } - /// Consume the backend, extracting the gathered proof. + /// Consume the backend, extracting the gathered proof in lexicographical order + /// by value. pub fn extract_proof(self) -> Vec { self.proof.into_inner().into_iter().collect() } @@ -221,3 +222,33 @@ impl Clone for Proving { } } } + +/// A basic backend. Just wraps the given database, directly inserting into and deleting from +/// it. Doesn't cache anything. +pub struct Basic(pub H); + +impl Backend for Basic { + fn as_hashdb(&self) -> &HashDB { + self.0.as_hashdb() + } + + fn as_hashdb_mut(&mut self) -> &mut HashDB { + self.0.as_hashdb_mut() + } + + fn add_to_account_cache(&mut self, _: Address, _: Option, _: bool) { } + + fn cache_code(&self, _: H256, _: Arc>) { } + + fn get_cached_account(&self, _: &Address) -> Option> { None } + + fn get_cached(&self, _: &Address, _: F) -> Option + where F: FnOnce(Option<&mut Account>) -> U + { + None + } + + fn get_cached_code(&self, _: &H256) -> Option>> { None } + fn note_non_null_account(&self, _: &Address) { } + fn is_known_null(&self, _: &Address) -> bool { false } +} diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index b1594dd9b..e710559df 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -238,7 +238,7 @@ pub fn check_proof( /// Reverting a checkpoint with `revert_to_checkpoint` involves copying /// original values from the latest checkpoint back into `cache`. The code /// takes care not to overwrite cached storage while doing that. -/// checkpoint can be discateded with `discard_checkpoint`. All of the orignal +/// checkpoint can be discarded with `discard_checkpoint`. All of the orignal /// backed-up values are moved into a parent checkpoint (if any). /// pub struct State { @@ -433,6 +433,11 @@ impl State { self.ensure_cached(a, RequireCache::None, false, |a| a.map_or(false, |a| !a.is_null())) } + /// Determine whether an account exists and has code. + pub fn exists_and_has_code(&self, a: &Address) -> trie::Result { + self.ensure_cached(a, RequireCache::CodeSize, false, |a| a.map_or(false, |a| a.code_size().map_or(false, |size| size != 0))) + } + /// Get the balance of account `a`. pub fn balance(&self, a: &Address) -> trie::Result { self.ensure_cached(a, RequireCache::None, true, @@ -939,7 +944,6 @@ mod tests { use ethkey::Secret; use util::{U256, H256, Address, Hashable}; use tests::helpers::*; - use devtools::*; use env_info::EnvInfo; use spec::*; use transaction::*; @@ -955,8 +959,7 @@ mod tests { fn should_apply_create_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -998,9 +1001,8 @@ mod tests { let a = Address::zero(); - let temp = RandomTempPath::new(); let mut state = { - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); assert_eq!(state.exists(&a).unwrap(), false); state.inc_nonce(&a).unwrap(); state.commit().unwrap(); @@ -1015,8 +1017,7 @@ mod tests { fn should_trace_failed_create_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1052,8 +1053,7 @@ mod tests { fn should_trace_call_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1095,8 +1095,7 @@ mod tests { fn should_trace_basic_call_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1137,8 +1136,7 @@ mod tests { fn should_trace_call_transaction_to_builtin() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1179,8 +1177,7 @@ mod tests { fn should_not_trace_subcall_transaction_to_builtin() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1222,8 +1219,7 @@ mod tests { fn should_not_trace_callcode() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1281,15 +1277,14 @@ mod tests { fn should_not_trace_delegatecall() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); info.number = 0x789b0; let engine = &*Spec::new_test().engine; - println!("schedule.have_delegate_call: {:?}", engine.schedule(&info).have_delegate_call); + println!("schedule.have_delegate_call: {:?}", engine.schedule(info.number).have_delegate_call); let t = Transaction { nonce: 0.into(), @@ -1343,8 +1338,7 @@ mod tests { fn should_trace_failed_call_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1383,8 +1377,7 @@ mod tests { fn should_trace_call_with_subcall_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1443,8 +1436,7 @@ mod tests { fn should_trace_call_with_basic_subcall_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1498,8 +1490,7 @@ mod tests { fn should_not_trace_call_with_invalid_basic_subcall_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1541,8 +1532,7 @@ mod tests { fn should_trace_failed_subcall_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1597,8 +1587,7 @@ mod tests { fn should_trace_call_with_subcall_with_subcall_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1672,8 +1661,7 @@ mod tests { fn should_trace_failed_subcall_with_subcall_transaction() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1745,8 +1733,7 @@ mod tests { fn should_trace_suicide() { init_log(); - let temp = RandomTempPath::new(); - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); let mut info = EnvInfo::default(); info.gas_limit = 1_000_000.into(); @@ -1797,9 +1784,8 @@ mod tests { #[test] fn code_from_database() { let a = Address::zero(); - let temp = RandomTempPath::new(); let (root, db) = { - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); state.require_or_from(&a, false, ||Account::new_contract(42.into(), 0.into()), |_|{}).unwrap(); state.init_code(&a, vec![1, 2, 3]).unwrap(); assert_eq!(state.code(&a).unwrap(), Some(Arc::new([1u8, 2, 3].to_vec()))); @@ -1815,9 +1801,8 @@ mod tests { #[test] fn storage_at_from_database() { let a = Address::zero(); - let temp = RandomTempPath::new(); let (root, db) = { - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); state.set_storage(&a, H256::from(&U256::from(1u64)), H256::from(&U256::from(69u64))).unwrap(); state.commit().unwrap(); state.drop() @@ -1830,9 +1815,8 @@ mod tests { #[test] fn get_from_database() { let a = Address::zero(); - let temp = RandomTempPath::new(); let (root, db) = { - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); state.inc_nonce(&a).unwrap(); state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap(); state.commit().unwrap(); @@ -1848,8 +1832,7 @@ mod tests { #[test] fn remove() { let a = Address::zero(); - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); assert_eq!(state.exists(&a).unwrap(), false); assert_eq!(state.exists_and_not_null(&a).unwrap(), false); state.inc_nonce(&a).unwrap(); @@ -1865,8 +1848,7 @@ mod tests { #[test] fn empty_account_is_not_created() { let a = Address::zero(); - let path = RandomTempPath::new(); - let db = get_temp_state_db_in(path.as_path()); + let db = get_temp_state_db(); let (root, db) = { let mut state = State::new(db, U256::from(0), Default::default()); state.add_balance(&a, &U256::default(), CleanupMode::NoEmpty).unwrap(); // create an empty account @@ -1881,8 +1863,7 @@ mod tests { #[test] fn empty_account_exists_when_creation_forced() { let a = Address::zero(); - let path = RandomTempPath::new(); - let db = get_temp_state_db_in(path.as_path()); + let db = get_temp_state_db(); let (root, db) = { let mut state = State::new(db, U256::from(0), Default::default()); state.add_balance(&a, &U256::default(), CleanupMode::ForceCreate).unwrap(); // create an empty account @@ -1897,9 +1878,8 @@ mod tests { #[test] fn remove_from_database() { let a = Address::zero(); - let temp = RandomTempPath::new(); let (root, db) = { - let mut state = get_temp_state_in(temp.as_path()); + let mut state = get_temp_state(); state.inc_nonce(&a).unwrap(); state.commit().unwrap(); assert_eq!(state.exists(&a).unwrap(), true); @@ -1925,8 +1905,7 @@ mod tests { #[test] fn alter_balance() { - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); let a = Address::zero(); let b = 1u64.into(); state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap(); @@ -1947,8 +1926,7 @@ mod tests { #[test] fn alter_nonce() { - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); let a = Address::zero(); state.inc_nonce(&a).unwrap(); assert_eq!(state.nonce(&a).unwrap(), U256::from(1u64)); @@ -1964,8 +1942,7 @@ mod tests { #[test] fn balance_nonce() { - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); let a = Address::zero(); assert_eq!(state.balance(&a).unwrap(), U256::from(0u64)); assert_eq!(state.nonce(&a).unwrap(), U256::from(0u64)); @@ -1976,8 +1953,7 @@ mod tests { #[test] fn ensure_cached() { - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); let a = Address::zero(); state.require(&a, false).unwrap(); state.commit().unwrap(); @@ -1986,8 +1962,7 @@ mod tests { #[test] fn checkpoint_basic() { - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); let a = Address::zero(); state.checkpoint(); state.add_balance(&a, &U256::from(69u64), CleanupMode::NoEmpty).unwrap(); @@ -2003,8 +1978,7 @@ mod tests { #[test] fn checkpoint_nested() { - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); let a = Address::zero(); state.checkpoint(); state.checkpoint(); @@ -2018,16 +1992,14 @@ mod tests { #[test] fn create_empty() { - let mut state_result = get_temp_state(); - let mut state = state_result.reference_mut(); + let mut state = get_temp_state(); state.commit().unwrap(); assert_eq!(state.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); } #[test] fn should_not_panic_on_state_diff_with_storage() { - let state = get_temp_state(); - let mut state = state.reference().clone(); + let mut state = get_temp_state(); let a: Address = 0xa.into(); state.init_code(&a, b"abcdefg".to_vec()).unwrap();; diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index 2831d2f9b..a5823f50b 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -448,7 +448,8 @@ impl state::Backend for StateDB { fn is_known_null(&self, address: &Address) -> bool { trace!(target: "account_bloom", "Check account bloom: {:?}", address); let bloom = self.account_bloom.lock(); - !bloom.check(&*address.sha3()) + let is_null = !bloom.check(&*address.sha3()); + is_null } } @@ -463,8 +464,7 @@ mod tests { fn state_db_smoke() { init_log(); - let mut state_db_result = get_temp_state_db(); - let state_db = state_db_result.take(); + let state_db = get_temp_state_db(); let root_parent = H256::random(); let address = Address::random(); let h0 = H256::random(); diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index e61edd478..02db15617 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -72,8 +72,7 @@ fn should_return_registrar() { #[test] fn returns_state_root_basic() { - let client_result = generate_dummy_client(6); - let client = client_result.reference(); + let client = generate_dummy_client(6); let test_spec = get_test_spec(); let genesis_header = test_spec.genesis_header(); @@ -125,8 +124,7 @@ fn query_none_block() { #[test] fn query_bad_block() { - let client_result = get_test_client_with_blocks(vec![get_bad_state_dummy_block()]); - let client = client_result.reference(); + let client = get_test_client_with_blocks(vec![get_bad_state_dummy_block()]); let bad_block: Option<_> = client.block_header(BlockId::Number(1)); assert!(bad_block.is_none()); @@ -135,8 +133,7 @@ fn query_bad_block() { #[test] fn returns_chain_info() { let dummy_block = get_good_dummy_block(); - let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); - let client = client_result.reference(); + let client = get_test_client_with_blocks(vec![dummy_block.clone()]); let block = BlockView::new(&dummy_block); let info = client.chain_info(); assert_eq!(info.best_block_hash, block.header().hash()); @@ -145,8 +142,7 @@ fn returns_chain_info() { #[test] fn returns_logs() { let dummy_block = get_good_dummy_block(); - let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); - let client = client_result.reference(); + let client = get_test_client_with_blocks(vec![dummy_block.clone()]); let logs = client.logs(Filter { from_block: BlockId::Earliest, to_block: BlockId::Latest, @@ -160,14 +156,13 @@ fn returns_logs() { #[test] fn returns_logs_with_limit() { let dummy_block = get_good_dummy_block(); - let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); - let client = client_result.reference(); + let client = get_test_client_with_blocks(vec![dummy_block.clone()]); let logs = client.logs(Filter { from_block: BlockId::Earliest, to_block: BlockId::Latest, address: None, topics: vec![], - limit: Some(2), + limit: None, }); assert_eq!(logs.len(), 0); } @@ -175,8 +170,7 @@ fn returns_logs_with_limit() { #[test] fn returns_block_body() { let dummy_block = get_good_dummy_block(); - let client_result = get_test_client_with_blocks(vec![dummy_block.clone()]); - let client = client_result.reference(); + let client = get_test_client_with_blocks(vec![dummy_block.clone()]); let block = BlockView::new(&dummy_block); let body = client.block_body(BlockId::Hash(block.header().hash())).unwrap(); let body = body.rlp(); @@ -187,8 +181,7 @@ fn returns_block_body() { #[test] fn imports_block_sequence() { - let client_result = generate_dummy_client(6); - let client = client_result.reference(); + let client = generate_dummy_client(6); let block = client.block_header(BlockId::Number(5)).unwrap(); assert!(!block.into_inner().is_empty()); @@ -196,8 +189,7 @@ fn imports_block_sequence() { #[test] fn can_collect_garbage() { - let client_result = generate_dummy_client(100); - let client = client_result.reference(); + let client = generate_dummy_client(100); client.tick(); assert!(client.blockchain_cache_info().blocks < 100 * 1024); } @@ -205,19 +197,16 @@ fn can_collect_garbage() { #[test] fn can_generate_gas_price_median() { - let client_result = generate_dummy_client_with_data(3, 1, slice_into![1, 2, 3]); - let client = client_result.reference(); + let client = generate_dummy_client_with_data(3, 1, slice_into![1, 2, 3]); assert_eq!(Some(&U256::from(2)), client.gas_price_corpus(3).median()); - let client_result = generate_dummy_client_with_data(4, 1, slice_into![1, 4, 3, 2]); - let client = client_result.reference(); + let client = generate_dummy_client_with_data(4, 1, slice_into![1, 4, 3, 2]); assert_eq!(Some(&U256::from(3)), client.gas_price_corpus(3).median()); } #[test] fn can_generate_gas_price_histogram() { - let client_result = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]); - let client = client_result.reference(); + let client = generate_dummy_client_with_data(20, 1, slice_into![6354,8593,6065,4842,7845,7002,689,4958,4250,6098,5804,4320,643,8895,2296,8589,7145,2000,2512,1408]); let hist = client.gas_price_corpus(20).histogram(5).unwrap(); let correct_hist = ::stats::Histogram { bucket_bounds: vec_into![643, 2294, 3945, 5596, 7247, 8898], counts: vec![4,2,4,6,4] }; @@ -226,32 +215,29 @@ fn can_generate_gas_price_histogram() { #[test] fn empty_gas_price_histogram() { - let client_result = generate_dummy_client_with_data(20, 0, slice_into![]); - let client = client_result.reference(); + let client = generate_dummy_client_with_data(20, 0, slice_into![]); assert!(client.gas_price_corpus(20).histogram(5).is_none()); } #[test] fn corpus_is_sorted() { - let client_result = generate_dummy_client_with_data(2, 1, slice_into![U256::from_str("11426908979").unwrap(), U256::from_str("50426908979").unwrap()]); - let client = client_result.reference(); + let client = generate_dummy_client_with_data(2, 1, slice_into![U256::from_str("11426908979").unwrap(), U256::from_str("50426908979").unwrap()]); let corpus = client.gas_price_corpus(20); assert!(corpus[0] < corpus[1]); } #[test] fn can_handle_long_fork() { - let client_result = generate_dummy_client(1200); - let client = client_result.reference(); + let client = generate_dummy_client(1200); for _ in 0..20 { client.import_verified_blocks(); } assert_eq!(1200, client.chain_info().best_block_number); - push_blocks_to_client(client, 45, 1201, 800); - push_blocks_to_client(client, 49, 1201, 800); - push_blocks_to_client(client, 53, 1201, 600); + push_blocks_to_client(&client, 45, 1201, 800); + push_blocks_to_client(&client, 49, 1201, 800); + push_blocks_to_client(&client, 53, 1201, 600); for _ in 0..400 { client.import_verified_blocks(); @@ -262,8 +248,7 @@ fn can_handle_long_fork() { #[test] fn can_mine() { let dummy_blocks = get_good_dummy_block_seq(2); - let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]); - let client = client_result.reference(); + let client = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]); let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).close(); @@ -329,14 +314,13 @@ fn does_not_propagate_delayed_transactions() { value: 0.into(), data: Vec::new(), }.sign(secret, None), None); - let client_result = generate_dummy_client(1); - let client = client_result.reference(); + let client = generate_dummy_client(1); - client.miner().import_own_transaction(&**client, tx0).unwrap(); - client.miner().import_own_transaction(&**client, tx1).unwrap(); + client.miner().import_own_transaction(&*client, tx0).unwrap(); + client.miner().import_own_transaction(&*client, tx1).unwrap(); assert_eq!(0, client.ready_transactions().len()); assert_eq!(2, client.miner().pending_transactions().len()); - push_blocks_to_client(client, 53, 2, 2); + push_blocks_to_client(&client, 53, 2, 2); client.flush_queue(); assert_eq!(2, client.ready_transactions().len()); assert_eq!(2, client.miner().pending_transactions().len()); @@ -346,8 +330,7 @@ fn does_not_propagate_delayed_transactions() { fn transaction_proof() { use ::client::ProvingBlockChainClient; - let client_result = generate_dummy_client(0); - let client = client_result.reference(); + let client = generate_dummy_client(0); let address = Address::random(); let test_spec = Spec::new_test(); for _ in 0..20 { @@ -367,7 +350,7 @@ fn transaction_proof() { data: Vec::new(), }.fake_sign(address); - let proof = client.prove_transaction(transaction.clone(), BlockId::Latest).unwrap(); + let proof = client.prove_transaction(transaction.clone(), BlockId::Latest).unwrap().1; let backend = state::backend::ProofCheck::new(&proof); let mut factories = ::factory::Factories::default(); diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 70269b6e4..548187e48 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -27,10 +27,8 @@ use builtin::Builtin; use state::*; use evm::Schedule; use engines::Engine; -use env_info::EnvInfo; use ethereum; use ethereum::ethash::EthashParams; -use devtools::*; use miner::Miner; use header::Header; use transaction::{Action, Transaction, SignedTransaction}; @@ -73,7 +71,7 @@ impl Engine for TestEngine { self.engine.builtins() } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { + fn schedule(&self, _block_number: u64) -> Schedule { let mut schedule = Schedule::new_frontier(); schedule.max_depth = self.max_depth; schedule @@ -133,28 +131,26 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransa rlp.out() } -pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult> { +pub fn generate_dummy_client(block_number: u32) -> Arc { generate_dummy_client_with_spec_and_data(Spec::new_test, block_number, 0, &[]) } -pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult> { +pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc { generate_dummy_client_with_spec_and_data(Spec::new_null, block_number, txs_per_block, tx_gas_prices) } -pub fn generate_dummy_client_with_spec_and_data(get_test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult> where F: Fn()->Spec { +pub fn generate_dummy_client_with_spec_and_data(get_test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc where F: Fn()->Spec { generate_dummy_client_with_spec_accounts_and_data(get_test_spec, None, block_number, txs_per_block, tx_gas_prices) } -pub fn generate_dummy_client_with_spec_and_accounts(get_test_spec: F, accounts: Option>) -> GuardedTempResult> where F: Fn()->Spec { +pub fn generate_dummy_client_with_spec_and_accounts(get_test_spec: F, accounts: Option>) -> Arc where F: Fn()->Spec { generate_dummy_client_with_spec_accounts_and_data(get_test_spec, accounts, 0, 0, &[]) } -pub fn generate_dummy_client_with_spec_accounts_and_data(get_test_spec: F, accounts: Option>, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult> where F: Fn()->Spec { - let dir = RandomTempPath::new(); +pub fn generate_dummy_client_with_spec_accounts_and_data(get_test_spec: F, accounts: Option>, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> Arc where F: Fn()->Spec { let test_spec = get_test_spec(); - let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); - let client_db = Arc::new(Database::open(&db_config, dir.as_path().to_str().unwrap()).unwrap()); + let client_db = new_db(); let client = Client::new( ClientConfig::default(), @@ -165,8 +161,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data(get_test_spec: F, ac ).unwrap(); let test_engine = &*test_spec.engine; - let mut db_result = get_temp_state_db(); - let mut db = test_spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); + let mut db = test_spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let genesis_header = test_spec.genesis_header(); let mut rolling_timestamp = 40; @@ -205,7 +200,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data(get_test_spec: F, ac action: Action::Create, data: vec![], value: U256::zero(), - }.sign(kp.secret(), None), None).unwrap(); + }.sign(kp.secret(), Some(test_spec.network_id())), None).unwrap(); n += 1; } @@ -220,11 +215,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data(get_test_spec: F, ac } client.flush_queue(); client.import_verified_blocks(); - - GuardedTempResult::> { - _temp: dir, - result: Some(client) - } + client } pub fn push_blocks_to_client(client: &Arc, timestamp_salt: u64, starting_number: usize, block_number: usize) { @@ -256,11 +247,9 @@ pub fn push_blocks_to_client(client: &Arc, timestamp_salt: u64, starting } } -pub fn get_test_client_with_blocks(blocks: Vec) -> GuardedTempResult> { - let dir = RandomTempPath::new(); +pub fn get_test_client_with_blocks(blocks: Vec) -> Arc { let test_spec = get_test_spec(); - let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); - let client_db = Arc::new(Database::open(&db_config, dir.as_path().to_str().unwrap()).unwrap()); + let client_db = new_db(); let client = Client::new( ClientConfig::default(), @@ -277,23 +266,15 @@ pub fn get_test_client_with_blocks(blocks: Vec) -> GuardedTempResult> { - _temp: dir, - result: Some(client) - } + client } -fn new_db(path: &str) -> Arc { - Arc::new( - Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), path) - .expect("Opening database for tests should always work.") - ) +fn new_db() -> Arc { + Arc::new(::util::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))) } -pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult { - let temp = RandomTempPath::new(); - let db = new_db(temp.as_str()); +pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain { + let db = new_db(); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); let mut batch = db.transaction(); @@ -302,16 +283,11 @@ pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult { - _temp: temp, - result: Some(bc) - } + bc } -pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempResult { - let temp = RandomTempPath::new(); - let db = new_db(temp.as_str()); +pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain { + let db = new_db(); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); @@ -321,69 +297,29 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempRes bc.commit(); } db.write(batch).unwrap(); - - GuardedTempResult:: { - _temp: temp, - result: Some(bc) - } + bc } -pub fn generate_dummy_empty_blockchain() -> GuardedTempResult { - let temp = RandomTempPath::new(); - let db = new_db(temp.as_str()); +pub fn generate_dummy_empty_blockchain() -> BlockChain { + let db = new_db(); let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); - - GuardedTempResult:: { - _temp: temp, - result: Some(bc) - } + bc } -pub fn get_temp_state_db() -> GuardedTempResult { - let temp = RandomTempPath::new(); - let journal_db = get_temp_state_db_in(temp.as_path()); - - GuardedTempResult { - _temp: temp, - result: Some(journal_db) - } -} - -pub fn get_temp_state() -> GuardedTempResult> { - let temp = RandomTempPath::new(); - let journal_db = get_temp_state_db_in(temp.as_path()); - - GuardedTempResult { - _temp: temp, - result: Some(State::new(journal_db, U256::from(0), Default::default())), - } -} - -pub fn get_temp_mem_state() -> State<::state_db::StateDB> { - let journal_db = get_temp_mem_state_db(); +pub fn get_temp_state() -> State<::state_db::StateDB> { + let journal_db = get_temp_state_db(); State::new(journal_db, U256::from(0), Default::default()) } -pub fn get_temp_state_db_in(path: &Path) -> StateDB { - let db = new_db(path.to_str().expect("Only valid utf8 paths for tests.")); - let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, ::db::COL_STATE); - StateDB::new(journal_db, 5 * 1024 * 1024) -} - -pub fn get_temp_mem_state_db() -> StateDB { - let db = Arc::new(::util::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); +pub fn get_temp_state_db() -> StateDB { + let db = new_db(); let journal_db = journaldb::new(db, journaldb::Algorithm::EarlyMerge, ::db::COL_STATE); StateDB::new(journal_db, 5 * 1024 * 1024) } -pub fn get_temp_state_in(path: &Path) -> State<::state_db::StateDB> { - let journal_db = get_temp_state_db_in(path); - State::new(journal_db, U256::from(0), Default::default()) -} - pub fn get_good_dummy_block_seq(count: usize) -> Vec { let test_spec = get_test_spec(); - get_good_dummy_block_fork_seq(1, count, &test_spec.genesis_header().hash()) + get_good_dummy_block_fork_seq(1, count, &test_spec.genesis_header().hash()) } pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_hash: &H256) -> Vec { @@ -405,7 +341,6 @@ pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_h rolling_timestamp = rolling_timestamp + 10; r.push(create_test_block(&block_header)); - } r } diff --git a/ethcore/src/types/transaction.rs b/ethcore/src/types/transaction.rs index 79e27d97d..2c35400a8 100644 --- a/ethcore/src/types/transaction.rs +++ b/ethcore/src/types/transaction.rs @@ -19,13 +19,16 @@ use std::ops::Deref; use rlp::*; use util::sha3::Hashable; -use util::{H256, Address, U256, Bytes, HeapSizeOf}; +use util::{H256, Address, U256, Bytes, HeapSizeOf, Uint}; use ethkey::{Signature, Secret, Public, recover, public_to_address, Error as EthkeyError}; use error::*; use evm::Schedule; use header::BlockNumber; use ethjson; +/// Fake address for unsigned transactions as defined by EIP-86. +pub const UNSIGNED_SENDER: Address = ::util::H160([0xff; 20]); + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "ipc", binary)] /// Transaction action type. @@ -110,8 +113,8 @@ impl HeapSizeOf for Transaction { impl From for SignedTransaction { fn from(t: ethjson::state::Transaction) -> Self { let to: Option = t.to.into(); - let secret = Secret::from_slice(&t.secret.0).expect("Valid secret expected."); - Transaction { + let secret = t.secret.map(|s| Secret::from_slice(&s.0).expect("Valid secret expected.")); + let tx = Transaction { nonce: t.nonce.into(), gas_price: t.gas_price.into(), gas: t.gas_limit.into(), @@ -121,7 +124,11 @@ impl From for SignedTransaction { }, value: t.value.into(), data: t.data.into(), - }.sign(&secret, None) + }; + match secret { + Some(s) => tx.sign(&s, None), + None => tx.null_sign(1), + } } } @@ -180,8 +187,8 @@ impl Transaction { pub fn invalid_sign(self) -> UnverifiedTransaction { UnverifiedTransaction { unsigned: self, - r: U256::default(), - s: U256::default(), + r: U256::one(), + s: U256::one(), v: 0, hash: 0.into(), }.compute_hash() @@ -192,13 +199,28 @@ impl Transaction { SignedTransaction { transaction: UnverifiedTransaction { unsigned: self, - r: U256::default(), - s: U256::default(), + r: U256::one(), + s: U256::one(), v: 0, hash: 0.into(), }.compute_hash(), sender: from, - public: Public::default(), + public: None, + } + } + + /// Add EIP-86 compatible empty signature. + pub fn null_sign(self, network_id: u64) -> SignedTransaction { + SignedTransaction { + transaction: UnverifiedTransaction { + unsigned: self, + r: U256::zero(), + s: U256::zero(), + v: network_id, + hash: 0.into(), + }.compute_hash(), + sender: UNSIGNED_SENDER, + public: None, } } @@ -276,6 +298,11 @@ impl UnverifiedTransaction { self } + /// Checks is signature is empty. + pub fn is_unsigned(&self) -> bool { + self.r.is_zero() && self.s.is_zero() + } + /// Append object with a signature into RLP stream fn rlp_append_sealed_transaction(&self, s: &mut RlpStream) { s.begin_list(9); @@ -307,6 +334,7 @@ impl UnverifiedTransaction { /// The network ID, or `None` if this is a global transaction. pub fn network_id(&self) -> Option { match self.v { + v if self.is_unsigned() => Some(v), v if v > 36 => Some((v - 35) / 2), _ => None, } @@ -340,21 +368,33 @@ impl UnverifiedTransaction { // TODO: consider use in block validation. #[cfg(test)] #[cfg(feature = "json-tests")] - pub fn validate(self, schedule: &Schedule, require_low: bool, allow_network_id_of_one: bool) -> Result { - if require_low && !self.signature().is_low_s() { + pub fn validate(self, schedule: &Schedule, require_low: bool, allow_network_id_of_one: bool, allow_empty_signature: bool) -> Result { + let chain_id = if allow_network_id_of_one { Some(1) } else { None }; + self.verify_basic(require_low, chain_id, allow_empty_signature)?; + if !allow_empty_signature || !self.is_unsigned() { + self.recover_public()?; + } + if self.gas < U256::from(self.gas_required(&schedule)) { + return Err(TransactionError::InvalidGasLimit(::util::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into()) + } + Ok(self) + } + + /// Verify basic signature params. Does not attempt sender recovery. + pub fn verify_basic(&self, check_low_s: bool, chain_id: Option, allow_empty_signature: bool) -> Result<(), Error> { + if check_low_s && !(allow_empty_signature && self.is_unsigned()) { + self.check_low_s()?; + } + // EIP-86: Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account 0. + if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) { return Err(EthkeyError::InvalidSignature.into()) } - match self.network_id() { - None => {}, - Some(1) if allow_network_id_of_one => {}, + match (self.network_id(), chain_id) { + (None, _) => {}, + (Some(n), Some(m)) if n == m => {}, _ => return Err(TransactionError::InvalidNetworkId.into()), - } - self.recover_public()?; - if self.gas < U256::from(self.gas_required(&schedule)) { - Err(TransactionError::InvalidGasLimit(::util::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into()) - } else { - Ok(self) - } + }; + Ok(()) } } @@ -363,7 +403,7 @@ impl UnverifiedTransaction { pub struct SignedTransaction { transaction: UnverifiedTransaction, sender: Address, - public: Public, + public: Option, } impl HeapSizeOf for SignedTransaction { @@ -392,13 +432,21 @@ impl From for UnverifiedTransaction { impl SignedTransaction { /// Try to verify transaction and recover sender. pub fn new(transaction: UnverifiedTransaction) -> Result { - let public = transaction.recover_public()?; - let sender = public_to_address(&public); - Ok(SignedTransaction { - transaction: transaction, - sender: sender, - public: public, - }) + if transaction.is_unsigned() { + Ok(SignedTransaction { + transaction: transaction, + sender: UNSIGNED_SENDER, + public: None, + }) + } else { + let public = transaction.recover_public()?; + let sender = public_to_address(&public); + Ok(SignedTransaction { + transaction: transaction, + sender: sender, + public: Some(public), + }) + } } /// Returns transaction sender. @@ -407,9 +455,14 @@ impl SignedTransaction { } /// Returns a public key of the sender. - pub fn public_key(&self) -> Public { + pub fn public_key(&self) -> Option { self.public } + + /// Checks is signature is empty. + pub fn is_unsigned(&self) -> bool { + self.transaction.is_unsigned() + } } /// Signed Transaction that is a part of canon blockchain. @@ -435,6 +488,9 @@ impl LocalizedTransaction { if let Some(sender) = self.cached_sender { return sender; } + if self.is_unsigned() { + return UNSIGNED_SENDER.clone(); + } let sender = public_to_address(&self.recover_public() .expect("LocalizedTransaction is always constructed from transaction from blockchain; Blockchain only stores verified transactions; qed")); self.cached_sender = Some(sender); diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index 849f7caad..a5d8fe73f 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -34,4 +34,8 @@ impl Verifier for CanonVerifier { fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error> { verification::verify_block_final(expected, got) } + + fn verify_block_external(&self, header: &Header, bytes: &[u8], engine: &Engine) -> Result<(), Error> { + engine.verify_block_external(header, Some(bytes)) + } } diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index 2fcd877f5..8464ba1e2 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -34,4 +34,8 @@ impl Verifier for NoopVerifier { fn verify_block_final(&self, _expected: &Header, _got: &Header) -> Result<(), Error> { Ok(()) } + + fn verify_block_external(&self, _header: &Header, _bytes: &[u8], _engine: &Engine) -> Result<(), Error> { + Ok(()) + } } diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index e5dabd392..55b711c1c 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -27,4 +27,6 @@ pub trait Verifier: Send + Sync { fn verify_block_family(&self, header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error>; /// Do a final verification check for an enacted header vs its expected counterpart. fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error>; + /// Verify a block, inspecing external state. + fn verify_block_external(&self, header: &Header, bytes: &[u8], engine: &Engine) -> Result<(), Error>; } diff --git a/ethcrypto/src/lib.rs b/ethcrypto/src/lib.rs index ea0ea9754..4f14cf4d9 100644 --- a/ethcrypto/src/lib.rs +++ b/ethcrypto/src/lib.rs @@ -34,6 +34,9 @@ pub const KEY_LENGTH: usize = 32; pub const KEY_ITERATIONS: usize = 10240; pub const KEY_LENGTH_AES: usize = KEY_LENGTH / 2; +/// Default MAC to use (in RPC). +pub const DEFAULT_MAC: [u8; 2] = [0, 0]; + #[derive(PartialEq, Debug)] pub enum ScryptError { // log(N) < r / 16 diff --git a/ethkey/src/brain.rs b/ethkey/src/brain.rs index 5ed23b404..cf675a843 100644 --- a/ethkey/src/brain.rs +++ b/ethkey/src/brain.rs @@ -57,8 +57,8 @@ mod tests { #[test] fn test_brain() { let words = "this is sparta!".to_owned(); - let first_keypair = Brain(words.clone()).generate().unwrap(); - let second_keypair = Brain(words.clone()).generate().unwrap(); + let first_keypair = Brain::new(words.clone()).generate().unwrap(); + let second_keypair = Brain::new(words.clone()).generate().unwrap(); assert_eq!(first_keypair.secret(), second_keypair.secret()); } } diff --git a/ethkey/src/signature.rs b/ethkey/src/signature.rs index 347222287..0c9e41ef5 100644 --- a/ethkey/src/signature.rs +++ b/ethkey/src/signature.rs @@ -25,6 +25,7 @@ use rustc_serialize::hex::{ToHex, FromHex}; use bigint::hash::{H520, H256}; use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address}; +/// Signature encoded as RSV components #[repr(C)] pub struct Signature([u8; 65]); @@ -44,8 +45,32 @@ impl Signature { self.0[64] } + /// Encode the signature into VRS array (V altered to be in "Electrum" notation). + pub fn into_vrs(self) -> [u8; 65] { + let mut vrs = [0u8; 65]; + vrs[0] = self.v() + 27; + vrs[1..33].copy_from_slice(self.r()); + vrs[33..65].copy_from_slice(self.s()); + vrs + } + + /// Parse bytes as a signature encoded as VRS (V in "Electrum" notation). + /// May return empty (invalid) signature if given data has invalid length. + pub fn from_vrs(data: &[u8]) -> Self { + if data.len() != 65 || data[0] < 27 { + // fallback to empty (invalid) signature + return Signature::default(); + } + + let mut sig = [0u8; 65]; + sig[0..32].copy_from_slice(&data[1..33]); + sig[32..64].copy_from_slice(&data[33..65]); + sig[64] = data[0] - 27; + Signature(sig) + } + /// Create a signature object from the sig. - pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Signature { + pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Self { let mut sig = [0u8; 65]; sig[0..32].copy_from_slice(&r); sig[32..64].copy_from_slice(&s); @@ -222,6 +247,21 @@ mod tests { use {Generator, Random, Message}; use super::{sign, verify_public, verify_address, recover, Signature}; + #[test] + fn vrs_conversion() { + // given + let keypair = Random.generate().unwrap(); + let message = Message::default(); + let signature = sign(keypair.secret(), &message).unwrap(); + + // when + let vrs = signature.clone().into_vrs(); + let from_vrs = Signature::from_vrs(&vrs); + + // then + assert_eq!(signature, from_vrs); + } + #[test] fn signature_to_and_from_str() { let keypair = Random.generate().unwrap(); diff --git a/evmbin/src/ext.rs b/evmbin/src/ext.rs index a293ccc80..781120c36 100644 --- a/evmbin/src/ext.rs +++ b/evmbin/src/ext.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use std::collections::HashMap; use util::{U256, H256, Address, Bytes, trie}; use ethcore::client::EnvInfo; -use ethcore::evm::{self, Ext, ContractCreateResult, MessageCallResult, Schedule, CallType}; +use ethcore::evm::{self, Ext, ContractCreateResult, MessageCallResult, Schedule, CallType, CreateContractAddress}; pub struct FakeExt { schedule: Schedule, @@ -31,7 +31,7 @@ pub struct FakeExt { impl Default for FakeExt { fn default() -> Self { FakeExt { - schedule: Schedule::new_post_eip150(usize::max_value(), true, true, true), + schedule: Schedule::new_post_eip150(usize::max_value(), true, true, true, true), store: HashMap::new(), depth: 1, } @@ -68,7 +68,7 @@ impl Ext for FakeExt { unimplemented!(); } - fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8]) -> ContractCreateResult { + fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8], _address: CreateContractAddress) -> ContractCreateResult { unimplemented!(); } diff --git a/hash-fetch/src/client.rs b/hash-fetch/src/client.rs index 40682a89c..958fc7aa2 100644 --- a/hash-fetch/src/client.rs +++ b/hash-fetch/src/client.rs @@ -211,7 +211,7 @@ mod tests { } fn fetch_with_abort(&self, url: &str, _abort: fetch::Abort) -> Self::Result { - assert_eq!(url, "https://ethcore.io/assets/images/ethcore-black-horizontal.png"); + assert_eq!(url, "https://parity.io/assets/images/ethcore-black-horizontal.png"); future::ok(if self.return_success { let cursor = ::std::io::Cursor::new(b"result"); fetch::Response::from_reader(cursor) diff --git a/hash-fetch/src/urlhint.rs b/hash-fetch/src/urlhint.rs index 579c83845..156420dad 100644 --- a/hash-fetch/src/urlhint.rs +++ b/hash-fetch/src/urlhint.rs @@ -370,7 +370,7 @@ pub mod tests { // then assert_eq!(res, Some(URLHintResult::Content(Content { - url: "https://ethcore.io/assets/images/ethcore-black-horizontal.png".into(), + url: "https://parity.io/assets/images/ethcore-black-horizontal.png".into(), mime: mime!(Image/Png), owner: Address::from_str("deadcafebeefbeefcafedeaddeedfeedffffffff").unwrap(), }))) @@ -395,11 +395,11 @@ pub mod tests { #[test] fn should_guess_mime_type_from_url() { - let url1 = "https://ethcore.io/parity"; - let url2 = "https://ethcore.io/parity#content-type=image/png"; - let url3 = "https://ethcore.io/parity#something&content-type=image/png"; - let url4 = "https://ethcore.io/parity.png#content-type=image/jpeg"; - let url5 = "https://ethcore.io/parity.png"; + let url1 = "https://parity.io/parity"; + let url2 = "https://parity.io/parity#content-type=image/png"; + let url3 = "https://parity.io/parity#something&content-type=image/png"; + let url4 = "https://parity.io/parity.png#content-type=image/jpeg"; + let url5 = "https://parity.io/parity.png"; assert_eq!(guess_mime_type(url1), None); diff --git a/js/.gitignore b/js/.gitignore index 786a10498..555c4b4bb 100644 --- a/js/.gitignore +++ b/js/.gitignore @@ -8,4 +8,3 @@ docs .happypack .npmjs .eslintcache -yarn.lock diff --git a/js/package.json b/js/package.json index 4f4b33ab7..61f239cbd 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "1.7.53", + "version": "1.7.70", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", @@ -48,7 +48,7 @@ "ci:build:embed": "NODE_ENV=production EMBED=1 node webpack/embed", "start": "npm install && npm run build:lib && npm run build:dll && npm run start:app", "start:app": "node webpack/dev.server", - "clean": "rm -rf ./.build ./.coverage ./.happypack ./.npmjs ./build ./node_modules/.cache", + "clean": "rm -rf ./.build ./.coverage ./.happypack ./.npmjs ./build ./node_modules/.cache ./node_modules/@parity", "coveralls": "npm run testCoverage && coveralls < coverage/lcov.info", "lint": "npm run lint:css && npm run lint:js", "lint:cached": "npm run lint:css && npm run lint:js:cached", @@ -164,6 +164,7 @@ "blockies": "0.0.2", "brace": "0.9.0", "bytes": "2.4.0", + "date-difference": "1.0.0", "debounce": "1.0.0", "es6-error": "4.0.0", "es6-promise": "4.0.5", @@ -228,6 +229,7 @@ "web3": "0.17.0-beta", "whatwg-fetch": "2.0.1", "worker-loader": "^0.8.0", + "yarn": "^0.21.3", "zxcvbn": "4.4.1" } } diff --git a/js/src/3rdparty/email-verification/terms-of-service.js b/js/src/3rdparty/email-verification/terms-of-service.js index c5deb7ee4..8826be032 100644 --- a/js/src/3rdparty/email-verification/terms-of-service.js +++ b/js/src/3rdparty/email-verification/terms-of-service.js @@ -22,6 +22,6 @@ export default (
  • We collect your email address when you use this service. This is temporarily kept in memory, and then encrypted and stored in our EU servers. We only retain the cryptographic hash of the email address to prevent duplicated accounts. The cryptographic hash of your email address is also stored on the blockchain which is public by design. You consent to this use.
  • You pay a fee for the cost of this service using the account you want to verify.
  • Your email address is transmitted to a third party EU email verification service mailjet for the sole purpose of the email verification. You consent to this use. Mailjet's privacy policy is here: https://www.mailjet.com/privacy-policy.
  • -
  • Parity Technology Limited is registered in England and Wales under company number 09760015 and complies with the Data Protection Act 1998 (UK). You may contact us via email at admin@parity.io. Our general privacy policy can be found here: https://ethcore.io/legal.html.
  • +
  • Parity Technology Limited is registered in England and Wales under company number 09760015 and complies with the Data Protection Act 1998 (UK). You may contact us via email at admin@parity.io. Our general privacy policy can be found here: https://parity.io/legal.html.
  • ); diff --git a/js/src/3rdparty/etherscan/call.js b/js/src/3rdparty/etherscan/call.js index 6b72e1bea..069627d78 100644 --- a/js/src/3rdparty/etherscan/call.js +++ b/js/src/3rdparty/etherscan/call.js @@ -15,6 +15,7 @@ // along with Parity. If not, see . import { stringify } from 'qs'; +import { apiLink } from './links'; const options = { method: 'GET', @@ -24,31 +25,11 @@ const options = { }; export function call (module, action, _params, test, netVersion) { - let prefix = 'api.'; - - switch (netVersion) { - case '2': - case '3': - prefix = 'testnet.'; - break; - - case '42': - prefix = 'kovan.'; - break; - - case '0': - default: - if (test) { - prefix = 'testnet.'; - } - break; - } - const query = stringify(Object.assign({ module, action }, _params || {})); - return fetch(`https://${prefix}etherscan.io/api?${query}`, options) + return fetch(apiLink(query, test, netVersion), options) .then((response) => { if (!response.ok) { throw { code: response.status, message: response.statusText }; // eslint-disable-line diff --git a/js/src/3rdparty/etherscan/links.js b/js/src/3rdparty/etherscan/links.js index 8c9101268..3b08d60e8 100644 --- a/js/src/3rdparty/etherscan/links.js +++ b/js/src/3rdparty/etherscan/links.js @@ -15,28 +15,31 @@ // along with Parity. If not, see . // NOTE: Keep 'isTestnet' for backwards library compatibility -export const url = (isTestnet = false, netVersion = '0') => { - let prefix = ''; - - switch (netVersion) { - case '2': - case '3': - prefix = 'testnet.'; - break; - - case '42': - prefix = 'kovan.'; - break; - - case '0': - default: - if (isTestnet) { - prefix = 'testnet.'; - } - break; +const getUrlPrefix = (isTestnet = false, netVersion = '0', defaultPrefix = '') => { + if (isTestnet) { + return 'ropsten.'; } - return `https://${prefix}etherscan.io`; + switch (netVersion) { + case '1': + return defaultPrefix; + + case '3': + return 'ropsten.'; + + case '4': + return 'rinkeby.'; + + case '42': + return 'kovan.'; + + default: + return 'testnet.'; + } +}; + +export const url = (isTestnet = false, netVersion = '0', defaultPrefix = '') => { + return `https://${getUrlPrefix(isTestnet, netVersion, defaultPrefix)}etherscan.io`; }; export const txLink = (hash, isTestnet = false, netVersion = '0') => { @@ -46,3 +49,7 @@ export const txLink = (hash, isTestnet = false, netVersion = '0') => { export const addressLink = (address, isTestnet = false, netVersion = '0') => { return `${url(isTestnet, netVersion)}/address/${address}`; }; + +export const apiLink = (query, isTestnet = false, netVersion = '0') => { + return `${url(isTestnet, netVersion, 'api.')}/api?${query}`; +}; diff --git a/js/src/3rdparty/etherscan/links.spec.js b/js/src/3rdparty/etherscan/links.spec.js new file mode 100644 index 000000000..c906940cb --- /dev/null +++ b/js/src/3rdparty/etherscan/links.spec.js @@ -0,0 +1,57 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +const { url, txLink, addressLink, apiLink } = require('./links'); + +describe('etherscan/links', function () { + it('builds link with a prefix', () => { + expect(url(false, '1', 'api.')).to.be.equal('https://api.etherscan.io'); + }); + + it('builds link to main network', () => { + expect(url(false, '1')).to.be.equal('https://etherscan.io'); + }); + + it('builds link to ropsten', () => { + expect(url(false, '3')).to.be.equal('https://ropsten.etherscan.io'); + expect(url(true)).to.be.equal('https://ropsten.etherscan.io'); + }); + + it('builds link to kovan', () => { + expect(url(false, '42')).to.be.equal('https://kovan.etherscan.io'); + }); + + it('builds link to rinkeby', () => { + expect(url(false, '4')).to.be.equal('https://rinkeby.etherscan.io'); + }); + + it('builds link to the testnet selector for unknown networks', () => { + expect(url(false, '10042')).to.be.equal('https://testnet.etherscan.io'); + expect(url(false, '51224')).to.be.equal('https://testnet.etherscan.io'); + }); + + it('builds transaction link', () => { + expect(txLink('aTxHash', false, '1')).to.be.equal('https://etherscan.io/tx/aTxHash'); + }); + + it('builds address link', () => { + expect(addressLink('anAddress', false, '1')).to.be.equal('https://etherscan.io/address/anAddress'); + }); + + it('builds api link', () => { + expect(apiLink('answer=42', false, '1')).to.be.equal('https://api.etherscan.io/api?answer=42'); + }); +}); diff --git a/js/src/3rdparty/sms-verification/terms-of-service.js b/js/src/3rdparty/sms-verification/terms-of-service.js index 98acd2599..9451a382b 100644 --- a/js/src/3rdparty/sms-verification/terms-of-service.js +++ b/js/src/3rdparty/sms-verification/terms-of-service.js @@ -22,6 +22,6 @@ export default (
  • We collect your phone number when you use this service. This is temporarily kept in memory, and then encrypted and stored in our EU servers. We only retain the cryptographic hash of the number to prevent duplicated accounts. You consent to this use.
  • You pay a fee for the cost of this service using the account you want to verify.
  • Your phone number is transmitted to a third party US SMS verification service Twilio for the sole purpose of the SMS verification. You consent to this use. Twilio’s privacy policy is here: https://www.twilio.com/legal/privacy/developer.
  • -
  • Parity Technology Limited is registered in England and Wales under company number 09760015 and complies with the Data Protection Act 1998 (UK). You may contact us via email at admin@parity.io. Our general privacy policy can be found here: https://ethcore.io/legal.html.
  • +
  • Parity Technology Limited is registered in England and Wales under company number 09760015 and complies with the Data Protection Act 1998 (UK). You may contact us via email at admin@parity.io. Our general privacy policy can be found here: https://parity.io/legal.html.
  • ); diff --git a/js/src/abi/decoder/decoder.js b/js/src/abi/decoder/decoder.js index 9cb07e3d7..6922c91e8 100644 --- a/js/src/abi/decoder/decoder.js +++ b/js/src/abi/decoder/decoder.js @@ -113,7 +113,15 @@ export default class Decoder { const str = taken.bytes.map((code) => String.fromCharCode(code)).join(''); - return new DecodeResult(new Token(param.type, utf8.decode(str)), offset + 1); + let decoded; + + try { + decoded = utf8.decode(str); + } catch (error) { + decoded = str; + } + + return new DecodeResult(new Token(param.type, decoded), offset + 1); case 'array': lengthOffset = asU32(Decoder.peek(slices, offset)).div(32).toNumber(); diff --git a/js/src/abi/decoder/decoder.spec.js b/js/src/abi/decoder/decoder.spec.js index 1f27a3e65..5065be3a7 100644 --- a/js/src/abi/decoder/decoder.spec.js +++ b/js/src/abi/decoder/decoder.spec.js @@ -38,6 +38,7 @@ describe('abi/decoder/Decoder', () => { const int1 = '0111111111111111111111111111111111111111111111111111111111111111'; const intn = 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85'; const string1 = '6761766f66796f726b0000000000000000000000000000000000000000000000'; + const string2 = '4665726ee16e64657a0000000000000000000000000000000000000000000000'; const tokenAddress1 = new Token('address', `0x${address1.slice(-40)}`); const tokenAddress2 = new Token('address', `0x${address2.slice(-40)}`); const tokenAddress3 = new Token('address', `0x${address3.slice(-40)}`); @@ -53,6 +54,7 @@ describe('abi/decoder/Decoder', () => { const tokenUint1 = new Token('uint', new BigNumber(int1, 16)); const tokenUintn = new Token('uint', new BigNumber(intn, 16)); const tokenString1 = new Token('string', 'gavofyork'); + const tokenString2 = new Token('string', 'Fernández'); const slices = [ address1, address2, address3, address4 ]; describe('peek', () => { @@ -160,6 +162,12 @@ describe('abi/decoder/Decoder', () => { ).to.deep.equal(tokenString1); }); + it('decodes utf8-invalid string', () => { + expect( + Decoder.decodeParam(new ParamType('string'), [padU32(0x20), padU32(9), string2], 0).token + ).to.deep.equal(tokenString2); + }); + it('decodes string (indexed)', () => { expect( Decoder.decodeParam(new ParamType('string', null, 0, true), [bytes1], 0) diff --git a/js/src/abi/spec/event/event.js b/js/src/abi/spec/event/event.js index 071a73965..604f58cb1 100644 --- a/js/src/abi/spec/event/event.js +++ b/js/src/abi/spec/event/event.js @@ -99,15 +99,15 @@ export default class Event { const namedTokens = {}; topicParams.forEach((param, idx) => { - namedTokens[param.name] = topicTokens[idx]; + namedTokens[param.name || idx] = topicTokens[idx]; }); dataParams.forEach((param, idx) => { - namedTokens[param.name] = dataTokens[idx]; + namedTokens[param.name || idx] = dataTokens[idx]; }); const inputParamTypes = this.inputParamTypes(); const decodedParams = this.inputParamNames() - .map((name, idx) => new DecodedLogParam(name, inputParamTypes[idx], namedTokens[name])); + .map((name, idx) => new DecodedLogParam(name, inputParamTypes[idx], namedTokens[name || idx])); return new DecodedLog(decodedParams, address); } diff --git a/js/src/api/api.js b/js/src/api/api.js index 2c102086f..526ecbf1b 100644 --- a/js/src/api/api.js +++ b/js/src/api/api.js @@ -59,7 +59,8 @@ export default class Api extends EventEmitter { } return null; - }); + }) + .catch(() => null); transport.addMiddleware(middleware); } diff --git a/js/src/api/contract/contract.js b/js/src/api/contract/contract.js index 2156b8af1..0aff05684 100644 --- a/js/src/api/contract/contract.js +++ b/js/src/api/contract/contract.js @@ -182,10 +182,11 @@ export default class Contract { log.params = {}; log.event = event.name; - decoded.params.forEach((param) => { + decoded.params.forEach((param, index) => { const { type, value } = param.token; + const key = param.name || index; - log.params[param.name] = { type, value }; + log.params[key] = { type, value }; }); return log; diff --git a/js/src/api/format/output.js b/js/src/api/format/output.js index df40b59a0..7bf39d17c 100644 --- a/js/src/api/format/output.js +++ b/js/src/api/format/output.js @@ -92,6 +92,16 @@ export function outChainStatus (status) { } export function outDate (date) { + if (typeof date.toISOString === 'function') { + return date; + } + + try { + if (typeof date === 'string' && (new Date(date)).toISOString() === date) { + return new Date(date); + } + } catch (error) {} + return new Date(outNumber(date).toNumber() * 1000); } diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js index 16b14eaef..674091563 100644 --- a/js/src/api/rpc/parity/parity.js +++ b/js/src/api/rpc/parity/parity.js @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { - inAddress, inAddresses, inData, inHex, inNumber16, inOptions, inBlockNumber, inDeriveHash, inDeriveIndex -} from '../../format/input'; -import { outAccountInfo, outAddress, outAddresses, outChainStatus, outHistogram, outHwAccountInfo, outNodeKind, outNumber, outPeers, outRecentDapps, outTransaction, outVaultMeta } from '../../format/output'; +import { inAddress, inAddresses, inBlockNumber, inData, inDeriveHash, inDeriveIndex, inHex, inNumber16, inOptions } from '../../format/input'; +import { outAccountInfo, outAddress, outAddresses, outBlock, outChainStatus, outHistogram, outHwAccountInfo, outNodeKind, outNumber, outPeers, outRecentDapps, outTransaction, outVaultMeta } from '../../format/output'; export default class Parity { constructor (transport) { @@ -72,11 +70,21 @@ export default class Parity { .execute('parity_checkRequest', inNumber16(requestId)); } + cidV0 (data) { + return this._transport + .execute('parity_cidV0', inData(data)); + } + closeVault (vaultName) { return this._transport .execute('parity_closeVault', vaultName); } + composeTransaction (options) { + return this._transport + .execute('parity_composeTransaction', inOptions(options)); + } + consensusCapability () { return this._transport .execute('parity_consensusCapability'); @@ -189,6 +197,12 @@ export default class Parity { .execute('parity_generateSecretPhrase'); } + getBlockHeaderByNumber (blockNumber = 'latest') { + return this._transport + .execute('parity_getBlockHeaderByNumber', inBlockNumber(blockNumber)) + .then(outBlock); + } + getDappAddresses (dappId) { return this._transport .execute('parity_getDappAddresses', dappId) diff --git a/js/src/contracts/tokenreg.js b/js/src/contracts/tokenreg.js index 22e3c834d..2bbf639bf 100644 --- a/js/src/contracts/tokenreg.js +++ b/js/src/contracts/tokenreg.js @@ -27,7 +27,7 @@ export default class TokenReg { } getInstance () { - return this.getContract().instance; + return this.getContract().then((contract) => contract.instance); } tokenCount () { diff --git a/js/src/dapps/registry/Events/actions.js b/js/src/dapps/registry/Events/actions.js index 2b15b0f13..e1f316718 100644 --- a/js/src/dapps/registry/Events/actions.js +++ b/js/src/dapps/registry/Events/actions.js @@ -43,7 +43,7 @@ export const subscribe = (name, from = 0, to = 'pending') => events.forEach((e) => { Promise.all([ - api.eth.getBlockByNumber(e.blockNumber), + api.parity.getBlockHeaderByNumber(e.blockNumber), api.eth.getTransactionByHash(e.transactionHash) ]) .then(([block, tx]) => { diff --git a/js/src/dapps/signaturereg/services.js b/js/src/dapps/signaturereg/services.js index d9c60da6b..9c01e49fb 100644 --- a/js/src/dapps/signaturereg/services.js +++ b/js/src/dapps/signaturereg/services.js @@ -158,7 +158,7 @@ export function attachEvents (contract, callback) { } export function getBlock (blockNumber) { - return api.eth.getBlockByNumber(blockNumber); + return api.parity.getBlockHeaderByNumber(blockNumber); } export function callRegister (instance, id, options = {}) { diff --git a/js/src/dapps/tokendeploy/Deploy/Event/event.js b/js/src/dapps/tokendeploy/Deploy/Event/event.js index 4fa0726da..9503c67c2 100644 --- a/js/src/dapps/tokendeploy/Deploy/Event/event.js +++ b/js/src/dapps/tokendeploy/Deploy/Event/event.js @@ -94,7 +94,7 @@ export default class Event extends Component { Promise .all([ - api.eth.getBlockByNumber(event.blockNumber), + api.parity.getBlockHeaderByNumber(event.blockNumber), getCoin(event.params.tokenreg, event.params.coin) ]) .then(([block, coin]) => { diff --git a/js/src/dapps/tokendeploy/Transfer/Event/event.js b/js/src/dapps/tokendeploy/Transfer/Event/event.js index 623220baf..bc28bd8b1 100644 --- a/js/src/dapps/tokendeploy/Transfer/Event/event.js +++ b/js/src/dapps/tokendeploy/Transfer/Event/event.js @@ -97,8 +97,8 @@ export default class Event extends Component { return; } - api.eth - .getBlockByNumber(event.blockNumber) + api.parity + .getBlockHeaderByNumber(event.blockNumber) .then((block) => { this.setState({ block }); }); diff --git a/js/src/i18n/constants.js b/js/src/i18n/constants.js index 6b4d7dafd..54693f81b 100644 --- a/js/src/i18n/constants.js +++ b/js/src/i18n/constants.js @@ -17,7 +17,7 @@ const DEFAULT_LOCALE = 'en'; const DEFAULT_LOCALES = process.env.NODE_ENV === 'production' ? ['en'] - : ['en', 'de', 'nl', 'zh']; + : ['en', 'de', 'nl', 'zh', 'zh-Hant-TW']; const LS_STORE_KEY = '_parity::locale'; export { diff --git a/js/src/i18n/languages.js b/js/src/i18n/languages.js index b178fe4c2..65265b690 100644 --- a/js/src/i18n/languages.js +++ b/js/src/i18n/languages.js @@ -18,5 +18,6 @@ export default { de: 'Deutsch', en: 'English', nl: 'Nederlands', - zh: '简体中文' + zh: '简体中文', + 'zh-Hant-TW': '繁體中文' }; diff --git a/js/src/i18n/nl/account.js b/js/src/i18n/nl/account.js index 57701292a..ee211bbca 100755 --- a/js/src/i18n/nl/account.js +++ b/js/src/i18n/nl/account.js @@ -16,13 +16,17 @@ export default { button: { - delete: `verwijder account`, + delete: `verwijder`, edit: `bewerk`, + faucet: `Kovan ETH`, password: `wachtwoord`, shapeshift: `shapeshift`, transfer: `verzend`, verify: `verifieer` }, + hardware: { + confirmDelete: `Weet je zeker dat je de volgende hardware adressen van je account lijst wilt verwijderen?` + }, header: { outgoingTransactions: `{count} uitgaande transacties`, uuid: `uuid: {uuid}` diff --git a/js/src/i18n/nl/accounts.js b/js/src/i18n/nl/accounts.js index 315324632..e213bddb2 100755 --- a/js/src/i18n/nl/accounts.js +++ b/js/src/i18n/nl/accounts.js @@ -16,8 +16,8 @@ export default { button: { - newAccount: `nieuw account`, - newWallet: `nieuw wallet`, + newAccount: `account`, + newWallet: `wallet`, vaults: `kluizen` }, summary: { @@ -27,5 +27,8 @@ export default { tooltip: { actions: `voor de huidige weergave zijn koppelingen beschikbaar op de werkbalk voor snelle toegang: het uitvoeren van acties of het creëren van een nieuw item`, overview: `hier vind je een overzichtelijke weergave van je accounts, waarin je meta informatie kunt bewerken en transacties kunt uitvoeren en bekijken` + }, + tooltips: { + owner: `{name} (eigenaar)` } }; diff --git a/js/src/i18n/nl/addAddress.js b/js/src/i18n/nl/addAddress.js index 1b2281888..e048988e9 100755 --- a/js/src/i18n/nl/addAddress.js +++ b/js/src/i18n/nl/addAddress.js @@ -19,6 +19,7 @@ export default { add: `Adres Opslaan`, close: `Annuleer` }, + header: `Om een nieuwe invoer aan je adresboek toe te voegen, heb je het netwerk adres van het account nodig en kun je optioneel een beschrijving toevoegen. Zodra de nieuwe invoer is toegevoegd, zal het in je adresboek verschijnen.`, input: { address: { hint: `het netwerk adres van het item`, @@ -33,5 +34,5 @@ export default { label: `Adres Naam` } }, - label: `voeg opgeslagen adres toe` + label: `voeg een opgeslagen adres toe` }; diff --git a/js/src/i18n/nl/address.js b/js/src/i18n/nl/address.js new file mode 100644 index 000000000..fc9d2eab1 --- /dev/null +++ b/js/src/i18n/nl/address.js @@ -0,0 +1,28 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + edit: `bewerken`, + forget: `vergeten`, + save: `opslaan` + }, + delete: { + confirmInfo: `Weet je zeker dat je het volgende adres uit je adresboek wilt verwijderen?`, + title: `bevestig verwijderen` + }, + title: `Adres Informatie` +}; diff --git a/js/src/i18n/nl/addresses.js b/js/src/i18n/nl/addresses.js new file mode 100644 index 000000000..c16c5f234 --- /dev/null +++ b/js/src/i18n/nl/addresses.js @@ -0,0 +1,25 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + add: `adres` + }, + errors: { + invalidFile: `Het opgegeven bestand is ongeldig...` + }, + title: `Opgeslagen Adressen` +}; diff --git a/js/src/i18n/nl/application.js b/js/src/i18n/nl/application.js index 1a6b2ee5c..bcb110b88 100755 --- a/js/src/i18n/nl/application.js +++ b/js/src/i18n/nl/application.js @@ -15,6 +15,9 @@ // along with Parity. If not, see . export default { + frame: { + error: `FOUT: Deze applicatie kan niet en zou niet geladen moeten worden in een embedded iFrame` + }, status: { consensus: { capable: `Capable`, diff --git a/js/src/i18n/nl/contract.js b/js/src/i18n/nl/contract.js index 5f2ca39cc..9818f5edd 100755 --- a/js/src/i18n/nl/contract.js +++ b/js/src/i18n/nl/contract.js @@ -15,5 +15,27 @@ // along with Parity. If not, see . export default { - minedBlock: `Opgenomen in blok #{blockNumber}` + buttons: { + close: `Sluit`, + details: `details`, + edit: `bewerken`, + execute: `uitvoeren`, + forget: `vergeten` + }, + details: { + title: `contract details` + }, + events: { + eventPending: `pending`, + noEvents: `Er zijn vanuit dit contract nog geen events verzonden.`, + title: `events` + }, + minedBlock: `Opgenomen in blok #{blockNumber}`, + queries: { + buttons: { + query: `Query` + }, + title: `queries` + }, + title: `Contract Informatie` }; diff --git a/js/src/i18n/nl/contracts.js b/js/src/i18n/nl/contracts.js new file mode 100644 index 000000000..18ab842a0 --- /dev/null +++ b/js/src/i18n/nl/contracts.js @@ -0,0 +1,28 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + deploy: `publiceer`, + develop: `ontwikkel`, + watch: `bekijk` + }, + sortOrder: { + date: `datum`, + minedBlock: `opgenomen blok` + }, + title: `Contracten` +}; diff --git a/js/src/i18n/nl/createAccount.js b/js/src/i18n/nl/createAccount.js index 69585df35..98b7ac26b 100755 --- a/js/src/i18n/nl/createAccount.js +++ b/js/src/i18n/nl/createAccount.js @@ -20,10 +20,6 @@ export default { hint: `Het netwerk adres van het account`, label: `adres` }, - name: { - hint: `Een beschrijvende naam van het account`, - label: `account naam` - }, phrase: { hint: `De account herstel zin`, label: `Eigenaar's herstel zin (houd deze woorden veilig en prive want hiermee kun je volledige, ongelimiteerde toegang tot het account verkrijgen).` @@ -35,31 +31,38 @@ export default { button: { back: `Terug`, cancel: `Annuleer`, - close: `Sluit`, create: `Aanmaken`, + done: `Klaar`, import: `Importeer`, next: `Volgende`, print: `Herstel zin afdrukken` }, creationType: { fromGeth: { - label: `Importeer accounts uit Geth keystore` + description: `Importeer accounts uit Geth keystore met het originele wachtwoord`, + label: `Geth keystore` }, fromJSON: { - label: `Importeer account uit een opgeslagen JSON file` + description: `Importeer account uit een JSON sleutelbestand met het originele wachtwoord`, + label: `JSON bestand` }, fromNew: { - label: `Handmatig account aanmaken` + description: `Selecteer je identiteits-icoon en kies je wachtwoord`, + label: `Nieuw Account` }, fromPhrase: { - label: `Herstel account met een herstel zin` + description: `Herstel je account met een eerder bewaarde herstel zin en een nieuw wachtwoord`, + label: `Herstel zin` }, fromPresale: { - label: `Importeer account van een Ethereum voor-verkoop (pre-sale) wallet` + description: `Importeer een Ethereum voor-verkoop (pre-sale) wallet bestand met het originele wachtwoord`, + label: `voor-verkoop wallet` }, fromRaw: { - label: `Importeer een prive sleutel (raw private key)` - } + description: `Importeer een eerder gemaakte prive sleutel (raw private key) met een nieuw wachtwoord`, + label: `Prive sleutel` + }, + info: `Selecteer de manier waarop je je account wilt aanmaken of importeren. Maak een nieuw account aan met een naam en wachtwoord, of importeer/herstel een bestaand account vanuit verschillende bronnen zoals een herstel zin of een sleutelbestand. Met behulp van deze wizard word je door het proces begeleid om een account aan te maken.` }, newAccount: { hint: { @@ -80,6 +83,7 @@ export default { } }, newGeth: { + available: `Er zijn momenteel {count} importeerbare sleutels (keys) beschikbaar vanuit Geth keystore, welke nog niet in je Parity installatie beschikbaar zijn. Selecteer de accounts die je wilt importeren en ga verder naar de volgende stap om het importeren te voltooien.`, noKeys: `Er zijn momenteel geen importeerbare sleutels (keys) beschikbaar in de Geth keystore; of ze zijn al in je Parity installatie beschikbaar` }, newImport: { diff --git a/js/src/i18n/nl/createWallet.js b/js/src/i18n/nl/createWallet.js index 6acd2e2c8..9f3419497 100644 --- a/js/src/i18n/nl/createWallet.js +++ b/js/src/i18n/nl/createWallet.js @@ -53,7 +53,7 @@ export default { label: `wallet naam` }, ownerMulti: { - hint: `het eigenaars account van dit contract`, + hint: `het account wat eigenaar is van dit contract`, label: `van account (contract eigenaar)` }, ownersMulti: { @@ -80,6 +80,7 @@ export default { }, states: { completed: `Het contract is succesvol aangemaakt`, + confirmationNeeded: `Voor het aanmaken van dit contract is bevestiging door andere eigenaren van het Wallet vereist`, preparing: `Transactie aan het voorbereiden voor verzending op het netwerk`, validatingCode: `De contract code van het aangemaakte contract wordt gevalideerd`, waitingConfirm: `Wachten tot de transactie bevestigd is in de Parity Secure Signer`, @@ -93,7 +94,7 @@ export default { }, type: { multisig: { - description: `Creëer/Maak een {link} Wallet aan`, + description: `Maak een {link} Wallet aan`, label: `Multi-Sig wallet`, link: `standaard multi-signature` }, diff --git a/js/src/i18n/nl/dapps.js b/js/src/i18n/nl/dapps.js index 3c7cf6d7b..6949c4d48 100644 --- a/js/src/i18n/nl/dapps.js +++ b/js/src/i18n/nl/dapps.js @@ -36,11 +36,10 @@ export default { }, external: { accept: `Ik begrijp dat deze toepassingen niet bij Parity zijn aangesloten`, - warning: `Deze applicaties gepuliceerd door derde partijen zijn niet bij Parity aangesloten, noch worden ze gepubliceerd door Parity. Alle applicaties blijven in beheer van hun eigen auteur. Zorg ervoor dat je snapt wat het doel van een applicatie is voordat je ermee aan de slag gaat.` + warning: `Deze applicaties zijn gepuliceerd door derde partijen welke niet verwant zijn aan Parity en zijn dus ook niet door Parity uitgebracht. Alle applicaties blijven in beheer van hun eigen auteur. Zorg ervoor dat je snapt wat het doel van een applicatie is voordat je ermee aan de slag gaat.` }, label: `Gedecentraliseerde Applicaties`, permissions: { - description: `{activeIcon} account is beschikbaar voor applicaties, {defaultIcon} account is het standaard account`, label: `zichtbare dapp accounts` } }; diff --git a/js/src/i18n/nl/deployContract.js b/js/src/i18n/nl/deployContract.js index 478992464..042d52276 100644 --- a/js/src/i18n/nl/deployContract.js +++ b/js/src/i18n/nl/deployContract.js @@ -37,6 +37,13 @@ export default { hint: `het account wat eigenaar is van dit contract`, label: `van account (contract eigenaar)` }, + advanced: { + label: `geavanceerde verzend opties` + }, + amount: { + hint: `de naar het contract te verzenden hoeveelheid`, + label: `te verzenden hoeveelheid (in {tag})` + }, code: { hint: `de gecompileerde code van het aan te maken contract`, label: `code` @@ -65,6 +72,7 @@ export default { }, state: { completed: `Het contract is succesvol aangemaakt`, + confirmationNeeded: `Deze actie vereist de bevestiging van de andere eigenaren van het contract`, preparing: `Transactie aan het voorbereiden om te verzenden op het netwerk`, validatingCode: `De contract code van het aangemaakte contract valideren`, waitReceipt: `Wachten tot het aanmaken van het contract bevestigd is`, @@ -74,6 +82,7 @@ export default { completed: `voltooid`, deployment: `aangemaakt`, details: `contract details`, + extras: `extra informatie`, failed: `aanmaken mislukt`, parameters: `contract parameters`, rejected: `afgewezen` diff --git a/js/src/i18n/nl/faucet.js b/js/src/i18n/nl/faucet.js new file mode 100644 index 000000000..f35acc0b7 --- /dev/null +++ b/js/src/i18n/nl/faucet.js @@ -0,0 +1,28 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + close: `sluit`, + done: `klaar`, + request: `verzoek` + }, + summary: { + done: `Jouw Kovan ETH is aangevraagd bij het faucet, wat reageerde met het volgende bericht -`, + info: `Om een hoeveelheid Kovan ETH aan te vragen voor dit adres, moet je ervoor zorgen dat het adres op het mainnet sms-geverifieerd is. Zodra je dit uitvoert, zal het faucet Kovan ETH naar je huidige account verzenden.` + }, + title: `Kovan ETH Faucet` +}; diff --git a/js/src/i18n/nl/firstRun.js b/js/src/i18n/nl/firstRun.js index d182c76e1..9c7c4cf5d 100755 --- a/js/src/i18n/nl/firstRun.js +++ b/js/src/i18n/nl/firstRun.js @@ -17,16 +17,33 @@ export default { button: { close: `Sluiten`, - create: `creëer`, - next: `volgende`, + create: `Creëer`, + next: `Volgende`, print: `Woorden Afdrukken`, skip: `Overslaan` }, + completed: { + congrats: `Gefeliciteerd! Je node configuratie is succesvol afgerond en het programma is klaar voor gebruikt.`, + next: `Om je snel aan de slag te laten gaan krijg je in de volgende stap een korte algemene inleiding in het gebruik van het programma en lopen we door de beschikbare funcies.` + }, title: { completed: `voltooid`, newAccount: `nieuw account`, recovery: `herstelzin`, terms: `voorwaarden`, welcome: `welkom` + }, + tnc: { + accept: `Ik accepteer de voorwaarden en condities` + }, + welcome: { + description: `Als onderdeel van een nieuwe installatie, begeleiden we je in de enkele hierna volgende stappen met het configureren van je Parity node en jouw bijbehorende accounts. Ons doel hiervan is om het je zo gemakkelijk mogelijk te maken and zodat je binnen de kortste tijd klaar bent voor gebruik, dus heb even geduld en blijf bij ons. Zodra je de wizard voltooid hebt, heb je -`, + greeting: `Welkom bij Parity, de snelste en makkelijkste manier om je eigen node te draaien.`, + next: `Klik volgende om door te gaan.`, + step: { + account: `Je eerste Parity account aangemaakt;`, + privacy: `Onze privacybeleid en bedrijfsvoorwaarden begrepen;`, + recovery: `De mogelijkheid om je account te herstellen.` + } } }; diff --git a/js/src/i18n/nl/index.js b/js/src/i18n/nl/index.js index 281e9974c..0d11be8f1 100755 --- a/js/src/i18n/nl/index.js +++ b/js/src/i18n/nl/index.js @@ -18,10 +18,13 @@ import account from './account'; import accounts from './accounts'; import addAddress from './addAddress'; import addContract from './addContract'; +import address from './address'; +import addresses from './addresses'; import addressSelect from './addressSelect'; import application from './application'; import connection from './connection'; import contract from './contract'; +import contracts from './contracts'; import createAccount from './createAccount'; import createWallet from './createWallet'; import dapp from './dapp'; @@ -32,31 +35,41 @@ import editMeta from './editMeta'; import errors from './errors'; import executeContract from './executeContract'; import extension from './extension'; +import faucet from './faucet'; import firstRun from './firstRun'; import home from './home'; import loadContract from './loadContract'; import parityBar from './parityBar'; import passwordChange from './passwordChange'; +import saveContract from './saveContract'; import settings from './settings'; import shapeshift from './shapeshift'; +import signer from './signer'; +import status from './status'; import tabBar from './tabBar'; import transfer from './transfer'; import txEditor from './txEditor'; import ui from './ui'; import upgradeParity from './upgradeParity'; import vaults from './vaults'; +import verification from './verification'; +import wallet from './wallet'; import walletSettings from './walletSettings'; import web from './web'; +import writeContract from './writeContract'; export default { account, accounts, addAddress, addContract, + address, + addresses, addressSelect, application, connection, contract, + contracts, createAccount, createWallet, dapp, @@ -67,19 +80,26 @@ export default { errors, executeContract, extension, + faucet, firstRun, home, loadContract, parityBar, passwordChange, + saveContract, settings, shapeshift, + signer, + status, tabBar, transfer, txEditor, ui, upgradeParity, vaults, + verification, + wallet, walletSettings, - web + web, + writeContract }; diff --git a/js/src/i18n/nl/passwordChange.js b/js/src/i18n/nl/passwordChange.js index c59e50eed..eca3fd919 100644 --- a/js/src/i18n/nl/passwordChange.js +++ b/js/src/i18n/nl/passwordChange.js @@ -30,6 +30,7 @@ export default { label: `nieuw wachtwoord` }, passwordHint: { + display: `Hint {hint}`, hint: `hint voor het nieuwe wachtwoord`, label: `(optioneel) nieuwe wachtwoord hint` }, diff --git a/js/src/i18n/nl/saveContract.js b/js/src/i18n/nl/saveContract.js new file mode 100644 index 000000000..e51a3be3d --- /dev/null +++ b/js/src/i18n/nl/saveContract.js @@ -0,0 +1,27 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + cancel: `Annuleer`, + save: `Opslaan` + }, + name: { + hint: `kies een naam voor dit contract`, + label: `contract naam` + }, + title: `contract opslaan` +}; diff --git a/js/src/i18n/nl/settings.js b/js/src/i18n/nl/settings.js index 81f485696..f6705df78 100644 --- a/js/src/i18n/nl/settings.js +++ b/js/src/i18n/nl/settings.js @@ -22,6 +22,18 @@ export default { label: `achtergrond` }, parity: { + chains: { + chain_classic: `Parity synchroniseert met het Ethereum Classic netwerk`, + chain_dev: `Parity gebruikt een lokale ontwikkelaars chain`, + chain_expanse: `Parity synchroniseert met het Expanse netwerk`, + chain_foundation: `Parity synchroniseert met het Ethereum netwerk wat door de Ethereum Foundation is uitgebracht`, + chain_kovan: `Parity synchroniseert met het Kovan test netwerk`, + chain_olympic: `Parity synchroniseert met het Olympic test netwerk`, + chain_ropsten: `Parity synchroniseert met het Ropsten test netwerk`, + cmorden_kovan: `Parity synchroniseert met het Morden (Classic) test netwerk`, + hint: `de chain waarmee de Parity node synchroniseert`, + label: `te synchroniseren chain/netwerk` + }, languages: { hint: `de taal waarin deze interface wordt weergegeven`, label: `Weergave taal` @@ -35,7 +47,7 @@ export default { mode_offline: `Parity synchroniseert niet`, mode_passive: `Parity synchroniseert in het begin. Daarna slaapt Parity en wordt regelmatig wakker voor synchronisatie` }, - overview_0: `Pas de Parity node instellingen aan en kies de synchronisatie modus in dit menu.`, + overview_0: `Pas de Parity node instellingen aan en kies de manier van synchroniseren in dit menu.`, label: `parity` }, proxy: { @@ -53,7 +65,7 @@ export default { label: `Accounts` }, addresses: { - description: `Een overzicht van alle contacten en adresboek items die door deze Parity installatie worden beheerd. Monitor en volg accounts waarbij je transactie details met slechts een muisklik kunt weergeven.`, + description: `Een overzicht van alle door deze Parity installatie beheerde contacten en adresboek items. Monitor en volg accounts waarbij je transactie details met slechts een muisklik kunt weergeven.`, label: `Adresboek` }, apps: { @@ -64,10 +76,10 @@ export default { description: `Monitor, volg en maak gebruik van specifieke contracten die op het netwerk zijn gezet. Dit is een meer technisch gerichte omgeving, voornamelijk bedoeld voor geavanceerde gebruikers die de werking van bepaalde contracten goed begrijpen.`, label: `Contracten` }, - overview_0: `Beheer de beschikbare weergaven van deze interface en selecteer enkel de delen van de applicatie die voor jou van belang zijn.`, + overview_0: `Beheer de beschikbare weergaven van deze interface, en selecteer enkel de delen van de applicatie die voor jou van belang zijn.`, overview_1: `Ben je een eind gebruiker? De standaard instellingen zijn geschikt voor zowel beginners als gevorderde gebruikers.`, overview_2: `Ben je een ontwikkelaar? Voeg enkele functies toe om je contracten te beheren en gebruik te maken van gedecentraliseerde applicaties.`, - overview_3: `Ben je een miner of run je een grootschalige node? Voeg enkele functies toe om je alle informatie te geven die je nodig hebt om je node te monitoren.`, + overview_3: `Ben je een miner of draai je een grootschalige node? Voeg enkele functies toe om je alle informatie te geven die je nodig hebt om je node te monitoren.`, settings: { description: `Deze weergave. Hiermee kun je Parity aan passen in termen van opties, bediening en look en feel.`, label: `Instellingen` diff --git a/js/src/i18n/nl/signer.js b/js/src/i18n/nl/signer.js new file mode 100644 index 000000000..ec7ee96f8 --- /dev/null +++ b/js/src/i18n/nl/signer.js @@ -0,0 +1,103 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + embedded: { + noPending: `Er zijn momenteel geen lopende verzoeken die op je goedkeuring wachten` + }, + mainDetails: { + editTx: `Bewerk condities/gas/gasprijs`, + tooltips: { + total1: `De waarde van de transactie inclusief de miningskosten is {total} {type}.`, + total2: `(Dit is inclusief een miners vergoeding van {fee} {token})`, + value1: `De waarde van de transactie.` + } + }, + requestOrigin: { + dapp: `door een dapp op {url}`, + ipc: `via IPC sessie`, + rpc: `via RPC {rpc}`, + signerCurrent: `via huidige tab`, + signerUI: `via UI sessie`, + unknownInterface: `via onbekende interface`, + unknownRpc: `niet geïdentificeerd`, + unknownUrl: `onbekende URL` + }, + requestsPage: { + noPending: `Er zijn geen verzoeken die je goedkeuring vereisen.`, + pendingTitle: `Openstaande Verzoeken`, + queueTitle: `Lokale Transacties` + }, + sending: { + hardware: { + confirm: `Bevestig de transactie op je aangesloten hardware wallet`, + connect: `Sluit je hardware wallet aan voordat je de transactie bevestigd` + } + }, + signRequest: { + request: `Een verzoek om data te ondertekenen met jouw account:`, + state: { + confirmed: `Bevestigd`, + rejected: `Afgewezen` + }, + unknownBinary: `(Onbekende binary data)`, + warning: `WAARSCHUWING: Deze gevolgen hiervan kunnen ernstig zijn. Bevestig het verzoek alleen als je het zeker weet.` + }, + title: `Trusted Signer`, + txPending: { + buttons: { + viewToggle: `bekijk transactie` + } + }, + txPendingConfirm: { + buttons: { + confirmBusy: `Bevestigen...`, + confirmRequest: `Bevestig Verzoek` + }, + errors: { + invalidWallet: `Opgegeven wallet bestand is ongeldig.` + }, + password: { + decrypt: { + hint: `open (decrypt) de sleutel met je wachtwoord`, + label: `Sleutel Wachtwoord` + }, + unlock: { + hint: `ontgrendel het account`, + label: `Account Wachtwoord` + } + }, + passwordHint: `(hint) {passwordHint}`, + selectKey: { + hint: `De sleutelbestand (keyfile) die je voor dit account wilt gebruiken`, + label: `Selecteer Lokale Sleutel (key)` + }, + tooltips: { + password: `Geef een wachtwoord voor dit account` + } + }, + txPendingForm: { + changedMind: `Ik heb me bedacht`, + reject: `wijs verzoek af` + }, + txPendingReject: { + buttons: { + reject: `Wijs Verzoek Af` + }, + info: `Weet je zeker dat je dit verzoek wilt afwijzen?`, + undone: `Dit kan niet ongedaan gemaakt worden` + } +}; diff --git a/js/src/i18n/nl/status.js b/js/src/i18n/nl/status.js new file mode 100644 index 000000000..9c0294ab0 --- /dev/null +++ b/js/src/i18n/nl/status.js @@ -0,0 +1,66 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + debug: { + reverse: `Omgekeerde volgorde`, + stopped: `De live weergave van de Parity logboeken is momenteel gestopt via de UI, start de live weergave om de laatste updates te zien.`, + title: `Node Logboeken` + }, + miningSettings: { + input: { + author: { + hint: `de mining auteur`, + label: `auteur` + }, + extradata: { + hint: `extra data voor mined blokken`, + label: `extra data` + }, + gasFloor: { + hint: `het gas-floor doel voor mining`, + label: `gas-floor doel` + }, + gasPrice: { + hint: `de minimale gas prijs voor mining`, + label: `minimale gas prijs` + } + }, + title: `mining instellingen` + }, + status: { + hashrate: `{hashrate} H/s`, + input: { + chain: `chain`, + enode: `enode`, + no: `nee`, + peers: `peers`, + port: `netwerk poort`, + rpcEnabled: `rpc ingeschakeld`, + rpcInterface: `rpc interface`, + rpcPort: `rpc poort`, + yes: `ja` + }, + title: { + bestBlock: `beste block`, + hashRate: `hash rate`, + network: `netwerk instellingen`, + node: `Node`, + peers: `peers` + } + }, + title: `Status` +}; diff --git a/js/src/i18n/nl/transfer.js b/js/src/i18n/nl/transfer.js index 1370711b4..29866470b 100644 --- a/js/src/i18n/nl/transfer.js +++ b/js/src/i18n/nl/transfer.js @@ -21,7 +21,41 @@ export default { label: `transactie data` } }, + buttons: { + back: `Terug`, + cancel: `Annuleer`, + close: `Sluit`, + next: `Volgende`, + send: `Verzend` + }, + details: { + advanced: { + label: `geavanceerde verzend opties` + }, + amount: { + hint: `de naar de ontvanger te verzenden hoeveelheid`, + label: `te verzenden hoeveelheid (in {tag})` + }, + fullBalance: { + label: `volledige account balans` + }, + recipient: { + hint: `het ontvangende adres`, + label: `ontvanger adres` + }, + sender: { + hint: `het verzendende adres`, + label: `Verzender adres` + }, + total: { + label: `totale transactie hoeveelheid` + } + }, + wallet: { + confirmation: `Deze transactie vereist bevestiging van andere eigenaren.`, + operationHash: `hash van deze bewerking` + }, warning: { - wallet_spent_limit: `Deze transactie waarde is boven de toegestane dag limiet en zal moeten worden bevestigd door andere eigenaren.` + wallet_spent_limit: `De waarde van deze transactie is hoger dan de toegestane dag limiet en zal moeten worden bevestigd door andere eigenaren.` } }; diff --git a/js/src/i18n/nl/ui.js b/js/src/i18n/nl/ui.js index c0454e9f6..1b7a9163b 100644 --- a/js/src/i18n/nl/ui.js +++ b/js/src/i18n/nl/ui.js @@ -15,8 +15,40 @@ // along with Parity. If not, see . export default { + actionbar: { + export: { + button: { + export: `exporteer` + } + }, + import: { + button: { + cancel: `Annuleer`, + confirm: `Bevestig`, + import: `importeer` + }, + confirm: `Bevestig dat dit is wat je wilt importeren.`, + error: `Er is een fout opgetreden: {errorText}`, + step: { + error: `fout`, + select: `selecteer een bestand`, + validate: `valideer` + }, + title: `Importeer vanuit een bestand` + }, + search: { + hint: `Voer zoekopdracht in...` + }, + sort: { + sortBy: `Sorteer op {label}`, + typeDefault: `Standaard`, + typeEth: `Sorteer op ETH`, + typeName: `Sorteer op naam`, + typeTags: `Sorteer op tags` + } + }, balance: { - none: `Er zijn geen tegoeden gekoppeld aan dit account` + none: `Geen tegoeden gekoppeld aan dit account` }, blockStatus: { bestBlock: `{blockNumber} beste blok`, @@ -28,10 +60,61 @@ export default { no: `nee`, yes: `ja` }, + copyToClipboard: { + copied: `{data} is naar het klembord gekopierd` + }, + errors: { + close: `sluit` + }, + fileSelect: { + defaultLabel: `Sleep hier een bestand naartoe, of klik om een bestand te selecteren voor uploaden` + }, + gasPriceSelector: { + customTooltip: { + transactions: `{number} {number, plural, one {transaction} other {transactions}} met een ingestelde gasprijs tussen de {minPrice} en {maxPrice}` + } + }, identityName: { null: `NUL`, unnamed: `NAAMLOOS` }, + methodDecoding: { + condition: { + block: `, {historic, select, true {Submitted} false {Submission}} in blok {blockNumber}`, + time: `, {historic, select, true {Submitted} false {Submission}} op {timestamp}` + }, + deploy: { + address: `Een contract aangemaakt op adres`, + params: `met de volgende parameters:`, + willDeploy: `Zal een contract aanmaken`, + withValue: `, verzenden van {value}` + }, + gasUsed: `({gas} gas gebruikt)`, + gasValues: `{gas} gas ({gasPrice}M/{tag})`, + input: { + data: `data`, + input: `input`, + withInput: `met de {inputDesc} {inputValue}` + }, + receive: { + contract: `het contract`, + info: `{historic, select, true {Received} false {Will receive}} {valueEth} van {aContract}{address}` + }, + signature: { + info: `{historic, select, true {Executed} false {Will execute}} the {method} function on the contract {address} transferring {ethValue}{inputLength, plural, zero {,} other {passing the following {inputLength, plural, one {parameter} other {parameters}}}}` + }, + token: { + transfer: `{historic, select, true {Transferred} false {Will transfer}} {value} naar {address}` + }, + transfer: { + contract: `het contract`, + info: `{historic, select, true {Transferred} false {Will transfer}} {valueEth} naar {aContract}{address}` + }, + txValues: `{historic, select, true {Provided} false {Provides}} {gasProvided}{gasUsed} voor een totale transactie waarde van {totalEthValue}`, + unknown: { + info: `{historic, select, true {Executed} false {Will execute}} the {method} on the contract {address} transferring {ethValue}.` + } + }, passwordStrength: { label: `wachtwoord sterkte` }, @@ -48,6 +131,10 @@ export default { posted: `De transactie is op het netwerk geplaatst met hash {hashLink}`, waiting: `wachten op bevestigingen` }, + vaultSelect: { + hint: `de kluis waaraan dit account gekoppeld is`, + label: `gekoppelde kluis` + }, verification: { gatherData: { accountHasRequested: { @@ -60,10 +147,6 @@ export default { pending: `Aan het controleren of je account is geverifieerd…`, true: `Je account is al geverifieerd.` }, - email: { - hint: `de code zal naar dit adres worden verzonden`, - label: `e-mail adres` - }, fee: `De extra vergoeding is {amount} ETH.`, isAbleToRequest: { pending: `Valideren van je invoer…` @@ -74,10 +157,6 @@ export default { true: `De verificatie server is actief.` }, nofee: `Er zijn geen extra kosten.`, - phoneNumber: { - hint: `De SMS zal naar dit nummer worden verstuurd`, - label: `telefoonnummer in internationaal formaat` - }, termsOfService: `Ik ga akkoord met de voorwaarden en condities hieronder.` } } diff --git a/js/src/i18n/nl/upgradeParity.js b/js/src/i18n/nl/upgradeParity.js index c057c9e7d..732a7b267 100644 --- a/js/src/i18n/nl/upgradeParity.js +++ b/js/src/i18n/nl/upgradeParity.js @@ -15,13 +15,13 @@ // along with Parity. If not, see . export default { - busy: `Parity wordt momenteel bijgewerkt naar versie {newversion}`, + busy: `Parity wordt momenteel bijgewerkt naar versie {newversion}. Wacht tot het proces is voltooid.`, button: { close: `sluiten`, done: `klaar`, upgrade: `werk nu bij` }, - completed: `Het bijwerken naar Parity {newversion} is succesvol voltooid.`, + completed: `Het bijwerken naar Parity {newversion} is succesvol voltooid. Klik op "klaar" om het programma automatisch opnieuw op te starten.`, consensus: { capable: `Je huidige versie van Parity voldoet aan de netwerk vereisten.`, capableUntil: `Je huidige versie van Parity voldoet aan de netwerk vereisten tot aan blok {blockNumber}`, @@ -30,7 +30,10 @@ export default { }, failed: `Het bijwerken naar Parity {newversion} gaf een fout en is mislukt.`, info: { - upgrade: `Een nieuwe versie van Parity, version {newversion} is beschikbaar als upgrade vanaf je huidige versie {currentversion}` + currentVersion: `Je huidige versie is {currentversion}`, + next: `Klik op "werk nu bij" om het bijwerken van je Parity te starten.`, + upgrade: `Een nieuwe versie {newversion} is beschikbaar`, + welcome: `Welkom bij de Parity upgrade wizard, deze stelt je in staat om Parity op zeer eenvoudige wijze bij te werken naar de nieuwste versie.` }, step: { completed: `bijwerken voltooid`, diff --git a/js/src/i18n/nl/vaults.js b/js/src/i18n/nl/vaults.js index b16c6807e..3659fb7d7 100644 --- a/js/src/i18n/nl/vaults.js +++ b/js/src/i18n/nl/vaults.js @@ -26,8 +26,9 @@ export default { button: { accounts: `accounts`, add: `Maak kluis`, - close: `sluit kluis`, - open: `open kluis` + close: `sluit`, + edit: `bewerk`, + open: `open` }, confirmClose: { info: `Je staat op het punt op een kluis te sluiten. Alle aan deze kluis verbonden accounts zullen niet meer zichtbaar zijn na het voltooien van deze actie. Om deze accounts weer zichtbaar te maken dien je de kluis weer te openen.`, @@ -70,6 +71,38 @@ export default { }, title: `Maak een nieuwe kluis aan` }, + editMeta: { + allowPassword: `Wijzig kluis wachtwoord`, + button: { + close: `sluit`, + save: `opslaan` + }, + currentPassword: { + hint: `je huidige kluis wachtwoord`, + label: `huidige wachtwoord` + }, + description: { + hint: `de omschrijving van deze kluis`, + label: `kluis omschrijving` + }, + password: { + hint: `een sterk, uniek wachtwoord`, + label: `nieuw wachtwoord` + }, + password2: { + hint: `verifieer je nieuwe wachtwoord`, + label: `nieuw wachtwoord (herhaal)` + }, + passwordHint: { + hint: `je wachtwoord hint voor deze kluis`, + label: `wachtwoord hint` + }, + title: `Bewerk Kluis Metadata` + }, empty: `Er zijn momenteel geen kluizen om weer tegeven.`, + selector: { + noneAvailable: `Er zijn momenteel geen kluizen geopend en beschikbaar voor selectie. Maak eerst een kluis aan en open deze, voordat je een kluis selecteert voor het verplaatsen van een account.`, + title: `Selecteer Account Kluis` + }, title: `Kluis Beheer` }; diff --git a/js/src/i18n/nl/verification.js b/js/src/i18n/nl/verification.js new file mode 100644 index 000000000..bd0ba1c28 --- /dev/null +++ b/js/src/i18n/nl/verification.js @@ -0,0 +1,85 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + cancel: `Annuleer`, + done: `Klaar`, + next: `Volgende` + }, + code: { + error: `ongeldige code`, + hint: `Voer de ontvangen code in.`, + label: `verificatie code`, + sent: `De verificatie code is verstuurd naar {receiver}.` + }, + confirmation: { + authorise: `De verificatie code zal naar het contract worden verzonden. Gebruik de Parity Signer om dit goed te keuren.`, + windowOpen: `Houd dit scherm open.` + }, + done: { + message: `Gefeliciteerd, je account is geverifieerd!` + }, + email: { + enterCode: `Voer de code in die je per e-email hebt ontvangen.` + }, + gatherData: { + email: { + hint: `de code zal naar dit adres worden verstuurd`, + label: `e-mail adres` + }, + phoneNumber: { + hint: `De SMS zal naar dit nummer worden verstuurd`, + label: `telefoon nummer in internationaal formaat` + } + }, + gatherDate: { + email: { + error: `ongeldig e-mail adres` + }, + phoneNumber: { + error: `ongeldig telefoon nummer` + } + }, + loading: `Laden van verificatie data.`, + request: { + authorise: `Een verificatie verzoek zal naar het contract worden verzonden. Gebruik de Parity Signer om dit goed te keuren.`, + requesting: `Een code aanvragen bij de Parity-server en wachten tot de puzzel in het contract opgenomen wordt.`, + windowOpen: `Houd dit scherm open.` + }, + sms: { + enterCode: `Voer de code in die je per SMS hebt ontvangen.` + }, + steps: { + code: `Voer Code in`, + completed: `Voltooi`, + confirm: `Bevestig`, + data: `Voer Data in`, + method: `Methode`, + request: `Verzoek` + }, + title: `verifieer je account`, + types: { + email: { + description: `De hash van het e-mail adres waarvan je bewijst dat het van jou is, zal worden opgeslagen in de blockchain.`, + label: `E-mail Verificatie` + }, + sms: { + description: `Het zal in de blockchain worden vast gelegd dat jij in het bezit bent van een telefoon nummer (not which).`, + label: `SMS Verificatie` + } + } +}; diff --git a/js/src/i18n/nl/wallet.js b/js/src/i18n/nl/wallet.js new file mode 100644 index 000000000..d0460e58f --- /dev/null +++ b/js/src/i18n/nl/wallet.js @@ -0,0 +1,45 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + edit: `bewerk`, + forget: `vergeet`, + settings: `instellingen`, + transfer: `verzend` + }, + confirmations: { + buttons: { + confirmAs: `Bevestig als...`, + revokeAs: `Herroep als...` + }, + none: `Er zijn momenteel geen transacties die op bevestiging wachten.`, + tooltip: { + confirmed: `Bevestigd door {number}/{required} eigenaren` + } + }, + details: { + requiredOwners: `Dit wallet vereist ten minste {owners} voor de goedkeuring van elke actie (transactions, modifications).`, + requiredOwnersNumber: `{number} {numberValue, plural, one {owner} other {owners}}`, + spent: `{spent} is vandaag besteed, van de {limit} ingestelde daglimiet. De daglimiet is op {date} opnieuw ingesteld`, + title: `Details` + }, + title: `Wallet Beheer`, + transactions: { + none: `Er zijn geen verzonden transacties.`, + title: `Transacties` + } +}; diff --git a/js/src/i18n/nl/walletSettings.js b/js/src/i18n/nl/walletSettings.js index ca0842944..66fd70001 100644 --- a/js/src/i18n/nl/walletSettings.js +++ b/js/src/i18n/nl/walletSettings.js @@ -15,6 +15,16 @@ // along with Parity. If not, see . export default { + addOwner: { + title: `Eigenaar toevoegen` + }, + buttons: { + cancel: `Annuleer`, + close: `Sluit`, + next: `Volgende`, + send: `Verzend`, + sending: `Verzenden...` + }, changes: { modificationString: `Om je wijzigingen door te voeren zullen andere eigenaren deze zelfde wijzigingen moeten verzenden. Om het @@ -25,7 +35,8 @@ export default { edit: { message: `Om de instellingen van dit contract de wijzigen zullen minimaal {owners, number} {owners, plural, one {owner } other {owners }} precies dezelfde - wijzigingen moeten verzenden. Je kunt hier de wijzigingen in string-vorm plakken.` + wijzigingen moeten verzenden. Je kunt de wijzigingen hier + in string-vorm plakken.` }, modifications: { daylimit: { @@ -47,11 +58,12 @@ export default { label: `van account (wallet eigenaar)` } }, - rejected: { - busyStep: { - state: `De wallet instellingen zullen niet worden gewijzigd. Je kunt dit venster veilig sluiten.`, - title: `De wijzigingen zijn afgewezen.` - }, - title: `afgewezen` + ownersChange: { + details: `van {from} naar {to}`, + title: `Wijzig Vereiste Eigenaren` + }, + rejected: `De transactie #{txid} is afgewezen`, + removeOwner: { + title: `Verwijder Eigenaar` } }; diff --git a/js/src/i18n/nl/writeContract.js b/js/src/i18n/nl/writeContract.js new file mode 100644 index 000000000..e264ac83a --- /dev/null +++ b/js/src/i18n/nl/writeContract.js @@ -0,0 +1,62 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + autoCompile: `Auto-Compile`, + compile: `Compileer`, + deploy: `Maak Aan`, + import: `Importeer Solidity`, + load: `Laad`, + new: `Nieuw`, + optimise: `Optimaliseer`, + save: `Opslaan` + }, + compiling: { + action: `Compileer de bron code.`, + busy: `Compileren...` + }, + details: { + saved: `(opgeslagen {timestamp})` + }, + error: { + noContract: `Er is geen contract gevonden.`, + params: `Een fout is opgetreden met de volgende omschrijving` + }, + input: { + abi: `ABI Interface`, + code: `Bytecode`, + metadata: `Metadata`, + swarm: `Swarm Metadata Hash` + }, + title: { + contract: `Selecteer een contract`, + loading: `Laden...`, + main: `Schrijf een Contract`, + messages: `Compiler berichten`, + new: `Nieuw Solidity Contract`, + parameters: `Parameters`, + saved: `opgeslagen @ {timestamp}`, + selectSolidity: `Selecteer een Solidity versie`, + solidity: `Solidity {version} laden` + }, + type: { + humanErc20: `Implementatie van het Human Token Contract`, + implementErc20: `Implementatie van ERC20 Token Contract`, + multisig: `Implementatie van een multisig Wallet`, + standardErc20: `Standaard ERC20 Token Contract` + } +}; diff --git a/js/src/i18n/store.js b/js/src/i18n/store.js index fdceb6beb..f2506950e 100644 --- a/js/src/i18n/store.js +++ b/js/src/i18n/store.js @@ -29,6 +29,7 @@ import deMessages from './de'; import enMessages from './en'; import nlMessages from './nl'; import zhMessages from './zh'; +import zhHantTWMessages from './zh-Hant-TW'; let instance = null; @@ -37,7 +38,8 @@ const MESSAGES = { de: Object.assign(flatten(deMessages), LANGUAGES), en: Object.assign(flatten(enMessages), LANGUAGES), nl: Object.assign(flatten(nlMessages), LANGUAGES), - zh: Object.assign(flatten(zhMessages), LANGUAGES) + zh: Object.assign(flatten(zhMessages), LANGUAGES), + 'zh-Hant-TW': Object.assign(flatten(zhHantTWMessages), LANGUAGES) }; addLocaleData([...de, ...en, ...nl, ...zh]); diff --git a/js/src/i18n/zh-Hant-TW/account.js b/js/src/i18n/zh-Hant-TW/account.js new file mode 100644 index 000000000..c1ddb288d --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/account.js @@ -0,0 +1,39 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + delete: `刪除`, // delete + edit: `編輯`, // edit + faucet: `Kovan測試網路以太幣`, // Kovan ETH + password: `密碼`, // password + shapeshift: `shapeshift`, + transfer: `轉帳`, // transfer + verify: `確認`// verify + }, + hardware: { + confirmDelete: `你確定從你的帳戶列表中移除下面的硬體地址嗎?` + }, // Are you sure you want to remove the following hardware address from your account list? + header: { + outgoingTransactions: `{count}筆正在發生的轉帳`, // {count} outgoing transactions + uuid: `uuid: {uuid}` + }, + title: `帳戶管理`, // Account Management + transactions: { + poweredBy: `Transaction list powered by {etherscan}提供的交易列表`, + title: `交易`// transactions + } +}; diff --git a/js/src/i18n/zh-Hant-TW/accounts.js b/js/src/i18n/zh-Hant-TW/accounts.js new file mode 100644 index 000000000..d717b3583 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/accounts.js @@ -0,0 +1,36 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + newAccount: `帳戶`, // account + newWallet: `錢包`, // wallet + vaults: `保險庫`// vaults + }, + summary: { + minedBlock: `在第#{blockNumber}個區塊被挖出`// Mined at block #{blockNumber} + }, + title: `帳戶總覽`, // Accounts Overview + tooltip: { + actions: `與當前視窗有關的操作可以在工具欄中快速被找到,不論是執行操作還是建立新項`, + // actions relating to the current view are available on the toolbar for quick access, be it for performing actions or creating a new item + overview: `你的帳戶很容易使用,使你可以編輯元資訊、轉帳、檢視交易和向帳戶充值` + // your accounts are visible for easy access, allowing you to edit the meta information, make transfers, view transactions and fund the account + }, + tooltips: { + owner: `{name}持有者`// {name} (owner) + } +}; diff --git a/js/src/i18n/zh-Hant-TW/addAddress.js b/js/src/i18n/zh-Hant-TW/addAddress.js new file mode 100644 index 000000000..5d18e441f --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/addAddress.js @@ -0,0 +1,41 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + add: `儲存地址`, // Save Address + close: `取消` // Cancel + }, + header: `如果想在地址簿中新增一條新的記錄,你需要擁有帳戶的網路地址並提供一個的描述(可選)。一旦新增,記錄就可以體現在你的地址簿中。`, + // To add a new entry to your addressbook, you need the network + // address of the account and can supply an optional description. + // Once added it will reflect in your address book. + input: { + address: { + hint: `記錄的網路地址`, // the network address for the entry + label: `網路地址` // network address + }, + description: { + hint: `記錄的詳細描述`, // an expanded description for the entry + label: `(可選)地址描述` // (optional) address description + }, + name: { + hint: `記錄的名字`, // a descriptive name for the entry + label: `地址名` // address name + } + }, + label: `新增已儲存的地址` // add saved address +}; diff --git a/js/src/i18n/zh-Hant-TW/addContract.js b/js/src/i18n/zh-Hant-TW/addContract.js new file mode 100644 index 000000000..314779896 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/addContract.js @@ -0,0 +1,60 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + abi: { + hint: `合約的ABI`, // the abi for the contract + label: `合約ABI` // contract abi + }, + abiType: { + custom: { + description: `通過自定義ABI創造的合約`, // Contract created from custom ABI + label: `自定義合約` // Custom Contract + }, + multisigWallet: { + description: `以太坊多重簽名合約{link}`, // Ethereum Multisig contract {link} + label: `多重簽名錢包`, // Multisig Wallet + link: `參考合約程式碼` // see contract code + }, + token: { + description: `一個標準的{erc20}代幣`, // A standard {erc20} token + erc20: `ERC 20`, // ERC 20 + label: `代幣` // Token + } + }, + address: { + hint: `合約的網路地址`, // the network address for the contract + label: `網路地址` // network address + }, + button: { + add: `新增合約`, // Add Contract + cancel: `取消`, // Cancel + next: `下一步`, // Next + prev: `上一步` // Back + }, + description: { + hint: `記錄的詳細描述`, // an expanded description for the entry + label: `(可選)合約描述` // (optional) contract description + }, + name: { + hint: `合約的描述性名稱`, // a descriptive name for the contract + label: `合約名` // contract name + }, + title: { + details: `輸入合約細節`, // enter contract details + type: `選擇合約種類` // choose a contract type + } +}; diff --git a/js/src/i18n/zh-Hant-TW/address.js b/js/src/i18n/zh-Hant-TW/address.js new file mode 100644 index 000000000..11cb4ab07 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/address.js @@ -0,0 +1,28 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + edit: `編輯`, // edit + forget: `忘記`, // forget + save: `儲存`// save + }, + delete: { + confirmInfo: `你確定你想把下面的地址從你的地址簿中移除嗎?`, // Are you sure you want to remove the following address from your addressbook? + title: `確認移除`// confirm removal + }, + title: `地址資訊`// Address Information +}; diff --git a/js/src/i18n/zh-Hant-TW/addressSelect.js b/js/src/i18n/zh-Hant-TW/addressSelect.js new file mode 100644 index 000000000..bc3194019 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/addressSelect.js @@ -0,0 +1,26 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + fromEmail: `使用郵箱{email}進行確認`, // Verified using email {email} + fromRegistry: `{name}(來自注冊)`, // {name} (from registry) + labels: { + accounts: `帳戶`, // accounts + contacts: `合約`, // contacts + contracts: `合約`// contracts + }, + noAccount: `查不到這個帳戶`// No account matches this query... +}; diff --git a/js/src/i18n/zh-Hant-TW/addresses.js b/js/src/i18n/zh-Hant-TW/addresses.js new file mode 100644 index 000000000..bacbb79db --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/addresses.js @@ -0,0 +1,25 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + add: `地址` // address + }, + errors: { + invalidFile: `提供的檔案是無效的`// The provided file is invalid... + }, + title: `儲存的地址`// Saved Addresses +}; diff --git a/js/src/i18n/zh-Hant-TW/application.js b/js/src/i18n/zh-Hant-TW/application.js new file mode 100644 index 000000000..f5f0e9a23 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/application.js @@ -0,0 +1,30 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + frame: { + error: `錯誤:這個應用不能也不應該載入到內建框架中`// ERROR: This application cannot and should not be loaded in an embedded iFrame + }, + status: { + consensus: { + capable: `可行`, // Capable + capableUntil: `到第 #{blockNumber} 區塊前可行`, // Capable until #{blockNumber} + incapableSince: `自第 #{blockNumber} 區塊後不可行`, // Incapable since #{blockNumber} + unknown: `未知能力`// Unknown capability + }, + upgrade: `升級`// Upgrade + } +}; diff --git a/js/src/i18n/zh-Hant-TW/connection.js b/js/src/i18n/zh-Hant-TW/connection.js new file mode 100644 index 000000000..ed48452e5 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/connection.js @@ -0,0 +1,30 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . +export default { + connectingAPI: `正在連線至Parity Secure API`, // Connecting to the Parity Secure API. + connectingNode: `正在連線Parity節點。如果彈出任何資訊,請確認你的Parity節點正在執行並連線至網際網路。`, + // Connecting to the Parity Node. If this informational message persists, + // please ensure that your Parity node is running and reachable on the network. + invalidToken: `無效的簽名令牌`, // invalid signer token + noConnection: `無法連線至Parity Secure API。請升級的你的安全令牌或者生成一個新的,執行{newToken}並貼上生成的令牌到下方。`, + // Unable to make a connection to the Parity Secure API. To update your secure + // token or to generate a new one, run {newToken} and paste the generated token + // into the space below. + token: { + hint: `一個Parity生成的令牌`, // a generated token from Parity + label: `安全令牌` // secure token + } +}; diff --git a/js/src/i18n/zh-Hant-TW/contract.js b/js/src/i18n/zh-Hant-TW/contract.js new file mode 100644 index 000000000..9f5b40f0a --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/contract.js @@ -0,0 +1,41 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + close: `關閉`, // close + details: `詳細資料`, // details + edit: `編輯`, // edit + execute: `執行`, // execute + forget: `forget` // forget + }, + details: { + title: `合約細節` // contract details + }, + events: { + eventPending: `待定中`, // pending + noEvents: `此合約沒有傳送過任何事件`, // No events has been sent from this contract. + title: `事件` // events + }, + minedBlock: `挖到了第{blockNumber}個區塊`, // Mined at block #{blockNumber} + queries: { + buttons: { + query: `查詢` // Query + }, + title: `查詢` // queries + }, + title: `合約資訊` // Contract Information +}; diff --git a/js/src/i18n/zh-Hant-TW/contracts.js b/js/src/i18n/zh-Hant-TW/contracts.js new file mode 100644 index 000000000..a81387f28 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/contracts.js @@ -0,0 +1,28 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + deploy: `部署`, // deploy + develop: `開發`, // develop + watch: `觀察` // watch + }, + sortOrder: { + date: `日期`, // date + minedBlock: `挖到的區塊` // mined block + }, + title: `合約` // Contracts +}; diff --git a/js/src/i18n/zh-Hant-TW/createAccount.js b/js/src/i18n/zh-Hant-TW/createAccount.js new file mode 100644 index 000000000..81e7b81b5 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/createAccount.js @@ -0,0 +1,165 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + accountDetails: { + address: { + hint: `帳戶地址`, + label: `地址` + }, + name: { + hint: `描述帳戶的名字`, + label: `帳戶名` + }, + phrase: { + hint: `帳戶恢復詞`, + label: `帳戶恢復詞(安全儲存,別人擁有它就可以完全控制你的帳戶)` + } + }, + accountDetailsGeth: { + imported: `你已經從Geth keystore匯入了{number}個地址` + }, + button: { + back: `返回`, + cancel: `取消`, + close: `關閉`, + create: `建立`, + done: `Done`, + import: `匯入`, + next: `下一步`, + print: `列印恢復詞` + }, + creationType: { + fromGeth: { + description: `Import accounts from the Geth keystore with the original password`, + label: `從Geth keystore匯入帳戶` + }, + fromJSON: { + description: `Import an industry-standard JSON keyfile with the original password`, + label: `從JSON檔案匯入帳戶` + }, + fromNew: { + description: `Selecting your identity icon and specifying the password`, + label: `手動建立新帳戶` + }, + fromPhrase: { + description: `Recover using a previously stored recovery phrase and new password`, + label: `通過恢復詞恢復帳戶` + }, + fromPresale: { + description: `Import an Ethereum presale wallet file with the original password`, + label: `從以太坊預售錢包匯入帳戶` + }, + fromRaw: { + description: `Enter a previously created raw private key with a new password`, + label: `匯入私鑰` + }, + info: `Please select the type of account you want to create. Either create an account via name & password, or import it from a variety of existing sources. From here the wizard will guide you through the process of completing your account creation.` + }, + newAccount: { + hint: { + hint: `(可選)幫助你記住密碼的提示`, + label: `密碼提示` + }, + name: { + hint: `描述帳戶的名字`, + label: `帳戶名` + }, + password: { + hint: `足夠強的密碼`, + label: `密碼` + }, + password2: { + hint: `確認你的密碼`, + label: `再次輸入密碼` + } + }, + newGeth: { + available: `There are currently {count} importable keys available from the Geth keystore which are not already available on your Parity instance. Select the accounts you wish to import and move to the next step to complete the import.`, + noKeys: `現在Geth keystore中沒有可匯入的私鑰` + }, + newImport: { + file: { + hint: `要匯入的錢包檔案`, + label: `錢包檔案` + }, + hint: { + hint: `(可選)幫助你記住密碼的提示`, + label: `密碼提示` + }, + name: { + hint: `描述帳戶的名字`, + label: `帳戶名` + }, + password: { + hint: `輸入密碼,解鎖錢包`, + label: `密碼` + } + }, + rawKey: { + hint: { + hint: `(可選)幫助你記住密碼的提示`, + label: `密碼提示` + }, + name: { + hint: `描述帳戶的名字`, + label: `帳戶名` + }, + password: { + hint: `足夠強的密碼`, + label: `密碼` + }, + password2: { + hint: `確認密碼`, + label: `再次輸入密碼` + }, + private: { + hint: `原始的十六進位制編碼私鑰`, + label: `私鑰` + } + }, + recoveryPhrase: { + hint: { + hint: `(可選)幫助你記住密碼的提示`, + label: `密碼提示` + }, + name: { + hint: `描述帳戶的名字`, + label: `帳戶名` + }, + password: { + hint: `足夠強的密碼`, + label: `密碼` + }, + password2: { + hint: `確認密碼`, + label: `再次輸入密碼` + }, + phrase: { + hint: `帳戶恢復詞`, + label: `帳戶恢復詞` + }, + windowsKey: { + label: `在Windows系統上由Parity 1.4.5以前的版本建立的私鑰` + } + }, + title: { + accountInfo: `帳戶資訊`, + createAccount: `建立帳戶`, + createType: `建立型別`, + importWallet: `匯入錢包` + } +}; diff --git a/js/src/i18n/zh-Hant-TW/createWallet.js b/js/src/i18n/zh-Hant-TW/createWallet.js new file mode 100644 index 000000000..55dbc6da5 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/createWallet.js @@ -0,0 +1,106 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + add: `新增`, // Add + cancel: `取消`, // Cancel + close: `關閉`, // Close + create: `建立`, // Create + done: `完成`, // Done + next: `下一步`, // Next + sending: `傳送中...` // Sending... + }, + deployment: { + message: `部署正在進行中` // The deployment is currently in progress + }, + details: { + address: { + hint: `錢包的合約地址`, // the wallet contract address + label: `錢包地址` // wallet address + }, + dayLimitMulti: { + hint: `無需確認即可使用的ETH數量`, // amount of ETH spendable without confirmations + label: `錢包每日限額` // wallet day limit + }, + description: { + hint: `本地錢包描述`, // the local description for this wallet + label: `錢包描述(可選)` // wallet description (optional) + }, + descriptionMulti: { + hint: `本地錢包描述`, // the local description for this wallet + label: `錢包描述(可選)` // wallet description (optional) + }, + name: { + hint: `錢包本地名稱`, // the local name for this wallet + label: `錢包名稱` // wallet name + }, + nameMulti: { + hint: `錢包本地名稱`, // the local name for this wallet + label: `錢包名稱` // wallet name + }, + ownerMulti: { + hint: `合約的持有者帳戶`, // the owner account for this contract + label: `從帳戶 (contract owner)` // from account (contract owner) + }, + ownersMulti: { + label: `其他錢包持有者` // other wallet owners + }, + ownersMultiReq: { + hint: `接受交易所需的持有者人數`, // number of required owners to accept a transaction + label: `所需持有者` // required owners + } + }, + info: { + added: `已新增`, // added + copyAddress: `複製地址至貼上板`, // copy address to clipboard + created: `{name}已被{deployedOrAdded}至`, // {name} has been {deployedOrAdded} at + dayLimit: `每日限額已被設定為{dayLimit}ETH`, // The daily limit is set to {dayLimit} ETH. + deployed: `已部署`, // deployed + numOwners: `需要{numOwners}個持有者才能確認一個交易`, // {numOwners} owners are required to confirm a transaction. + owners: `以下為錢包持有者` // The following are wallet owners + }, + rejected: { + message: `部署被拒絕`, // The deployment has been rejected + state: `錢包不會被建立。你可以安全地關閉本視窗`, // The wallet will not be created. You can safely close this window. + title: `失敗` // rejected + }, + states: { + completed: `合約部署已完成`, // The contract deployment has been completed + confirmationNeeded: `合約部署需要來自本錢包的其他持有者的確認`, // The contract deployment needs confirmations from other owners of the Wallet + preparing: `交易正在準備被網路廣播`, // Preparing transaction for network transmission + validatingCode: `正在驗證已部署的程式碼`, // Validating the deployed contract code + waitingConfirm: `正在等待Parity Secure Signer確認本交易`, // Waiting for confirmation of the transaction in the Parity Secure Signer + waitingReceipt: `正在等待合約部署交易收據` // Waiting for the contract deployment transaction receipt + }, + steps: { + deployment: `錢包部署`, // wallet deployment + details: `錢包詳情`, // wallet details + info: `錢包資訊`, // wallet informaton + type: `錢包類別` // wallet type + }, + type: { + multisig: { + description: `建立/部署一個{link}錢包`, // Create/Deploy a {link} Wallet + label: `多重簽名錢包`, // Multi-Sig Wallet + link: `標準多重簽名` // standard multi-signature + }, + watch: { + description: `新增一個已有錢包到你的帳戶`, // Add an existing wallet to your accounts + label: `觀察錢包` // Watch a wallet + } + } +}; diff --git a/js/src/i18n/zh-Hant-TW/dapp.js b/js/src/i18n/zh-Hant-TW/dapp.js new file mode 100644 index 000000000..967ad542b --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/dapp.js @@ -0,0 +1,20 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + loading: `正在載入`, // Loading + unavailable: `不能獲取這個dapp`// The dapp cannot be reached +}; diff --git a/js/src/i18n/zh-Hant-TW/dapps.js b/js/src/i18n/zh-Hant-TW/dapps.js new file mode 100644 index 000000000..44e97d55b --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/dapps.js @@ -0,0 +1,48 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + add: { + builtin: { + desc: `Parity團隊開發的實驗性的,用以展示dapp的效能、整合、實驗性特性和控制特定網路的的客戶端行為`, + // Experimental applications developed by the Parity team to show off dapp capabilities, integration, experimental features and to control certain network-wide client behaviour. + label: `與Parity繫結的應用`// Applications bundled with Parity + }, + label: `visible applications可見的應用`, // visible applications + local: { + desc: `All applications installed locally on the machine by the user for access by the Parity client.`, + label: `本地可用的應用`// Applications locally available + }, + network: { + desc: `這些應用與Parity沒有關聯,也不是Parity釋出的。 它們是由各自的作者控制的。 在使用以前,請確保你理解每個應用的目標。`, + // These applications are not affiliated with Parity nor are they published by Parity.Each remain under the control of their respective authors.Please ensure that you understand the goals for each application before interacting. + label: `全球網路上的應用`// Applications on the global network + } + }, + button: { + edit: `編輯`, // edit + permissions: `許可`// permissions + }, + external: { + accept: `我理解這些應用和Parity沒有關聯`, // I understand that these applications are not affiliated with Parity + warning: `第三方開發者開發的應用與Parity沒有關聯,也不是Parity釋出的。 它們是由各自的作者控制的。 在使用以前,請確保你理解每個應用的目標。` + // Applications made available on the network by 3rd-party authors are not affiliated with Parity nor are they published by Parity. Each remain under the control of their respective authors. Please ensure that you understand the goals for each before interacting. + }, + label: `去中心化應用`, // Decentralized Applications + permissions: { + label: `可見的dapp帳戶`// visible dapp accounts + } +}; diff --git a/js/src/i18n/zh-Hant-TW/deleteAccount.js b/js/src/i18n/zh-Hant-TW/deleteAccount.js new file mode 100644 index 000000000..e9f49cd3c --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/deleteAccount.js @@ -0,0 +1,24 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + password: { + hint: `提供帳戶密碼,確認刪除帳戶`, // provide the account password to confirm the account deletion + label: `帳戶密碼`// account password + }, + question: `你確定你想永久地刪除下面的帳戶?`, // Are you sure you want to permanently delete the following account? + title: `確認刪除`// confirm removal +}; diff --git a/js/src/i18n/zh-Hant-TW/deployContract.js b/js/src/i18n/zh-Hant-TW/deployContract.js new file mode 100644 index 000000000..05af22f9f --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/deployContract.js @@ -0,0 +1,90 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + busy: { + title: `部署正在進行中`// The deployment is currently in progress + }, + button: { + cancel: `取消`, // Cancel + close: `關閉`, // Close + create: `建立`, // Create + done: `完成`, // Done + next: `下一個`// Next + }, + completed: { + description: `你的合約已經被部署在`// Your contract has been deployed at + }, + details: { + abi: { + hint: `合約的abi或者solc 組合輸出`, // the abi of the contract to deploy or solc combined-output + label: `abi / solc 組合輸出 `// abi / solc combined-output + }, + address: { + hint: `這個合約所有者的帳戶`, // the owner account for this contract + label: `來自帳戶(合約所有者)`// from account (contract owner) + }, + advanced: { + label: `高階的傳送選項`// advanced sending options + }, + amount: { + hint: `轉到這個合約中的數額`, // the amount to transfer to the contract + label: `傳送數額{tag}`// amount to transfer (in {tag}) + }, + code: { + hint: `編譯好的合約程式碼`, // the compiled code of the contract to deploy + label: `程式碼`// code + }, + contract: { + label: `選擇一個合約`// select a contract + }, + description: { + hint: `對這個合約的描述`, // a description for the contract + label: `合約描述(可選)`// contract description (optional) + }, + name: { + hint: `已經部署合約的名字`, // a name for the deployed contract + label: `合約名字`// contract name + } + }, + owner: { + noneSelected: `選擇一個有效的地址作為合約的所有者`// a valid account as the contract owner needs to be selected + }, + parameters: { + choose: `選擇合約引數`// Choose the contract parameters + }, + rejected: { + description: `你可以安全地關閉視窗,合約部署不會發生。`, // You can safely close this window, the contract deployment will not occur. + title: `部署已經被拒絕`// The deployment has been rejected + }, + state: { + completed: `合約部署已經完成`, // The contract deployment has been completed + confirmationNeeded: `這一操作需要這個合約其他所有人的確認。`, // The operation needs confirmations from the other owners of the contract + preparing: `為網路傳輸準備交易`, // Preparing transaction for network transmission + validatingCode: `驗證已經部署的合約的程式碼`, // Validating the deployed contract code + waitReceipt: `等待合約部署交易收據`, // Waiting for the contract deployment transaction receipt + waitSigner: `等待Parity Secure Signer中的交易被確認 `// Waiting for confirmation of the transaction in the Parity Secure Signer + }, + title: { + completed: `完成`, // completed + deployment: `部署`, // deployment + details: `合約細節`, // contract details + extras: `額外資訊`, // extra information + failed: `部署失敗`, // deployment failed + parameters: `s合約引數`, // contract parameter + rejected: `拒絕`// rejected + } +}; diff --git a/js/src/i18n/zh-Hant-TW/details_windows.js b/js/src/i18n/zh-Hant-TW/details_windows.js new file mode 100644 index 000000000..fcc570066 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/details_windows.js @@ -0,0 +1,17 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default `Windows`; diff --git a/js/src/i18n/zh-Hant-TW/editMeta.js b/js/src/i18n/zh-Hant-TW/editMeta.js new file mode 100644 index 000000000..6da3683fb --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/editMeta.js @@ -0,0 +1,34 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + description: { + hint: `此地址的描述`, // description for this address + label: `地址描述` // address description + }, + name: { + label: `名稱` // name + }, + passwordHint: { + hint: `密碼恢復提示`, // a hint to allow password recovery + label: `(可選)密碼提示` // (optional) password hint + }, + tags: { + hint: `按來新增一個標籤`, // press to add a tag + label: `(可選)標籤` // (optional) tags + }, + title: `編輯元資料` // edit metadata +}; diff --git a/js/src/i18n/zh-Hant-TW/errors.js b/js/src/i18n/zh-Hant-TW/errors.js new file mode 100644 index 000000000..82c41218f --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/errors.js @@ -0,0 +1,24 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + duplicateName: `名稱已存在`, // the name already exists + invalidKey: `原始私鑰需要被16進位制,64個字元長度並以"0x"開頭`, // the raw key needs to be hex, 64 characters in length and contain the prefix "0x" + noFile: `選擇一個可用的錢包檔案來輸入`, // select a valid wallet file to import + noKey: `你需要提供原始私鑰`, // you need to provide the raw private key + noMatchPassword: `所提供的密碼不正確`, // the supplied passwords does not match + noName: `你需要明確一個可用的名稱` // you need to specify a valid name +}; diff --git a/js/src/i18n/zh-Hant-TW/executeContract.js b/js/src/i18n/zh-Hant-TW/executeContract.js new file mode 100644 index 000000000..1c84414ef --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/executeContract.js @@ -0,0 +1,58 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + busy: { + posted: `你的交易已被公佈至網路`, // Your transaction has been posted to the network + title: `函式執行正在進行中`, // The function execution is in progress + waitAuth: `正在等待Parity Signer授權` // Waiting for authorization in the Parity Signer + }, + button: { + cancel: `取消`, // cancel + done: `完成`, // done + next: `下一步`, // next + post: `公佈交易`, // post transaction + prev: `上一步` // prev + }, + details: { + address: { + hint: `來自帳戶`, // from account + label: `將要交易的帳戶` // the account to transact with + }, + advancedCheck: { + label: `高階傳送選項` // advanced sending options + }, + amount: { + hint: `此交易將會發送的數量`, // the amount to send to with the transaction + label: `交易價值(ETH)` // transaction value (in ETH) + }, + function: { + hint: `此合約將會呼叫的函式`, // the function to call on the contract + label: `將執行的函式` // function to execute + } + }, + rejected: { + state: `你可以安全的關閉此視窗,函式將不會被執行。`, // You can safely close this window, the function execution will not occur. + title: `執行失敗` // The execution has been rejected + }, + steps: { + advanced: `高階選項`, // advanced options + complete: `完成`, // complete + rejected: `失敗`, // rejected + sending: `傳送中`, // sending + transfer: `函式詳情` // function details + } +}; diff --git a/js/src/i18n/zh-Hant-TW/extension.js b/js/src/i18n/zh-Hant-TW/extension.js new file mode 100644 index 000000000..5c0987038 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/extension.js @@ -0,0 +1,22 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + install: `現在就安裝這個擴充套件`, // Install the extension now + intro: `Parity現在有一個Chrome的擴充套件,可以安全的瀏覽以太坊所支援的分散式應用。我們強烈推薦你安裝這個擴充套件來進一步提升你的Parity使用體驗。` + // Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled distributed applications. + // It is highly recommended that you install this extension to further enhance your Parity experience. +}; diff --git a/js/src/i18n/zh-Hant-TW/faucet.js b/js/src/i18n/zh-Hant-TW/faucet.js new file mode 100644 index 000000000..46474e13a --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/faucet.js @@ -0,0 +1,29 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + close: `關閉`, // close + done: `關閉`, // close + request: `請求`// request + }, + summary: { + done: `你已經向水龍頭請求Kovan ETH測試幣`, // Your Kovan ETH has been requested from the faucet which responded with - + info: `如果請求將Kovan ETH測試幣存入這個地址,你需要確定這個地址在主網路上已經用簡訊驗證過了。 一旦執行水龍頭將向當前帳戶存入Kovan ETH測試幣。` + // To request a deposit of Kovan ETH to this address, you need to ensure that the address is sms-verified on the mainnet.Once executed the faucet will deposit Kovan ETH into the current account. + }, + title: `Kovan ETH測試幣水龍頭`// Kovan ETH Faucet Kovan +}; diff --git a/js/src/i18n/zh-Hant-TW/firstRun.js b/js/src/i18n/zh-Hant-TW/firstRun.js new file mode 100644 index 000000000..aeca368ea --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/firstRun.js @@ -0,0 +1,52 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + close: `關閉`, // Close + create: `建立`, // Create + next: `下一步`, // Next + print: `列印片語`, // Print Phrase + skip: `跳過`// Skip + }, + completed: { + congrats: `恭喜!你的節點設定已經完成,你現在可以使用應用了。`, + // Congratulations! Your node setup has been completed successfully and you are ready to use the application. + next: `下面你將瀏覽可用的功能和通用的應用介面,讓你最快速地使用Parity。` + // Next you will receive a walk-through of the available functions and the general application interface to get you up and running in record time. + }, + title: { + completed: `完成`, // completed + newAccount: `新帳戶`, // new account + recovery: `恢復`, // recovery + terms: `條款`, // terms + welcome: `歡迎`// welcome + }, + tnc: { + accept: `我接受這些條款和條件`// I accept these terms and conditions + }, + welcome: { + description: `作為初次安裝的一部分,下面的幾個步驟將指導你如何設定你的Parity和相關帳戶。我們的目標是使得使用Parity變得儘可能的簡單,讓你成功執行,所以請有點耐心。 一旦完成,你將擁有`, + // As part of a new installation, the next few steps will guide you through the process of setting up you Parity instance and your associated accounts.Our aim is to make it as simple as possible and to get you up and running in record-time, so please bear with us.Once completed you will have - + greeting: `歡迎使用Parity,這是執行以太坊節點的最快和最簡單的方式。`, // Welcome to Parity, the fastest and simplest way to run your node. + next: `點選下一步繼續`, // Click Next to continue your journey. + step: { + account: `建立你的第一個Parity帳戶`, // Created your first Parity account + privacy: `理解你的隱私政策和運作條款`, // Understood our privacy policy & terms of operation + recovery: `有能力可以恢復你的帳戶`// Have the ability to recover your account + } + } +}; diff --git a/js/src/i18n/zh-Hant-TW/home.js b/js/src/i18n/zh-Hant-TW/home.js new file mode 100644 index 000000000..7e5592c15 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/home.js @@ -0,0 +1,38 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + account: { + visited: `已訪問{when}` // accessed {when} + }, + accounts: { + none: `沒有可用的近期帳戶歷史`, // No recent accounts history available + title: `近期帳戶` // Recent Accounts + }, + dapp: { + visited: `已訪問{when}` // accessed {when} + }, + dapps: { + none: `沒有可用的近期應用歷史`, // No recent Applications history available + title: `近期Dapps` // Recent Dapps + }, + title: `Parity首頁`, // Parity Home + url: { + none: `沒有可用的近期URL歷史`, // No recent URL history available + title: `網頁應用`, // Web Applications + visited: `已訪問{when}` // visited {when} + } +}; diff --git a/js/src/i18n/zh-Hant-TW/index.js b/js/src/i18n/zh-Hant-TW/index.js new file mode 100644 index 000000000..7b20b6249 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/index.js @@ -0,0 +1,105 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +import account from './account'; +import accounts from './accounts'; +import addAddress from './addAddress'; +import addContract from './addContract'; +import address from './address'; +import addressSelect from './addressSelect'; +import addresses from './addresses'; +import application from './application'; +import connection from './connection'; +import contract from './contract'; +import contracts from './contracts'; +import createAccount from './createAccount'; +import createWallet from './createWallet'; +import dapp from './dapp'; +import dapps from './dapps'; +import deleteAccount from './deleteAccount'; +import deployContract from './deployContract'; +import editMeta from './editMeta'; +import errors from './errors'; +import executeContract from './executeContract'; +import extension from './extension'; +import faucet from './faucet'; +import firstRun from './firstRun'; +import home from './home'; +import loadContract from './loadContract'; +import parityBar from './parityBar'; +import passwordChange from './passwordChange'; +import saveContract from './saveContract'; +import settings from './settings'; +import shapeshift from './shapeshift'; +import signer from './signer'; +import status from './status'; +import tabBar from './tabBar'; +import transfer from './transfer'; +import txEditor from './txEditor'; +import ui from './ui'; +import upgradeParity from './upgradeParity'; +import vaults from './vaults'; +import verification from './verification'; +import wallet from './wallet'; +import walletSettings from './walletSettings'; +import web from './web'; +import writeContract from './writeContract'; + +export default { + account, + accounts, + addAddress, + addContract, + address, + addresses, + addressSelect, + application, + connection, + contract, + contracts, + createAccount, + createWallet, + dapp, + dapps, + deleteAccount, + deployContract, + editMeta, + errors, + executeContract, + extension, + faucet, + firstRun, + home, + loadContract, + parityBar, + passwordChange, + saveContract, + settings, + signer, + shapeshift, + status, + tabBar, + transfer, + txEditor, + ui, + upgradeParity, + vaults, + verification, + wallet, + walletSettings, + web, + writeContract +}; diff --git a/js/src/i18n/zh-Hant-TW/loadContract.js b/js/src/i18n/zh-Hant-TW/loadContract.js new file mode 100644 index 000000000..b99054349 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/loadContract.js @@ -0,0 +1,43 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + cancel: `取消`, // Cancel + load: `載入`, // Load + no: `否`, // No + yes: `是` // Yes + }, + contract: { + savedAt: `已儲存{when}` // Saved {when} + }, + header: { + saved: `已儲存的合約`, // Saved Contracts + snippets: `合約片段` // Contract Snippets + }, + removal: { + confirm: `你確定要將以下合約從已儲存的合約中刪除嗎?`, // Are you sure you want to remove the following contract from your saved contracts? + savedAt: `已儲存{when}` // Saved {when} + }, + tab: { + local: `本地`, // Local + snippets: `片段` // Snippets + }, + title: { + remove: `確認刪除`, // confirm removal + view: `檢視合約` // view contracts + } +}; diff --git a/js/src/i18n/zh-Hant-TW/parityBar.js b/js/src/i18n/zh-Hant-TW/parityBar.js new file mode 100644 index 000000000..e68b27a54 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/parityBar.js @@ -0,0 +1,29 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + close: `關閉` // Close + }, + label: { + parity: `Parity`, // Parity + signer: `Signer` // Singer + }, + title: { + accounts: `預設帳戶`, // Default Account + signer: `Parity Signer:待處理` // Parity Signer: Pending + } +}; diff --git a/js/src/i18n/zh-Hant-TW/passwordChange.js b/js/src/i18n/zh-Hant-TW/passwordChange.js new file mode 100644 index 000000000..e6e54b9b4 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/passwordChange.js @@ -0,0 +1,54 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + cancel: `取消`, // Cancel + change: `更改`, // Change + test: `測試`, // Test + wait: `請等待...` // Wait... + }, + currentPassword: { + hint: `此帳戶的原密碼`, // your current password for this account + label: `原密碼` // current password + }, + newPassword: { + hint: `此帳戶的新密碼`, // the new password for this account + label: `新密碼` // new password + }, + passwordHint: { + display: `提示{hint}`, // Hint {hint} + hint: `新密碼的提示`, // hint for the new password + label: `(可選)新的密碼提示` // (optional) new password hint + }, + repeatPassword: { + error: `所提供的密碼不正確`, // the supplied passwords do not match + hint: `請重複此帳戶的新密碼`, // repeat the new password for this account + label: `重複新密碼` // repeat new password + }, + success: `你的密碼已經成功更改`, // Your password has been successfully changed + tabChange: { + label: `更改密碼` // Change Password + }, + tabTest: { + label: `測試密碼` // Test Password + }, + testPassword: { + hint: `你的帳戶密碼`, // your account password + label: `密碼` // password + }, + title: `密碼管理器` // Password Manager +}; diff --git a/js/src/i18n/zh-Hant-TW/saveContract.js b/js/src/i18n/zh-Hant-TW/saveContract.js new file mode 100644 index 000000000..10075e62d --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/saveContract.js @@ -0,0 +1,27 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + cancel: `取消`, // Cancel + save: `儲存` // Save + }, + name: { + hint: `為此合約選擇一個名稱`, // choose a name for this contract + label: `合約名稱` // contract name + }, + title: `儲存合約` // save contract +}; diff --git a/js/src/i18n/zh-Hant-TW/settings.js b/js/src/i18n/zh-Hant-TW/settings.js new file mode 100644 index 000000000..bf026c384 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/settings.js @@ -0,0 +1,126 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + background: { + button_more: `生成更多`, // generate more + overview_0: `你現在所看到的背景圖案在你的Parity安裝中是獨一無二的。每次創造一個新的Signer令牌都會改變一次圖案。這也保證了去中性化應用不能偽裝成可信的樣子。`, + // The background pattern you can see right now is unique to your Parity installation. It will change every time you create a new + // Signer token. This is so that decentralized applications cannot pretend to be trustworthy. + overview_1: `選擇一個你喜歡的圖案並記住它的樣子。這個圖案從現在開始會經常出現,除非你清空了瀏覽器的快取或者使用了新的Signer令牌。`, + // Pick a pattern you like and memorize it. This Pattern will always be shown from now on, unless you clear your browser cache or + // use a new Signer token. + label: `背景` // background + }, + parity: { + chains: { + chain_classic: `將Parity同步至以太坊經典網路`, // Parity syncs to the Ethereum Classic network + chain_dev: `將Parity使用一條本地開發用區塊鏈`, // Parity uses a local development chain + chain_expanse: `將Parity同步至Expanse網路`, // Parity syncs to the Expanse network + chain_foundation: `將Parity同步至以太坊基金會發起的以太坊網路`, // Parity syncs to the Ethereum network launched by the Ethereum Foundation + chain_kovan: `將Parity同步至Kovan測試網路`, // Parity syncs to the Kovan test network + chain_olympic: `將Parity同步至Olympic測試網路`, // Parity syncs to the Olympic test network + chain_ropsten: `將Parity同步至Ropsten測試網路`, // Parity syncs to the Ropsten test network + cmorden_kovan: `將Parity同步至Morden(經典)測試網路`, // Parity syncs to Morden (Classic) test network + hint: `Parity節點同步的區塊鏈`, // the chain for the Parity node to sync to + label: `將同步的區塊鏈/網路` // chain/network to sync + }, + languages: { + hint: `此介面顯示的語言`, // the language this interface is displayed with + label: `介面語言` // UI language + }, + loglevels: `選擇一個不同的logs層次`, // Choose the different logs level. + modes: { + hint: `Parity節點的同步模式`, // the syncing mode for the Parity node + label: `執行模式`, // mode of operation + mode_active: `Parity持續地同步區塊鏈`, // Parity continuously syncs the chain + mode_dark: `Parity只有在RPC啟用時才同步`, // Parity syncs only when the RPC is active + mode_offline: `Parity不同步`, // Parity doesn't sync + mode_passive: `Parity初始同步,然後進入休眠並有規律地再同步` // Parity syncs initially, then sleeps and wakes regularly to resync + }, + overview_0: `通過此介面控制Parity節點設定和同步設定`, // Control the Parity node settings and nature of syncing via this interface. + label: `parity` // parity + }, + proxy: { + details_0: `除了通過IP地址和埠來訪問Parity,你也能通過.parity子域名來使用Parity,訪問 {homeProxy}。為了設定基於子域名的路由,你需要新增相關的代理記錄至你的瀏覽器。`, + // Instead of accessing Parity via the IP address and port, you will be able to access it via the .parity subdomain, by visiting + // {homeProxy}. To setup subdomain-based routing, you need to add the relevant proxy entries to your browser, + details_1: `如果想了解如何配置代理,教程已提供在{windowsLink},{macOSLink}和{ubuntuLink}。`, + // To learn how to configure the proxy, instructions are provided for {windowsLink}, {macOSLink} or {ubuntuLink}. + details_macos: `macOS`, // macOS + details_ubuntu: `Ubuntu`, // Ubuntu + details_windows: `Windows`, // Windows + overview_0: `代理設定使你可以通過一個可記憶的地址來訪問Parity和所有相關的去中性化應用。`, + // The proxy setup allows you to access Parity and all associated decentralized applications via memorable addresses. + label: `代理` // proxy + }, + views: { + accounts: { + description: `一個此Parity例項所關聯和匯入的所有帳戶的列表。傳送交易、接收流入價值、管理你的帳目和資助你的帳戶。`, + // A list of all the accounts associated with and imported into this Parity instance. Send transactions, receive incoming values, + // manage your balances and fund your accounts. + label: `帳戶` // Accounts + }, + addresses: { + description: `一個此Parity例項管理的所有聯絡人和地址簿記錄的列表。只需點選一個按鈕就可以觀察帳戶並獲得所有交易相關的資訊。`, + // A list of all contacts and address book entries managed by this Parity instance. Watch accounts and have the details available + // at the click of a button when transacting. + label: `地址簿` // Addressbook + }, + apps: { + description: `與整個底層網路交流的分散式應用。新增應用,管理你的應用庫和與網路上的其他應用進行互動。`, + // Distributed applications that interact with the underlying network. Add applications, manage you application portfolio and + // interact with application from around the network. + label: `應用` // Applications + }, + contracts: { + description: `觀察和互動已經被部署在網路上的特定合約。這是一個更注重技術的環境,特別為可以理解合約內部執行機制的高階使用者所設立。`, + // Watch and interact with specific contracts that have been deployed on the network. This is a more technically-focused environment, + // specifically for advanced users that understand the inner working of certain contracts. + label: `合約` // Contracts + }, + overview_0: `僅可視部分對你可用的應用來管理應用介面`, + // Manage the available application views using only the parts of the application applicable to you. + overview_1: `你是終端使用者?預設設定為初學者和高階使用者進行了相同的設定。`, + // Are you an end-user? The defaults are setup for both beginner and advanced users alike. + overview_2: `你是開發者?新增一些功能來管理合約和與應用部署互動。`, + // Are you a developer? Add some features to manage contracts and interact with application deployments. + overview_3: `你是礦工或者運營一個大型節點?新增一些功能來讓你獲得更多有關節點執行的資訊。`, + // Are you a miner or run a large-scale node? Add the features to give you all the information needed to watch the node operation. + settings: { + description: `此介面。允許你自定義應用的選項、執行、視覺化和感官。`, + // This view. Allows you to customize the application in term of options, operation and look and feel. + label: `設定` // Settings + }, + signer: { + description: `這個應用安全交易管理區域,你可以通過任何從本應用和其他分散式應用發起的即將傳送的交易`, + // The secure transaction management area of the application where you can approve any outgoing transactions made + // from the application as well as those placed into the queue by distributed applications. + label: `Signer` // Signer + }, + status: { + description: `觀察Parity節點現在的執行情況:網路連線數、實際執行例項的Logs和具體挖礦資訊(如果已開啟並設定)`, + // See how the Parity node is performing in terms of connections to the network, logs from the actual running instance + // and details of mining (if enabled and configured). + label: `狀態` // Status + }, + label: `視窗`, // views + home: { + label: `首頁` // Home + } + }, + label: `設定` // settings +}; diff --git a/js/src/i18n/zh-Hant-TW/shapeshift.js b/js/src/i18n/zh-Hant-TW/shapeshift.js new file mode 100644 index 000000000..bbcf0c94f --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/shapeshift.js @@ -0,0 +1,76 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + awaitingDepositStep: { + awaitingConfirmation: `正在等待你的{typeSymbol}資金交易的存款地址的確認資訊`, + // Awaiting confirmation of the deposit address for your {typeSymbol} funds exchange + awaitingDeposit: `{shapeshiftLink}正在等待{typeSymbol}的存入.從你的{typeSymbol}網路客戶端傳送資金至-`, + // {shapeshiftLink} is awaiting a {typeSymbol} deposit. Send the funds from your {typeSymbol} network client to - + minimumMaximum: `{minimum}至少, {maximum}至多` // {minimum} minimum, {maximum} maximum + }, + awaitingExchangeStep: { + awaitingCompletion: `正在完成資金交易併發送資金至你的Parity帳戶`, + // Awaiting the completion of the funds exchange and transfer of funds to your Parity account. + receivedInfo: `{shapeshiftLink}已經收到存款-` + // {shapeshiftLink} has received a deposit of - + }, + button: { + cancel: `取消`, // Cancel + done: `關閉`, // Close + shift: `轉換資金` // Shift Funds + }, + completedStep: { + completed: `{shapeshiftLink}已經完成了資金交易。`, // {shapeshiftLink} has completed the funds exchange. + parityFunds: `資金的改變會馬上在你的Parity帳戶裡體現。` + // The change in funds will be reflected in your Parity account shortly. + }, + errorStep: { + info: `通過{shapeshiftLink}進行的資金轉換因為一個交易的致命錯誤失敗了。交易提供的錯誤資訊如下:` + // The funds shifting via {shapeshiftLink} failed with a fatal error on the exchange. The error message received from the exchange + // is as follow: + }, + optionsStep: { + noPairs: `目前沒有可匹配的交易/貨幣可用來進行轉換`, + // There are currently no exchange pairs/coins available to fund with. + returnAddr: { + hint: `轉換錯誤後的發回地址`, // the return address for send failures + label: `(可選){coinSymbol}發回地址` // (optional) {coinSymbol} return address + }, + terms: { + label: `我理解ShapeShift.io是一個第三方服務,使用此服務發生的任何資訊/資金髮送是完全不受Parity控制的` + // I understand that ShapeShift.io is a 3rd-party service and by using the service any transfer of information and/or funds is + // completely out of the control of Parity + }, + typeSelect: { + hint: `數字貨幣轉換的種類`, // the type of crypto conversion to do + label: `來自資金帳戶` // fund account from + } + }, + price: { + minMax: `({minimum}至小, {maximum}至大)` // ({minimum} minimum, {maximum} maximum) + }, + title: { + completed: `完成`, // completed + deposit: `等待存款`, // awaiting deposit + details: `詳情`, // details + error: `交易失敗`, // exchange failed + exchange: `等待交易` // awaiting exchange + }, + warning: { + noPrice: `所選擇的型別沒有匹配的價格` // No price match was found for the selected type + } +}; diff --git a/js/src/i18n/zh-Hant-TW/signer.js b/js/src/i18n/zh-Hant-TW/signer.js new file mode 100644 index 000000000..df816d734 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/signer.js @@ -0,0 +1,107 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + embedded: { + noPending: `目前沒有待處理的確認等待你的處理` + // There are currently no pending requests awaiting your confirmation + }, + mainDetails: { + editTx: `編輯條款/gas/gasPrice`, // Edit conditions/gas/gasPrice + tooltips: { + total1: `包括交易費的交易的總價值是{total} {type}`, + // The value of the transaction including the mining fee is {total} {type}. + total2: `(包括了交易費 {fee} {token})`, + // (This includes a mining fee of {fee} {token}) + value1: `交易價值` // The value of the transaction. + } + }, + requestOrigin: { + dapp: `來自dapp {url}`, // by a dapp at {url} + ipc: `通過IPC會話`, // via IPC session + rpc: `通過RPC{rpc}`, // via RPC {rpc} + signerCurrent: `通過當前標籤頁`, // via current tab + signerUI: `通過互動會話`, // via UI session + unknownInterface: `通過未知互動`, // via unknown interface + unknownRpc: `未明確的`, // unidentified + unknownUrl: `未知URL` // unknown URL + }, + requestsPage: { + noPending: `沒有請求需要你的確認`, // There are no requests requiring your confirmation. + pendingTitle: `待處理請求`, // Pending Requests + queueTitle: `本地交易` // Local Transactions + }, + sending: { + hardware: { + confirm: `請在你連線的硬體裝置上確認交易`, // Please confirm the transaction on your attached hardware device + connect: `請在確認交易前連線你的硬體裝置` // Please attach your hardware device before confirming the transaction + } + }, + signRequest: { + request: `一個簽名資料在請求你的帳號:`, // A request to sign data using your account: + state: { + confirmed: `通過`, // Confirmed + rejected: `拒絕` // Rejected + }, + unknownBinary: `(未知二進位制資料)`, // (Unknown binary data) + warning: `警告:此操作的結果是不可逆的。請在確認資訊後再通過請求。` + // WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure. + }, + title: `可信的Signer`, // Trusted Signer + txPending: { + buttons: { + viewToggle: `檢視交易` // view transaction + } + }, + txPendingConfirm: { + buttons: { + confirmBusy: `通過中...`, // Confirming... + confirmRequest: `通過請求` // Confirm Request + }, + errors: { + invalidWallet: `所提供的錢包檔案不可用` // Given wallet file is invalid. + }, + password: { + decrypt: { + hint: `解金鑰匙`, // decrypt the key + label: `鑰匙密碼` // Key Password + }, + unlock: { + hint: `解鎖帳戶`, // unlock the account + label: `帳戶密碼` // Account Password + } + }, + passwordHint: `(提示){passwordHint}`, // (hint) {passwordHint} + selectKey: { + hint: `此帳戶的鑰匙檔案`, // The keyfile to use for this account + label: `選擇本地鑰匙` // Select Local Key + }, + tooltips: { + password: `請為此帳戶提供密碼` // Please provide a password for this account + } + }, + txPendingForm: { + changedMind: `我改主意了`, // I've changed my mind + reject: `拒絕請求` // reject request + }, + txPendingReject: { + buttons: { + reject: `拒絕請求` // Reject Request + }, + info: `你確定要拒絕請求嗎?`, // Are you sure you want to reject request? + undone: `此操作是不可逆的` // This cannot be undone + } +}; diff --git a/js/src/i18n/zh-Hant-TW/status.js b/js/src/i18n/zh-Hant-TW/status.js new file mode 100644 index 000000000..1c98f8a0b --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/status.js @@ -0,0 +1,67 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + debug: { + reverse: `翻轉訂單`, // Reverse Order + stopped: `Parity的互動目前停止了重新整理和顯示Logs,請啟動它來檢視最新的更新。`, + // Refresh and display of logs from Parity is currently stopped via the UI, start it to see the latest updates. + title: `節點Logs` // Node Logs + }, + miningSettings: { + input: { + author: { + hint: `礦工名字`, // the mining author + label: `礦工` // author + }, + extradata: { + hint: `提取挖到區塊的資料`, // extra data for mined blocks + label: `提取資料` // extradata + }, + gasFloor: { + hint: `挖礦的gas下限目標`, // the gas floor target for mining + label: `gas下限目標` // gas floor target + }, + gasPrice: { + hint: `挖礦的最低gas價格`, // the minimum gas price for mining + label: `最低gas價格` // minimal gas price + } + }, + title: `挖礦設定` // mining settings + }, + status: { + hashrate: `{hashrate} H/s`, // {hashrate} H/s + input: { + chain: `鏈`, // chain + enode: `enode`, // enode + no: `否`, // no + peers: `同步節點`, // peers + port: `網路埠`, // network port + rpcEnabled: `rpc開啟`, // rpc enabled + rpcInterface: `rpc互動`, // rpc interface + rpcPort: `rpc埠`, // rpc port + yes: `是` // yes + }, + title: { + bestBlock: `最新區塊`, // best block + hashRate: `雜湊率`, // hash rate + network: `網路設定`, // network settings + node: `節點`, // Node + peers: `同步節點` // peers + } + }, + title: `狀態` // Status +}; diff --git a/js/src/i18n/zh-Hant-TW/tabBar.js b/js/src/i18n/zh-Hant-TW/tabBar.js new file mode 100644 index 000000000..73ccabf96 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/tabBar.js @@ -0,0 +1,22 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + tooltip: { + overview: `在應用的不同部分和不同介面進行導航,在帳戶介面、代幣介面和分散式應用介面之間切換。` + // navigate between the different parts and views of the application, switching between an account view, token view and distributed application view + } +}; diff --git a/js/src/i18n/zh-Hant-TW/transfer.js b/js/src/i18n/zh-Hant-TW/transfer.js new file mode 100644 index 000000000..76bb1f701 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/transfer.js @@ -0,0 +1,62 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + advanced: { + data: { + hint: `交易附帶資料`, // the data to pass through with the transaction + label: `交易資料`// transaction data + } + }, + buttons: { + back: `返回`, // Back + cancel: `取消`, // Cancel + close: `關閉`, // Close + next: `下一步`, // Next + send: `傳送`// Send + }, + details: { + advanced: { + label: `高階傳送選項`// advanced sending options + }, + amount: { + hint: `傳送數額`, // the amount to transfer to the recipient + label: `傳送數額{tag}`// amount to transfer (in {tag}) + }, + fullBalance: { + label: `所有的餘額`// full account balance + }, + recipient: { + hint: `收款人地址`, // the recipient address + label: `收款人地址`// recipient address + }, + sender: { + hint: `傳送人地址`, // the sender address + label: `傳送人地址`// sender address + }, + total: { + label: `傳送數額`// total transaction amount + } + }, + wallet: { + confirmation: `這筆交易需要其他人的確認。`, // This transaction needs confirmation from other owners. + operationHash: `操作雜湊`// operation hash + }, + warning: { + wallet_spent_limit: `這筆轉帳的數額超過了每日轉帳數額上限。此交易需要其他人的確認才可以傳送成功。` + // This transaction value is above the remaining daily limit. It will need to be confirmed by other owners. + } +}; diff --git a/js/src/i18n/zh-Hant-TW/txEditor.js b/js/src/i18n/zh-Hant-TW/txEditor.js new file mode 100644 index 000000000..812d9be38 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/txEditor.js @@ -0,0 +1,40 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + condition: { + block: { + hint: `在某個區塊高度後傳送`, // The minimum block to send from + label: `交易傳送區塊`// Transaction send block + }, + blocknumber: `在某個區塊後傳送`, // Send after BlockNumber + date: { + hint: `在某日後傳送`, // The minimum date to send from + label: `交易傳送日期`// Transaction send date + }, + datetime: `在某日某時後傳送`, // Send after Date & Tim + label: `交易啟用的條件`, // Condition where transaction activates + none: `無條件`, // No conditions + time: { + hint: `在某時間後傳送`, // The minimum time to send from + label: `交易傳送時間`// Transaction send time + } + }, + gas: { + info: `你可以基於最近的交易gas價格的分佈選擇gas價格。 gas價格越低,交易費用越便宜。 gas 價格越高,交易被網路打包的速度越快。` + // You can choose the gas price based on the distribution of recent included transaction gas prices.The lower the gas price is, the cheaper the transaction will be.The higher the gas price is, the faster it should get mined by the network. + } +}; diff --git a/js/src/i18n/zh-Hant-TW/ui.js b/js/src/i18n/zh-Hant-TW/ui.js new file mode 100644 index 000000000..c7e4e3790 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/ui.js @@ -0,0 +1,163 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + actionbar: { + export: { + button: { + export: `匯出`// export + } + }, + import: { + button: { + cancel: `取消`, // Cancel + confirm: `確認`, // Confirm + import: `匯入`// import + }, + confirm: `確認這是你想匯入的`, // Confirm that this is what was intended to import. + error: `發生錯誤:{errorText}`, // An error occured: {errorText} + step: { + error: `錯誤`, // error + select: `選擇一個檔案`, // select a file + validate: `確認`// validate + }, + title: `從一個檔案匯入`// Import from a file + }, + search: { + hint: `輸入搜尋內容……`// Enter search input... + }, + sort: { + sortBy: `根據{label}排序`, // Sort by {label} + typeDefault: `預設`, // Default + typeEth: `根據以太幣數額排序`, // Sort by ETH + typeName: `根據帳戶名字排序`, // Sort by name + typeTags: `根據標籤排序`// Sort by tags + } + }, + balance: { + none: `這個帳戶沒有餘額`// No balances associated with this account + }, + blockStatus: { + bestBlock: `最新區塊{blockNumber}`, // {blockNumber} best block + syncStatus: `currentBlock}/{highestBlock}區塊同步`, // {currentBlock}/{highestBlock} syncing{ + warpRestore: `{percentage}%恢復`, // {percentage}% warp restore + warpStatus: `, {percentage}%歷史`// {percentage}% historic + }, + confirmDialog: { + no: `不是`, // no + yes: `是`// yes + }, + copyToClipboard: { + copied: `複製{data}到貼上板`// copied {data} to clipboard + }, + errors: { + close: `關閉`// close + }, + fileSelect: { + defaultLabel: `拉一個檔案到這裡,或者選擇一個檔案上傳`// Drop a file here, or click to select a file to upload + }, + gasPriceSelector: { + customTooltip: { + transactions: `{number} {number, plural, one {transaction} other {transactions}} with gas price set from {minPrice} to {maxPrice}` + } + }, + identityName: { + null: `空`, // NULL + unnamed: `未命名`// UNNAMED + }, + methodDecoding: { + condition: { + block: `, {historic, select, true {Submitted} false {Submission}} at block {blockNumber}`, + time: `, {historic, select, true {Submitted} false {Submission}} at {timestamp}` + }, + deploy: { + address: `在地址上部署一個合約`, // Deployed a contract at address + params: `附帶下面的引數:`, // with the following parameters: + willDeploy: `將要部署一個合約`, // Will deploy a contract + withValue: `, 傳送{value}`// sending {value} + }, + gasUsed: `({gas}gas消耗)`, // {gas} gas used + gasValues: `{gas} gas ({gasPrice}M/{tag})`, + input: { + data: `資料`, // data + input: `輸入`, // input + withInput: `with the {inputDesc} {inputValue}` + }, + receive: { + contract: `合約`, // the contract + info: `{historic, select, true {Received} false {Will receive}} {valueEth} from {aContract}{address}` + }, + signature: { + info: `{historic, select, true {Executed} false {Will execute}} the {method} function on the contract {address} trsansferring {ethValue}{inputLength, plural, zero {,} other {passing the following {inputLength, plural, one {parameter} other {parameters}}}}` + }, + token: { + transfer: `{historic, select, true {Transferred} false {Will transfer}} {value} to {address}` + }, + transfer: { + contract: `the contract`, + info: `{historic, select, true {Transferred} false {Will transfer}} {valueEth} to {aContract}{address}` + }, + txValues: `{historic, select, true {Provided} false {Provides}} {gasProvided}{gasUsed} for a total transaction value of {totalEthValue}`, + unknown: { + info: `{historic, select, true {Executed} false {Will execute}} the {method} on the contract {address} transferring {ethValue}.` + } + }, + passwordStrength: { + label: `密碼強度`// password strength + }, + tooltips: { + button: { + done: `完成`, // Done + next: `下一步`, // Next + skip: `跳過`// Skip + } + }, + txHash: { + confirmations: `{count} {value, plural, one {confirmation} other {confirmations}}`, + oog: `這筆交易已經耗光了gas。請用更多的gas嘗試。`, // The transaction might have gone out of gas. Try again with more gas. + posted: `這筆交易已經被髮送到網路,附帶雜湊是{hashLink}`, // The transaction has been posted to the network with a hash of {hashLink} + waiting: `等待確認`// waiting for confirmations + }, + vaultSelect: { + hint: `這個帳戶繫結的保險庫是`, // the vault this account is attached to + label: `相關保險庫`// associated vault + }, + verification: { + gatherData: { + accountHasRequested: { + false: `.你還沒有從這個帳戶請求確認。`, // You did not request verification from this account yet + pending: `檢查一下你是否請求了驗證……`, // Checking if you requested verification… + true: `你已經從這個帳戶請求到驗證。`// You already requested verification from this account. + }, + accountIsVerified: { + false: `你的帳戶還沒有被驗證。`, // Your account is not verified yet. + pending: `檢查一下你的帳戶是否已經被驗證……`, // Checking if your account is verified… + true: `你的帳戶已經被驗證。`// Your account is already verified. + }, + fee: `額外的費用是{amount}ETH`, // The additional fee is {amount} ETH. + isAbleToRequest: { + pending: `驗證你的輸入……`// Validating your input… + }, + isServerRunning: { + false: `驗證伺服器沒有在執行。`, // The verification server is not running. + pending: `檢查一下驗證伺服器是否在執行……`, // Checking if the verification server is running… + true: `驗證伺服器正在執行。`// The verification server is running. + }, + nofee: `沒有額外的費用。`, // There is no additional fee. + termsOfService: `我同意下面的條款和條件。`// I agree to the terms and conditions below. + } + } +}; diff --git a/js/src/i18n/zh-Hant-TW/upgradeParity.js b/js/src/i18n/zh-Hant-TW/upgradeParity.js new file mode 100644 index 000000000..fc6a60304 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/upgradeParity.js @@ -0,0 +1,55 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + busy: `你正在升級到Parity最新版本{newversion}。請等待升級過程完成。`, + // Your upgrade to Parity {newversion} is currently in progress. Please wait until the process completes. + button: { + close: `關閉`, // close + done: `完成`, // done + upgrade: `現在升級`// upgrade now + }, + completed: `你升級到Parity最新版本{newversion}的操作已經完成。點選“完成”將自動重新載入這個應用。`, + // Your upgrade to Parity {newversion} has been successfully completed. Click "done" to automatically reload the application. + consensus: { + capable: `你當前的Parity版本能夠處理網路請求。`, + // Your current Parity version is capable of handling the network requirements. + capableUntil: `你當前的Parity版本能夠處理直到第{blockNumber}個區塊的網路請求。`, + // Your current Parity version is capable of handling the network requirements until block {blockNumber} + incapableSince: `你當前的Parity版本能夠處理第{blockNumber}個區塊以後的網路請求。`, + // Your current Parity version is incapable of handling the network requirements since block {blockNumber} + unknown: `你當前的Parity版本能夠處理網路請求。` + // Your current Parity version is capable of handling the network requirements. + }, + failed: `升級到Parity最新版本{newversion}遇到錯誤,升級失敗。`, + // Your upgrade to Parity {newversion} has failed with an error. + info: { + currentVersion: `你現在正在執行{currentversion}版本。`, // You are currently running {currentversion} + next: `點選“現在升級”,開始Parity升級。`, // Proceed with "upgrade now" to start your Parity upgrade. + upgrade: `可以升級到最新版本{newversion}`, // An upgrade to version {newversion} is available + welcome: `迎來到Parity升級指南,讓你享受無縫升級到Parity最新版本的體驗。` + // Welcome to the Parity upgrade wizard, allowing you a completely seamless upgrade experience to the next version of Parity.歡 + }, + step: { + completed: `升級完成`, // upgrade completed + error: `錯誤`, // error + info: `可以升級`, // upgrade available + updating: `升級Parity`// upgrading parity + }, + version: { + unknown: `未知`// unknown + } +}; diff --git a/js/src/i18n/zh-Hant-TW/vaults.js b/js/src/i18n/zh-Hant-TW/vaults.js new file mode 100644 index 000000000..ffd6c4646 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/vaults.js @@ -0,0 +1,114 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + accounts: { + button: { + cancel: `取消`, // Cancel + execute: `設定` // Set + }, + empty: `此保險庫中沒有帳戶`, // There are no accounts in this vault + title: `管理保險庫帳戶` // Manage Vault Accounts + }, + button: { + accounts: `帳戶`, // accounts + add: `建立保險庫`, // create vault + close: `關閉`, // close + edit: `編輯`, // edit + open: `開啟` // open + }, + confirmClose: { + info: `你即將關閉一個保險庫。所有與這個保險庫相關的帳戶在這個操作完成後都不再可見。如果想再見到關聯帳戶,請重新開啟保險庫。`, + // You are about to close a vault. Any accounts associated with the vault won't be visible after this operation concludes. To view + // the associated accounts, open the vault again. + title: `關閉保險庫` // Close Vault + }, + confirmOpen: { + info: `你即將開啟一個保險庫。在確認了你的密碼之後,所有與這個保險庫關聯的帳戶都會可見。關閉保險庫會在介面中移除所有帳戶,直到保險庫被再次開啟。`, + // You are about to open a vault. After confirming your password, all accounts associated with this vault will be visible. Closing + // the vault will remove the accounts from view until the vault is opened again. + password: { + hint: `建立保險庫時設定的密碼`, // the password specified when creating the vault + label: `保險庫密碼` // vault password + }, + title: `開啟保險庫` // Open Vault + }, + create: { + button: { + close: `關閉`, // close + vault: `建立保險庫` // create valut + }, + description: { + hint: `該保險庫更詳細的描述` // an extended description for the vault + }, + descriptions: { + label: `(可選)描述` // (optional) description + }, + hint: { + hint: `(可選)一個幫助記憶密碼的提示`, // (optional) a hint to help with remembering the password + label: `密碼提示` // password hint + }, + name: { + hint: `一個保險庫的名字`, // a name for the vault + label: `保險庫名稱` // vault name + }, + password: { + hint: `一個高強度且獨一無二的密碼`, // a strong, unique password + label: `密碼` // password + }, + password2: { + hint: `驗證你的密碼`, // verify your password + label: `密碼(重複)` // password (repeat) + }, + title: `建立一個新的保險庫` // Create a new vault + }, + editMeta: { + allowPassword: `更改保險庫密碼`, // Change vault password + button: { + close: `關閉`, // close + save: `儲存` // save + }, + currentPassword: { + hint: `保險庫的原密碼`, // your current vault password + label: `原密碼` // current password + }, + description: { + hint: `此保險庫的描述`, // the description for this vault + label: `保險庫描述` // vault description + }, + password: { + hint: `一個高強度且獨一無二的密碼`, // a strong, unique password + label: `新密碼` // new password + }, + password2: { + hint: `驗證你的新密碼`, // verify your new password + label: `新密碼(重複)` // new password (repeat) + }, + passwordHint: { + hint: `此保險庫的密碼提示`, // your password hint for this vault + label: `密碼提示` // password hint + }, + title: `編輯保險庫元資料` // Edit Vault Metadata + }, + empty: `目前沒有任何可顯示的保險庫`, // There are currently no vaults to display. + selector: { + noneAvailable: `目前沒有任何開啟、可選的保險庫。請在移動帳戶之前建立並開啟一個保險庫。`, + // There are currently no vaults opened and available for selection. Create and open some first before attempting to select + // a vault for an account move. + title: `選擇帳戶保險庫` // Select Account Vault + }, + title: `保險庫管理` // Vault Management +}; diff --git a/js/src/i18n/zh-Hant-TW/verification.js b/js/src/i18n/zh-Hant-TW/verification.js new file mode 100644 index 000000000..d5efa8fac --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/verification.js @@ -0,0 +1,85 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + button: { + cancel: `取消`, // Cancel + done: `完成`, // Done + next: `下一步`// Next + }, + code: { + error: `無效驗證碼`, // invalid code + hint: `輸入你收到的驗證碼。`, // Enter the code you received. + label: `驗證碼`, // verification code + sent: `驗證碼被髮送到接收者{receiver}.`// The verification code has been sent to {receiver} + }, + confirmation: { + authorise: `驗證碼將被髮送到合約。請使用Parity Signer進行授權。`, // The verification code will be sent to the contract. Please authorize this using the Parity Signer. + windowOpen: `請保持這個視窗開啟狀態。`// Please keep this window open. + }, + done: { + message: `恭喜,你的帳戶已經被認證。`// Congratulations, your account is verified! + }, + email: { + enterCode: `輸入你從郵箱獲得驗證碼。`// Enter the code you received via e-mail. + }, + gatherData: { + email: { + hint: `驗證碼將被髮送到這個地址`, // the code will be sent to this address + label: `郵箱地址`// e-mail address + }, + phoneNumber: { + hint: `簡訊將被髮送到這個號碼`, // the SMS will be sent to this number + label: `國際格式的手機號碼`// phone number in international format + } + }, + gatherDate: { + email: { + error: `無效郵箱`// invalid e-mail + }, + phoneNumber: { + error: `無效數字`// invalid number + } + }, + loading: `載入驗證資料`, // Loading verification data. + request: { + authorise: `驗證請求將被髮送到這個合約。請使用Parity Signer進行授權。`, // A verification request will be sent to the contract. Please authorize this using the Parity Signer. + requesting: `正在從Parity伺服器請求一個驗證碼,等待它被輸入到合約。`, // Requesting a code from the Parity server and waiting for the puzzle to be put into the contract. + windowOpen: `請保持視窗為開啟狀態。`// Please keep this window open. + }, + sms: { + enterCode: `輸入你從簡訊收到的驗證碼。`// Enter the code you received via SMS. + }, + steps: { + code: `輸入驗證碼`, // Enter Code + completed: `完成`, // Completed + confirm: `確認`, // Confirm + data: `輸入資料`, // Enter Data + method: `方式`, // Method + request: `請求`// Request + }, + title: `t驗證你的帳戶`, // verify your accoun + types: { + email: { + description: `你所控制的郵箱地址的雜湊值將被儲存在區塊鏈。`, // The hash of the e-mail address you prove control over will be stored on the blockchain. + label: `郵箱驗證`// E-mail Verification + }, + sms: { + description: `你所控制的手機號碼將被儲存在區塊鏈。`, // It will be stored on the blockchain that you control a phone number (not which). + label: `簡訊驗證`// SMS Verification + } + } +}; diff --git a/js/src/i18n/zh-Hant-TW/wallet.js b/js/src/i18n/zh-Hant-TW/wallet.js new file mode 100644 index 000000000..4c864e40f --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/wallet.js @@ -0,0 +1,46 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + edit: `編輯`, // edit + forget: `forget`, + settings: `設定`, // settings + transfer: `轉帳`// transfer + }, + confirmations: { + buttons: { + confirmAs: `確定為……`, // Confirm As... + revokeAs: `撤回為……`// Revoke As... + }, + none: `現在沒有交易需要確認。`, // No transactions needs confirmation right now. + tooltip: { + confirmed: `被{number}/{required}所有人確認`// Confirmed by {number}/{required} owners + } + }, + details: { + requiredOwners: `這個錢包需要至少{owners}所有人驗證所有的操作(交易,修改)`, + // This wallet requires at least {owners} to validate any action (transactions, modifications). + requiredOwnersNumber: `{number} {numberValue, plural, one {owner} other {owners}}`, + spent: `{spent} has been spent today, out of {limit} set as the daily limit, which has been reset on {date}`, + title: `細節`// Details + }, + title: `錢包管理`, // Wallet Management + transactions: { + none: `沒有交易被髮送。`, // No transactions has been sent. + title: `交易`// Transactions + } +}; diff --git a/js/src/i18n/zh-Hant-TW/walletSettings.js b/js/src/i18n/zh-Hant-TW/walletSettings.js new file mode 100644 index 000000000..f59b2bb6a --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/walletSettings.js @@ -0,0 +1,75 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + addOwner: { + title: `新增持有人` // Add Owner + }, + buttons: { + cancel: `取消`, // Cancel + close: `關閉`, // Close + next: `下一個`, // Next + send: `傳送`, // Send + sending: `正在傳送...` // Sending... + }, + changes: { + modificationString: `為了保證你做的修改會被執行, + 其他的帳戶持有人也需要傳送相同的修改。 + 他們可以通過貼上以下字串來簡單的完成更改:`, + // For your modifications to be taken into account, + // other owners have to send the same modifications. They can paste + // this string to make it easier: + none: `錢包設定沒有發生任何更改。`, // No modifications have been made to the Wallet settings. + overview: `你將會造成以下更改` // You are about to make the following modifications + }, + edit: { + message: `為了編輯這個合約的設定,至少{owners, number} + {owners, plural, one {owner } other {owners }}必須傳送完全相同的修改 + 你可以將字串化的修改貼上在這裡。` + // In order to edit this contract's settings, at + // least {owners, number} {owners, plural, one {owner } other {owners }} have to + // send the very same modifications. You can paste a stringified version + // of the modifications here. + }, + modifications: { + daylimit: { + hint: `不需要確認即可傳送的ETH數量`, // amount of ETH spendable without confirmations + label: `錢包每日限額` // wallet day limit + }, + fromString: { + label: `修改` // modifications + }, + owners: { + label: `其他錢包持有人` // other wallet owners + }, + required: { + hint: `確認交易所需的通過持有人人數`, // number of required owners to accept a transaction + label: `所需持有人` // required owners + }, + sender: { + hint: `作為此持有人傳送修改`, // send modifications as this owner + label: `來自帳戶 (wallet owner)` // from account (wallet owner) + } + }, + ownersChange: { + details: `從 {from} 至 {to}`, // from {from} to {to} + title: `改變所需持有人` + }, + rejected: `交易#{txid}已經被拒絕`, // The transaction #{txid} has been rejected + removeOwner: { + title: `移除持有人` // Remove Owner + } +}; diff --git a/js/src/i18n/zh-Hant-TW/web.js b/js/src/i18n/zh-Hant-TW/web.js new file mode 100644 index 000000000..290b3e0a3 --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/web.js @@ -0,0 +1,19 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + requestToken: `正在請求使用代幣` // Requesting access token... +}; diff --git a/js/src/i18n/zh-Hant-TW/writeContract.js b/js/src/i18n/zh-Hant-TW/writeContract.js new file mode 100644 index 000000000..37656b56d --- /dev/null +++ b/js/src/i18n/zh-Hant-TW/writeContract.js @@ -0,0 +1,62 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default { + buttons: { + autoCompile: `自動編譯`, // Auto-Compile + compile: `編譯`, // Compile + deploy: `部署`, // Deploy + import: `載入Solidity`, // Import Solidity + load: `載入`, // Load + new: `新建`, // New + optimise: `優化`, // Optimise + save: `儲存` // Save + }, + compiling: { + action: `請編譯原始碼`, // Please compile the source code. + busy: `編譯中...` // Compiling... + }, + details: { + saved: `(已儲存 {timestamp})` // (saved {timestamp}) + }, + error: { + noContract: `沒有找到合約`, // No contract has been found. + params: `發生瞭如下描述的一個錯誤` // An error occurred with the following description + }, + input: { + abi: `ABI介面`, // ABI Interface + code: `位元組碼`, // Bytecode + metadata: `元資料`, // Metadata + swarm: `Swarm元資料雜湊` // Sarm Metadata Hash + }, + title: { + contract: `選擇一個合約`, // Select a contract + loading: `載入中...`, // Loading... + main: `寫一個合約`, // Write a Contract + messages: `編譯器訊息`, // Compiler messages + new: `新建Solidity合約`, // New Solidity Contract + parameters: `變數`, // Parameters + saved: `已儲存 @ {timestamp}`, // saved @ {timestamp} + selectSolidity: `選擇Solidity版本`, // Select a Solidity version + solidity: `正在載入Solidity {version}` // Loading Solidity {version} + }, + type: { + humanErc20: `Human代幣合約編碼`, // Implementation of the Human Token Contract + implementErc20: `ERC20代幣合約編碼`, // Implementation of the ERC20 Token Contract + multisig: `多籤錢包編碼`, // Implementation of a multisig Wallet + standardErc20: `標準ERC20代幣合約` // Standard ERC20 Token Contract + } +}; diff --git a/js/src/i18n/zh/account.js b/js/src/i18n/zh/account.js index 7c9d25520..2a8febc28 100644 --- a/js/src/i18n/zh/account.js +++ b/js/src/i18n/zh/account.js @@ -16,24 +16,24 @@ export default { button: { - delete: `delete`, - edit: `edit`, - faucet: `Kovan ETH`, - password: `password`, + delete: `删除`, // delete + edit: `编辑`, // edit + faucet: `Kovan测试网络以太币`, // Kovan ETH + password: `密码`, // password shapeshift: `shapeshift`, - transfer: `transfer`, - verify: `verify` + transfer: `转账`, // transfer + verify: `确认`// verify }, hardware: { - confirmDelete: `Are you sure you want to remove the following hardware address from your account list?` - }, + confirmDelete: `你确定从你的账户列表中移除下面的硬件地址吗?` + }, // Are you sure you want to remove the following hardware address from your account list? header: { - outgoingTransactions: `{count} outgoing transactions`, + outgoingTransactions: `{count}笔正在发生的转账`, // {count} outgoing transactions uuid: `uuid: {uuid}` }, - title: `Account Management`, + title: `账户管理`, // Account Management transactions: { - poweredBy: `Transaction list powered by {etherscan}`, - title: `transactions` + poweredBy: `Transaction list powered by {etherscan}提供的交易列表`, + title: `交易`// transactions } }; diff --git a/js/src/i18n/zh/accounts.js b/js/src/i18n/zh/accounts.js index 2db3d5fd9..78b18fc4b 100644 --- a/js/src/i18n/zh/accounts.js +++ b/js/src/i18n/zh/accounts.js @@ -16,19 +16,21 @@ export default { button: { - newAccount: `account`, - newWallet: `wallet`, - vaults: `vaults` + newAccount: `账户`, // account + newWallet: `钱包`, // wallet + vaults: `保险库`// vaults }, summary: { - minedBlock: `Mined at block #{blockNumber}` + minedBlock: `在第#{blockNumber}个区块被挖出`// Mined at block #{blockNumber} }, - title: `Accounts Overview`, + title: `账户总览`, // Accounts Overview tooltip: { - actions: `actions relating to the current view are available on the toolbar for quick access, be it for performing actions or creating a new item`, - overview: `your accounts are visible for easy access, allowing you to edit the meta information, make transfers, view transactions and fund the account` + actions: `与当前视窗有关的操作可以在工具栏中快速被找到,不论是执行操作还是创建新项`, + // actions relating to the current view are available on the toolbar for quick access, be it for performing actions or creating a new item + overview: `你的账户很容易使用,使你可以编辑元信息、转账、查看交易和向账户充值` + // your accounts are visible for easy access, allowing you to edit the meta information, make transfers, view transactions and fund the account }, tooltips: { - owner: `{name} (owner)` + owner: `{name}持有者`// {name} (owner) } }; diff --git a/js/src/i18n/zh/addAddress.js b/js/src/i18n/zh/addAddress.js index 59ae71518..f80042102 100644 --- a/js/src/i18n/zh/addAddress.js +++ b/js/src/i18n/zh/addAddress.js @@ -16,23 +16,26 @@ export default { button: { - add: `Save Address`, - close: `Cancel` + add: `保存地址`, // Save Address + close: `取消` // Cancel }, - header: `To add a new entry to your addressbook, you need the network address of the account and can supply an optional description. Once added it will reflect in your address book.`, + header: `如果想在地址簿中添加一条新的记录,你需要拥有账户的网络地址并提供一个的描述(可选)。一旦添加,记录就可以体现在你的地址簿中。`, + // To add a new entry to your addressbook, you need the network + // address of the account and can supply an optional description. + // Once added it will reflect in your address book. input: { address: { - hint: `the network address for the entry`, - label: `network address` + hint: `记录的网络地址`, // the network address for the entry + label: `网络地址` // network address }, description: { - hint: `an expanded description for the entry`, - label: `(optional) address description` + hint: `记录的详细描述`, // an expanded description for the entry + label: `(可选)地址描述` // (optional) address description }, name: { - hint: `a descriptive name for the entry`, - label: `address name` + hint: `记录的名字`, // a descriptive name for the entry + label: `地址名` // address name } }, - label: `add saved address` + label: `添加已保存的地址` // add saved address }; diff --git a/js/src/i18n/zh/addContract.js b/js/src/i18n/zh/addContract.js index edbecf118..c45a37b3a 100644 --- a/js/src/i18n/zh/addContract.js +++ b/js/src/i18n/zh/addContract.js @@ -16,45 +16,45 @@ export default { abi: { - hint: `the abi for the contract`, - label: `contract abi` + hint: `合约的ABI`, // the abi for the contract + label: `合约ABI` // contract abi }, abiType: { custom: { - description: `Contract created from custom ABI`, - label: `Custom Contract` + description: `通过自定义ABI创造的合约`, // Contract created from custom ABI + label: `自定义合约` // Custom Contract }, multisigWallet: { - description: `Ethereum Multisig contract {link}`, - label: `Multisig Wallet`, - link: `see contract code` + description: `以太坊多重签名合约{link}`, // Ethereum Multisig contract {link} + label: `多重签名钱包`, // Multisig Wallet + link: `参考合约代码` // see contract code }, token: { - description: `A standard {erc20} token`, - erc20: `ERC 20`, - label: `Token` + description: `一个标准的{erc20}代币`, // A standard {erc20} token + erc20: `ERC 20`, // ERC 20 + label: `代币` // Token } }, address: { - hint: `the network address for the contract`, - label: `network address` + hint: `合约的网络地址`, // the network address for the contract + label: `网络地址` // network address }, button: { - add: `Add Contract`, - cancel: `Cancel`, - next: `Next`, - prev: `Back` + add: `添加合约`, // Add Contract + cancel: `取消`, // Cancel + next: `下一步`, // Next + prev: `上一步` // Back }, description: { - hint: `an expanded description for the entry`, - label: `(optional) contract description` + hint: `记录的详细描述`, // an expanded description for the entry + label: `(可选)合约描述` // (optional) contract description }, name: { - hint: `a descriptive name for the contract`, - label: `contract name` + hint: `合约的描述性名称`, // a descriptive name for the contract + label: `合约名` // contract name }, title: { - details: `enter contract details`, - type: `choose a contract type` + details: `输入合约细节`, // enter contract details + type: `选择合约种类` // choose a contract type } }; diff --git a/js/src/i18n/zh/address.js b/js/src/i18n/zh/address.js index ec06d4237..f9328afed 100644 --- a/js/src/i18n/zh/address.js +++ b/js/src/i18n/zh/address.js @@ -16,13 +16,13 @@ export default { buttons: { - edit: `edit`, - forget: `forget`, - save: `save` + edit: `编辑`, // edit + forget: `忘记`, // forget + save: `保存`// save }, delete: { - confirmInfo: `Are you sure you want to remove the following address from your addressbook?`, - title: `confirm removal` + confirmInfo: `你确定你想把下面的地址从你的地址簿中移除吗?`, // Are you sure you want to remove the following address from your addressbook? + title: `确认移除`// confirm removal }, - title: `Address Information` + title: `地址信息`// Address Information }; diff --git a/js/src/i18n/zh/addressSelect.js b/js/src/i18n/zh/addressSelect.js index 108ac80f5..5c45a49a1 100644 --- a/js/src/i18n/zh/addressSelect.js +++ b/js/src/i18n/zh/addressSelect.js @@ -15,12 +15,12 @@ // along with Parity. If not, see . export default { - fromEmail: `Verified using email {email}`, - fromRegistry: `{name} (from registry)`, + fromEmail: `使用邮箱{email}进行确认`, // Verified using email {email} + fromRegistry: `{name}(来自注册)`, // {name} (from registry) labels: { - accounts: `accounts`, - contacts: `contacts`, - contracts: `contracts` + accounts: `账户`, // accounts + contacts: `合约`, // contacts + contracts: `合约`// contracts }, - noAccount: `No account matches this query...` + noAccount: `查不到这个账户`// No account matches this query... }; diff --git a/js/src/i18n/zh/addresses.js b/js/src/i18n/zh/addresses.js index 00bb28272..5e3bd26f0 100644 --- a/js/src/i18n/zh/addresses.js +++ b/js/src/i18n/zh/addresses.js @@ -16,10 +16,10 @@ export default { buttons: { - add: `address` + add: `地址` // address }, errors: { - invalidFile: `The provided file is invalid...` + invalidFile: `提供的文件是无效的`// The provided file is invalid... }, - title: `Saved Addresses` + title: `保存的地址`// Saved Addresses }; diff --git a/js/src/i18n/zh/application.js b/js/src/i18n/zh/application.js index 4469d83b2..62412c2d2 100644 --- a/js/src/i18n/zh/application.js +++ b/js/src/i18n/zh/application.js @@ -16,15 +16,15 @@ export default { frame: { - error: `ERROR: This application cannot and should not be loaded in an embedded iFrame` + error: `错误:这个应用不能也不应该载入到内置框架中`// ERROR: This application cannot and should not be loaded in an embedded iFrame }, status: { consensus: { - capable: `Capable`, - capableUntil: `Capable until #{blockNumber}`, - incapableSince: `Incapable since #{blockNumber}`, - unknown: `Unknown capability` + capable: `可行`, // Capable + capableUntil: `到第 #{blockNumber} 区块前可行`, // Capable until #{blockNumber} + incapableSince: `自第 #{blockNumber} 区块后不可行`, // Incapable since #{blockNumber} + unknown: `未知能力`// Unknown capability }, - upgrade: `Upgrade` + upgrade: `升级`// Upgrade } }; diff --git a/js/src/i18n/zh/connection.js b/js/src/i18n/zh/connection.js index e51943178..45cf05cf5 100644 --- a/js/src/i18n/zh/connection.js +++ b/js/src/i18n/zh/connection.js @@ -13,14 +13,18 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . - export default { - connectingAPI: `Connecting to the Parity Secure API.`, - connectingNode: `Connecting to the Parity Node. If this informational message persists, please ensure that your Parity node is running and reachable on the network.`, - invalidToken: `invalid signer token`, - noConnection: `Unable to make a connection to the Parity Secure API. To update your secure token or to generate a new one, run {newToken} and paste the generated token into the space below.`, + connectingAPI: `正在连接至Parity Secure API`, // Connecting to the Parity Secure API. + connectingNode: `正在连接Parity节点。如果弹出任何信息,请确认你的Parity节点正在运行并连接至互联网。`, + // Connecting to the Parity Node. If this informational message persists, + // please ensure that your Parity node is running and reachable on the network. + invalidToken: `无效的签名令牌`, // invalid signer token + noConnection: `无法连接至Parity Secure API。请升级的你的安全令牌或者生成一个新的,运行{newToken}并粘贴生成的令牌到下方。`, + // Unable to make a connection to the Parity Secure API. To update your secure + // token or to generate a new one, run {newToken} and paste the generated token + // into the space below. token: { - hint: `a generated token from Parity`, - label: `secure token` + hint: `一个Parity生成的令牌`, // a generated token from Parity + label: `安全令牌` // secure token } }; diff --git a/js/src/i18n/zh/contract.js b/js/src/i18n/zh/contract.js index bf7f00298..ad97a85fb 100644 --- a/js/src/i18n/zh/contract.js +++ b/js/src/i18n/zh/contract.js @@ -16,26 +16,26 @@ export default { buttons: { - close: `Close`, - details: `details`, - edit: `edit`, - execute: `execute`, - forget: `forget` + close: `关闭`, // close + details: `详细资料`, // details + edit: `编辑`, // edit + execute: `运行`, // execute + forget: `forget` // forget }, details: { - title: `contract details` + title: `合约细节` // contract details }, events: { - eventPending: `pending`, - noEvents: `No events has been sent from this contract.`, - title: `events` + eventPending: `待定中`, // pending + noEvents: `此合约没有发送过任何事件`, // No events has been sent from this contract. + title: `事件` // events }, - minedBlock: `Mined at block #{blockNumber}`, + minedBlock: `挖到了第{blockNumber}个区块`, // Mined at block #{blockNumber} queries: { buttons: { - query: `Query` + query: `查询` // Query }, - title: `queries` + title: `查询` // queries }, - title: `Contract Information` + title: `合约信息` // Contract Information }; diff --git a/js/src/i18n/zh/contracts.js b/js/src/i18n/zh/contracts.js index 4ff840759..a1cdec5af 100644 --- a/js/src/i18n/zh/contracts.js +++ b/js/src/i18n/zh/contracts.js @@ -16,13 +16,13 @@ export default { buttons: { - deploy: `deploy`, - develop: `develop`, - watch: `watch` + deploy: `部署`, // deploy + develop: `开发`, // develop + watch: `观察` // watch }, sortOrder: { - date: `date`, - minedBlock: `mined block` + date: `日期`, // date + minedBlock: `挖到的区块` // mined block }, - title: `Contracts` + title: `合约` // Contracts }; diff --git a/js/src/i18n/zh/createWallet.js b/js/src/i18n/zh/createWallet.js index eeb9e9a98..76a0e2797 100644 --- a/js/src/i18n/zh/createWallet.js +++ b/js/src/i18n/zh/createWallet.js @@ -16,91 +16,91 @@ export default { button: { - add: `Add`, - cancel: `Cancel`, - close: `Close`, - create: `Create`, - done: `Done`, - next: `Next`, - sending: `Sending...` + add: `添加`, // Add + cancel: `取消`, // Cancel + close: `关闭`, // Close + create: `创建`, // Create + done: `完成`, // Done + next: `下一步`, // Next + sending: `发送中...` // Sending... }, deployment: { - message: `The deployment is currently in progress` + message: `部署正在进行中` // The deployment is currently in progress }, details: { address: { - hint: `the wallet contract address`, - label: `wallet address` + hint: `钱包的合约地址`, // the wallet contract address + label: `钱包地址` // wallet address }, dayLimitMulti: { - hint: `amount of ETH spendable without confirmations`, - label: `wallet day limit` + hint: `无需确认即可使用的ETH数量`, // amount of ETH spendable without confirmations + label: `钱包每日限额` // wallet day limit }, description: { - hint: `the local description for this wallet`, - label: `wallet description (optional)` + hint: `本地钱包描述`, // the local description for this wallet + label: `钱包描述(可选)` // wallet description (optional) }, descriptionMulti: { - hint: `the local description for this wallet`, - label: `wallet description (optional)` + hint: `本地钱包描述`, // the local description for this wallet + label: `钱包描述(可选)` // wallet description (optional) }, name: { - hint: `the local name for this wallet`, - label: `wallet name` + hint: `钱包本地名称`, // the local name for this wallet + label: `钱包名称` // wallet name }, nameMulti: { - hint: `the local name for this wallet`, - label: `wallet name` + hint: `钱包本地名称`, // the local name for this wallet + label: `钱包名称` // wallet name }, ownerMulti: { - hint: `the owner account for this contract`, - label: `from account (contract owner)` + hint: `合约的持有者账户`, // the owner account for this contract + label: `从账户 (contract owner)` // from account (contract owner) }, ownersMulti: { - label: `other wallet owners` + label: `其他钱包持有者` // other wallet owners }, ownersMultiReq: { - hint: `number of required owners to accept a transaction`, - label: `required owners` + hint: `接受交易所需的持有者人数`, // number of required owners to accept a transaction + label: `所需持有者` // required owners } }, info: { - added: `added`, - copyAddress: `copy address to clipboard`, - created: `{name} has been {deployedOrAdded} at`, - dayLimit: `The daily limit is set to {dayLimit} ETH.`, - deployed: `deployed`, - numOwners: `{numOwners} owners are required to confirm a transaction.`, - owners: `The following are wallet owners` + added: `已添加`, // added + copyAddress: `复制地址至粘贴板`, // copy address to clipboard + created: `{name}已被{deployedOrAdded}至`, // {name} has been {deployedOrAdded} at + dayLimit: `每日限额已被设置为{dayLimit}ETH`, // The daily limit is set to {dayLimit} ETH. + deployed: `已部署`, // deployed + numOwners: `需要{numOwners}个持有者才能确认一个交易`, // {numOwners} owners are required to confirm a transaction. + owners: `以下为钱包持有者` // The following are wallet owners }, rejected: { - message: `The deployment has been rejected`, - state: `The wallet will not be created. You can safely close this window.`, - title: `rejected` + message: `部署被拒绝`, // The deployment has been rejected + state: `钱包不会被创建。你可以安全地关闭本窗口`, // The wallet will not be created. You can safely close this window. + title: `失败` // rejected }, states: { - completed: `The contract deployment has been completed`, - confirmationNeeded: `The contract deployment needs confirmations from other owners of the Wallet`, - preparing: `Preparing transaction for network transmission`, - validatingCode: `Validating the deployed contract code`, - waitingConfirm: `Waiting for confirmation of the transaction in the Parity Secure Signer`, - waitingReceipt: `Waiting for the contract deployment transaction receipt` + completed: `合约部署已完成`, // The contract deployment has been completed + confirmationNeeded: `合约部署需要来自本钱包的其他持有者的确认`, // The contract deployment needs confirmations from other owners of the Wallet + preparing: `交易正在准备被网络广播`, // Preparing transaction for network transmission + validatingCode: `正在验证已部署的代码`, // Validating the deployed contract code + waitingConfirm: `正在等待Parity Secure Signer确认本交易`, // Waiting for confirmation of the transaction in the Parity Secure Signer + waitingReceipt: `正在等待合约部署交易收据` // Waiting for the contract deployment transaction receipt }, steps: { - deployment: `wallet deployment`, - details: `wallet details`, - info: `wallet informaton`, - type: `wallet type` + deployment: `钱包部署`, // wallet deployment + details: `钱包详情`, // wallet details + info: `钱包信息`, // wallet informaton + type: `钱包类别` // wallet type }, type: { multisig: { - description: `Create/Deploy a {link} Wallet`, - label: `Multi-Sig wallet`, - link: `standard multi-signature` + description: `创建/部署一个{link}钱包`, // Create/Deploy a {link} Wallet + label: `多重签名钱包`, // Multi-Sig Wallet + link: `标准多重签名` // standard multi-signature }, watch: { - description: `Add an existing wallet to your accounts`, - label: `Watch a wallet` + description: `添加一个已有钱包到你的账户`, // Add an existing wallet to your accounts + label: `观察钱包` // Watch a wallet } } }; diff --git a/js/src/i18n/zh/dapp.js b/js/src/i18n/zh/dapp.js index 29dd2fd16..c23e47f13 100644 --- a/js/src/i18n/zh/dapp.js +++ b/js/src/i18n/zh/dapp.js @@ -15,6 +15,6 @@ // along with Parity. If not, see . export default { - loading: `Loading`, - unavailable: `The dapp cannot be reached` + loading: `正在加载`, // Loading + unavailable: `不能获取这个dapp`// The dapp cannot be reached }; diff --git a/js/src/i18n/zh/dapps.js b/js/src/i18n/zh/dapps.js index 9ed3415d1..74fea9b0d 100644 --- a/js/src/i18n/zh/dapps.js +++ b/js/src/i18n/zh/dapps.js @@ -17,29 +17,32 @@ export default { add: { builtin: { - desc: `Experimental applications developed by the Parity team to show off dapp capabilities, integration, experimental features and to control certain network-wide client behaviour.`, - label: `Applications bundled with Parity` + desc: `Parity团队开发的实验性的,用以展示dapp的性能、集成、实验性特性和控制特定网络的的客户端行为`, + // Experimental applications developed by the Parity team to show off dapp capabilities, integration, experimental features and to control certain network-wide client behaviour. + label: `与Parity绑定的应用`// Applications bundled with Parity }, - label: `visible applications`, + label: `visible applications可见的应用`, // visible applications local: { desc: `All applications installed locally on the machine by the user for access by the Parity client.`, - label: `Applications locally available` + label: `本地可用的应用`// Applications locally available }, network: { - desc: `These applications are not affiliated with Parity nor are they published by Parity. Each remain under the control of their respective authors. Please ensure that you understand the goals for each application before interacting.`, - label: `Applications on the global network` + desc: `这些应用与Parity没有关联,也不是Parity发布的。 它们是由各自的作者控制的。 在使用以前,请确保你理解每个应用的目标。`, + // These applications are not affiliated with Parity nor are they published by Parity.Each remain under the control of their respective authors.Please ensure that you understand the goals for each application before interacting. + label: `全球网络上的应用`// Applications on the global network } }, button: { - edit: `edit`, - permissions: `permissions` + edit: `编辑`, // edit + permissions: `许可`// permissions }, external: { - accept: `I understand that these applications are not affiliated with Parity`, - warning: `Applications made available on the network by 3rd-party authors are not affiliated with Parity nor are they published by Parity. Each remain under the control of their respective authors. Please ensure that you understand the goals for each before interacting.` + accept: `我理解这些应用和Parity没有关联`, // I understand that these applications are not affiliated with Parity + warning: `第三方开发者开发的应用与Parity没有关联,也不是Parity发布的。 它们是由各自的作者控制的。 在使用以前,请确保你理解每个应用的目标。` + // Applications made available on the network by 3rd-party authors are not affiliated with Parity nor are they published by Parity. Each remain under the control of their respective authors. Please ensure that you understand the goals for each before interacting. }, - label: `Decentralized Applications`, + label: `去中心化应用`, // Decentralized Applications permissions: { - label: `visible dapp accounts` + label: `可见的dapp账户`// visible dapp accounts } }; diff --git a/js/src/i18n/zh/deleteAccount.js b/js/src/i18n/zh/deleteAccount.js index 4818a785a..f879c60a1 100644 --- a/js/src/i18n/zh/deleteAccount.js +++ b/js/src/i18n/zh/deleteAccount.js @@ -16,9 +16,9 @@ export default { password: { - hint: `provide the account password to confirm the account deletion`, - label: `account password` + hint: `提供账户密码,确认删除账户`, // provide the account password to confirm the account deletion + label: `账户密码`// account password }, - question: `Are you sure you want to permanently delete the following account?`, - title: `confirm removal` + question: `你确定你想永久地删除下面的账户?`, // Are you sure you want to permanently delete the following account? + title: `确认删除`// confirm removal }; diff --git a/js/src/i18n/zh/deployContract.js b/js/src/i18n/zh/deployContract.js index 0b5a05503..a07047d1c 100644 --- a/js/src/i18n/zh/deployContract.js +++ b/js/src/i18n/zh/deployContract.js @@ -16,75 +16,75 @@ export default { busy: { - title: `The deployment is currently in progress` + title: `部署正在进行中`// The deployment is currently in progress }, button: { - cancel: `Cancel`, - close: `Close`, - create: `Create`, - done: `Done`, - next: `Next` + cancel: `取消`, // Cancel + close: `关闭`, // Close + create: `创建`, // Create + done: `完成`, // Done + next: `下一个`// Next }, completed: { - description: `Your contract has been deployed at` + description: `你的合约已经被部署在`// Your contract has been deployed at }, details: { abi: { - hint: `the abi of the contract to deploy or solc combined-output`, - label: `abi / solc combined-output` + hint: `合约的abi或者solc 组合输出`, // the abi of the contract to deploy or solc combined-output + label: `abi / solc 组合输出 `// abi / solc combined-output }, address: { - hint: `the owner account for this contract`, - label: `from account (contract owner)` + hint: `这个合约所有者的账户`, // the owner account for this contract + label: `来自账户(合约所有者)`// from account (contract owner) }, advanced: { - label: `advanced sending options` + label: `高级的发送选项`// advanced sending options }, amount: { - hint: `the amount to transfer to the contract`, - label: `amount to transfer (in {tag})` + hint: `转到这个合约中的数额`, // the amount to transfer to the contract + label: `发送数额{tag}`// amount to transfer (in {tag}) }, code: { - hint: `the compiled code of the contract to deploy`, - label: `code` + hint: `编译好的合约代码`, // the compiled code of the contract to deploy + label: `代码`// code }, contract: { - label: `select a contract` + label: `选择一个合约`// select a contract }, description: { - hint: `a description for the contract`, - label: `contract description (optional)` + hint: `对这个合约的描述`, // a description for the contract + label: `合约描述(可选)`// contract description (optional) }, name: { - hint: `a name for the deployed contract`, - label: `contract name` + hint: `已经部署合约的名字`, // a name for the deployed contract + label: `合约名字`// contract name } }, owner: { - noneSelected: `a valid account as the contract owner needs to be selected` + noneSelected: `选择一个有效的地址作为合约的所有者`// a valid account as the contract owner needs to be selected }, parameters: { - choose: `Choose the contract parameters` + choose: `选择合约参数`// Choose the contract parameters }, rejected: { - description: `You can safely close this window, the contract deployment will not occur.`, - title: `The deployment has been rejected` + description: `你可以安全地关闭窗口,合约部署不会发生。`, // You can safely close this window, the contract deployment will not occur. + title: `部署已经被拒绝`// The deployment has been rejected }, state: { - completed: `The contract deployment has been completed`, - confirmationNeeded: `The operation needs confirmations from the other owners of the contract`, - preparing: `Preparing transaction for network transmission`, - validatingCode: `Validating the deployed contract code`, - waitReceipt: `Waiting for the contract deployment transaction receipt`, - waitSigner: `Waiting for confirmation of the transaction in the Parity Secure Signer` + completed: `合约部署已经完成`, // The contract deployment has been completed + confirmationNeeded: `这一操作需要这个合约其他所有人的确认。`, // The operation needs confirmations from the other owners of the contract + preparing: `为网络传输准备交易`, // Preparing transaction for network transmission + validatingCode: `验证已经部署的合约的代码`, // Validating the deployed contract code + waitReceipt: `等待合约部署交易收据`, // Waiting for the contract deployment transaction receipt + waitSigner: `等待Parity Secure Signer中的交易被确认 `// Waiting for confirmation of the transaction in the Parity Secure Signer }, title: { - completed: `completed`, - deployment: `deployment`, - details: `contract details`, - extras: `extra information`, - failed: `deployment failed`, - parameters: `contract parameters`, - rejected: `rejected` + completed: `完成`, // completed + deployment: `部署`, // deployment + details: `合约细节`, // contract details + extras: `额外信息`, // extra information + failed: `部署失败`, // deployment failed + parameters: `s合约参数`, // contract parameter + rejected: `拒绝`// rejected } }; diff --git a/js/src/i18n/zh/editMeta.js b/js/src/i18n/zh/editMeta.js index b5b521341..29efa726e 100644 --- a/js/src/i18n/zh/editMeta.js +++ b/js/src/i18n/zh/editMeta.js @@ -16,19 +16,19 @@ export default { description: { - hint: `description for this address`, - label: `address description` + hint: `此地址的描述`, // description for this address + label: `地址描述` // address description }, name: { - label: `name` + label: `名称` // name }, passwordHint: { - hint: `a hint to allow password recovery`, - label: `(optional) password hint` + hint: `密码恢复提示`, // a hint to allow password recovery + label: `(可选)密码提示` // (optional) password hint }, tags: { - hint: `press to add a tag`, - label: `(optional) tags` + hint: `按来添加一个标签`, // press to add a tag + label: `(可选)标签` // (optional) tags }, - title: `edit metadata` + title: `编辑元数据` // edit metadata }; diff --git a/js/src/i18n/zh/errors.js b/js/src/i18n/zh/errors.js index 76fed24cd..8d908acd3 100644 --- a/js/src/i18n/zh/errors.js +++ b/js/src/i18n/zh/errors.js @@ -15,10 +15,10 @@ // along with Parity. If not, see . export default { - duplicateName: `the name already exists`, - invalidKey: `the raw key needs to be hex, 64 characters in length and contain the prefix "0x"`, - noFile: `select a valid wallet file to import`, - noKey: `you need to provide the raw private key`, - noMatchPassword: `the supplied passwords does not match`, - noName: `you need to specify a valid name` + duplicateName: `名称已存在`, // the name already exists + invalidKey: `原始私钥需要被16进制,64个字符长度并以"0x"开头`, // the raw key needs to be hex, 64 characters in length and contain the prefix "0x" + noFile: `选择一个可用的钱包文件来输入`, // select a valid wallet file to import + noKey: `你需要提供原始私钥`, // you need to provide the raw private key + noMatchPassword: `所提供的密码不正确`, // the supplied passwords does not match + noName: `你需要明确一个可用的名称` // you need to specify a valid name }; diff --git a/js/src/i18n/zh/executeContract.js b/js/src/i18n/zh/executeContract.js index 011264d3f..847670edc 100644 --- a/js/src/i18n/zh/executeContract.js +++ b/js/src/i18n/zh/executeContract.js @@ -16,43 +16,43 @@ export default { busy: { - posted: `Your transaction has been posted to the network`, - title: `The function execution is in progress`, - waitAuth: `Waiting for authorization in the Parity Signer` + posted: `你的交易已被公布至网络`, // Your transaction has been posted to the network + title: `函数执行正在进行中`, // The function execution is in progress + waitAuth: `正在等待Parity Signer授权` // Waiting for authorization in the Parity Signer }, button: { - cancel: `cancel`, - done: `done`, - next: `next`, - post: `post transaction`, - prev: `prev` + cancel: `取消`, // cancel + done: `完成`, // done + next: `下一步`, // next + post: `公布交易`, // post transaction + prev: `上一步` // prev }, details: { address: { - hint: `from account`, - label: `the account to transact with` + hint: `来自账户`, // from account + label: `将要交易的账户` // the account to transact with }, advancedCheck: { - label: `advanced sending options` + label: `高级发送选项` // advanced sending options }, amount: { - hint: `the amount to send to with the transaction`, - label: `transaction value (in ETH)` + hint: `此交易将会发送的数量`, // the amount to send to with the transaction + label: `交易价值(ETH)` // transaction value (in ETH) }, function: { - hint: `the function to call on the contract`, - label: `function to execute` + hint: `此合约将会调用的函数`, // the function to call on the contract + label: `将执行的函数` // function to execute } }, rejected: { - state: `You can safely close this window, the function execution will not occur.`, - title: `The execution has been rejected` + state: `你可以安全的关闭此视窗,函数将不会被执行。`, // You can safely close this window, the function execution will not occur. + title: `执行失败` // The execution has been rejected }, steps: { - advanced: `advanced options`, - complete: `complete`, - rejected: `rejected`, - sending: `sending`, - transfer: `function details` + advanced: `高级选项`, // advanced options + complete: `完成`, // complete + rejected: `失败`, // rejected + sending: `发送中`, // sending + transfer: `函数详情` // function details } }; diff --git a/js/src/i18n/zh/extension.js b/js/src/i18n/zh/extension.js index 88ba33674..e79c03667 100644 --- a/js/src/i18n/zh/extension.js +++ b/js/src/i18n/zh/extension.js @@ -15,6 +15,8 @@ // along with Parity. If not, see . export default { - install: `Install the extension now`, - intro: `Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled distributed applications. It is highly recommended that you install this extension to further enhance your Parity experience.` + install: `现在就安装这个扩展`, // Install the extension now + intro: `Parity现在有一个Chrome的扩展,可以安全的浏览以太坊所支持的分布式应用。我们强烈推荐你安装这个扩展来进一步提升你的Parity使用体验。` + // Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled distributed applications. + // It is highly recommended that you install this extension to further enhance your Parity experience. }; diff --git a/js/src/i18n/zh/faucet.js b/js/src/i18n/zh/faucet.js index 11aacef9c..e371b49a2 100644 --- a/js/src/i18n/zh/faucet.js +++ b/js/src/i18n/zh/faucet.js @@ -16,13 +16,14 @@ export default { buttons: { - close: `close`, - done: `close`, - request: `request` + close: `关闭`, // close + done: `关闭`, // close + request: `请求`// request }, summary: { - done: `Your Kovan ETH has been requested from the faucet which responded with -`, - info: `To request a deposit of Kovan ETH to this address, you need to ensure that the address is sms-verified on the mainnet. Once executed the faucet will deposit Kovan ETH into the current account.` + done: `你已经向水龙头请求Kovan ETH测试币`, // Your Kovan ETH has been requested from the faucet which responded with - + info: `如果请求将Kovan ETH测试币存入这个地址,你需要确定这个地址在主网络上已经用短信验证过了。 一旦执行水龙头将向当前账户存入Kovan ETH测试币。` + // To request a deposit of Kovan ETH to this address, you need to ensure that the address is sms-verified on the mainnet.Once executed the faucet will deposit Kovan ETH into the current account. }, - title: `Kovan ETH Faucet` + title: `Kovan ETH测试币水龙头`// Kovan ETH Faucet Kovan }; diff --git a/js/src/i18n/zh/firstRun.js b/js/src/i18n/zh/firstRun.js index 5a3e04a17..92278f2fb 100644 --- a/js/src/i18n/zh/firstRun.js +++ b/js/src/i18n/zh/firstRun.js @@ -16,34 +16,37 @@ export default { button: { - close: `Close`, - create: `Create`, - next: `Next`, - print: `Print Phrase`, - skip: `Skip` + close: `关闭`, // Close + create: `创建`, // Create + next: `下一步`, // Next + print: `打印词组`, // Print Phrase + skip: `跳过`// Skip }, completed: { - congrats: `Congratulations! Your node setup has been completed successfully and you are ready to use the application.`, - next: `Next you will receive a walk-through of the available functions and the general application interface to get you up and running in record time.` + congrats: `恭喜!你的节点设置已经完成,你现在可以使用应用了。`, + // Congratulations! Your node setup has been completed successfully and you are ready to use the application. + next: `下面你将浏览可用的功能和通用的应用界面,让你最快速地使用Parity。` + // Next you will receive a walk-through of the available functions and the general application interface to get you up and running in record time. }, title: { - completed: `completed`, - newAccount: `new account`, - recovery: `recovery`, - terms: `terms`, - welcome: `welcome` + completed: `完成`, // completed + newAccount: `新账户`, // new account + recovery: `恢复`, // recovery + terms: `条款`, // terms + welcome: `欢迎`// welcome }, tnc: { - accept: `I accept these terms and conditions` + accept: `我接受这些条款和条件`// I accept these terms and conditions }, welcome: { - description: `As part of a new installation, the next few steps will guide you through the process of setting up you Parity instance and your associated accounts. Our aim is to make it as simple as possible and to get you up and running in record-time, so please bear with us. Once completed you will have -`, - greeting: `Welcome to Parity, the fastest and simplest way to run your node.`, - next: `Click Next to continue your journey.`, + description: `作为初次安装的一部分,下面的几个步骤将指导你如何设置你的Parity和相关账户。我们的目标是使得使用Parity变得尽可能的简单,让你成功运行,所以请有点耐心。 一旦完成,你将拥有`, + // As part of a new installation, the next few steps will guide you through the process of setting up you Parity instance and your associated accounts.Our aim is to make it as simple as possible and to get you up and running in record-time, so please bear with us.Once completed you will have - + greeting: `欢迎使用Parity,这是运行以太坊节点的最快和最简单的方式。`, // Welcome to Parity, the fastest and simplest way to run your node. + next: `点击下一步继续`, // Click Next to continue your journey. step: { - account: `Created your first Parity account`, - privacy: `Understood our privacy policy & terms of operation`, - recovery: `Have the ability to recover your account` + account: `创建你的第一个Parity账户`, // Created your first Parity account + privacy: `理解你的隐私政策和运作条款`, // Understood our privacy policy & terms of operation + recovery: `有能力可以恢复你的账户`// Have the ability to recover your account } } }; diff --git a/js/src/i18n/zh/home.js b/js/src/i18n/zh/home.js index 0b5e68c04..a17c06ddc 100644 --- a/js/src/i18n/zh/home.js +++ b/js/src/i18n/zh/home.js @@ -16,23 +16,23 @@ export default { account: { - visited: `accessed {when}` + visited: `已访问{when}` // accessed {when} }, accounts: { - none: `No recent accounts history available`, - title: `Recent Accounts` + none: `没有可用的近期账户历史`, // No recent accounts history available + title: `近期账户` // Recent Accounts }, dapp: { - visited: `accessed {when}` + visited: `已访问{when}` // accessed {when} }, dapps: { - none: `No recent Applications history available`, - title: `Recent Dapps` + none: `没有可用的近期应用历史`, // No recent Applications history available + title: `近期Dapps` // Recent Dapps }, - title: `Parity Home`, + title: `Parity首页`, // Parity Home url: { - none: `No recent URL history available`, - title: `Web Applications`, - visited: `visited {when}` + none: `没有可用的近期URL历史`, // No recent URL history available + title: `网页应用`, // Web Applications + visited: `已访问{when}` // visited {when} } }; diff --git a/js/src/i18n/zh/loadContract.js b/js/src/i18n/zh/loadContract.js index d4edb3a81..ab86e5a25 100644 --- a/js/src/i18n/zh/loadContract.js +++ b/js/src/i18n/zh/loadContract.js @@ -16,28 +16,28 @@ export default { button: { - cancel: `Cancel`, - load: `Load`, - no: `No`, - yes: `Yes` + cancel: `取消`, // Cancel + load: `加载`, // Load + no: `否`, // No + yes: `是` // Yes }, contract: { - savedAt: `Saved {when}` + savedAt: `已保存{when}` // Saved {when} }, header: { - saved: `Saved Contracts`, - snippets: `Contract Snippets` + saved: `已保存的合约`, // Saved Contracts + snippets: `合约片段` // Contract Snippets }, removal: { - confirm: `Are you sure you want to remove the following contract from your saved contracts?`, - savedAt: `Saved {when}` + confirm: `你确定要将以下合约从已保存的合约中删除吗?`, // Are you sure you want to remove the following contract from your saved contracts? + savedAt: `已保存{when}` // Saved {when} }, tab: { - local: `Local`, - snippets: `Snippets` + local: `本地`, // Local + snippets: `片段` // Snippets }, title: { - remove: `confirm removal`, - view: `view contracts` + remove: `确认删除`, // confirm removal + view: `查看合约` // view contracts } }; diff --git a/js/src/i18n/zh/parityBar.js b/js/src/i18n/zh/parityBar.js index 94090a961..fb7c7433c 100644 --- a/js/src/i18n/zh/parityBar.js +++ b/js/src/i18n/zh/parityBar.js @@ -16,14 +16,14 @@ export default { button: { - close: `Close` + close: `关闭` // Close }, label: { - parity: `Parity`, - signer: `Signer` + parity: `Parity`, // Parity + signer: `Signer` // Singer }, title: { - accounts: `Default Account`, - signer: `Parity Signer: Pending` + accounts: `默认账户`, // Default Account + signer: `Parity Signer:待处理` // Parity Signer: Pending } }; diff --git a/js/src/i18n/zh/passwordChange.js b/js/src/i18n/zh/passwordChange.js index 714a6e25b..d25ffd5f0 100644 --- a/js/src/i18n/zh/passwordChange.js +++ b/js/src/i18n/zh/passwordChange.js @@ -16,39 +16,39 @@ export default { button: { - cancel: `Cancel`, - change: `Change`, - test: `Test`, - wait: `Wait...` + cancel: `取消`, // Cancel + change: `更改`, // Change + test: `测试`, // Test + wait: `请等待...` // Wait... }, currentPassword: { - hint: `your current password for this account`, - label: `current password` + hint: `此账户的原密码`, // your current password for this account + label: `原密码` // current password }, newPassword: { - hint: `the new password for this account`, - label: `new password` + hint: `此账户的新密码`, // the new password for this account + label: `新密码` // new password }, passwordHint: { - display: `Hint {hint}`, - hint: `hint for the new password`, - label: `(optional) new password hint` + display: `提示{hint}`, // Hint {hint} + hint: `新密码的提示`, // hint for the new password + label: `(可选)新的密码提示` // (optional) new password hint }, repeatPassword: { - error: `the supplied passwords do not match`, - hint: `repeat the new password for this account`, - label: `repeat new password` + error: `所提供的密码不正确`, // the supplied passwords do not match + hint: `请重复此账户的新密码`, // repeat the new password for this account + label: `重复新密码` // repeat new password }, - success: `Your password has been successfully changed`, + success: `你的密码已经成功更改`, // Your password has been successfully changed tabChange: { - label: `Change Password` + label: `更改密码` // Change Password }, tabTest: { - label: `Test Password` + label: `测试密码` // Test Password }, testPassword: { - hint: `your account password`, - label: `password` + hint: `你的账户密码`, // your account password + label: `密码` // password }, - title: `Password Manager` + title: `密码管理器` // Password Manager }; diff --git a/js/src/i18n/zh/saveContract.js b/js/src/i18n/zh/saveContract.js index 62ce1e33f..b92ecf401 100644 --- a/js/src/i18n/zh/saveContract.js +++ b/js/src/i18n/zh/saveContract.js @@ -16,12 +16,12 @@ export default { buttons: { - cancel: `Cancel`, - save: `Save` + cancel: `取消`, // Cancel + save: `保存` // Save }, name: { - hint: `choose a name for this contract`, - label: `contract name` + hint: `为此合约选择一个名称`, // choose a name for this contract + label: `合约名称` // contract name }, - title: `save contract` + title: `保存合约` // save contract }; diff --git a/js/src/i18n/zh/settings.js b/js/src/i18n/zh/settings.js index 3e475e087..3630caa45 100644 --- a/js/src/i18n/zh/settings.js +++ b/js/src/i18n/zh/settings.js @@ -16,86 +16,111 @@ export default { background: { - button_more: `generate more`, - overview_0: `The background pattern you can see right now is unique to your Parity installation. It will change every time you create a new Signer token. This is so that decentralized applications cannot pretend to be trustworthy.`, - overview_1: `Pick a pattern you like and memorize it. This Pattern will always be shown from now on, unless you clear your browser cache or use a new Signer token.`, - label: `background` + button_more: `生成更多`, // generate more + overview_0: `你现在所看到的背景图案在你的Parity安装中是独一无二的。每次创造一个新的Signer令牌都会改变一次图案。这也保证了去中性化应用不能伪装成可信的样子。`, + // The background pattern you can see right now is unique to your Parity installation. It will change every time you create a new + // Signer token. This is so that decentralized applications cannot pretend to be trustworthy. + overview_1: `选择一个你喜欢的图案并记住它的样子。这个图案从现在开始会经常出现,除非你清空了浏览器的缓存或者使用了新的Signer令牌。`, + // Pick a pattern you like and memorize it. This Pattern will always be shown from now on, unless you clear your browser cache or + // use a new Signer token. + label: `背景` // background }, parity: { chains: { - chain_classic: `Parity syncs to the Ethereum Classic network`, - chain_dev: `Parity uses a local development chain`, - chain_expanse: `Parity syncs to the Expanse network`, - chain_foundation: `Parity syncs to the Ethereum network launched by the Ethereum Foundation`, - chain_kovan: `Parity syncs to the Kovan test network`, - chain_olympic: `Parity syncs to the Olympic test network`, - chain_ropsten: `Parity syncs to the Ropsten test network`, - cmorden_kovan: `Parity syncs to Morden (Classic) test network`, - hint: `the chain for the Parity node to sync to`, - label: `chain/network to sync` + chain_classic: `将Parity同步至以太坊经典网络`, // Parity syncs to the Ethereum Classic network + chain_dev: `将Parity使用一条本地开发用区块链`, // Parity uses a local development chain + chain_expanse: `将Parity同步至Expanse网络`, // Parity syncs to the Expanse network + chain_foundation: `将Parity同步至以太坊基金会发起的以太坊网络`, // Parity syncs to the Ethereum network launched by the Ethereum Foundation + chain_kovan: `将Parity同步至Kovan测试网络`, // Parity syncs to the Kovan test network + chain_olympic: `将Parity同步至Olympic测试网络`, // Parity syncs to the Olympic test network + chain_ropsten: `将Parity同步至Ropsten测试网络`, // Parity syncs to the Ropsten test network + cmorden_kovan: `将Parity同步至Morden(经典)测试网络`, // Parity syncs to Morden (Classic) test network + hint: `Parity节点同步的区块链`, // the chain for the Parity node to sync to + label: `将同步的区块链/网络` // chain/network to sync }, languages: { - hint: `the language this interface is displayed with`, - label: `UI language` + hint: `此界面显示的语言`, // the language this interface is displayed with + label: `界面语言` // UI language }, - loglevels: `Choose the different logs level.`, + loglevels: `选择一个不同的logs层次`, // Choose the different logs level. modes: { - hint: `the syncing mode for the Parity node`, - label: `mode of operation`, - mode_active: `Parity continuously syncs the chain`, - mode_dark: `Parity syncs only when the RPC is active`, - mode_offline: `Parity doesn't sync`, - mode_passive: `Parity syncs initially, then sleeps and wakes regularly to resync` + hint: `Parity节点的同步模式`, // the syncing mode for the Parity node + label: `运行模式`, // mode of operation + mode_active: `Parity持续地同步区块链`, // Parity continuously syncs the chain + mode_dark: `Parity只有在RPC激活时才同步`, // Parity syncs only when the RPC is active + mode_offline: `Parity不同步`, // Parity doesn't sync + mode_passive: `Parity初始同步,然后进入休眠并有规律地再同步` // Parity syncs initially, then sleeps and wakes regularly to resync }, - overview_0: `Control the Parity node settings and nature of syncing via this interface.`, - label: `parity` + overview_0: `通过此界面控制Parity节点设置和同步设置`, // Control the Parity node settings and nature of syncing via this interface. + label: `parity` // parity }, proxy: { - details_0: `Instead of accessing Parity via the IP address and port, you will be able to access it via the .parity subdomain, by visiting {homeProxy}. To setup subdomain-based routing, you need to add the relevant proxy entries to your browser,`, - details_1: `To learn how to configure the proxy, instructions are provided for {windowsLink}, {macOSLink} or {ubuntuLink}.`, - details_macos: `macOS`, - details_ubuntu: `Ubuntu`, - details_windows: `Windows`, - overview_0: `The proxy setup allows you to access Parity and all associated decentralized applications via memorable addresses.`, - label: `proxy` + details_0: `除了通过IP地址和端口来访问Parity,你也能通过.parity子域名来使用Parity,访问 {homeProxy}。为了设置基于子域名的路由,你需要添加相关的代理记录至你的浏览器。`, + // Instead of accessing Parity via the IP address and port, you will be able to access it via the .parity subdomain, by visiting + // {homeProxy}. To setup subdomain-based routing, you need to add the relevant proxy entries to your browser, + details_1: `如果想了解如何配置代理,教程已提供在{windowsLink},{macOSLink}和{ubuntuLink}。`, + // To learn how to configure the proxy, instructions are provided for {windowsLink}, {macOSLink} or {ubuntuLink}. + details_macos: `macOS`, // macOS + details_ubuntu: `Ubuntu`, // Ubuntu + details_windows: `Windows`, // Windows + overview_0: `代理设置使你可以通过一个可记忆的地址来访问Parity和所有相关的去中性化应用。`, + // The proxy setup allows you to access Parity and all associated decentralized applications via memorable addresses. + label: `代理` // proxy }, views: { accounts: { - description: `A list of all the accounts associated with and imported into this Parity instance. Send transactions, receive incoming values, manage your balances and fund your accounts.`, - label: `Accounts` + description: `一个此Parity实例所关联和导入的所有账户的列表。发送交易、接收流入价值、管理你的账目和资助你的账户。`, + // A list of all the accounts associated with and imported into this Parity instance. Send transactions, receive incoming values, + // manage your balances and fund your accounts. + label: `账户` // Accounts }, addresses: { - description: `A list of all contacts and address book entries managed by this Parity instance. Watch accounts and have the details available at the click of a button when transacting.`, - label: `Addressbook` + description: `一个此Parity实例管理的所有联系人和地址簿记录的列表。只需点击一个按钮就可以观察账户并获得所有交易相关的信息。`, + // A list of all contacts and address book entries managed by this Parity instance. Watch accounts and have the details available + // at the click of a button when transacting. + label: `地址簿` // Addressbook }, apps: { - description: `Distributed applications that interact with the underlying network. Add applications, manage you application portfolio and interact with application from around the network.`, - label: `Applications` + description: `与整个底层网络交流的分布式应用。添加应用,管理你的应用库和与网络上的其他应用进行交互。`, + // Distributed applications that interact with the underlying network. Add applications, manage you application portfolio and + // interact with application from around the network. + label: `应用` // Applications }, contracts: { - description: `Watch and interact with specific contracts that have been deployed on the network. This is a more technically-focused environment, specifically for advanced users that understand the inner working of certain contracts.`, - label: `Contracts` + description: `观察和交互已经被部署在网络上的特定合约。这是一个更注重技术的环境,特别为可以理解合约内部运行机制的高级用户所设立。`, + // Watch and interact with specific contracts that have been deployed on the network. This is a more technically-focused environment, + // specifically for advanced users that understand the inner working of certain contracts. + label: `合约` // Contracts }, - overview_0: `Manage the available application views using only the parts of the application applicable to you.`, - overview_1: `Are you an end-user? The defaults are setup for both beginner and advanced users alike.`, - overview_2: `Are you a developer? Add some features to manage contracts and interact with application deployments.`, - overview_3: `Are you a miner or run a large-scale node? Add the features to give you all the information needed to watch the node operation.`, + overview_0: `仅可视部分对你可用的应用来管理应用界面`, + // Manage the available application views using only the parts of the application applicable to you. + overview_1: `你是终端用户?默认设置为初学者和高级用户进行了相同的设置。`, + // Are you an end-user? The defaults are setup for both beginner and advanced users alike. + overview_2: `你是开发者?添加一些功能来管理合约和与应用部署交互。`, + // Are you a developer? Add some features to manage contracts and interact with application deployments. + overview_3: `你是矿工或者运营一个大型节点?添加一些功能来让你获得更多有关节点运行的信息。`, + // Are you a miner or run a large-scale node? Add the features to give you all the information needed to watch the node operation. settings: { - description: `This view. Allows you to customize the application in term of options, operation and look and feel.`, - label: `Settings` + description: `此界面。允许你自定义应用的选项、运行、可视化和感官。`, + // This view. Allows you to customize the application in term of options, operation and look and feel. + label: `设置` // Settings }, signer: { - description: `The secure transaction management area of the application where you can approve any outgoing transactions made from the application as well as those placed into the queue by distributed applications.`, - label: `Signer` + description: `这个应用安全交易管理区域,你可以通过任何从本应用和其他分布式应用发起的即将发送的交易`, + // The secure transaction management area of the application where you can approve any outgoing transactions made + // from the application as well as those placed into the queue by distributed applications. + label: `Signer` // Signer }, status: { - description: `See how the Parity node is performing in terms of connections to the network, logs from the actual running instance and details of mining (if enabled and configured).`, - label: `Status` + description: `观察Parity节点现在的运行情况:网络连接数、实际运行实例的Logs和具体挖矿信息(如果已开启并设置)`, + // See how the Parity node is performing in terms of connections to the network, logs from the actual running instance + // and details of mining (if enabled and configured). + label: `状态` // Status }, - label: `views`, + label: `视窗`, // views home: { - label: `Home` + label: `首页` // Home } }, - label: `settings` + label: `设置` // settings }; diff --git a/js/src/i18n/zh/shapeshift.js b/js/src/i18n/zh/shapeshift.js index 247927834..7af706d27 100644 --- a/js/src/i18n/zh/shapeshift.js +++ b/js/src/i18n/zh/shapeshift.js @@ -16,51 +16,61 @@ export default { awaitingDepositStep: { - awaitingConfirmation: `Awaiting confirmation of the deposit address for your {typeSymbol} funds exchange`, - awaitingDeposit: `{shapeshiftLink} is awaiting a {typeSymbol} deposit. Send the funds from your {typeSymbol} network client to -`, - minimumMaximum: `{minimum} minimum, {maximum} maximum` + awaitingConfirmation: `正在等待你的{typeSymbol}资金交易的存款地址的确认信息`, + // Awaiting confirmation of the deposit address for your {typeSymbol} funds exchange + awaitingDeposit: `{shapeshiftLink}正在等待{typeSymbol}的存入.从你的{typeSymbol}网络客户端发送资金至-`, + // {shapeshiftLink} is awaiting a {typeSymbol} deposit. Send the funds from your {typeSymbol} network client to - + minimumMaximum: `{minimum}至少, {maximum}至多` // {minimum} minimum, {maximum} maximum }, awaitingExchangeStep: { - awaitingCompletion: `Awaiting the completion of the funds exchange and transfer of funds to your Parity account.`, - receivedInfo: `{shapeshiftLink} has received a deposit of -` + awaitingCompletion: `正在完成资金交易并发送资金至你的Parity账户`, + // Awaiting the completion of the funds exchange and transfer of funds to your Parity account. + receivedInfo: `{shapeshiftLink}已经收到存款-` + // {shapeshiftLink} has received a deposit of - }, button: { - cancel: `Cancel`, - done: `Close`, - shift: `Shift Funds` + cancel: `取消`, // Cancel + done: `关闭`, // Close + shift: `转换资金` // Shift Funds }, completedStep: { - completed: `{shapeshiftLink} has completed the funds exchange.`, - parityFunds: `The change in funds will be reflected in your Parity account shortly.` + completed: `{shapeshiftLink}已经完成了资金交易。`, // {shapeshiftLink} has completed the funds exchange. + parityFunds: `资金的改变会马上在你的Parity账户里体现。` + // The change in funds will be reflected in your Parity account shortly. }, errorStep: { - info: `The funds shifting via {shapeshiftLink} failed with a fatal error on the exchange. The error message received from the exchange is as follow:` + info: `通过{shapeshiftLink}进行的资金转换因为一个交易的致命错误失败了。交易提供的错误信息如下:` + // The funds shifting via {shapeshiftLink} failed with a fatal error on the exchange. The error message received from the exchange + // is as follow: }, optionsStep: { - noPairs: `There are currently no exchange pairs/coins available to fund with.`, + noPairs: `目前没有可匹配的交易/货币可用来进行转换`, + // There are currently no exchange pairs/coins available to fund with. returnAddr: { - hint: `the return address for send failures`, - label: `(optional) {coinSymbol} return address` + hint: `转换错误后的发回地址`, // the return address for send failures + label: `(可选){coinSymbol}发回地址` // (optional) {coinSymbol} return address }, terms: { - label: `I understand that ShapeShift.io is a 3rd-party service and by using the service any transfer of information and/or funds is completely out of the control of Parity` + label: `我理解ShapeShift.io是一个第三方服务,使用此服务发生的任何信息/资金发送是完全不受Parity控制的` + // I understand that ShapeShift.io is a 3rd-party service and by using the service any transfer of information and/or funds is + // completely out of the control of Parity }, typeSelect: { - hint: `the type of crypto conversion to do`, - label: `fund account from` + hint: `数字货币转换的种类`, // the type of crypto conversion to do + label: `来自资金账户` // fund account from } }, price: { - minMax: `({minimum} minimum, {maximum} maximum)` + minMax: `({minimum}至小, {maximum}至大)` // ({minimum} minimum, {maximum} maximum) }, title: { - completed: `completed`, - deposit: `awaiting deposit`, - details: `details`, - error: `exchange failed`, - exchange: `awaiting exchange` + completed: `完成`, // completed + deposit: `等待存款`, // awaiting deposit + details: `详情`, // details + error: `交易失败`, // exchange failed + exchange: `等待交易` // awaiting exchange }, warning: { - noPrice: `No price match was found for the selected type` + noPrice: `所选择的类型没有匹配的价格` // No price match was found for the selected type } }; diff --git a/js/src/i18n/zh/signer.js b/js/src/i18n/zh/signer.js index 3f8615c52..ab3b99e53 100644 --- a/js/src/i18n/zh/signer.js +++ b/js/src/i18n/zh/signer.js @@ -16,88 +16,92 @@ export default { embedded: { - noPending: `There are currently no pending requests awaiting your confirmation` + noPending: `目前没有待处理的确认等待你的处理` + // There are currently no pending requests awaiting your confirmation }, mainDetails: { - editTx: `Edit conditions/gas/gasPrice`, + editTx: `编辑条款/gas/gasPrice`, // Edit conditions/gas/gasPrice tooltips: { - total1: `The value of the transaction including the mining fee is {total} {type}.`, - total2: `(This includes a mining fee of {fee} {token})`, - value1: `The value of the transaction.` + total1: `包括交易费的交易的总价值是{total} {type}`, + // The value of the transaction including the mining fee is {total} {type}. + total2: `(包括了交易费 {fee} {token})`, + // (This includes a mining fee of {fee} {token}) + value1: `交易价值` // The value of the transaction. } }, requestOrigin: { - dapp: `by a dapp at {url}`, - ipc: `via IPC session`, - rpc: `via RPC {rpc}`, - signerCurrent: `via current tab`, - signerUI: `via UI session`, - unknownInterface: `via unknown interface`, - unknownRpc: `unidentified`, - unknownUrl: `unknown URL` + dapp: `来自dapp {url}`, // by a dapp at {url} + ipc: `通过IPC会话`, // via IPC session + rpc: `通过RPC{rpc}`, // via RPC {rpc} + signerCurrent: `通过当前标签页`, // via current tab + signerUI: `通过交互会话`, // via UI session + unknownInterface: `通过未知交互`, // via unknown interface + unknownRpc: `未明确的`, // unidentified + unknownUrl: `未知URL` // unknown URL }, requestsPage: { - noPending: `There are no requests requiring your confirmation.`, - pendingTitle: `Pending Requests`, - queueTitle: `Local Transactions` + noPending: `没有请求需要你的确认`, // There are no requests requiring your confirmation. + pendingTitle: `待处理请求`, // Pending Requests + queueTitle: `本地交易` // Local Transactions }, sending: { hardware: { - confirm: `Please confirm the transaction on your attached hardware device`, - connect: `Please attach your hardware device before confirming the transaction` + confirm: `请在你连接的硬件设备上确认交易`, // Please confirm the transaction on your attached hardware device + connect: `请在确认交易前连接你的硬件设备` // Please attach your hardware device before confirming the transaction } }, signRequest: { - request: `A request to sign data using your account:`, + request: `一个签名数据在请求你的账号:`, // A request to sign data using your account: state: { - confirmed: `Confirmed`, - rejected: `Rejected` + confirmed: `通过`, // Confirmed + rejected: `拒绝` // Rejected }, - unknownBinary: `(Unknown binary data)`, - warning: `WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure.` + unknownBinary: `(未知二进制数据)`, // (Unknown binary data) + warning: `警告:此操作的结果是不可逆的。请在确认信息后再通过请求。` + // WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure. }, - title: `Trusted Signer`, + title: `可信的Signer`, // Trusted Signer txPending: { buttons: { - viewToggle: `view transaction` + viewToggle: `查看交易` // view transaction } }, txPendingConfirm: { buttons: { - confirmBusy: `Confirming...`, - confirmRequest: `Confirm Request` + confirmBusy: `通过中...`, // Confirming... + confirmRequest: `通过请求` // Confirm Request }, errors: { - invalidWallet: `Given wallet file is invalid.` + invalidWallet: `所提供的钱包文件不可用` // Given wallet file is invalid. }, password: { decrypt: { - hint: `decrypt the key`, - label: `Key Password` + hint: `解密钥匙`, // decrypt the key + label: `钥匙密码` // Key Password }, unlock: { - hint: `unlock the account`, - label: `Account Password` + hint: `解锁账户`, // unlock the account + label: `账户密码` // Account Password } }, - passwordHint: `(hint) {passwordHint}`, + passwordHint: `(提示){passwordHint}`, // (hint) {passwordHint} selectKey: { - hint: `The keyfile to use for this account`, - label: `Select Local Key` + hint: `此账户的钥匙文件`, // The keyfile to use for this account + label: `选择本地钥匙` // Select Local Key }, tooltips: { - password: `Please provide a password for this account` + password: `请为此账户提供密码` // Please provide a password for this account } }, txPendingForm: { - changedMind: `I've changed my mind`, - reject: `reject request` + changedMind: `我改主意了`, // I've changed my mind + reject: `拒绝请求` // reject request }, txPendingReject: { buttons: { - reject: `Reject Request` + reject: `拒绝请求` // Reject Request }, - info: `Are you sure you want to reject request?`, - undone: `This cannot be undone` + info: `你确定要拒绝请求吗?`, // Are you sure you want to reject request? + undone: `此操作是不可逆的` // This cannot be undone } }; diff --git a/js/src/i18n/zh/status.js b/js/src/i18n/zh/status.js index 536c0ff90..395a2a190 100644 --- a/js/src/i18n/zh/status.js +++ b/js/src/i18n/zh/status.js @@ -16,51 +16,52 @@ export default { debug: { - reverse: `Reverse Order`, - stopped: `Refresh and display of logs from Parity is currently stopped via the UI, start it to see the latest updates.`, - title: `Node Logs` + reverse: `翻转订单`, // Reverse Order + stopped: `Parity的交互目前停止了刷新和显示Logs,请启动它来查看最新的更新。`, + // Refresh and display of logs from Parity is currently stopped via the UI, start it to see the latest updates. + title: `节点Logs` // Node Logs }, miningSettings: { input: { author: { - hint: `the mining author`, - label: `author` + hint: `矿工名字`, // the mining author + label: `矿工` // author }, extradata: { - hint: `extra data for mined blocks`, - label: `extradata` + hint: `提取挖到区块的数据`, // extra data for mined blocks + label: `提取数据` // extradata }, gasFloor: { - hint: `the gas floor target for mining`, - label: `gas floor target` + hint: `挖矿的gas下限目标`, // the gas floor target for mining + label: `gas下限目标` // gas floor target }, gasPrice: { - hint: `the minimum gas price for mining`, - label: `minimal gas price` + hint: `挖矿的最低gas价格`, // the minimum gas price for mining + label: `最低gas价格` // minimal gas price } }, - title: `mining settings` + title: `挖矿设置` // mining settings }, status: { - hashrate: `{hashrate} H/s`, + hashrate: `{hashrate} H/s`, // {hashrate} H/s input: { - chain: `chain`, - enode: `enode`, - no: `no`, - peers: `peers`, - port: `network port`, - rpcEnabled: `rpc enabled`, - rpcInterface: `rpc interface`, - rpcPort: `rpc port`, - yes: `yes` + chain: `链`, // chain + enode: `enode`, // enode + no: `否`, // no + peers: `同步节点`, // peers + port: `网络端口`, // network port + rpcEnabled: `rpc开启`, // rpc enabled + rpcInterface: `rpc交互`, // rpc interface + rpcPort: `rpc端口`, // rpc port + yes: `是` // yes }, title: { - bestBlock: `best block`, - hashRate: `hash rate`, - network: `network settings`, - node: `Node`, - peers: `peers` + bestBlock: `最新区块`, // best block + hashRate: `哈希率`, // hash rate + network: `网络设置`, // network settings + node: `节点`, // Node + peers: `同步节点` // peers } }, - title: `Status` + title: `状态` // Status }; diff --git a/js/src/i18n/zh/tabBar.js b/js/src/i18n/zh/tabBar.js index 1692a1997..7521c1b33 100644 --- a/js/src/i18n/zh/tabBar.js +++ b/js/src/i18n/zh/tabBar.js @@ -16,6 +16,7 @@ export default { tooltip: { - overview: `navigate between the different parts and views of the application, switching between an account view, token view and distributed application view` + overview: `在应用的不同部分和不同界面进行导航,在账户界面、代币界面和分布式应用界面之间切换。` + // navigate between the different parts and views of the application, switching between an account view, token view and distributed application view } }; diff --git a/js/src/i18n/zh/transfer.js b/js/src/i18n/zh/transfer.js index 3207f5b06..79c886719 100644 --- a/js/src/i18n/zh/transfer.js +++ b/js/src/i18n/zh/transfer.js @@ -17,45 +17,46 @@ export default { advanced: { data: { - hint: `the data to pass through with the transaction`, - label: `transaction data` + hint: `交易附带数据`, // the data to pass through with the transaction + label: `交易数据`// transaction data } }, buttons: { - back: `Back`, - cancel: `Cancel`, - close: `Close`, - next: `Next`, - send: `Send` + back: `返回`, // Back + cancel: `取消`, // Cancel + close: `关闭`, // Close + next: `下一步`, // Next + send: `发送`// Send }, details: { advanced: { - label: `advanced sending options` + label: `高级发送选项`// advanced sending options }, amount: { - hint: `the amount to transfer to the recipient`, - label: `amount to transfer (in {tag})` + hint: `发送数额`, // the amount to transfer to the recipient + label: `发送数额{tag}`// amount to transfer (in {tag}) }, fullBalance: { - label: `full account balance` + label: `所有的余额`// full account balance }, recipient: { - hint: `the recipient address`, - label: `recipient address` + hint: `收款人地址`, // the recipient address + label: `收款人地址`// recipient address }, sender: { - hint: `the sender address`, - label: `sender address` + hint: `发送人地址`, // the sender address + label: `发送人地址`// sender address }, total: { - label: `total transaction amount` + label: `发送数额`// total transaction amount } }, wallet: { - confirmation: `This transaction needs confirmation from other owners.`, - operationHash: `operation hash` + confirmation: `这笔交易需要其他人的确认。`, // This transaction needs confirmation from other owners. + operationHash: `操作哈希`// operation hash }, warning: { - wallet_spent_limit: `This transaction value is above the remaining daily limit. It will need to be confirmed by other owners.` + wallet_spent_limit: `这笔转账的数额超过了每日转账数额上限。此交易需要其他人的确认才可以发送成功。` + // This transaction value is above the remaining daily limit. It will need to be confirmed by other owners. } }; diff --git a/js/src/i18n/zh/txEditor.js b/js/src/i18n/zh/txEditor.js index 7dab159a8..da55c7b23 100644 --- a/js/src/i18n/zh/txEditor.js +++ b/js/src/i18n/zh/txEditor.js @@ -17,23 +17,24 @@ export default { condition: { block: { - hint: `The minimum block to send from`, - label: `Transaction send block` + hint: `在某个区块高度后发送`, // The minimum block to send from + label: `交易发送区块`// Transaction send block }, - blocknumber: `Send after BlockNumber`, + blocknumber: `在某个区块后发送`, // Send after BlockNumber date: { - hint: `The minimum date to send from`, - label: `Transaction send date` + hint: `在某日后发送`, // The minimum date to send from + label: `交易发送日期`// Transaction send date }, - datetime: `Send after Date & Time`, - label: `Condition where transaction activates`, - none: `No conditions`, + datetime: `在某日某时后发送`, // Send after Date & Tim + label: `交易激活的条件`, // Condition where transaction activates + none: `无条件`, // No conditions time: { - hint: `The minimum time to send from`, - label: `Transaction send time` + hint: `在某时间后发送`, // The minimum time to send from + label: `交易发送时间`// Transaction send time } }, gas: { - info: `You can choose the gas price based on the distribution of recent included transaction gas prices. The lower the gas price is, the cheaper the transaction will be. The higher the gas price is, the faster it should get mined by the network.` + info: `你可以基于最近的交易gas价格的分布选择gas价格。 gas价格越低,交易费用越便宜。 gas 价格越高,交易被网络打包的速度越快。` + // You can choose the gas price based on the distribution of recent included transaction gas prices.The lower the gas price is, the cheaper the transaction will be.The higher the gas price is, the faster it should get mined by the network. } }; diff --git a/js/src/i18n/zh/ui.js b/js/src/i18n/zh/ui.js index d84e7bd13..694372f00 100644 --- a/js/src/i18n/zh/ui.js +++ b/js/src/i18n/zh/ui.js @@ -18,56 +18,56 @@ export default { actionbar: { export: { button: { - export: `export` + export: `导出`// export } }, import: { button: { - cancel: `Cancel`, - confirm: `Confirm`, - import: `import` + cancel: `取消`, // Cancel + confirm: `确认`, // Confirm + import: `导入`// import }, - confirm: `Confirm that this is what was intended to import.`, - error: `An error occured: {errorText}`, + confirm: `确认这是你想导入的`, // Confirm that this is what was intended to import. + error: `发生错误:{errorText}`, // An error occured: {errorText} step: { - error: `error`, - select: `select a file`, - validate: `validate` + error: `错误`, // error + select: `选择一个文件`, // select a file + validate: `确认`// validate }, - title: `Import from a file` + title: `从一个文件导入`// Import from a file }, search: { - hint: `Enter search input...` + hint: `输入搜索内容……`// Enter search input... }, sort: { - sortBy: `Sort by {label}`, - typeDefault: `Default`, - typeEth: `Sort by ETH`, - typeName: `Sort by name`, - typeTags: `Sort by tags` + sortBy: `根据{label}排序`, // Sort by {label} + typeDefault: `默认`, // Default + typeEth: `根据以太币数额排序`, // Sort by ETH + typeName: `根据账户名字排序`, // Sort by name + typeTags: `根据标签排序`// Sort by tags } }, balance: { - none: `No balances associated with this account` + none: `这个账户没有余额`// No balances associated with this account }, blockStatus: { - bestBlock: `{blockNumber} best block`, - syncStatus: `{currentBlock}/{highestBlock} syncing`, - warpRestore: `{percentage}% warp restore`, - warpStatus: `, {percentage}% historic` + bestBlock: `最新区块{blockNumber}`, // {blockNumber} best block + syncStatus: `currentBlock}/{highestBlock}区块同步`, // {currentBlock}/{highestBlock} syncing{ + warpRestore: `{percentage}%恢复`, // {percentage}% warp restore + warpStatus: `, {percentage}%历史`// {percentage}% historic }, confirmDialog: { - no: `no`, - yes: `yes` + no: `不是`, // no + yes: `是`// yes }, copyToClipboard: { - copied: `copied {data} to clipboard` + copied: `复制{data}到粘贴板`// copied {data} to clipboard }, errors: { - close: `close` + close: `关闭`// close }, fileSelect: { - defaultLabel: `Drop a file here, or click to select a file to upload` + defaultLabel: `拉一个文件到这里,或者选择一个文件上传`// Drop a file here, or click to select a file to upload }, gasPriceSelector: { customTooltip: { @@ -75,8 +75,8 @@ export default { } }, identityName: { - null: `NULL`, - unnamed: `UNNAMED` + null: `空`, // NULL + unnamed: `未命名`// UNNAMED }, methodDecoding: { condition: { @@ -84,20 +84,20 @@ export default { time: `, {historic, select, true {Submitted} false {Submission}} at {timestamp}` }, deploy: { - address: `Deployed a contract at address`, - params: `with the following parameters:`, - willDeploy: `Will deploy a contract`, - withValue: `, sending {value}` + address: `在地址上部署一个合约`, // Deployed a contract at address + params: `附带下面的参数:`, // with the following parameters: + willDeploy: `将要部署一个合约`, // Will deploy a contract + withValue: `, 发送{value}`// sending {value} }, - gasUsed: `({gas} gas used)`, + gasUsed: `({gas}gas消耗)`, // {gas} gas used gasValues: `{gas} gas ({gasPrice}M/{tag})`, input: { - data: `data`, - input: `input`, + data: `数据`, // data + input: `输入`, // input withInput: `with the {inputDesc} {inputValue}` }, receive: { - contract: `the contract`, + contract: `合约`, // the contract info: `{historic, select, true {Received} false {Will receive}} {valueEth} from {aContract}{address}` }, signature: { @@ -116,48 +116,48 @@ export default { } }, passwordStrength: { - label: `password strength` + label: `密码强度`// password strength }, tooltips: { button: { - done: `Done`, - next: `Next`, - skip: `Skip` + done: `完成`, // Done + next: `下一步`, // Next + skip: `跳过`// Skip } }, txHash: { confirmations: `{count} {value, plural, one {confirmation} other {confirmations}}`, - oog: `The transaction might have gone out of gas. Try again with more gas.`, - posted: `The transaction has been posted to the network with a hash of {hashLink}`, - waiting: `waiting for confirmations` + oog: `这笔交易已经耗光了gas。请用更多的gas尝试。`, // The transaction might have gone out of gas. Try again with more gas. + posted: `这笔交易已经被发送到网络,附带哈希是{hashLink}`, // The transaction has been posted to the network with a hash of {hashLink} + waiting: `等待确认`// waiting for confirmations }, vaultSelect: { - hint: `the vault this account is attached to`, - label: `associated vault` + hint: `这个账户绑定的保险库是`, // the vault this account is attached to + label: `相关保险库`// associated vault }, verification: { gatherData: { accountHasRequested: { - false: `You did not request verification from this account yet.`, - pending: `Checking if you requested verification…`, - true: `You already requested verification from this account.` + false: `.你还没有从这个账户请求确认。`, // You did not request verification from this account yet + pending: `检查一下你是否请求了验证……`, // Checking if you requested verification… + true: `你已经从这个账户请求到验证。`// You already requested verification from this account. }, accountIsVerified: { - false: `Your account is not verified yet.`, - pending: `Checking if your account is verified…`, - true: `Your account is already verified.` + false: `你的账户还没有被验证。`, // Your account is not verified yet. + pending: `检查一下你的账户是否已经被验证……`, // Checking if your account is verified… + true: `你的账户已经被验证。`// Your account is already verified. }, - fee: `The additional fee is {amount} ETH.`, + fee: `额外的费用是{amount}ETH`, // The additional fee is {amount} ETH. isAbleToRequest: { - pending: `Validating your input…` + pending: `验证你的输入……`// Validating your input… }, isServerRunning: { - false: `The verification server is not running.`, - pending: `Checking if the verification server is running…`, - true: `The verification server is running.` + false: `验证服务器没有在运行。`, // The verification server is not running. + pending: `检查一下验证服务器是否在运行……`, // Checking if the verification server is running… + true: `验证服务器正在运行。`// The verification server is running. }, - nofee: `There is no additional fee.`, - termsOfService: `I agree to the terms and conditions below.` + nofee: `没有额外的费用。`, // There is no additional fee. + termsOfService: `我同意下面的条款和条件。`// I agree to the terms and conditions below. } } }; diff --git a/js/src/i18n/zh/upgradeParity.js b/js/src/i18n/zh/upgradeParity.js index b3d871452..a3ddd27bd 100644 --- a/js/src/i18n/zh/upgradeParity.js +++ b/js/src/i18n/zh/upgradeParity.js @@ -15,33 +15,41 @@ // along with Parity. If not, see . export default { - busy: `Your upgrade to Parity {newversion} is currently in progress. Please wait until the process completes.`, + busy: `你正在升级到Parity最新版本{newversion}。请等待升级过程完成。`, + // Your upgrade to Parity {newversion} is currently in progress. Please wait until the process completes. button: { - close: `close`, - done: `done`, - upgrade: `upgrade now` + close: `关闭`, // close + done: `完成`, // done + upgrade: `现在升级`// upgrade now }, - completed: `Your upgrade to Parity {newversion} has been successfully completed. Click "done" to automatically reload the application.`, + completed: `你升级到Parity最新版本{newversion}的操作已经完成。点击“完成”将自动重新加载这个应用。`, + // Your upgrade to Parity {newversion} has been successfully completed. Click "done" to automatically reload the application. consensus: { - capable: `Your current Parity version is capable of handling the network requirements.`, - capableUntil: `Your current Parity version is capable of handling the network requirements until block {blockNumber}`, - incapableSince: `Your current Parity version is incapable of handling the network requirements since block {blockNumber}`, - unknown: `Your current Parity version is capable of handling the network requirements.` + capable: `你当前的Parity版本能够处理网络请求。`, + // Your current Parity version is capable of handling the network requirements. + capableUntil: `你当前的Parity版本能够处理直到第{blockNumber}个区块的网络请求。`, + // Your current Parity version is capable of handling the network requirements until block {blockNumber} + incapableSince: `你当前的Parity版本能够处理第{blockNumber}个区块以后的网络请求。`, + // Your current Parity version is incapable of handling the network requirements since block {blockNumber} + unknown: `你当前的Parity版本能够处理网络请求。` + // Your current Parity version is capable of handling the network requirements. }, - failed: `Your upgrade to Parity {newversion} has failed with an error.`, + failed: `升级到Parity最新版本{newversion}遇到错误,升级失败。`, + // Your upgrade to Parity {newversion} has failed with an error. info: { - currentVersion: `You are currently running {currentversion}`, - next: `Proceed with "upgrade now" to start your Parity upgrade.`, - upgrade: `An upgrade to version {newversion} is available`, - welcome: `Welcome to the Parity upgrade wizard, allowing you a completely seamless upgrade experience to the next version of Parity.` + currentVersion: `你现在正在运行{currentversion}版本。`, // You are currently running {currentversion} + next: `点击“现在升级”,开始Parity升级。`, // Proceed with "upgrade now" to start your Parity upgrade. + upgrade: `可以升级到最新版本{newversion}`, // An upgrade to version {newversion} is available + welcome: `迎来到Parity升级指南,让你享受无缝升级到Parity最新版本的体验。` + // Welcome to the Parity upgrade wizard, allowing you a completely seamless upgrade experience to the next version of Parity.欢 }, step: { - completed: `upgrade completed`, - error: `error`, - info: `upgrade available`, - updating: `upgrading parity` + completed: `升级完成`, // upgrade completed + error: `错误`, // error + info: `可以升级`, // upgrade available + updating: `升级Parity`// upgrading parity }, version: { - unknown: `unknown` + unknown: `未知`// unknown } }; diff --git a/js/src/i18n/zh/vaults.js b/js/src/i18n/zh/vaults.js index 04ff4d558..7d31ca64b 100644 --- a/js/src/i18n/zh/vaults.js +++ b/js/src/i18n/zh/vaults.js @@ -17,92 +17,98 @@ export default { accounts: { button: { - cancel: `Cancel`, - execute: `Set` + cancel: `取消`, // Cancel + execute: `设定` // Set }, - empty: `There are no accounts in this vault`, - title: `Manage Vault Accounts` + empty: `此保险库中没有账户`, // There are no accounts in this vault + title: `管理保险库账户` // Manage Vault Accounts }, button: { - accounts: `accounts`, - add: `create vault`, - close: `close`, - edit: `edit`, - open: `open` + accounts: `账户`, // accounts + add: `创建保险库`, // create vault + close: `关闭`, // close + edit: `编辑`, // edit + open: `打开` // open }, confirmClose: { - info: `You are about to close a vault. Any accounts associated with the vault won't be visible after this operation concludes. To view the associated accounts, open the vault again.`, - title: `Close Vault` + info: `你即将关闭一个保险库。所有与这个保险库相关的账户在这个操作完成后都不再可见。如果想再见到关联账户,请重新打开保险库。`, + // You are about to close a vault. Any accounts associated with the vault won't be visible after this operation concludes. To view + // the associated accounts, open the vault again. + title: `关闭保险库` // Close Vault }, confirmOpen: { - info: `You are about to open a vault. After confirming your password, all accounts associated with this vault will be visible. Closing the vault will remove the accounts from view until the vault is opened again.`, + info: `你即将打开一个保险库。在确认了你的密码之后,所有与这个保险库关联的账户都会可见。关闭保险库会在界面中移除所有账户,直到保险库被再次打开。`, + // You are about to open a vault. After confirming your password, all accounts associated with this vault will be visible. Closing + // the vault will remove the accounts from view until the vault is opened again. password: { - hint: `the password specified when creating the vault`, - label: `vault password` + hint: `创建保险库时设置的密码`, // the password specified when creating the vault + label: `保险库密码` // vault password }, - title: `Open Vault` + title: `打开保险库` // Open Vault }, create: { button: { - close: `close`, - vault: `create vault` + close: `关闭`, // close + vault: `创建保险库` // create valut }, description: { - hint: `an extended description for the vault` + hint: `该保险库更详细的描述` // an extended description for the vault }, descriptions: { - label: `(optional) description` + label: `(可选)描述` // (optional) description }, hint: { - hint: `(optional) a hint to help with remembering the password`, - label: `password hint` + hint: `(可选)一个帮助记忆密码的提示`, // (optional) a hint to help with remembering the password + label: `密码提示` // password hint }, name: { - hint: `a name for the vault`, - label: `vault name` + hint: `一个保险库的名字`, // a name for the vault + label: `保险库名称` // vault name }, password: { - hint: `a strong, unique password`, - label: `password` + hint: `一个高强度且独一无二的密码`, // a strong, unique password + label: `密码` // password }, password2: { - hint: `verify your password`, - label: `password (repeat)` + hint: `验证你的密码`, // verify your password + label: `密码(重复)` // password (repeat) }, - title: `Create a new vault` + title: `创建一个新的保险库` // Create a new vault }, editMeta: { - allowPassword: `Change vault password`, + allowPassword: `更改保险库密码`, // Change vault password button: { - close: `close`, - save: `save` + close: `关闭`, // close + save: `保存` // save }, currentPassword: { - hint: `your current vault password`, - label: `current password` + hint: `保险库的原密码`, // your current vault password + label: `原密码` // current password }, description: { - hint: `the description for this vault`, - label: `vault description` + hint: `此保险库的描述`, // the description for this vault + label: `保险库描述` // vault description }, password: { - hint: `a strong, unique password`, - label: `new password` + hint: `一个高强度且独一无二的密码`, // a strong, unique password + label: `新密码` // new password }, password2: { - hint: `verify your new password`, - label: `new password (repeat)` + hint: `验证你的新密码`, // verify your new password + label: `新密码(重复)` // new password (repeat) }, passwordHint: { - hint: `your password hint for this vault`, - label: `password hint` + hint: `此保险库的密码提示`, // your password hint for this vault + label: `密码提示` // password hint }, - title: `Edit Vault Metadata` + title: `编辑保险库元数据` // Edit Vault Metadata }, - empty: `There are currently no vaults to display.`, + empty: `目前没有任何可显示的保险库`, // There are currently no vaults to display. selector: { - noneAvailable: `There are currently no vaults opened and available for selection. Create and open some first before attempting to select a vault for an account move.`, - title: `Select Account Vault` + noneAvailable: `目前没有任何打开、可选的保险库。请在移动账户之前创建并打开一个保险库。`, + // There are currently no vaults opened and available for selection. Create and open some first before attempting to select + // a vault for an account move. + title: `选择账户保险库` // Select Account Vault }, - title: `Vault Management` + title: `保险库管理` // Vault Management }; diff --git a/js/src/i18n/zh/verification.js b/js/src/i18n/zh/verification.js index 2d98ed82a..b46d9077a 100644 --- a/js/src/i18n/zh/verification.js +++ b/js/src/i18n/zh/verification.js @@ -16,70 +16,70 @@ export default { button: { - cancel: `Cancel`, - done: `Done`, - next: `Next` + cancel: `取消`, // Cancel + done: `完成`, // Done + next: `下一步`// Next }, code: { - error: `invalid code`, - hint: `Enter the code you received.`, - label: `verification code`, - sent: `The verification code has been sent to {receiver}.` + error: `无效验证码`, // invalid code + hint: `输入你收到的验证码。`, // Enter the code you received. + label: `验证码`, // verification code + sent: `验证码被发送到接收者{receiver}.`// The verification code has been sent to {receiver} }, confirmation: { - authorise: `The verification code will be sent to the contract. Please authorize this using the Parity Signer.`, - windowOpen: `Please keep this window open.` + authorise: `验证码将被发送到合约。请使用Parity Signer进行授权。`, // The verification code will be sent to the contract. Please authorize this using the Parity Signer. + windowOpen: `请保持这个窗口打开状态。`// Please keep this window open. }, done: { - message: `Congratulations, your account is verified!` + message: `恭喜,你的账户已经被认证。`// Congratulations, your account is verified! }, email: { - enterCode: `Enter the code you received via e-mail.` + enterCode: `输入你从邮箱获得验证码。`// Enter the code you received via e-mail. }, gatherData: { email: { - hint: `the code will be sent to this address`, - label: `e-mail address` + hint: `验证码将被发送到这个地址`, // the code will be sent to this address + label: `邮箱地址`// e-mail address }, phoneNumber: { - hint: `the SMS will be sent to this number`, - label: `phone number in international format` + hint: `短信将被发送到这个号码`, // the SMS will be sent to this number + label: `国际格式的手机号码`// phone number in international format } }, gatherDate: { email: { - error: `invalid e-mail` + error: `无效邮箱`// invalid e-mail }, phoneNumber: { - error: `invalid number` + error: `无效数字`// invalid number } }, - loading: `Loading verification data.`, + loading: `加载验证数据`, // Loading verification data. request: { - authorise: `A verification request will be sent to the contract. Please authorize this using the Parity Signer.`, - requesting: `Requesting a code from the Parity server and waiting for the puzzle to be put into the contract.`, - windowOpen: `Please keep this window open.` + authorise: `验证请求将被发送到这个合约。请使用Parity Signer进行授权。`, // A verification request will be sent to the contract. Please authorize this using the Parity Signer. + requesting: `正在从Parity服务器请求一个验证码,等待它被输入到合约。`, // Requesting a code from the Parity server and waiting for the puzzle to be put into the contract. + windowOpen: `请保持窗口为打开状态。`// Please keep this window open. }, sms: { - enterCode: `Enter the code you received via SMS.` + enterCode: `输入你从短信收到的验证码。`// Enter the code you received via SMS. }, steps: { - code: `Enter Code`, - completed: `Completed`, - confirm: `Confirm`, - data: `Enter Data`, - method: `Method`, - request: `Request` + code: `输入验证码`, // Enter Code + completed: `完成`, // Completed + confirm: `确认`, // Confirm + data: `输入数据`, // Enter Data + method: `方式`, // Method + request: `请求`// Request }, - title: `verify your account`, + title: `t验证你的账户`, // verify your accoun types: { email: { - description: `The hash of the e-mail address you prove control over will be stored on the blockchain.`, - label: `E-mail Verification` + description: `你所控制的邮箱地址的哈希值将被存储在区块链。`, // The hash of the e-mail address you prove control over will be stored on the blockchain. + label: `邮箱验证`// E-mail Verification }, sms: { - description: `It will be stored on the blockchain that you control a phone number (not which).`, - label: `SMS Verification` + description: `你所控制的手机号码将被存储在区块链。`, // It will be stored on the blockchain that you control a phone number (not which). + label: `短信验证`// SMS Verification } } }; diff --git a/js/src/i18n/zh/wallet.js b/js/src/i18n/zh/wallet.js index 92063af8b..fd391ad43 100644 --- a/js/src/i18n/zh/wallet.js +++ b/js/src/i18n/zh/wallet.js @@ -16,30 +16,31 @@ export default { buttons: { - edit: `edit`, + edit: `编辑`, // edit forget: `forget`, - settings: `settings`, - transfer: `transfer` + settings: `设置`, // settings + transfer: `转账`// transfer }, confirmations: { buttons: { - confirmAs: `Confirm As...`, - revokeAs: `Revoke As...` + confirmAs: `确定为……`, // Confirm As... + revokeAs: `撤回为……`// Revoke As... }, - none: `No transactions needs confirmation right now.`, + none: `现在没有交易需要确认。`, // No transactions needs confirmation right now. tooltip: { - confirmed: `Confirmed by {number}/{required} owners` + confirmed: `被{number}/{required}所有人确认`// Confirmed by {number}/{required} owners } }, details: { - requiredOwners: `This wallet requires at least {owners} to validate any action (transactions, modifications).`, + requiredOwners: `这个钱包需要至少{owners}所有人验证所有的操作(交易,修改)`, + // This wallet requires at least {owners} to validate any action (transactions, modifications). requiredOwnersNumber: `{number} {numberValue, plural, one {owner} other {owners}}`, spent: `{spent} has been spent today, out of {limit} set as the daily limit, which has been reset on {date}`, - title: `Details` + title: `细节`// Details }, - title: `Wallet Management`, + title: `钱包管理`, // Wallet Management transactions: { - none: `No transactions has been sent.`, - title: `Transactions` + none: `没有交易被发送。`, // No transactions has been sent. + title: `交易`// Transactions } }; diff --git a/js/src/i18n/zh/walletSettings.js b/js/src/i18n/zh/walletSettings.js index ddeae3798..429542a37 100644 --- a/js/src/i18n/zh/walletSettings.js +++ b/js/src/i18n/zh/walletSettings.js @@ -16,54 +16,60 @@ export default { addOwner: { - title: `Add Owner` + title: `添加持有人` // Add Owner }, buttons: { - cancel: `Cancel`, - close: `Close`, - next: `Next`, - send: `Send`, - sending: `Sending...` + cancel: `取消`, // Cancel + close: `关闭`, // Close + next: `下一个`, // Next + send: `发送`, // Send + sending: `正在发送...` // Sending... }, changes: { - modificationString: `For your modifications to be taken into account, - other owners have to send the same modifications. They can paste - this string to make it easier:`, - none: `No modifications have been made to the Wallet settings.`, - overview: `You are about to make the following modifications` + modificationString: `为了保证你做的修改会被执行, + 其他的账户持有人也需要发送相同的修改。 + 他们可以通过粘贴以下字符串来简单的完成更改:`, + // For your modifications to be taken into account, + // other owners have to send the same modifications. They can paste + // this string to make it easier: + none: `钱包设置没有发生任何更改。`, // No modifications have been made to the Wallet settings. + overview: `你将会造成以下更改` // You are about to make the following modifications }, edit: { - message: `In order to edit this contract's settings, at - least {owners, number} {owners, plural, one {owner } other {owners }} have to - send the very same modifications. You can paste a stringified version - of the modifications here.` + message: `为了编辑这个合约的设置,至少{owners, number} + {owners, plural, one {owner } other {owners }}必须发送完全相同的修改 + 你可以将字符串化的修改粘贴在这里。` + // In order to edit this contract's settings, at + // least {owners, number} {owners, plural, one {owner } other {owners }} have to + // send the very same modifications. You can paste a stringified version + // of the modifications here. }, modifications: { daylimit: { - hint: `amount of ETH spendable without confirmations`, - label: `wallet day limit` + hint: `不需要确认即可发送的ETH数量`, // amount of ETH spendable without confirmations + label: `钱包每日限额` // wallet day limit }, fromString: { - label: `modifications` + label: `修改` // modifications }, owners: { - label: `other wallet owners` + label: `其他钱包持有人` // other wallet owners }, required: { - hint: `number of required owners to accept a transaction`, - label: `required owners` + hint: `确认交易所需的通过持有人人数`, // number of required owners to accept a transaction + label: `所需持有人` // required owners }, sender: { - hint: `send modifications as this owner`, - label: `from account (wallet owner)` + hint: `作为此持有人发送修改`, // send modifications as this owner + label: `来自账户 (wallet owner)` // from account (wallet owner) } }, ownersChange: { - details: `from {from} to {to}`, - title: `Change Required Owners` + details: `从 {from} 至 {to}`, // from {from} to {to} + title: `改变所需持有人` }, - rejected: `The transaction #{txid} has been rejected`, + rejected: `交易#{txid}已经被拒绝`, // The transaction #{txid} has been rejected removeOwner: { - title: `Remove Owner` + title: `移除持有人` // Remove Owner } }; diff --git a/js/src/i18n/zh/web.js b/js/src/i18n/zh/web.js index 6136d387f..55aef547f 100644 --- a/js/src/i18n/zh/web.js +++ b/js/src/i18n/zh/web.js @@ -15,5 +15,5 @@ // along with Parity. If not, see . export default { - requestToken: `Requesting access token...` + requestToken: `正在请求使用代币` // Requesting access token... }; diff --git a/js/src/i18n/zh/writeContract.js b/js/src/i18n/zh/writeContract.js index 62f83dd4d..c258b4680 100644 --- a/js/src/i18n/zh/writeContract.js +++ b/js/src/i18n/zh/writeContract.js @@ -16,47 +16,47 @@ export default { buttons: { - autoCompile: `Auto-Compile`, - compile: `Compile`, - deploy: `Deploy`, - import: `Import Solidity`, - load: `Load`, - new: `New`, - optimise: `Optimise`, - save: `Save` + autoCompile: `自动编译`, // Auto-Compile + compile: `编译`, // Compile + deploy: `部署`, // Deploy + import: `载入Solidity`, // Import Solidity + load: `加载`, // Load + new: `新建`, // New + optimise: `优化`, // Optimise + save: `保存` // Save }, compiling: { - action: `Please compile the source code.`, - busy: `Compiling...` + action: `请编译源代码`, // Please compile the source code. + busy: `编译中...` // Compiling... }, details: { - saved: `(saved {timestamp})` + saved: `(已保存 {timestamp})` // (saved {timestamp}) }, error: { - noContract: `No contract has been found.`, - params: `An error occurred with the following description` + noContract: `没有找到合约`, // No contract has been found. + params: `发生了如下描述的一个错误` // An error occurred with the following description }, input: { - abi: `ABI Definition`, - code: `Bytecode`, - metadata: `Metadata`, - swarm: `Swarm Metadata Hash` + abi: `ABI界面`, // ABI Interface + code: `字节码`, // Bytecode + metadata: `元数据`, // Metadata + swarm: `Swarm元数据哈希` // Sarm Metadata Hash }, title: { - contract: `Select a contract`, - loading: `Loading...`, - main: `Write a Contract`, - messages: `Compiler messages`, - new: `New Solidity Contract`, - parameters: `Parameters`, - saved: `saved @ {timestamp}`, - selectSolidity: `Select a Solidity version`, - solidity: `Loading Solidity {version}` + contract: `选择一个合约`, // Select a contract + loading: `加载中...`, // Loading... + main: `写一个合约`, // Write a Contract + messages: `编译器消息`, // Compiler messages + new: `新建Solidity合约`, // New Solidity Contract + parameters: `变量`, // Parameters + saved: `已保存 @ {timestamp}`, // saved @ {timestamp} + selectSolidity: `选择Solidity版本`, // Select a Solidity version + solidity: `正在加载Solidity {version}` // Loading Solidity {version} }, type: { - humanErc20: `Implementation of the Human Token Contract`, - implementErc20: `Implementation of ERC20 Token Contract`, - multisig: `Implementation of a multisig Wallet`, - standardErc20: `Standard ERC20 Token Contract` + humanErc20: `Human代币合约编码`, // Implementation of the Human Token Contract + implementErc20: `ERC20代币合约编码`, // Implementation of the ERC20 Token Contract + multisig: `多签钱包编码`, // Implementation of a multisig Wallet + standardErc20: `标准ERC20代币合约` // Standard ERC20 Token Contract } }; diff --git a/js/src/index.ejs b/js/src/index.ejs index ec8592b88..305568f5b 100644 --- a/js/src/index.ejs +++ b/js/src/index.ejs @@ -8,6 +8,7 @@