Merge branch 'master' into new-jsonrpc
This commit is contained in:
commit
44052e7d8d
@ -26,14 +26,14 @@ linux-stable:
|
||||
- cargo build -j $(nproc) --release -p ethstore
|
||||
- cargo build -j $(nproc) --release -p ethkey
|
||||
- strip target/release/parity
|
||||
- strip target/release/evm
|
||||
- strip target/release/parity-evm
|
||||
- strip target/release/ethstore
|
||||
- strip target/release/ethkey
|
||||
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||
- md5sum target/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh amd64
|
||||
- cp target/release/parity deb/usr/bin/parity
|
||||
- cp target/release/evm deb/usr/bin/evm
|
||||
- cp target/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
@ -55,9 +55,9 @@ linux-stable:
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
- target/release/parity/evmbin
|
||||
- target/release/parity/ethstore
|
||||
- target/release/parity/ethkey
|
||||
- target/release/parity-evm
|
||||
- target/release/ethstore
|
||||
- target/release/ethkey
|
||||
name: "stable-x86_64-unknown-linux-gnu_parity"
|
||||
linux-stable-debian:
|
||||
stage: build
|
||||
@ -73,14 +73,14 @@ linux-stable-debian:
|
||||
- cargo build -j $(nproc) --release -p ethstore
|
||||
- cargo build -j $(nproc) --release -p ethkey
|
||||
- strip target/release/parity
|
||||
- strip target/release/evm
|
||||
- strip target/release/parity-evm
|
||||
- strip target/release/ethstore
|
||||
- strip target/release/ethkey
|
||||
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||
- md5sum target/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh amd64
|
||||
- cp target/release/parity deb/usr/bin/parity
|
||||
- cp target/release/evm deb/usr/bin/evm
|
||||
- cp target/release/parity-evm deb/usr/bin/parity-evm
|
||||
- cp target/release/ethstore deb/usr/bin/ethstore
|
||||
- cp target/release/ethkey deb/usr/bin/ethkey
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
@ -506,15 +506,16 @@ docker-build:
|
||||
test-coverage:
|
||||
stage: test
|
||||
only:
|
||||
- coverage
|
||||
- master
|
||||
script:
|
||||
- git submodule update --init --recursive
|
||||
- rm -rf target/*
|
||||
- rm -rf js/.coverage
|
||||
- scripts/cov.sh
|
||||
- COVERAGE=$(grep -Po 'covered":.*?[^\\]"' target/kcov/index.json | grep "[0-9]*\.[0-9]" -o)
|
||||
- echo "Coverage:" $COVERAGE
|
||||
# - COVERAGE=$(grep -Po 'covered":.*?[^\\]"' target/cov/index.json | grep "[0-9]*\.[0-9]" -o)
|
||||
# - echo "Coverage:" $COVERAGE
|
||||
tags:
|
||||
- kcov
|
||||
allow_failure: true
|
||||
test-darwin:
|
||||
stage: test
|
||||
only:
|
||||
|
69
Cargo.lock
generated
69
Cargo.lock
generated
@ -31,7 +31,7 @@ dependencies = [
|
||||
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 7.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.7.0",
|
||||
"parity-ipfs-api 1.7.0",
|
||||
@ -44,6 +44,7 @@ dependencies = [
|
||||
"rpassword 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rpc-cli 1.4.0",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -356,7 +357,7 @@ version = "0.5.6"
|
||||
source = "git+https://github.com/ethcore/rust-secp256k1#98ad9b9ecae44a563efdd64273bcebc6b4ed81c6"
|
||||
dependencies = [
|
||||
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -414,7 +415,7 @@ dependencies = [
|
||||
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lru-cache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.1.0",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -892,10 +893,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.35"
|
||||
version = "0.3.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rayon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -942,7 +943,7 @@ name = "hidapi"
|
||||
version = "0.3.1"
|
||||
source = "git+https://github.com/ethcore/hidapi-rs#9a127c1dca7e327e4fdd428406a76c9f5ef48563"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1245,7 +1246,7 @@ name = "libusb-sys"
|
||||
version = "0.2.3"
|
||||
source = "git+https://github.com/ethcore/libusb-sys#c10b1180646c9dc3f23a9b6bb825abcd3b7487ce"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1309,7 +1310,7 @@ name = "miniz-sys"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1445,7 +1446,7 @@ name = "nanomsg-sys"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/ethcore/nanomsg.rs.git#c40fe442c9afaea5b38009a3d992ca044dcceb00"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1578,14 +1579,6 @@ name = "num-traits"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.2.0"
|
||||
@ -1768,7 +1761,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git#24514f56ade650f54b97c2cff4e27d798b274e41"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git#547a5352d779bc7821a7a2ec14c6d480833aeabb"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1939,11 +1932,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "0.4.2"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2011,7 +2005,7 @@ name = "rocksdb-sys"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/ethcore/rust-rocksdb#64c63ccbe1f62c2e2b39262486f9ba813793af58"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2066,7 +2060,7 @@ name = "rust-crypto"
|
||||
version = "0.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2086,6 +2080,14 @@ dependencies = [
|
||||
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.1"
|
||||
@ -2155,6 +2157,14 @@ dependencies = [
|
||||
"semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.6.1"
|
||||
@ -2164,6 +2174,11 @@ dependencies = [
|
||||
"regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.9.6"
|
||||
@ -2218,7 +2233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "sha3"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2714,7 +2729,7 @@ dependencies = [
|
||||
"checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb"
|
||||
"checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d"
|
||||
"checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82"
|
||||
"checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312"
|
||||
"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
|
||||
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1"
|
||||
@ -2783,7 +2798,6 @@ dependencies = [
|
||||
"checksum num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c"
|
||||
"checksum num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "48cdcc9ff4ae2a8296805ac15af88b3d88ce62128ded0cb74ffb63a587502a84"
|
||||
"checksum num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "51eab148f171aefad295f8cece636fc488b9b392ef544da31ea4b8ef6b9e9c39"
|
||||
"checksum num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "51fedae97a05f7353612fe017ab705a37e6db8f4d67c5c6fe739a9e70d6eed09"
|
||||
"checksum num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55aabf4e2d6271a2e4e4c0f2ea1f5b07cc589cc1a9e9213013b54a76678ca4f3"
|
||||
"checksum number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "084d05f4bf60621a9ac9bde941a410df548f4de9545f06e5ee9d3aef4b97cd77"
|
||||
"checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1"
|
||||
@ -2814,7 +2828,7 @@ dependencies = [
|
||||
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
|
||||
"checksum quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6732e32663c9c271bfc7c1823486b471f18c47a2dbf87c066897b7b51afc83be"
|
||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||
"checksum rayon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "655df67c314c30fa3055a365eae276eb88aa4f3413a352a1ab32c1320eda41ea"
|
||||
"checksum rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50c575b58c2b109e2fbc181820cbe177474f35610ff9e357dc75f6bac854ffbf"
|
||||
"checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29"
|
||||
"checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9"
|
||||
"checksum reqwest 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bef9ed8fdfcc30947d6b774938dc0c3f369a474efe440df2c7f278180b2d2e6"
|
||||
@ -2827,6 +2841,7 @@ dependencies = [
|
||||
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
|
||||
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
||||
"checksum rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e114e275f7c9b5d50bb52b28f9aac1921209f02aa6077c8b255e21eefaf8ffa"
|
||||
"checksum schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "167852e03fcd0029c3ddebb5afb0715b2996f6e262b2c2aceaa7cd84edd4b158"
|
||||
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
|
||||
"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc"
|
||||
@ -2835,7 +2850,9 @@ dependencies = [
|
||||
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
|
||||
"checksum semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2ff60ecdb19c255841c066cbfa5f8c2a4ada1eb3ae47c77ab6667128da71f5"
|
||||
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
||||
"checksum semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e88e43a5a74dd2a11707f9c21dfd4a423c66bd871df813227bb0a3e78f3a1ae9"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0ae9a3c8b07c09dbe43022486d55a18c629a0618d2241e49829aaef9b6d862f9"
|
||||
"checksum serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3172bf2940b975c0e4f6ab42a511c0a4407d4f46ccef87a9d3615db5c26fa96"
|
||||
"checksum serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecc6e0379ca933ece58302d2d3034443f06fbf38fd535857c1dc516195cbc3bf"
|
||||
|
@ -4,6 +4,7 @@ name = "parity"
|
||||
version = "1.7.0"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
log = "0.3"
|
||||
@ -11,7 +12,7 @@ env_logger = "0.3"
|
||||
rustc-serialize = "0.3"
|
||||
docopt = "0.6"
|
||||
time = "0.1"
|
||||
num_cpus = "0.2"
|
||||
num_cpus = "1.2"
|
||||
number_prefix = "0.2"
|
||||
rpassword = "0.2.1"
|
||||
semver = "0.5"
|
||||
@ -52,6 +53,9 @@ ethcore-dapps = { path = "dapps", optional = true }
|
||||
clippy = { version = "0.0.103", optional = true}
|
||||
ethcore-secretstore = { path = "secret_store", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
ethcore-ipc-tests = { path = "ipc/tests" }
|
||||
|
||||
|
@ -14,28 +14,22 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! `TraceDB` errors.
|
||||
extern crate rustc_version;
|
||||
|
||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
const MIN_RUSTC_VERSION: &'static str = "1.15.1";
|
||||
|
||||
const RESYNC_ERR: &'static str =
|
||||
"Your current parity installation has synced without transaction tracing.
|
||||
To use Parity with transaction tracing, you'll need to resync with tracing.
|
||||
To do this, remove or move away your current database and restart parity. e.g.:
|
||||
fn main() {
|
||||
let is = rustc_version::version().unwrap();
|
||||
let required = MIN_RUSTC_VERSION.parse().unwrap();
|
||||
assert!(is >= required, format!("
|
||||
|
||||
> mv ~/.parity/906a34e69aec8c0d /tmp
|
||||
> parity";
|
||||
It looks like you are compiling Parity with an old rustc compiler {}.
|
||||
Parity requires version {}. Please update your compiler.
|
||||
If you use rustup, try this:
|
||||
|
||||
/// `TraceDB` errors.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Returned when tracing is enabled,
|
||||
/// but database does not contain traces of old transactions.
|
||||
ResyncRequired,
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
write!(f, "{}", RESYNC_ERR)
|
||||
}
|
||||
rustup update stable
|
||||
|
||||
and try building Parity again.
|
||||
|
||||
", is, required));
|
||||
}
|
@ -15,7 +15,7 @@ log = "0.3"
|
||||
env_logger = "0.3"
|
||||
rustc-serialize = "0.3"
|
||||
rust-crypto = "0.2.34"
|
||||
num_cpus = "0.2"
|
||||
num_cpus = "1.2"
|
||||
crossbeam = "0.2.9"
|
||||
lazy_static = "0.2"
|
||||
bloomchain = "0.1"
|
||||
|
@ -30,7 +30,8 @@
|
||||
"params": {
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x2A"
|
||||
"networkID" : "0x2A",
|
||||
"validateReceipts" : false
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
|
@ -139,6 +139,7 @@
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"eip98Transition": "0x7fffffffffffffff",
|
||||
"accountStartNonce": "0x00",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
|
@ -553,7 +553,6 @@ pub fn enact(
|
||||
b.set_extra_data(header.extra_data().clone()).unwrap_or_else(|e| warn!("Couldn't set extradata: {}. Ignoring.", e));
|
||||
b.set_uncles_hash(header.uncles_hash().clone());
|
||||
b.set_transactions_root(header.transactions_root().clone());
|
||||
b.set_receipts_root(header.receipts_root().clone());
|
||||
|
||||
push_transactions(&mut b, transactions)?;
|
||||
for u in uncles {
|
||||
|
@ -393,7 +393,7 @@ impl Client {
|
||||
})?;
|
||||
|
||||
// Final Verification
|
||||
if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header()) {
|
||||
if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header(), self.engine().params().validate_receipts) {
|
||||
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
return Err(());
|
||||
}
|
||||
|
@ -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/>.
|
||||
|
||||
use trace::Error as TraceError;
|
||||
use util::UtilError;
|
||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
|
||||
@ -23,8 +22,6 @@ use util::trie::TrieError;
|
||||
/// Client configuration errors.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// TraceDB configuration error.
|
||||
Trace(TraceError),
|
||||
/// TrieDB-related error.
|
||||
Trie(TrieError),
|
||||
/// Database error
|
||||
@ -33,12 +30,6 @@ pub enum Error {
|
||||
Util(UtilError),
|
||||
}
|
||||
|
||||
impl From<TraceError> for Error {
|
||||
fn from(err: TraceError) -> Self {
|
||||
Error::Trace(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TrieError> for Error {
|
||||
fn from(err: TrieError) -> Self {
|
||||
Error::Trie(err)
|
||||
@ -60,7 +51,6 @@ impl<E> From<Box<E>> for Error where Error: From<E> {
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
match *self {
|
||||
Error::Trace(ref err) => write!(f, "{}", err),
|
||||
Error::Trie(ref err) => write!(f, "{}", err),
|
||||
Error::Util(ref err) => write!(f, "{}", err),
|
||||
Error::Database(ref s) => write!(f, "Database error: {}", s),
|
||||
|
@ -90,6 +90,8 @@ pub struct MinerOptions {
|
||||
pub reseal_on_own_tx: bool,
|
||||
/// Minimum period between transaction-inspired reseals.
|
||||
pub reseal_min_period: Duration,
|
||||
/// Maximum period between blocks (enables force sealing after that).
|
||||
pub reseal_max_period: Duration,
|
||||
/// Maximum amount of gas to bother considering for block insertion.
|
||||
pub tx_gas_limit: U256,
|
||||
/// Maximum size of the transaction queue.
|
||||
@ -123,6 +125,7 @@ impl Default for MinerOptions {
|
||||
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
|
||||
pending_set: PendingSet::AlwaysQueue,
|
||||
reseal_min_period: Duration::from_secs(2),
|
||||
reseal_max_period: Duration::from_secs(120),
|
||||
work_queue_size: 20,
|
||||
enable_resubmission: true,
|
||||
tx_queue_banning: Banning::Disabled,
|
||||
@ -212,6 +215,7 @@ pub struct Miner {
|
||||
transaction_queue: Arc<Mutex<BanningTransactionQueue>>,
|
||||
sealing_work: Mutex<SealingWork>,
|
||||
next_allowed_reseal: Mutex<Instant>,
|
||||
next_mandatory_reseal: RwLock<Instant>,
|
||||
sealing_block_last_request: Mutex<u64>,
|
||||
// for sealing...
|
||||
options: MinerOptions,
|
||||
@ -268,6 +272,7 @@ impl Miner {
|
||||
Miner {
|
||||
transaction_queue: Arc::new(Mutex::new(txq)),
|
||||
next_allowed_reseal: Mutex::new(Instant::now()),
|
||||
next_mandatory_reseal: RwLock::new(Instant::now() + options.reseal_max_period),
|
||||
sealing_block_last_request: Mutex::new(0),
|
||||
sealing_work: Mutex::new(SealingWork{
|
||||
queue: UsingQueue::new(options.work_queue_size),
|
||||
@ -298,7 +303,9 @@ impl Miner {
|
||||
}
|
||||
|
||||
fn forced_sealing(&self) -> bool {
|
||||
self.options.force_sealing || !self.options.new_work_notify.is_empty()
|
||||
self.options.force_sealing
|
||||
|| !self.options.new_work_notify.is_empty()
|
||||
|| Instant::now() > *self.next_mandatory_reseal.read()
|
||||
}
|
||||
|
||||
/// Clear all pending block states
|
||||
@ -482,6 +489,7 @@ impl Miner {
|
||||
// Save proposal for later seal submission and broadcast it.
|
||||
Seal::Proposal(seal) => {
|
||||
trace!(target: "miner", "Received a Proposal seal.");
|
||||
*self.next_mandatory_reseal.write() = Instant::now() + self.options.reseal_max_period;
|
||||
{
|
||||
let mut sealing_work = self.sealing_work.lock();
|
||||
sealing_work.queue.push(block.clone());
|
||||
@ -497,7 +505,8 @@ impl Miner {
|
||||
})
|
||||
},
|
||||
// Directly import a regular sealed block.
|
||||
Seal::Regular(seal) =>
|
||||
Seal::Regular(seal) => {
|
||||
*self.next_mandatory_reseal.write() = Instant::now() + self.options.reseal_max_period;
|
||||
block
|
||||
.lock()
|
||||
.seal(&*self.engine, seal)
|
||||
@ -505,7 +514,8 @@ impl Miner {
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("ERROR: seal failed when given internally generated seal: {}", e);
|
||||
false
|
||||
}),
|
||||
})
|
||||
},
|
||||
Seal::None => false,
|
||||
}
|
||||
} else {
|
||||
@ -1290,6 +1300,7 @@ mod tests {
|
||||
reseal_on_external_tx: false,
|
||||
reseal_on_own_tx: true,
|
||||
reseal_min_period: Duration::from_secs(5),
|
||||
reseal_max_period: Duration::from_secs(120),
|
||||
tx_gas_limit: !U256::zero(),
|
||||
tx_queue_size: 1024,
|
||||
tx_queue_gas_limit: GasLimit::None,
|
||||
|
@ -55,6 +55,8 @@ pub struct CommonParams {
|
||||
pub fork_block: Option<(BlockNumber, H256)>,
|
||||
/// Number of first block where EIP-98 rules begin.
|
||||
pub eip98_transition: BlockNumber,
|
||||
/// Validate block receipts root.
|
||||
pub validate_receipts: bool,
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::Params> for CommonParams {
|
||||
@ -68,6 +70,7 @@ impl From<ethjson::spec::Params> for CommonParams {
|
||||
min_gas_limit: p.min_gas_limit.into(),
|
||||
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
|
||||
eip98_transition: p.eip98_transition.map_or(0, Into::into),
|
||||
validate_receipts: p.validate_receipts.unwrap_or(true),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
mod bloom;
|
||||
mod config;
|
||||
mod db;
|
||||
mod error;
|
||||
mod executive_tracer;
|
||||
mod import;
|
||||
mod noop_tracer;
|
||||
@ -28,7 +27,6 @@ pub use types::trace_types::{filter, flat, localized, trace};
|
||||
pub use types::trace_types::error::Error as TraceError;
|
||||
pub use self::config::Config;
|
||||
pub use self::db::TraceDB;
|
||||
pub use self::error::Error;
|
||||
pub use types::trace_types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
|
||||
pub use types::trace_types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
||||
pub use self::noop_tracer::{NoopTracer, NoopVMTracer};
|
||||
|
@ -31,7 +31,7 @@ impl Verifier for CanonVerifier {
|
||||
verification::verify_block_family(header, bytes, engine, bc)
|
||||
}
|
||||
|
||||
fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error> {
|
||||
verification::verify_block_final(expected, got)
|
||||
fn verify_block_final(&self, expected: &Header, got: &Header, receipts: bool) -> Result<(), Error> {
|
||||
verification::verify_block_final(expected, got, receipts)
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ impl Verifier for NoopVerifier {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_block_final(&self, _expected: &Header, _got: &Header) -> Result<(), Error> {
|
||||
fn verify_block_final(&self, _expected: &Header, _got: &Header, _receipts: bool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &
|
||||
}
|
||||
|
||||
/// Phase 4 verification. Check block information against transaction enactment results,
|
||||
pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> {
|
||||
pub fn verify_block_final(expected: &Header, got: &Header, check_receipts: bool) -> Result<(), Error> {
|
||||
if expected.gas_used() != got.gas_used() {
|
||||
return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: expected.gas_used().clone(), found: got.gas_used().clone() })))
|
||||
}
|
||||
@ -188,7 +188,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error>
|
||||
if expected.state_root() != got.state_root() {
|
||||
return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root().clone(), found: got.state_root().clone() })))
|
||||
}
|
||||
if expected.receipts_root() != got.receipts_root() {
|
||||
if check_receipts && expected.receipts_root() != got.receipts_root() {
|
||||
return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: expected.receipts_root().clone(), found: got.receipts_root().clone() })))
|
||||
}
|
||||
Ok(())
|
||||
|
@ -26,5 +26,5 @@ pub trait Verifier: Send + Sync {
|
||||
/// Verify a block relative to its parent and uncles.
|
||||
fn verify_block_family(&self, header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error>;
|
||||
/// Do a final verification check for an enacted header vs its expected counterpart.
|
||||
fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error>;
|
||||
fn verify_block_final(&self, expected: &Header, got: &Header, receipts: bool) -> Result<(), Error>;
|
||||
}
|
||||
|
@ -5,11 +5,11 @@ version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[lib]
|
||||
name = "evm"
|
||||
name = "evmbin"
|
||||
path = "./src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "evm"
|
||||
name = "parity-evm"
|
||||
path = "./src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "parity.js",
|
||||
"version": "1.7.12",
|
||||
"version": "1.7.18",
|
||||
"main": "release/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"author": "Parity Team <admin@parity.io>",
|
||||
|
@ -1 +1,2 @@
|
||||
// test script 7
|
||||
// test script 8
|
||||
// trigger rebuild on master 15 Mar 2017, 11:19
|
||||
|
@ -107,13 +107,25 @@ export default class Contract {
|
||||
});
|
||||
}
|
||||
|
||||
deploy (options, values, statecb = () => {}) {
|
||||
deploy (options, values, statecb = () => {}, skipGasEstimate = false) {
|
||||
let gasEstPromise;
|
||||
|
||||
if (skipGasEstimate) {
|
||||
gasEstPromise = Promise.resolve(null);
|
||||
} else {
|
||||
statecb(null, { state: 'estimateGas' });
|
||||
|
||||
return this
|
||||
.deployEstimateGas(options, values)
|
||||
.then(([gasEst, gas]) => {
|
||||
options.gas = gas.toFixed(0);
|
||||
gasEstPromise = this.deployEstimateGas(options, values)
|
||||
.then(([gasEst, gas]) => gas);
|
||||
}
|
||||
|
||||
return gasEstPromise
|
||||
.then((_gas) => {
|
||||
if (_gas) {
|
||||
options.gas = _gas.toFixed(0);
|
||||
}
|
||||
|
||||
const gas = _gas || options.gas;
|
||||
|
||||
statecb(null, { state: 'postTransaction', gas });
|
||||
|
||||
|
@ -253,23 +253,28 @@ export default class Deployment extends Component {
|
||||
|
||||
onDeploy = () => {
|
||||
const { managerInstance, registryInstance, tokenregInstance } = this.context;
|
||||
const { base, deployBusy, globalReg, globalFee, name, nameError, tla, tlaError, totalSupply, totalSupplyError } = this.state;
|
||||
const { base, deployBusy, globalReg, name, nameError, tla, tlaError, totalSupply, totalSupplyError } = this.state;
|
||||
const hasError = !!(nameError || tlaError || totalSupplyError);
|
||||
|
||||
if (hasError || deployBusy) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tokenreg = (globalReg ? tokenregInstance : registryInstance).address;
|
||||
const registry = globalReg ? tokenregInstance : registryInstance;
|
||||
const tokenreg = registry.address;
|
||||
|
||||
const values = [base.mul(totalSupply), tla, name, tokenreg];
|
||||
const options = {
|
||||
value: globalReg ? globalFee : 0
|
||||
};
|
||||
const options = {};
|
||||
|
||||
this.setState({ deployBusy: true, deployState: 'Estimating gas for the transaction' });
|
||||
|
||||
return api.parity
|
||||
.defaultAccount()
|
||||
return registry.fee.call({}, [])
|
||||
.then((fee) => {
|
||||
console.log('deploying with fee of', fee.toFixed());
|
||||
options.value = fee;
|
||||
|
||||
return api.parity.defaultAccount();
|
||||
})
|
||||
.then((defaultAddress) => {
|
||||
options.from = defaultAddress;
|
||||
|
||||
|
@ -19,7 +19,7 @@ import { Dialog, RaisedButton, FlatButton, SelectField, MenuItem } from 'materia
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
|
||||
import InputText from '../../Inputs/Text';
|
||||
import { ADDRESS_TYPE } from '../../Inputs/validation';
|
||||
import { ADDRESS_TYPE, URL_TYPE } from '../../Inputs/validation';
|
||||
|
||||
import styles from './token.css';
|
||||
|
||||
@ -128,6 +128,22 @@ export default class AddMeta extends Component {
|
||||
|
||||
renderForm () {
|
||||
const selectedMeta = metaDataKeys[this.state.metaKeyIndex];
|
||||
const metaLabel = selectedMeta.label.toLowerCase();
|
||||
let metaType;
|
||||
|
||||
switch (selectedMeta.validation) {
|
||||
case ADDRESS_TYPE:
|
||||
metaType = 'Address';
|
||||
break;
|
||||
|
||||
case URL_TYPE:
|
||||
metaType = 'URL';
|
||||
break;
|
||||
|
||||
default:
|
||||
metaType = 'URL Hint';
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -145,7 +161,7 @@ export default class AddMeta extends Component {
|
||||
<InputText
|
||||
key={ selectedMeta.value }
|
||||
floatingLabelText={ `${selectedMeta.label} value` }
|
||||
hintText={ `The value of the ${selectedMeta.label.toLowerCase()} (${selectedMeta.validation === ADDRESS_TYPE ? 'Address' : 'Url Hint'})` }
|
||||
hintText={ `The value of the ${metaLabel} (${metaType})` }
|
||||
|
||||
validationType={ selectedMeta.validation }
|
||||
onChange={ this.onChange }
|
||||
@ -174,14 +190,20 @@ export default class AddMeta extends Component {
|
||||
|
||||
onAdd = () => {
|
||||
const { index } = this.props;
|
||||
const { form, metaKeyIndex } = this.state;
|
||||
|
||||
const selectedMeta = metaDataKeys[metaKeyIndex];
|
||||
|
||||
const keyIndex = this.state.metaKeyIndex;
|
||||
const key = metaDataKeys[keyIndex].value;
|
||||
const value = form.value;
|
||||
const validationType = selectedMeta.validation;
|
||||
|
||||
this.props.handleAddMeta(
|
||||
index,
|
||||
key,
|
||||
this.state.form.value
|
||||
value,
|
||||
validationType
|
||||
);
|
||||
|
||||
this.setState({ complete: true });
|
||||
|
@ -61,8 +61,8 @@ const mapDispatchToProps = (dispatch) => {
|
||||
dispatch(unregisterToken(index));
|
||||
},
|
||||
|
||||
handleAddMeta: (index, key, value) => {
|
||||
dispatch(addTokenMeta(index, key, value));
|
||||
handleAddMeta: (index, key, value, validationType) => {
|
||||
dispatch(addTokenMeta(index, key, value, validationType));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -14,7 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { getTokenTotalSupply } from '../utils';
|
||||
import { URL_TYPE } from '../Inputs/validation';
|
||||
import { getTokenTotalSupply, urlToHash } from '../utils';
|
||||
|
||||
const { bytesToHex } = window.parity.api.util;
|
||||
|
||||
@ -178,40 +179,63 @@ export const queryTokenMeta = (index, query) => (dispatch, getState) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const addTokenMeta = (index, key, value) => (dispatch, getState) => {
|
||||
export const addTokenMeta = (index, key, value, validationType) => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
|
||||
const contractInstance = state.status.contract.instance;
|
||||
const ghhInstance = state.status.githubhint.instance;
|
||||
|
||||
const token = state.tokens.tokens.find(t => t.index === index);
|
||||
const options = { from: token.owner };
|
||||
const values = [ index, key, value ];
|
||||
let valuesPromise;
|
||||
|
||||
contractInstance
|
||||
// Get the right values (could be a hashed URL from GHH)
|
||||
if (validationType === URL_TYPE) {
|
||||
valuesPromise = addGithubhintURL(ghhInstance, options, value)
|
||||
.then((hash) => [ index, key, hash ]);
|
||||
} else {
|
||||
valuesPromise = Promise.resolve([ index, key, value ]);
|
||||
}
|
||||
|
||||
return valuesPromise
|
||||
.then((values) => {
|
||||
return contractInstance
|
||||
.setMeta
|
||||
.estimateGas(options, values)
|
||||
.then((gasEstimate) => {
|
||||
options.gas = gasEstimate.mul(1.2).toFixed(0);
|
||||
return contractInstance.setMeta.postTransaction(options, values);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(`addTokenMeta: #${index} error`, e);
|
||||
});
|
||||
};
|
||||
|
||||
export const addGithubhintURL = (from, key, url) => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const contractInstance = state.status.githubhint.instance;
|
||||
const options = { from };
|
||||
const values = [ key, url ];
|
||||
export const addGithubhintURL = (ghhInstance, _options, url) => {
|
||||
return urlToHash(ghhInstance, url)
|
||||
.then((result) => {
|
||||
const { hash, registered } = result;
|
||||
|
||||
contractInstance
|
||||
if (registered) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
const options = { from: _options.from };
|
||||
const values = [ hash, url ];
|
||||
|
||||
ghhInstance
|
||||
.hintURL
|
||||
.estimateGas(options, values)
|
||||
.then((gasEstimate) => {
|
||||
options.gas = gasEstimate.mul(1.2).toFixed(0);
|
||||
return contractInstance.hintURL.postTransaction(options, values);
|
||||
return ghhInstance.hintURL.postTransaction(options, values);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('addGithubhintURL error', e);
|
||||
.catch((error) => {
|
||||
console.error(`registering "${url}" to GHH`, error);
|
||||
});
|
||||
|
||||
return hash;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -14,13 +14,13 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { HEX_TYPE, ADDRESS_TYPE } from './Inputs/validation';
|
||||
import { URL_TYPE, ADDRESS_TYPE } from './Inputs/validation';
|
||||
|
||||
export const metaDataKeys = [
|
||||
{
|
||||
label: 'Image',
|
||||
value: 'IMG',
|
||||
validation: HEX_TYPE
|
||||
validation: URL_TYPE
|
||||
},
|
||||
{
|
||||
label: 'Address',
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
const { api } = window.parity;
|
||||
const api = window.parent.secureApi;
|
||||
|
||||
export {
|
||||
api
|
||||
|
@ -18,6 +18,45 @@ import { api } from './parity';
|
||||
|
||||
import { eip20 as eip20Abi } from '~/contracts/abi';
|
||||
|
||||
export const INVALID_URL_HASH = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470';
|
||||
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
|
||||
/**
|
||||
* Convert the given URL to a content hash,
|
||||
* and checks if it is already registered in GHH
|
||||
*/
|
||||
export const urlToHash = (ghhInstance, url) => {
|
||||
if (!url || !url.length) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
return api.parity
|
||||
.hashContent(url)
|
||||
.catch((error) => {
|
||||
const message = error.text || error.message || error.toString();
|
||||
|
||||
throw new Error(`${message} (${url})`);
|
||||
})
|
||||
.then((contentHash) => {
|
||||
console.log('lookupHash', url, contentHash);
|
||||
|
||||
if (contentHash === INVALID_URL_HASH) {
|
||||
throw new Error(`"${url}" is not a valid URL`);
|
||||
}
|
||||
|
||||
return ghhInstance.entries
|
||||
.call({}, [contentHash])
|
||||
.then(([accountSlashRepo, commit, contentHashOwner]) => {
|
||||
const registered = (contentHashOwner !== ZERO_ADDRESS);
|
||||
|
||||
return {
|
||||
hash: contentHash,
|
||||
registered
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const getTokenTotalSupply = (tokenAddress) => {
|
||||
return api
|
||||
.eth
|
||||
|
@ -130,7 +130,7 @@ export default class CreationType extends Component {
|
||||
<div className={ styles.summary }>
|
||||
<FormattedMessage
|
||||
id='createAccount.creationType.info'
|
||||
defaultMessage='Please select the type of account you want to create. Either create an account via name & password, or import it from a variety of existing sources. From here the wizard will guid you through the process of completing your account creation.'
|
||||
defaultMessage='Please select the type of account you want to create. Either create an account via name & password, or import it from a variety of existing sources. From here the wizard will guide you through the process of completing your account creation.'
|
||||
/>
|
||||
</div>
|
||||
{ this.renderList(createType) }
|
||||
|
@ -16,12 +16,16 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { MenuItem } from 'material-ui';
|
||||
import { Checkbox, MenuItem } from 'material-ui';
|
||||
|
||||
import { AddressSelect, Form, Input, Select } from '~/ui';
|
||||
import { validateAbi } from '~/util/validation';
|
||||
import { parseAbiType } from '~/util/abi';
|
||||
|
||||
const CHECK_STYLE = {
|
||||
marginTop: '1em'
|
||||
};
|
||||
|
||||
export default class DetailsStep extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
@ -30,8 +34,10 @@ export default class DetailsStep extends Component {
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
onAbiChange: PropTypes.func.isRequired,
|
||||
onAmountChange: PropTypes.func.isRequired,
|
||||
onCodeChange: PropTypes.func.isRequired,
|
||||
onDescriptionChange: PropTypes.func.isRequired,
|
||||
onExtrasChange: PropTypes.func.isRequired,
|
||||
onFromAddressChange: PropTypes.func.isRequired,
|
||||
onInputsChange: PropTypes.func.isRequired,
|
||||
onNameChange: PropTypes.func.isRequired,
|
||||
@ -39,11 +45,14 @@ export default class DetailsStep extends Component {
|
||||
|
||||
abi: PropTypes.string,
|
||||
abiError: PropTypes.string,
|
||||
amount: PropTypes.string,
|
||||
amountError: PropTypes.string,
|
||||
balances: PropTypes.object,
|
||||
code: PropTypes.string,
|
||||
codeError: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
descriptionError: PropTypes.string,
|
||||
extras: PropTypes.bool,
|
||||
fromAddress: PropTypes.string,
|
||||
fromAddressError: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
@ -52,6 +61,7 @@ export default class DetailsStep extends Component {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
extras: false,
|
||||
readOnly: false
|
||||
};
|
||||
|
||||
@ -83,7 +93,7 @@ export default class DetailsStep extends Component {
|
||||
fromAddress, fromAddressError,
|
||||
name, nameError,
|
||||
description, descriptionError,
|
||||
abiError,
|
||||
abiError, extras,
|
||||
code, codeError
|
||||
} = this.props;
|
||||
|
||||
@ -189,10 +199,70 @@ export default class DetailsStep extends Component {
|
||||
value={ code }
|
||||
/>
|
||||
|
||||
{ this.renderValueInput() }
|
||||
|
||||
<div>
|
||||
<Checkbox
|
||||
checked={ extras }
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='deployContract.details.advanced.label'
|
||||
defaultMessage='advanced sending options'
|
||||
/>
|
||||
}
|
||||
onCheck={ this.onCheckExtras }
|
||||
style={ CHECK_STYLE }
|
||||
/>
|
||||
</div>
|
||||
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
renderValueInput () {
|
||||
const { abi, amount, amountError } = this.props;
|
||||
|
||||
let payable = false;
|
||||
|
||||
try {
|
||||
const parsedAbi = JSON.parse(abi);
|
||||
|
||||
payable = parsedAbi.find((method) => method.type === 'constructor' && method.payable);
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!payable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Input
|
||||
error={ amountError }
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='deployContract.details.amount.hint'
|
||||
defaultMessage='the amount to transfer to the contract'
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='deployContract.details.amount.label'
|
||||
defaultMessage='amount to transfer (in {tag})'
|
||||
values={ {
|
||||
tag: 'ETH'
|
||||
} }
|
||||
/>
|
||||
}
|
||||
min={ 0 }
|
||||
step={ 0.1 }
|
||||
type='number'
|
||||
onChange={ this.onAmountChange }
|
||||
value={ amount }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderContractSelect () {
|
||||
const { contracts } = this.state;
|
||||
|
||||
@ -295,6 +365,16 @@ export default class DetailsStep extends Component {
|
||||
onDescriptionChange(description);
|
||||
}
|
||||
|
||||
onAmountChange = (event, value) => {
|
||||
const { onAmountChange } = this.props;
|
||||
|
||||
onAmountChange(value);
|
||||
}
|
||||
|
||||
onCheckExtras = () => {
|
||||
this.props.onExtrasChange(!this.props.extras);
|
||||
}
|
||||
|
||||
onAbiChange = (abi) => {
|
||||
const { api } = this.context;
|
||||
const { onAbiChange, onParamsChange, onInputsChange } = this.props;
|
||||
|
@ -14,6 +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 BigNumber from 'bignumber.js';
|
||||
import { pick } from 'lodash';
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
@ -22,12 +23,13 @@ import { connect } from 'react-redux';
|
||||
|
||||
import { BusyStep, Button, CompletedStep, CopyToClipboard, GasPriceEditor, IdentityIcon, Portal, TxHash, Warning } from '~/ui';
|
||||
import { CancelIcon, DoneIcon } from '~/ui/Icons';
|
||||
import { ERRORS, validateAbi, validateCode, validateName } from '~/util/validation';
|
||||
import { ERRORS, validateAbi, validateCode, validateName, validatePositiveNumber } from '~/util/validation';
|
||||
import { deploy, deployEstimateGas } from '~/util/tx';
|
||||
|
||||
import DetailsStep from './DetailsStep';
|
||||
import ParametersStep from './ParametersStep';
|
||||
import ErrorStep from './ErrorStep';
|
||||
import Extras from '../Transfer/Extras';
|
||||
|
||||
import styles from './deployContract.css';
|
||||
|
||||
@ -50,6 +52,14 @@ const STEPS = {
|
||||
/>
|
||||
)
|
||||
},
|
||||
EXTRAS: {
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id='deployContract.title.extras'
|
||||
defaultMessage='extra information'
|
||||
/>
|
||||
)
|
||||
},
|
||||
DEPLOYMENT: {
|
||||
waiting: true,
|
||||
title: (
|
||||
@ -97,12 +107,16 @@ class DeployContract extends Component {
|
||||
state = {
|
||||
abi: '',
|
||||
abiError: ERRORS.invalidAbi,
|
||||
amount: '0',
|
||||
amountValue: new BigNumber(0),
|
||||
amountError: '',
|
||||
code: '',
|
||||
codeError: ERRORS.invalidCode,
|
||||
deployState: '',
|
||||
deployError: null,
|
||||
description: '',
|
||||
descriptionError: null,
|
||||
extras: false,
|
||||
fromAddress: Object.keys(this.props.accounts)[0],
|
||||
fromAddressError: null,
|
||||
name: '',
|
||||
@ -144,7 +158,19 @@ class DeployContract extends Component {
|
||||
|
||||
const realStepKeys = deployError || rejected
|
||||
? []
|
||||
: Object.keys(STEPS).filter((k) => k !== 'CONTRACT_PARAMETERS' || inputs.length > 0);
|
||||
: Object.keys(STEPS)
|
||||
.filter((k) => {
|
||||
if (k === 'CONTRACT_PARAMETERS') {
|
||||
return inputs.length > 0;
|
||||
}
|
||||
|
||||
if (k === 'EXTRAS') {
|
||||
return this.state.extras;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
const realStep = realStepKeys.findIndex((k) => k === step);
|
||||
const realSteps = realStepKeys.length
|
||||
? realStepKeys.map((k) => STEPS[k])
|
||||
@ -207,8 +233,8 @@ class DeployContract extends Component {
|
||||
}
|
||||
|
||||
renderDialogActions () {
|
||||
const { deployError, abiError, codeError, nameError, descriptionError, fromAddressError, fromAddress, step } = this.state;
|
||||
const isValid = !nameError && !fromAddressError && !descriptionError && !abiError && !codeError;
|
||||
const { deployError, abiError, amountError, codeError, nameError, descriptionError, fromAddressError, fromAddress, step } = this.state;
|
||||
const isValid = !nameError && !fromAddressError && !descriptionError && !abiError && !codeError && !amountError;
|
||||
|
||||
const cancelBtn = (
|
||||
<Button
|
||||
@ -256,32 +282,7 @@ class DeployContract extends Component {
|
||||
return closeBtn;
|
||||
}
|
||||
|
||||
switch (step) {
|
||||
case 'CONTRACT_DETAILS':
|
||||
return [
|
||||
cancelBtn,
|
||||
<Button
|
||||
disabled={ !isValid }
|
||||
key='next'
|
||||
icon={
|
||||
<IdentityIcon
|
||||
address={ fromAddress }
|
||||
button
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='deployContract.button.next'
|
||||
defaultMessage='Next'
|
||||
/>
|
||||
}
|
||||
onClick={ this.onParametersStep }
|
||||
/>
|
||||
];
|
||||
|
||||
case 'CONTRACT_PARAMETERS':
|
||||
return [
|
||||
cancelBtn,
|
||||
const createButton = (
|
||||
<Button
|
||||
icon={
|
||||
<IdentityIcon
|
||||
@ -298,6 +299,52 @@ class DeployContract extends Component {
|
||||
}
|
||||
onClick={ this.onDeployStart }
|
||||
/>
|
||||
);
|
||||
|
||||
const nextButton = (
|
||||
<Button
|
||||
disabled={ !isValid }
|
||||
key='next'
|
||||
icon={
|
||||
<IdentityIcon
|
||||
address={ fromAddress }
|
||||
button
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='deployContract.button.next'
|
||||
defaultMessage='Next'
|
||||
/>
|
||||
}
|
||||
onClick={ this.onNextStep }
|
||||
/>
|
||||
);
|
||||
|
||||
const hasParameters = this.state.inputs.length > 0;
|
||||
const showExtras = this.state.extras;
|
||||
|
||||
switch (step) {
|
||||
case 'CONTRACT_DETAILS':
|
||||
return [
|
||||
cancelBtn,
|
||||
hasParameters || showExtras
|
||||
? nextButton
|
||||
: createButton
|
||||
];
|
||||
|
||||
case 'CONTRACT_PARAMETERS':
|
||||
return [
|
||||
cancelBtn,
|
||||
showExtras
|
||||
? nextButton
|
||||
: createButton
|
||||
];
|
||||
|
||||
case 'EXTRAS':
|
||||
return [
|
||||
cancelBtn,
|
||||
createButton
|
||||
];
|
||||
|
||||
case 'DEPLOYMENT':
|
||||
@ -344,6 +391,8 @@ class DeployContract extends Component {
|
||||
{ ...this.state }
|
||||
accounts={ accounts }
|
||||
balances={ balances }
|
||||
onAmountChange={ this.onAmountChange }
|
||||
onExtrasChange={ this.onExtrasChange }
|
||||
onFromAddressChange={ this.onFromAddressChange }
|
||||
onDescriptionChange={ this.onDescriptionChange }
|
||||
onNameChange={ this.onNameChange }
|
||||
@ -365,6 +414,9 @@ class DeployContract extends Component {
|
||||
/>
|
||||
);
|
||||
|
||||
case 'EXTRAS':
|
||||
return this.renderExtrasPage();
|
||||
|
||||
case 'DEPLOYMENT':
|
||||
const body = txhash
|
||||
? <TxHash hash={ txhash } />
|
||||
@ -411,17 +463,32 @@ class DeployContract extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
renderExtrasPage () {
|
||||
if (!this.gasStore.histogram) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Extras
|
||||
gasStore={ this.gasStore }
|
||||
hideData
|
||||
isEth
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
estimateGas = () => {
|
||||
const { api } = this.context;
|
||||
const { abiError, abiParsed, code, codeError, fromAddress, fromAddressError, params } = this.state;
|
||||
const { abiError, abiParsed, amountValue, amountError, code, codeError, fromAddress, fromAddressError, params } = this.state;
|
||||
|
||||
if (abiError || codeError || fromAddressError) {
|
||||
if (abiError || codeError || fromAddressError || amountError) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
data: code,
|
||||
from: fromAddress
|
||||
from: fromAddress,
|
||||
value: amountValue
|
||||
};
|
||||
|
||||
const contract = api.newContract(abiParsed);
|
||||
@ -437,6 +504,19 @@ class DeployContract extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
onNextStep = () => {
|
||||
switch (this.state.step) {
|
||||
case 'CONTRACT_DETAILS':
|
||||
return this.onParametersStep();
|
||||
|
||||
case 'CONTRACT_PARAMETERS':
|
||||
return this.onExtrasStep();
|
||||
|
||||
default:
|
||||
console.warn('wrong call of "onNextStep" from', this.state.step);
|
||||
}
|
||||
}
|
||||
|
||||
onParametersStep = () => {
|
||||
const { inputs } = this.state;
|
||||
|
||||
@ -444,6 +524,14 @@ class DeployContract extends Component {
|
||||
return this.setState({ step: 'CONTRACT_PARAMETERS' });
|
||||
}
|
||||
|
||||
return this.onExtrasStep();
|
||||
}
|
||||
|
||||
onExtrasStep = () => {
|
||||
if (this.state.extras) {
|
||||
return this.setState({ step: 'EXTRAS' });
|
||||
}
|
||||
|
||||
return this.onDeployStart();
|
||||
}
|
||||
|
||||
@ -488,10 +576,24 @@ class DeployContract extends Component {
|
||||
this.setState(validateCode(code), this.estimateGas);
|
||||
}
|
||||
|
||||
onAmountChange = (amount) => {
|
||||
const { numberError } = validatePositiveNumber(amount);
|
||||
const nextAmountValue = numberError
|
||||
? new BigNumber(0)
|
||||
: this.context.api.util.toWei(amount);
|
||||
|
||||
this.gasStore.setEthValue(nextAmountValue);
|
||||
this.setState({ amount, amountValue: nextAmountValue, amountError: numberError }, this.estimateGas);
|
||||
}
|
||||
|
||||
onExtrasChange = (extras) => {
|
||||
this.setState({ extras });
|
||||
}
|
||||
|
||||
onDeployStart = () => {
|
||||
const { api, store } = this.context;
|
||||
const { source } = this.props;
|
||||
const { abiParsed, code, description, name, params, fromAddress } = this.state;
|
||||
const { abiParsed, amountValue, code, description, name, params, fromAddress } = this.state;
|
||||
|
||||
const metadata = {
|
||||
abi: abiParsed,
|
||||
@ -503,16 +605,17 @@ class DeployContract extends Component {
|
||||
source
|
||||
};
|
||||
|
||||
const options = {
|
||||
const options = this.gasStore.overrideTransaction({
|
||||
data: code,
|
||||
from: fromAddress
|
||||
};
|
||||
from: fromAddress,
|
||||
value: amountValue
|
||||
});
|
||||
|
||||
this.setState({ step: 'DEPLOYMENT' });
|
||||
|
||||
const contract = api.newContract(abiParsed);
|
||||
|
||||
deploy(contract, options, params, metadata, this.onDeploymentState)
|
||||
deploy(contract, options, params, metadata, this.onDeploymentState, true)
|
||||
.then((address) => {
|
||||
// No contract address given, might need some confirmations
|
||||
// from the wallet owners...
|
||||
|
@ -49,7 +49,7 @@ export default class FirstRun extends Component {
|
||||
defaultMessage='As part of a new installation, the next few steps will guide you through the process of setting up you Parity instance and your associated accounts. Our aim is to make it as simple as possible and to get you up and running in record-time, so please bear with us. Once completed you will have -'
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
<FormattedMessage
|
||||
@ -70,7 +70,7 @@ export default class FirstRun extends Component {
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='firstRun.welcome.next'
|
||||
|
@ -24,7 +24,7 @@ import { nullableProptype } from '~/util/proptypes';
|
||||
import TokenSelect from './tokenSelect';
|
||||
import styles from '../transfer.css';
|
||||
|
||||
const CHECK_STYLE = {
|
||||
export const CHECK_STYLE = {
|
||||
position: 'absolute',
|
||||
top: '38px',
|
||||
left: '1em'
|
||||
|
@ -25,12 +25,17 @@ export default class Extras extends Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.string,
|
||||
dataError: PropTypes.string,
|
||||
hideData: PropTypes.bool,
|
||||
gasStore: PropTypes.object.isRequired,
|
||||
isEth: PropTypes.bool,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func,
|
||||
total: PropTypes.string,
|
||||
totalError: PropTypes.string
|
||||
}
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
hideData: false
|
||||
};
|
||||
|
||||
render () {
|
||||
const { gasStore, onChange } = this.props;
|
||||
@ -49,9 +54,9 @@ export default class Extras extends Component {
|
||||
}
|
||||
|
||||
renderData () {
|
||||
const { isEth, data, dataError } = this.props;
|
||||
const { isEth, data, dataError, hideData } = this.props;
|
||||
|
||||
if (!isEth) {
|
||||
if (!isEth || hideData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,26 @@ export default class SecureApi extends Api {
|
||||
return this._transport.token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the current API with the given values
|
||||
* (`signerPort`, `dappsInterface`, `dappsPort`, ...)
|
||||
*/
|
||||
configure (configuration) {
|
||||
const { dappsInterface, dappsPort, signerPort } = configuration;
|
||||
|
||||
if (dappsInterface) {
|
||||
this._dappsInterface = dappsInterface;
|
||||
}
|
||||
|
||||
if (dappsPort) {
|
||||
this._dappsPort = dappsPort;
|
||||
}
|
||||
|
||||
if (signerPort) {
|
||||
this._signerPort = signerPort;
|
||||
}
|
||||
}
|
||||
|
||||
connect () {
|
||||
if (this._isConnecting) {
|
||||
return;
|
||||
|
@ -81,6 +81,7 @@ export default class Input extends Component {
|
||||
tabIndex: PropTypes.number,
|
||||
type: PropTypes.string,
|
||||
submitOnBlur: PropTypes.bool,
|
||||
step: PropTypes.number,
|
||||
style: PropTypes.object,
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.number,
|
||||
@ -124,7 +125,7 @@ export default class Input extends Component {
|
||||
render () {
|
||||
const { value } = this.state;
|
||||
const { autoFocus, children, className, hideUnderline, disabled, error, focused, label } = this.props;
|
||||
const { hint, onClick, multiLine, rows, type, min, max, style, tabIndex } = this.props;
|
||||
const { hint, onClick, multiLine, rows, type, min, max, step, style, tabIndex } = this.props;
|
||||
|
||||
const readOnly = this.props.readOnly || disabled;
|
||||
|
||||
@ -179,6 +180,7 @@ export default class Input extends Component {
|
||||
readOnly={ readOnly }
|
||||
ref='input'
|
||||
rows={ rows }
|
||||
step={ step }
|
||||
style={ textFieldStyle }
|
||||
tabIndex={ tabIndex }
|
||||
type={ type || 'text' }
|
||||
|
@ -107,7 +107,7 @@ class MethodDecoding extends Component {
|
||||
|
||||
renderGas () {
|
||||
const { historic, transaction } = this.props;
|
||||
const { gas, gasPrice } = transaction;
|
||||
const { gas, gasPrice, value } = transaction;
|
||||
|
||||
if (!gas || !gasPrice) {
|
||||
return null;
|
||||
@ -126,9 +126,9 @@ class MethodDecoding extends Component {
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
const gasProvidedEth = (
|
||||
const totalEthValue = (
|
||||
<span className={ styles.highlight }>
|
||||
{ this.renderEtherValue(gas.mul(gasPrice)) }
|
||||
{ this.renderEtherValue(gas.mul(gasPrice).plus(value || 0)) }
|
||||
</span>
|
||||
);
|
||||
const gasUsed = transaction.gasUsed
|
||||
@ -149,12 +149,12 @@ class MethodDecoding extends Component {
|
||||
<div className={ styles.gasDetails }>
|
||||
<FormattedMessage
|
||||
id='ui.methodDecoding.txValues'
|
||||
defaultMessage='{historic, select, true {Provided} false {Provides}} {gasProvided}{gasUsed} for a total transaction value of {gasProvidedEth}'
|
||||
defaultMessage='{historic, select, true {Provided} false {Provides}} {gasProvided}{gasUsed} for a total transaction value of {totalEthValue}'
|
||||
values={ {
|
||||
historic,
|
||||
gasProvided,
|
||||
gasProvidedEth,
|
||||
gasUsed
|
||||
gasUsed,
|
||||
totalEthValue
|
||||
} }
|
||||
/>
|
||||
{ this.renderMinBlock() }
|
||||
@ -349,6 +349,7 @@ class MethodDecoding extends Component {
|
||||
renderDeploy () {
|
||||
const { historic, transaction } = this.props;
|
||||
const { methodInputs } = this.state;
|
||||
const { value } = transaction;
|
||||
|
||||
if (!historic) {
|
||||
return (
|
||||
@ -357,6 +358,19 @@ class MethodDecoding extends Component {
|
||||
id='ui.methodDecoding.deploy.willDeploy'
|
||||
defaultMessage='Will deploy a contract'
|
||||
/>
|
||||
{
|
||||
value && value.gt(0)
|
||||
? (
|
||||
<FormattedMessage
|
||||
id='ui.methodDecoding.deploy.withValue'
|
||||
defaultMessage=', sending {value}'
|
||||
values={ {
|
||||
value: this.renderEtherValue(value)
|
||||
} }
|
||||
/>
|
||||
)
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ $popoverZ: 3600;
|
||||
left: 0;
|
||||
right: 0;
|
||||
opacity: 0.25;
|
||||
z-index: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
|
@ -18,6 +18,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactPortal from 'react-portal';
|
||||
import keycode from 'keycode';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
import { CloseIcon } from '~/ui/Icons';
|
||||
@ -29,7 +30,6 @@ import styles from './portal.css';
|
||||
|
||||
export default class Portal extends Component {
|
||||
static propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
activeStep: PropTypes.number,
|
||||
busy: PropTypes.bool,
|
||||
@ -45,11 +45,16 @@ export default class Portal extends Component {
|
||||
isChildModal: PropTypes.bool,
|
||||
isSmallModal: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
onClose: PropTypes.func,
|
||||
onKeyDown: PropTypes.func,
|
||||
steps: PropTypes.array,
|
||||
title: nodeOrStringProptype()
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onClose: noop
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
this.setBodyOverflow(this.props.open);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ $widthExpanded: 42%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 0 1 $widthNormal;
|
||||
max-width: $widthNormal;
|
||||
opacity: 0.85;
|
||||
padding: 0.25em;
|
||||
|
||||
|
@ -73,7 +73,7 @@ export function postTransaction (_func, _options, _values = []) {
|
||||
});
|
||||
}
|
||||
|
||||
export function deploy (contract, _options, values, metadata = {}, statecb = () => {}) {
|
||||
export function deploy (contract, _options, values, metadata = {}, statecb = () => {}, skipGasEstimate = false) {
|
||||
const options = { ..._options };
|
||||
const { api } = contract;
|
||||
const address = options.from;
|
||||
@ -82,16 +82,27 @@ export function deploy (contract, _options, values, metadata = {}, statecb = ()
|
||||
.isWallet(api, address)
|
||||
.then((isWallet) => {
|
||||
if (!isWallet) {
|
||||
return contract.deploy(options, values, statecb);
|
||||
return contract.deploy(options, values, statecb, skipGasEstimate);
|
||||
}
|
||||
|
||||
let gasEstPromise;
|
||||
|
||||
if (skipGasEstimate) {
|
||||
gasEstPromise = Promise.resolve(null);
|
||||
} else {
|
||||
statecb(null, { state: 'estimateGas' });
|
||||
|
||||
return deployEstimateGas(contract, options, values)
|
||||
.then(([gasEst, gas]) => {
|
||||
options.gas = gas.toFixed(0);
|
||||
gasEstPromise = deployEstimateGas(contract, options, values)
|
||||
.then(([gasEst, gas]) => gas);
|
||||
}
|
||||
|
||||
statecb(null, { state: 'postTransaction', gas });
|
||||
return gasEstPromise
|
||||
.then((gas) => {
|
||||
if (gas) {
|
||||
options.gas = gas.toFixed(0);
|
||||
}
|
||||
|
||||
statecb(null, { state: 'postTransaction', gas: options.gas });
|
||||
|
||||
return WalletsUtils.getDeployArgs(contract, options, values);
|
||||
})
|
||||
|
@ -17,12 +17,20 @@
|
||||
import { action, observable } from 'mobx';
|
||||
import store from 'store';
|
||||
|
||||
const OLD_LS_FIRST_RUN_KEY = 'showFirstRun';
|
||||
const LS_FIRST_RUN_KEY = '_parity::showFirstRun';
|
||||
|
||||
export default class Store {
|
||||
@observable firstrunVisible = false;
|
||||
|
||||
constructor (api) {
|
||||
// Migrate the old key to the new one
|
||||
this._migrateStore();
|
||||
|
||||
this._api = api;
|
||||
this.firstrunVisible = store.get('showFirstRun');
|
||||
// Show the first run if it hasn't been shown before
|
||||
// (thus an undefined value)
|
||||
this.firstrunVisible = store.get(LS_FIRST_RUN_KEY) === undefined;
|
||||
|
||||
this._checkAccounts();
|
||||
}
|
||||
@ -33,16 +41,41 @@ export default class Store {
|
||||
|
||||
@action toggleFirstrun = (visible = false) => {
|
||||
this.firstrunVisible = visible;
|
||||
store.set('showFirstRun', !!visible);
|
||||
|
||||
// There's no need to write to storage that the
|
||||
// First Run should be visible
|
||||
if (!visible) {
|
||||
store.set(LS_FIRST_RUN_KEY, !!visible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate the old LocalStorage ket format
|
||||
* to the new one
|
||||
*/
|
||||
_migrateStore () {
|
||||
const oldValue = store.get(OLD_LS_FIRST_RUN_KEY);
|
||||
const newValue = store.get(LS_FIRST_RUN_KEY);
|
||||
|
||||
if (newValue === undefined && oldValue !== undefined) {
|
||||
store.set(LS_FIRST_RUN_KEY, oldValue);
|
||||
store.remove(OLD_LS_FIRST_RUN_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
_checkAccounts () {
|
||||
this._api.parity
|
||||
.allAccountsInfo()
|
||||
.then((info) => {
|
||||
return Promise
|
||||
.all([
|
||||
this._api.parity.listVaults(),
|
||||
this._api.parity.allAccountsInfo()
|
||||
])
|
||||
.then(([ vaults, info ]) => {
|
||||
const accounts = Object.keys(info).filter((address) => info[address].uuid);
|
||||
// Has accounts if any vaults or accounts
|
||||
const hasAccounts = (accounts && accounts.length > 0) || (vaults && vaults.length > 0);
|
||||
|
||||
this.toggleFirstrun(this.firstrunVisible || !accounts || !accounts.length);
|
||||
// Show First Run if no accounts and no vaults
|
||||
this.toggleFirstrun(this.firstrunVisible || !hasAccounts);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('checkAccounts', error);
|
||||
|
@ -32,7 +32,8 @@
|
||||
"description": "A registry of transactable tokens on the network",
|
||||
"author": "Parity Team <admin@ethcore.io>",
|
||||
"version": "1.0.0",
|
||||
"visible": true
|
||||
"visible": true,
|
||||
"secure": true
|
||||
},
|
||||
{
|
||||
"id": "0xf49089046f53f5d2e5f3513c1c32f5ff57d986e46309a42d2b249070e4e72c46",
|
||||
|
@ -105,7 +105,7 @@ class WriteContract extends Component {
|
||||
className={ styles.editor }
|
||||
style={ { flex: `${size}%` } }
|
||||
>
|
||||
<h2>asd{ this.renderTitle() }</h2>
|
||||
<h2>{ this.renderTitle() }</h2>
|
||||
|
||||
<Editor
|
||||
ref='editor'
|
||||
|
@ -53,6 +53,9 @@ pub struct Params {
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="eip98Transition")]
|
||||
pub eip98_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(rename="validateReceipts")]
|
||||
pub validate_receipts: Option<bool>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -85,6 +85,7 @@ engine_signer = "0xdeadbeefcafe0000000000000000000000000001"
|
||||
force_sealing = true
|
||||
reseal_on_txs = "all"
|
||||
reseal_min_period = 4000
|
||||
reseal_max_period = 60000
|
||||
work_queue_size = 20
|
||||
relay_set = "cheap"
|
||||
usd_per_tx = "0.0025"
|
||||
|
@ -50,6 +50,7 @@ engine_signer = "0xdeadbeefcafe0000000000000000000000000001"
|
||||
force_sealing = true
|
||||
reseal_on_txs = "all"
|
||||
reseal_min_period = 4000
|
||||
reseal_max_period = 60000
|
||||
price_update_period = "hourly"
|
||||
tx_queue_size = 1024
|
||||
tx_queue_gas = "auto"
|
||||
|
@ -224,6 +224,8 @@ usage! {
|
||||
or |c: &Config| otry!(c.mining).reseal_on_txs.clone(),
|
||||
flag_reseal_min_period: u64 = 2000u64,
|
||||
or |c: &Config| otry!(c.mining).reseal_min_period.clone(),
|
||||
flag_reseal_max_period: u64 = 120000u64,
|
||||
or |c: &Config| otry!(c.mining).reseal_max_period.clone(),
|
||||
flag_work_queue_size: usize = 20usize,
|
||||
or |c: &Config| otry!(c.mining).work_queue_size.clone(),
|
||||
flag_tx_gas_limit: Option<String> = None,
|
||||
@ -460,6 +462,7 @@ struct Mining {
|
||||
force_sealing: Option<bool>,
|
||||
reseal_on_txs: Option<String>,
|
||||
reseal_min_period: Option<u64>,
|
||||
reseal_max_period: Option<u64>,
|
||||
work_queue_size: Option<usize>,
|
||||
tx_gas_limit: Option<String>,
|
||||
tx_time_limit: Option<u64>,
|
||||
@ -701,6 +704,7 @@ mod tests {
|
||||
flag_force_sealing: true,
|
||||
flag_reseal_on_txs: "all".into(),
|
||||
flag_reseal_min_period: 4000u64,
|
||||
flag_reseal_max_period: 60000u64,
|
||||
flag_work_queue_size: 20usize,
|
||||
flag_tx_gas_limit: Some("6283184".into()),
|
||||
flag_tx_time_limit: Some(100u64),
|
||||
@ -900,6 +904,7 @@ mod tests {
|
||||
force_sealing: Some(true),
|
||||
reseal_on_txs: Some("all".into()),
|
||||
reseal_min_period: Some(4000),
|
||||
reseal_max_period: Some(60000),
|
||||
work_queue_size: None,
|
||||
relay_set: None,
|
||||
usd_per_tx: None,
|
||||
|
@ -224,6 +224,9 @@ Sealing/Mining Options:
|
||||
--reseal-min-period MS Specify the minimum time between reseals from
|
||||
incoming transactions. MS is time measured in
|
||||
milliseconds (default: {flag_reseal_min_period}).
|
||||
--reseal-max-period MS Specify the maximum time since last block to enable
|
||||
force-sealing. MS is time measured in
|
||||
milliseconds (default: {flag_reseal_max_period}).
|
||||
--work-queue-size ITEMS Specify the number of historical work packages
|
||||
which are kept cached lest a solution is found for
|
||||
them later. High values take more memory but result
|
||||
|
@ -522,6 +522,7 @@ impl Configuration {
|
||||
tx_queue_strategy: to_queue_strategy(&self.args.flag_tx_queue_strategy)?,
|
||||
pending_set: to_pending_set(&self.args.flag_relay_set)?,
|
||||
reseal_min_period: Duration::from_millis(reseal_min_period),
|
||||
reseal_max_period: Duration::from_millis(self.args.flag_reseal_max_period),
|
||||
work_queue_size: self.args.flag_work_queue_size,
|
||||
enable_resubmission: !self.args.flag_remove_solved,
|
||||
tx_queue_banning: match self.args.flag_tx_time_limit {
|
||||
|
@ -32,7 +32,6 @@ mod codes {
|
||||
pub const NO_WORK: i64 = -32001;
|
||||
pub const NO_AUTHOR: i64 = -32002;
|
||||
pub const NO_NEW_WORK: i64 = -32003;
|
||||
pub const NOT_ENOUGH_DATA: i64 = -32006;
|
||||
pub const UNKNOWN_ERROR: i64 = -32009;
|
||||
pub const TRANSACTION_ERROR: i64 = -32010;
|
||||
pub const EXECUTION_ERROR: i64 = -32015;
|
||||
@ -41,9 +40,6 @@ mod codes {
|
||||
pub const ACCOUNT_LOCKED: i64 = -32020;
|
||||
pub const PASSWORD_INVALID: i64 = -32021;
|
||||
pub const ACCOUNT_ERROR: i64 = -32023;
|
||||
pub const SIGNER_DISABLED: i64 = -32030;
|
||||
pub const DAPPS_DISABLED: i64 = -32031;
|
||||
pub const NETWORK_DISABLED: i64 = -32035;
|
||||
pub const REQUEST_REJECTED: i64 = -32040;
|
||||
pub const REQUEST_REJECTED_LIMIT: i64 = -32041;
|
||||
pub const REQUEST_NOT_FOUND: i64 = -32042;
|
||||
@ -174,9 +170,9 @@ pub fn no_author() -> Error {
|
||||
|
||||
pub fn not_enough_data() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::NOT_ENOUGH_DATA),
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
message: "The node does not have enough data to compute the given statistic.".into(),
|
||||
data: None
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,25 +186,25 @@ pub fn token(e: String) -> Error {
|
||||
|
||||
pub fn signer_disabled() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::SIGNER_DISABLED),
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
message: "Trusted Signer is disabled. This API is not available.".into(),
|
||||
data: None
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dapps_disabled() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::DAPPS_DISABLED),
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
message: "Dapps Server is disabled. This API is not available.".into(),
|
||||
data: None
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn network_disabled() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::NETWORK_DISABLED),
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
message: "Network is disabled or not yet up.".into(),
|
||||
data: None
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,7 +317,7 @@ pub fn from_call_error(error: CallError) -> Error {
|
||||
|
||||
pub fn unknown_block() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
code: ErrorCode::InvalidParams,
|
||||
message: "Unknown block number".into(),
|
||||
data: None,
|
||||
}
|
||||
|
43
rpc/src/v1/helpers/fake_sign.rs
Normal file
43
rpc/src/v1/helpers/fake_sign.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::sync::Weak;
|
||||
use ethcore::client::MiningBlockChainClient;
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::transaction::{Transaction, SignedTransaction, Action};
|
||||
|
||||
use jsonrpc_core::Error;
|
||||
use v1::helpers::CallRequest;
|
||||
use v1::helpers::dispatch::default_gas_price;
|
||||
|
||||
pub fn sign_call<B: MiningBlockChainClient, M: MinerService>(
|
||||
client: &Weak<B>,
|
||||
miner: &Weak<M>,
|
||||
request: CallRequest,
|
||||
) -> Result<SignedTransaction, Error> {
|
||||
let client = take_weak!(client);
|
||||
let miner = take_weak!(miner);
|
||||
let from = request.from.unwrap_or(0.into());
|
||||
|
||||
Ok(Transaction {
|
||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or(50_000_000.into()),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)),
|
||||
value: request.value.unwrap_or(0.into()),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
}.fake_sign(from))
|
||||
}
|
@ -19,6 +19,7 @@ pub mod errors;
|
||||
|
||||
pub mod block_import;
|
||||
pub mod dispatch;
|
||||
pub mod fake_sign;
|
||||
pub mod informant;
|
||||
pub mod oneshot;
|
||||
|
||||
|
@ -23,7 +23,7 @@ use std::sync::{Arc, Weak};
|
||||
use futures::{self, future, BoxFuture, Future};
|
||||
use rlp::{self, UntrustedRlp, View};
|
||||
use time::get_time;
|
||||
use util::{H160, H256, Address, U256, H64, Uint};
|
||||
use util::{H160, H256, Address, U256, H64};
|
||||
use util::sha3::Hashable;
|
||||
use util::Mutex;
|
||||
|
||||
@ -36,14 +36,14 @@ use ethcore::filter::Filter as EthcoreFilter;
|
||||
use ethcore::header::{Header as BlockHeader, BlockNumber as EthBlockNumber};
|
||||
use ethcore::log_entry::LogEntry;
|
||||
use ethcore::miner::{MinerService, ExternalMinerService};
|
||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethsync::{SyncProvider};
|
||||
|
||||
use jsonrpc_core::Error;
|
||||
use jsonrpc_macros::Trailing;
|
||||
|
||||
use v1::helpers::{CallRequest as CRequest, errors, limit_logs};
|
||||
use v1::helpers::{errors, limit_logs, fake_sign};
|
||||
use v1::helpers::dispatch::{Dispatcher, FullDispatcher, default_gas_price};
|
||||
use v1::helpers::block_import::is_major_importing;
|
||||
use v1::traits::Eth;
|
||||
@ -222,19 +222,6 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
||||
Ok(Some(block))
|
||||
}
|
||||
|
||||
fn sign_call(&self, request: CRequest) -> Result<SignedTransaction, Error> {
|
||||
let (client, miner) = (take_weak!(self.client), take_weak!(self.miner));
|
||||
let from = request.from.unwrap_or(Address::zero());
|
||||
Ok(EthTransaction {
|
||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or(U256::from(50_000_000)),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)),
|
||||
value: request.value.unwrap_or_else(U256::zero),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
}.fake_sign(from))
|
||||
}
|
||||
|
||||
fn dapp_accounts(&self, dapp: DappId) -> Result<Vec<H160>, Error> {
|
||||
let store = take_weak!(self.accounts);
|
||||
store
|
||||
@ -654,7 +641,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
|
||||
fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
|
||||
let request = CallRequest::into(request);
|
||||
let signed = match self.sign_call(request) {
|
||||
let signed = match fake_sign::sign_call(&self.client, &self.miner, request) {
|
||||
Ok(signed) => signed,
|
||||
Err(e) => return future::err(e).boxed(),
|
||||
};
|
||||
@ -672,7 +659,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
|
||||
fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
||||
let request = CallRequest::into(request);
|
||||
let signed = match self.sign_call(request) {
|
||||
let signed = match fake_sign::sign_call(&self.client, &self.miner, request) {
|
||||
Ok(signed) => signed,
|
||||
Err(e) => return future::err(e).boxed(),
|
||||
};
|
||||
|
@ -27,15 +27,15 @@ use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, By
|
||||
pub struct TracesClient;
|
||||
|
||||
impl Traces for TracesClient {
|
||||
fn filter(&self, _filter: TraceFilter) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
fn filter(&self, _filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn block_traces(&self, _block_number: BlockNumber) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
fn block_traces(&self, _block_number: BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn transaction_traces(&self, _transaction_hash: H256) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
fn transaction_traces(&self, _transaction_hash: H256) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
@ -43,15 +43,15 @@ impl Traces for TracesClient {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn call(&self, _request: CallRequest, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
||||
fn call(&self, _request: CallRequest, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn raw_transaction(&self, _raw_transaction: Bytes, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
||||
fn raw_transaction(&self, _raw_transaction: Bytes, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
|
||||
fn replay_transaction(&self, _transaction_hash: H256, _flags: Vec<String>) -> Result<Option<TraceResults>, Error> {
|
||||
fn replay_transaction(&self, _transaction_hash: H256, _flags: Vec<String>) -> Result<TraceResults, Error> {
|
||||
Err(errors::light_unimplemented(None))
|
||||
}
|
||||
}
|
||||
|
@ -19,14 +19,14 @@
|
||||
use std::sync::{Weak, Arc};
|
||||
|
||||
use rlp::{UntrustedRlp, View};
|
||||
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId};
|
||||
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
|
||||
use ethcore::transaction::SignedTransaction;
|
||||
|
||||
use jsonrpc_core::Error;
|
||||
use jsonrpc_macros::Trailing;
|
||||
use v1::traits::Traces;
|
||||
use v1::helpers::{errors, CallRequest as CRequest};
|
||||
use v1::helpers::{errors, fake_sign};
|
||||
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
||||
|
||||
fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
|
||||
@ -38,12 +38,12 @@ fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
|
||||
}
|
||||
|
||||
/// Traces api implementation.
|
||||
pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
||||
pub struct TracesClient<C, M> {
|
||||
client: Weak<C>,
|
||||
miner: Weak<M>,
|
||||
}
|
||||
|
||||
impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
||||
impl<C, M> TracesClient<C, M> {
|
||||
/// Creates new Traces client.
|
||||
pub fn new(client: &Arc<C>, miner: &Arc<M>) -> Self {
|
||||
TracesClient {
|
||||
@ -51,86 +51,59 @@ impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
||||
miner: Arc::downgrade(miner),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: share with eth.rs
|
||||
fn sign_call(&self, request: CRequest) -> Result<SignedTransaction, Error> {
|
||||
let client = take_weak!(self.client);
|
||||
let miner = take_weak!(self.miner);
|
||||
let from = request.from.unwrap_or(0.into());
|
||||
Ok(EthTransaction {
|
||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or(50_000_000.into()),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()),
|
||||
value: request.value.unwrap_or(0.into()),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
}.fake_sign(from))
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M: MinerService + 'static {
|
||||
fn filter(&self, filter: TraceFilter) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.filter_traces(filter.into());
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(traces)
|
||||
impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'static, M: MinerService + 'static {
|
||||
fn filter(&self, filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||
Ok(take_weak!(self.client).filter_traces(filter.into())
|
||||
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||
}
|
||||
|
||||
fn block_traces(&self, block_number: BlockNumber) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.block_traces(block_number.into());
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(traces)
|
||||
fn block_traces(&self, block_number: BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||
Ok(take_weak!(self.client).block_traces(block_number.into())
|
||||
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||
}
|
||||
|
||||
fn transaction_traces(&self, transaction_hash: H256) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.transaction_traces(TransactionId::Hash(transaction_hash.into()));
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(traces)
|
||||
fn transaction_traces(&self, transaction_hash: H256) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||
Ok(take_weak!(self.client).transaction_traces(TransactionId::Hash(transaction_hash.into()))
|
||||
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||
}
|
||||
|
||||
fn trace(&self, transaction_hash: H256, address: Vec<Index>) -> Result<Option<LocalizedTrace>, Error> {
|
||||
let client = take_weak!(self.client);
|
||||
let id = TraceId {
|
||||
transaction: TransactionId::Hash(transaction_hash.into()),
|
||||
address: address.into_iter().map(|i| i.value()).collect()
|
||||
};
|
||||
let trace = client.trace(id);
|
||||
let trace = trace.map(LocalizedTrace::from);
|
||||
|
||||
Ok(trace)
|
||||
Ok(take_weak!(self.client).trace(id)
|
||||
.map(LocalizedTrace::from))
|
||||
}
|
||||
|
||||
fn call(&self, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
||||
fn call(&self, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||
let block = block.0;
|
||||
|
||||
let request = CallRequest::into(request);
|
||||
let signed = self.sign_call(request)?;
|
||||
Ok(match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
||||
Ok(e) => Some(TraceResults::from(e)),
|
||||
_ => None,
|
||||
})
|
||||
let signed = fake_sign::sign_call(&self.client, &self.miner, request)?;
|
||||
|
||||
take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags))
|
||||
.map(TraceResults::from)
|
||||
.map_err(errors::from_call_error)
|
||||
}
|
||||
|
||||
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
||||
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||
let block = block.0;
|
||||
|
||||
UntrustedRlp::new(&raw_transaction.into_vec()).as_val()
|
||||
.map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))
|
||||
.and_then(|tx| SignedTransaction::new(tx).map_err(errors::from_transaction_error))
|
||||
.and_then(|signed| {
|
||||
Ok(match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
||||
Ok(e) => Some(TraceResults::from(e)),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
let tx = UntrustedRlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?;
|
||||
let signed = SignedTransaction::new(tx).map_err(errors::from_transaction_error)?;
|
||||
|
||||
take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags))
|
||||
.map(TraceResults::from)
|
||||
.map_err(errors::from_call_error)
|
||||
}
|
||||
|
||||
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<Option<TraceResults>, Error> {
|
||||
Ok(match take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags)) {
|
||||
Ok(e) => Some(TraceResults::from(e)),
|
||||
_ => None,
|
||||
})
|
||||
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<TraceResults, Error> {
|
||||
take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags))
|
||||
.map(TraceResults::from)
|
||||
.map_err(errors::from_call_error)
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ fn miner_service(spec: &Spec, accounts: Arc<AccountProvider>) -> Arc<Miner> {
|
||||
tx_queue_banning: Banning::Disabled,
|
||||
pending_set: PendingSet::SealingOrElseQueue,
|
||||
reseal_min_period: Duration::from_secs(0),
|
||||
reseal_max_period: Duration::from_secs(120),
|
||||
work_queue_size: 50,
|
||||
enable_resubmission: true,
|
||||
refuse_service_transactions: false,
|
||||
|
@ -901,7 +901,7 @@ fn rpc_eth_send_transaction_with_bad_to() {
|
||||
"id": 1
|
||||
}"#;
|
||||
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid length."},"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: expected a hex-encoded hash with 0x prefix."},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(&request), Some(response.into()));
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ fn rpc_parity_unsigned_transactions_count_when_signer_disabled() {
|
||||
let io = deps.default_client();
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available."},"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available."},"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
@ -393,7 +393,7 @@ fn rpc_parity_signer_port() {
|
||||
// when
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_signerPort", "params": [], "id": 1}"#;
|
||||
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
|
||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available."},"id":1}"#;
|
||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available."},"id":1}"#;
|
||||
|
||||
// then
|
||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||
@ -411,7 +411,7 @@ fn rpc_parity_dapps_port() {
|
||||
// when
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsPort", "params": [], "id": 1}"#;
|
||||
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
|
||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available."},"id":1}"#;
|
||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available."},"id":1}"#;
|
||||
|
||||
// then
|
||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||
@ -429,7 +429,7 @@ fn rpc_parity_dapps_interface() {
|
||||
// when
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsInterface", "params": [], "id": 1}"#;
|
||||
let response1 = r#"{"jsonrpc":"2.0","result":"127.0.0.1","id":1}"#;
|
||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available."},"id":1}"#;
|
||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available."},"id":1}"#;
|
||||
|
||||
// then
|
||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||
|
@ -230,7 +230,7 @@ fn should_be_able_to_kill_account() {
|
||||
let address = accounts[0];
|
||||
|
||||
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_killAccount", "params": ["0xf00baba2f00baba2f00baba2f00baba2f00baba2"], "id": 1}}"#);
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"invalid length 1, expected a tuple of size 2"},"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: invalid length 1, expected a tuple of size 2."},"id":1}"#;
|
||||
let res = tester.io.handle_request_sync(&request);
|
||||
assert_eq!(res, Some(response.into()));
|
||||
|
||||
|
@ -16,17 +16,17 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethcore::executed::{CallType, Executed};
|
||||
use ethcore::executed::{CallType, Executed, CallError};
|
||||
use ethcore::trace::trace::{Action, Res, Call};
|
||||
use ethcore::trace::LocalizedTrace;
|
||||
use ethcore::client::{TestBlockChainClient};
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
|
||||
use jsonrpc_core::IoHandler;
|
||||
use v1::tests::helpers::{TestMinerService};
|
||||
use v1::{Traces, TracesClient};
|
||||
|
||||
struct Tester {
|
||||
_client: Arc<TestBlockChainClient>,
|
||||
client: Arc<TestBlockChainClient>,
|
||||
_miner: Arc<TestMinerService>,
|
||||
io: IoHandler,
|
||||
}
|
||||
@ -69,7 +69,7 @@ fn io() -> Tester {
|
||||
io.extend_with(traces.to_delegate());
|
||||
|
||||
Tester {
|
||||
_client: client,
|
||||
client: client,
|
||||
_miner: miner,
|
||||
io: io,
|
||||
}
|
||||
@ -85,6 +85,17 @@ fn rpc_trace_filter() {
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_filter_missing_trace() {
|
||||
let tester = io();
|
||||
*tester.client.traces.write() = None;
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_filter","params": [{}],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_block() {
|
||||
let tester = io();
|
||||
@ -95,6 +106,17 @@ fn rpc_trace_block() {
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_block_missing_traces() {
|
||||
let tester = io();
|
||||
*tester.client.traces.write() = None;
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_block","params": ["0x10"],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_transaction() {
|
||||
let tester = io();
|
||||
@ -105,6 +127,17 @@ fn rpc_trace_transaction() {
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_transaction_missing_trace() {
|
||||
let tester = io();
|
||||
*tester.client.traces.write() = None;
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_transaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005"],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_get() {
|
||||
let tester = io();
|
||||
@ -115,6 +148,16 @@ fn rpc_trace_get() {
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_get_missing_trace() {
|
||||
let tester = io();
|
||||
*tester.client.traces.write() = None;
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_get","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["0","0","0"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_call() {
|
||||
let tester = io();
|
||||
@ -125,6 +168,17 @@ fn rpc_trace_call() {
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_call_state_pruned() {
|
||||
let tester = io();
|
||||
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_raw_transaction() {
|
||||
let tester = io();
|
||||
@ -135,6 +189,17 @@ fn rpc_trace_raw_transaction() {
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_raw_transaction_state_pruned() {
|
||||
let tester = io();
|
||||
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_replay_transaction() {
|
||||
let tester = io();
|
||||
@ -144,3 +209,14 @@ fn rpc_trace_replay_transaction() {
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_replay_transaction_state_pruned() {
|
||||
let tester = io();
|
||||
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ build_rpc_trait! {
|
||||
pub trait Traces {
|
||||
/// Returns traces matching given filter.
|
||||
#[rpc(name = "trace_filter")]
|
||||
fn filter(&self, TraceFilter) -> Result<Vec<LocalizedTrace>, Error>;
|
||||
fn filter(&self, TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||
|
||||
/// Returns transaction trace at given index.
|
||||
#[rpc(name = "trace_get")]
|
||||
@ -33,22 +33,22 @@ build_rpc_trait! {
|
||||
|
||||
/// Returns all traces of given transaction.
|
||||
#[rpc(name = "trace_transaction")]
|
||||
fn transaction_traces(&self, H256) -> Result<Vec<LocalizedTrace>, Error>;
|
||||
fn transaction_traces(&self, H256) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||
|
||||
/// Returns all traces produced at given block.
|
||||
#[rpc(name = "trace_block")]
|
||||
fn block_traces(&self, BlockNumber) -> Result<Vec<LocalizedTrace>, Error>;
|
||||
fn block_traces(&self, BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||
|
||||
/// Executes the given call and returns a number of possible traces for it.
|
||||
#[rpc(name = "trace_call")]
|
||||
fn call(&self, CallRequest, Vec<String>, Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error>;
|
||||
fn call(&self, CallRequest, Vec<String>, Trailing<BlockNumber>) -> Result<TraceResults, Error>;
|
||||
|
||||
/// Executes the given raw transaction and returns a number of possible traces for it.
|
||||
#[rpc(name = "trace_rawTransaction")]
|
||||
fn raw_transaction(&self, Bytes, Vec<String>, Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error>;
|
||||
fn raw_transaction(&self, Bytes, Vec<String>, Trailing<BlockNumber>) -> Result<TraceResults, Error>;
|
||||
|
||||
/// Executes the transaction with the given hash and returns a number of possible traces for it.
|
||||
#[rpc(name = "trace_replayTransaction")]
|
||||
fn replay_transaction(&self, H256, Vec<String>) -> Result<Option<TraceResults>, Error>;
|
||||
fn replay_transaction(&self, H256, Vec<String>) -> Result<TraceResults, Error>;
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ macro_rules! impl_hash {
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
|
||||
if value.len() < 2 || &value[0..2] != "0x" {
|
||||
return Err(E::custom("Expected hex-encoded hash with 0x prefix."));
|
||||
return Err(E::custom("expected a hex-encoded hash with 0x prefix"));
|
||||
}
|
||||
if value.len() != 2 + $size * 2 {
|
||||
return Err(E::invalid_length(value.len() - 2, &self));
|
||||
@ -142,7 +142,7 @@ macro_rules! impl_hash {
|
||||
result.copy_from_slice(v);
|
||||
Ok($name(result))
|
||||
},
|
||||
Err(e) => Err(E::custom(format!("Invalid hex value: {:?}", e))),
|
||||
Err(e) => Err(E::custom(format!("invalid hex value: {:?}", e))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ macro_rules! impl_uint {
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
if value.len() < 2 || &value[0..2] != "0x" {
|
||||
return Err(E::custom("Use hex-encoded numbers with 0x prefix."))
|
||||
return Err(E::custom("expected a hex-encoded numbers with 0x prefix"))
|
||||
}
|
||||
|
||||
// 0x + len
|
||||
@ -87,7 +87,7 @@ macro_rules! impl_uint {
|
||||
return Err(E::invalid_length(value.len() - 2, &self));
|
||||
}
|
||||
|
||||
$other::from_str(&value[2..]).map($name).map_err(|e| E::custom(&format!("Invalid hex value: {:?}", e)))
|
||||
$other::from_str(&value[2..]).map($name).map_err(|e| E::custom(&format!("invalid hex value: {:?}", e)))
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, value: String) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# Installing KCOV under ubuntu
|
||||
# https://users.rust-lang.org/t/tutorial-how-to-collect-test-coverages-for-rust-project/650#
|
||||
### Install deps
|
||||
@ -24,8 +24,7 @@ fi
|
||||
cargo test $TARGETS --no-run || exit $?
|
||||
|
||||
|
||||
|
||||
KCOV_TARGET="target/kcov"
|
||||
KCOV_TARGET="target/cov"
|
||||
KCOV_FLAGS="--verify"
|
||||
EXCLUDE="/usr/lib,\
|
||||
/usr/include,\
|
||||
@ -39,17 +38,25 @@ util/src/network/tests,\
|
||||
ethcore/src/evm/tests,\
|
||||
ethstore/tests,\
|
||||
target/debug/build,\
|
||||
target/release/build\
|
||||
target/release/build,\
|
||||
*.db
|
||||
"
|
||||
|
||||
rm -rf $KCOV_TARGET
|
||||
mkdir -p $KCOV_TARGET
|
||||
|
||||
echo "Cover RUST"
|
||||
for FILE in `find target/debug/deps ! -name "*.*"`
|
||||
do
|
||||
$KCOV --exclude-pattern $EXCLUDE $KCOV_FLAGS $KCOV_TARGET $FILE
|
||||
done
|
||||
|
||||
$KCOV --coveralls-id=${CI_BUILD_ID} --exclude-pattern $EXCLUDE $KCOV_FLAGS $KCOV_TARGET target/debug/parity-*
|
||||
$KCOV --exclude-pattern $EXCLUDE $KCOV_FLAGS $KCOV_TARGET target/debug/parity-*
|
||||
echo "Cover JS"
|
||||
cd js
|
||||
npm install&&npm run test:coverage
|
||||
cd ..
|
||||
codecov
|
||||
bash <(curl -s https://codecov.io/bash)&&
|
||||
echo "Uploaded code coverage"
|
||||
|
||||
exit 0
|
||||
|
@ -25,7 +25,7 @@ echo "Homepage: https://ethcore.io" >> $control
|
||||
echo "Vcs-Git: git://github.com/ethcore/parity.git" >> $control
|
||||
echo "Vcs-Browser: https://github.com/ethcore/parity" >> $control
|
||||
echo "Architecture: $1" >> $control
|
||||
echo "Depends: libssl1.0.0 (>=1.0.0), libudev-dev" >> $control
|
||||
echo "Depends: libssl1.0.0 (>=1.0.0)" >> $control
|
||||
echo "Description: Ethereum network client by Ethcore" >> $control
|
||||
#build .deb package
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
cd docker/hub
|
||||
docker build --build-arg BUILD_TAG=$1 --no-cache=true --tag ethcore/parity:$1 .
|
||||
if [ "$1" == "latest" ]; then DOCKER_BUILD_TAG="beta-release"; fi
|
||||
docker build --build-arg BUILD_TAG=$DOCKER_BUILD_TAG --no-cache=true --tag ethcore/parity:$1 .
|
||||
docker push ethcore/parity:$1
|
||||
|
Loading…
Reference in New Issue
Block a user