Merge branch 'master' into auth-round

This commit is contained in:
keorn 2016-11-09 10:35:00 +00:00
commit 49f2a72d5d
184 changed files with 4102 additions and 2208 deletions

View File

@ -8,17 +8,18 @@ variables:
RUST_BACKTRACE: "1"
RUSTFLAGS: ""
CARGOFLAGS: ""
NIGHTLY: "nigtly"
cache:
key: "$CI_BUILD_REF_NAME"
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
untracked: true
linux-stable:
stage: build
image: ethcore/rust:stable
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- cargo build --release $CARGOFLAGS
- strip target/release/parity
@ -41,44 +42,14 @@ linux-stable:
paths:
- target/release/parity
name: "stable-x86_64-unknown-linux-gnu_parity"
linux-stable-14.04:
stage: build
image: ethcore/rust-14.04:latest
only:
- $NIGHTLY
- beta
- tags
- stable
script:
- cargo build --release $CARGOFLAGS
- strip target/release/parity
- md5sum target/release/parity >> parity.md5
- sh scripts/deb-build.sh amd64
- cp target/release/parity deb/usr/bin/parity
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
- dpkg-deb -b deb "parity_"$VER"_amd64.deb"
- 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
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-ubuntu_14_04-gnu/parity --body target/release/parity
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-ubuntu_14_04-gnu/parity.md5 --body parity.md5
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-ubuntu_14_04-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-ubuntu_14_04-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
tags:
- rust
- rust-14.04
artifacts:
paths:
- target/release/parity
name: "stable-x86_64-unknown-ubuntu_14_04-gnu_parity"
linux-beta:
stage: build
image: ethcore/rust:beta
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- cargo build --release $CARGOFLAGS
- strip target/release/parity
@ -94,10 +65,10 @@ linux-nightly:
stage: build
image: ethcore/rust:nightly
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- cargo build --release $CARGOFLAGS
- strip target/release/parity
@ -113,10 +84,10 @@ linux-centos:
stage: build
image: ethcore/rust-centos:latest
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- export CXX="g++"
- export CC="gcc"
@ -134,14 +105,47 @@ linux-centos:
paths:
- target/release/parity
name: "x86_64-unknown-centos-gnu_parity"
linux-i686:
stage: build
image: ethcore/rust-i686:latest
only:
- beta
- tags
- stable
- triggers
script:
- export HOST_CC=gcc
- export HOST_CXX=g++
- cargo build --target i686-unknown-linux-gnu --release $CARGOFLAGS
- strip target/i686-unknown-linux-gnu/release/parity
- md5sum target/i686-unknown-linux-gnu/release/parity >> parity.md5
- sh scripts/deb-build.sh i386
- cp target/i686-unknown-linux-gnu/release/parity deb/usr/bin/parity
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
- dpkg-deb -b deb "parity_"$VER"_i386.deb"
- 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
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity --body target/i686-unknown-linux-gnu/release/parity
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity.md5 --body parity.md5
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb" --body "parity_"$VER"_i386.deb"
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/"parity_"$VER"_i386.deb.md5" --body "parity_"$VER"_i386.deb.md5"
tags:
- rust
- rust-i686
artifacts:
paths:
- target/i686-unknown-linux-gnu/release/parity
name: "i686-unknown-linux-gnu"
allow_failure: true
linux-armv7:
stage: build
image: ethcore/rust-armv7:latest
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- export CC=arm-linux-gnueabihf-gcc
- export CXX=arm-linux-gnueabihf-g++
@ -178,10 +182,10 @@ linux-arm:
stage: build
image: ethcore/rust-arm:latest
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- export CC=arm-linux-gnueabihf-gcc
- export CXX=arm-linux-gnueabihf-g++
@ -218,10 +222,10 @@ linux-armv6:
stage: build
image: ethcore/rust-armv6:latest
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- export CC=arm-linux-gnueabi-gcc
- export CXX=arm-linux-gnueabi-g++
@ -251,10 +255,10 @@ linux-aarch64:
stage: build
image: ethcore/rust-aarch64:latest
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- export CC=aarch64-linux-gnu-gcc
- export CXX=aarch64-linux-gnu-g++
@ -290,10 +294,10 @@ linux-aarch64:
darwin:
stage: build
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- cargo build --release $CARGOFLAGS
- rm -rf parity.md5
@ -309,12 +313,15 @@ darwin:
- target/release/parity
name: "x86_64-apple-darwin_parity"
windows:
cache:
key: "%CI_BUILD_STAGE%/%CI_BUILD_REF_NAME%"
untracked: true
stage: build
only:
- $NIGHTLY
- beta
- tags
- stable
- triggers
script:
- set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt
- set LIB=C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64
@ -325,8 +332,8 @@ windows:
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe
- signtool sign /f %keyfile% /p %certpass% target\release\parity.exe
- msbuild windows\ptray\ptray.vcxproj /p:Platform=x86 /p:Configuration=Release
- signtool sign /f %keyfile% /p %certpass% windows\ptray\release\ptray.exe
- msbuild windows\ptray\ptray.vcxproj /p:Platform=x64 /p:Configuration=Release
- signtool sign /f %keyfile% /p %certpass% windows\ptray\x64\release\ptray.exe
- cd nsis
- makensis.exe installer.nsi
- copy installer.exe InstallParity.exe
@ -361,9 +368,7 @@ windows:
test-darwin:
stage: test
only:
- beta
- tags
- stable
- triggers
before_script:
- git submodule update --init --recursive
script:
@ -371,12 +376,11 @@ test-darwin:
- ./test.sh $CARGOFLAGS --no-release
tags:
- osx
allow_failure: true
test-windows:
stage: test
only:
- beta
- tags
- stable
- triggers
before_script:
- git submodule update --init --recursive
script:
@ -390,7 +394,7 @@ test-rust-stable:
image: ethcore/rust:stable
before_script:
- git submodule update --init --recursive
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF_NAME $(git merge-base $CI_BUILD_REF_NAME master) | grep \.js | wc -l)
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only CI_BUILD_REF CI_BUILD_REF@{1} | grep \.js | wc -l)
- echo $JS_FILES_MODIFIED
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; fi
script:
@ -400,6 +404,42 @@ test-rust-stable:
tags:
- rust
- rust-stable
test-rust-beta:
stage: test
only:
- triggers
image: ethcore/rust:beta
before_script:
- git submodule update --init --recursive
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only CI_BUILD_REF CI_BUILD_REF@{1} | grep \.js | wc -l)
- echo $JS_FILES_MODIFIED
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; fi
script:
- export RUST_BACKTRACE=1
- echo $JS_FILES_MODIFIED
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; else ./test.sh $CARGOFLAGS --no-release; fi
tags:
- rust
- rust-beta
allow_failure: true
test-rust-nightly:
stage: test
only:
- triggers
image: ethcore/rust:nightly
before_script:
- git submodule update --init --recursive
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only CI_BUILD_REF CI_BUILD_REF@{1} | grep \.js | wc -l)
- echo $JS_FILES_MODIFIED
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; fi
script:
- export RUST_BACKTRACE=1
- echo $JS_FILES_MODIFIED
- if [ -z $JS_FILES_MODIFIED ]; then echo "skip js test"; else ./test.sh $CARGOFLAGS --no-release; fi
tags:
- rust
- rust-nightly
allow_failure: true
js-tests:
stage: test
image: ethcore/rust:stable
@ -417,12 +457,11 @@ js-release:
- master
- beta
- stable
- tags
image: ethcore/rust:stable
before_script:
- ./js/scripts/install-deps.sh
- if [[ $NIGHTLY != "master" ]]; then ./js/scripts/install-deps.sh; fi
script:
- ./js/scripts/build.sh
- ./js/scripts/release.sh
- if [[ $NIGHTLY != "master" ]]; then ./js/scripts/build.sh; fi
- if [[ $NIGHTLY != "master" ]]; then ./js/scripts/release.sh; fi
tags:
- javascript

82
Cargo.lock generated
View File

