Compare commits

...

36 Commits

Author SHA1 Message Date
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
arkpar
82e33fa033 Merge branch 'beta' of github.com:ethcore/parity into beta 2017-02-20 17:39:24 +01:00
arkpar
fa8eb22e79 Backported mac installer fix 2017-02-20 17:38:58 +01:00
Denis S. Soldatov aka General-Beck
55b51890dd [ci-skip] backport Dockerfile for hub 2017-02-20 20:08:07 +04:00
GitLab Build Bot
0f99b1e123 js-precompiled 20170220-130332 2017-02-20 15:18:20 +01:00
Arkadiy Paronyan
51e4c82337 v1.5.3 (#4611) 2017-02-20 13:48:38 +01:00
Jaco Greeff
7df702494d Handle invalid ABI retrieved from address_book gracefully (#4606) (#4610)
* Handle invalid ABI gracefully

* Also include failed abi in log
2017-02-20 13:48:23 +01:00
Arkadiy Paronyan
b5219bc723 Backporting to beta (#4602)
* Static link for snappy

* added 3 warpnodes for ropsten (#4289)

* added 3 warpnodes for ropsten

* Fixed indentation
2017-02-19 20:55:52 +01:00
Arkadiy Paronyan
27765a71dd Validate transaction before adding to the queue (#4600) 2017-02-19 17:55:55 +01:00
GitLab Build Bot
a1b9f03121 [ci skip] js-precompiled 20170216-173539 2017-02-16 17:42:25 +00:00
GitLab Build Bot
1c40421982 [ci skip] js-precompiled 20170216-171113 2017-02-16 17:18:45 +00:00
Tomasz Drwięga
07324795f1 Beta backports (#4569)
* Fixing evmbin compilation and added standard build. (#4561)

* Alias for personal_sendTransaction (#4554)

* Fix console dapp (#4544)

* Fixing linting issues. Better support for console as secure app

* Fixing linting issues

* Fix no data sent in TxQueue dapp (#4502)

* Fix wrong PropType req for Embedded Signer

* Fix wrong data for tx #4499
2017-02-16 17:46:25 +01:00
Jaco Greeff
19520442c1 Explicitly set seconds to 0 from selector (#4559) (#4571)
* Explicitly set seconds/milli to 0

* Use condition time & block setters consistently

* Fix failing test

* test for 0 ms & sec

* It cannot hurt, clone date before setting

* Prettier date test constants (OCD)
2017-02-16 17:46:18 +01:00
Denis S. Soldatov aka General-Beck
e0c5baece0 armv6 build -> only triggers
[ci-skip]
2017-02-16 20:45:27 +04:00
Nikolay Volf
f4f7b83d1f replace expect with an error (#4542) 2017-02-15 19:03:36 +01:00
GitLab Build Bot
30d7872226 [ci skip] js-precompiled 20170215-145227 2017-02-15 14:56:17 +00:00
Jaco Greeff
4d4821c577 [beta] Skip OOG check for simple transfers #4558 (#4560)
* Skip OOG check for simple transfers #4558

* Fix failing test
2017-02-15 15:45:52 +01:00
114 changed files with 1853 additions and 986 deletions

View File

@@ -290,7 +290,7 @@ linux-armv6:
# - beta
# - tags
# - stable
# - triggers
- triggers
script:
- export CC=arm-linux-gnueabi-gcc
- export CXX=arm-linux-gnueabi-g++
@@ -379,6 +379,7 @@ darwin:
export PLATFORM=x86_64-apple-darwin
cargo build -j 8 --features final --release #$CARGOFLAGS
cargo build -j 8 --features final --release -p ethstore #$CARGOFLAGS
cargo build -j 8 --features final --release -p evmbin #$CARGOFLAGS
rm -rf parity.md5
md5sum target/release/parity > parity.md5
export SHA3=$(target/release/parity tools hash target/release/parity)
@@ -470,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:
@@ -500,7 +501,7 @@ test-windows:
- git submodule update --init --recursive
script:
- set RUST_BACKTRACE=1
- echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release
- echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p evmbin -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release
tags:
- rust-windows
allow_failure: true

53
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
[root]
name = "parity"
version = "1.5.2"
version = "1.5.6"
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,8 +23,9 @@ dependencies = [
"ethcore-rpc 1.5.0",
"ethcore-signer 1.5.0",
"ethcore-stratum 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"ethsync 1.5.0",
"evmbin 1.5.0",
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -372,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.2",
"ethcore-util 1.5.6",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
@@ -420,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.2",
"ethcore-util 1.5.6",
"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)",
@@ -468,7 +469,7 @@ name = "ethcore-ipc"
version = "1.5.0"
dependencies = [
"ethcore-devtools 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",
]
@@ -515,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.2",
"ethcore-util 1.5.6",
"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)",
@@ -530,7 +531,7 @@ dependencies = [
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-network 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",
@@ -542,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.2",
"ethcore-util 1.5.6",
"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)",
@@ -558,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.2",
"ethcore-util 1.5.6",
"ethcrypto 0.1.0",
"ethkey 0.2.0",
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -585,7 +586,7 @@ dependencies = [
"ethcore-devtools 1.5.0",
"ethcore-io 1.5.0",
"ethcore-ipc 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"ethcrypto 0.1.0",
"ethjson 0.1.0",
"ethkey 0.2.0",
@@ -620,7 +621,7 @@ dependencies = [
"ethcore-devtools 1.5.0",
"ethcore-io 1.5.0",
"ethcore-rpc 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",
@@ -639,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.2",
"ethcore-util 1.5.6",
"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)",
@@ -650,7 +651,7 @@ dependencies = [
[[package]]
name = "ethcore-util"
version = "1.5.2"
version = "1.5.6"
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)",
@@ -699,7 +700,7 @@ dependencies = [
name = "ethjson"
version = "0.1.0"
dependencies = [
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",
@@ -755,7 +756,7 @@ dependencies = [
"ethcore-ipc-nano 1.5.0",
"ethcore-light 1.5.0",
"ethcore-network 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",
@@ -766,6 +767,16 @@ dependencies = [
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "evmbin"
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.6",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "evmjit"
version = "1.5.0"
@@ -964,7 +975,7 @@ version = "1.5.0"
dependencies = [
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",
]
@@ -1489,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.2",
"ethcore-util 1.5.6",
"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)",
@@ -1514,7 +1525,7 @@ version = "1.4.0"
dependencies = [
"ethcore-rpc 1.5.0",
"ethcore-signer 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",
@@ -1547,7 +1558,7 @@ dependencies = [
[[package]]
name = "parity-ui-precompiled"
version = "1.4.0"
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#3d9331084db85d1584040add67752cc5d2d3d059"
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#6de2feb98a0902dc0b6845981b54036d30bac7dd"
dependencies = [
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1560,7 +1571,7 @@ dependencies = [
"ethcore 1.5.0",
"ethcore-ipc 1.5.0",
"ethcore-ipc-codegen 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"ethsync 1.5.0",
"ipc-common-types 1.5.0",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1840,7 +1851,7 @@ version = "1.4.0"
dependencies = [
"ethcore-bigint 0.1.2",
"ethcore-rpc 1.5.0",
"ethcore-util 1.5.2",
"ethcore-util 1.5.6",
"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)",

View File

@@ -1,7 +1,7 @@
[package]
description = "Parity Ethereum client"
name = "parity"
version = "1.5.2"
version = "1.5.6"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"
@@ -47,6 +47,7 @@ ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
ethcore-logger = { path = "logger" }
ethcore-stratum = { path = "stratum" }
ethcore-dapps = { path = "dapps", optional = true }
evmbin = { path = "evmbin" }
rpc-cli = { path = "rpc_cli" }
parity-rpc-client = { path = "rpc_client" }
ethcore-light = { path = "ethcore/light" }

View File

@@ -312,7 +312,7 @@ impl Server {
let special = Arc::new({
let mut special = HashMap::new();
special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, panic_handler.clone()));
special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, cors_domains.clone(), panic_handler.clone()));
special.insert(router::SpecialEndpoint::Utils, apps::utils());
special.insert(
router::SpecialEndpoint::Api,

View File

@@ -21,11 +21,15 @@ use jsonrpc_core::{IoHandler, ResponseHandler, Request, Response};
use jsonrpc_http_server::{ServerHandler, PanicHandler, AccessControlAllowOrigin, RpcHandler};
use endpoint::{Endpoint, EndpointPath, Handler};
pub fn rpc(handler: Arc<IoHandler>, panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>) -> Box<Endpoint> {
pub fn rpc(
handler: Arc<IoHandler>,
cors_domains: Vec<String>,
panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>,
) -> Box<Endpoint> {
Box::new(RpcEndpoint {
handler: Arc::new(RpcMiddleware::new(handler)),
panic_handler: panic_handler,
cors_domain: None,
cors_domain: Some(cors_domains.into_iter().map(AccessControlAllowOrigin::Value).collect()),
// NOTE [ToDr] We don't need to do any hosts validation here. It's already done in router.
allowed_hosts: None,
})

View File

@@ -1,5 +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 \
@@ -19,48 +24,60 @@ RUN apt-get update && \
file \
openssl \
libssl-dev \
libudev-dev \
pkg-config \
dpkg-dev \
# evmjit dependencies
zlib1g-dev \
libedit-dev
# cmake and llvm ppas. then update ppas
RUN add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
libedit-dev \
libudev-dev &&\
# cmake and llvm ppa's. then update ppa's
add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
apt-get update && \
apt-get install -y --force-yes cmake llvm-3.7-dev
apt-get install -y --force-yes cmake llvm-3.7-dev && \
# install evmjit
RUN git clone https://github.com/debris/evmjit && \
git clone https://github.com/debris/evmjit && \
cd evmjit && \
mkdir build && cd build && \
cmake .. && make && make install && cd
cmake .. && make && make install && cd && \
# install rustup
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
curl https://sh.rustup.rs -sSf | sh -s -- -y && \
# rustup directory
ENV PATH /root/.cargo/bin:$PATH
PATH=/root/.cargo/bin:$PATH && \
# show backtraces
ENV RUST_BACKTRACE 1
# show tools
RUN rustc -vV && \
cargo -V && \
gcc -v &&\
g++ -v
RUST_BACKTRACE=1 && \
# build parity
RUN git clone https://github.com/ethcore/parity && \
cd /build&&git clone https://github.com/ethcore/parity && \
cd parity && \
git pull && \
cargo build --release --features final && \
ls /build/parity/target/release/parity && \
strip /build/parity/target/release/parity
RUN file /build/parity/target/release/parity
git pull&& \
git checkout $BUILD_TAG && \
cargo build --verbose --release --features final && \
#ls /build/parity/target/release/parity && \
strip /build/parity/target/release/parity && \
file /build/parity/target/release/parity&&mkdir -p /parity&& cp /build/parity/target/release/parity /parity&&\
#cleanup Docker image
rm -rf /root/.cargo&&rm -rf /root/.multirust&&rm -rf /root/.rustup&&rm -rf /build&&\
apt-get purge -y \
# make
build-essential \
# add-apt-repository
software-properties-common \
make \
curl \
wget \
git \
g++ \
gcc \
binutils \
file \
pkg-config \
dpkg-dev \
# evmjit dependencies
zlib1g-dev \
libedit-dev \
cmake llvm-3.7-dev&&\
rm -rf /var/lib/apt/lists/*
# setup ENTRYPOINT
EXPOSE 8080 8545 8180
ENTRYPOINT ["/build/parity/target/release/parity"]
ENTRYPOINT ["/parity/parity"]

View File

@@ -47,16 +47,17 @@
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
},
"nodes": [
"enode://08c7ee6a4f861ff0664a49532bcc86de1363acd608999d1b76609bb9bc278649906f069057630fd9493924a368b5d1dc9b8f8bf13ac26df72512f6d1fabd8c95@45.32.7.81:30303",
"enode://e809c4a2fec7daed400e5e28564e23693b23b2cc5a019b612505631bbe7b9ccf709c1796d2a3d29ef2b045f210caf51e3c4f5b6d3587d43ad5d6397526fa6179@174.112.32.157:30303",
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
"enode://7ff0a073bf2ee9e94fae86de914eca0c0266c0b7051f4592ff0e9820706a085919ea667459897cde4efe3f0465f608cf402bde861983ce6ae3f9185df371aea7@138.197.135.19:30303",
"enode://ffea3b01c000cdd89e1e9229fea3e80e95b646f9b2aa55071fc865e2f19543c9b06045cc2e69453e6b78100a119e66be1b5ad50b36f2ffd27293caa28efdd1b2@162.243.55.45: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://08c7ee6a4f861ff0664a49532bcc86de1363acd608999d1b76609bb9bc278649906f069057630fd9493924a368b5d1dc9b8f8bf13ac26df72512f6d1fabd8c95@45.32.7.81:30303",
"enode://921cf8e4c345fe8db913c53964f9cadc667644e7f20195a0b7d877bd689a5934e146ff2c2259f1bae6817b6585153a007ceb67d260b720fa3e6fc4350df25c7f@51.255.49.170:30303",
"enode://ffea3b01c000cdd89e1e9229fea3e80e95b646f9b2aa55071fc865e2f19543c9b06045cc2e69453e6b78100a119e66be1b5ad50b36f2ffd27293caa28efdd1b2@128.199.93.177:3030",
"enode://ffea3b01c000cdd89e1e9229fea3e80e95b646f9b2aa55071fc865e2f19543c9b06045cc2e69453e6b78100a119e66be1b5ad50b36f2ffd27293caa28efdd1b2@128.199.93.177:30303",
"enode://ca5ae4eca09ba6787e29cf6d86f7634d07aae6b9e6317a59aff675851c0bf445068173208cf8ef7f5cd783d8e29b85b2fa3fa358124cf0546823149724f9bde1@138.68.1.16:30303",
"enode://ee3da491ce6a155eb132708eb0e8d04b0637926ec0ae1b79e63fc97cb9fc3818f49250a0ae0d7f79ed62b66ec677f408c4e01741504dc7a051e274f1e803d454@91.121.65.179:40404",
"enode://48e063a6cf5f335b1ef2ed98126bf522cf254396f850c7d442fe2edbbc23398787e14cd4de7968a00175a82762de9cbe9e1407d8ccbcaeca5004d65f8398d759@159.203.255.59:30303"
],

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

@@ -44,7 +44,10 @@
},
"nodes": [
"enode://a22f0977ce02653bf95e38730106356342df48b5222e2c2a1a6f9ef34769bf593bae9ca0a888cf60839edd52efc1b6e393c63a57d76f4c4fe14e641f1f9e637e@128.199.55.137:30303",
"enode://012239fccf3ff1d92b036983a430cb6705c6528c96c0354413f8854802138e5135c084ab36e7c54efb621c46728df8c3a6f4c1db9bb48a1330efe3f82f2dd7a6@52.169.94.142:30303"
"enode://012239fccf3ff1d92b036983a430cb6705c6528c96c0354413f8854802138e5135c084ab36e7c54efb621c46728df8c3a6f4c1db9bb48a1330efe3f82f2dd7a6@52.169.94.142:30303",
"enode://1462682e4b7ba2258346d55e25e5b9d264b0db40cee12bdfba4e72b1d7050350ea954c006e9106dd96a128e6e0bd6dffb17eed51f9f99bf7f9cdadfeaf8da4ff@51.15.61.253:30303",
"enode://98fbb020c799ae39a828bd75dc2bd5d4721539faf317076b275f91182a5c8900b592e8abfdddceae674a7c3bb40ea00a6ca9ccb7805ab58c4b7b29c61c8f7239@51.15.62.44:30303",
"enode://d801dd4e3d15a8bf785931add164bd9c313e3f6b5749d9302b311f2b48064cba5c86c32b1302c27cd983fc89ae07d4d306dd1197610835b8782e95dfb1b3f9ea@51.15.43.255:30303"
],
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "0", "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<()>,
@@ -112,6 +116,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()?,
@@ -180,11 +185,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) {

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

@@ -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

@@ -594,6 +594,7 @@ impl Miner {
.map(|accounts| accounts.into_iter().collect::<HashSet<_>>());
let insertion_time = client.chain_info().best_block_number;
let best_header = client.best_block_header().decode();
transactions.into_iter()
.map(|tx| {
@@ -612,6 +613,8 @@ impl Miner {
// try to install service transaction checker before appending transactions
self.service_transaction_action.update_from_chain_client(client);
self.engine.verify_transaction_basic(&tx, &best_header)?;
let details_provider = TransactionDetailsProvider::new(client, &self.service_transaction_action);
match origin {
TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {

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

@@ -271,7 +271,9 @@ impl SimpleSecretStore for EthMultiStore {
// Remove from cache
let mut cache = self.cache.write();
let is_empty = {
let mut accounts = cache.get_mut(address).expect("Entry exists, because it was returned by `get`; qed");
let mut accounts = cache.get_mut(address)
.ok_or(Error::InvalidAccount)?;
if let Some(position) = accounts.iter().position(|acc| acc == &account) {
accounts.remove(position);
}

View File

@@ -1,7 +1,7 @@
[package]
name = "evm"
name = "evmbin"
description = "Parity's EVM implementation"
version = "0.1.0"
version = "1.5.0"
authors = ["Parity Technologies <admin@parity.io>"]
[lib]

View File

@@ -31,7 +31,7 @@ pub struct FakeExt {
impl Default for FakeExt {
fn default() -> Self {
FakeExt {
schedule: Schedule::new_homestead_gas_fix(),
schedule: Schedule::new_post_eip150(usize::max_value(), true, true, true),
store: HashMap::new(),
depth: 1,
}
@@ -51,8 +51,8 @@ impl Ext for FakeExt {
unimplemented!();
}
fn exists_and_not_null(&self, address: &Address) -> bool {
unimplemented!();
fn exists_and_not_null(&self, _address: &Address) -> bool {
unimplemented!();
}
fn origin_balance(&self) -> U256 {

View File

@@ -21,7 +21,6 @@
extern crate ethcore;
extern crate rustc_serialize;
extern crate docopt;
#[macro_use]
extern crate ethcore_util as util;
mod ext;

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

@@ -260,7 +260,7 @@ export class LocalTransaction extends BaseTransaction {
to: transaction.to,
nonce: transaction.nonce,
value: transaction.value,
data: transaction.data,
data: transaction.input,
gasPrice, gas
};

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;

File diff suppressed because one or more lines are too long

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

@@ -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

@@ -81,11 +81,11 @@ export default class GasPriceEditor {
switch (conditionType) {
case CONDITIONS.BLOCK:
this.condition = Object.assign({}, this.condition, { block: this.blockNumber || 1 });
this.setConditionBlockNumber(this.blockNumber || 1);
break;
case CONDITIONS.TIME:
this.condition = Object.assign({}, this.condition, { time: new Date() });
this.setConditionDateTime(new Date());
break;
case CONDITIONS.NONE:
@@ -103,7 +103,12 @@ export default class GasPriceEditor {
});
}
@action setConditionDateTime = (time) => {
@action setConditionDateTime = (_time) => {
const time = new Date(_time);
time.setMilliseconds(0); // ignored by/not passed to Parity
time.setSeconds(0); // current time selector doesn't allow seconds
this.condition = Object.assign({}, this.condition, { time });
}

View File

@@ -162,9 +162,17 @@ describe('ui/GasPriceEditor/Store', () => {
});
describe('setConditionDateTime', () => {
it('sets the datatime', () => {
store.setConditionDateTime('testingDateTime');
expect(store.condition.time).to.equal('testingDateTime');
const BASEDATE = '1973-06-11 07:52';
const ZEROTIME = new Date(BASEDATE).getTime();
it('sets the datetime', () => {
store.setConditionDateTime(new Date(`${BASEDATE}:00.000`));
expect(store.condition.time.getTime()).to.equal(ZEROTIME);
});
it('zeros both seconds and miliseconds', () => {
store.setConditionDateTime(new Date(`${BASEDATE}:12.345`));
expect(store.condition.time.getTime()).to.equal(ZEROTIME);
});
});

View File

@@ -55,9 +55,19 @@ export default class MethodDecodingStore {
}
loadFromAbi (_abi, contractAddress) {
const abi = new Abi(_abi);
let abi;
if (contractAddress && abi) {
try {
abi = new Abi(_abi);
} catch (error) {
console.warn('loadFromAbi', error, _abi);
}
if (!abi) {
return;
}
if (contractAddress) {
this._contractsAbi[contractAddress] = abi;
}

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

@@ -1,4 +1,4 @@
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
@@ -21,8 +21,10 @@ import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { txLink } from '~/3rdparty/etherscan/links';
import ShortenedHash from '../ShortenedHash';
import Warning from '~/ui/Warning';
import { DEFAULT_GAS } from '~/util/constants';
import ShortenedHash from '../ShortenedHash';
import styles from './txHash.css';
class TxHash extends Component {
@@ -32,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
}
@@ -43,8 +45,59 @@ class TxHash extends Component {
state = {
blockNumber: new BigNumber(0),
isRecipientContract: false,
subscriptionId: null,
transaction: null
transaction: null,
transactionReceipt: null
}
componentWillMount () {
this.fetchTransaction();
}
componentWillReceiveProps (nextProps) {
const prevHash = this.props.hash;
const nextHash = nextProps.hash;
if (prevHash !== nextHash) {
this.fetchTransaction(nextProps);
}
}
/**
* Get the sent transaction data
*/
fetchTransaction (props = this.props) {
const { hash } = props;
if (!hash) {
return;
}
this.context.api.eth
.getTransactionByHash(hash)
.then((transaction) => {
this.setState({ transaction });
return this.fetchRecipientCode(transaction);
});
}
fetchRecipientCode (transaction) {
if (!transaction || !transaction.to) {
return;
}
this.context.api.eth
.getCode(transaction.to)
.then((code) => {
const isRecipientContract = code && !/^(0x)?0*$/.test(code);
this.setState({ isRecipientContract });
})
.catch((error) => {
console.error('fetchRecipientCode', error);
});
}
componentDidMount () {
@@ -63,34 +116,68 @@ 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>
);
return (
<div>
{ this.renderWarning() }
<p>{
summary
? hashLink
: <FormattedMessage
id='ui.txHash.posted'
defaultMessage='The transaction has been posted to the network with a hash of {hashLink}'
values={ { hashLink } } />
values={ { hashLink } }
/>
}</p>
{ this.renderConfirmations() }
</div>
);
}
renderWarning () {
const { isRecipientContract, transaction, transactionReceipt } = this.state;
if (!(transactionReceipt && transactionReceipt.blockNumber && transactionReceipt.blockNumber.gt(0))) {
return null;
}
const { gas, input } = transaction;
const { gasUsed = new BigNumber(0) } = transactionReceipt;
const isOog = gasUsed.gte(gas);
// Skip OOG check if a simple transaction to a non-contract account
// @see: https://github.com/ethcore/parity/issues/4550
const skipOogCheck = gasUsed.eq(DEFAULT_GAS) && (!input || input === '0x') && !isRecipientContract;
if (!isOog || skipOogCheck) {
return null;
}
return (
<Warning
warning={
<FormattedMessage
id='ui.txHash.oog'
defaultMessage='The transaction might have gone out of gas. Try again with more gas.'
/>
}
/>
);
}
renderConfirmations () {
const { maxConfirmations } = this.props;
const { blockNumber, transaction } = this.state;
const { blockNumber, transactionReceipt } = this.state;
if (!(transaction && transaction.blockNumber && transaction.blockNumber.gt(0))) {
if (!(transactionReceipt && transactionReceipt.blockNumber && transactionReceipt.blockNumber.gt(0))) {
return (
<div className={ styles.confirm }>
<LinearProgress
@@ -101,16 +188,18 @@ class TxHash extends Component {
<div className={ styles.progressinfo }>
<FormattedMessage
id='ui.txHash.waiting'
defaultMessage='waiting for confirmations' />
defaultMessage='waiting for confirmations'
/>
</div>
</div>
);
}
const confirmations = blockNumber.minus(transaction.blockNumber).plus(1);
const confirmations = blockNumber.minus(transactionReceipt.blockNumber).plus(1);
const value = Math.min(confirmations.toNumber(), maxConfirmations);
let count = confirmations.toFormat(0);
if (confirmations.lte(maxConfirmations)) {
count = `${count}/${maxConfirmations}`;
}
@@ -123,7 +212,8 @@ class TxHash extends Component {
max={ maxConfirmations }
value={ value }
color='white'
mode='determinate' />
mode='determinate'
/>
<div className={ styles.progressinfo }>
<abbr title={ `block #${blockNumber.toFormat(0)}` }>
<FormattedMessage
@@ -132,7 +222,8 @@ class TxHash extends Component {
values={ {
count,
value
} } />
} }
/>
</abbr>
</div>
</div>
@@ -143,29 +234,32 @@ class TxHash extends Component {
const { api } = this.context;
const { hash } = this.props;
const nextState = { blockNumber };
if (error || !hash || /^(0x)?0*$/.test(hash)) {
return;
return this.setState(nextState);
}
return api.eth
.getTransactionReceipt(hash)
.then((transaction) => {
this.setState({
blockNumber,
transaction
});
.then((transactionReceipt) => {
nextState.transactionReceipt = transactionReceipt;
})
.catch((error) => {
console.warn('onBlockNumber', error);
this.setState({ blockNumber });
console.error('onBlockNumber', error);
})
.then(() => {
this.setState(nextState);
});
}
}
function mapStateToProps (state) {
const { isTest } = state.nodeStatus;
const { netVersion } = state.nodeStatus;
return { isTest };
return {
netVersion
};
}
export default connect(

View File

@@ -33,6 +33,7 @@ function createApi () {
blockNumber = new BigNumber(100);
api = {
eth: {
getTransactionByHash: sinon.stub().resolves({ gas: 21000 }),
getTransactionReceipt: (hash) => {
return Promise.resolve({
blockNumber: new BigNumber(100),
@@ -62,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

@@ -14,54 +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/>.
import parity from '~/jsonrpc/interfaces/parity';
import signer from '~/jsonrpc/interfaces/signer';
import trace from '~/jsonrpc/interfaces/trace';
export default function web3extensions (web3) {
const { Method, formatters } = web3._extend;
const { Method } = web3._extend;
// TODO [ToDr] Consider output/input formatters.
const methods = (object, name) => {
return Object.keys(object).map(method => {
return new Method({
name: method,
call: `${name}_{method}`,
params: object[method].params.length
});
});
};
return [{
property: 'personal',
methods: [
new Method({
name: 'sendTransaction',
call: 'personal_sendTransaction',
params: 2,
inputFormatter: [formatters.inputTransactionFormatter, null]
}),
new Method({
name: 'signerEnabled',
call: 'personal_signerEnabled',
params: 0,
inputFormatter: []
})
],
property: 'parity',
methods: methods(parity, 'parity'),
properties: []
}, {
property: 'ethcore',
methods: [
new Method({
name: 'getNetPeers',
call: 'ethcore_netPeers',
params: 0,
outputFormatter: x => x
}),
new Method({
name: 'getNetChain',
call: 'ethcore_netChain',
params: 0,
outputFormatter: x => x
}),
new Method({
name: 'gasPriceStatistics',
call: 'ethcore_gasPriceStatistics',
params: 0,
outputFormatter: a => a.map(web3.toBigNumber)
}),
new Method({
name: 'unsignedTransactionsCount',
call: 'ethcore_unsignedTransactionsCount',
params: 0,
inputFormatter: []
})
],
property: 'signer',
methods: methods(signer, 'signer'),
properties: []
}, {
property: 'trace',
methods: methods(trace, 'trace'),
properties: []
}];
}

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};

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