Merge branch 'master' into serdeup
This commit is contained in:
commit
1c2a4c116a
46
Cargo.lock
generated
46
Cargo.lock
generated
@ -311,7 +311,7 @@ version = "0.5.6"
|
|||||||
source = "git+https://github.com/paritytech/rust-secp256k1#b6b67055edc929057e97d64f036c78ad91f58a7f"
|
source = "git+https://github.com/paritytech/rust-secp256k1#b6b67055edc929057e97d64f036c78ad91f58a7f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (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)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -794,7 +794,7 @@ version = "0.2.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -824,10 +824,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.43"
|
version = "0.3.51"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -900,7 +900,7 @@ name = "hidapi"
|
|||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "git+https://github.com/paritytech/hidapi-rs#9a127c1dca7e327e4fdd428406a76c9f5ef48563"
|
source = "git+https://github.com/paritytech/hidapi-rs#9a127c1dca7e327e4fdd428406a76c9f5ef48563"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1193,7 +1193,7 @@ name = "libusb-sys"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "git+https://github.com/paritytech/libusb-sys#c10b1180646c9dc3f23a9b6bb825abcd3b7487ce"
|
source = "git+https://github.com/paritytech/libusb-sys#c10b1180646c9dc3f23a9b6bb825abcd3b7487ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1264,10 +1264,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz-sys"
|
name = "miniz-sys"
|
||||||
version = "0.1.7"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1372,7 +1372,7 @@ name = "nanomsg-sys"
|
|||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920"
|
source = "git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1545,7 +1545,7 @@ name = "openssl-sys"
|
|||||||
version = "0.9.13"
|
version = "0.9.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1824,7 +1824,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-precompiled"
|
name = "parity-ui-precompiled"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "git+https://github.com/paritytech/js-precompiled.git#7dc30d69a4e15b1fc22d3d25939a177f0979df07"
|
source = "git+https://github.com/paritytech/js-precompiled.git#d046d5b5393e90617f4d9a51a5af90fbe516793d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2036,17 +2036,6 @@ dependencies = [
|
|||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rayon"
|
|
||||||
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)",
|
|
||||||
"libc 0.2.21 (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)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -2109,7 +2098,7 @@ name = "ring"
|
|||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2142,7 +2131,7 @@ name = "rocksdb-sys"
|
|||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/paritytech/rust-rocksdb#4364caec4dd5da1a1d78c39276774ee65bf55c7d"
|
source = "git+https://github.com/paritytech/rust-rocksdb#4364caec4dd5da1a1d78c39276774ee65bf55c7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2197,7 +2186,7 @@ name = "rust-crypto"
|
|||||||
version = "0.2.36"
|
version = "0.2.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (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)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2359,7 +2348,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "sha3"
|
name = "sha3"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2934,7 +2923,7 @@ dependencies = [
|
|||||||
"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d"
|
"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d"
|
||||||
"checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d"
|
"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 futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82"
|
||||||
"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
|
"checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a"
|
||||||
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
||||||
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
|
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
|
||||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||||
@ -2981,7 +2970,7 @@ dependencies = [
|
|||||||
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
||||||
"checksum mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a74cc2587bf97c49f3f5bab62860d6abf3902ca73b66b51d9b049fbdcd727bd2"
|
"checksum mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a74cc2587bf97c49f3f5bab62860d6abf3902ca73b66b51d9b049fbdcd727bd2"
|
||||||
"checksum mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e50bf542f81754ef69e5cea856946a3819f7c09ea97b4903c8bc8a89f74e7b6"
|
"checksum mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e50bf542f81754ef69e5cea856946a3819f7c09ea97b4903c8bc8a89f74e7b6"
|
||||||
"checksum miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1f4d337a01c32e1f2122510fed46393d53ca35a7f429cb0450abaedfa3ed54"
|
"checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726"
|
||||||
"checksum mio 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ba718a36791275c6782c0445a5f79b5ef4e68c01a4e60ac04aae28290e4957"
|
"checksum mio 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ba718a36791275c6782c0445a5f79b5ef4e68c01a4e60ac04aae28290e4957"
|
||||||
"checksum mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)" = "<none>"
|
"checksum mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)" = "<none>"
|
||||||
"checksum mio-uds 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "78437f00d9615c366932cbfe79790b5c2945706ba67cf78378ffacc0069ed9de"
|
"checksum mio-uds 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "78437f00d9615c366932cbfe79790b5c2945706ba67cf78378ffacc0069ed9de"
|
||||||
@ -3037,7 +3026,6 @@ dependencies = [
|
|||||||
"checksum quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6683b0e23d80813b1a535841f0048c1537d3f86d63c999e8373b39a9b0eb74a"
|
"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 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 rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||||
"checksum rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50c575b58c2b109e2fbc181820cbe177474f35610ff9e357dc75f6bac854ffbf"
|
|
||||||
"checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"
|
"checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"
|
||||||
"checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"
|
"checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"
|
||||||
"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
|
"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
|
||||||
|
@ -453,11 +453,14 @@ impl Ethash {
|
|||||||
let parent_has_uncles = parent.uncles_hash() != &sha3::SHA3_EMPTY_LIST_RLP;
|
let parent_has_uncles = parent.uncles_hash() != &sha3::SHA3_EMPTY_LIST_RLP;
|
||||||
|
|
||||||
let min_difficulty = self.ethash_params.minimum_difficulty;
|
let min_difficulty = self.ethash_params.minimum_difficulty;
|
||||||
|
|
||||||
let difficulty_hardfork = header.number() >= self.ethash_params.difficulty_hardfork_transition;
|
let difficulty_hardfork = header.number() >= self.ethash_params.difficulty_hardfork_transition;
|
||||||
let difficulty_bound_divisor = match difficulty_hardfork {
|
let difficulty_bound_divisor = if difficulty_hardfork {
|
||||||
true => self.ethash_params.difficulty_hardfork_bound_divisor,
|
self.ethash_params.difficulty_hardfork_bound_divisor
|
||||||
false => self.ethash_params.difficulty_bound_divisor,
|
} else {
|
||||||
|
self.ethash_params.difficulty_bound_divisor
|
||||||
};
|
};
|
||||||
|
|
||||||
let duration_limit = self.ethash_params.duration_limit;
|
let duration_limit = self.ethash_params.duration_limit;
|
||||||
let frontier_limit = self.ethash_params.homestead_transition;
|
let frontier_limit = self.ethash_params.homestead_transition;
|
||||||
|
|
||||||
@ -483,7 +486,10 @@ impl Ethash {
|
|||||||
if diff_inc <= threshold {
|
if diff_inc <= threshold {
|
||||||
*parent.difficulty() + *parent.difficulty() / difficulty_bound_divisor * (threshold - diff_inc).into()
|
*parent.difficulty() + *parent.difficulty() / difficulty_bound_divisor * (threshold - diff_inc).into()
|
||||||
} else {
|
} else {
|
||||||
*parent.difficulty() - *parent.difficulty() / difficulty_bound_divisor * min(diff_inc - threshold, 99).into()
|
let multiplier = min(diff_inc - threshold, 99).into();
|
||||||
|
parent.difficulty().saturating_sub(
|
||||||
|
*parent.difficulty() / difficulty_bound_divisor * multiplier
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
target = max(min_difficulty, target);
|
target = max(min_difficulty, target);
|
||||||
|
@ -7,8 +7,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
ethkey = { path = "../" }
|
ethkey = { path = "../" }
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
rustc-hex = "1.0"
|
|
||||||
docopt = "0.8"
|
docopt = "0.8"
|
||||||
|
rustc-hex = "1.0"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "ethkey"
|
name = "ethkey"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "1.7.96",
|
"version": "1.7.97",
|
||||||
"main": "release/index.js",
|
"main": "release/index.js",
|
||||||
"jsnext:main": "src/index.js",
|
"jsnext:main": "src/index.js",
|
||||||
"author": "Parity Team <admin@parity.io>",
|
"author": "Parity Team <admin@parity.io>",
|
||||||
|
@ -21,6 +21,7 @@ import Contract from './contract';
|
|||||||
|
|
||||||
import { Db, Eth, Parity, Net, Personal, Shh, Signer, Trace, Web3 } from './rpc';
|
import { Db, Eth, Parity, Net, Personal, Shh, Signer, Trace, Web3 } from './rpc';
|
||||||
import Subscriptions from './subscriptions';
|
import Subscriptions from './subscriptions';
|
||||||
|
import Pubsub from './pubsub';
|
||||||
import util from './util';
|
import util from './util';
|
||||||
import { isFunction } from './util/types';
|
import { isFunction } from './util/types';
|
||||||
|
|
||||||
@ -46,10 +47,13 @@ export default class Api extends EventEmitter {
|
|||||||
this._trace = new Trace(transport);
|
this._trace = new Trace(transport);
|
||||||
this._web3 = new Web3(transport);
|
this._web3 = new Web3(transport);
|
||||||
|
|
||||||
|
if (isFunction(transport.subscribe)) {
|
||||||
|
this._pubsub = new Pubsub(transport);
|
||||||
|
}
|
||||||
|
|
||||||
if (allowSubscriptions) {
|
if (allowSubscriptions) {
|
||||||
this._subscriptions = new Subscriptions(this);
|
this._subscriptions = new Subscriptions(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doing a request here in test env would cause an error
|
// Doing a request here in test env would cause an error
|
||||||
if (LocalAccountsMiddleware && process.env.NODE_ENV !== 'test') {
|
if (LocalAccountsMiddleware && process.env.NODE_ENV !== 'test') {
|
||||||
const middleware = this.parity
|
const middleware = this.parity
|
||||||
@ -67,6 +71,13 @@ export default class Api extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get pubsub () {
|
||||||
|
if (!this._pubsub) {
|
||||||
|
throw Error('Pubsub is only available with a subscribing-supported transport injected!');
|
||||||
|
}
|
||||||
|
return this._pubsub;
|
||||||
|
}
|
||||||
|
|
||||||
get db () {
|
get db () {
|
||||||
return this._db;
|
return this._db;
|
||||||
}
|
}
|
||||||
|
227
js/src/api/pubsub/eth/eth.js
Normal file
227
js/src/api/pubsub/eth/eth.js
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
import PubsubBase from '../pubsubBase';
|
||||||
|
|
||||||
|
import { inAddress, inBlockNumber, inHex, inNumber16, inOptions, inFilter } from '../../format/input';
|
||||||
|
import { outAddress, outBlock, outNumber, outTransaction, outSyncing, outReceipt, outLog } from '../../format/output';
|
||||||
|
|
||||||
|
export default class Eth extends PubsubBase {
|
||||||
|
constructor (transport) {
|
||||||
|
super(transport);
|
||||||
|
this._api = 'parity';
|
||||||
|
}
|
||||||
|
|
||||||
|
newHeads (callback) {
|
||||||
|
return this.addListener('eth', 'newHeads', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
logs (callback) {
|
||||||
|
throw Error('not supported yet');
|
||||||
|
}
|
||||||
|
|
||||||
|
// eth API
|
||||||
|
protocolVersion (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_protocolVersion', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
syncing (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_syncing', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outSyncing(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hashrate (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_hashrate', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
coinbase (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_coinbase', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddress(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mining (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_mining', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
gasPrice (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_gasPrice', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
accounts (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_accounts', (error, accounts) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, (accounts || []).map(outAddress));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
blockNumber (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_blockNumber', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getBalance (callback, address, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'eth_getBalance', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inAddress(address), inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getStorageAt (callback, address, index = 0, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'eth_getStorageAt', callback, [inAddress(address), inNumber16(index), inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlockByHash (callback, hash, full = false) {
|
||||||
|
return this.addListener(this._api, 'eth_getBlockByHash', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outBlock(data));
|
||||||
|
}, [inHex(hash), full]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlockByNumber (callback, blockNumber = 'latest', full = false) {
|
||||||
|
return this.addListener(this._api, 'eth_getBlockByNumber', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outBlock(data));
|
||||||
|
}, [inBlockNumber(blockNumber), full]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransactionCount (callback, address, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'eth_getTransactionCount', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inAddress(address), inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlockTransactionCountByHash (callback, hash) {
|
||||||
|
return this.addListener(this._api, 'eth_getBlockTransactionCountByHash', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inHex(hash)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlockTransactionCountByNumber (callback, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'eth_getBlockTransactionCountByNumber', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUncleCountByBlockHash (callback, hash) {
|
||||||
|
return this.addListener(this._api, 'eth_getUncleCountByBlockHash', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inHex(hash)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUncleCountByBlockNumber (callback, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'eth_getUncleCountByBlockNumber', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCode (callback, address, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'eth_getCode', callback, [inAddress(address), inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
call (callback, options, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'eth_call', callback, [inOptions(options), inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
estimateGas (callback, options) {
|
||||||
|
return this.addListener(this._api, 'eth_estimateGas', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inOptions(options)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransactionByHash (callback, hash) {
|
||||||
|
return this.addListener(this._api, 'eth_getTransactionByHash', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outTransaction(data));
|
||||||
|
}, [inHex(hash)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransactionByBlockHashAndIndex (callback, hash, index = 0) {
|
||||||
|
return this.addListener(this._api, 'eth_getTransactionByBlockHashAndIndex', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outTransaction(data));
|
||||||
|
}, [inHex(hash), inNumber16(index)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransactionByBlockNumberAndIndex (callback, blockNumber = 'latest', index = 0) {
|
||||||
|
return this.addListener(this._api, 'eth_getTransactionByBlockNumberAndIndex', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outTransaction(data));
|
||||||
|
}, [inBlockNumber(blockNumber), inNumber16(index)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransactionReceipt (callback, txhash) {
|
||||||
|
return this.addListener(this._api, 'eth_getTransactionReceipt', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outReceipt(data));
|
||||||
|
}, [inHex(txhash)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUncleByBlockHashAndIndex (callback, hash, index = 0) {
|
||||||
|
return this.addListener(this._api, 'eth_getUncleByBlockHashAndIndex', callback, [inHex(hash), inNumber16(index)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUncleByBlockNumberAndIndex (callback, blockNumber = 'latest', index = 0) {
|
||||||
|
return this.addListener(this._api, 'eth_getUncleByBlockNumberAndIndex', callback, [inBlockNumber(blockNumber), inNumber16(index)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLogs (callback, options) {
|
||||||
|
return this.addListener(this._api, 'eth_getLogs', (error, logs) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, (logs) => logs.map(outLog));
|
||||||
|
}, [inFilter(options)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getWork (callback) {
|
||||||
|
return this.addListener(this._api, 'eth_getWork', callback);
|
||||||
|
}
|
||||||
|
}
|
16
js/src/api/pubsub/eth/index.js
Normal file
16
js/src/api/pubsub/eth/index.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
export default from './eth';
|
16
js/src/api/pubsub/index.js
Normal file
16
js/src/api/pubsub/index.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
export default from './pubsub';
|
16
js/src/api/pubsub/net/index.js
Normal file
16
js/src/api/pubsub/net/index.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
export default from './net';
|
42
js/src/api/pubsub/net/net.js
Normal file
42
js/src/api/pubsub/net/net.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
import PubsubBase from '../pubsubBase';
|
||||||
|
|
||||||
|
import { outNumber } from '../../format/output';
|
||||||
|
|
||||||
|
export default class Net extends PubsubBase {
|
||||||
|
constructor (transport) {
|
||||||
|
super(transport);
|
||||||
|
this._api = 'parity';
|
||||||
|
}
|
||||||
|
|
||||||
|
// net API
|
||||||
|
version (callback) {
|
||||||
|
return this.addListener(this._api, 'net_version', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
peerCount (callback) {
|
||||||
|
return this.addListener(this._api, 'net_peerCount', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
listening (callback) {
|
||||||
|
return this.addListener(this._api, 'net_listening', callback);
|
||||||
|
}
|
||||||
|
}
|
16
js/src/api/pubsub/parity/index.js
Normal file
16
js/src/api/pubsub/parity/index.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
export default from './parity';
|
355
js/src/api/pubsub/parity/parity.js
Normal file
355
js/src/api/pubsub/parity/parity.js
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import PubsubBase from '../pubsubBase';
|
||||||
|
import { inAddress, inBlockNumber, inData, inHex, inDeriveHash, inDeriveIndex } from '../../format/input';
|
||||||
|
import { outAccountInfo, outAddress, outBlock, outChainStatus, outHistogram, outHwAccountInfo, outNodeKind, outNumber, outPeers, outTransaction, outAddresses, outRecentDapps, outVaultMeta } from '../../format/output';
|
||||||
|
|
||||||
|
export default class Parity extends PubsubBase {
|
||||||
|
constructor (transport) {
|
||||||
|
super(transport);
|
||||||
|
this._api = 'parity';
|
||||||
|
}
|
||||||
|
|
||||||
|
// parity API
|
||||||
|
accountsInfo (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_accountsInfo', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAccountInfo(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hardwareAccountsInfo (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_hardwareAccountsInfo', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outHwAccountInfo(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultAccount (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_defaultAccount', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddress(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
transactionsLimit (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_transactionsLimit', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
extraData (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_extraData', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
gasFloorTarget (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_gasFloorTarget', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
gasCeilTarget (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_gasCeilTarget', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
minGasPrice (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_minGasPrice', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
devLogs (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_devLogs', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
devLogsLevels (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_devLogsLevels', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
netChain (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_netChain', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
netPeers (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_netPeers', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outPeers(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
netPort (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_netPort', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
rpcSettings (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_rpcSettings', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_nodeName', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultExtraData (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_defaultExtraData', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
gasPriceHistogram (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_gasPriceHistogram', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outHistogram(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
unsignedTransactionsCount (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_unsignedTransactionsCount', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
registryAddress (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_registryAddress', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddress(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
listAccounts (callback, count, offset = null, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'parity_listAccounts', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, (data) => (data || []).map(outAddress));
|
||||||
|
}, [count, inAddress(offset), inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
listStorageKeys (callback, address, count, hash = null, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'parity_listStorageKeys', callback, [inAddress(address), count, inHex(hash), inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingTransactions (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_pendingTransactions', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outTransaction(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
futureTransactions (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_futureTransactions', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outTransaction(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingTransactionsStats (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_pendingTransactionsStats', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
localTransactions (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_localTransactions', (error, transactions) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, transactions => {
|
||||||
|
Object.values(transactions)
|
||||||
|
.filter(tx => tx.transaction)
|
||||||
|
.map(tx => {
|
||||||
|
tx.transaction = outTransaction(tx.transaction);
|
||||||
|
});
|
||||||
|
return transactions;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dappsUrl (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_dappsUrl', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
wsUrl (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_wsUrl', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
nextNonce (callback, account) {
|
||||||
|
return this.addListener(this._api, 'parity_nextNonce', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNumber(data));
|
||||||
|
}, [inAddress(account)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_mode', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
chain (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_chain', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
enode (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_enode', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
consensusCapability (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_consensusCapability', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
versionInfo (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_versionInfo', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
releasesInfo (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_releasesInfo', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
chainStatus (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_chainStatus', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outChainStatus(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeKind (callback) {
|
||||||
|
return this.addListener(this._api, 'parity_nodeKind', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outNodeKind(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlockHeaderByNumber (callback, blockNumber = 'latest') {
|
||||||
|
return this.addListener(this._api, 'parity_getBlockHeaderByNumber', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outBlock(data));
|
||||||
|
}, [inBlockNumber(blockNumber)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
cidV0 (callback, data) {
|
||||||
|
return this.addListener(this._api, 'parity_cidV0', callback, [inData(data)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parity accounts API (only secure API or configured to be exposed)
|
||||||
|
allAccountsInfo (callback) {
|
||||||
|
return this._addListener(this._api, 'parity_allAccountsInfo', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAccountInfo(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getDappAddresses (callback, dappId) {
|
||||||
|
return this._addListener(this._api, 'parity_getDappAddresses', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddresses(data));
|
||||||
|
}, [dappId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDappDefaultAddress (callback, dappId) {
|
||||||
|
return this._addListener(this._api, 'parity_getDappDefaultAddress', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddress(data));
|
||||||
|
}, [dappId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getNewDappsAddresses (callback) {
|
||||||
|
return this._addListener(this._api, 'parity_getDappDefaultAddress', (error, addresses) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, addresses ? addresses.map(outAddress) : null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getNewDappsDefaultAddress (callback) {
|
||||||
|
return this._addListener(this._api, 'parity_getNewDappsDefaultAddress', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddress(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
listRecentDapps (callback) {
|
||||||
|
return this._addListener(this._api, 'parity_listRecentDapps', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outRecentDapps(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
listGethAccounts (callback) {
|
||||||
|
return this._addListener(this._api, 'parity_listGethAccounts', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddresses(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
listVaults (callback) {
|
||||||
|
return this._addListener(this._api, 'parity_listVaults', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
listOpenedVaults (callback) {
|
||||||
|
return this._addListener(this._api, 'parity_listOpenedVaults', callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
getVaultMeta (callback, vaultName) {
|
||||||
|
return this._addListener(this._api, 'parity_getVaultMeta', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outVaultMeta(data));
|
||||||
|
}, [vaultName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
deriveAddressHash (callback, address, password, hash, shouldSave) {
|
||||||
|
return this._addListener(this._api, 'parity_deriveAddressHash', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddress(data));
|
||||||
|
}, [inAddress(address), password, inDeriveHash(hash), !!shouldSave]);
|
||||||
|
}
|
||||||
|
|
||||||
|
deriveAddressIndex (callback, address, password, index, shouldSave) {
|
||||||
|
return this._addListener(this._api, 'parity_deriveAddressIndex', (error, data) => {
|
||||||
|
error
|
||||||
|
? callback(error)
|
||||||
|
: callback(null, outAddress(data));
|
||||||
|
}, [inAddress(address), password, inDeriveIndex(index), !!shouldSave]);
|
||||||
|
}
|
||||||
|
}
|
50
js/src/api/pubsub/pubsub.js
Normal file
50
js/src/api/pubsub/pubsub.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import Eth from './eth';
|
||||||
|
import Parity from './parity';
|
||||||
|
import Net from './net';
|
||||||
|
|
||||||
|
import { isFunction } from '../util/types';
|
||||||
|
|
||||||
|
export default class Pubsub {
|
||||||
|
constructor (transport) {
|
||||||
|
if (!transport || !isFunction(transport.subscribe)) {
|
||||||
|
throw new Error('Pubsub API needs transport with subscribe() function defined. (WebSocket)');
|
||||||
|
}
|
||||||
|
|
||||||
|
this._eth = new Eth(transport);
|
||||||
|
this._net = new Net(transport);
|
||||||
|
this._parity = new Parity(transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
get net () {
|
||||||
|
return this._net;
|
||||||
|
}
|
||||||
|
|
||||||
|
get eth () {
|
||||||
|
return this._eth;
|
||||||
|
}
|
||||||
|
|
||||||
|
get parity () {
|
||||||
|
return this._parity;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribe (subscriptionIds) {
|
||||||
|
// subscriptions are namespace independent. Thus we can simply removeListener from any.
|
||||||
|
return this._parity.removeListener(subscriptionIds);
|
||||||
|
}
|
||||||
|
}
|
613
js/src/api/pubsub/pubsub.spec.js
Normal file
613
js/src/api/pubsub/pubsub.spec.js
Normal file
@ -0,0 +1,613 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
import { TEST_WS_URL, mockWs } from '../../../test/mockRpc';
|
||||||
|
import { isBigNumber } from '../../../test/types';
|
||||||
|
|
||||||
|
import Ws from '../transport/ws';
|
||||||
|
import Pubsub from './pubsub';
|
||||||
|
|
||||||
|
describe('api/pubsub/Pubsub', () => {
|
||||||
|
let scope;
|
||||||
|
let instance;
|
||||||
|
const address = '0x63Cf90D3f0410092FC0fca41846f596223979195';
|
||||||
|
|
||||||
|
describe('accountsInfo', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: {
|
||||||
|
'0x63cf90d3f0410092fc0fca41846f596223979195': {
|
||||||
|
name: 'name', uuid: 'uuid', meta: '{"data":"data"}'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('retrieves the available account info', (done) => {
|
||||||
|
instance.parity.accountsInfo((error, result) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(result).to.deep.equal({
|
||||||
|
'0x63Cf90D3f0410092FC0fca41846f596223979195': {
|
||||||
|
name: 'name', uuid: 'uuid', meta: {
|
||||||
|
data: 'data'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Unsubscribe', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2 },
|
||||||
|
{ method: 'parity_unsubscribe', reply: true }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Promise gets resolved on success.', (done) => {
|
||||||
|
instance.parity.accountsInfo().then(s => {
|
||||||
|
instance.parity.unsubscribe(s).then(b => {
|
||||||
|
expect(b).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('chainStatus', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: {
|
||||||
|
'blockGap': [0x123, 0x456]
|
||||||
|
},
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('retrieves the chain status', (done) => {
|
||||||
|
instance.parity.chainStatus((error, result) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(result).to.deep.equal({
|
||||||
|
'blockGap': [new BigNumber(0x123), new BigNumber(0x456)]
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('gasFloorTarget', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123456',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the gasfloor, formatted', (done) => {
|
||||||
|
instance.parity.gasFloorTarget((error, result) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(result)).to.be.true;
|
||||||
|
expect(result.eq(0x123456)).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('transactionsLimit', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: 1024,
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the tx limit, formatted', (done) => {
|
||||||
|
instance.parity.transactionsLimit((error, result) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(result)).to.be.true;
|
||||||
|
expect(result.eq(1024)).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('minGasPrice', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123456',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the min gasprice, formatted', (done) => {
|
||||||
|
instance.parity.minGasPrice((error, result) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(result)).to.be.true;
|
||||||
|
expect(result.eq(0x123456)).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('netPeers', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: { active: 123, connected: 456, max: 789, peers: [] },
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the peer structure, formatted', (done) => {
|
||||||
|
instance.parity.netPeers((error, peers) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(peers.active.eq(123)).to.be.true;
|
||||||
|
expect(peers.connected.eq(456)).to.be.true;
|
||||||
|
expect(peers.max.eq(789)).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('netPort', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: 33030,
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the connected port, formatted', (done) => {
|
||||||
|
instance.parity.netPort((error, count) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(count)).to.be.true;
|
||||||
|
expect(count.eq(33030)).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Eth API
|
||||||
|
describe('accounts', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: [address.toLowerCase()],
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a list of accounts, formatted', (done) => {
|
||||||
|
instance.eth.accounts((error, accounts) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(accounts).to.deep.equal([address]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('newHeads', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'eth_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'eth_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123456',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns newHeads for eth_subscribe', (done) => {
|
||||||
|
instance.eth.newHeads((error, blockNumber) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(blockNumber).to.equal('0x123456');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('blockNumber', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123456',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the current blockNumber, formatted', (done) => {
|
||||||
|
instance.eth.blockNumber((error, blockNumber) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(blockNumber)).to.be.true;
|
||||||
|
expect(blockNumber.toString(16)).to.equal('123456');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('call', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: [],
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats the input options & blockNumber', (done) => {
|
||||||
|
instance.eth.call((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_call', [{ data: '0x12345678' }, 'earliest']]);
|
||||||
|
done();
|
||||||
|
}, { data: '12345678' }, 'earliest');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('provides a latest blockNumber when not specified', (done) => {
|
||||||
|
instance.eth.call((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_call', [{ data: '0x12345678' }, 'latest']]);
|
||||||
|
done();
|
||||||
|
}, { data: '12345678' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('coinbase', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: address.toLowerCase(),
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the coinbase, formatted', (done) => {
|
||||||
|
instance.eth.coinbase((error, account) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(account).to.deep.equal(address);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('estimateGas', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts the options correctly', (done) => {
|
||||||
|
instance.eth.estimateGas((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_estimateGas', [{ gas: '0x5208' }]]);
|
||||||
|
done();
|
||||||
|
}, { gas: 21000 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the gas used, formatted', (done) => {
|
||||||
|
instance.eth.estimateGas((error, gas) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(gas)).to.be.true;
|
||||||
|
expect(gas.toString(16)).to.deep.equal('123');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('gasPrice', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the gas price, formatted', (done) => {
|
||||||
|
instance.eth.gasPrice((error, price) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(price)).to.be.true;
|
||||||
|
expect(price.toString(16)).to.deep.equal('123');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getBalance', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes in the address (default blockNumber)', (done) => {
|
||||||
|
instance.eth.getBalance((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getBalance', [address.toLowerCase(), 'latest']]);
|
||||||
|
done();
|
||||||
|
}, address);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes in the address & blockNumber', (done) => {
|
||||||
|
instance.eth.getBalance((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getBalance', [address.toLowerCase(), '0x456']]);
|
||||||
|
done();
|
||||||
|
}, address, 0x456);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the balance', (done) => {
|
||||||
|
instance.eth.getBalance((error, balance) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(balance)).to.be.true;
|
||||||
|
expect(balance.toString(16)).to.deep.equal('123');
|
||||||
|
done();
|
||||||
|
}, address);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getBlockByHash', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: { miner: address.toLowerCase() },
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats the input hash as a hash, default full', (done) => {
|
||||||
|
instance.eth.getBlockByHash((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getBlockByHash', ['0x1234', false]]);
|
||||||
|
done();
|
||||||
|
}, '1234');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats the input hash as a hash, full true', (done) => {
|
||||||
|
instance.eth.getBlockByHash((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getBlockByHash', ['0x1234', true]]);
|
||||||
|
done();
|
||||||
|
}, '1234', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats the output into block', (done) => {
|
||||||
|
instance.eth.getBlockByHash((error, block) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(block.miner).to.equal(address);
|
||||||
|
done();
|
||||||
|
}, '1234');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getBlockByNumber', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: { miner: address.toLowerCase() },
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('assumes blockNumber latest & full false', (done) => {
|
||||||
|
instance.eth.getBlockByNumber((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getBlockByNumber', ['latest', false]]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses input blockNumber & full false', (done) => {
|
||||||
|
instance.eth.getBlockByNumber((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getBlockByNumber', ['0x1234', false]]);
|
||||||
|
done();
|
||||||
|
}, '0x1234');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats the input blockNumber, full true', (done) => {
|
||||||
|
instance.eth.getBlockByNumber((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getBlockByNumber', ['0x1234', true]]);
|
||||||
|
done();
|
||||||
|
}, 0x1234, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats the output into block', (done) => {
|
||||||
|
instance.eth.getBlockByNumber((error, block) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(block.miner).to.equal(address);
|
||||||
|
done();
|
||||||
|
}, 0x1234);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTransactionCount', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
scope = mockWs([{ method: 'parity_subscribe', reply: 2, subscription: {
|
||||||
|
method: 'parity_subscription',
|
||||||
|
params: {
|
||||||
|
result: '0x123',
|
||||||
|
subscription: 2
|
||||||
|
}
|
||||||
|
} }]);
|
||||||
|
instance = new Pubsub(new Ws(TEST_WS_URL));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes in the address (default blockNumber)', (done) => {
|
||||||
|
instance.eth.getTransactionCount((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getTransactionCount', [address.toLowerCase(), 'latest']]);
|
||||||
|
done();
|
||||||
|
}, address);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes in the address & blockNumber', (done) => {
|
||||||
|
instance.eth.getTransactionCount((error) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(scope.body.parity_subscribe.params).to.deep.equal(['eth_getTransactionCount', [address.toLowerCase(), '0x456']]);
|
||||||
|
done();
|
||||||
|
}, address, 0x456);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the count, formatted', (done) => {
|
||||||
|
instance.eth.getTransactionCount((error, count) => {
|
||||||
|
expect(error).to.be.null;
|
||||||
|
expect(isBigNumber(count)).to.be.true;
|
||||||
|
expect(count.toString(16)).to.equal('123');
|
||||||
|
done();
|
||||||
|
}, address, 0x456);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
37
js/src/api/pubsub/pubsubBase.js
Normal file
37
js/src/api/pubsub/pubsubBase.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default class PubsubBase {
|
||||||
|
// Provider for websocket pubsub transport
|
||||||
|
constructor (transport) {
|
||||||
|
this._transport = transport;
|
||||||
|
}
|
||||||
|
|
||||||
|
addListener (module, eventName, callback, eventParams) {
|
||||||
|
return eventParams
|
||||||
|
? this._transport.subscribe(module, callback, eventName, eventParams)
|
||||||
|
: this._transport.subscribe(module, callback, eventName, []);
|
||||||
|
// this._transport.subscribe(module, callback, eventName); After Patch from tomac is merged to master! => eth_subscribe does not support empty array as params
|
||||||
|
}
|
||||||
|
|
||||||
|
removeListener (subscriptionIds) {
|
||||||
|
return this._transport.unsubscribe(subscriptionIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribe (subscriptionIds) {
|
||||||
|
return this.removeListener(subscriptionIds);
|
||||||
|
}
|
||||||
|
}
|
@ -110,7 +110,7 @@ describe('api/rpc/parity', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('newPeers', () => {
|
describe('netPeers', () => {
|
||||||
it('returns the peer structure, formatted', () => {
|
it('returns the peer structure, formatted', () => {
|
||||||
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789, peers: [] } } }]);
|
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789, peers: [] } } }]);
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ export default class Trace {
|
|||||||
.then(outTraces);
|
.then(outTraces);
|
||||||
}
|
}
|
||||||
|
|
||||||
call (options, blockNumber = 'latest', whatTrace = ['trace']) {
|
call (options, whatTrace = ['trace'], blockNumber = 'latest') {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('trace_call', inOptions(options), inBlockNumber(blockNumber), inTraceType(whatTrace))
|
.execute('trace_call', inOptions(options), inTraceType(whatTrace), inBlockNumber(blockNumber))
|
||||||
.then(outTraceReplay);
|
.then(outTraceReplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,14 @@ import TransportError from '../error';
|
|||||||
|
|
||||||
/* global WebSocket */
|
/* global WebSocket */
|
||||||
export default class Ws extends JsonRpcBase {
|
export default class Ws extends JsonRpcBase {
|
||||||
constructor (url, token, autoconnect = true) {
|
// token is optional (secure API)
|
||||||
|
constructor (url, token = null, autoconnect = true) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._url = url;
|
this._url = url;
|
||||||
this._token = token;
|
this._token = token;
|
||||||
this._messages = {};
|
this._messages = {};
|
||||||
|
this._subscriptions = { 'eth_subscription': [], 'parity_subscription': [] };
|
||||||
this._sessionHash = null;
|
this._sessionHash = null;
|
||||||
|
|
||||||
this._connecting = false;
|
this._connecting = false;
|
||||||
@ -68,10 +70,6 @@ export default class Ws extends JsonRpcBase {
|
|||||||
this._reconnectTimeoutId = null;
|
this._reconnectTimeoutId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const time = parseInt(new Date().getTime() / 1000, 10);
|
|
||||||
const sha3 = keccak_256(`${this._token}:${time}`);
|
|
||||||
const hash = `${sha3}_${time}`;
|
|
||||||
|
|
||||||
if (this._ws) {
|
if (this._ws) {
|
||||||
this._ws.onerror = null;
|
this._ws.onerror = null;
|
||||||
this._ws.onopen = null;
|
this._ws.onopen = null;
|
||||||
@ -81,13 +79,23 @@ export default class Ws extends JsonRpcBase {
|
|||||||
this._ws = null;
|
this._ws = null;
|
||||||
this._sessionHash = null;
|
this._sessionHash = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._connecting = true;
|
this._connecting = true;
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
this._lastError = null;
|
this._lastError = null;
|
||||||
|
|
||||||
|
// rpc secure API
|
||||||
|
if (this._token) {
|
||||||
|
const time = parseInt(new Date().getTime() / 1000, 10);
|
||||||
|
const sha3 = keccak_256(`${this._token}:${time}`);
|
||||||
|
const hash = `${sha3}_${time}`;
|
||||||
|
|
||||||
this._sessionHash = sha3;
|
this._sessionHash = sha3;
|
||||||
this._ws = new WebSocket(this._url, hash);
|
this._ws = new WebSocket(this._url, hash);
|
||||||
|
// non-secure API
|
||||||
|
} else {
|
||||||
|
this._ws = new WebSocket(this._url);
|
||||||
|
}
|
||||||
|
|
||||||
this._ws.onerror = this._onError;
|
this._ws.onerror = this._onError;
|
||||||
this._ws.onopen = this._onOpen;
|
this._ws.onopen = this._onOpen;
|
||||||
this._ws.onclose = this._onClose;
|
this._ws.onclose = this._onClose;
|
||||||
@ -194,13 +202,48 @@ export default class Ws extends JsonRpcBase {
|
|||||||
}, 50);
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_extract = (result) => {
|
||||||
|
const { result: res, id, method, params } = result;
|
||||||
|
const msg = this._messages[id];
|
||||||
|
|
||||||
|
// initial pubsub ACK
|
||||||
|
if (id && msg.subscription) {
|
||||||
|
// save subscription to map subId -> messageId
|
||||||
|
this._subscriptions[msg.subscription][res] = id;
|
||||||
|
// resolve promise with messageId because subId's can collide (eth/parity)
|
||||||
|
msg.resolve(id);
|
||||||
|
// save subId for unsubscribing later
|
||||||
|
msg.subId = res;
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// normal message
|
||||||
|
if (id) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pubsub format
|
||||||
|
if (method.includes('subscription')) {
|
||||||
|
const messageId = this._messages[this._subscriptions[method][params.subscription]];
|
||||||
|
|
||||||
|
if (messageId) {
|
||||||
|
return messageId;
|
||||||
|
} else {
|
||||||
|
throw Error(`Received Subscription which is already unsubscribed ${JSON.stringify(result)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Error(`Unknown message format: No ID or subscription ${JSON.stringify(result)}`);
|
||||||
|
}
|
||||||
|
|
||||||
_onMessage = (event) => {
|
_onMessage = (event) => {
|
||||||
try {
|
try {
|
||||||
const result = JSON.parse(event.data);
|
const result = JSON.parse(event.data);
|
||||||
const { method, params, json, resolve, reject } = this._messages[result.id];
|
const { method, params, json, resolve, reject, callback, subscription } = this._extract(result);
|
||||||
|
|
||||||
Logging.send(method, params, { json, result });
|
Logging.send(method, params, { json, result });
|
||||||
|
|
||||||
|
result.error = (result.params && result.params.error) || result.error;
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
this.error(event.data);
|
this.error(event.data);
|
||||||
|
|
||||||
@ -211,14 +254,23 @@ export default class Ws extends JsonRpcBase {
|
|||||||
|
|
||||||
const error = new TransportError(method, result.error.code, result.error.message);
|
const error = new TransportError(method, result.error.code, result.error.message);
|
||||||
|
|
||||||
|
if (result.id) {
|
||||||
reject(error);
|
reject(error);
|
||||||
|
} else {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
|
||||||
delete this._messages[result.id];
|
delete this._messages[result.id];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if not initial subscription message resolve & delete
|
||||||
|
if (result.id && !subscription) {
|
||||||
resolve(result.result);
|
resolve(result.result);
|
||||||
delete this._messages[result.id];
|
delete this._messages[result.id];
|
||||||
|
} else if (result.params) {
|
||||||
|
callback(null, result.params.result);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('ws::_onMessage', event.data, e);
|
console.error('ws::_onMessage', event.data, e);
|
||||||
}
|
}
|
||||||
@ -249,6 +301,43 @@ export default class Ws extends JsonRpcBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_methodsFromApi (api) {
|
||||||
|
const method = `${api}_subscribe`;
|
||||||
|
const uMethod = `${api}_unsubscribe`;
|
||||||
|
const subscription = `${api}_subscription`;
|
||||||
|
|
||||||
|
return { method, uMethod, subscription };
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe (api, callback, ...params) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const id = this.id;
|
||||||
|
const { method, uMethod, subscription } = this._methodsFromApi(api);
|
||||||
|
const json = this.encode(method, params);
|
||||||
|
|
||||||
|
this._messages[id] = { id, method, uMethod, params, json, resolve, reject, callback, subscription };
|
||||||
|
|
||||||
|
this._send(id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribe (messageId) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const id = this.id;
|
||||||
|
const { subId, uMethod, subscription } = this._messages[messageId];
|
||||||
|
const params = [subId];
|
||||||
|
const json = this.encode(uMethod, params);
|
||||||
|
const uResolve = (v) => {
|
||||||
|
delete this._messages[messageId];
|
||||||
|
delete this._subscriptions[subscription][subId];
|
||||||
|
resolve(v);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._messages[id] = { id, method: uMethod, params, json, resolve: uResolve, reject };
|
||||||
|
this._send(id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
set url (url) {
|
set url (url) {
|
||||||
this._url = url;
|
this._url = url;
|
||||||
}
|
}
|
||||||
|
@ -545,6 +545,39 @@ The following options are possible for the \`defaultBlock\` parameter:
|
|||||||
input: {
|
input: {
|
||||||
type: Data,
|
type: Data,
|
||||||
desc: 'the data send along with the transaction.'
|
desc: 'the data send along with the transaction.'
|
||||||
|
},
|
||||||
|
v: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the standardised V field of the signature.'
|
||||||
|
},
|
||||||
|
standard_v: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the standardised V field of the signature (0 or 1).'
|
||||||
|
},
|
||||||
|
r: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the R field of the signature.'
|
||||||
|
},
|
||||||
|
raw: {
|
||||||
|
type: Data,
|
||||||
|
desc: 'raw transaction data'
|
||||||
|
},
|
||||||
|
publicKey: {
|
||||||
|
type: Hash,
|
||||||
|
desc: 'public key of the signer.'
|
||||||
|
},
|
||||||
|
networkId: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the network id of the transaction, if any.'
|
||||||
|
},
|
||||||
|
creates: {
|
||||||
|
type: Hash,
|
||||||
|
desc: 'creates contract hash'
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
type: Object,
|
||||||
|
optional: true,
|
||||||
|
desc: 'conditional submission, Block number in `block` or timestamp in `time` or `null`. (parity-feature)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
example: {
|
example: {
|
||||||
@ -1057,6 +1090,39 @@ The following options are possible for the \`defaultBlock\` parameter:
|
|||||||
input: {
|
input: {
|
||||||
type: Data,
|
type: Data,
|
||||||
desc: 'the data send along with the transaction.'
|
desc: 'the data send along with the transaction.'
|
||||||
|
},
|
||||||
|
v: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the standardised V field of the signature.'
|
||||||
|
},
|
||||||
|
standard_v: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the standardised V field of the signature (0 or 1).'
|
||||||
|
},
|
||||||
|
r: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the R field of the signature.'
|
||||||
|
},
|
||||||
|
raw: {
|
||||||
|
type: Data,
|
||||||
|
desc: 'raw transaction data'
|
||||||
|
},
|
||||||
|
publicKey: {
|
||||||
|
type: Hash,
|
||||||
|
desc: 'public key of the signer.'
|
||||||
|
},
|
||||||
|
networkId: {
|
||||||
|
type: Quantity,
|
||||||
|
desc: 'the network id of the transaction, if any.'
|
||||||
|
},
|
||||||
|
creates: {
|
||||||
|
type: Hash,
|
||||||
|
desc: 'creates contract hash'
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
type: Object,
|
||||||
|
optional: true,
|
||||||
|
desc: 'conditional submission, Block number in `block` or timestamp in `time` or `null`. (parity-feature)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,10 @@ export function mockWs (requests) {
|
|||||||
scope.requests++;
|
scope.requests++;
|
||||||
|
|
||||||
mockServer.send(JSON.stringify(response));
|
mockServer.send(JSON.stringify(response));
|
||||||
|
|
||||||
|
if (request.method.match('subscribe') && request.subscription) {
|
||||||
|
mockServer.send(JSON.stringify(request.subscription));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return scope;
|
return scope;
|
||||||
|
@ -515,6 +515,10 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn miner_options(&self, reseal_min_period: u64) -> Result<MinerOptions, String> {
|
fn miner_options(&self, reseal_min_period: u64) -> Result<MinerOptions, String> {
|
||||||
|
if self.args.flag_force_sealing && reseal_min_period == 0 {
|
||||||
|
return Err("Force sealing can't be used with reseal_min_period = 0".into());
|
||||||
|
}
|
||||||
|
|
||||||
let reseal = self.args.flag_reseal_on_txs.parse::<ResealPolicy>()?;
|
let reseal = self.args.flag_reseal_on_txs.parse::<ResealPolicy>()?;
|
||||||
|
|
||||||
let options = MinerOptions {
|
let options = MinerOptions {
|
||||||
@ -1334,6 +1338,13 @@ mod tests {
|
|||||||
assert_eq!(conf3.miner_options(min_period).unwrap(), mining_options);
|
assert_eq!(conf3.miner_options(min_period).unwrap(), mining_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_fail_on_force_reseal_and_reseal_min_period() {
|
||||||
|
let conf = parse(&["parity", "--chain", "dev", "--force-sealing"]);
|
||||||
|
|
||||||
|
assert!(conf.miner_options(0).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_parse_updater_options() {
|
fn should_parse_updater_options() {
|
||||||
// when
|
// when
|
||||||
|
@ -162,7 +162,7 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
|
|||||||
let hash = signed_transaction.transaction.hash();
|
let hash = signed_transaction.transaction.hash();
|
||||||
|
|
||||||
self.miner.import_own_transaction(&*self.client, signed_transaction)
|
self.miner.import_own_transaction(&*self.client, signed_transaction)
|
||||||
.map_err(errors::from_transaction_error)
|
.map_err(errors::transaction)
|
||||||
.map(|_| hash)
|
.map(|_| hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -400,7 +400,7 @@ impl Dispatcher for LightDispatcher {
|
|||||||
|
|
||||||
self.transaction_queue.write().import(signed_transaction)
|
self.transaction_queue.write().import(signed_transaction)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
.map_err(errors::from_transaction_error)
|
.map_err(errors::transaction)
|
||||||
.map(|_| hash)
|
.map(|_| hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,8 +538,8 @@ fn signature(accounts: &AccountProvider, address: Address, hash: H256, password:
|
|||||||
SignWith::Password(pass) => accounts.sign(address, Some(pass), hash).map(WithToken::No),
|
SignWith::Password(pass) => accounts.sign(address, Some(pass), hash).map(WithToken::No),
|
||||||
SignWith::Token(token) => accounts.sign_with_token(address, token, hash).map(Into::into),
|
SignWith::Token(token) => accounts.sign_with_token(address, token, hash).map(Into::into),
|
||||||
}.map_err(|e| match password {
|
}.map_err(|e| match password {
|
||||||
SignWith::Nothing => errors::from_signing_error(e),
|
SignWith::Nothing => errors::signing(e),
|
||||||
_ => errors::from_password_error(e),
|
_ => errors::password(e),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,8 +570,8 @@ fn decrypt(accounts: &AccountProvider, address: Address, msg: Bytes, password: S
|
|||||||
SignWith::Password(pass) => accounts.decrypt(address, Some(pass), &DEFAULT_MAC, &msg).map(WithToken::No),
|
SignWith::Password(pass) => accounts.decrypt(address, Some(pass), &DEFAULT_MAC, &msg).map(WithToken::No),
|
||||||
SignWith::Token(token) => accounts.decrypt_with_token(address, token, &DEFAULT_MAC, &msg).map(Into::into),
|
SignWith::Token(token) => accounts.decrypt_with_token(address, token, &DEFAULT_MAC, &msg).map(Into::into),
|
||||||
}.map_err(|e| match password {
|
}.map_err(|e| match password {
|
||||||
SignWith::Nothing => errors::from_signing_error(e),
|
SignWith::Nothing => errors::signing(e),
|
||||||
_ => errors::from_password_error(e),
|
_ => errors::password(e),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ pub fn network_disabled() -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encryption_error<T: fmt::Debug>(error: T) -> Error {
|
pub fn encryption<T: fmt::Debug>(error: T) -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::ENCRYPTION_ERROR),
|
code: ErrorCode::ServerError(codes::ENCRYPTION_ERROR),
|
||||||
message: "Encryption error.".into(),
|
message: "Encryption error.".into(),
|
||||||
@ -229,7 +229,7 @@ pub fn encryption_error<T: fmt::Debug>(error: T) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encoding_error<T: fmt::Debug>(error: T) -> Error {
|
pub fn encoding<T: fmt::Debug>(error: T) -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::ENCODING_ERROR),
|
code: ErrorCode::ServerError(codes::ENCODING_ERROR),
|
||||||
message: "Encoding error.".into(),
|
message: "Encoding error.".into(),
|
||||||
@ -237,7 +237,7 @@ pub fn encoding_error<T: fmt::Debug>(error: T) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn database_error<T: fmt::Debug>(error: T) -> Error {
|
pub fn database<T: fmt::Debug>(error: T) -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::DATABASE_ERROR),
|
code: ErrorCode::ServerError(codes::DATABASE_ERROR),
|
||||||
message: "Database error.".into(),
|
message: "Database error.".into(),
|
||||||
@ -245,7 +245,7 @@ pub fn database_error<T: fmt::Debug>(error: T) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_fetch_error<T: fmt::Debug>(error: T) -> Error {
|
pub fn fetch<T: fmt::Debug>(error: T) -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::FETCH_ERROR),
|
code: ErrorCode::ServerError(codes::FETCH_ERROR),
|
||||||
message: "Error while fetching content.".into(),
|
message: "Error while fetching content.".into(),
|
||||||
@ -253,7 +253,7 @@ pub fn from_fetch_error<T: fmt::Debug>(error: T) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_signing_error(error: AccountError) -> Error {
|
pub fn signing(error: AccountError) -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::ACCOUNT_LOCKED),
|
code: ErrorCode::ServerError(codes::ACCOUNT_LOCKED),
|
||||||
message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(),
|
message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(),
|
||||||
@ -261,7 +261,7 @@ pub fn from_signing_error(error: AccountError) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_password_error(error: AccountError) -> Error {
|
pub fn password(error: AccountError) -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::PASSWORD_INVALID),
|
code: ErrorCode::ServerError(codes::PASSWORD_INVALID),
|
||||||
message: "Account password is invalid or account does not exist.".into(),
|
message: "Account password is invalid or account does not exist.".into(),
|
||||||
@ -301,7 +301,7 @@ pub fn transaction_message(error: TransactionError) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_transaction_error(error: EthcoreError) -> Error {
|
pub fn transaction(error: EthcoreError) -> Error {
|
||||||
|
|
||||||
if let EthcoreError::Transaction(e) = error {
|
if let EthcoreError::Transaction(e) = error {
|
||||||
Error {
|
Error {
|
||||||
@ -318,7 +318,7 @@ pub fn from_transaction_error(error: EthcoreError) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_rlp_error(error: DecoderError) -> Error {
|
pub fn rlp(error: DecoderError) -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::InvalidParams,
|
code: ErrorCode::InvalidParams,
|
||||||
message: "Invalid RLP.".into(),
|
message: "Invalid RLP.".into(),
|
||||||
@ -326,7 +326,7 @@ pub fn from_rlp_error(error: DecoderError) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_call_error(error: CallError) -> Error {
|
pub fn call(error: CallError) -> Error {
|
||||||
match error {
|
match error {
|
||||||
CallError::StatePruned => state_pruned(),
|
CallError::StatePruned => state_pruned(),
|
||||||
CallError::StateCorrupt => state_corrupt(),
|
CallError::StateCorrupt => state_corrupt(),
|
||||||
|
@ -32,7 +32,7 @@ pub fn cid(content: Bytes) -> Result<String, Error> {
|
|||||||
let mut buf = Vec::with_capacity(len);
|
let mut buf = Vec::with_capacity(len);
|
||||||
buf.resize(len, 0);
|
buf.resize(len, 0);
|
||||||
hasher.result(&mut buf);
|
hasher.result(&mut buf);
|
||||||
let mh = multihash::encode(multihash::Hash::SHA2256, &buf).map_err(errors::encoding_error)?;
|
let mh = multihash::encode(multihash::Hash::SHA2256, &buf).map_err(errors::encoding)?;
|
||||||
let cid = Cid::new(Codec::DagProtobuf, Version::V0, &mh);
|
let cid = Cid::new(Codec::DagProtobuf, Version::V0, &mh);
|
||||||
Ok(cid.to_string().into())
|
Ok(cid.to_string().into())
|
||||||
}
|
}
|
||||||
|
@ -86,13 +86,13 @@ fn decrypt_with_shadow_coefficients(mut decrypted_shadow: Public, mut common_sha
|
|||||||
let mut shadow_coefficients_sum = shadow_coefficients[0].clone();
|
let mut shadow_coefficients_sum = shadow_coefficients[0].clone();
|
||||||
for shadow_coefficient in shadow_coefficients.iter().skip(1) {
|
for shadow_coefficient in shadow_coefficients.iter().skip(1) {
|
||||||
shadow_coefficients_sum.add(shadow_coefficient)
|
shadow_coefficients_sum.add(shadow_coefficient)
|
||||||
.map_err(errors::encryption_error)?;
|
.map_err(errors::encryption)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
math::public_mul_secret(&mut common_shadow_point, &shadow_coefficients_sum)
|
math::public_mul_secret(&mut common_shadow_point, &shadow_coefficients_sum)
|
||||||
.map_err(errors::encryption_error)?;
|
.map_err(errors::encryption)?;
|
||||||
math::public_add(&mut decrypted_shadow, &common_shadow_point)
|
math::public_add(&mut decrypted_shadow, &common_shadow_point)
|
||||||
.map_err(errors::encryption_error)?;
|
.map_err(errors::encryption)?;
|
||||||
Ok(decrypted_shadow)
|
Ok(decrypted_shadow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
match self.miner.balance(&*self.client, &address) {
|
match self.miner.balance(&*self.client, &address) {
|
||||||
Some(balance) => Ok(balance.into()),
|
Some(balance) => Ok(balance.into()),
|
||||||
None => Err(errors::database_error("latest balance missing"))
|
None => Err(errors::database("latest balance missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
@ -388,7 +388,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
match self.miner.storage_at(&*self.client, &address, &H256::from(position)) {
|
match self.miner.storage_at(&*self.client, &address, &H256::from(position)) {
|
||||||
Some(s) => Ok(s.into()),
|
Some(s) => Ok(s.into()),
|
||||||
None => Err(errors::database_error("latest storage missing"))
|
None => Err(errors::database("latest storage missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
@ -413,13 +413,13 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
.or_else(|| self.miner.nonce(&*self.client, &address));
|
.or_else(|| self.miner.nonce(&*self.client, &address));
|
||||||
match nonce {
|
match nonce {
|
||||||
Some(nonce) => Ok(nonce.into()),
|
Some(nonce) => Ok(nonce.into()),
|
||||||
None => Err(errors::database_error("latest nonce missing"))
|
None => Err(errors::database("latest nonce missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
match self.miner.nonce(&*self.client, &address) {
|
match self.miner.nonce(&*self.client, &address) {
|
||||||
Some(nonce) => Ok(nonce.into()),
|
Some(nonce) => Ok(nonce.into()),
|
||||||
None => Err(errors::database_error("latest nonce missing"))
|
None => Err(errors::database("latest nonce missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
@ -472,7 +472,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
match self.miner.code(&*self.client, &address) {
|
match self.miner.code(&*self.client, &address) {
|
||||||
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
||||||
None => Err(errors::database_error("latest code missing"))
|
None => Err(errors::database("latest code missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
@ -618,8 +618,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
fn send_raw_transaction(&self, raw: Bytes) -> Result<RpcH256, Error> {
|
fn send_raw_transaction(&self, raw: Bytes) -> Result<RpcH256, Error> {
|
||||||
UntrustedRlp::new(&raw.into_vec()).as_val()
|
UntrustedRlp::new(&raw.into_vec()).as_val()
|
||||||
.map_err(errors::from_rlp_error)
|
.map_err(errors::rlp)
|
||||||
.and_then(|tx| SignedTransaction::new(tx).map_err(errors::from_transaction_error))
|
.and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))
|
||||||
.and_then(|signed_transaction| {
|
.and_then(|signed_transaction| {
|
||||||
FullDispatcher::new(self.client.clone(), self.miner.clone())
|
FullDispatcher::new(self.client.clone(), self.miner.clone())
|
||||||
.dispatch_transaction(signed_transaction.into())
|
.dispatch_transaction(signed_transaction.into())
|
||||||
@ -645,7 +645,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
future::done(result
|
future::done(result
|
||||||
.map(|b| b.output.into())
|
.map(|b| b.output.into())
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::call)
|
||||||
).boxed()
|
).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +657,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
};
|
};
|
||||||
future::done(self.client.estimate_gas(&signed, num.unwrap_or_default().into())
|
future::done(self.client.estimate_gas(&signed, num.unwrap_or_default().into())
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::call)
|
||||||
).boxed()
|
).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,18 +363,18 @@ impl Eth for EthClient {
|
|||||||
let best_header = self.client.best_block_header().decode();
|
let best_header = self.client.best_block_header().decode();
|
||||||
|
|
||||||
UntrustedRlp::new(&raw.into_vec()).as_val()
|
UntrustedRlp::new(&raw.into_vec()).as_val()
|
||||||
.map_err(errors::from_rlp_error)
|
.map_err(errors::rlp)
|
||||||
.and_then(|tx| {
|
.and_then(|tx| {
|
||||||
self.client.engine().verify_transaction_basic(&tx, &best_header)
|
self.client.engine().verify_transaction_basic(&tx, &best_header)
|
||||||
.map_err(errors::from_transaction_error)?;
|
.map_err(errors::transaction)?;
|
||||||
|
|
||||||
let signed = SignedTransaction::new(tx).map_err(errors::from_transaction_error)?;
|
let signed = SignedTransaction::new(tx).map_err(errors::transaction)?;
|
||||||
let hash = signed.hash();
|
let hash = signed.hash();
|
||||||
|
|
||||||
self.transaction_queue.write().import(signed.into())
|
self.transaction_queue.write().import(signed.into())
|
||||||
.map(|_| hash)
|
.map(|_| hash)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
.map_err(errors::from_transaction_error)
|
.map_err(errors::transaction)
|
||||||
})
|
})
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ impl Parity for ParityClient {
|
|||||||
|
|
||||||
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes, Error> {
|
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes, Error> {
|
||||||
ecies::encrypt(&key.into(), &DEFAULT_MAC, &phrase.0)
|
ecies::encrypt(&key.into(), &DEFAULT_MAC, &phrase.0)
|
||||||
.map_err(errors::encryption_error)
|
.map_err(errors::encryption)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,9 +127,9 @@ impl<F: Fetch> ParitySet for ParitySetClient<F> {
|
|||||||
fn hash_content(&self, url: String) -> BoxFuture<H256, Error> {
|
fn hash_content(&self, url: String) -> BoxFuture<H256, Error> {
|
||||||
self.fetch.process(self.fetch.fetch(&url).then(move |result| {
|
self.fetch.process(self.fetch.fetch(&url).then(move |result| {
|
||||||
result
|
result
|
||||||
.map_err(errors::from_fetch_error)
|
.map_err(errors::fetch)
|
||||||
.and_then(|response| {
|
.and_then(|response| {
|
||||||
sha3(&mut io::BufReader::new(response)).map_err(errors::from_fetch_error)
|
sha3(&mut io::BufReader::new(response)).map_err(errors::fetch)
|
||||||
})
|
})
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}))
|
}))
|
||||||
|
@ -284,7 +284,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
|
|
||||||
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes, Error> {
|
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes, Error> {
|
||||||
ecies::encrypt(&key.into(), &DEFAULT_MAC, &phrase.0)
|
ecies::encrypt(&key.into(), &DEFAULT_MAC, &phrase.0)
|
||||||
.map_err(errors::encryption_error)
|
.map_err(errors::encryption)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_engine_signer(&self, address: H160, password: String) -> Result<bool, Error> {
|
fn set_engine_signer(&self, address: H160, password: String) -> Result<bool, Error> {
|
||||||
self.miner.set_engine_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)?;
|
self.miner.set_engine_signer(address.into(), password).map_err(Into::into).map_err(errors::password)?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,9 +168,9 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
fn hash_content(&self, url: String) -> BoxFuture<H256, Error> {
|
fn hash_content(&self, url: String) -> BoxFuture<H256, Error> {
|
||||||
self.fetch.process(self.fetch.fetch(&url).then(move |result| {
|
self.fetch.process(self.fetch.fetch(&url).then(move |result| {
|
||||||
result
|
result
|
||||||
.map_err(errors::from_fetch_error)
|
.map_err(errors::fetch)
|
||||||
.and_then(|response| {
|
.and_then(|response| {
|
||||||
sha3(&mut io::BufReader::new(response)).map_err(errors::from_fetch_error)
|
sha3(&mut io::BufReader::new(response)).map_err(errors::fetch)
|
||||||
})
|
})
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}))
|
}))
|
||||||
|
@ -133,7 +133,7 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
|
|||||||
fn verify_transaction<F>(bytes: Bytes, request: FilledTransactionRequest, process: F) -> Result<ConfirmationResponse, Error> where
|
fn verify_transaction<F>(bytes: Bytes, request: FilledTransactionRequest, process: F) -> Result<ConfirmationResponse, Error> where
|
||||||
F: FnOnce(PendingTransaction) -> Result<ConfirmationResponse, Error>,
|
F: FnOnce(PendingTransaction) -> Result<ConfirmationResponse, Error>,
|
||||||
{
|
{
|
||||||
let signed_transaction = UntrustedRlp::new(&bytes.0).as_val().map_err(errors::from_rlp_error)?;
|
let signed_transaction = UntrustedRlp::new(&bytes.0).as_val().map_err(errors::rlp)?;
|
||||||
let signed_transaction = SignedTransaction::new(signed_transaction).map_err(|e| errors::invalid_params("Invalid signature.", e))?;
|
let signed_transaction = SignedTransaction::new(signed_transaction).map_err(|e| errors::invalid_params("Invalid signature.", e))?;
|
||||||
let sender = signed_transaction.sender();
|
let sender = signed_transaction.sender();
|
||||||
|
|
||||||
|
@ -87,23 +87,23 @@ impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'stat
|
|||||||
|
|
||||||
self.client.call(&signed, block.into(), to_call_analytics(flags))
|
self.client.call(&signed, block.into(), to_call_analytics(flags))
|
||||||
.map(TraceResults::from)
|
.map(TraceResults::from)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::call)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||||
let block = block.unwrap_or_default();
|
let block = block.unwrap_or_default();
|
||||||
|
|
||||||
let tx = UntrustedRlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?;
|
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)?;
|
let signed = SignedTransaction::new(tx).map_err(errors::transaction)?;
|
||||||
|
|
||||||
self.client.call(&signed, block.into(), to_call_analytics(flags))
|
self.client.call(&signed, block.into(), to_call_analytics(flags))
|
||||||
.map(TraceResults::from)
|
.map(TraceResults::from)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::call)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<TraceResults, Error> {
|
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<TraceResults, Error> {
|
||||||
self.client.replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags))
|
self.client.replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags))
|
||||||
.map(TraceResults::from)
|
.map(TraceResults::from)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::call)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user