Compare commits

..

31 Commits

Author SHA1 Message Date
arkpar
08dd20a0f1 v1.5.9 2017-03-11 15:49:04 +01:00
Gav Wood
fcdc396e36 Fix auto-updater. (#4869) 2017-03-11 14:46:03 +01:00
arkpar
f14e425fc8 Fixing windows build script 2017-03-08 17:50:29 +01:00
GitLab Build Bot
2ce7144835 js-precompiled 20170308-152339 2017-03-08 17:27:32 +01:00
arkpar
fa14a62c8d Force js update 2017-03-08 15:40:26 +01:00
keorn
7f5795dee6 [stable] Engine backports (#4807)
* calibrate before rejection

* change flag name

* add eip155

* fix build

* make network_id default
2017-03-08 14:43:54 +01:00
arkpar
d0b6f2648b Switch js branch to stable 2017-03-07 17:51:06 +01:00
arkpar
a79cf7155a v1.5.8 2017-03-07 17:25:55 +01:00
Igor Artamonov
5baccf6f65 update ETC bootnodes (#4794) 2017-03-07 13:12:07 +01:00
arkpar
95ee6300df v1.5.7 2017-03-07 11:22:17 +01:00
Gav Wood
dc19465d31 Sane updater (#4658)
* Make updater avoid downloading earlier versions.

* Disable if files can't be moved.
2017-03-07 11:19:19 +01:00
Arkadiy Paronyan
dc8bc8d8dd [beta] Update comments and reg ABI (#4788)
* Update comments.

* Fix up new ABI.
2017-03-06 20:18:57 +01:00
Arkadiy Paronyan
3102cf7bc6 v1.5.6 (#4786) 2017-03-06 19:59:39 +01:00
Denis S. Soldatov aka General-Beck
ada9b02141 update docker-build
add arg
[ci skip]
2017-03-06 22:43:11 +04:00
Denis S. Soldatov aka General-Beck
f5d14e01d4 update docker for hub
add BUILD_TAG ARG
[ci skip]
2017-03-06 22:41:09 +04:00
GitLab Build Bot
bb9ff46a32 js-precompiled 20170306-150340 2017-03-06 16:27:48 +01:00
Tomasz Drwięga
1c177adca1 Optimize signature for fallback function. (#4780) (#4784) 2017-03-06 15:56:20 +01:00
Arkadiy Paronyan
c585985543 Engine backports (#4718) (#4781)
* custom dev presets

* add registrar field

* use constructor for dev registrar

* fix test
2017-03-06 15:02:09 +01:00
GitLab Build Bot
1be865beb0 js-precompiled 20170306-113802 2017-03-06 13:00:08 +01:00
Jaco Greeff
260bcfd368 [beta] Etherscan links (#4772) (#4778)
* Etherscan links (#4772)

* Port tests

* update address links

* Signer accountlink isTest
2017-03-06 12:09:00 +01:00
Arkadiy Paronyan
02be8d869c Fix invalid props (#4767) 2017-03-05 10:27:37 +01:00
Arkadiy Paronyan
46ac2cb94b Backporting to beta (#4741)
* New chains (#4720)

* Add Kovan chain.

* Fix up --testnet.

* Fix tests.

* Fix test.

* fix test

* Fix test.

* Fix to UglifyJS 2.8.2 to fix app build issues (#4723)

* Update classic bootnodes, ref #4717 (#4735)

* allow failure docker beta

* adjust pruning history default to 64 (#4709)

* backporting from master

[ci-skip]update docker-build.sh

* update gitlab.ci

fix docker hub build
[ci skip]

* update gitlab

docker beta-release->latest

* Add registry.

* Add info on forks.

* Fixed spec file

* Support both V1 & V2 DataChanged events in registry (#4734)

* Add info on forks.

* Add new registry ABI

* Import registry2 & fix exports

* Select ABI based on code hash

* Render new event types (owner not available)

* New registry.

* Rename old chain.

* Fix test.

* Another fix.

* Finish rename.

* Fixed fonts URLs (#4579)

* Fix Token Reg Dapp issues in Firefox (#4489)

* Fix overflow issues in Firefox (#4348)

* Fix wrong Promise inferance

* Add new Componennt for Token Images (#4496)

* Revert "Add new Componennt for Token Images (#4496)"

This reverts commit 6ffbdab891f85e4d988e3e8e96fc2c651bd68e04.

* Add StackEventListener (#4745)

* Update testnet detection (#4746)

* Fix Account Selection in Signer (#4744)

* Can pass FormattedMessage to Input (eg. Status // RPC Enabled)

* Simple fixed-width fix for Accoutn Selection in Parity Signer
2017-03-04 18:54:34 +01:00
Jaco Greeff
659cf2bb37 [beta] beta backports (#4763)
* https://mkr-market -> https://oasisdex.com (4701 beta)

* Wallet s/delete/forget/ (beta 4741)
2017-03-04 18:54:11 +01:00
arkpar
d3d6ff8ca9 v1.5.5 2017-03-03 11:48:02 +01:00
GitLab Build Bot
74b850e7fc js-precompiled 20170223-141159 2017-02-23 17:10:16 +01:00
Jaco Greeff
e4e25b771e [beta] Fix Geth account import (#4643)
* Fix Geth import - actually pass addresses through

* Fix geth accounts not displayed

* Port saving of returned addresses (master MobX, beta state)

* log result -> importGethAccounts
2017-02-23 15:05:03 +01:00
Denis S. Soldatov aka General-Beck
7fc3f4eda0 [ci skip] 2017-02-23 03:36:47 +04:00
Denis S. Soldatov aka General-Beck
b20ffbde8e [ci skip] 2017-02-23 03:32:25 +04:00
Arkadiy Paronyan
3fe38163f5 [beta] Backporting #4633 (#4640)
* Tweak some checks. (#4633)

* Tweak some checks.

* Fixed build and added a difficulty test

* v1.5.4
2017-02-22 19:17:02 +01:00
Denis S. Soldatov aka General-Beck
0d18436a3d [ci skip] typo fix in gitlab-ci 2017-02-20 22:08:53 +04:00
Denis S. Soldatov aka General-Beck
9ebfb14bb5 [ci skip] backport doker-build stage 2017-02-20 22:06:18 +04:00
103 changed files with 1123 additions and 492 deletions

View File

@@ -444,9 +444,9 @@ windows:
- aws configure set aws_access_key_id %s3_key%
- aws configure set aws_secret_access_key %s3_secret%
- echo %CI_BUILD_REF_NAME%
- echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
- echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
- echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
- echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
- echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
- echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
- echo %S3_BUCKET%
- aws s3 rm --recursive s3://%S3_BUCKET%/%CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe --body target\release\parity.exe
@@ -471,13 +471,13 @@ docker-build:
stage: build
only:
- tags
- triggers
before_script:
- docker info
script:
- cd docker/hub
- if [ "$CI_BUILD_REF_NAME" == "beta-release" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi
- docker login -u $Docker_Hub_User -p $Docker_Hub_Pass
- docker build --tag ethcore/parity:$CI_BUILD_REF_NAME .
- docker push ethcore/parity:$CI_BUILD_REF_NAME
- sh scripts/docker-build.sh $DOCKER_TAG
tags:
- docker
test-darwin:

48
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
[root]
name = "parity"
version = "1.5.3"
version = "1.5.9"
dependencies = [
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -23,7 +23,7 @@ dependencies = [
"ethcore-rpc 1.5.0",
"ethcore-signer 1.5.0",
"ethcore-stratum 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"ethsync 1.5.0",
"evmbin 1.5.0",
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -373,7 +373,7 @@ dependencies = [
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-ipc-nano 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
@@ -421,7 +421,7 @@ dependencies = [
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-devtools 1.5.0",
"ethcore-rpc 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"fetch 0.1.0",
"futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
@@ -469,7 +469,7 @@ name = "ethcore-ipc"
version = "1.5.0"
dependencies = [
"ethcore-devtools 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -516,7 +516,7 @@ dependencies = [
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-ipc-nano 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"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.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -531,7 +531,7 @@ dependencies = [
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-network 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.1.0",
"smallvec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -543,7 +543,7 @@ name = "ethcore-logger"
version = "1.5.0"
dependencies = [
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"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)",
@@ -559,7 +559,7 @@ dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-devtools 1.5.0",
"ethcore-io 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"ethcrypto 0.1.0",
"ethkey 0.2.0",
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -586,7 +586,7 @@ dependencies = [
"ethcore-devtools 1.5.0",
"ethcore-io 1.5.0",
"ethcore-ipc 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"ethcrypto 0.1.0",
"ethjson 0.1.0",
"ethkey 0.2.0",
@@ -621,7 +621,7 @@ dependencies = [
"ethcore-devtools 1.5.0",
"ethcore-io 1.5.0",
"ethcore-rpc 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=mio-old)",
"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)",
@@ -640,7 +640,7 @@ dependencies = [
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-ipc-nano 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=mio-old)",
"jsonrpc-tcp-server 0.1.0 (git+https://github.com/ethcore/jsonrpc.git?branch=mio-old)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -651,7 +651,7 @@ dependencies = [
[[package]]
name = "ethcore-util"
version = "1.5.3"
version = "1.5.9"
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)",
@@ -700,7 +700,7 @@ dependencies = [
name = "ethjson"
version = "0.1.0"
dependencies = [
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -756,7 +756,7 @@ dependencies = [
"ethcore-ipc-nano 1.5.0",
"ethcore-light 1.5.0",
"ethcore-network 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"ethkey 0.2.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)",
@@ -773,7 +773,7 @@ version = "1.5.0"
dependencies = [
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -975,7 +975,7 @@ version = "1.5.0"
dependencies = [
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1500,7 +1500,7 @@ name = "parity-hash-fetch"
version = "1.5.0"
dependencies = [
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"fetch 0.1.0",
"futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1525,7 +1525,7 @@ version = "1.4.0"
dependencies = [
"ethcore-rpc 1.5.0",
"ethcore-signer 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=mio-old)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1544,7 +1544,7 @@ name = "parity-ui"
version = "1.5.0"
dependencies = [
"parity-ui-dev 1.4.0",
"parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git?branch=beta)",
"parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git?branch=stable)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1558,7 +1558,7 @@ dependencies = [
[[package]]
name = "parity-ui-precompiled"
version = "1.4.0"
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#24137b8138964ea1cbada452aa56f8f5fe24bcaa"
source = "git+https://github.com/ethcore/js-precompiled.git?branch=stable#9fb19b623adc025b0f173fbcbd197f41b03770d5"
dependencies = [
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1571,7 +1571,7 @@ dependencies = [
"ethcore 1.5.0",
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"ethsync 1.5.0",
"ipc-common-types 1.5.0",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1851,7 +1851,7 @@ version = "1.4.0"
dependencies = [
"ethcore-bigint 0.1.2",
"ethcore-rpc 1.5.0",
"ethcore-util 1.5.3",
"ethcore-util 1.5.9",
"futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-rpc-client 1.4.0",
"rpassword 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2545,7 +2545,7 @@ dependencies = [
"checksum openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d2845e841700e7b04282ceaa115407ea84e0db918ae689ad9ceb6f06fa6046bd"
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git?branch=beta)" = "<none>"
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git?branch=stable)" = "<none>"
"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621"
"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
"checksum phf 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "447d9d45f2e0b4a9b532e808365abf18fc211be6ca217202fcd45236ef12f026"

View File

@@ -1,7 +1,7 @@
[package]
description = "Parity Ethereum client"
name = "parity"
version = "1.5.3"
version = "1.5.9"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"

View File

@@ -11,7 +11,7 @@ rustc_version = "0.1"
[dependencies]
parity-ui-dev = { path = "../../js", optional = true }
parity-ui-precompiled = { git = "https://github.com/ethcore/js-precompiled.git", branch = "beta", optional = true }
parity-ui-precompiled = { git = "https://github.com/ethcore/js-precompiled.git", branch = "stable", optional = true }
[features]
no-precompiled-js = ["parity-ui-dev"]

View File

@@ -1,6 +1,10 @@
FROM ubuntu:14.04
MAINTAINER Parity Technologies <devops@parity.io>
WORKDIR /build
#ENV for build TAG
ARG BUILD_TAG
ENV BUILD_TAG ${BUILD_TAG:-master}
RUN echo $BUILD_TAG
# install tools and dependencies
RUN apt-get update && \
apt-get install -y --force-yes --no-install-recommends \
@@ -47,7 +51,7 @@ RUN apt-get update && \
cd /build&&git clone https://github.com/ethcore/parity && \
cd parity && \
git pull&& \
git checkout $CI_BUILD_REF_NAME && \
git checkout $BUILD_TAG && \
cargo build --verbose --release --features final && \
#ls /build/parity/target/release/parity && \
strip /build/parity/target/release/parity && \

View File

@@ -47,18 +47,12 @@
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
},
"nodes": [
"enode://08c7ee6a4f861ff0664a49532bcc86de1363acd608999d1b76609bb9bc278649906f069057630fd9493924a368b5d1dc9b8f8bf13ac26df72512f6d1fabd8c95@45.32.7.81:30303",
"enode://e809c4a2fec7daed400e5e28564e23693b23b2cc5a019b612505631bbe7b9ccf709c1796d2a3d29ef2b045f210caf51e3c4f5b6d3587d43ad5d6397526fa6179@174.112.32.157:30303",
"enode://687be94c3a7beaa3d2fde82fa5046cdeb3e8198354e05b29d6e0d4e276713e3707ac10f784a7904938b06b46c764875c241b0337dd853385a4d8bfcbf8190647@95.183.51.229:30303",
"enode://6e538e7c1280f0a31ff08b382db5302480f775480b8e68f8febca0ceff81e4b19153c6f8bf60313b93bef2cc34d34e1df41317de0ce613a201d1660a788a03e2@52.206.67.235:30303",
"enode://ca5ae4eca09ba6787e29cf6d86f7634d07aae6b9e6317a59aff675851c0bf445068173208cf8ef7f5cd783d8e29b85b2fa3fa358124cf0546823149724f9bde1@138.68.1.16:30303",
"enode://217ebe27e89bf4fec8ce06509323ff095b1014378deb75ab2e5f6759a4e8750a3bd8254b8c6833136e4d5e58230d65ee8ab34a5db5abf0640408c4288af3c8a7@188.138.1.237:30303",
"enode://fa20444ef991596ce99b81652ac4e61de1eddc4ff21d3cd42762abd7ed47e7cf044d3c9ccddaf6035d39725e4eb372806787829ccb9a08ec7cb71883cb8c3abd@50.149.116.182:30303",
"enode://4bd6a4df3612c718333eb5ea7f817923a8cdf1bed89cee70d1710b45a0b6b77b2819846440555e451a9b602ad2efa2d2facd4620650249d8468008946887820a@71.178.232.20:30304",
"enode://921cf8e4c345fe8db913c53964f9cadc667644e7f20195a0b7d877bd689a5934e146ff2c2259f1bae6817b6585153a007ceb67d260b720fa3e6fc4350df25c7f@51.255.49.170:30303",
"enode://ffea3b01c000cdd89e1e9229fea3e80e95b646f9b2aa55071fc865e2f19543c9b06045cc2e69453e6b78100a119e66be1b5ad50b36f2ffd27293caa28efdd1b2@128.199.93.177:3030",
"enode://ee3da491ce6a155eb132708eb0e8d04b0637926ec0ae1b79e63fc97cb9fc3818f49250a0ae0d7f79ed62b66ec677f408c4e01741504dc7a051e274f1e803d454@91.121.65.179:40404",
"enode://48e063a6cf5f335b1ef2ed98126bf522cf254396f850c7d442fe2edbbc23398787e14cd4de7968a00175a82762de9cbe9e1407d8ccbcaeca5004d65f8398d759@159.203.255.59:30303"
"enode://5fbfb426fbb46f8b8c1bd3dd140f5b511da558cd37d60844b525909ab82e13a25ee722293c829e52cb65c2305b1637fa9a2ea4d6634a224d5f400bfe244ac0de@162.243.55.45:30303",
"enode://42d8f29d1db5f4b2947cd5c3d76c6d0d3697e6b9b3430c3d41e46b4bb77655433aeedc25d4b4ea9d8214b6a43008ba67199374a9b53633301bca0cd20c6928ab@104.155.176.151:30303",
"enode://814920f1ec9510aa9ea1c8f79d8b6e6a462045f09caa2ae4055b0f34f7416fca6facd3dd45f1cf1673c0209e0503f02776b8ff94020e98b6679a0dc561b4eba0@104.154.136.117:30303",
"enode://72e445f4e89c0f476d404bc40478b0df83a5b500d2d2e850e08eb1af0cd464ab86db6160d0fde64bd77d5f0d33507ae19035671b3c74fec126d6e28787669740@104.198.71.200:30303"
],
"accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },

View File

@@ -1,5 +1,5 @@
{
"name": "Frontier/Homestead",
"name": "Foundation",
"dataDir": "ethereum",
"engine": {
"Ethash": {
@@ -9,7 +9,7 @@
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0x3bb2bb5c6c9c9b7f4ef430b47dc7e026310042ea",
"registrar" : "0xe3389675d0338462dC76C6f9A3e432550c36A142",
"homesteadTransition": "0x118c30",
"daoHardforkTransition": "0x1d4c00",
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",

View File

@@ -0,0 +1,59 @@
{
"name": "Kovan",
"dataDir": "kovan",
"engine": {
"authorityRound": {
"params": {
"gasLimitBoundDivisor": "0x400",
"registrar" : "0xfAb104398BBefbd47752E7702D9fE23047E1Bca3",
"stepDuration": "4",
"blockReward": "0x4563918244F40000",
"validators" : {
"list": [
"0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED",
"0x00427feae2419c15b89d1c21af10d1b6650a4d3d",
"0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c",
"0x0020ee4Be0e2027d76603cB751eE069519bA81A1",
"0x0010f94b296a852aaac52ea6c5ac72e03afd032d",
"0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A",
"0x00E6d2b931F55a3f1701c7389d592a7778897879",
"0x00e4a10650e5a6D6001C38ff8E64F97016a1645c",
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
]
}
}
}
},
"params": {
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x2A"
},
"genesis": {
"seal": {
"authorityRound": {
"step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"gasLimit": "0x5B8D80"
},
"accounts": {
"0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
},
"nodes": [
"enode://c005dd308256c60fab247813d8bf6d6e81f9cd354287837eb1c2fcf294adaa913a3208e88900ef5c55a8cba7042c301d80503edec2ad3f92a72e241ee6743854@192.241.230.87:30303",
"enode://48caeceb2724f2f71406990aa81efe87f8c53f26441d891473da2ae50cc138f238addc0e46b5aee240db55de8c711daac53d7b32a3f13e30edb86a3ca7c2700b@138.68.143.220:30303",
"enode://85705212fd28ebdd56669fb55e958feb9d81f74fe76c82f867564b6c2995e69f596df0f588eba16f1a43b69ce06485d68231a0c83fed8469b41eba0e390c126f@139.59.146.42:30303",
"enode://2aa81bd0a761cd4f02c934dcf3f81c5b65953e51ab5ba03ceb1f125eb06418a1cdffb1c9d01871aa7bd456f3fce35e745608189ad1164f72b2161634b0c3f6ea@188.166.240.190:30303",
"enode://c5900cdd6d20795d58372f42dfbab9d664c27bb97e9c27972741942736e919122f9bac28e74cbc58e4ff195475ea90d9880b71a37af5b5a8cb41d843f765cff8@174.138.79.48:30303"
]
}

View File

@@ -47,7 +47,10 @@
},
"nodes": [
"enode://e731347db0521f3476e6bbbb83375dcd7133a1601425ebd15fd10f3835fd4c304fba6282087ca5a0deeafadf0aa0d4fd56c3323331901c1f38bd181c283e3e35@128.199.55.137:30303",
"enode://ceb5c0f85eb994dbe9693bf46d99b03f6b838d17cc74e68d5eb003171ff39e5f120b17f965b267c319303f94d80b9d994b77062fb1486d76ce95d9f3d8fe1cb4@46.101.122.141:30303"
"enode://ceb5c0f85eb994dbe9693bf46d99b03f6b838d17cc74e68d5eb003171ff39e5f120b17f965b267c319303f94d80b9d994b77062fb1486d76ce95d9f3d8fe1cb4@46.101.122.141:30303",
"enode://fb28713820e718066a2f5df6250ae9d07cff22f672dbf26be6c75d088f821a9ad230138ba492c533a80407d054b1436ef18e951bb65e6901553516c8dffe8ff0@104.155.176.151:30304",
"enode://afdc6076b9bf3e7d3d01442d6841071e84c76c73a7016cb4f35c0437df219db38565766234448f1592a07ba5295a867f0ce87b359bf50311ed0b830a2361392d@104.154.136.117:30403",
"enode://21101a9597b79e933e17bc94ef3506fe99a137808907aa8fefa67eea4b789792ad11fb391f38b00087f8800a2d3dff011572b62a31232133dd1591ac2d1502c8@104.198.71.200:30403"
],
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -49,6 +49,8 @@ pub struct AuthorityRoundParams {
pub step_duration: Duration,
/// Block reward.
pub block_reward: U256,
/// Namereg contract address.
pub registrar: Address,
/// Starting step,
pub start_step: Option<u64>,
/// Valid validators.
@@ -62,6 +64,7 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
step_duration: Duration::from_secs(p.step_duration.into()),
validators: p.validators,
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
registrar: p.registrar.map_or_else(Address::new, Into::into),
start_step: p.start_step.map(Into::into),
}
}
@@ -73,6 +76,7 @@ pub struct AuthorityRound {
params: CommonParams,
gas_limit_bound_divisor: U256,
block_reward: U256,
registrar: Address,
step_duration: Duration,
builtins: BTreeMap<Address, Builtin>,
transition_service: IoService<()>,
@@ -82,6 +86,8 @@ pub struct AuthorityRound {
account_provider: Mutex<Arc<AccountProvider>>,
password: RwLock<Option<String>>,
validators: Box<ValidatorSet + Send + Sync>,
/// Is this Engine just for testing (prevents step calibration).
calibrate_step: bool,
}
fn header_step(header: &Header) -> Result<usize, ::rlp::DecoderError> {
@@ -112,6 +118,7 @@ impl AuthorityRound {
params: params,
gas_limit_bound_divisor: our_params.gas_limit_bound_divisor,
block_reward: our_params.block_reward,
registrar: our_params.registrar,
step_duration: our_params.step_duration,
builtins: builtins,
transition_service: IoService::<()>::start()?,
@@ -121,6 +128,7 @@ impl AuthorityRound {
account_provider: Mutex::new(Arc::new(AccountProvider::transient_provider())),
password: RwLock::new(None),
validators: new_validator_set(our_params.validators),
calibrate_step: our_params.start_step.is_none(),
});
// Do not initialize timeouts for tests.
if should_timeout {
@@ -130,6 +138,12 @@ impl AuthorityRound {
Ok(engine)
}
fn calibrate_step(&self) {
if self.calibrate_step {
self.step.store((unix_now().as_secs() / self.step_duration.as_secs()) as usize, AtomicOrdering::SeqCst);
}
}
fn remaining_step_duration(&self) -> Duration {
let now = unix_now();
let step_end = self.step_duration * (self.step.load(AtomicOrdering::SeqCst) as u32 + 1);
@@ -147,6 +161,16 @@ impl AuthorityRound {
fn is_step_proposer(&self, step: usize, address: &Address) -> bool {
self.step_proposer(step) == *address
}
fn is_future_step(&self, step: usize) -> bool {
if step > self.step.load(AtomicOrdering::SeqCst) + 1 {
// Make absolutely sure that the step is correct.
self.calibrate_step();
step > self.step.load(AtomicOrdering::SeqCst) + 1
} else {
false
}
}
}
fn unix_now() -> Duration {
@@ -180,11 +204,16 @@ impl IoHandler<()> for TransitionHandler {
impl Engine for AuthorityRound {
fn name(&self) -> &str { "AuthorityRound" }
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
/// Two fields - consensus step and the corresponding proposer signature.
fn seal_fields(&self) -> usize { 2 }
fn params(&self) -> &CommonParams { &self.params }
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.registrar.hex()] }
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
fn step(&self) {
@@ -276,7 +305,10 @@ impl Engine for AuthorityRound {
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
let header_step = header_step(header)?;
// Give one step slack if step is lagging, double vote is still not possible.
if header_step <= self.step.load(AtomicOrdering::SeqCst) + 1 {
if self.is_future_step(header_step) {
trace!(target: "engine", "verify_block_unordered: block from the future");
Err(BlockError::InvalidSeal)?
} else {
let proposer_signature = header_signature(header)?;
let ok_sig = verify_address(&self.step_proposer(header_step), &proposer_signature, &header.bare_hash())?;
if ok_sig {
@@ -285,9 +317,6 @@ impl Engine for AuthorityRound {
trace!(target: "poa", "verify_block_unordered: invalid seal signature");
Err(BlockError::InvalidSeal)?
}
} else {
trace!(target: "poa", "verify_block_unordered: block from the future");
Err(BlockError::InvalidSeal)?
}
}

View File

@@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap;
use util::Address;
use util::{Address, HashMap};
use builtin::Builtin;
use engines::{Engine, Seal};
use env_info::EnvInfo;
@@ -26,14 +26,16 @@ use block::ExecutedBlock;
/// An engine which does not provide any consensus mechanism, just seals blocks internally.
pub struct InstantSeal {
params: CommonParams,
registrar: Address,
builtins: BTreeMap<Address, Builtin>,
}
impl InstantSeal {
/// Returns new instance of InstantSeal with default VM Factory
pub fn new(params: CommonParams, builtins: BTreeMap<Address, Builtin>) -> Self {
pub fn new(params: CommonParams, registrar: Address, builtins: BTreeMap<Address, Builtin>) -> Self {
InstantSeal {
params: params,
registrar: registrar,
builtins: builtins,
}
}
@@ -48,6 +50,10 @@ impl Engine for InstantSeal {
&self.params
}
fn additional_params(&self) -> HashMap<String, String> {
hash_map!["registrar".to_owned() => self.registrar.hex()]
}
fn builtins(&self) -> &BTreeMap<Address, Builtin> {
&self.builtins
}
@@ -76,9 +82,9 @@ mod tests {
fn instant_can_seal() {
let spec = Spec::new_instant();
let engine = &*spec.engine;
let genesis_header = spec.genesis_header();
let mut db_result = get_temp_state_db();
let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap();
let genesis_header = spec.genesis_header();
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let b = b.close_and_lock();

View File

@@ -160,7 +160,9 @@ pub trait Engine : Sync + Send {
fn verify_transaction(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }
/// The network ID that transactions should be signed with.
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> { None }
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> {
Some(self.params().chain_id)
}
/// Verify the seal of a block. This is an auxilliary method that actually just calls other `verify_` methods
/// to get the job done. By default it must pass `verify_basic` and `verify_block_unordered`. If more or fewer

View File

@@ -86,6 +86,7 @@ pub struct Tendermint {
authority: RwLock<Address>,
/// Password used for signing messages.
password: RwLock<Option<String>>,
registrar: Address,
/// Blockchain height.
height: AtomicUsize,
/// Consensus round.
@@ -119,6 +120,7 @@ impl Tendermint {
block_reward: our_params.block_reward,
authority: RwLock::new(Address::default()),
password: RwLock::new(None),
registrar: our_params.registrar,
height: AtomicUsize::new(1),
round: AtomicUsize::new(0),
step: RwLock::new(Step::Propose),
@@ -376,14 +378,20 @@ impl Tendermint {
impl Engine for Tendermint {
fn name(&self) -> &str { "Tendermint" }
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
/// (consensus round, proposal signature, authority signatures)
fn seal_fields(&self) -> usize { 3 }
fn params(&self) -> &CommonParams { &self.params }
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.registrar.hex()] }
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
fn maximum_uncle_count(&self) -> usize { 0 }
fn maximum_uncle_age(&self) -> usize { 0 }
/// Additional engine-specific information for the user/developer concerning `header`.

View File

@@ -18,7 +18,7 @@
use ethjson;
use super::transition::TendermintTimeouts;
use util::{U256, Uint};
use util::{U256, Uint, Address, FixedHash};
use time::Duration;
/// `Tendermint` params.
@@ -32,6 +32,8 @@ pub struct TendermintParams {
pub timeouts: TendermintTimeouts,
/// Block reward.
pub block_reward: U256,
/// Namereg contract address.
pub registrar: Address,
}
fn to_duration(ms: ethjson::uint::Uint) -> Duration {
@@ -52,6 +54,7 @@ impl From<ethjson::spec::TendermintParams> for TendermintParams {
commit: p.timeout_commit.map_or(dt.commit, to_duration),
},
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
registrar: p.registrar.map_or_else(Address::new, Into::into),
}
}
}

View File

@@ -850,4 +850,22 @@ mod tests {
ethash.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002));
assert_eq!(*header.gas_limit(), U256::from(150_002));
}
#[test]
fn difficulty_max_timestamp() {
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(u64::max_value());
let difficulty = ethash.calculate_difficulty(&header, &parent_header);
assert_eq!(U256::from(12543204905719u64), difficulty);
}
}

View File

@@ -30,46 +30,52 @@ pub use self::denominations::*;
use super::spec::*;
/// Most recent fork block that we support on Mainnet.
pub const FORK_SUPPORTED_FRONTIER: u64 = 2675000;
pub const FORK_SUPPORTED_FOUNDATION: u64 = 2675000;
/// Most recent fork block that we support on Ropsten.
pub const FORK_SUPPORTED_ROPSTEN: u64 = 10;
/// Most recent fork block that we support on Kovan.
pub const FORK_SUPPORTED_KOVAN: u64 = 0;
fn load(b: &[u8]) -> Spec {
Spec::load(b).expect("chain spec is invalid")
}
/// Create a new Olympic chain spec.
/// Create a new Foundation Olympic chain spec.
pub fn new_olympic() -> Spec { load(include_bytes!("../../res/ethereum/olympic.json")) }
/// Create a new Frontier mainnet chain spec.
pub fn new_frontier() -> Spec { load(include_bytes!("../../res/ethereum/frontier.json")) }
/// Create a new Foundation Mainnet chain spec.
pub fn new_foundation() -> Spec { load(include_bytes!("../../res/ethereum/foundation.json")) }
/// Create a new Frontier mainnet chain spec without the DAO hardfork.
/// Create a new Classic Mainnet chain spec without the DAO hardfork.
pub fn new_classic() -> Spec { load(include_bytes!("../../res/ethereum/classic.json")) }
/// Create a new Frontier mainnet chain spec without the DAO hardfork.
/// Create a new Expanse mainnet chain spec.
pub fn new_expanse() -> Spec { load(include_bytes!("../../res/ethereum/expanse.json")) }
/// Create a new Frontier chain spec as though it never changes to Homestead.
/// Create a new Kovan testnet chain spec.
pub fn new_kovan() -> Spec { load(include_bytes!("../../res/ethereum/kovan.json")) }
/// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead.
pub fn new_frontier_test() -> Spec { load(include_bytes!("../../res/ethereum/frontier_test.json")) }
/// Create a new Homestead chain spec as though it never changed from Frontier.
/// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier.
pub fn new_homestead_test() -> Spec { load(include_bytes!("../../res/ethereum/homestead_test.json")) }
/// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier.
/// Create a new Foundation Homestead-EIP150-era chain spec as though it never changed from Homestead/Frontier.
pub fn new_eip150_test() -> Spec { load(include_bytes!("../../res/ethereum/eip150_test.json")) }
/// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier.
/// Create a new Foundation Homestead-EIP161-era chain spec as though it never changed from Homestead/Frontier.
pub fn new_eip161_test() -> Spec { load(include_bytes!("../../res/ethereum/eip161_test.json")) }
/// Create a new Frontier/Homestead/DAO chain spec with transition points at #5 and #8.
/// Create a new Foundation Frontier/Homestead/DAO chain spec with transition points at #5 and #8.
pub fn new_transition_test() -> Spec { load(include_bytes!("../../res/ethereum/transition_test.json")) }
/// Create a new Frontier main net chain spec without genesis accounts.
/// Create a new Foundation Mainnet chain spec without genesis accounts.
pub fn new_mainnet_like() -> Spec { load(include_bytes!("../../res/ethereum/frontier_like_test.json")) }
/// Create a new Ropsten chain spec.
/// Create a new Foundation Ropsten chain spec.
pub fn new_ropsten() -> Spec { load(include_bytes!("../../res/ethereum/ropsten.json")) }
/// Create a new Morden chain spec.
@@ -112,7 +118,7 @@ mod tests {
#[test]
fn frontier() {
let frontier = new_frontier();
let frontier = new_foundation();
assert_eq!(frontier.state_root(), "d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544".into());
let genesis = frontier.genesis_block();

View File

@@ -276,7 +276,7 @@ impl Decodable for Header {
number: r.val_at(8)?,
gas_limit: r.val_at(9)?,
gas_used: r.val_at(10)?,
timestamp: r.val_at(11)?,
timestamp: min(r.val_at::<U256>(11)?, u64::max_value().into()).as_u64(),
extra_data: r.val_at(12)?,
seal: vec![],
hash: RefCell::new(Some(r.as_raw().sha3())),

View File

@@ -32,7 +32,7 @@
//! use ethcore::miner::{Miner, MinerService};
//!
//! fn main() {
//! let miner: Miner = Miner::with_spec(&ethereum::new_frontier());
//! let miner: Miner = Miner::with_spec(&ethereum::new_foundation());
//! // get status
//! assert_eq!(miner.status().transactions_in_pending_queue, 0);
//!

View File

@@ -157,7 +157,7 @@ impl Spec {
fn engine(engine_spec: ethjson::spec::Engine, params: CommonParams, builtins: BTreeMap<Address, Builtin>) -> Arc<Engine> {
match engine_spec {
ethjson::spec::Engine::Null => Arc::new(NullEngine::new(params, builtins)),
ethjson::spec::Engine::InstantSeal => Arc::new(InstantSeal::new(params, builtins)),
ethjson::spec::Engine::InstantSeal(instant) => Arc::new(InstantSeal::new(params, instant.params.registrar.map_or_else(Address::new, Into::into), builtins)),
ethjson::spec::Engine::Ethash(ethash) => Arc::new(ethereum::Ethash::new(params, From::from(ethash.params), builtins)),
ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(params, From::from(basic_authority.params), builtins)),
ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(params, From::from(authority_round.params), builtins).expect("Failed to start AuthorityRound consensus engine."),

View File

@@ -186,7 +186,7 @@ pub mod headers {
type Verified = Header;
fn create(input: Self::Input, engine: &Engine) -> Result<Self::Unverified, Error> {
verify_header_params(&input, engine).map(|_| input)
verify_header_params(&input, engine, true).map(|_| input)
}
fn verify(unverified: Self::Unverified, engine: &Engine, check_seal: bool) -> Result<Self::Verified, Error> {

View File

@@ -51,12 +51,12 @@ impl HeapSizeOf for PreverifiedBlock {
/// Phase 1 quick block verification. Only does checks that are cheap. Operates on a single block
pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Result<(), Error> {
verify_header_params(&header, engine)?;
verify_header_params(&header, engine, true)?;
verify_block_integrity(bytes, &header.transactions_root(), &header.uncles_hash())?;
engine.verify_block_basic(&header, Some(bytes))?;
for u in UntrustedRlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::<Header>()) {
let u = u?;
verify_header_params(&u, engine)?;
verify_header_params(&u, engine, false)?;
engine.verify_block_basic(&u, None)?;
}
// Verify transactions.
@@ -195,7 +195,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error>
}
/// Check basic header parameters.
pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Error> {
pub fn verify_header_params(header: &Header, engine: &Engine, is_full: bool) -> Result<(), Error> {
if header.number() >= From::from(BlockNumber::max_value()) {
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { max: Some(From::from(BlockNumber::max_value())), min: None, found: header.number() })))
}
@@ -210,9 +210,11 @@ pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Erro
if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size {
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
}
let max_time = get_time().sec as u64 + 30;
if header.timestamp() > max_time {
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
if is_full {
let max_time = get_time().sec as u64 + 30;
if header.timestamp() > max_time {
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
}
}
Ok(())
}

View File

@@ -3,7 +3,7 @@
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(v15/0eC6fl06luXEYWpBSJvXCIX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
src: local('Roboto Light'), local('Roboto-Light'), url(./v15/0eC6fl06luXEYWpBSJvXCIX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
/* cyrillic */
@@ -11,7 +11,7 @@
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(v15/Fl4y0QdOxyyTHEGMXX8kcYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
src: local('Roboto Light'), local('Roboto-Light'), url(./v15/Fl4y0QdOxyyTHEGMXX8kcYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@@ -19,7 +19,7 @@
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(v15/-L14Jk06m6pUHB-5mXQQnYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
src: local('Roboto Light'), local('Roboto-Light'), url(./v15/-L14Jk06m6pUHB-5mXQQnYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@@ -27,7 +27,7 @@
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(v15/I3S1wsgSg9YCurV6PUkTOYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
src: local('Roboto Light'), local('Roboto-Light'), url(./v15/I3S1wsgSg9YCurV6PUkTOYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@@ -35,7 +35,7 @@
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(v15/NYDWBdD4gIq26G5XYbHsFIX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
src: local('Roboto Light'), local('Roboto-Light'), url(./v15/NYDWBdD4gIq26G5XYbHsFIX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@@ -43,7 +43,7 @@
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(v15/Pru33qjShpZSmG3z6VYwnYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
src: local('Roboto Light'), local('Roboto-Light'), url(./v15/Pru33qjShpZSmG3z6VYwnYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@@ -51,6 +51,6 @@
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(v15/Hgo13k-tfSpn0qi1SFdUfZBw1xU1rKptJj_0jans920.woff2) format('woff2');
src: local('Roboto Light'), local('Roboto-Light'), url(./v15/Hgo13k-tfSpn0qi1SFdUfZBw1xU1rKptJj_0jans920.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}

View File

@@ -3,7 +3,7 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 300;
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(v4/N4duVc9C58uwPiY8_59Fz0ExlR2MysFCBK8OirNw2kM.woff2) format('woff2');
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(./v4/N4duVc9C58uwPiY8_59Fz0ExlR2MysFCBK8OirNw2kM.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
/* cyrillic */
@@ -11,7 +11,7 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 300;
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(v4/N4duVc9C58uwPiY8_59Fz2dsm03krrxlabhmVQFB99s.woff2) format('woff2');
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(./v4/N4duVc9C58uwPiY8_59Fz2dsm03krrxlabhmVQFB99s.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@@ -19,7 +19,7 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 300;
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(v4/N4duVc9C58uwPiY8_59FzyJ0caWjaSBdV-xZbEgst_k.woff2) format('woff2');
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(./v4/N4duVc9C58uwPiY8_59FzyJ0caWjaSBdV-xZbEgst_k.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@@ -27,7 +27,7 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 300;
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(v4/N4duVc9C58uwPiY8_59Fz2MSHb9EAJwuSzGfuRChQzQ.woff2) format('woff2');
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(./v4/N4duVc9C58uwPiY8_59Fz2MSHb9EAJwuSzGfuRChQzQ.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@@ -35,7 +35,7 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 300;
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(v4/N4duVc9C58uwPiY8_59Fz-pRBTtN4E2_qSPBnw6AgMc.woff2) format('woff2');
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(./v4/N4duVc9C58uwPiY8_59Fz-pRBTtN4E2_qSPBnw6AgMc.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@@ -43,7 +43,7 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 300;
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(v4/N4duVc9C58uwPiY8_59Fz9Dnm4qiMZlH5rhYv_7LI2Y.woff2) format('woff2');
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(./v4/N4duVc9C58uwPiY8_59Fz9Dnm4qiMZlH5rhYv_7LI2Y.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@@ -51,6 +51,6 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 300;
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(v4/N4duVc9C58uwPiY8_59Fz9TIkQYohD4BpHvJ3NvbHoA.woff2) format('woff2');
src: local('Roboto Mono Light'), local('RobotoMono-Light'), url(./v4/N4duVc9C58uwPiY8_59Fz9TIkQYohD4BpHvJ3NvbHoA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}

View File

@@ -188,6 +188,7 @@
"scryptsy": "2.0.0",
"solc": "ngotchac/solc-js",
"store": "1.3.20",
"uglify-js": "2.8.2",
"useragent.js": "0.5.6",
"utf8": "2.1.2",
"valid-url": "1.0.9",

View File

@@ -21,15 +21,15 @@ const PAGE_SIZE = 25;
import util from '../../api/util';
import { call } from './call';
function _call (method, params, test) {
return call('account', method, params, test);
function _call (method, params, test, netVersion) {
return call('account', method, params, test, netVersion);
}
function balance (address, test = false) {
function balance (address, test, netVersion) {
return _call('balance', {
address: address,
tag: 'latest'
}, test).then((balance) => {
}, test, netVersion).then((balance) => {
// same format as balancemulti below
return {
account: address,
@@ -38,21 +38,21 @@ function balance (address, test = false) {
});
}
function balances (addresses, test = false) {
function balances (addresses, test, netVersion) {
return _call('balancemulti', {
address: addresses.join(','),
tag: 'latest'
}, test);
}, test, netVersion);
}
function transactions (address, page, test = false) {
function transactions (address, page, test, netVersion) {
// page offset from 0
return _call('txlist', {
address: address,
offset: PAGE_SIZE,
page: (page || 0) + 1,
sort: 'desc'
}, test).then((transactions) => {
}, test, netVersion).then((transactions) => {
return transactions.map((tx) => {
return {
blockNumber: new BigNumber(tx.blockNumber || 0),
@@ -67,9 +67,9 @@ function transactions (address, page, test = false) {
}
const account = {
balance: balance,
balances: balances,
transactions: transactions
balance,
balances,
transactions
};
export { account };

View File

@@ -23,14 +23,32 @@ const options = {
}
};
export function call (module, action, _params, test) {
const host = test ? 'testnet.etherscan.io' : 'api.etherscan.io';
export function call (module, action, _params, test, netVersion) {
let prefix = 'api.';
switch (netVersion) {
case '2':
case '3':
prefix = 'testnet.';
break;
case '42':
prefix = 'kovan.';
break;
case '0':
default:
if (test) {
prefix = 'testnet.';
}
break;
}
const query = stringify(Object.assign({
module, action
}, _params || {}));
return fetch(`https://${host}/api?${query}`, options)
return fetch(`https://${prefix}etherscan.io/api?${query}`, options)
.then((response) => {
if (!response.ok) {
throw { code: response.status, message: response.statusText }; // eslint-disable-line

View File

@@ -19,8 +19,8 @@ import { stringify } from 'qs';
import { url } from './links';
function mockget (requests, test) {
let scope = nock(url(test));
function mockget (requests, test, netVersion) {
let scope = nock(url(test, netVersion));
requests.forEach((request) => {
scope = scope

View File

@@ -14,14 +14,35 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export const url = (isTestnet = false) => {
return `https://${isTestnet ? 'testnet.' : ''}etherscan.io`;
// NOTE: Keep 'isTestnet' for backwards library compatibility
export const url = (isTestnet = false, netVersion = '0') => {
let prefix = '';
switch (netVersion) {
case '2':
case '3':
prefix = 'testnet.';
break;
case '42':
prefix = 'kovan.';
break;
case '0':
default:
if (isTestnet) {
prefix = 'testnet.';
}
break;
}
return `https://${prefix}etherscan.io`;
};
export const txLink = (hash, isTestnet = false) => {
return `${url(isTestnet)}/tx/${hash}`;
export const txLink = (hash, isTestnet = false, netVersion = '0') => {
return `${url(isTestnet, netVersion)}/tx/${hash}`;
};
export const addressLink = (address, isTestnet = false) => {
return `${url(isTestnet)}/address/${address}`;
export const addressLink = (address, isTestnet = false, netVersion = '0') => {
return `${url(isTestnet, netVersion)}/address/${address}`;
};

View File

@@ -21,8 +21,9 @@ export function eventSignature (eventName, params) {
const { strName, name } = parseName(eventName);
const types = (params || []).map(fromParamType).join(',');
const id = `${strName}(${types})`;
const signature = strName ? keccak_256(id) : '';
return { id, name, signature: keccak_256(id) };
return { id, name, signature };
}
export function methodSignature (methodName, params) {

View File

@@ -46,7 +46,7 @@ describe('abi/util/signature', () => {
expect(eventSignature(undefined, [])).to.deep.equal({
id: '()',
name: undefined,
signature: '861731d50c3880a2ca1994d5ec287b94b2f4bd832a67d3e41c08177bdd5674fe'
signature: ''
});
});
@@ -54,7 +54,7 @@ describe('abi/util/signature', () => {
expect(eventSignature(undefined, undefined)).to.deep.equal({
id: '()',
name: undefined,
signature: '861731d50c3880a2ca1994d5ec287b94b2f4bd832a67d3e41c08177bdd5674fe'
signature: ''
});
});
});
@@ -96,7 +96,7 @@ describe('abi/util/signature', () => {
expect(methodSignature(undefined, [])).to.deep.equal({
id: '()',
name: undefined,
signature: '861731d5'
signature: ''
});
});
@@ -104,7 +104,7 @@ describe('abi/util/signature', () => {
expect(methodSignature(undefined, undefined)).to.deep.equal({
id: '()',
name: undefined,
signature: '861731d5'
signature: ''
});
});
});

View File

@@ -174,7 +174,7 @@ export default class Parity {
importGethAccounts (accounts) {
return this._transport
.execute('parity_importGethAccounts', inAddresses)
.execute('parity_importGethAccounts', inAddresses(accounts))
.then(outAddresses);
}

View File

@@ -14,34 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import badgereg from './badgereg.json';
import basiccoin from './basiccoin.json';
import basiccoinmanager from './basiccoinmanager.json';
import dappreg from './dappreg.json';
import eip20 from './eip20.json';
import emailverification from './email-verification.json';
import gavcoin from './gavcoin.json';
import githubhint from './githubhint.json';
import owned from './owned.json';
import registry from './registry.json';
import signaturereg from './signaturereg.json';
import smsverification from './sms-verification.json';
import tokenreg from './tokenreg.json';
import wallet from './wallet.json';
export {
badgereg,
basiccoin,
basiccoinmanager,
dappreg,
eip20,
emailverification,
gavcoin,
githubhint,
owned,
registry,
signaturereg,
smsverification,
tokenreg,
wallet
};
export badgereg from './badgereg.json';
export basiccoin from './basiccoin.json';
export basiccoinmanager from './basiccoinmanager.json';
export dappreg from './dappreg.json';
export eip20 from './eip20.json';
export emailverification from './email-verification.json';
export gavcoin from './gavcoin.json';
export githubhint from './githubhint.json';
export owned from './owned.json';
export registry from './registry.json';
export registry2 from './registry2.json';
export signaturereg from './signaturereg.json';
export smsverification from './sms-verification.json';
export tokenreg from './tokenreg.json';
export wallet from './wallet.json';

File diff suppressed because one or more lines are too long

View File

@@ -16,6 +16,7 @@
import BigNumber from 'bignumber.js';
import { url as etherscanUrl } from '~/3rdparty/etherscan/links';
import * as abis from '~/contracts/abi';
import { api } from './parity';
@@ -28,7 +29,7 @@ const subscriptions = {};
let defaultSubscriptionId;
let nextSubscriptionId = 1000;
let isTest = false;
let netVersion = '0';
export function subscribeEvents (addresses, callback) {
const subscriptionId = nextSubscriptionId++;
@@ -117,14 +118,15 @@ export function attachInstances () {
return Promise
.all([
api.parity.registryAddress(),
api.parity.netChain()
api.parity.netChain(),
api.partiy.netVersion()
])
.then(([registryAddress, netChain]) => {
.then(([registryAddress, netChain, _netVersion]) => {
const registry = api.newContract(abis.registry, registryAddress).instance;
isTest = ['morden', 'ropsten', 'testnet'].includes(netChain);
netVersion = _netVersion;
console.log(`contract was found at registry=${registryAddress}`);
console.log(`running on ${netChain}, isTest=${isTest}`);
console.log(`running on ${netChain}, network ${netVersion}`);
return Promise
.all([
@@ -282,5 +284,5 @@ export function loadTokenBalance (tokenAddress, address) {
}
export function txLink (txHash) {
return `https://${isTest ? 'testnet.' : ''}etherscan.io/tx/${txHash}`;
return `https://${etherscanUrl(false, netVersion)}/tx/${txHash}`;
}

View File

@@ -53,7 +53,13 @@ const renderEvent = (classNames, verb) => (e) => {
return (
<tr key={ e.key } className={ classes }>
<td>
<Address address={ e.parameters.owner.value } />
<Address
address={
e.parameters.owner
? e.parameters.owner.value
: e.from
}
/>
</td>
<td>
<abbr title={ e.transaction }>{ verb }</abbr>
@@ -79,17 +85,23 @@ const renderDataChanged = (e) => {
return (
<tr key={ e.key } className={ classNames }>
<td>
<Address address={ e.parameters.owner.value } />
<Address
address={
e.parameters.owner
? e.parameters.owner.value
: e.from
}
/>
</td>
<td>
<abbr title={ e.transaction }>updated</abbr>
</td>
<td>
{ 'key ' }
key&nbsp;
<code>
{ new Buffer(e.parameters.plainKey.value).toString('utf8') }
</code>
{ 'of ' }
&nbsp;of&nbsp;
<code>
<Hash hash={ bytesToHex(e.parameters.name.value) } />
</code>

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/>.
import { registry as registryAbi } from '~/contracts/abi';
import { registry as registryAbi, registry2 as registryAbi2 } from '~/contracts/abi';
import { api } from './parity.js';
import * as addresses from './addresses/actions.js';
@@ -27,15 +27,17 @@ import * as reverse from './Reverse/actions.js';
export { addresses, accounts, lookup, events, names, records, reverse };
export const setIsTestnet = (isTestnet) => ({ type: 'set isTestnet', isTestnet });
const REGISTRY_V1_HASHES = [
'0x34f7c51bbb1b1902fbdabfdf04811100f5c9f998f26dd535d2f6f977492c748e', // ropsten
'0x64c3ee34851517a9faecd995c102b339f03e564ad6772dc43a26f993238b20ec' // homestead
];
export const setNetVersion = (netVersion) => ({ type: 'set netVersion', netVersion });
export const fetchIsTestnet = () => (dispatch) =>
api.net.version()
.then((netVersion) => {
dispatch(setIsTestnet(
netVersion === '2' || // morden
netVersion === '3' // ropsten
));
dispatch(setNetVersion(netVersion));
})
.catch((err) => {
console.error('could not check if testnet');
@@ -47,12 +49,28 @@ export const fetchIsTestnet = () => (dispatch) =>
export const setContract = (contract) => ({ type: 'set contract', contract });
export const fetchContract = () => (dispatch) =>
api.parity.registryAddress()
api.parity
.registryAddress()
.then((address) => {
const contract = api.newContract(registryAbi, address);
dispatch(setContract(contract));
dispatch(fetchFee());
dispatch(fetchOwner());
return api.eth
.getCode(address)
.then((code) => {
const codeHash = api.util.sha3(code);
const isVersion1 = REGISTRY_V1_HASHES.includes(codeHash);
console.log(`registry at ${address}, code ${codeHash}, version ${isVersion1 ? 1 : 2}`);
const contract = api.newContract(
isVersion1
? registryAbi
: registryAbi2,
address
);
dispatch(setContract(contract));
dispatch(fetchFee());
dispatch(fetchOwner());
});
})
.catch((err) => {
console.error('could not fetch contract');

View File

@@ -22,8 +22,8 @@ import namesReducer from './Names/reducers.js';
import recordsReducer from './Records/reducers.js';
import reverseReducer from './Reverse/reducers.js';
const isTestnetReducer = (state = null, action) =>
action.type === 'set isTestnet' ? action.isTestnet : state;
const netVersionReducer = (state = null, action) =>
action.type === 'set netVersion' ? action.netVersion : state;
const contractReducer = (state = null, action) =>
action.type === 'set contract' ? action.contract : state;
@@ -35,7 +35,7 @@ const ownerReducer = (state = null, action) =>
action.type === 'set owner' ? action.owner : state;
const initialState = {
isTestnet: isTestnetReducer(undefined, { type: '' }),
netVersion: netVersionReducer(undefined, { type: '' }),
accounts: accountsReducer(undefined, { type: '' }),
contacts: contactsReducer(undefined, { type: '' }),
contract: contractReducer(undefined, { type: '' }),
@@ -49,7 +49,7 @@ const initialState = {
};
export default (state = initialState, action) => ({
isTestnet: isTestnetReducer(state.isTestnet, action),
netVersion: netVersionReducer(state.netVersion, action),
accounts: accountsReducer(state.accounts, action),
contacts: contactsReducer(state.contacts, action),
contract: contractReducer(state.contract, action),

View File

@@ -28,7 +28,7 @@ class Address extends Component {
static propTypes = {
address: PropTypes.string.isRequired,
account: nullableProptype(PropTypes.object.isRequired),
isTestnet: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
key: PropTypes.string,
shortenHash: PropTypes.bool
};
@@ -56,7 +56,7 @@ class Address extends Component {
}
renderCaption () {
const { address, account, isTestnet, shortenHash } = this.props;
const { address, account, netVersion, shortenHash } = this.props;
if (account) {
const { name } = account;
@@ -64,7 +64,7 @@ class Address extends Component {
return (
<a
className={ styles.link }
href={ etherscanUrl(address, isTestnet) }
href={ etherscanUrl(address, false, netVersion) }
target='_blank'
>
<abbr
@@ -103,14 +103,14 @@ function mapStateToProps (initState, initProps) {
});
return (state, props) => {
const { isTestnet } = state;
const { netVersion } = state;
const { address = '' } = props;
const account = allAccounts[address] || null;
return {
account,
isTestnet
netVersion
};
};
}

View File

@@ -26,7 +26,7 @@ const leading0x = /^0x/;
class Hash extends Component {
static propTypes = {
hash: PropTypes.string.isRequired,
isTestnet: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
linked: PropTypes.bool
}
@@ -35,7 +35,7 @@ class Hash extends Component {
}
render () {
const { hash, isTestnet, linked } = this.props;
const { hash, netVersion, linked } = this.props;
let shortened = hash.toLowerCase().replace(leading0x, '');
shortened = shortened.length > (6 + 6)
@@ -46,7 +46,7 @@ class Hash extends Component {
return (
<a
className={ styles.link }
href={ etherscanUrl(hash, isTestnet) }
href={ etherscanUrl(hash, false, netVersion) }
target='_blank'
>
<abbr title={ hash }>{ shortened }</abbr>
@@ -60,7 +60,7 @@ class Hash extends Component {
export default connect(
(state) => ({ // mapStateToProps
isTestnet: state.isTestnet
netVersion: state.netVersion
}),
null // mapDispatchToProps
)(Hash);

View File

@@ -14,13 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { url as externalUrl } from '~/3rdparty/etherscan/links';
const leading0x = /^0x/;
const etherscanUrl = (hash, isTestnet) => {
const etherscanUrl = (hash, isTestnet, netVersion) => {
hash = hash.toLowerCase().replace(leading0x, '');
const type = hash.length === 40 ? 'address' : 'tx';
return `https://${isTestnet ? 'testnet.' : ''}etherscan.io/${type}/0x${hash}`;
return `https://${externalUrl(isTestnet, netVersion)}/${type}/0x${hash}`;
};
export default etherscanUrl;

View File

@@ -105,22 +105,22 @@ export default class InputText extends Component {
const validation = validate(value, validationType, contract);
if (validation instanceof Promise) {
const loadingTimeout = setTimeout(() => {
this.setState({ disabled: true, loading: true });
}, 50);
return validation
.then(validation => {
this.setValidation({
...validation,
disabled: false,
loading: false
});
return Promise.resolve(validation)
.then((validation) => {
clearTimeout(loadingTimeout);
event.target.focus();
this.setValidation({
...validation,
disabled: false,
loading: false
});
}
this.setValidation(validation);
event.target.focus();
});
}
onKeyDown = (event) => {

View File

@@ -49,7 +49,7 @@
}
.token-container {
flex: 1;
flex: 1 1 auto;
}
.full-width .token-container {

View File

@@ -97,3 +97,4 @@ if (module.hot) {
);
});
}

View File

@@ -106,7 +106,7 @@ export default class NewGeth extends Component {
api.parity
.listGethAccounts()
.then((_addresses) => {
const addresses = (addresses || []).filter((address) => !accounts[address]);
const addresses = (_addresses || []).filter((address) => !accounts[address]);
return Promise
.all(addresses.map((address) => api.eth.getBalance(address)))

View File

@@ -139,7 +139,7 @@ export default class CreateAccount extends Component {
case 2:
if (createType === 'fromGeth') {
return (
<AccountDetailsGeth addresses={ this.state.gethAddresses } />
<AccountDetailsGeth addresses={ this.state.gethImported } />
);
}
@@ -310,10 +310,14 @@ export default class CreateAccount extends Component {
if (createType === 'fromGeth') {
return api.parity
.importGethAccounts(this.state.gethAddresses)
.then((result) => {
console.log('result', result);
.then((gethImported) => {
console.log('importGethAccounts', gethImported);
return Promise.all(this.state.gethAddresses.map((address) => {
this.setState({
gethImported
});
return Promise.all(gethImported.map((address) => {
return api.parity.setAccountName(address, 'Geth Import');
}));
})

View File

@@ -84,7 +84,6 @@ class ExecuteContract extends Component {
contract: PropTypes.object.isRequired,
fromAddress: PropTypes.string,
gasLimit: PropTypes.object.isRequired,
isTest: PropTypes.bool,
onClose: PropTypes.func.isRequired,
onFromAddressChange: PropTypes.func.isRequired
}

View File

@@ -44,7 +44,7 @@ export default class VerificationStore {
@observable consentGiven = false;
@observable requestTx = null;
@observable code = '';
@observable isCodeValid = null;
@observable isCodeValid = false;
@observable confirmationTx = null;
constructor (api, abi, certifierName, account, isTestnet) {
@@ -132,7 +132,7 @@ export default class VerificationStore {
const values = [ sha3.text(code) ];
this.code = code;
this.isCodeValid = null;
this.isCodeValid = false;
confirm.estimateGas(options, values)
.then((gas) => {
options.gas = gas.mul(1.2).toFixed(0);

View File

@@ -288,9 +288,11 @@ export default class Status {
.then(([
netPeers, clientVersion, netVersion, defaultExtraData, netChain, netPort, rpcSettings, enode, upgradeStatus
]) => {
const isTest =
netVersion === '2' || // morden
netVersion === '3'; // ropsten
const isTest = [
'2', // morden
'3', // ropsten
'42' // kovan
].includes(netVersion);
const longStatus = {
netPeers,
@@ -298,6 +300,7 @@ export default class Status {
defaultExtraData,
netChain,
netPort,
netVersion,
rpcSettings,
isTest,
enode

View File

@@ -40,6 +40,7 @@ const initialState = {
max: new BigNumber(0)
},
netPort: new BigNumber(0),
netVersion: '0',
rpcSettings: {},
syncing: true,
isConnected: false,

View File

@@ -46,6 +46,10 @@ const UNDERLINE_FOCUSED = {
const NAME_ID = ' ';
export default class Input extends Component {
static contextTypes = {
intl: React.PropTypes.object.isRequired
};
static propTypes = {
allowCopy: PropTypes.oneOfType([
PropTypes.string,
@@ -78,7 +82,8 @@ export default class Input extends Component {
style: PropTypes.object,
value: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string
PropTypes.string,
PropTypes.node
])
};
@@ -134,6 +139,13 @@ export default class Input extends Component {
? UNDERLINE_FOCUSED
: readOnly && typeof focused !== 'boolean' ? { display: 'none' } : null;
const textValue = typeof value !== 'string' && (value && value.props)
? this.context.intl.formatMessage(
value.props,
value.props.values || {}
)
: value;
return (
<div className={ styles.container } style={ style }>
{ this.renderCopyButton() }
@@ -168,7 +180,8 @@ export default class Input extends Component {
underlineStyle={ underlineStyle }
underlineFocusStyle={ underlineFocusStyle }
underlineShow={ !hideUnderline }
value={ value }>
value={ textValue }
>
{ children }
</TextField>
</div>

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/>.
import EventListener from 'react-event-listener';
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import ReactPortal from 'react-portal';
@@ -23,6 +22,7 @@ import keycode from 'keycode';
import { nodeOrStringProptype } from '~/util/proptypes';
import { CloseIcon } from '~/ui/Icons';
import ParityBackground from '~/ui/ParityBackground';
import StackEventListener from '~/ui/StackEventListener';
import Title from '~/ui/Title';
import styles from './portal.css';
@@ -92,10 +92,7 @@ export default class Portal extends Component {
onClick={ this.stopEvent }
onKeyDown={ this.handleKeyDown }
>
<EventListener
target='window'
onKeyUp={ this.handleKeyUp }
/>
<StackEventListener onKeyUp={ this.handleKeyUp } />
<ParityBackground className={ styles.parityBackground } />
{ this.renderClose() }
<Title
@@ -174,7 +171,7 @@ export default class Portal extends Component {
switch (codeName) {
case 'esc':
event.preventDefault();
return this.handleClose();
return this.props.onClose();
}
}

View File

@@ -0,0 +1,17 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './stackEventListener';

View File

@@ -0,0 +1,56 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import ReactEventListener from 'react-event-listener';
import React, { Component, PropTypes } from 'react';
let listenerId = 0;
let listenerIds = [];
export default class StackEventListener extends Component {
static propTypes = {
onKeyUp: PropTypes.func.isRequired
};
componentWillMount () {
// Add to the list of listeners on mount
this.id = ++listenerId;
listenerIds.push(this.id);
}
componentWillUnmount () {
// Remove from the listeners list on unmount
listenerIds = listenerIds.filter((id) => this.id !== id);
}
render () {
return (
<ReactEventListener
target='window'
onKeyUp={ this.handleKeyUp }
/>
);
}
handleKeyUp = (event) => {
// Only handle event if last of the listeners list
if (this.id !== listenerIds.slice(-1)[0]) {
return event;
}
return this.props.onKeyUp(event);
}
}

View File

@@ -34,8 +34,8 @@ class TxHash extends Component {
static propTypes = {
hash: PropTypes.string.isRequired,
isTest: PropTypes.bool,
maxConfirmations: PropTypes.number,
netVersion: PropTypes.string.isRequired,
summary: PropTypes.bool
}
@@ -116,10 +116,10 @@ class TxHash extends Component {
}
render () {
const { hash, isTest, summary } = this.props;
const { hash, netVersion, summary } = this.props;
const hashLink = (
<a href={ txLink(hash, isTest) } target='_blank'>
<a href={ txLink(hash, false, netVersion) } target='_blank'>
<ShortenedHash data={ hash } />
</a>
);
@@ -255,9 +255,11 @@ class TxHash extends Component {
}
function mapStateToProps (state) {
const { isTest } = state.nodeStatus;
const { netVersion } = state.nodeStatus;
return { isTest };
return {
netVersion
};
}
export default connect(

View File

@@ -63,7 +63,9 @@ function createRedux () {
subscribe: sinon.stub(),
getState: () => {
return {
nodeStatus: { isTest: true }
nodeStatus: {
netVersion: '42'
}
};
}
};

View File

@@ -16,6 +16,7 @@
import moment from 'moment';
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { txLink, addressLink } from '~/3rdparty/etherscan/links';
@@ -25,7 +26,7 @@ import MethodDecoding from '../../MethodDecoding';
import styles from '../txList.css';
export default class TxRow extends Component {
class TxRow extends Component {
static contextTypes = {
api: PropTypes.object.isRequired
};
@@ -33,7 +34,7 @@ export default class TxRow extends Component {
static propTypes = {
tx: PropTypes.object.isRequired,
address: PropTypes.string.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
block: PropTypes.object,
historic: PropTypes.bool,
@@ -45,7 +46,7 @@ export default class TxRow extends Component {
};
render () {
const { tx, address, isTest, historic, className } = this.props;
const { address, className, historic, netVersion, tx } = this.props;
return (
<tr className={ className || '' }>
@@ -57,8 +58,9 @@ export default class TxRow extends Component {
<div>
<a
className={ styles.link }
href={ txLink(tx.hash, isTest) }
target='_blank'>
href={ txLink(tx.hash, false, netVersion) }
target='_blank'
>
{ `${tx.hash.substr(2, 6)}...${tx.hash.slice(-6)}` }
</a>
</div>
@@ -75,13 +77,13 @@ export default class TxRow extends Component {
}
renderAddress (address) {
const { isTest } = this.props;
const { netVersion } = this.props;
let esLink = null;
if (address) {
esLink = (
<a
href={ addressLink(address, isTest) }
href={ addressLink(address, false, netVersion) }
target='_blank'
className={ styles.link }>
<IdentityName address={ address } shorten />
@@ -131,3 +133,16 @@ export default class TxRow extends Component {
);
}
}
function mapStateToProps (state) {
const { netVersion } = state.nodeStatus;
return {
netVersion
};
}
export default connect(
mapStateToProps,
null
)(TxRow);

View File

@@ -25,9 +25,27 @@ import TxRow from './txRow';
const api = new Api({ execute: sinon.stub() });
const STORE = {
dispatch: sinon.stub(),
subscribe: sinon.stub(),
getState: () => {
return {
nodeStatus: {
netVersion: '42'
},
personal: {
accounts: {
'0x123': {}
}
}
};
}
};
function render (props) {
return shallow(
<TxRow
store={ STORE }
{ ...props } />,
{ context: { api } }
);
@@ -45,7 +63,7 @@ describe('ui/TxList/TxRow', () => {
value: new BigNumber(1)
};
expect(render({ address: '0x123', block, isTest: true, tx })).to.be.ok;
expect(render({ address: '0x123', block, netVersion: '42', tx })).to.be.ok;
});
});
});

View File

@@ -35,7 +35,7 @@ class TxList extends Component {
PropTypes.array,
PropTypes.object
]).isRequired,
isTest: PropTypes.bool.isRequired
netVersion: PropTypes.string.isRequired
}
store = new Store(this.context.api);
@@ -63,7 +63,7 @@ class TxList extends Component {
}
renderRows () {
const { address, isTest } = this.props;
const { address, netVersion } = this.props;
return this.store.sortedHashes.map((txhash) => {
const tx = this.store.transactions[txhash];
@@ -76,7 +76,7 @@ class TxList extends Component {
tx={ tx }
block={ block }
address={ address }
isTest={ isTest }
netVersion={ netVersion }
/>
);
});
@@ -84,10 +84,10 @@ class TxList extends Component {
}
function mapStateToProps (state) {
const { isTest } = state.nodeStatus;
const { netVersion } = state.nodeStatus;
return {
isTest
netVersion
};
}

View File

@@ -30,7 +30,7 @@ const STORE = {
getState: () => {
return {
nodeStatus: {
isTest: true
netVersion: '42'
}
};
}

View File

@@ -21,8 +21,8 @@ import etherscan from '~/3rdparty/etherscan';
export default class Store {
@observable address = null;
@observable isLoading = false;
@observable isTest = undefined;
@observable isTracing = false;
@observable netVersion = '0';
@observable txHashes = [];
constructor (api) {
@@ -44,8 +44,8 @@ export default class Store {
this.isLoading = isLoading;
}
@action setTest = (isTest) => {
this.isTest = isTest;
@action setNetVersion = (netVersion) => {
this.netVersion = netVersion;
}
@action setTracing = (isTracing) => {
@@ -55,7 +55,7 @@ export default class Store {
@action updateProps = (props) => {
transaction(() => {
this.setAddress(props.address);
this.setTest(props.isTest);
this.setNetVersion(props.netVersion);
// TODO: When tracing is enabled again, adjust to actually set
this.setTracing(false && props.traceMode);
@@ -65,7 +65,7 @@ export default class Store {
}
getTransactions () {
if (this.isTest === undefined) {
if (this.netVersion === '0') {
return Promise.resolve();
}
@@ -87,7 +87,7 @@ export default class Store {
}
fetchEtherscanTransactions () {
return etherscan.account.transactions(this.address, 0, this.isTest);
return etherscan.account.transactions(this.address, 0, false, this.netVersion);
}
fetchTraceTransactions () {

View File

@@ -43,7 +43,7 @@ function mockQuery () {
sort: 'desc'
},
reply: [{ hash: '123' }]
}], true);
}], false, '42');
}
describe('views/Account/Transactions/store', () => {
@@ -94,10 +94,10 @@ describe('views/Account/Transactions/store', () => {
});
});
describe('setTest', () => {
it('sets the isTest flag', () => {
store.setTest(true);
expect(store.isTest).to.be.true;
describe('setNetVersion', () => {
it('sets the netVersion', () => {
store.setNetVersion('testing');
expect(store.netVersion).to.equal('testing');
});
});
@@ -124,7 +124,7 @@ describe('views/Account/Transactions/store', () => {
it('retrieves the hashes via etherscan', () => {
sinon.spy(store, 'fetchEtherscanTransactions');
store.setAddress(ADDRESS);
store.setTest(true);
store.setNetVersion('42');
store.setTracing(false);
return store.getTransactions().then(() => {
@@ -137,7 +137,7 @@ describe('views/Account/Transactions/store', () => {
it('retrieves the hashes via tracing', () => {
sinon.spy(store, 'fetchTraceTransactions');
store.setAddress(ADDRESS);
store.setTest(true);
store.setNetVersion('42');
store.setTracing(true);
return store.getTransactions().then(() => {
@@ -151,7 +151,7 @@ describe('views/Account/Transactions/store', () => {
describe('fetchEtherscanTransactions', () => {
it('retrieves the transactions', () => {
store.setAddress(ADDRESS);
store.setTest(true);
store.setNetVersion('42');
return store.fetchEtherscanTransactions().then((transactions) => {
expect(transactions).to.deep.equal([{
@@ -169,7 +169,7 @@ describe('views/Account/Transactions/store', () => {
describe('fetchTraceTransactions', () => {
it('retrieves the transactions', () => {
store.setAddress(ADDRESS);
store.setTest(true);
store.setNetVersion('42');
return store.fetchTraceTransactions().then((transactions) => {
expect(transactions).to.deep.equal([

View File

@@ -32,7 +32,7 @@ class Transactions extends Component {
static propTypes = {
address: PropTypes.string.isRequired,
isTest: PropTypes.bool,
netVersion: PropTypes.string.isRequired,
traceMode: PropTypes.bool
}
@@ -48,7 +48,7 @@ class Transactions extends Component {
return;
}
const hasChanged = ['isTest', 'address']
const hasChanged = ['address', 'netVersion']
.map(key => newProps[key] !== this.props[key])
.reduce((truth, keyTruth) => truth || keyTruth, false);
@@ -109,10 +109,10 @@ class Transactions extends Component {
}
function mapStateToProps (state) {
const { isTest, traceMode } = state.nodeStatus;
const { netVersion, traceMode } = state.nodeStatus;
return {
isTest,
netVersion,
traceMode
};
}

View File

@@ -31,7 +31,7 @@ function createRedux () {
},
images: {},
nodeStatus: {
isTest: false,
netVersion: '1',
traceMode: false
},
personal: {

View File

@@ -84,8 +84,6 @@ class TabBar extends Component {
};
static propTypes = {
isTest: PropTypes.bool,
netChain: PropTypes.string,
pending: PropTypes.array,
views: PropTypes.array.isRequired
};

View File

@@ -46,8 +46,6 @@ class Application extends Component {
static propTypes = {
blockNumber: PropTypes.object,
children: PropTypes.node,
isTest: PropTypes.bool,
netChain: PropTypes.string,
pending: PropTypes.array
}
@@ -86,17 +84,14 @@ class Application extends Component {
}
renderApp () {
const { blockNumber, children, pending, netChain, isTest } = this.props;
const { blockNumber, children, pending } = this.props;
return (
<Container
upgradeStore={ this.upgradeStore }
onCloseFirstRun={ this.store.closeFirstrun }
showFirstRun={ this.store.firstrunVisible }>
<TabBar
netChain={ netChain }
isTest={ isTest }
pending={ pending } />
<TabBar pending={ pending } />
<div className={ styles.content }>
{ children }
</div>
@@ -123,15 +118,13 @@ class Application extends Component {
}
function mapStateToProps (state) {
const { blockNumber, netChain, isTest } = state.nodeStatus;
const { blockNumber } = state.nodeStatus;
const { hasAccounts } = state.personal;
const { pending } = state.signer;
return {
blockNumber,
hasAccounts,
isTest,
netChain,
pending
};
}

View File

@@ -31,7 +31,7 @@ export default class Event extends Component {
static propTypes = {
event: PropTypes.object.isRequired,
isTest: PropTypes.bool
netVersion: PropTypes.string.isRequired
}
state = {
@@ -43,11 +43,11 @@ export default class Event extends Component {
}
render () {
const { event, isTest } = this.props;
const { event, netVersion } = this.props;
const { block, transaction } = this.state;
const classes = `${styles.event} ${styles[event.state]}`;
const url = txLink(event.transactionHash, isTest);
const url = txLink(event.transactionHash, false, netVersion);
const keys = Object.keys(event.params).join(', ');
const values = Object.keys(event.params).map((name, index) => {
const param = event.params[name];

View File

@@ -28,9 +28,9 @@ export default class Events extends Component {
};
static propTypes = {
isTest: PropTypes.bool.isRequired,
isLoading: PropTypes.bool,
events: PropTypes.array
events: PropTypes.array,
netVersion: PropTypes.string.isRequired
};
static defaultProps = {
@@ -39,7 +39,7 @@ export default class Events extends Component {
};
render () {
const { events, isTest, isLoading } = this.props;
const { events, isLoading, netVersion } = this.props;
if (isLoading) {
return (
@@ -67,7 +67,8 @@ export default class Events extends Component {
<Event
key={ event.key }
event={ event }
isTest={ isTest } />
netVersion={ netVersion }
/>
);
});
@@ -82,7 +83,9 @@ export default class Events extends Component {
</th>
</tr>
</thead>
<tbody>{ list }</tbody>
<tbody>
{ list }
</tbody>
</table>
</Container>
);

View File

@@ -52,7 +52,7 @@ class Contract extends Component {
accountsInfo: PropTypes.object,
balances: PropTypes.object,
contracts: PropTypes.object,
isTest: PropTypes.bool,
netVersion: PropTypes.string.isRequired,
params: PropTypes.object
};
@@ -119,7 +119,7 @@ class Contract extends Component {
}
render () {
const { accountsInfo, balances, contracts, params, isTest } = this.props;
const { accountsInfo, balances, contracts, netVersion, params } = this.props;
const { allEvents, contract, queryValues, loadingEvents } = this.state;
const account = contracts[params.address];
const balance = balances[params.address];
@@ -148,9 +148,9 @@ class Contract extends Component {
values={ queryValues }
/>
<Events
isTest={ isTest }
isLoading={ loadingEvents }
events={ allEvents }
netVersion={ netVersion }
/>
{ this.renderDetails(account) }
</Page>
@@ -484,14 +484,14 @@ class Contract extends Component {
function mapStateToProps (state) {
const { accounts, accountsInfo, contracts } = state.personal;
const { balances } = state.balances;
const { isTest } = state.nodeStatus;
const { netVersion } = state.nodeStatus;
return {
isTest,
accounts,
accountsInfo,
balances,
contracts,
balances
netVersion
};
}

View File

@@ -61,7 +61,7 @@ class UrlButton extends Component {
hint={
<FormattedMessage
id='dapps.button.url.input'
defaultMessage='https://mkr.market' />
defaultMessage='https://oasisdex.com' />
}
onBlur={ this.hideInput }
onFocus={ this.showInput }

View File

@@ -55,6 +55,7 @@ $modalZ: 10001;
.container {
display: flex;
flex-direction: column;
width: 100%;
}
.overlay {
@@ -114,7 +115,8 @@ $modalZ: 10001;
flex-direction: column;
min-height: 30vh;
max-height: 80vh;
max-width: calc(100vw - 1em);
max-width: calc(100vw - 2em);
width: 960px;
.content {
flex: 1;

View File

@@ -21,7 +21,7 @@ import styles from './accountLink.css';
export default class AccountLink extends Component {
static propTypes = {
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
address: PropTypes.string.isRequired,
className: PropTypes.string,
children: PropTypes.node
@@ -32,15 +32,15 @@ export default class AccountLink extends Component {
};
componentWillMount () {
const { address, isTest } = this.props;
const { address, netVersion } = this.props;
this.updateLink(address, isTest);
this.updateLink(address, netVersion);
}
componentWillReceiveProps (nextProps) {
const { address, isTest } = nextProps;
const { address, netVersion } = nextProps;
this.updateLink(address, isTest);
this.updateLink(address, netVersion);
}
render () {
@@ -56,8 +56,8 @@ export default class AccountLink extends Component {
);
}
updateLink (address, isTest) {
const link = addressLink(address, isTest);
updateLink (address, netVersion) {
const link = addressLink(address, false, netVersion);
this.setState({
link

View File

@@ -25,7 +25,7 @@ export default class Account extends Component {
static propTypes = {
className: PropTypes.string,
address: PropTypes.string.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
balance: PropTypes.object // eth BigNumber, not required since it mght take time to fetch
};
@@ -51,13 +51,14 @@ export default class Account extends Component {
}
render () {
const { address, isTest, className } = this.props;
const { address, netVersion, className } = this.props;
return (
<div className={ `${styles.acc} ${className}` }>
<AccountLink
address={ address }
isTest={ isTest }>
netVersion={ netVersion }
>
<IdentityIcon
center
address={ address } />
@@ -76,14 +77,15 @@ export default class Account extends Component {
}
renderName () {
const { address, isTest } = this.props;
const { address, netVersion } = this.props;
const name = <IdentityName address={ address } empty />;
if (!name) {
return (
<AccountLink
address={ address }
isTest={ isTest }>
netVersion={ netVersion }
>
[{ this.shortAddress(address) }]
</AccountLink>
);
@@ -92,7 +94,8 @@ export default class Account extends Component {
return (
<AccountLink
address={ address }
isTest={ isTest } >
netVersion={ netVersion }
>
<span>
<span className={ styles.name }>{ name }</span>
<span className={ styles.address }>[{ this.tinyAddress(address) }]</span>

View File

@@ -27,7 +27,7 @@ export default class RequestPending extends Component {
gasLimit: PropTypes.object.isRequired,
id: PropTypes.object.isRequired,
isSending: PropTypes.bool.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
onConfirm: PropTypes.func.isRequired,
onReject: PropTypes.func.isRequired,
payload: PropTypes.oneOfType([
@@ -51,7 +51,7 @@ export default class RequestPending extends Component {
};
render () {
const { className, date, focus, gasLimit, id, isSending, isTest, onReject, payload, store } = this.props;
const { className, date, focus, gasLimit, id, isSending, netVersion, onReject, payload, store } = this.props;
if (payload.sign) {
const { sign } = payload;
@@ -65,7 +65,7 @@ export default class RequestPending extends Component {
id={ id }
isFinished={ false }
isSending={ isSending }
isTest={ isTest }
netVersion={ netVersion }
onConfirm={ this.onConfirm }
onReject={ onReject }
store={ store } />
@@ -82,7 +82,7 @@ export default class RequestPending extends Component {
gasLimit={ gasLimit }
id={ id }
isSending={ isSending }
isTest={ isTest }
netVersion={ netVersion }
onConfirm={ this.onConfirm }
onReject={ onReject }
store={ store }

View File

@@ -0,0 +1,112 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
import { shallow } from 'enzyme';
import React from 'react';
import sinon from 'sinon';
import RequestPending from './';
const ADDRESS = '0x1234567890123456789012345678901234567890';
const TRANSACTION = {
from: ADDRESS,
gas: new BigNumber(21000),
gasPrice: new BigNumber(20000000),
value: new BigNumber(1)
};
const PAYLOAD_SENDTX = {
sendTransaction: TRANSACTION
};
const PAYLOAD_SIGN = {
sign: {
address: ADDRESS,
data: 'testing'
}
};
const PAYLOAD_SIGNTX = {
signTransaction: TRANSACTION
};
let component;
let onConfirm;
let onReject;
function render (payload) {
onConfirm = sinon.stub();
onReject = sinon.stub();
component = shallow(
<RequestPending
date={ new Date() }
gasLimit={ new BigNumber(100000) }
id={ new BigNumber(123) }
isSending={ false }
netVersion='42'
onConfirm={ onConfirm }
onReject={ onReject }
origin={ {} }
payload={ payload }
store={ {} }
/>
);
return component;
}
describe('views/Signer/RequestPending', () => {
describe('sendTransaction', () => {
beforeEach(() => {
render(PAYLOAD_SENDTX);
});
it('renders defaults', () => {
expect(component).to.be.ok;
});
it('renders TransactionPending component', () => {
expect(component.find('TransactionPending')).to.have.length(1);
});
});
describe('sign', () => {
beforeEach(() => {
render(PAYLOAD_SIGN);
});
it('renders defaults', () => {
expect(component).to.be.ok;
});
it('renders SignRequest component', () => {
expect(component.find('SignRequest')).to.have.length(1);
});
});
describe('signTransaction', () => {
beforeEach(() => {
render(PAYLOAD_SIGNTX);
});
it('renders defaults', () => {
expect(component).to.be.ok;
});
it('renders TransactionPending component', () => {
expect(component.find('TransactionPending')).to.have.length(1);
});
});
});

View File

@@ -44,8 +44,8 @@ export default class SignRequest extends Component {
address: PropTypes.string.isRequired,
data: PropTypes.string.isRequired,
isFinished: PropTypes.bool.isRequired,
isTest: PropTypes.bool.isRequired,
store: PropTypes.object.isRequired,
netVersion: PropTypes.string.isRequired,
className: PropTypes.string,
focus: PropTypes.bool,
@@ -92,7 +92,7 @@ export default class SignRequest extends Component {
renderDetails () {
const { api } = this.context;
const { address, isTest, store, data } = this.props;
const { address, netVersion, store, data } = this.props;
const balance = store.balances[address];
if (!balance) {
@@ -105,7 +105,8 @@ export default class SignRequest extends Component {
<Account
address={ address }
balance={ balance }
isTest={ isTest } />
netVersion={ netVersion }
/>
</div>
<div className={ styles.info } title={ api.util.sha3(data) }>
<p>A request to sign data using your account:</p>

View File

@@ -31,7 +31,7 @@ export default class TransactionMainDetails extends Component {
fromBalance: PropTypes.object,
gasStore: PropTypes.object,
id: PropTypes.object.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
totalValue: PropTypes.object.isRequired,
transaction: PropTypes.object.isRequired,
value: PropTypes.object.isRequired
@@ -50,7 +50,7 @@ export default class TransactionMainDetails extends Component {
}
render () {
const { children, from, fromBalance, gasStore, isTest, transaction } = this.props;
const { children, from, fromBalance, gasStore, netVersion, transaction } = this.props;
return (
<div className={ styles.transaction }>
@@ -59,7 +59,7 @@ export default class TransactionMainDetails extends Component {
<Account
address={ from }
balance={ fromBalance }
isTest={ isTest }
netVersion={ netVersion }
/>
</div>
</div>

View File

@@ -39,7 +39,7 @@ export default class TransactionPending extends Component {
gasLimit: PropTypes.object,
id: PropTypes.object.isRequired,
isSending: PropTypes.bool.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
nonce: PropTypes.number,
onConfirm: PropTypes.func.isRequired,
onReject: PropTypes.func.isRequired,
@@ -87,7 +87,7 @@ export default class TransactionPending extends Component {
}
renderTransaction () {
const { className, focus, id, isSending, isTest, store, transaction } = this.props;
const { className, focus, id, isSending, netVersion, store, transaction } = this.props;
const { totalValue } = this.state;
const { from, value } = transaction;
@@ -101,7 +101,7 @@ export default class TransactionPending extends Component {
fromBalance={ fromBalance }
gasStore={ this.gasStore }
id={ id }
isTest={ isTest }
netVersion={ netVersion }
totalValue={ totalValue }
transaction={ transaction }
value={ value } />

View File

@@ -22,18 +22,19 @@ export default class TxHashLink extends Component {
static propTypes = {
children: PropTypes.node,
className: PropTypes.string,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
txHash: PropTypes.string.isRequired
}
render () {
const { children, className, isTest, txHash } = this.props;
const { children, className, netVersion, txHash } = this.props;
return (
<a
className={ className }
href={ txLink(txHash, isTest) }
target='_blank'>
href={ txLink(txHash, false, netVersion) }
target='_blank'
>
{ children || txHash }
</a>
);

View File

@@ -38,7 +38,7 @@ class Embedded extends Component {
startRejectRequest: PropTypes.func.isRequired
}).isRequired,
gasLimit: PropTypes.object.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
signer: PropTypes.shape({
finished: PropTypes.array.isRequired,
pending: PropTypes.array.isRequired
@@ -79,7 +79,7 @@ class Embedded extends Component {
}
renderPending = (data, index) => {
const { actions, gasLimit, isTest } = this.props;
const { actions, gasLimit, netVersion } = this.props;
const { date, id, isSending, payload } = data;
return (
@@ -90,7 +90,7 @@ class Embedded extends Component {
gasLimit={ gasLimit }
id={ id }
isSending={ isSending }
isTest={ isTest }
netVersion={ netVersion }
key={ id }
onConfirm={ actions.startConfirmRequest }
onReject={ actions.startRejectRequest }
@@ -106,13 +106,13 @@ class Embedded extends Component {
}
function mapStateToProps (state) {
const { gasLimit, isTest } = state.nodeStatus;
const { gasLimit, netVersion } = state.nodeStatus;
const { actions, signer } = state;
return {
actions,
gasLimit,
isTest,
netVersion,
signer
};
}

View File

@@ -40,7 +40,7 @@ class RequestsPage extends Component {
startRejectRequest: PropTypes.func.isRequired
}).isRequired,
gasLimit: PropTypes.object.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
signer: PropTypes.shape({
pending: PropTypes.array.isRequired,
finished: PropTypes.array.isRequired
@@ -105,7 +105,7 @@ class RequestsPage extends Component {
}
renderPending = (data, index) => {
const { actions, gasLimit, isTest } = this.props;
const { actions, gasLimit, netVersion } = this.props;
const { date, id, isSending, payload } = data;
return (
@@ -116,7 +116,7 @@ class RequestsPage extends Component {
gasLimit={ gasLimit }
id={ id }
isSending={ isSending }
isTest={ isTest }
netVersion={ netVersion }
key={ id }
onConfirm={ actions.startConfirmRequest }
onReject={ actions.startRejectRequest }
@@ -128,13 +128,13 @@ class RequestsPage extends Component {
}
function mapStateToProps (state) {
const { gasLimit, isTest } = state.nodeStatus;
const { gasLimit, netVersion } = state.nodeStatus;
const { actions, signer } = state;
return {
actions,
gasLimit,
isTest,
netVersion,
signer
};
}

View File

@@ -36,7 +36,7 @@ class WalletConfirmations extends Component {
static propTypes = {
accounts: PropTypes.object.isRequired,
address: PropTypes.string.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
owners: PropTypes.array.isRequired,
require: PropTypes.object.isRequired,
confirmOperation: PropTypes.func.isRequired,
@@ -109,7 +109,7 @@ class WalletConfirmation extends Component {
accounts: PropTypes.object.isRequired,
confirmation: PropTypes.object.isRequired,
address: PropTypes.string.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
owners: PropTypes.array.isRequired,
require: PropTypes.object.isRequired,
confirmOperation: PropTypes.func.isRequired,
@@ -320,13 +320,14 @@ class WalletConfirmation extends Component {
}
renderTransactionRow (confirmation, className) {
const { address, isTest } = this.props;
const { address, netVersion } = this.props;
const { operation, transactionHash, blockNumber, value, to, data } = confirmation;
if (value && to && data) {
return (
<TxRow
className={ className }
netVersion={ netVersion }
key={ operation }
tx={ {
hash: transactionHash,
@@ -337,7 +338,6 @@ class WalletConfirmation extends Component {
input: bytesToHex(data)
} }
address={ address }
isTest={ isTest }
historic={ false }
/>
);

View File

@@ -25,7 +25,7 @@ import txListStyles from '~/ui/TxList/txList.css';
export default class WalletTransactions extends Component {
static propTypes = {
address: PropTypes.string.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
transactions: PropTypes.array
};
@@ -43,7 +43,7 @@ export default class WalletTransactions extends Component {
);
}
renderTransactions () {
const { address, isTest, transactions } = this.props;
const { address, netVersion, transactions } = this.props;
if (!transactions) {
return null;
@@ -62,6 +62,7 @@ export default class WalletTransactions extends Component {
return (
<TxRow
netVersion={ netVersion }
key={ `${transactionHash}_${index}` }
tx={ {
hash: transactionHash,
@@ -69,7 +70,6 @@ export default class WalletTransactions extends Component {
blockNumber, from, to, value
} }
address={ address }
isTest={ isTest }
/>
);
});

View File

@@ -40,20 +40,23 @@ import styles from './wallet.css';
class WalletContainer extends Component {
static propTypes = {
isTest: PropTypes.any
netVersion: PropTypes.string.isRequired
};
render () {
const { isTest, ...others } = this.props;
const { netVersion, ...others } = this.props;
if (isTest !== false && isTest !== true) {
if (netVersion === '0') {
return (
<Loading size={ 4 } />
);
}
return (
<Wallet isTest={ isTest } { ...others } />
<Wallet
netVersion={ netVersion }
{ ...others }
/>
);
}
}
@@ -67,7 +70,7 @@ class Wallet extends Component {
address: PropTypes.string.isRequired,
balance: nullableProptype(PropTypes.object.isRequired),
images: PropTypes.object.isRequired,
isTest: PropTypes.bool.isRequired,
netVersion: PropTypes.string.isRequired,
owned: PropTypes.bool.isRequired,
setVisibleAccounts: PropTypes.func.isRequired,
wallet: PropTypes.object.isRequired,
@@ -177,7 +180,7 @@ class Wallet extends Component {
}
renderDetails () {
const { address, isTest, wallet } = this.props;
const { address, netVersion, wallet } = this.props;
const { owners, require, confirmations, transactions } = wallet;
if (!owners || !require) {
@@ -190,19 +193,19 @@ class Wallet extends Component {
return [
<WalletConfirmations
netVersion={ netVersion }
key='confirmations'
owners={ owners }
require={ require }
confirmations={ confirmations }
isTest={ isTest }
address={ address }
/>,
<WalletTransactions
address={ address }
netVersion={ netVersion }
key='transactions'
transactions={ transactions }
address={ address }
isTest={ isTest }
/>
];
}
@@ -228,7 +231,7 @@ class Wallet extends Component {
<Button
key='delete'
icon={ <ActionDelete /> }
label='delete'
label='forget'
onClick={ this.showDeleteDialog } />
);
@@ -354,7 +357,7 @@ function mapStateToProps (_, initProps) {
const { address } = initProps.params;
return (state) => {
const { isTest } = state.nodeStatus;
const { netVersion } = state.nodeStatus;
const { accountsInfo = {}, accounts = {} } = state.personal;
const { balances } = state.balances;
const { images } = state;
@@ -372,7 +375,7 @@ function mapStateToProps (_, initProps) {
address,
balance,
images,
isTest,
netVersion,
owned,
wallet,
walletAccount

View File

@@ -62,7 +62,7 @@ export default class Web extends Component {
}
setUrl = (url) => {
url = url || store.get(LS_LAST_ADDRESS) || 'https://mkr.market';
url = url || store.get(LS_LAST_ADDRESS) || 'https://oasisdex.com';
if (!hasProtocol.test(url)) {
url = `https://${url}`;
}
@@ -150,4 +150,3 @@ export default class Web extends Component {
});
};
}

View File

@@ -17,6 +17,7 @@
//! Authority params deserialization.
use uint::Uint;
use hash::Address;
use super::ValidatorSet;
/// Authority params deserialization.
@@ -33,6 +34,8 @@ pub struct AuthorityRoundParams {
/// Block reward.
#[serde(rename="blockReward")]
pub block_reward: Option<Uint>,
/// Address of the registrar contract.
pub registrar: Option<Address>,
/// Starting step. Determined automatically if not specified.
/// To be used for testing only.
#[serde(rename="startStep")]

View File

@@ -16,7 +16,7 @@
//! Engine deserialization.
use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint};
use super::{Ethash, InstantSeal, BasicAuthority, AuthorityRound, Tendermint};
/// Engine deserialization.
#[derive(Debug, PartialEq, Deserialize)]
@@ -26,7 +26,7 @@ pub enum Engine {
Null,
/// Instantly sealing engine.
#[serde(rename="instantSeal")]
InstantSeal,
InstantSeal(InstantSeal),
/// Ethash engine.
Ethash(Ethash),
/// BasicAuthority engine.
@@ -55,12 +55,10 @@ mod tests {
assert_eq!(Engine::Null, deserialized);
let s = r#"{
"instantSeal": null
"instantSeal": { "params": {} }
}"#;
let deserialized: Engine = serde_json::from_str(s).unwrap();
assert_eq!(Engine::InstantSeal, deserialized);
let _deserialized: Engine = serde_json::from_str(s).unwrap();
let s = r#"{
"Ethash": {

View File

@@ -0,0 +1,50 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Instant params deserialization.
use hash::Address;
/// Instant params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
pub struct InstantSealParams {
/// Address of the registrar contract.
pub registrar: Option<Address>,
}
/// Instant engine deserialization.
#[derive(Debug, PartialEq, Deserialize)]
pub struct InstantSeal {
/// Instant Seal params.
pub params: InstantSealParams,
}
#[cfg(test)]
mod tests {
use serde_json;
use spec::instant_seal::InstantSeal;
#[test]
fn instant_seal_deserialization() {
let s = r#"{
"params": {
"registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
}
}"#;
let _deserialized: InstantSeal = serde_json::from_str(s).unwrap();
}
}

View File

@@ -26,6 +26,7 @@ pub mod engine;
pub mod state;
pub mod ethash;
pub mod validator_set;
pub mod instant_seal;
pub mod basic_authority;
pub mod authority_round;
pub mod tendermint;
@@ -40,6 +41,7 @@ pub use self::engine::Engine;
pub use self::state::State;
pub use self::ethash::{Ethash, EthashParams};
pub use self::validator_set::ValidatorSet;
pub use self::instant_seal::{InstantSeal, InstantSealParams};
pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams};
pub use self::authority_round::{AuthorityRound, AuthorityRoundParams};
pub use self::tendermint::{Tendermint, TendermintParams};

View File

@@ -17,6 +17,7 @@
//! Tendermint params deserialization.
use uint::Uint;
use hash::Address;
use super::ValidatorSet;
/// Tendermint params deserialization.
@@ -42,6 +43,8 @@ pub struct TendermintParams {
/// Block reward.
#[serde(rename="blockReward")]
pub block_reward: Option<Uint>,
/// Address of the registrar contract.
pub registrar: Option<Address>,
}
/// Tendermint engine deserialization.

View File

@@ -578,7 +578,7 @@
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>VERSION</key>
<string>1.5.3</string>
<string>1.5.9</string>
</dict>
<key>UUID</key>
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>

View File

@@ -10,7 +10,7 @@
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
!define VERSIONMAJOR 1
!define VERSIONMINOR 5
!define VERSIONBUILD 3
!define VERSIONBUILD 9
!define ARGS "--warp"
!define FIRST_START_ARGS "ui --warp --mode=passive"

View File

@@ -238,7 +238,7 @@ usage! {
or |c: &Config| otry!(c.footprint).tracing.clone(),
flag_pruning: String = "auto",
or |c: &Config| otry!(c.footprint).pruning.clone(),
flag_pruning_history: u64 = 1200u64,
flag_pruning_history: u64 = 64u64,
or |c: &Config| otry!(c.footprint).pruning_history.clone(),
flag_cache_size_db: u32 = 64u32,
or |c: &Config| otry!(c.footprint).cache_size_db.clone(),

View File

@@ -59,7 +59,7 @@ Operating Options:
--chain CHAIN Specify the blockchain type. CHAIN may be either a
JSON chain specification file or olympic, frontier,
homestead, mainnet, morden, ropsten, classic, expanse,
testnet or dev (default: {flag_chain}).
testnet, kovan or dev (default: {flag_chain}).
-d --base-path PATH Specify the base data storage path.
(default: {flag_base_path}).
--db-path PATH Specify the database directory path
@@ -335,8 +335,7 @@ Legacy Options:
to be the same as Geth's. Overrides the --ipc-path
and --ipcpath options. Alters RPCs to reflect Geth
bugs. Includes the personal_ RPC by default.
--testnet Geth-compatible testnet mode. Equivalent to --chain
testnet --keys-path $HOME/parity/testnet-keys.
--testnet Testnet mode. Equivalent to --chain testnet.
Overrides the --keys-path option.
--import-geth-keys Attempt to import keys from Geth client.
--datadir PATH Equivalent to --base-path PATH.

View File

@@ -33,7 +33,7 @@ use ethcore_rpc::NetworkSettings;
use cache::CacheConfig;
use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_for_db,
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy};
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras};
use params::{SpecType, ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras};
use ethcore_logger::Config as LogConfig;
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
use dapps::Configuration as DappsConfiguration;
@@ -102,7 +102,6 @@ impl Configuration {
let vm_type = self.vm_type()?;
let mode = match self.args.flag_mode.as_ref() { "last" => None, mode => Some(to_mode(&mode, self.args.flag_mode_timeout, self.args.flag_mode_alarm)?), };
let update_policy = self.update_policy()?;
let miner_options = self.miner_options()?;
let logger_config = self.logger_config();
let http_conf = self.http_config()?;
let ipc_conf = self.ipc_config()?;
@@ -307,6 +306,12 @@ impl Configuration {
let verifier_settings = self.verifier_settings();
// Special presets are present for the dev chain.
let (gas_pricer, miner_options) = match spec {
SpecType::Dev => (GasPricerConfig::Fixed(0.into()), self.miner_options(0)?),
_ => (self.gas_pricer_config()?, self.miner_options(self.args.flag_reseal_min_period)?),
};
let run_cmd = RunCmd {
cache_config: cache_config,
dirs: dirs,
@@ -321,7 +326,7 @@ impl Configuration {
net_conf: net_conf,
network_id: network_id,
acc_conf: self.accounts_config()?,
gas_pricer: self.gas_pricer_config()?,
gas_pricer: gas_pricer,
miner_extras: self.miner_extras()?,
update_policy: update_policy,
mode: mode,
@@ -412,7 +417,7 @@ impl Configuration {
fn chain(&self) -> String {
if self.args.flag_testnet {
"ropsten".to_owned()
"testnet".to_owned()
} else {
self.args.flag_chain.clone()
}
@@ -459,7 +464,7 @@ impl Configuration {
Ok(cfg)
}
fn miner_options(&self) -> Result<MinerOptions, String> {
fn miner_options(&self, reseal_min_period: u64) -> Result<MinerOptions, String> {
let reseal = self.args.flag_reseal_on_txs.parse::<ResealPolicy>()?;
let options = MinerOptions {
@@ -475,7 +480,7 @@ impl Configuration {
tx_queue_gas_limit: to_gas_limit(&self.args.flag_tx_queue_gas)?,
tx_queue_strategy: to_queue_strategy(&self.args.flag_tx_queue_strategy)?,
pending_set: to_pending_set(&self.args.flag_relay_set)?,
reseal_min_period: Duration::from_millis(self.args.flag_reseal_min_period),
reseal_min_period: Duration::from_millis(reseal_min_period),
work_queue_size: self.args.flag_work_queue_size,
enable_resubmission: !self.args.flag_remove_solved,
tx_queue_banning: match self.args.flag_tx_time_limit {
@@ -759,8 +764,8 @@ impl Configuration {
let dapps_path = replace_home(&data_path, &self.args.flag_dapps_path);
let ui_path = replace_home(&data_path, &self.args.flag_ui_path);
if self.args.flag_geth && !cfg!(windows) {
let geth_root = if self.args.flag_testnet { path::ethereum::test() } else { path::ethereum::default() };
if self.args.flag_geth && !cfg!(windows) {
let geth_root = if self.chain() == "testnet".to_owned() { path::ethereum::test() } else { path::ethereum::default() };
::std::fs::create_dir_all(geth_root.as_path()).unwrap_or_else(
|e| warn!("Failed to create '{}' for geth mode: {}", &geth_root.to_str().unwrap(), e));
}
@@ -943,7 +948,7 @@ mod tests {
file_path: Some("blockchain.json".into()),
format: Default::default(),
pruning: Default::default(),
pruning_history: 1200,
pruning_history: 64,
compaction: Default::default(),
wal: true,
tracing: Default::default(),
@@ -965,7 +970,7 @@ mod tests {
dirs: Default::default(),
file_path: Some("blockchain.json".into()),
pruning: Default::default(),
pruning_history: 1200,
pruning_history: 64,
format: Default::default(),
compaction: Default::default(),
wal: true,
@@ -987,7 +992,7 @@ mod tests {
dirs: Default::default(),
file_path: Some("state.json".into()),
pruning: Default::default(),
pruning_history: 1200,
pruning_history: 64,
format: Default::default(),
compaction: Default::default(),
wal: true,
@@ -1011,7 +1016,7 @@ mod tests {
dirs: Default::default(),
file_path: Some("blockchain.json".into()),
pruning: Default::default(),
pruning_history: 1200,
pruning_history: 64,
format: Some(DataFormat::Hex),
compaction: Default::default(),
wal: true,
@@ -1046,7 +1051,7 @@ mod tests {
dirs: Default::default(),
spec: Default::default(),
pruning: Default::default(),
pruning_history: 1200,
pruning_history: 64,
daemon: None,
logger_config: Default::default(),
miner_options: Default::default(),
@@ -1093,13 +1098,14 @@ mod tests {
let conf3 = parse(&["parity", "--tx-queue-strategy", "gas"]);
// then
assert_eq!(conf0.miner_options().unwrap(), mining_options);
let min_period = conf0.args.flag_reseal_min_period;
assert_eq!(conf0.miner_options(min_period).unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasFactorAndGasPrice;
assert_eq!(conf1.miner_options().unwrap(), mining_options);
assert_eq!(conf1.miner_options(min_period).unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasPriceOnly;
assert_eq!(conf2.miner_options().unwrap(), mining_options);
assert_eq!(conf2.miner_options(min_period).unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasAndGasPrice;
assert_eq!(conf3.miner_options().unwrap(), mining_options);
assert_eq!(conf3.miner_options(min_period).unwrap(), mining_options);
}
#[test]
@@ -1127,7 +1133,7 @@ mod tests {
// then
assert_eq!(conf.network_settings(), NetworkSettings {
name: "testname".to_owned(),
chain: "ropsten".to_owned(),
chain: "testnet".to_owned(),
network_port: 30303,
rpc_enabled: true,
rpc_interface: "local".to_owned(),
@@ -1291,4 +1297,17 @@ mod tests {
let conf = Configuration::parse(&args).unwrap();
assert!(conf.init_reserved_nodes().is_ok());
}
#[test]
fn test_dev_chain() {
let args = vec!["parity", "--chain", "dev"];
let conf = parse(&args);
match conf.into_command().unwrap().cmd {
Cmd::Run(c) => {
assert_eq!(c.gas_pricer, GasPricerConfig::Fixed(0.into()));
assert_eq!(c.miner_options.reseal_min_period, Duration::from_millis(0));
},
_ => panic!("Should be Cmd::Run"),
}
}
}

View File

@@ -120,7 +120,7 @@ mod stratum;
use std::{process, env};
use std::collections::HashMap;
use std::io::{self as stdio, BufReader, Read, Write};
use std::fs::File;
use std::fs::{metadata, File};
use std::path::PathBuf;
use util::sha3::sha3;
use cli::Args;
@@ -290,8 +290,19 @@ fn main() {
let latest_exe = latest_exe_path();
let have_update = latest_exe.as_ref().map_or(false, |p| p.exists());
let is_non_updated_current = exe.as_ref().map_or(false, |exe| latest_exe.as_ref().map_or(false, |lexe| exe.canonicalize().ok() != lexe.canonicalize().ok()));
trace_main!("Starting... (have-update: {}, non-updated-current: {})", have_update, is_non_updated_current);
let exit_code = if have_update && is_non_updated_current {
let update_is_newer = match (
latest_exe.as_ref()
.and_then(|p| metadata(p.as_path()).ok())
.and_then(|m| m.modified().ok()),
exe.as_ref()
.and_then(|p| metadata(p.as_path()).ok())
.and_then(|m| m.modified().ok())
) {
(Some(latest_exe_time), Some(this_exe_time)) if latest_exe_time > this_exe_time => true,
_ => false,
};
trace_main!("Starting... (have-update: {}, non-updated-current: {})", have_update, is_non_updated_current); trace_main!("Starting... (have-update: {}, non-updated-current: {})", have_update, is_non_updated_current);
let exit_code = if have_update && is_non_updated_current && update_is_newer {
trace_main!("Attempting to run latest update ({})...", latest_exe.as_ref().expect("guarded by have_update; latest_exe must exist for have_update; qed").display());
run_parity().unwrap_or_else(|| { trace_main!("Falling back to local..."); main_direct(true) })
} else {

View File

@@ -26,9 +26,10 @@ use user_defaults::UserDefaults;
#[derive(Debug, PartialEq)]
pub enum SpecType {
Mainnet,
Foundation,
Morden,
Ropsten,
Kovan,
Olympic,
Classic,
Expanse,
@@ -38,7 +39,7 @@ pub enum SpecType {
impl Default for SpecType {
fn default() -> Self {
SpecType::Mainnet
SpecType::Foundation
}
}
@@ -47,10 +48,11 @@ impl str::FromStr for SpecType {
fn from_str(s: &str) -> Result<Self, Self::Err> {
let spec = match s {
"frontier" | "homestead" | "mainnet" => SpecType::Mainnet,
"foundation" | "frontier" | "homestead" | "mainnet" => SpecType::Foundation,
"frontier-dogmatic" | "homestead-dogmatic" | "classic" => SpecType::Classic,
"morden" | "classic-testnet" => SpecType::Morden,
"ropsten" | "testnet" => SpecType::Ropsten,
"ropsten" => SpecType::Ropsten,
"kovan" | "testnet" => SpecType::Kovan,
"olympic" => SpecType::Olympic,
"expanse" => SpecType::Expanse,
"dev" => SpecType::Dev,
@@ -63,12 +65,13 @@ impl str::FromStr for SpecType {
impl fmt::Display for SpecType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
SpecType::Mainnet => "homestead",
SpecType::Foundation => "foundation",
SpecType::Morden => "morden",
SpecType::Ropsten => "ropsten",
SpecType::Olympic => "olympic",
SpecType::Classic => "classic",
SpecType::Expanse => "expanse",
SpecType::Kovan => "kovan",
SpecType::Dev => "dev",
SpecType::Custom(ref custom) => custom,
})
@@ -78,12 +81,13 @@ impl fmt::Display for SpecType {
impl SpecType {
pub fn spec(&self) -> Result<Spec, String> {
match *self {
SpecType::Mainnet => Ok(ethereum::new_frontier()),
SpecType::Foundation => Ok(ethereum::new_foundation()),
SpecType::Morden => Ok(ethereum::new_morden()),
SpecType::Ropsten => Ok(ethereum::new_ropsten()),
SpecType::Olympic => Ok(ethereum::new_olympic()),
SpecType::Classic => Ok(ethereum::new_classic()),
SpecType::Expanse => Ok(ethereum::new_expanse()),
SpecType::Kovan => Ok(ethereum::new_kovan()),
SpecType::Dev => Ok(Spec::new_instant()),
SpecType::Custom(ref filename) => {
let file = fs::File::open(filename).map_err(|_| "Could not load specification file.")?;
@@ -315,10 +319,12 @@ mod tests {
#[test]
fn test_spec_type_parsing() {
assert_eq!(SpecType::Mainnet, "frontier".parse().unwrap());
assert_eq!(SpecType::Mainnet, "homestead".parse().unwrap());
assert_eq!(SpecType::Mainnet, "mainnet".parse().unwrap());
assert_eq!(SpecType::Ropsten, "testnet".parse().unwrap());
assert_eq!(SpecType::Foundation, "frontier".parse().unwrap());
assert_eq!(SpecType::Foundation, "homestead".parse().unwrap());
assert_eq!(SpecType::Foundation, "mainnet".parse().unwrap());
assert_eq!(SpecType::Foundation, "foundation".parse().unwrap());
assert_eq!(SpecType::Kovan, "testnet".parse().unwrap());
assert_eq!(SpecType::Kovan, "kovan".parse().unwrap());
assert_eq!(SpecType::Morden, "morden".parse().unwrap());
assert_eq!(SpecType::Ropsten, "ropsten".parse().unwrap());
assert_eq!(SpecType::Olympic, "olympic".parse().unwrap());
@@ -328,17 +334,18 @@ mod tests {
#[test]
fn test_spec_type_default() {
assert_eq!(SpecType::Mainnet, SpecType::default());
assert_eq!(SpecType::Foundation, SpecType::default());
}
#[test]
fn test_spec_type_display() {
assert_eq!(format!("{}", SpecType::Mainnet), "homestead");
assert_eq!(format!("{}", SpecType::Foundation), "foundation");
assert_eq!(format!("{}", SpecType::Ropsten), "ropsten");
assert_eq!(format!("{}", SpecType::Morden), "morden");
assert_eq!(format!("{}", SpecType::Olympic), "olympic");
assert_eq!(format!("{}", SpecType::Classic), "classic");
assert_eq!(format!("{}", SpecType::Expanse), "expanse");
assert_eq!(format!("{}", SpecType::Kovan), "kovan");
assert_eq!(format!("{}", SpecType::Dev), "dev");
assert_eq!(format!("{}", SpecType::Custom("foo/bar".into())), "foo/bar");
}

View File

@@ -41,11 +41,11 @@ ${convertContract(name, json, prefs)}
function convertContract(name, json, prefs) {
return `${prefs._pub ? "pub " : ""}struct ${name} {
contract: ethabi::Contract,
address: util::Address,
pub address: util::Address,
${prefs._explicit_do_call ? "" : `do_call: Box<Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send${prefs._sync ? " + Sync " : ""}+ 'static>,`}
}
impl ${name} {
pub fn new${prefs._explicit_do_call ? "" : "<F>"}(address: util::Address${prefs._explicit_do_call ? "" : `", do_call: F"`}) -> Self
pub fn new${prefs._explicit_do_call ? "" : "<F>"}(address: util::Address${prefs._explicit_do_call ? "" : `, do_call: F`}) -> Self
${prefs._explicit_do_call ? "" : `where F: Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send ${prefs._sync ? "+ Sync " : ""}+ 'static`} {
${name} {
contract: ethabi::Contract::new(ethabi::Interface::load(b"${JSON.stringify(json.filter(a => a.type == 'function')).replaceAll('"', '\\"')}").expect("JSON is autogenerated; qed")),
@@ -233,19 +233,23 @@ function convertFunction(json, _prefs) {
let prefs = {"_pub": true, "_": {"_client": {"string": true}, "_platform": {"string": true}}, "_sync": true};
// default contract json ABI
let jsonabi = [{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}];
// default name
let name = 'Contract';
// parse command line options
for (let i = 1; i < process.argv.length; ++i) {
let arg = process.argv[i];
if (arg.indexOf("--jsonabi") == 0) {
if (arg.indexOf("--jsonabi=") == 0) {
jsonabi = arg.slice(10);
if (fs.existsSync(jsonabi)) {
jsonabi = JSON.parse(fs.readFileSync(jsonabi).toString());
}
} else if (arg.indexOf("--explicit-do-call") == 0) {
prefs._explicit_do_call = true;
} else if (arg.indexOf("--name=") == 0) {
name = arg.slice(7);
}
}
let out = makeContractFile("Contract", jsonabi, prefs);
let out = makeContractFile(name, jsonabi, prefs);
console.log(`${out}`);

4
scripts/docker-build.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
cd docker/hub
docker build --build-arg BUILD_TAG=$1 --no-cache=true --tag ethcore/parity:$1 .
docker push ethcore/parity:$1

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