@ -1,6 +1,6 @@
[root]
name = "parity"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
@ -8,21 +8,21 @@ dependencies = [
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.4.0",
"ethcore-dapps 1.4.0",
"ethcore 1.5.0",
"ethcore-dapps 1.5.0",
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-io 1.5.0",
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-hypervisor 1.2.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-ipc-tests 0.1.0",
"ethcore-logger 1.4.0",
"ethcore-rpc 1.4.0",
"ethcore-signer 1.4.0",
"ethcore-logger 1.5.0",
"ethcore-rpc 1.5.0",
"ethcore-signer 1.5.0",
"ethcore-stratum 1.4.0",
"ethcore-util 1.4.0",
"ethsync 1.4.0",
"ethcore-util 1.5.0",
"ethsync 1.5.0",
"fdlimit 0.1.0",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -274,7 +274,7 @@ dependencies = [
[[package]]
name = "ethcore"
version = "1.4.0"
version = "1.5.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)",
@ -285,11 +285,11 @@ dependencies = [
"ethash 1.4.0",
"ethcore-bloom-journal 0.1.0",
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-io 1.5.0",
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-util 1.4.0",
"ethcore-util 1.5.0",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
@ -329,14 +329,14 @@ dependencies = [
[[package]]
name = "ethcore-dapps"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-devtools 1.4.0",
"ethcore-rpc 1.4.0",
"ethcore-util 1.4.0",
"ethcore-rpc 1.5.0",
"ethcore-util 1.5.0",
"fetch 0.1.0",
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -367,7 +367,7 @@ dependencies = [
[[package]]
name = "ethcore-io"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -381,7 +381,7 @@ name = "ethcore-ipc"
version = "1.4.0"
dependencies = [
"ethcore-devtools 1.4.0",
"ethcore-util 1.4.0",
"ethcore-util 1.5.0",
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -428,7 +428,7 @@ dependencies = [
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-util 1.4.0",
"ethcore-util 1.5.0",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -436,10 +436,10 @@ dependencies = [
[[package]]
name = "ethcore-logger"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.4.0",
"ethcore-util 1.5.0",
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -449,13 +449,13 @@ dependencies = [
[[package]]
name = "ethcore-network"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-util 1.4.0",
"ethcore-io 1.5.0",
"ethcore-util 1.5.0",
"ethcrypto 0.1.0",
"ethkey 0.2.0",
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -474,20 +474,20 @@ dependencies = [
[[package]]
name = "ethcore-rpc"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
"ethash 1.4.0",
"ethcore 1.4.0",
"ethcore 1.5.0",
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-io 1.5.0",
"ethcore-ipc 1.4.0",
"ethcore-util 1.4.0",
"ethcore-util 1.5.0",
"ethcrypto 0.1.0",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
"ethsync 1.4.0",
"ethsync 1.5.0",
"fetch 0.1.0",
"json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git)",
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -504,14 +504,14 @@ dependencies = [
[[package]]
name = "ethcore-signer"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-rpc 1.4.0",
"ethcore-util 1.4.0",
"ethcore-io 1.5.0",
"ethcore-rpc 1.5.0",
"ethcore-util 1.5.0",
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -530,7 +530,7 @@ dependencies = [
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-util 1.4.0",
"ethcore-util 1.5.0",
"json-tcp-server 0.1.0 (git+https://github.com/ethcore/json-tcp-server)",
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -541,7 +541,7 @@ dependencies = [
[[package]]
name = "ethcore-util"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -590,7 +590,7 @@ dependencies = [
name = "ethjson"
version = "0.1.0"
dependencies = [
"ethcore-util 1.4.0",
"ethcore-util 1.5.0",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -633,17 +633,17 @@ dependencies = [
[[package]]
name = "ethsync"
version = "1.4.0"
version = "1.5.0"
dependencies = [
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.4.0",
"ethcore-io 1.4.0",
"ethcore 1.5.0",
"ethcore-io 1.5.0",
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-network 1.4.0",
"ethcore-util 1.4.0",
"ethcore-network 1.5.0",
"ethcore-util 1.5.0",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1249,7 +1249,7 @@ dependencies = [
[[package]]
name = "parity-ui-precompiled"
version = "1.4.0"
source = "git+https://github.com/ethcore/js-precompiled.git#cb99e22b536486190f3e19b2760e1142096b5fd7"
source = "git+https://github.com/ethcore/js-precompiled.git#5d1134b5f836aafccb648e300817524081ac91e3"
dependencies = [
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@ -1,7 +1,7 @@
[package]
description = "Ethcore client."
name = "parity"
version = "1.4.0"
version = "1.5.0"
license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"

View File

@ -1,9 +1,12 @@
# [Parity](https://ethcore.io/parity.html)
### Fast, light, and robust Ethereum implementation
[![Join the chat at https://gitter.im/ethcore/parity.js](https://badges.gitter.im/ethcore/parity.js.svg)](https://gitter.im/ethcore/parity.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status][travis-image]][travis-url] [![build status](https://gitlab.ethcore.io/Mirrors/ethcore-parity/badges/master/build.svg)](https://gitlab.ethcore.io/Mirrors/ethcore-parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![GPLv3][license-image]][license-url]
[![Build Status][travis-image]][travis-url] [![build status](https://gitlab.ethcore.io/Mirrors/ethcore-parity/badges/master/build.svg)](https://gitlab.ethcore.io/Mirrors/ethcore-parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/ethcore/parity][gitter-image]][gitter-url] [![GPLv3][license-image]][license-url]
### Join the chat!
Parity [![Join the chat at https://gitter.im/ethcore/parity][gitter-image]][gitter-url] and
parity.js [![Join the chat at https://gitter.im/ethcore/parity.js](https://badges.gitter.im/ethcore/parity.js.svg)](https://gitter.im/ethcore/parity.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[Internal Documentation][doc-url]
@ -21,7 +24,7 @@ Be sure to check out [our wiki][wiki-url] for more information.
[doc-url]: https://ethcore.github.io/parity/ethcore/index.html
[wiki-url]: https://github.com/ethcore/parity/wiki
**Requires Rust version 1.12.0 to build**
**Parity requires Rust version 1.12.0 to build**
----
@ -31,12 +34,15 @@ 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.
By default, Parity will run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number
of RPC APIs.
Parity comes with a built-in wallet. To access [Parity Wallet](http://127.0.0.1:8080/) this simply go to http://127.0.0.1:8080/. It
includes various functionality allowing you to:
- create and manage your Ethereum accounts;
- manage your Ether and any Ethereum tokens;
- create and register your own tokens;
- and much more.
Parity also runs a server for running decentralized apps, or "Dapps", on `http://127.0.0.1:8080`.
This includes a few useful Dapps, including Ethereum Wallet, Maker OTC, and a node status page.
In a near-future release, it will be easy to install Dapps and use them through this web interface.
By default, Parity will also run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number
of RPC APIs.
If you run into an issue while using parity, feel free to file one in this repository
or hop on our [gitter chat room][gitter-url] to ask a question. We are glad to help!

View File

@ -38,8 +38,8 @@ after_test:
- cargo build --verbose --release
- ps: if($env:cert) { Start-FileDownload $env:cert -FileName $env:keyfile }
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass target\release\parity.exe }
- msbuild windows\ptray\ptray.vcxproj /p:Platform=x86 /p:Configuration=Release
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass windows\ptray\release\ptray.exe }
- msbuild windows\ptray\ptray.vcxproj /p:Platform=x64 /p:Configuration=Release
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass windows\ptray\x64\release\ptray.exe }
- makensis.exe nsis\installer.nsi
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass nsis\installer.exe }

View File

@ -1,7 +1,7 @@
[package]
description = "Parity Dapps crate"
name = "ethcore-dapps"
version = "1.4.0"
version = "1.5.0"
license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io"]
build = "build.rs"

View File

@ -3,7 +3,7 @@ description = "Ethcore library"
homepage = "http://ethcore.io"
license = "GPL-3.0"
name = "ethcore"
version = "1.4.0"
version = "1.5.0"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"

View File

@ -15,7 +15,9 @@
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff"
"eip161dTransition": "0x7fffffffffffffff",
"ecip1010PauseTransition": "0x2dc6c0",
"ecip1010ContinueTransition": "0x4c4b40"
}
}
},

View File

@ -65,7 +65,7 @@ use evm::{Factory as EvmFactory, Schedule};
use miner::{Miner, MinerService};
use snapshot::{self, io as snapshot_io};
use factory::Factories;
use rlp::{View, UntrustedRlp};
use rlp::{decode, View, UntrustedRlp};
use state_db::StateDB;
use rand::OsRng;
@ -147,6 +147,7 @@ pub struct Client {
factories: Factories,
history: u64,
rng: Mutex<OsRng>,
on_mode_change: Mutex<Option<Box<FnMut(&Mode) + 'static + Send>>>,
}
impl Client {
@ -211,7 +212,7 @@ impl Client {
let panic_handler = PanicHandler::new_in_arc();
panic_handler.forward_from(&block_queue);
let awake = match config.mode { Mode::Dark(..) => false, _ => true };
let awake = match config.mode { Mode::Dark(..) | Mode::Off => false, _ => true };
let factories = Factories {
vm: EvmFactory::new(config.vm_type.clone(), config.jump_table_size),
@ -243,6 +244,7 @@ impl Client {
factories: factories,
history: history,
rng: Mutex::new(try!(OsRng::new().map_err(::util::UtilError::StdIo))),
on_mode_change: Mutex::new(None),
};
Ok(Arc::new(client))
}
@ -260,6 +262,11 @@ impl Client {
}
}
/// Register an action to be done if a mode change happens.
pub fn on_mode_change<F>(&self, f: F) where F: 'static + FnMut(&Mode) + Send {
*self.on_mode_change.lock() = Some(Box::new(f));
}
/// Flush the block import queue.
pub fn flush_queue(&self) {
self.block_queue.flush();
@ -862,18 +869,37 @@ impl BlockChainClient for Client {
}
fn keep_alive(&self) {
let mode = self.mode.lock().clone();
if mode != Mode::Active {
let should_wake = match &*self.mode.lock() {
&Mode::Dark(..) | &Mode::Passive(..) => true,
_ => false,
};
if should_wake {
self.wake_up();
(*self.sleep_state.lock()).last_activity = Some(Instant::now());
}
}
fn mode(&self) -> IpcMode { self.mode.lock().clone().into() }
fn mode(&self) -> IpcMode {
let r = self.mode.lock().clone().into();
trace!(target: "mode", "Asked for mode = {:?}. returning {:?}", &*self.mode.lock(), r);
r
}
fn set_mode(&self, mode: IpcMode) {
*self.mode.lock() = mode.clone().into();
match mode {
fn set_mode(&self, new_mode: IpcMode) {
trace!(target: "mode", "Client::set_mode({:?})", new_mode);
{
let mut mode = self.mode.lock();
*mode = new_mode.clone().into();
trace!(target: "mode", "Mode now {:?}", &*mode);
match *self.on_mode_change.lock() {
Some(ref mut f) => {
trace!(target: "mode", "Making callback...");
f(&*mode)
},
_ => {}
}
}
match new_mode {
IpcMode::Active => self.wake_up(),
IpcMode::Off => self.sleep(),
_ => {(*self.sleep_state.lock()).last_activity = Some(Instant::now()); }
@ -1197,6 +1223,18 @@ impl BlockChainClient for Client {
fn signing_network_id(&self) -> Option<u8> {
self.engine.signing_network_id(&self.latest_env_info())
}
fn block_extra_info(&self, id: BlockID) -> Option<BTreeMap<String, String>> {
self.block_header(id)
.map(|block| decode(&block))
.map(|header| self.engine.extra_info(&header))
}
fn uncle_extra_info(&self, id: UncleID) -> Option<BTreeMap<String, String>> {
self.uncle(id)
.map(|block| BlockView::new(&block).header())
.map(|header| self.engine.extra_info(&header))
}
}
impl MiningBlockChainClient for Client {

View File

@ -16,6 +16,7 @@
use std::str::FromStr;
use std::path::Path;
use std::fmt::{Display, Formatter, Error as FmtError};
pub use std::time::Duration;
pub use blockchain::Config as BlockChainConfig;
pub use trace::Config as TraceConfig;
@ -86,6 +87,17 @@ impl Default for Mode {
}
}
impl Display for Mode {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
match *self {
Mode::Active => write!(f, "active"),
Mode::Passive(..) => write!(f, "passive"),
Mode::Dark(..) => write!(f, "dark"),
Mode::Off => write!(f, "offline"),
}
}
}
/// Client configuration. Includes configs for all sub-systems.
#[derive(Debug, PartialEq, Default)]
pub struct ClientConfig {

View File

@ -38,6 +38,7 @@ use evm::{Factory as EvmFactory, VMType, Schedule};
use miner::{Miner, MinerService, TransactionImportResult};
use spec::Spec;
use types::mode::Mode;
use views::BlockView;
use verification::queue::QueueInfo;
use block::{OpenBlock, SealedBlock};
@ -427,6 +428,10 @@ impl BlockChainClient for TestBlockChainClient {
None // Simple default.
}
fn uncle_extra_info(&self, _id: UncleID) -> Option<BTreeMap<String, String>> {
None
}
fn transaction_receipt(&self, id: TransactionID) -> Option<LocalizedReceipt> {
self.receipts.read().get(&id).cloned()
}
@ -469,6 +474,13 @@ impl BlockChainClient for TestBlockChainClient {
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).cloned())
}
fn block_extra_info(&self, id: BlockID) -> Option<BTreeMap<String, String>> {
self.block(id)
.map(|block| BlockView::new(&block).header())
.map(|header| self.spec.engine.extra_info(&header))
}
fn block_status(&self, id: BlockID) -> BlockStatus {
match id {
BlockID::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain,

View File

@ -29,13 +29,13 @@ use error::{ImportResult, CallError};
use receipt::LocalizedReceipt;
use trace::LocalizedTrace;
use evm::{Factory as EvmFactory, Schedule};
use types::ids::*;
use types::trace_filter::Filter as TraceFilter;
use executive::Executed;
use env_info::LastHashes;
use types::call_analytics::CallAnalytics;
use block_import_error::BlockImportError;
use ipc::IpcConfig;
use types::ids::*;
use types::trace_filter::Filter as TraceFilter;
use types::call_analytics::CallAnalytics;
use types::blockchain_info::BlockChainInfo;
use types::block_status::BlockStatus;
use types::mode::Mode;
@ -235,6 +235,12 @@ pub trait BlockChainClient : Sync + Send {
/// Set the mode.
fn set_mode(&self, mode: Mode);
/// Returns engine-related extra info for `BlockID`.
fn block_extra_info(&self, id: BlockID) -> Option<BTreeMap<String, String>>;
/// Returns engine-related extra info for `UncleID`.
fn uncle_extra_info(&self, id: UncleID) -> Option<BTreeMap<String, String>>;
}
/// Extended client interface used for mining

View File

@ -174,7 +174,7 @@ impl Engine for AuthorityRound {
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { hash_map!["signature".to_owned() => "TODO".to_owned()] }
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { map!["signature".to_owned() => "TODO".to_owned()] }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
Schedule::new_post_eip150(true, true, true)

View File

@ -81,7 +81,7 @@ impl Engine for BasicAuthority {
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { hash_map!["signature".to_owned() => "TODO".to_owned()] }
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { map!["signature".to_owned() => "TODO".to_owned()] }
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
Schedule::new_homestead()

View File

@ -51,7 +51,7 @@ pub trait Engine : Sync + Send {
fn seal_fields(&self) -> usize { 0 }
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { BTreeMap::new() }
/// Additional information.
fn additional_params(&self) -> HashMap<String, String> { HashMap::new() }

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager, H256 as EH256};
use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager};
use util::*;
use block::*;
use builtin::Builtin;
@ -70,6 +70,10 @@ pub struct EthashParams {
pub eip161abc_transition: u64,
/// Number of first block where EIP-161.d begins.
pub eip161d_transition: u64,
/// Number of first block where ECIP-1010 begins.
pub ecip1010_pause_transition: u64,
/// Number of first block where ECIP-1010 ends.
pub ecip1010_continue_transition: u64
}
impl From<ethjson::spec::EthashParams> for EthashParams {
@ -94,6 +98,8 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
eip160_transition: p.eip160_transition.map_or(0, Into::into),
eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into),
eip161d_transition: p.eip161d_transition.map_or(0x7fffffffffffffff, Into::into),
ecip1010_pause_transition: p.ecip1010_pause_transition.map_or(0x7fffffffffffffff, Into::into),
ecip1010_continue_transition: p.ecip1010_continue_transition.map_or(0x7fffffffffffffff, Into::into),
}
}
}
@ -133,8 +139,8 @@ impl Engine for Ethash {
}
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, header: &Header) -> HashMap<String, String> {
hash_map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())]
fn extra_info(&self, header: &Header) -> BTreeMap<String, String> {
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 {
@ -237,10 +243,10 @@ impl Engine for Ethash {
return Err(From::from(BlockError::DifficultyOutOfBounds(OutOfBounds { min: Some(min_difficulty), max: None, found: header.difficulty().clone() })))
}
let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(quick_get_difficulty(
&Ethash::to_ethash(header.bare_hash()),
let difficulty = Ethash::boundary_to_difficulty(&H256(quick_get_difficulty(
&header.bare_hash().0,
header.nonce().low_u64(),
&Ethash::to_ethash(header.mix_hash())
&header.mix_hash().0
)));
if &difficulty < header.difficulty() {
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty().clone()), max: None, found: difficulty })));
@ -265,10 +271,10 @@ impl Engine for Ethash {
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
)));
}
let result = self.pow.compute_light(header.number() as u64, &Ethash::to_ethash(header.bare_hash()), header.nonce().low_u64());
let mix = Ethash::from_ethash(result.mix_hash);
let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(result.value));
trace!(target: "miner", "num: {}, seed: {}, h: {}, non: {}, mix: {}, res: {}" , header.number() as u64, Ethash::from_ethash(slow_get_seedhash(header.number() as u64)), header.bare_hash(), header.nonce().low_u64(), Ethash::from_ethash(result.mix_hash), Ethash::from_ethash(result.value));
let result = self.pow.compute_light(header.number() as u64, &header.bare_hash().0, header.nonce().low_u64());
let mix = H256(result.mix_hash);
let difficulty = Ethash::boundary_to_difficulty(&H256(result.value));
trace!(target: "miner", "num: {}, seed: {}, h: {}, non: {}, mix: {}, res: {}" , header.number() as u64, H256(slow_get_seedhash(header.number() as u64)), header.bare_hash(), header.nonce().low_u64(), H256(result.mix_hash), H256(result.value));
if mix != header.mix_hash() {
return Err(From::from(BlockError::MismatchedH256SealElement(Mismatch { expected: mix, found: header.mix_hash() })));
}
@ -317,7 +323,7 @@ impl Engine for Ethash {
}
}
#[cfg_attr(feature="dev", allow(wrong_self_convention))] // to_ethash should take self
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
impl Ethash {
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
const EXP_DIFF_PERIOD: u64 = 100000;
@ -353,9 +359,20 @@ impl Ethash {
};
target = max(min_difficulty, target);
if header.number() < self.ethash_params.bomb_defuse_transition {
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
if period > 1 {
target = max(min_difficulty, target + (U256::from(1) << (period - 2)));
if header.number() < self.ethash_params.ecip1010_pause_transition {
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
if period > 1 {
target = max(min_difficulty, target + (U256::from(1) << (period - 2)));
}
}
else if header.number() < self.ethash_params.ecip1010_continue_transition {
let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize;
target = max(min_difficulty, target + (U256::from(1) << fixed_difficulty));
}
else {
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize;
target = max(min_difficulty, target + (U256::from(1) << (period - delay - 2)));
}
}
target
@ -379,14 +396,6 @@ impl Ethash {
(((U256::one() << 255) / *difficulty) << 1).into()
}
}
fn to_ethash(hash: H256) -> EH256 {
unsafe { mem::transmute(hash) }
}
fn from_ethash(hash: EH256) -> H256 {
unsafe { mem::transmute(hash) }
}
}
impl Header {
@ -414,8 +423,8 @@ mod tests {
use env_info::EnvInfo;
use error::{BlockError, Error};
use header::Header;
use super::super::new_morden;
use super::Ethash;
use super::super::{new_morden, new_homestead_test};
use super::{Ethash, EthashParams};
use rlp;
#[test]
@ -637,5 +646,122 @@ mod tests {
assert_eq!(Ethash::difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap());
}
// TODO: difficulty test
#[test]
fn difficulty_frontier() {
let spec = new_homestead_test();
let ethparams = get_default_ethash_params();
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
let mut parent_header = Header::default();
parent_header.set_number(1000000);
parent_header.set_difficulty(U256::from_str("b69de81a22b").unwrap());
parent_header.set_timestamp(1455404053);
let mut header = Header::default();
header.set_number(parent_header.number() + 1);
header.set_timestamp(1455404058);
let difficulty = ethash.calculate_difficulty(&header, &parent_header);
assert_eq!(U256::from_str("b6b4bbd735f").unwrap(), difficulty);
}
#[test]
fn difficulty_homestead() {
let spec = new_homestead_test();
let ethparams = get_default_ethash_params();
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
let mut parent_header = Header::default();
parent_header.set_number(1500000);
parent_header.set_difficulty(U256::from_str("1fd0fd70792b").unwrap());
parent_header.set_timestamp(1463003133);
let mut header = Header::default();
header.set_number(parent_header.number() + 1);
header.set_timestamp(1463003177);
let difficulty = ethash.calculate_difficulty(&header, &parent_header);
assert_eq!(U256::from_str("1fc50f118efe").unwrap(), difficulty);
}
#[test]
fn difficulty_classic_bomb_delay() {
let spec = new_homestead_test();
let ethparams = EthashParams {
ecip1010_pause_transition: 3000000,
..get_default_ethash_params()
};
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
let mut parent_header = Header::default();
parent_header.set_number(3500000);
parent_header.set_difficulty(U256::from_str("6F62EAF8D3C").unwrap());
parent_header.set_timestamp(1452838500);
let mut header = Header::default();
header.set_number(parent_header.number() + 1);
header.set_timestamp(parent_header.timestamp() + 20);
assert_eq!(
U256::from_str("6F55FE9B74B").unwrap(),
ethash.calculate_difficulty(&header, &parent_header)
);
header.set_timestamp(parent_header.timestamp() + 5);
assert_eq!(
U256::from_str("6F71D75632D").unwrap(),
ethash.calculate_difficulty(&header, &parent_header)
);
header.set_timestamp(parent_header.timestamp() + 80);
assert_eq!(
U256::from_str("6F02746B3A5").unwrap(),
ethash.calculate_difficulty(&header, &parent_header)
);
}
#[test]
fn test_difficulty_bomb_continue() {
let spec = new_homestead_test();
let ethparams = EthashParams {
ecip1010_pause_transition: 3000000,
ecip1010_continue_transition: 5000000,
..get_default_ethash_params()
};
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
let mut parent_header = Header::default();
parent_header.set_number(5000102);
parent_header.set_difficulty(U256::from_str("14944397EE8B").unwrap());
parent_header.set_timestamp(1513175023);
let mut header = Header::default();
header.set_number(parent_header.number() + 1);
header.set_timestamp(parent_header.timestamp() + 6);
assert_eq!(
U256::from_str("1496E6206188").unwrap(),
ethash.calculate_difficulty(&header, &parent_header)
);
parent_header.set_number(5100123);
parent_header.set_difficulty(U256::from_str("14D24B39C7CF").unwrap());
parent_header.set_timestamp(1514609324);
header.set_number(parent_header.number() + 1);
header.set_timestamp(parent_header.timestamp() + 41);
assert_eq!(
U256::from_str("14CA9C5D9227").unwrap(),
ethash.calculate_difficulty(&header, &parent_header)
);
parent_header.set_number(6150001);
parent_header.set_difficulty(U256::from_str("305367B57227").unwrap());
parent_header.set_timestamp(1529664575);
header.set_number(parent_header.number() + 1);
header.set_timestamp(parent_header.timestamp() + 105);
assert_eq!(
U256::from_str("309D09E0C609").unwrap(),
ethash.calculate_difficulty(&header, &parent_header)
);
parent_header.set_number(8000000);
parent_header.set_difficulty(U256::from_str("1180B36D4CE5B6A").unwrap());
parent_header.set_timestamp(1535431724);
header.set_number(parent_header.number() + 1);
header.set_timestamp(parent_header.timestamp() + 420);
assert_eq!(
U256::from_str("5126FFD5BCBB9E7").unwrap(),
ethash.calculate_difficulty(&header, &parent_header)
);
}
}

View File

@ -27,6 +27,7 @@ use evm::Schedule;
use engines::Engine;
use env_info::EnvInfo;
use ethereum;
use ethereum::ethash::EthashParams;
use devtools::*;
use miner::Miner;
use header::Header;
@ -422,3 +423,29 @@ pub fn get_bad_state_dummy_block() -> Bytes {
create_test_block(&block_header)
}
pub fn get_default_ethash_params() -> EthashParams{
EthashParams {
gas_limit_bound_divisor: U256::from(1024),
minimum_difficulty: U256::from(131072),
difficulty_bound_divisor: U256::from(2048),
difficulty_increment_divisor: 10,
duration_limit: 13,
block_reward: U256::from(0),
registrar: "0000000000000000000000000000000000000001".into(),
homestead_transition: 1150000,
dao_hardfork_transition: 0x7fffffffffffffff,
dao_hardfork_beneficiary: "0000000000000000000000000000000000000001".into(),
dao_hardfork_accounts: vec![],
difficulty_hardfork_transition: 0x7fffffffffffffff,
difficulty_hardfork_bound_divisor: U256::from(0),
bomb_defuse_transition: 0x7fffffffffffffff,
eip150_transition: 0x7fffffffffffffff,
eip155_transition: 0x7fffffffffffffff,
eip160_transition: 0x7fffffffffffffff,
eip161abc_transition: 0x7fffffffffffffff,
eip161d_transition: 0x7fffffffffffffff,
ecip1010_pause_transition: 0x7fffffffffffffff,
ecip1010_continue_transition: 0x7fffffffffffffff
}
}

View File

@ -55,7 +55,7 @@ pub struct TraceId {
}
/// Uniquely identifies Uncle.
#[derive(Debug, Binary)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Binary)]
pub struct UncleID {
/// Block id.
pub block: BlockID,

View File

@ -20,7 +20,7 @@ pub use std::time::Duration;
use client::Mode as ClientMode;
/// IPC-capable shadow-type for client::config::Mode
#[derive(Clone, Binary)]
#[derive(Clone, Binary, Debug)]
pub enum Mode {
/// Same as ClientMode::Off.
Off,

View File

@ -159,7 +159,7 @@ impl Transaction {
unsigned: self,
r: sig.r().into(),
s: sig.s().into(),
v: sig.v() + if let Some(n) = network_id { 1 + n * 2 } else { 27 },
v: sig.v() + if let Some(n) = network_id { 35 + n * 2 } else { 27 },
hash: Cell::new(None),
sender: Cell::new(None),
}
@ -302,13 +302,13 @@ impl SignedTransaction {
}
/// 0 if `v` would have been 27 under "Electrum" notation, 1 if 28 or 4 if invalid.
pub fn standard_v(&self) -> u8 { match self.v { 0 => 4, v => (v - 1) & 1, } }
pub fn standard_v(&self) -> u8 { match self.v { v if v == 27 || v == 28 || v > 36 => (v - 1) % 2, _ => 4 } }
/// The network ID, or `None` if this is a global transaction.
pub fn network_id(&self) -> Option<u8> {
match self.v {
0 | 27 | 28 => None,
v => Some((v - 1) / 2),
v if v > 36 => Some((v - 35) / 2),
_ => None,
}
}
@ -456,21 +456,22 @@ fn should_recover_from_network_specific_signing() {
#[test]
fn should_agree_with_vitalik() {
use rustc_serialize::hex::FromHex;
use std::str::FromStr;
let test_vector = |tx_data: &str, address: &'static str| {
let signed: SignedTransaction = decode(&FromHex::from_hex(tx_data).unwrap());
signed.check_low_s().unwrap();
assert_eq!(signed.sender().unwrap(), address.into());
flushln!("networkid: {:?}", signed.network_id());
};
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xda39a520355857fdb37ecb527fe814230fa9962c");
test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc8a0c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0xd240215f30eafee2aaa5184d8f051ebb41c90b19");
test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a0ad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a8a0ad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2f2822c55d894df1ba32961c43325dcb3d614ee8");
test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0xc21df0434ceab6e18a1300d18206e54e807b4456");
test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf975cee81edae2ab5883f4e2fb2a7f2fd56f4131");
test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a0ceebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a0ceebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xd477474c9f48dcbfde5d97f30646242ab7a17e06");
test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a0e455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2da0e455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xb49948deb719ca21e38d29e3360f534b39db0e76");
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xbddfc81a8ce87b2360837049a6eda68ab2f58999");
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a0e4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c11a0e4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x8f2edcf67f329a146dd4cb1e6b3a072daff85b38");
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a0d2f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba0d2f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x4ec38d4782fd4a6ff85c1cde77ccf1ae3c54472c");
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce")
test_vector("f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112")
test_vector("f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be")
test_vector("f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0")
test_vector("f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554")
test_vector("f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4")
test_vector("f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35")
test_vector("f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332")
test_vector("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029")
test_vector("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f")
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

View File

@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
// test only
/**
* Run `PARITY_URL="127.0.0.1:8180" NODE_ENV="production" npm run build`
* to build the project ; use this server to test that the minifed

View File

@ -1,11 +1,13 @@
{
"name": "parity.js",
"version": "0.1.63",
"version": "0.2.21",
"main": "release/index.js",
"jsnext:main": "src/index.js",
"author": "Parity Team <admin@parity.io>",
"maintainers": [
"Jaco Greeff"
"Jaco Greeff",
"Nicolas Gotchac",
"Jannis Redmann"
],
"contributors": [],
"license": "GPL-3.0",
@ -23,16 +25,16 @@
"Promise"
],
"scripts": {
"build": "npm run build:dll && npm run build:app && npm run build:lib",
"build": "npm run build:lib && npm run build:dll && npm run build:app",
"build:app": "webpack --progress",
"build:lib": "webpack --config webpack.libraries --progress",
"build:dll": "webpack --config webpack.vendor --progress",
"ci:build": "npm run ci:build:dll && npm run ci:build:app && npm run ci:build:lib",
"ci:build": "npm run ci:build:lib && npm run ci:build:dll && npm run ci:build:app",
"ci:build:app": "NODE_ENV=production webpack",
"ci:build:lib": "NODE_ENV=production webpack --config webpack.libraries",
"ci:build:dll": "NODE_ENV=production webpack --config webpack.vendor",
"ci:build:npm": "NODE_ENV=production webpack --config webpack.npm",
"start": "npm install && npm run build:dll && npm run start:app",
"start": "npm install && npm run build:lib && npm run build:dll && npm run start:app",
"start:app": "webpack-dev-server -d --history-api-fallback --open --hot --inline --progress --colors --port 3000",
"clean": "rm -rf ./build ./coverage",
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
@ -44,7 +46,7 @@
"devDependencies": {
"babel-cli": "^6.10.1",
"babel-core": "^6.10.4",
"babel-eslint": "^6.1.2",
"babel-eslint": "^7.1.0",
"babel-loader": "^6.2.3",
"babel-plugin-lodash": "^3.2.2",
"babel-plugin-transform-class-properties": "^6.11.5",
@ -126,6 +128,9 @@
"marked": "^0.3.6",
"material-ui": "^0.16.1",
"material-ui-chip-input": "^0.8.0",
"mobx": "^2.6.1",
"mobx-react": "^3.5.8",
"mobx-react-devtools": "^4.2.9",
"moment": "^2.14.1",
"qs": "^6.3.0",
"react": "^15.2.1",

View File

@ -135,10 +135,11 @@ APIs implement the calls as exposed in the [Ethcore JSON Ethereum RPC](https://g
- [ethapi.db](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#db)
- [ethapi.eth](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#eth)
- [ethapi.ethcore](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#ethcore)
- [ethapi.parity](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#parity)
- [ethapi.net](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#net)
- [ethapi.personal](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#personal)
- [ethapi.shh](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#shh)
- [ethapi.signer](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#signer)
- [ethapi.trace](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#trace)
- [ethapi.web3](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#web3)

View File

@ -17,7 +17,7 @@
import { Http, Ws } from './transport';
import Contract from './contract';
import { Db, Eth, Ethcore, Net, Personal, Shh, Trace, Web3 } from './rpc';
import { Db, Eth, Parity, Net, Personal, Shh, Signer, Trace, Web3 } from './rpc';
import Subscriptions from './subscriptions';
import util from './util';
import { isFunction } from './util/types';
@ -32,10 +32,11 @@ export default class Api {
this._db = new Db(transport);
this._eth = new Eth(transport);
this._ethcore = new Ethcore(transport);
this._net = new Net(transport);
this._parity = new Parity(transport);
this._personal = new Personal(transport);
this._shh = new Shh(transport);
this._signer = new Signer(transport);
this._trace = new Trace(transport);
this._web3 = new Web3(transport);
@ -50,8 +51,8 @@ export default class Api {
return this._eth;
}
get ethcore () {
return this._ethcore;
get parity () {
return this._parity;
}
get net () {
@ -66,6 +67,10 @@ export default class Api {
return this._shh;
}
get signer () {
return this._signer;
}
get trace () {
return this._trace;
}

View File

@ -102,7 +102,7 @@ export default class Contract {
options.gas = gas.toFixed(0);
setState({ state: 'postTransaction', gas });
return this._api.eth.postTransaction(this._encodeOptions(this.constructors[0], options, values));
return this._api.parity.postTransaction(this._encodeOptions(this.constructors[0], options, values));
})
.then((requestId) => {
setState({ state: 'checkRequest', requestId });
@ -166,7 +166,7 @@ export default class Contract {
}
_pollCheckRequest = (requestId) => {
return this._api.pollMethod('eth_checkRequest', requestId);
return this._api.pollMethod('parity_checkRequest', requestId);
}
_pollTransactionReceipt = (txhash, gas) => {
@ -208,7 +208,7 @@ export default class Contract {
if (!func.constant) {
func.postTransaction = (options, values = []) => {
return this._api.eth
return this._api.parity
.postTransaction(this._encodeOptions(func, this._addOptionsTo(options), values));
};

View File

@ -249,9 +249,9 @@ describe('api/contract/Contract', () => {
before(() => {
scope = mockHttp([
{ method: 'eth_estimateGas', reply: { result: 1000 } },
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
{ method: 'eth_checkRequest', reply: { result: null } },
{ method: 'eth_checkRequest', reply: { result: '0x890' } },
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
{ method: 'parity_checkRequest', reply: { result: null } },
{ method: 'parity_checkRequest', reply: { result: '0x890' } },
{ method: 'eth_getTransactionReceipt', reply: { result: null } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_PEND } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } },
@ -266,7 +266,7 @@ describe('api/contract/Contract', () => {
});
it('passes the options through to postTransaction (incl. gas calculation)', () => {
expect(scope.body.eth_postTransaction.params).to.deep.equal([
expect(scope.body.parity_postTransaction.params).to.deep.equal([
{ data: '0x123', gas: '0x4b0' }
]);
});
@ -280,8 +280,8 @@ describe('api/contract/Contract', () => {
it('fails when gasUsed == gas', () => {
mockHttp([
{ method: 'eth_estimateGas', reply: { result: 1000 } },
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
{ method: 'eth_checkRequest', reply: { result: '0x789' } },
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
{ method: 'parity_checkRequest', reply: { result: '0x789' } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_EXCP } }
]);
@ -295,8 +295,8 @@ describe('api/contract/Contract', () => {
it('fails when no code was deployed', () => {
mockHttp([
{ method: 'eth_estimateGas', reply: { result: 1000 } },
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
{ method: 'eth_checkRequest', reply: { result: '0x789' } },
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
{ method: 'parity_checkRequest', reply: { result: '0x789' } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } },
{ method: 'eth_getCode', reply: { result: '0x' } }
]);
@ -360,15 +360,15 @@ describe('api/contract/Contract', () => {
describe('postTransaction', () => {
beforeEach(() => {
scope = mockHttp([{ method: 'eth_postTransaction', reply: { result: ['hashId'] } }]);
scope = mockHttp([{ method: 'parity_postTransaction', reply: { result: ['hashId'] } }]);
});
it('encodes options and mades an eth_postTransaction call', () => {
it('encodes options and mades an parity_postTransaction call', () => {
return func
.postTransaction({ someExtras: 'foo' }, VALUES)
.then(() => {
expect(scope.isDone()).to.be.true;
expect(scope.body.eth_postTransaction.params[0]).to.deep.equal({
expect(scope.body.parity_postTransaction.params[0]).to.deep.equal({
someExtras: 'foo',
to: ADDR,
data: ENCODED

View File

@ -39,11 +39,6 @@ export default class Eth {
.execute('eth_call', inOptions(options), inBlockNumber(blockNumber));
}
checkRequest (requestId) {
return this._transport
.execute('eth_checkRequest', inNumber16(requestId));
}
coinbase () {
return this._transport
.execute('eth_coinbase')
@ -267,11 +262,6 @@ export default class Eth {
.execute('eth_pendingTransactions');
}
postTransaction (options) {
return this._transport
.execute('eth_postTransaction', inOptions(options));
}
protocolVersion () {
return this._transport
.execute('eth_protocolVersion');

View File

@ -1,201 +0,0 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { inAddress, inData, inNumber16 } from '../../format/input';
import { outAddress, outHistogram, outNumber, outPeers } from '../../format/output';
export default class Ethcore {
constructor (transport) {
this._transport = transport;
}
acceptNonReservedPeers () {
return this._transport
.execute('ethcore_acceptNonReservedPeers');
}
addReservedPeer (encode) {
return this._transport
.execute('ethcore_addReservedPeer', encode);
}
dappsPort () {
return this._transport
.execute('ethcore_dappsPort')
.then(outNumber);
}
defaultExtraData () {
return this._transport
.execute('ethcore_defaultExtraData');
}
devLogs () {
return this._transport
.execute('ethcore_devLogs');
}
devLogsLevels () {
return this._transport
.execute('ethcore_devLogsLevels');
}
dropNonReservedPeers () {
return this._transport
.execute('ethcore_dropNonReservedPeers');
}
enode () {
return this._transport
.execute('ethcore_enode');
}
extraData () {
return this._transport
.execute('ethcore_extraData');
}
gasFloorTarget () {
return this._transport
.execute('ethcore_gasFloorTarget')
.then(outNumber);
}
gasPriceHistogram () {
return this._transport
.execute('ethcore_gasPriceHistogram')
.then(outHistogram);
}
generateSecretPhrase () {
return this._transport
.execute('ethcore_generateSecretPhrase');
}
hashContent (url) {
return this._transport
.execute('ethcore_hashContent', url);
}
minGasPrice () {
return this._transport
.execute('ethcore_minGasPrice')
.then(outNumber);
}
mode () {
return this._transport
.execute('ethcore_mode');
}
netChain () {
return this._transport
.execute('ethcore_netChain');
}
netPeers () {
return this._transport
.execute('ethcore_netPeers')
.then(outPeers);
}
netMaxPeers () {
return this._transport
.execute('ethcore_netMaxPeers')
.then(outNumber);
}
netPort () {
return this._transport
.execute('ethcore_netPort')
.then(outNumber);
}
nodeName () {
return this._transport
.execute('ethcore_nodeName');
}
phraseToAddress (phrase) {
return this._transport
.execute('ethcore_phraseToAddress', phrase)
.then(outAddress);
}
registryAddress () {
return this._transport
.execute('ethcore_registryAddress')
.then(outAddress);
}
removeReservedPeer (encode) {
return this._transport
.execute('ethcore_removeReservedPeer', encode);
}
rpcSettings () {
return this._transport
.execute('ethcore_rpcSettings');
}
setAuthor (address) {
return this._transport
.execute('ethcore_setAuthor', inAddress(address));
}
setExtraData (data) {
return this._transport
.execute('ethcore_setExtraData', inData(data));
}
setGasFloorTarget (quantity) {
return this._transport
.execute('ethcore_setGasFloorTarget', inNumber16(quantity));
}
setMinGasPrice (quantity) {
return this._transport
.execute('ethcore_setMinGasPrice', inNumber16(quantity));
}
setMode (mode) {
return this._transport
.execute('ethcore_setMode', mode);
}
setTransactionsLimit (quantity) {
return this._transport
.execute('ethcore_setTransactionsLimit', inNumber16(quantity));
}
signerPort () {
return this._transport
.execute('ethcore_signerPort')
.then(outNumber);
}
transactionsLimit () {
return this._transport
.execute('ethcore_transactionsLimit')
.then(outNumber);
}
unsignedTransactionsCount () {
return this._transport
.execute('ethcore_unsignedTransactionsCount')
.then(outNumber);
}
}

View File

@ -16,9 +16,10 @@
export Db from './db';
export Eth from './eth';
export Ethcore from './ethcore';
export Parity from './parity';
export Net from './net';
export Personal from './personal';
export Shh from './shh';
export Signer from './signer';
export Trace from './trace';
export Web3 from './web3';

View File

@ -14,4 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './ethcore';
export default from './parity';

View File

@ -16,12 +16,12 @@
import { createHttpApi } from '../../../../test/e2e/ethapi';
describe('ethapi.ethcore', () => {
describe('ethapi.parity', () => {
const ethapi = createHttpApi();
describe('gasFloorTarget', () => {
it('returns and translates the target', () => {
return ethapi.ethcore.gasFloorTarget().then((value) => {
return ethapi.parity.gasFloorTarget().then((value) => {
expect(value.gt(0)).to.be.true;
});
});
@ -29,7 +29,7 @@ describe('ethapi.ethcore', () => {
describe('gasPriceHistogram', () => {
it('returns and translates the target', () => {
return ethapi.ethcore.gasPriceHistogram().then((result) => {
return ethapi.parity.gasPriceHistogram().then((result) => {
expect(Object.keys(result)).to.deep.equal(['bucketBounds', 'counts']);
expect(result.bucketBounds.length > 0).to.be.true;
expect(result.counts.length > 0).to.be.true;
@ -39,7 +39,7 @@ describe('ethapi.ethcore', () => {
describe('netChain', () => {
it('returns and the chain', () => {
return ethapi.ethcore.netChain().then((value) => {
return ethapi.parity.netChain().then((value) => {
expect(value).to.equal('morden');
});
});
@ -47,7 +47,7 @@ describe('ethapi.ethcore', () => {
describe('netPort', () => {
it('returns and translates the port', () => {
return ethapi.ethcore.netPort().then((value) => {
return ethapi.parity.netPort().then((value) => {
expect(value.gt(0)).to.be.true;
});
});
@ -55,7 +55,7 @@ describe('ethapi.ethcore', () => {
describe('transactionsLimit', () => {
it('returns and translates the limit', () => {
return ethapi.ethcore.transactionsLimit().then((value) => {
return ethapi.parity.transactionsLimit().then((value) => {
expect(value.gt(0)).to.be.true;
});
});
@ -63,7 +63,7 @@ describe('ethapi.ethcore', () => {
describe('rpcSettings', () => {
it('returns and translates the settings', () => {
return ethapi.ethcore.rpcSettings().then((value) => {
return ethapi.parity.rpcSettings().then((value) => {
expect(value).to.be.ok;
});
});

View File

@ -0,0 +1,273 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { inAddress, inData, inHex, inNumber16, inOptions } from '../../format/input';
import { outAccountInfo, outAddress, outHistogram, outNumber, outPeers } from '../../format/output';
export default class Parity {
constructor (transport) {
this._transport = transport;
}
acceptNonReservedPeers () {
return this._transport
.execute('parity_acceptNonReservedPeers');
}
accounts () {
return this._transport
.execute('parity_accounts')
.then(outAccountInfo);
}
accountsInfo () {
return this._transport
.execute('parity_accountsInfo')
.then(outAccountInfo);
}
addReservedPeer (encode) {
return this._transport
.execute('parity_addReservedPeer', encode);
}
changePassword (account, password, newPassword) {
return this._transport
.execute('parity_changePassword', inAddress(account), password, newPassword);
}
checkRequest (requestId) {
return this._transport
.execute('parity_checkRequest', inNumber16(requestId));
}
dappsPort () {
return this._transport
.execute('parity_dappsPort')
.then(outNumber);
}
defaultExtraData () {
return this._transport
.execute('parity_defaultExtraData');
}
devLogs () {
return this._transport
.execute('parity_devLogs');
}
devLogsLevels () {
return this._transport
.execute('parity_devLogsLevels');
}
dropNonReservedPeers () {
return this._transport
.execute('parity_dropNonReservedPeers');
}
enode () {
return this._transport
.execute('parity_enode');
}
extraData () {
return this._transport
.execute('parity_extraData');
}
gasFloorTarget () {
return this._transport
.execute('parity_gasFloorTarget')
.then(outNumber);
}
gasPriceHistogram () {
return this._transport
.execute('parity_gasPriceHistogram')
.then(outHistogram);
}
generateSecretPhrase () {
return this._transport
.execute('parity_generateSecretPhrase');
}
hashContent (url) {
return this._transport
.execute('parity_hashContent', url);
}
listGethAccounts () {
return this._transport
.execute('parity_listGethAccounts')
.then((accounts) => (accounts || []).map(outAddress));
}
importGethAccounts (accounts) {
return this._transport
.execute('parity_importGethAccounts', (accounts || []).map(inAddress))
.then((accounts) => (accounts || []).map(outAddress));
}
minGasPrice () {
return this._transport
.execute('parity_minGasPrice')
.then(outNumber);
}
mode () {
return this._transport
.execute('parity_mode');
}
netChain () {
return this._transport
.execute('parity_netChain');
}
netPeers () {
return this._transport
.execute('parity_netPeers')
.then(outPeers);
}
netMaxPeers () {
return this._transport
.execute('parity_netMaxPeers')
.then(outNumber);
}
netPort () {
return this._transport
.execute('parity_netPort')
.then(outNumber);
}
newAccountFromPhrase (phrase, password) {
return this._transport
.execute('parity_newAccountFromPhrase', phrase, password)
.then(outAddress);
}
newAccountFromSecret (secret, password) {
return this._transport
.execute('parity_newAccountFromSecret', inHex(secret), password)
.then(outAddress);
}
newAccountFromWallet (json, password) {
return this._transport
.execute('parity_newAccountFromWallet', json, password)
.then(outAddress);
}
nodeName () {
return this._transport
.execute('parity_nodeName');
}
phraseToAddress (phrase) {
return this._transport
.execute('parity_phraseToAddress', phrase)
.then(outAddress);
}
postTransaction (options) {
return this._transport
.execute('parity_postTransaction', inOptions(options));
}
registryAddress () {
return this._transport
.execute('parity_registryAddress')
.then(outAddress);
}
removeReservedPeer (encode) {
return this._transport
.execute('parity_removeReservedPeer', encode);
}
rpcSettings () {
return this._transport
.execute('parity_rpcSettings');
}
setAccountName (address, name) {
return this._transport
.execute('parity_setAccountName', inAddress(address), name);
}
setAccountMeta (address, meta) {
return this._transport
.execute('parity_setAccountMeta', inAddress(address), JSON.stringify(meta));
}
setAuthor (address) {
return this._transport
.execute('parity_setAuthor', inAddress(address));
}
setExtraData (data) {
return this._transport
.execute('parity_setExtraData', inData(data));
}
setGasFloorTarget (quantity) {
return this._transport
.execute('parity_setGasFloorTarget', inNumber16(quantity));
}
setMinGasPrice (quantity) {
return this._transport
.execute('parity_setMinGasPrice', inNumber16(quantity));
}
setMode (mode) {
return this._transport
.execute('parity_setMode', mode);
}
setTransactionsLimit (quantity) {
return this._transport
.execute('parity_setTransactionsLimit', inNumber16(quantity));
}
signerPort () {
return this._transport
.execute('parity_signerPort')
.then(outNumber);
}
testPassword (account, password) {
return this._transport
.execute('parity_testPassword', inAddress(account), password);
}
transactionsLimit () {
return this._transport
.execute('parity_transactionsLimit')
.then(outNumber);
}
unsignedTransactionsCount () {
return this._transport
.execute('parity_unsignedTransactionsCount')
.then(outNumber);
}
}

View File

@ -18,14 +18,36 @@ import { TEST_HTTP_URL, mockHttp } from '../../../../test/mockRpc';
import { isBigNumber } from '../../../../test/types';
import Http from '../../transport/http';
import Ethcore from './ethcore';
import Parity from './parity';
const instance = new Ethcore(new Http(TEST_HTTP_URL));
const instance = new Parity(new Http(TEST_HTTP_URL));
describe('api/rpc/parity', () => {
describe('accountsInfo', () => {
it('retrieves the available account info', () => {
mockHttp([{ method: 'parity_accountsInfo', reply: {
result: {
'0x63cf90d3f0410092fc0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: '{"data":"data"}'
}
}
} }]);
return instance.accountsInfo().then((result) => {
expect(result).to.deep.equal({
'0x63Cf90D3f0410092FC0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: {
data: 'data'
}
}
});
});
});
});
describe('api/rpc/Ethcore', () => {
describe('gasFloorTarget', () => {
it('returns the gasfloor, formatted', () => {
mockHttp([{ method: 'ethcore_gasFloorTarget', reply: { result: '0x123456' } }]);
mockHttp([{ method: 'parity_gasFloorTarget', reply: { result: '0x123456' } }]);
return instance.gasFloorTarget().then((count) => {
expect(isBigNumber(count)).to.be.true;
@ -36,7 +58,7 @@ describe('api/rpc/Ethcore', () => {
describe('minGasPrice', () => {
it('returns the min gasprice, formatted', () => {
mockHttp([{ method: 'ethcore_minGasPrice', reply: { result: '0x123456' } }]);
mockHttp([{ method: 'parity_minGasPrice', reply: { result: '0x123456' } }]);
return instance.minGasPrice().then((count) => {
expect(isBigNumber(count)).to.be.true;
@ -47,7 +69,7 @@ describe('api/rpc/Ethcore', () => {
describe('netMaxPeers', () => {
it('returns the max peers, formatted', () => {
mockHttp([{ method: 'ethcore_netMaxPeers', reply: { result: 25 } }]);
mockHttp([{ method: 'parity_netMaxPeers', reply: { result: 25 } }]);
return instance.netMaxPeers().then((count) => {
expect(isBigNumber(count)).to.be.true;
@ -58,7 +80,7 @@ describe('api/rpc/Ethcore', () => {
describe('newPeers', () => {
it('returns the peer structure, formatted', () => {
mockHttp([{ method: 'ethcore_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]);
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]);
return instance.netPeers().then((peers) => {
expect(peers.active.eq(123)).to.be.true;
@ -70,7 +92,7 @@ describe('api/rpc/Ethcore', () => {
describe('netPort', () => {
it('returns the connected port, formatted', () => {
mockHttp([{ method: 'ethcore_netPort', reply: { result: 33030 } }]);
mockHttp([{ method: 'parity_netPort', reply: { result: 33030 } }]);
return instance.netPort().then((count) => {
expect(isBigNumber(count)).to.be.true;
@ -81,7 +103,7 @@ describe('api/rpc/Ethcore', () => {
describe('transactionsLimit', () => {
it('returns the tx limit, formatted', () => {
mockHttp([{ method: 'ethcore_transactionsLimit', reply: { result: 1024 } }]);
mockHttp([{ method: 'parity_transactionsLimit', reply: { result: 1024 } }]);
return instance.transactionsLimit().then((count) => {
expect(isBigNumber(count)).to.be.true;

View File

@ -14,113 +14,31 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { inAddress, inHex, inNumber10, inNumber16, inOptions } from '../../format/input';
import { outAccountInfo, outAddress, outSignerRequest } from '../../format/output';
import { inAddress, inNumber10, inOptions } from '../../format/input';
import { outAddress } from '../../format/output';
export default class Personal {
constructor (transport) {
this._transport = transport;
}
accountsInfo () {
return this._transport
.execute('personal_accountsInfo')
.then(outAccountInfo);
}
confirmRequest (requestId, options, password) {
return this._transport
.execute('personal_confirmRequest', inNumber16(requestId), options, password);
}
changePassword (account, password, newPassword) {
return this._transport
.execute('personal_changePassword', inAddress(account), password, newPassword);
}
generateAuthorizationToken () {
return this._transport
.execute('personal_generateAuthorizationToken');
}
listAccounts () {
return this._transport
.execute('personal_listAccounts')
.then((accounts) => (accounts || []).map(outAddress));
}
listGethAccounts () {
return this._transport
.execute('personal_listGethAccounts')
.then((accounts) => (accounts || []).map(outAddress));
}
importGethAccounts (accounts) {
return this._transport
.execute('personal_importGethAccounts', (accounts || []).map(inAddress))
.then((accounts) => (accounts || []).map(outAddress));
}
newAccount (password) {
return this._transport
.execute('personal_newAccount', password)
.then(outAddress);
}
newAccountFromPhrase (phrase, password) {
return this._transport
.execute('personal_newAccountFromPhrase', phrase, password)
.then(outAddress);
}
newAccountFromSecret (secret, password) {
return this._transport
.execute('personal_newAccountFromSecret', inHex(secret), password)
.then(outAddress);
}
newAccountFromWallet (json, password) {
return this._transport
.execute('personal_newAccountFromWallet', json, password)
.then(outAddress);
}
rejectRequest (requestId) {
return this._transport
.execute('personal_rejectRequest', inNumber16(requestId));
}
requestsToConfirm () {
return this._transport
.execute('personal_requestsToConfirm')
.then((requests) => (requests || []).map(outSignerRequest));
}
setAccountName (address, name) {
return this._transport
.execute('personal_setAccountName', inAddress(address), name);
}
setAccountMeta (address, meta) {
return this._transport
.execute('personal_setAccountMeta', inAddress(address), JSON.stringify(meta));
}
signAndSendTransaction (options, password) {
return this._transport
.execute('personal_signAndSendTransaction', inOptions(options), password);
}
signerEnabled () {
return this._transport
.execute('personal_signerEnabled');
}
testPassword (account, password) {
return this._transport
.execute('personal_testPassword', inAddress(account), password);
}
unlockAccount (account, password, duration = 1) {
return this._transport
.execute('personal_unlockAccount', inAddress(account), password, inNumber10(duration));

View File

@ -26,28 +26,6 @@ describe('rpc/Personal', () => {
const checksum = '0x63Cf90D3f0410092FC0fca41846f596223979195';
let scope;
describe('accountsInfo', () => {
it('retrieves the available account info', () => {
scope = mockHttp([{ method: 'personal_accountsInfo', reply: {
result: {
'0x63cf90d3f0410092fc0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: '{"data":"data"}'
}
}
} }]);
return instance.accountsInfo().then((result) => {
expect(result).to.deep.equal({
'0x63Cf90D3f0410092FC0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: {
data: 'data'
}
}
});
});
});
});
describe('listAccounts', () => {
it('retrieves a list of available accounts', () => {
scope = mockHttp([{ method: 'personal_listAccounts', reply: { result: [account] } }]);

View File

@ -12,24 +12,6 @@
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
const defaultHidden = [];
export function readHiddenApps () {
const stored = localStorage.getItem('hiddenApps');
if (stored) {
try {
return JSON.parse(stored);
} catch (error) {
console.warn('readHiddenApps', error);
}
}
return defaultHidden;
}
export function writeHiddenApps (hidden) {
localStorage.setItem('hiddenApps', JSON.stringify(hidden));
}
export default from './signer';

View File

@ -0,0 +1,50 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { inNumber16 } from '../../format/input';
import { outSignerRequest } from '../../format/output';
export default class Signer {
constructor (transport) {
this._transport = transport;
}
confirmRequest (requestId, options, password) {
return this._transport
.execute('signer_confirmRequest', inNumber16(requestId), options, password);
}
generateAuthorizationToken () {
return this._transport
.execute('signer_generateAuthorizationToken');
}
rejectRequest (requestId) {
return this._transport
.execute('signer_rejectRequest', inNumber16(requestId));
}
requestsToConfirm () {
return this._transport
.execute('signer_requestsToConfirm')
.then((requests) => (requests || []).map(outSignerRequest));
}
signerEnabled () {
return this._transport
.execute('signer_signerEnabled');
}
}

View File

@ -24,9 +24,9 @@ import Signer from './signer';
const events = {
'logging': { module: 'logging' },
'eth_blockNumber': { module: 'eth' },
'personal_accountsInfo': { module: 'personal' },
'personal_listAccounts': { module: 'personal' },
'personal_requestsToConfirm': { module: 'signer' }
'parity_accountsInfo': { module: 'personal' },
'eth_accounts': { module: 'personal' },
'signer_requestsToConfirm': { module: 'signer' }
};
export default class Manager {

View File

@ -37,18 +37,18 @@ export default class Personal {
}
_listAccounts = () => {
return this._api.personal
.listAccounts()
return this._api.eth
.accounts()
.then((accounts) => {
this._updateSubscriptions('personal_listAccounts', null, accounts);
this._updateSubscriptions('eth_accounts', null, accounts);
});
}
_accountsInfo = () => {
return this._api.personal
return this._api.parity
.accountsInfo()
.then((info) => {
this._updateSubscriptions('personal_accountsInfo', null, info);
this._updateSubscriptions('parity_accountsInfo', null, info);
});
}
@ -59,16 +59,16 @@ export default class Personal {
}
switch (data.method) {
case 'personal_importGethAccounts':
case 'parity_importGethAccounts':
case 'personal_newAccount':
case 'personal_newAccountFromPhrase':
case 'personal_newAccountFromWallet':
case 'parity_newAccountFromPhrase':
case 'parity_newAccountFromWallet':
this._listAccounts();
this._accountsInfo();
return;
case 'personal_setAccountName':
case 'personal_setAccountMeta':
case 'parity_setAccountName':
case 'parity_setAccountMeta':
this._accountsInfo();
return;
}

View File

@ -34,14 +34,15 @@ function stubApi (accounts, info) {
return {
_calls,
personal: {
parity: {
accountsInfo: () => {
const stub = sinon.stub().resolves(info || TEST_INFO)();
_calls.accountsInfo.push(stub);
return stub;
},
listAccounts: () => {
}
},
eth: {
accounts: () => {
const stub = sinon.stub().resolves(accounts || TEST_LIST)();
_calls.listAccounts.push(stub);
return stub;
@ -85,17 +86,17 @@ describe('api/subscriptions/personal', () => {
expect(personal.isStarted).to.be.true;
});
it('calls personal_accountsInfo', () => {
it('calls parity_accountsInfo', () => {
expect(api._calls.accountsInfo.length).to.be.ok;
});
it('calls personal_listAccounts', () => {
it('calls eth_accounts', () => {
expect(api._calls.listAccounts.length).to.be.ok;
});
it('updates subscribers', () => {
expect(cb.firstCall).to.have.been.calledWith('personal_listAccounts', null, TEST_LIST);
expect(cb.secondCall).to.have.been.calledWith('personal_accountsInfo', null, TEST_INFO);
expect(cb.firstCall).to.have.been.calledWith('eth_accounts', null, TEST_LIST);
expect(cb.secondCall).to.have.been.calledWith('parity_accountsInfo', null, TEST_INFO);
});
});

View File

@ -49,10 +49,10 @@ export default class Signer {
return;
}
return this._api.personal
return this._api.signer
.requestsToConfirm()
.then((requests) => {
this._updateSubscriptions('personal_requestsToConfirm', null, requests);
this._updateSubscriptions('signer_requestsToConfirm', null, requests);
nextTimeout();
})
.catch(nextTimeout);
@ -65,7 +65,7 @@ export default class Signer {
}
switch (data.method) {
case 'eth_postTransaction':
case 'parity_postTransaction':
case 'eth_sendTranasction':
case 'eth_sendRawTransaction':
this._listRequests(false);

View File

@ -56,6 +56,8 @@ export default class Http extends JsonRpcBase {
if (response.status !== 200) {
this._connected = false;
this.error(JSON.stringify({ status: response.status, statusText: response.statusText }));
console.error(`${method}(${JSON.stringify(params)}): ${response.status}: ${response.statusText}`);
throw new Error(`${response.status}: ${response.statusText}`);
}
@ -66,7 +68,9 @@ export default class Http extends JsonRpcBase {
if (response.error) {
this.error(JSON.stringify(response));
throw new Error(`${response.error.code}: ${response.error.message}`);
console.error(`${method}(${JSON.stringify(params)}): ${response.error.code}: ${response.error.message}`);
throw new Error(`${method}: ${response.error.code}: ${response.error.message}`);
}
this.log(JSON.stringify(response));

View File

@ -107,7 +107,9 @@ export default class Ws extends JsonRpcBase {
if (result.error) {
this.error(event.data);
reject(new Error(`${result.error.code}: ${result.error.message}`));
console.error(`${method}(${JSON.stringify(params)}): ${result.error.code}: ${result.error.message}`);
reject(new Error(`${method}: ${result.error.code}: ${result.error.message}`));
delete this._messages[result.id];
return;
}

View File

@ -57,4 +57,8 @@ export default class DappReg {
getContent (id) {
return this.meta(id, 'CONTENT');
}
getManifest (id) {
return this.meta(id, 'MANIFEST');
}
}

View File

@ -32,7 +32,7 @@ export default class Registry {
return;
}
this._api.ethcore
this._api.parity
.registryAddress()
.then((address) => {
this._instance = this._api.newContract(abis.registry, address).instance;

View File

@ -83,7 +83,7 @@ export default class Application extends Component {
Promise
.all([
attachInstances(),
api.personal.accountsInfo()
api.parity.accounts()
])
.then(([{ managerInstance, registryInstance, tokenregInstance }, accountsInfo]) => {
accountsInfo = accountsInfo || {};

View File

@ -296,7 +296,7 @@ export default class Deployment extends Component {
.then((signerRequestId) => {
this.setState({ signerRequestId, deployState: 'Transaction posted, Waiting for transaction authorization' });
return api.pollMethod('eth_checkRequest', signerRequestId);
return api.pollMethod('parity_checkRequest', signerRequestId);
})
.then((txHash) => {
this.setState({ txHash, deployState: 'Transaction authorized, Waiting for network confirmations' });

View File

@ -279,7 +279,7 @@ export default class Send extends Component {
.then((signerRequestId) => {
this.setState({ signerRequestId, sendState: 'Transaction posted, Waiting for transaction authorization' });
return api.pollMethod('eth_checkRequest', signerRequestId);
return api.pollMethod('parity_checkRequest', signerRequestId);
})
.then((txHash) => {
this.setState({ txHash, sendState: 'Transaction authorized, Waiting for network confirmations' });

View File

@ -100,8 +100,8 @@ export function attachInstances () {
return Promise
.all([
api.ethcore.registryAddress(),
api.ethcore.netChain()
api.parity.registryAddress(),
api.parity.netChain()
])
.then(([registryAddress, netChain]) => {
const registry = api.newContract(abis.registry, registryAddress).instance;

View File

@ -11,7 +11,6 @@
<div id="container"></div>
<script src="vendor.js"></script>
<script src="commons.js"></script>
<script src="/parity-utils/parity.js"></script>
<script src="githubhint.js"></script>
</body>
</html>

View File

@ -41,7 +41,9 @@ export default class Application extends Component {
registerBusy: false,
registerError: null,
registerState: '',
registerType: 'file'
registerType: 'file',
repo: '',
repoError: null
}
componentDidMount () {
@ -206,47 +208,64 @@ export default class Application extends Component {
}
onChangeCommit = (event) => {
const commit = event.target.value;
let commit = event.target.value;
const commitError = null;
let hasContent = false;
// TODO: field validation
this.setState({ commit, commitError, contentHashError: null }, () => {
const { repo } = this.state || '';
const parts = repo.split('/');
this.setState({ commit, commitError, contentHashError: 'hash lookup in progress' }, () => {
const { repo } = this.state;
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
hasContent = commit.length !== 0 && parts.length === 2 && parts[0].length !== 0 && parts[1].length !== 0;
if (!commitError && hasContent) {
this.setState({ contentHashError: 'hash lookup in progress' });
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
}
});
}
onChangeRepo = (event) => {
let repo = event.target.value;
const repoError = null;
let hasContent = false;
// TODO: field validation
if (!repoError) {
repo = repo.replace('https://github.com/', '');
}
this.setState({ repo, repoError, contentHashError: 'hash lookup in progress' }, () => {
const { commit } = this.state;
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
this.setState({ repo, repoError, contentHashError: null }, () => {
const { commit } = this.state || '';
const parts = repo.split('/');
hasContent = commit.length !== 0 && parts.length === 2 && parts[0].length !== 0 && parts[1].length !== 0;
if (!repoError && hasContent) {
this.setState({ contentHashError: 'hash lookup in progress' });
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
}
});
}
onChangeUrl = (event) => {
let url = event.target.value;
const urlError = null;
let hasContent = false;
// TODO: field validation
if (!urlError) {
const parts = url.split('/');
hasContent = parts.length !== 0;
if (parts[2] === 'github.com' || parts[2] === 'raw.githubusercontent.com') {
url = `https://raw.githubusercontent.com/${parts.slice(3).join('/')}`.replace('/blob/', '/');
}
}
this.setState({ url, urlError, contentHashError: 'hash lookup in progress' }, () => {
this.lookupHash(url);
this.setState({ url, urlError, contentHashError: null }, () => {
if (!urlError && hasContent) {
this.setState({ contentHashError: 'hash lookup in progress' });
this.lookupHash(url);
}
});
}
@ -271,7 +290,7 @@ export default class Application extends Component {
.then((signerRequestId) => {
this.setState({ signerRequestId, registerState: 'Transaction posted, Waiting for transaction authorization' });
return api.pollMethod('eth_checkRequest', signerRequestId);
return api.pollMethod('parity_checkRequest', signerRequestId);
})
.then((txHash) => {
this.setState({ txHash, registerState: 'Transaction authorized, Waiting for network confirmations' });
@ -285,7 +304,7 @@ export default class Application extends Component {
});
})
.then((txReceipt) => {
this.setState({ txReceipt, registerBusy: false, registerState: 'Network confirmed, Received transaction receipt', url: '', commit: '', commitError: null, contentHash: '', contentHashOwner: null, contentHashError: null });
this.setState({ txReceipt, registerBusy: false, registerState: 'Network confirmed, Received transaction receipt', url: '', commit: '', repo: '', commitError: null, contentHash: '', contentHashOwner: null, contentHashError: null });
})
.catch((error) => {
console.error('onSend', error);
@ -298,7 +317,7 @@ export default class Application extends Component {
this.setState({ registerBusy: true, registerState: 'Estimating gas for the transaction' });
const values = [contentHash, repo, commit];
const values = [contentHash, repo, commit.substr(0, 2) === '0x' ? commit : `0x${commit}`];
const options = { from: fromAddress };
this.trackRequest(
@ -367,7 +386,7 @@ export default class Application extends Component {
console.log(`lookupHash ${url}`);
api.ethcore
api.parity
.hashContent(url)
.then((contentHash) => {
console.log('lookupHash', contentHash);

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
const { api } = window.parity;
const api = window.parent.secureApi;
export {
api

View File

@ -18,7 +18,7 @@ import * as abis from '../../contracts/abi';
import { api } from './parity';
export function attachInterface () {
return api.ethcore
return api.parity
.registryAddress()
.then((registryAddress) => {
console.log(`the registry was found at ${registryAddress}`);
@ -29,7 +29,7 @@ export function attachInterface () {
.all([
registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']),
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
]);
})
.then(([address, addresses, accountsInfo]) => {

View File

@ -29,7 +29,7 @@ export { addresses, accounts, lookup, events, names, records };
export const setContract = (contract) => ({ type: 'set contract', contract });
export const fetchContract = () => (dispatch) =>
api.ethcore.registryAddress()
api.parity.registryAddress()
.then((address) => {
const contract = api.newContract(registryAbi, address);
dispatch(setContract(contract));

View File

@ -22,7 +22,7 @@ export const fetch = () => (dispatch) => {
return Promise
.all([
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
])
.then(([ accounts, data ]) => {
data = data || {};

View File

@ -39,7 +39,7 @@ const logToEvent = (log) => {
};
export function attachInterface (callback) {
return api.ethcore
return api.parity
.registryAddress()
.then((registryAddress) => {
console.log(`the registry was found at ${registryAddress}`);
@ -50,7 +50,7 @@ export function attachInterface (callback) {
.all([
registry.getAddress.call({}, [api.util.sha3('signaturereg'), 'A']),
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
]);
})
.then(([address, addresses, accountsInfo]) => {

View File

@ -38,7 +38,7 @@ export const loadAccounts = () => (dispatch) => {
Promise
.all([
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
])
.then(([ accounts, accountsInfo ]) => {
accountsInfo = accountsInfo || {};

View File

@ -34,7 +34,7 @@ export const FIND_CONTRACT = 'FIND_CONTRACT';
export const loadContract = () => (dispatch) => {
dispatch(setLoading(true));
api.ethcore
api.parity
.registryAddress()
.then((registryAddress) => {
console.log(`registry found at ${registryAddress}`);

View File

@ -6,8 +6,31 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="icon" href="/parity-logo-black-no-text.png" type="image/png">
<title>dev::Parity.js</title>
<script src="/parity-utils/parity.js"></script>
<style>
.box {
font-size: 1.5em;
text-align: center;
border-radius: 0.5em;
background: #eee;
padding: 1em;
margin: 1em;
}
</style>
</head>
<body>
<script src="/parity-utils/parity.js"></script>
<div class="box">
best block #<span id="blockNumber">unknown</span>
</div>
<script>
window.parity.api.subscribe('eth_blockNumber', function (error, blockNumber) {
if (error) {
console.log('error', error);
return;
}
document.getElementById('blockNumber').innerHTML = blockNumber.toFormat(0);
});
</script>
</body>
</html>

View File

@ -6,8 +6,33 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="icon" href="/parity-logo-black-no-text.png" type="image/png">
<title>dev::Web3</title>
<script src="/parity-utils/web3.js"></script>
<style>
.box {
font-size: 1.5em;
text-align: center;
border-radius: 0.5em;
background: #eee;
padding: 1em;
margin: 1em;
}
</style>
</head>
<body>
<script src="/parity-utils/web3.js"></script>
<div class="box">
best block #<span id="blockNumber">unknown</span>
</div>
<script>
window.setInterval(function () {
window.web3.eth.getBlockNumber(function (error, blockNumber) {
if (error) {
console.error('error', error);
return;
}
document.getElementById('blockNumber').innerHTML = blockNumber;
});
}, 1000);
</script>
</body>
</html>

View File

@ -31,7 +31,7 @@ import ContractInstances from './contracts';
import { initStore } from './redux';
import { ContextProvider, muiTheme } from './ui';
import { Accounts, Account, Addresses, Address, Application, Contract, Contracts, Dapp, Dapps, Settings, SettingsBackground, SettingsProxy, SettingsViews, Signer, Status } from './views';
import { Accounts, Account, Addresses, Address, Application, Contract, Contracts, Dapp, Dapps, Settings, SettingsBackground, SettingsParity, SettingsProxy, SettingsViews, Signer, Status } from './views';
import { setApi } from './redux/providers/apiActions';
@ -59,6 +59,8 @@ const store = initStore(api);
store.dispatch({ type: 'initAll', api });
store.dispatch(setApi(api));
window.secureApi = api;
const routerHistory = useRouterHistory(createHashHistory)({});
ReactDOM.render(
@ -72,13 +74,14 @@ ReactDOM.render(
<Route path='addresses' component={ Addresses } />
<Route path='address/:address' component={ Address } />
<Route path='apps' component={ Dapps } />
<Route path='app/:type/:name' component={ Dapp } />
<Route path='app/:id' component={ Dapp } />
<Route path='contracts' component={ Contracts } />
<Route path='contract/:address' component={ Contract } />
<Route path='settings' component={ Settings }>
<Route path='background' component={ SettingsBackground } />
<Route path='proxy' component={ SettingsProxy } />
<Route path='views' component={ SettingsViews } />
<Route path='parity' component={ SettingsParity } />
</Route>
<Route path='signer' component={ Signer } />
<Route path='status' component={ Status } />

View File

@ -16,20 +16,22 @@
import db from './interfaces/db';
import eth from './interfaces/eth';
import ethcore from './interfaces/ethcore';
import net from './interfaces/net';
import parity from './interfaces/parity';
import personal from './interfaces/personal';
import shh from './interfaces/shh';
import signer from './interfaces/signer';
import trace from './interfaces/trace';
import web3 from './interfaces/web3';
export default {
db: db,
eth: eth,
ethcore: ethcore,
net: net,
personal: personal,
shh: shh,
trace: trace,
web3: web3
db,
eth,
parity,
net,
personal,
shh,
signer,
trace,
web3
};

View File

@ -86,20 +86,6 @@ export default {
}
},
checkRequest: {
desc: 'Returns the transactionhash of the requestId (received from eth_postTransaction) if the request was confirmed',
params: [
{
type: Quantity,
desc: 'The requestId to check for'
}
],
returns: {
type: Hash,
desc: '32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available'
}
},
coinbase: {
desc: 'Returns the client coinbase address.',
params: [],
@ -823,22 +809,6 @@ export default {
}
},
postTransaction: {
desc: 'Posts a transaction to the Signer.',
params: [
{
type: Object,
desc: 'see [eth_sendTransaction](#eth_sendTransaction)',
format: 'inputCallFormatter'
}
],
returns: {
type: Quantity,
desc: 'The id of the actual transaction',
format: 'utils.toDecimal'
}
},
protocolVersion: {
desc: 'Returns the current ethereum protocol version.',
params: [],

View File

@ -26,6 +26,52 @@ export default {
}
},
accounts: {
desc: 'returns a map of accounts as an object',
params: [],
returns: {
type: Array,
desc: 'Account metadata',
details: {
name: {
type: String,
desc: 'Account name'
},
meta: {
type: String,
desc: 'Encoded JSON string the defines additional account metadata'
},
uuid: {
type: String,
desc: 'The account UUID, or null if not available/unknown/not applicable.'
}
}
}
},
accountsInfo: {
desc: 'returns a map of accounts as an object',
params: [],
returns: {
type: Array,
desc: 'Account metadata',
details: {
name: {
type: String,
desc: 'Account name'
},
meta: {
type: String,
desc: 'Encoded JSON string the defines additional account metadata'
},
uuid: {
type: String,
desc: 'The account UUID, or null if not available/unknown/not applicable.'
}
}
}
},
addReservedPeer: {
desc: '?',
params: [
@ -40,6 +86,20 @@ export default {
}
},
checkRequest: {
desc: 'Returns the transactionhash of the requestId (received from parity_postTransaction) if the request was confirmed',
params: [
{
type: Quantity,
desc: 'The requestId to check for'
}
],
returns: {
type: Hash,
desc: '32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available'
}
},
dappsPort: {
desc: 'Returns the port the dapps are running on, error if not enabled',
params: [],
@ -155,6 +215,29 @@ export default {
}
},
listGethAccounts: {
desc: 'Returns a list of the accounts available from Geth',
params: [],
returns: {
type: Array,
desc: '20 Bytes addresses owned by the client.'
}
},
importGethAccounts: {
desc: 'Imports a list of accounts from geth',
params: [
{
type: Array,
desc: 'List of the geth addresses to import'
}
],
returns: {
type: Array,
desc: 'Array of the imported addresses'
}
},
minGasPrice: {
desc: 'Returns currently set minimal gas price',
params: [],
@ -166,7 +249,7 @@ export default {
},
mode: {
desc: 'Get the mode. Results one of: "active", "passive", "dark", "off".',
desc: 'Get the mode. Results one of: "active", "passive", "dark", "offline".',
params: [],
returns: {
type: String,
@ -210,6 +293,60 @@ export default {
}
},
newAccountFromPhrase: {
desc: 'Creates a new account from a recovery passphrase',
params: [
{
type: String,
desc: 'Phrase'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromSecret: {
desc: 'Creates a new account from a private ethstore secret key',
params: [
{
type: Data,
desc: 'Secret, 32-byte hex'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromWallet: {
desc: 'Creates a new account from a JSON import',
params: [
{
type: String,
desc: 'JSON'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
nodeName: {
desc: 'Returns node name (identity)',
params: [],
@ -233,6 +370,22 @@ export default {
}
},
postTransaction: {
desc: 'Posts a transaction to the Signer.',
params: [
{
type: Object,
desc: 'see [eth_sendTransaction](#eth_sendTransaction)',
format: 'inputCallFormatter'
}
],
returns: {
type: Quantity,
desc: 'The id of the actual transaction',
format: 'utils.toDecimal'
}
},
removeReservedPeer: {
desc: '?',
params: [
@ -265,6 +418,42 @@ export default {
}
},
setAccountName: {
desc: 'Sets a name for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Name'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
setAccountMeta: {
desc: 'Sets metadata for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Metadata (JSON encoded)'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
setAuthor: {
desc: 'Changes author (coinbase) for mined blocks.',
params: [
@ -330,7 +519,7 @@ export default {
params: [
{
type: String,
desc: 'The mode to set, one of "active", "passive", "dark", "off"'
desc: 'The mode to set, one of "active", "passive", "dark", "offline"'
}
],
returns: {

View File

@ -17,83 +17,6 @@
import { Address, Data, Quantity } from '../types';
export default {
accountsInfo: {
desc: 'returns a map of accounts as an object',
params: [],
returns: {
type: Array,
desc: 'Account metadata',
details: {
name: {
type: String,
desc: 'Account name'
},
meta: {
type: String,
desc: 'Encoded JSON string the defines additional account metadata'
},
uuid: {
type: String,
desc: 'The account UUID, or null if not available/unknown/not applicable.'
}
}
}
},
generateAuthorizationToken: {
desc: 'Generates a new authorization token',
params: [],
returns: {
type: String,
desc: 'The new authorization token'
}
},
requestsToConfirm: {
desc: 'Returns a list of the transactions requiring authorization',
params: [],
returns: {
type: Array,
desc: 'A list of the outstanding transactions'
}
},
confirmRequest: {
desc: 'Confirm a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
},
{
type: Object,
desc: 'The request options'
},
{
type: String,
desc: 'The account password'
}
],
returns: {
type: Boolean,
desc: 'The status of the confirmation'
}
},
rejectRequest: {
desc: 'Rejects a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
}
],
returns: {
type: Boolean,
desc: 'The status of the rejection'
}
},
listAccounts: {
desc: 'Returns a list of addresses owned by client.',
params: [],
@ -103,29 +26,6 @@ export default {
}
},
listGethAccounts: {
desc: 'Returns a list of the accounts available from Geth',
params: [],
returns: {
type: Array,
desc: '20 Bytes addresses owned by the client.'
}
},
importGethAccounts: {
desc: 'Imports a list of accounts from geth',
params: [
{
type: Array,
desc: 'List of the geth addresses to import'
}
],
returns: {
type: Array,
desc: 'Array of the imported addresses'
}
},
newAccount: {
desc: 'Creates new account',
params: [
@ -140,96 +40,6 @@ export default {
}
},
newAccountFromPhrase: {
desc: 'Creates a new account from a recovery passphrase',
params: [
{
type: String,
desc: 'Phrase'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromSecret: {
desc: 'Creates a new account from a private ethstore secret key',
params: [
{
type: Data,
desc: 'Secret, 32-byte hex'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromWallet: {
desc: 'Creates a new account from a JSON import',
params: [
{
type: String,
desc: 'JSON'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
setAccountName: {
desc: 'Sets a name for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Name'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
setAccountMeta: {
desc: 'Sets metadata for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Metadata (JSON encoded)'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
signAndSendTransaction: {
desc: 'Sends and signs a transaction given account passphrase. Does not require the account to be unlocked nor unlocks the account for future transactions. ',
params: [
@ -284,15 +94,6 @@ export default {
}
},
signerEnabled: {
desc: 'Returns whether signer is enabled/disabled.',
params: [],
returns: {
type: Boolean,
desc: 'true when enabled, false when disabled'
}
},
unlockAccount: {
desc: '?',
params: [

View File

@ -0,0 +1,82 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { Quantity } from '../types';
export default {
generateAuthorizationToken: {
desc: 'Generates a new authorization token',
params: [],
returns: {
type: String,
desc: 'The new authorization token'
}
},
requestsToConfirm: {
desc: 'Returns a list of the transactions requiring authorization',
params: [],
returns: {
type: Array,
desc: 'A list of the outstanding transactions'
}
},
confirmRequest: {
desc: 'Confirm a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
},
{
type: Object,
desc: 'The request options'
},
{
type: String,
desc: 'The account password'
}
],
returns: {
type: Boolean,
desc: 'The status of the confirmation'
}
},
rejectRequest: {
desc: 'Rejects a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
}
],
returns: {
type: Boolean,
desc: 'The status of the rejection'
}
},
signerEnabled: {
desc: 'Returns whether signer is enabled/disabled.',
params: [],
returns: {
type: Boolean,
desc: 'true when enabled, false when disabled'
}
}
};

View File

@ -133,8 +133,8 @@ export default class AddAddress extends Component {
const { address, name, description } = this.state;
Promise.all([
api.personal.setAccountName(address, name),
api.personal.setAccountMeta(address, {
api.parity.setAccountName(address, name),
api.parity.setAccountMeta(address, {
description,
timestamp: Date.now(),
deleted: false

View File

@ -141,8 +141,8 @@ export default class AddContract extends Component {
const { abiParsed, address, name, description } = this.state;
Promise.all([
api.personal.setAccountName(address, name),
api.personal.setAccountMeta(address, {
api.parity.setAccountName(address, name),
api.parity.setAccountMeta(address, {
contract: true,
deleted: false,
timestamp: Date.now(),

View File

@ -27,7 +27,7 @@ const ERRORS = {
noName: 'you need to specify a valid name for the account',
noPhrase: 'you need to specify the recovery phrase',
noKey: 'you need to provide the raw private key',
invalidKey: 'the raw key needs to be hex, 64 characters in length',
invalidKey: 'the raw key needs to be hex, 64 characters in length and contain the prefix "0x"',
invalidPassword: 'you need to specify a password >= 8 characters',
noMatchPassword: 'the supplied passwords does not match'
};
@ -173,15 +173,15 @@ export default class CreateAccount extends Component {
Promise
.all([
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase()
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase()
])
.then((phrases) => {
return Promise
.all(phrases.map((phrase) => api.ethcore.phraseToAddress(phrase)))
.all(phrases.map((phrase) => api.parity.phraseToAddress(phrase)))
.then((addresses) => {
const accounts = {};

View File

@ -102,7 +102,7 @@ export default class NewGeth extends Component {
const { api } = this.context;
const { accounts } = this.props;
api.personal
api.parity
.listGethAccounts()
.then((_addresses) => {
const addresses = (addresses || []).filter((address) => !accounts[address]);

View File

@ -208,13 +208,13 @@ export default class CreateAccount extends Component {
});
if (createType === 'fromNew' || createType === 'fromPhrase') {
return api.personal
return api.parity
.newAccountFromPhrase(this.state.phrase, this.state.password)
.then((address) => {
this.setState({ address });
return api.personal
return api.parity
.setAccountName(address, this.state.name)
.then(() => api.personal.setAccountMeta(address, {
.then(() => api.parity.setAccountMeta(address, {
timestamp: Date.now(),
passwordHint: this.state.passwordHint
}));
@ -233,13 +233,13 @@ export default class CreateAccount extends Component {
this.newError(error);
});
} else if (createType === 'fromRaw') {
return api.personal
return api.parity
.newAccountFromSecret(this.state.rawKey, this.state.password)
.then((address) => {
this.setState({ address });
return api.personal
return api.parity
.setAccountName(address, this.state.name)
.then(() => api.personal.setAccountMeta(address, {
.then(() => api.parity.setAccountMeta(address, {
timestamp: Date.now(),
passwordHint: this.state.passwordHint
}));
@ -258,13 +258,13 @@ export default class CreateAccount extends Component {
this.newError(error);
});
} else if (createType === 'fromGeth') {
return api.personal
return api.parity
.importGethAccounts(this.state.gethAddresses)
.then((result) => {
console.log('result', result);
return Promise.all(this.state.gethAddresses.map((address) => {
return api.personal.setAccountName(address, 'Geth Import');
return api.parity.setAccountName(address, 'Geth Import');
}));
})
.then(() => {
@ -282,16 +282,16 @@ export default class CreateAccount extends Component {
});
}
return api.personal
return api.parity
.newAccountFromWallet(this.state.json, this.state.password)
.then((address) => {
this.setState({
address: address
});
return api.personal
return api.parity
.setAccountName(address, this.state.name)
.then(() => api.personal.setAccountMeta(address, {
.then(() => api.parity.setAccountMeta(address, {
timestamp: Date.now(),
passwordHint: this.state.passwordHint
}));

View File

@ -18,7 +18,7 @@ import React, { Component, PropTypes } from 'react';
import ActionDoneAll from 'material-ui/svg-icons/action/done-all';
import ContentClear from 'material-ui/svg-icons/content/clear';
import { BusyStep, CompletedStep, Button, IdentityIcon, Modal, TxHash } from '../../ui';
import { BusyStep, CompletedStep, CopyToClipboard, Button, IdentityIcon, Modal, TxHash } from '../../ui';
import { ERRORS, validateAbi, validateCode, validateName } from '../../util/validation';
import DetailsStep from './DetailsStep';
@ -155,6 +155,7 @@ export default class DeployContract extends Component {
<CompletedStep>
<div>Your contract has been deployed at</div>
<div>
<CopyToClipboard data={ address } label='copy address to clipboard' />
<IdentityIcon address={ address } inline center className={ styles.identityicon } />
<div className={ styles.address }>{ address }</div>
</div>
@ -212,8 +213,8 @@ export default class DeployContract extends Component {
.deploy(options, params, this.onDeploymentState)
.then((address) => {
return Promise.all([
api.personal.setAccountName(address, name),
api.personal.setAccountMeta(address, {
api.parity.setAccountName(address, name),
api.parity.setAccountMeta(address, {
abi: abiParsed,
contract: true,
timestamp: Date.now(),

View File

@ -99,11 +99,10 @@ export default class EditMeta extends Component {
renderTags () {
const { meta } = this.state;
const { tags } = meta || [];
return (
<InputChip
tokens={ tags }
tokens={ meta.tags || [] }
onTokensChange={ this.onTagsChange }
label='(optional) tags'
hint='press <Enter> to add a tag'
@ -139,8 +138,8 @@ export default class EditMeta extends Component {
Promise
.all([
api.personal.setAccountName(account.address, name),
api.personal.setAccountMeta(account.address, Object.assign({}, account.meta, meta))
api.parity.setAccountName(account.address, name),
api.parity.setAccountMeta(account.address, Object.assign({}, account.meta, meta))
])
.then(() => this.props.onClose())
.catch((error) => {

View File

@ -221,7 +221,7 @@ export default class ExecuteContract extends Component {
})
.then((requestId) => {
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
return api.pollMethod('eth_checkRequest', requestId);
return api.pollMethod('parity_checkRequest', requestId);
})
.then((txhash) => {
this.setState({ sending: false, step: 2, txhash, busyState: 'Your transaction has been posted to the network' });

View File

@ -183,9 +183,9 @@ export default class FirstRun extends Component {
canCreate: false
});
return api.personal
return api.parity
.newAccountFromPhrase(phrase, password)
.then((address) => api.personal.setAccountName(address, name))
.then((address) => api.parity.setAccountName(address, name))
.then(() => {
this.onNext();
})

View File

@ -317,7 +317,7 @@ export default class PasswordManager extends Component {
this.setState({ waiting: true, showMessage: false });
this.context
.api.personal
.api.parity
.testPassword(account.address, currentPass)
.then(correct => {
const message = correct
@ -343,7 +343,7 @@ export default class PasswordManager extends Component {
this.setState({ waiting: true, showMessage: false });
this.context
.api.personal
.api.parity
.testPassword(account.address, currentPass)
.then(correct => {
if (!correct) {
@ -363,11 +363,11 @@ export default class PasswordManager extends Component {
return Promise.all([
this.context
.api.personal
.api.parity
.setAccountMeta(account.address, meta),
this.context
.api.personal
.api.parity
.changePassword(account.address, currentPass, newPass)
])
.then(() => {

View File

@ -123,7 +123,13 @@ export default class Details extends Component {
.map((balance, index) => {
const token = balance.token;
const isEth = index === 0;
const imagesrc = token.image || images[token.address] || imageUnknown;
let imagesrc = token.image;
if (!imagesrc) {
imagesrc =
images[token.address]
? `${api.dappsUrl}${images[token.address]}`
: imageUnknown;
}
let value = 0;
if (isEth) {

View File

@ -424,7 +424,7 @@ export default class Transfer extends Component {
options.data = data;
}
return api.eth.postTransaction(options);
return api.parity.postTransaction(options);
}
_sendToken () {
@ -455,7 +455,7 @@ export default class Transfer extends Component {
: this._sendToken()
).then((requestId) => {
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
return api.pollMethod('eth_checkRequest', requestId);
return api.pollMethod('parity_checkRequest', requestId);
})
.then((txhash) => {
this.onNext();
@ -592,7 +592,7 @@ export default class Transfer extends Component {
Promise
.all([
api.ethcore.gasPriceHistogram(),
api.parity.gasPriceHistogram(),
api.eth.gasPrice()
])
.then(([gasPriceHistogram, gasPrice]) => {

View File

@ -42,7 +42,7 @@ export default class Balances {
_subscribeAccountsInfo () {
this._api
.subscribe('personal_accountsInfo', (error, accountsInfo) => {
.subscribe('parity_accountsInfo', (error, accountsInfo) => {
if (error) {
return;
}
@ -76,7 +76,7 @@ export default class Balances {
}
_retrieveTokens () {
this._api.ethcore
this._api.parity
.registryAddress()
.then((registryAddress) => {
const registry = this._api.newContract(abis.registry, registryAddress);

View File

@ -17,8 +17,6 @@
import { handleActions } from 'redux-actions';
import { bytesToHex } from '../../api/util/format';
import { parityNode } from '../../environment';
const ZERO = '0x0000000000000000000000000000000000000000000000000000000000000000';
const initialState = {
@ -28,7 +26,7 @@ const initialState = {
export function hashToImageUrl (hashArray) {
const hash = hashArray ? bytesToHex(hashArray) : ZERO;
return hash === ZERO ? null : `${parityNode}/api/content/${hash.substr(2)}`;
return hash === ZERO ? null : `/api/content/${hash.substr(2)}`;
}
export default handleActions({

View File

@ -28,9 +28,9 @@ export default class Personal {
_subscribeAccountsInfo () {
this._api
.subscribe('personal_accountsInfo', (error, accountsInfo) => {
.subscribe('parity_accountsInfo', (error, accountsInfo) => {
if (error) {
console.error('personal_accountsInfo', error);
console.error('parity_accountsInfo', error);
return;
}

View File

@ -14,22 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { signerRequestsToConfirm } from './signerActions';
export default class Signer {
@ -44,7 +28,7 @@ export default class Signer {
_subscribeRequestsToConfirm () {
this._api
.subscribe('personal_requestsToConfirm', (error, pending) => {
.subscribe('signer_requestsToConfirm', (error, pending) => {
if (error) {
return;
}

View File

@ -51,7 +51,7 @@ export default class SignerMiddleware {
onConfirmStart = (store, action) => {
const { id, password } = action.payload;
this._api.personal
this._api.signer
.confirmRequest(id, {}, password)
.then((txHash) => {
console.log('confirmRequest', id, txHash);
@ -71,7 +71,7 @@ export default class SignerMiddleware {
onRejectStart = (store, action) => {
const id = action.payload;
this._api.personal
this._api.signer
.rejectRequest(id)
.then(() => {
store.dispatch(actions.successRejectRequest({ id }));

View File

@ -16,8 +16,6 @@
import { statusBlockNumber, statusCollection, statusLogs } from './statusActions';
import { parityNode } from '../../environment';
export default class Status {
constructor (store, api) {
this._api = api;
@ -33,8 +31,8 @@ export default class Status {
}
_fetchEnode () {
this._api
.ethcore.enode()
this._api.parity
.enode()
.then((enode) => {
this._store.dispatch(statusCollection({ enode }));
})
@ -65,7 +63,7 @@ export default class Status {
setTimeout(this._pollPing, timeout);
};
fetch(`${parityNode}/api/ping`, { method: 'GET' })
fetch('/', { method: 'HEAD' })
.then((response) => dispatch(!!response.ok))
.catch(() => dispatch(false));
}
@ -103,16 +101,16 @@ export default class Status {
.all([
this._api.web3.clientVersion(),
this._api.eth.coinbase(),
this._api.ethcore.defaultExtraData(),
this._api.ethcore.extraData(),
this._api.ethcore.gasFloorTarget(),
this._api.parity.defaultExtraData(),
this._api.parity.extraData(),
this._api.parity.gasFloorTarget(),
this._api.eth.hashrate(),
this._api.ethcore.minGasPrice(),
this._api.ethcore.netChain(),
this._api.ethcore.netPeers(),
this._api.ethcore.netPort(),
this._api.ethcore.nodeName(),
this._api.ethcore.rpcSettings(),
this._api.parity.minGasPrice(),
this._api.parity.netChain(),
this._api.parity.netPeers(),
this._api.parity.netPort(),
this._api.parity.nodeName(),
this._api.parity.rpcSettings(),
this._api.eth.syncing(),
this._pollTraceMode()
])
@ -155,8 +153,8 @@ export default class Status {
Promise
.all([
this._api.ethcore.devLogs(),
this._api.ethcore.devLogsLevels()
this._api.parity.devLogs(),
this._api.parity.devLogsLevels()
])
.then(([devLogs, devLogsLevels]) => {
this._store.dispatch(statusLogs({

View File

@ -25,20 +25,25 @@ export default class SecureApi extends Api {
this._isConnecting = true;
this._connectState = 0;
this._needsToken = false;
this._dappsPort = 8080;
this._signerPort = 8180;
console.log('SecureApi:constructor', sysuiToken);
this._followConnection();
}
setToken = () => {
window.localStorage.setItem('sysuiToken', this._transport.token);
console.log('SecureApi:setToken', this._transport.token);
}
_followConnection = () => {
const nextTick = () => {
setTimeout(this._followConnection, 250);
setTimeout(() => this._followConnection(), 250);
};
const setManual = () => {
this._connectedState = 100;
this._connectState = 100;
this._needsToken = true;
this._isConnecting = false;
};
@ -49,8 +54,7 @@ export default class SecureApi extends Api {
// token = <passed via constructor>
case 0:
if (isConnected) {
this._isConnecting = false;
return this.setToken();
return this.connectSuccess();
} else if (lastError) {
this.updateToken('initial', 1);
}
@ -59,14 +63,13 @@ export default class SecureApi extends Api {
// token = 'initial'
case 1:
if (isConnected) {
this._connectState = 2;
this.personal
this.signer
.generateAuthorizationToken()
.then((token) => {
this.updateToken(token, 2);
})
.catch((error) => {
console.error('_followConnection', error);
console.error('SecureApi:generateAuthorizationToken', error);
setManual();
});
return;
@ -78,8 +81,7 @@ export default class SecureApi extends Api {
// token = <personal_generateAuthorizationToken>
case 2:
if (isConnected) {
this._isConnecting = false;
return this.setToken();
return this.connectSuccess();
} else if (lastError) {
return setManual();
}
@ -89,10 +91,42 @@ export default class SecureApi extends Api {
nextTick();
}
updateToken (token, connectedState = 0) {
this._connectState = connectedState;
connectSuccess () {
this._isConnecting = false;
this._needsToken = false;
this.setToken();
Promise
.all([
this.parity.dappsPort(),
this.parity.signerPort()
])
.then(([dappsPort, signerPort]) => {
this._dappsPort = dappsPort.toNumber();
this._signerPort = signerPort.toNumber();
});
console.log('SecureApi:connectSuccess', this._transport.token);
}
updateToken (token, connectState) {
this._connectState = connectState;
this._transport.updateToken(token.replace(/[^a-zA-Z0-9]/g, ''));
this._followConnection();
console.log('SecureApi:updateToken', this._transport.token, connectState);
}
get dappsPort () {
return this._dappsPort;
}
get dappsUrl () {
return `http://127.0.0.1:${this._dappsPort}`;
}
get signerPort () {
return this._signerPort;
}
get isConnecting () {

View File

@ -47,7 +47,13 @@ class Balance extends Component {
const value = token.format
? new BigNumber(balance.value).div(new BigNumber(token.format)).toFormat(3)
: api.util.fromWei(balance.value).toFormat(3);
const imagesrc = token.image || images[token.address] || unknownImage;
let imagesrc = token.image;
if (!imagesrc) {
imagesrc =
images[token.address]
? `${api.dappsUrl}${images[token.address]}`
: unknownImage;
}
return (
<div

View File

@ -59,10 +59,9 @@ class IdentityIcon extends Component {
updateIcon (_address, images) {
const { api } = this.context;
const { button, inline, tiny } = this.props;
const iconsrc = images[_address];
if (iconsrc) {
this.setState({ iconsrc });
if (images[_address]) {
this.setState({ iconsrc: `${api.dappsUrl}${images[_address]}` });
return;
}

View File

@ -149,7 +149,7 @@ export default class Header extends Component {
const { account } = this.props;
this.setState({ name }, () => {
api.personal
api.parity
.setAccountName(account.address, name)
.catch((error) => {
console.error(error);

View File

@ -81,7 +81,7 @@ class Delete extends Component {
account.meta.deleted = true;
api.personal
api.parity
.setAccountMeta(account.address, account.meta)
.then(() => {
router.push(route);

View File

@ -104,8 +104,8 @@ class Application extends Component {
checkAccounts () {
const { api } = this.context;
api.personal
.listAccounts()
api.eth
.accounts()
.then((accounts) => {
this.setState({
showFirstRun: showFirstRun || accounts.length === 0

Some files were not shown because too many files have changed in this diff Show More