Merge branch 'pip-msg' into lightcli
This commit is contained in:
commit
384aeda645
365
Cargo.lock
generated
365
Cargo.lock
generated
@ -5,7 +5,7 @@ dependencies = [
|
|||||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)",
|
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
|
||||||
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -27,9 +27,9 @@ dependencies = [
|
|||||||
"ethsync 1.7.0",
|
"ethsync 1.7.0",
|
||||||
"evmbin 0.1.0",
|
"evmbin 0.1.0",
|
||||||
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
|
||||||
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -193,6 +193,15 @@ dependencies = [
|
|||||||
"stable-heap 0.1.0 (git+https://github.com/carllerche/stable-heap?rev=3c5cd1ca47)",
|
"stable-heap 0.1.0 (git+https://github.com/carllerche/stable-heap?rev=3c5cd1ca47)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -282,7 +291,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ctrlc"
|
name = "ctrlc"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
source = "git+https://github.com/ethcore/rust-ctrlc.git#f4927770f89eca80ec250911eea3adcbf579ac48"
|
source = "git+https://github.com/paritytech/rust-ctrlc.git#b523017108bb2d571a7a69bd97bc406e63bc7a9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (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)",
|
||||||
@ -401,11 +410,12 @@ dependencies = [
|
|||||||
"ethstore 0.1.0",
|
"ethstore 0.1.0",
|
||||||
"evmjit 1.7.0",
|
"evmjit 1.7.0",
|
||||||
"hardware-wallet 1.7.0",
|
"hardware-wallet 1.7.0",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lru-cache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lru-cache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.2.0 (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)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.1.0",
|
"rlp 0.1.0",
|
||||||
@ -447,9 +457,9 @@ dependencies = [
|
|||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -623,10 +633,10 @@ dependencies = [
|
|||||||
"ethsync 1.7.0",
|
"ethsync 1.7.0",
|
||||||
"fetch 0.1.0",
|
"fetch 0.1.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-ipc-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-ipc-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
@ -653,7 +663,7 @@ dependencies = [
|
|||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"ethcrypto 0.1.0",
|
"ethcrypto 0.1.0",
|
||||||
"ethkey 0.2.0",
|
"ethkey 0.2.0",
|
||||||
"hyper 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -669,13 +679,14 @@ dependencies = [
|
|||||||
"ethcore-io 1.7.0",
|
"ethcore-io 1.7.0",
|
||||||
"ethcore-rpc 1.7.0",
|
"ethcore-rpc 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
|
"jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-ui 1.7.0",
|
"parity-ui 1.7.0",
|
||||||
"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_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ws 0.5.3 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)",
|
"ws 0.5.3 (git+https://github.com/paritytech/ws-rs.git?branch=mio-upstream-stable)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -689,14 +700,13 @@ dependencies = [
|
|||||||
"ethcore-ipc-nano 1.7.0",
|
"ethcore-ipc-nano 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-tcp-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-tcp-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
|
|
||||||
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -975,7 +985,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.10.0-a.0"
|
version = "0.10.0-a.0"
|
||||||
source = "git+https://github.com/ethcore/hyper#453c683b52208fefc32d29e4ac7c863439b2321f"
|
source = "git+https://github.com/paritytech/hyper#453c683b52208fefc32d29e4ac7c863439b2321f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -993,7 +1003,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.10.4"
|
version = "0.10.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1004,7 +1014,7 @@ dependencies = [
|
|||||||
"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)",
|
||||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1016,7 +1026,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1047,6 +1057,15 @@ name = "integer-encoding"
|
|||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iovec"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipc-common-types"
|
name = "ipc-common-types"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
@ -1082,67 +1101,82 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-core"
|
name = "jsonrpc-core"
|
||||||
version = "6.0.0"
|
version = "7.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#707cf73a7b72f2eecbf3665c53b4159ec867cbed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-http-server"
|
name = "jsonrpc-http-server"
|
||||||
version = "6.0.0"
|
version = "7.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#707cf73a7b72f2eecbf3665c53b4159ec867cbed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
|
"jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-ipc-server"
|
name = "jsonrpc-ipc-server"
|
||||||
version = "6.0.0"
|
version = "7.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#707cf73a7b72f2eecbf3665c53b4159ec867cbed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-tokio-ipc 0.1.0 (git+https://github.com/nikvolf/parity-tokio-ipc)",
|
||||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-macros"
|
name = "jsonrpc-macros"
|
||||||
version = "6.0.0"
|
version = "7.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#707cf73a7b72f2eecbf3665c53b4159ec867cbed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
|
"jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc-tcp-server"
|
name = "jsonrpc-pubsub"
|
||||||
version = "6.0.0"
|
version = "7.0.0"
|
||||||
source = "git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6#86d7a89c85f324b5f6671315d9b71010ca995300"
|
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#707cf73a7b72f2eecbf3665c53b4159ec867cbed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jsonrpc-server-utils"
|
||||||
|
version = "7.0.0"
|
||||||
|
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#707cf73a7b72f2eecbf3665c53b4159ec867cbed"
|
||||||
|
dependencies = [
|
||||||
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jsonrpc-tcp-server"
|
||||||
|
version = "7.0.0"
|
||||||
|
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#707cf73a7b72f2eecbf3665c53b4159ec867cbed"
|
||||||
|
dependencies = [
|
||||||
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
|
"jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1170,6 +1204,11 @@ name = "lazycell"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@ -1258,38 +1297,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 = "mio"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "git+https://github.com/ethcore/mio?branch=v0.5.x#3842d3b250ffd7bd9b16f9586b875ddcbac2b0dd"
|
|
||||||
dependencies = [
|
|
||||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.0-dev"
|
version = "0.6.0-dev"
|
||||||
@ -1298,7 +1305,7 @@ dependencies = [
|
|||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (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)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.2.0 (git+https://github.com/carllerche/slab?rev=5476efcafb)",
|
"slab 0.2.0 (git+https://github.com/carllerche/slab?rev=5476efcafb)",
|
||||||
@ -1308,13 +1315,13 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
source = "git+https://github.com/ethcore/mio#ef182bae193a9c7457cd2cf661fcaffb226e3eef"
|
source = "git+https://github.com/ethcore/mio#15a577039bed3c72f2952459f8ad687a56f63e29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazycell 0.4.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)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1323,23 +1330,56 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.1"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazycell 0.4.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)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio-named-pipes"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "git+https://github.com/alexcrichton/mio-named-pipes#903dc2f7eac6700c62bfdda258a599db13a9228f"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazycell 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio-uds"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miow"
|
name = "miow"
|
||||||
version = "0.1.3"
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miow"
|
||||||
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1417,15 +1457,6 @@ dependencies = [
|
|||||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nix"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@ -1630,8 +1661,7 @@ dependencies = [
|
|||||||
"cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.7.0",
|
"ethcore 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
|
"jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
|
||||||
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.1.0",
|
"rlp 0.1.0",
|
||||||
@ -1657,7 +1687,7 @@ name = "parity-reactor"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1668,14 +1698,30 @@ dependencies = [
|
|||||||
"ethcore-signer 1.7.0",
|
"ethcore-signer 1.7.0",
|
||||||
"ethcore-util 1.7.0",
|
"ethcore-util 1.7.0",
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)",
|
"jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"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)",
|
||||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ws 0.5.3 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)",
|
"ws 0.5.3 (git+https://github.com/paritytech/ws-rs.git?branch=mio-upstream-stable)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parity-tokio-ipc"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/nikvolf/parity-tokio-ipc#3d4234de6bdc78688ef803935111003080fd5375"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)",
|
||||||
|
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-line 0.1.0 (git+https://github.com/tokio-rs/tokio-line)",
|
||||||
|
"tokio-named-pipes 0.1.0 (git+https://github.com/alexcrichton/tokio-named-pipes)",
|
||||||
|
"tokio-uds 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1697,7 +1743,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/ethcore/js-precompiled.git#7039b5b8e44196718333dc3fcdfcadae2a97c7fd"
|
source = "git+https://github.com/ethcore/js-precompiled.git#47da49294ad958933e85a9c4f0f2bb4df5dc47de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -1899,7 +1945,7 @@ name = "reqwest"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hyper 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper-native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper-native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2188,11 +2234,6 @@ name = "siphasher"
|
|||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "slab"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -2357,16 +2398,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-core"
|
name = "tokio-core"
|
||||||
version = "0.1.2"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-io"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-line"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/tokio-rs/tokio-line#482614ae0c82daf584727ae65a80d854fe861f81"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-named-pipes"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/alexcrichton/tokio-named-pipes#3a22f8fc9a441b548aec25bd5df3b1e0ab99fabe"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)",
|
||||||
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-proto"
|
name = "tokio-proto"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -2379,7 +2451,7 @@ dependencies = [
|
|||||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2391,6 +2463,18 @@ dependencies = [
|
|||||||
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-uds"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio-uds 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.1.28"
|
version = "0.1.28"
|
||||||
@ -2412,6 +2496,11 @@ name = "traitobject"
|
|||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "traitobject"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "transient-hashmap"
|
name = "transient-hashmap"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -2524,7 +2613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ws"
|
name = "ws"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
source = "git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable#f5c0b35d660244d1b7500693c8cc28277ce1d418"
|
source = "git+https://github.com/paritytech/ws-rs.git?branch=mio-upstream-stable#f5c0b35d660244d1b7500693c8cc28277ce1d418"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)",
|
"bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)",
|
||||||
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2599,6 +2688,7 @@ dependencies = [
|
|||||||
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
|
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
|
||||||
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
||||||
"checksum bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)" = "<none>"
|
"checksum bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)" = "<none>"
|
||||||
|
"checksum bytes 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46112a0060ae15e3a3f9a445428a53e082b91215b744fa27a1948842f4a64b96"
|
||||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||||
"checksum cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e53e6cdfa5ca294863e8c8a32a7cdb4dc0a442c8971d47a0e75b6c27ea268a6a"
|
"checksum cid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e53e6cdfa5ca294863e8c8a32a7cdb4dc0a442c8971d47a0e75b6c27ea268a6a"
|
||||||
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
|
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
|
||||||
@ -2609,7 +2699,7 @@ dependencies = [
|
|||||||
"checksum core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05eed248dc504a5391c63794fe4fb64f46f071280afaa1b73308f3c0ce4574c5"
|
"checksum core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05eed248dc504a5391c63794fe4fb64f46f071280afaa1b73308f3c0ce4574c5"
|
||||||
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
|
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
|
||||||
"checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec"
|
"checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec"
|
||||||
"checksum ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)" = "<none>"
|
"checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "<none>"
|
||||||
"checksum daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "271ec51b7e0bee92f0d04601422c73eb76ececf197026711c97ad25038a010cf"
|
"checksum daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "271ec51b7e0bee92f0d04601422c73eb76ececf197026711c97ad25038a010cf"
|
||||||
"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
|
"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
|
||||||
"checksum docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4cc0acb4ce0828c6a5a11d47baa432fe885881c27428c3a4e473e454ffe57a76"
|
"checksum docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4cc0acb4ce0828c6a5a11d47baa432fe885881c27428c3a4e473e454ffe57a76"
|
||||||
@ -2631,25 +2721,29 @@ dependencies = [
|
|||||||
"checksum hidapi 0.3.1 (git+https://github.com/ethcore/hidapi-rs)" = "<none>"
|
"checksum hidapi 0.3.1 (git+https://github.com/ethcore/hidapi-rs)" = "<none>"
|
||||||
"checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58"
|
"checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58"
|
||||||
"checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae"
|
"checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae"
|
||||||
"checksum hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)" = "<none>"
|
"checksum hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)" = "<none>"
|
||||||
"checksum hyper 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "220407e5a263f110ec30a071787c9535918fdfc97def5680c90013c3f30c38c1"
|
"checksum hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "43a15e3273b2133aaac0150478ab443fb89f15c3de41d8d93d8f3bb14bf560f6"
|
||||||
"checksum hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9bf64f730d6ee4b0528a5f0a316363da9d8104318731509d4ccc86248f82b3"
|
"checksum hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9bf64f730d6ee4b0528a5f0a316363da9d8104318731509d4ccc86248f82b3"
|
||||||
"checksum hyper-native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afe68f772f0497a7205e751626bb8e1718568b58534b6108c73a74ef80483409"
|
"checksum hyper-native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afe68f772f0497a7205e751626bb8e1718568b58534b6108c73a74ef80483409"
|
||||||
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
|
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
|
||||||
"checksum igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c8c12b1795b8b168f577c45fa10379b3814dcb11b7ab702406001f0d63f40484"
|
"checksum igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c8c12b1795b8b168f577c45fa10379b3814dcb11b7ab702406001f0d63f40484"
|
||||||
"checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb"
|
"checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb"
|
||||||
|
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
|
||||||
"checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c"
|
"checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c"
|
||||||
"checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a"
|
"checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a"
|
||||||
"checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5"
|
"checksum itoa 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91fd9dc2c587067de817fec4ad355e3818c3d893a78cab32a0a474c7a15bb8d5"
|
||||||
"checksum jsonrpc-core 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
"checksum jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
|
||||||
"checksum jsonrpc-http-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
"checksum jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
|
||||||
"checksum jsonrpc-ipc-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
"checksum jsonrpc-ipc-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
|
||||||
"checksum jsonrpc-macros 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
"checksum jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
|
||||||
"checksum jsonrpc-tcp-server 6.0.0 (git+https://github.com/ethcore/jsonrpc.git?branch=parity-1.6)" = "<none>"
|
"checksum jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
|
||||||
|
"checksum jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
|
||||||
|
"checksum jsonrpc-tcp-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)" = "<none>"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||||
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
||||||
"checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
|
"checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
|
||||||
|
"checksum lazycell 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec38a5c22f1ef3e30d2642aa875620d60edeef36cef43c4739d86215ce816331"
|
||||||
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
||||||
"checksum libusb 0.3.0 (git+https://github.com/ethcore/libusb-rs)" = "<none>"
|
"checksum libusb 0.3.0 (git+https://github.com/ethcore/libusb-rs)" = "<none>"
|
||||||
"checksum libusb-sys 0.2.3 (git+https://github.com/ethcore/libusb-sys)" = "<none>"
|
"checksum libusb-sys 0.2.3 (git+https://github.com/ethcore/libusb-sys)" = "<none>"
|
||||||
@ -2662,12 +2756,13 @@ dependencies = [
|
|||||||
"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.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1f4d337a01c32e1f2122510fed46393d53ca35a7f429cb0450abaedfa3ed54"
|
||||||
"checksum mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)" = "<none>"
|
|
||||||
"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e"
|
|
||||||
"checksum mio 0.6.0-dev (git+https://github.com/ethcore/mio?branch=timer-fix)" = "<none>"
|
"checksum mio 0.6.0-dev (git+https://github.com/ethcore/mio?branch=timer-fix)" = "<none>"
|
||||||
"checksum mio 0.6.1 (git+https://github.com/ethcore/mio)" = "<none>"
|
"checksum mio 0.6.1 (git+https://github.com/ethcore/mio)" = "<none>"
|
||||||
"checksum mio 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "410a1a0ff76f5a226f1e4e3ff1756128e65cd30166e39c3892283e2ac09d5b67"
|
"checksum mio 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5b493dc9fd96bd2077f2117f178172b0765db4dfda3ea4d8000401e6d65d3e80"
|
||||||
"checksum miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bfc6782530ac8ace97af10a540054a37126b63b0702ddaaa243b73b5745b9a"
|
"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 miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1"
|
||||||
|
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||||
"checksum msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c04b68cc63a8480fb2550343695f7be72effdec953a9d4508161c3e69041c7d8"
|
"checksum msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c04b68cc63a8480fb2550343695f7be72effdec953a9d4508161c3e69041c7d8"
|
||||||
"checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6"
|
"checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6"
|
||||||
"checksum multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c9f70f2402fa07c16c40be8fd0a748a39257c5dc3ff5c857cbbde2f39135c505"
|
"checksum multihash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c9f70f2402fa07c16c40be8fd0a748a39257c5dc3ff5c857cbbde2f39135c505"
|
||||||
@ -2675,7 +2770,6 @@ dependencies = [
|
|||||||
"checksum nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
|
"checksum nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
|
||||||
"checksum native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4e52995154bb6f0b41e4379a279482c9387c1632e3798ba4e511ef8c54ee09"
|
"checksum native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4e52995154bb6f0b41e4379a279482c9387c1632e3798ba4e511ef8c54ee09"
|
||||||
"checksum net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a816012ca11cb47009693c1e0c6130e26d39e4d97ee2a13c50e868ec83e3204"
|
"checksum net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a816012ca11cb47009693c1e0c6130e26d39e4d97ee2a13c50e868ec83e3204"
|
||||||
"checksum nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f05c2fc965fc1cd6b73fa57fa7b89f288178737f2f3ce9e63e4a6a141189000e"
|
|
||||||
"checksum nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a7bb1da2be7da3cbffda73fc681d509ffd9e665af478d2bee1907cee0bc64b2"
|
"checksum nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a7bb1da2be7da3cbffda73fc681d509ffd9e665af478d2bee1907cee0bc64b2"
|
||||||
"checksum nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d95c5fa8b641c10ad0b8887454ebaafa3c92b5cd5350f8fc693adafd178e7b"
|
"checksum nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d95c5fa8b641c10ad0b8887454ebaafa3c92b5cd5350f8fc693adafd178e7b"
|
||||||
"checksum nodrop 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4d9a22dbcebdeef7bf275cbf444d6521d4e7a2fee187b72d80dba0817120dd8f"
|
"checksum nodrop 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4d9a22dbcebdeef7bf275cbf444d6521d4e7a2fee187b72d80dba0817120dd8f"
|
||||||
@ -2696,6 +2790,7 @@ dependencies = [
|
|||||||
"checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb"
|
"checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb"
|
||||||
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
|
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
|
||||||
"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
|
"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
|
||||||
|
"checksum parity-tokio-ipc 0.1.0 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
|
||||||
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "<none>"
|
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "<none>"
|
||||||
"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621"
|
"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621"
|
||||||
"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
|
"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
|
||||||
@ -2749,7 +2844,6 @@ dependencies = [
|
|||||||
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
|
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
|
||||||
"checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d"
|
"checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d"
|
||||||
"checksum siphasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c44e42fa187b5a8782489cf7740cc27c3125806be2bf33563cf5e02e9533fcd"
|
"checksum siphasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c44e42fa187b5a8782489cf7740cc27c3125806be2bf33563cf5e02e9533fcd"
|
||||||
"checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e"
|
|
||||||
"checksum slab 0.2.0 (git+https://github.com/carllerche/slab?rev=5476efcafb)" = "<none>"
|
"checksum slab 0.2.0 (git+https://github.com/carllerche/slab?rev=5476efcafb)" = "<none>"
|
||||||
"checksum slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dbdd334bd28d328dad1c41b0ea662517883d8880d8533895ef96c8003dec9c4"
|
"checksum slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dbdd334bd28d328dad1c41b0ea662517883d8880d8533895ef96c8003dec9c4"
|
||||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||||
@ -2772,12 +2866,17 @@ dependencies = [
|
|||||||
"checksum thread_local 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0694f51610ef7cfac7a1b81de7f1602ee5356e76541bcd62c40e71933338cab1"
|
"checksum thread_local 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0694f51610ef7cfac7a1b81de7f1602ee5356e76541bcd62c40e71933338cab1"
|
||||||
"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af"
|
"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af"
|
||||||
"checksum tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7aef43048292ca0bae4ab32180e85f6202cf2816c2a210c396a84b99dab9270"
|
"checksum tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7aef43048292ca0bae4ab32180e85f6202cf2816c2a210c396a84b99dab9270"
|
||||||
"checksum tokio-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "52416b3e937abac22a543a7f1c66bd37feb60137ff1ab42390fa02df85347e58"
|
"checksum tokio-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3d1be481b55126f02ef88ff86748086473cb537a949fc4a8f4be403a530ae54b"
|
||||||
|
"checksum tokio-io 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a278fde45f1be68e44995227d426aaa4841e0980bb0a21b981092f28c3c8473"
|
||||||
|
"checksum tokio-line 0.1.0 (git+https://github.com/tokio-rs/tokio-line)" = "<none>"
|
||||||
|
"checksum tokio-named-pipes 0.1.0 (git+https://github.com/alexcrichton/tokio-named-pipes)" = "<none>"
|
||||||
"checksum tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c0d6031f94d78d7b4d509d4a7c5e1cdf524a17e7b08d1c188a83cf720e69808"
|
"checksum tokio-proto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c0d6031f94d78d7b4d509d4a7c5e1cdf524a17e7b08d1c188a83cf720e69808"
|
||||||
"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
|
"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
|
||||||
|
"checksum tokio-uds 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc7b5fc8e19e220b29566d1750949224a518478eab9cebc8df60583242ca30a"
|
||||||
"checksum toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "fcd27a04ca509aff336ba5eb2abc58d456f52c4ff64d9724d88acb85ead560b6"
|
"checksum toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "fcd27a04ca509aff336ba5eb2abc58d456f52c4ff64d9724d88acb85ead560b6"
|
||||||
"checksum toml 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a442dfc13508e603c3f763274361db7f79d7469a0e95c411cde53662ab30fc72"
|
"checksum toml 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a442dfc13508e603c3f763274361db7f79d7469a0e95c411cde53662ab30fc72"
|
||||||
"checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616"
|
"checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616"
|
||||||
|
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
||||||
"checksum transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "715254c8f0811be1a79ad3ea5e6fa3c8eddec2b03d7f5ba78cf093e56d79c24f"
|
"checksum transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "715254c8f0811be1a79ad3ea5e6fa3c8eddec2b03d7f5ba78cf093e56d79c24f"
|
||||||
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
||||||
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
||||||
@ -2794,7 +2893,7 @@ dependencies = [
|
|||||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||||
"checksum ws 0.5.3 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)" = "<none>"
|
"checksum ws 0.5.3 (git+https://github.com/paritytech/ws-rs.git?branch=mio-upstream-stable)" = "<none>"
|
||||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||||
"checksum xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77b831a5ba77110f438f0ac5583aafeb087f70432998ba6b7dcb1d32185db453"
|
"checksum xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77b831a5ba77110f438f0ac5583aafeb087f70432998ba6b7dcb1d32185db453"
|
||||||
"checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef"
|
"checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef"
|
||||||
|
@ -24,9 +24,9 @@ serde = "0.9"
|
|||||||
serde_json = "0.9"
|
serde_json = "0.9"
|
||||||
app_dirs = "1.1.1"
|
app_dirs = "1.1.1"
|
||||||
fdlimit = "0.1"
|
fdlimit = "0.1"
|
||||||
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
hyper = { default-features = false, git = "https://github.com/paritytech/hyper" }
|
||||||
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" }
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
ethsync = { path = "sync" }
|
ethsync = { path = "sync" }
|
||||||
ethcore = { path = "ethcore" }
|
ethcore = { path = "ethcore" }
|
||||||
ethcore-util = { path = "util" }
|
ethcore-util = { path = "util" }
|
||||||
|
@ -8,33 +8,36 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[lib]
|
[lib]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.3"
|
base32 = "0.3"
|
||||||
log = "0.3"
|
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
|
||||||
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
|
||||||
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
|
||||||
unicase = "1.3"
|
|
||||||
url = "1.0"
|
|
||||||
rustc-serialize = "0.3"
|
|
||||||
serde = "0.9"
|
|
||||||
serde_json = "0.9"
|
|
||||||
serde_derive = "0.9"
|
|
||||||
linked-hash-map = "0.3"
|
linked-hash-map = "0.3"
|
||||||
parity-dapps-glue = "1.4"
|
log = "0.3"
|
||||||
base32 = "0.3"
|
|
||||||
mime = "0.2"
|
mime = "0.2"
|
||||||
mime_guess = "1.6.1"
|
mime_guess = "1.6.1"
|
||||||
|
rand = "0.3"
|
||||||
|
rustc-serialize = "0.3"
|
||||||
|
serde = "0.9"
|
||||||
|
serde_derive = "0.9"
|
||||||
|
serde_json = "0.9"
|
||||||
time = "0.1.35"
|
time = "0.1.35"
|
||||||
|
unicase = "1.3"
|
||||||
|
url = "1.0"
|
||||||
zip = { version = "0.1", default-features = false }
|
zip = { version = "0.1", default-features = false }
|
||||||
|
|
||||||
|
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
|
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
|
# TODO [ToDr] Temporary solution, server should be merged with RPC.
|
||||||
|
jsonrpc-server-utils = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
|
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
ethcore-rpc = { path = "../rpc" }
|
ethcore-rpc = { path = "../rpc" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
parity-ui = { path = "./ui" }
|
parity-dapps-glue = "1.4"
|
||||||
parity-hash-fetch = { path = "../hash-fetch" }
|
parity-hash-fetch = { path = "../hash-fetch" }
|
||||||
parity-reactor = { path = "../util/reactor" }
|
parity-reactor = { path = "../util/reactor" }
|
||||||
|
parity-ui = { path = "./ui" }
|
||||||
|
|
||||||
clippy = { version = "0.0.103", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ use unicase::UniCase;
|
|||||||
use hyper::{server, net, Decoder, Encoder, Next, Control};
|
use hyper::{server, net, Decoder, Encoder, Next, Control};
|
||||||
use hyper::header;
|
use hyper::header;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use hyper::header::AccessControlAllowOrigin;
|
|
||||||
|
|
||||||
use api::types::{App, ApiError};
|
use api::types::{App, ApiError};
|
||||||
use api::response;
|
use api::response;
|
||||||
@ -27,23 +26,20 @@ use apps::fetcher::Fetcher;
|
|||||||
|
|
||||||
use handlers::extract_url;
|
use handlers::extract_url;
|
||||||
use endpoint::{Endpoint, Endpoints, Handler, EndpointPath};
|
use endpoint::{Endpoint, Endpoints, Handler, EndpointPath};
|
||||||
use jsonrpc_http_server::cors;
|
use jsonrpc_http_server;
|
||||||
|
use jsonrpc_server_utils::cors;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RestApi {
|
pub struct RestApi {
|
||||||
cors_domains: Option<Vec<AccessControlAllowOrigin>>,
|
cors_domains: Option<Vec<cors::AccessControlAllowOrigin>>,
|
||||||
endpoints: Arc<Endpoints>,
|
endpoints: Arc<Endpoints>,
|
||||||
fetcher: Arc<Fetcher>,
|
fetcher: Arc<Fetcher>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RestApi {
|
impl RestApi {
|
||||||
pub fn new(cors_domains: Vec<String>, endpoints: Arc<Endpoints>, fetcher: Arc<Fetcher>) -> Box<Endpoint> {
|
pub fn new(cors_domains: Vec<cors::AccessControlAllowOrigin>, endpoints: Arc<Endpoints>, fetcher: Arc<Fetcher>) -> Box<Endpoint> {
|
||||||
Box::new(RestApi {
|
Box::new(RestApi {
|
||||||
cors_domains: Some(cors_domains.into_iter().map(|domain| match domain.as_ref() {
|
cors_domains: Some(cors_domains),
|
||||||
"all" | "*" | "any" => AccessControlAllowOrigin::Any,
|
|
||||||
"null" => AccessControlAllowOrigin::Null,
|
|
||||||
other => AccessControlAllowOrigin::Value(other.into()),
|
|
||||||
}).collect()),
|
|
||||||
endpoints: endpoints,
|
endpoints: endpoints,
|
||||||
fetcher: fetcher,
|
fetcher: fetcher,
|
||||||
})
|
})
|
||||||
@ -64,7 +60,7 @@ impl Endpoint for RestApi {
|
|||||||
|
|
||||||
struct RestApiRouter {
|
struct RestApiRouter {
|
||||||
api: RestApi,
|
api: RestApi,
|
||||||
origin: Option<String>,
|
cors_header: Option<header::AccessControlAllowOrigin>,
|
||||||
path: Option<EndpointPath>,
|
path: Option<EndpointPath>,
|
||||||
control: Option<Control>,
|
control: Option<Control>,
|
||||||
handler: Box<Handler>,
|
handler: Box<Handler>,
|
||||||
@ -74,7 +70,7 @@ impl RestApiRouter {
|
|||||||
fn new(api: RestApi, path: EndpointPath, control: Control) -> Self {
|
fn new(api: RestApi, path: EndpointPath, control: Control) -> Self {
|
||||||
RestApiRouter {
|
RestApiRouter {
|
||||||
path: Some(path),
|
path: Some(path),
|
||||||
origin: None,
|
cors_header: None,
|
||||||
control: Some(control),
|
control: Some(control),
|
||||||
api: api,
|
api: api,
|
||||||
handler: response::as_json_error(&ApiError {
|
handler: response::as_json_error(&ApiError {
|
||||||
@ -95,21 +91,22 @@ impl RestApiRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns basic headers for a response (it may be overwritten by the handler)
|
/// Returns basic headers for a response (it may be overwritten by the handler)
|
||||||
fn response_headers(&self) -> header::Headers {
|
fn response_headers(cors_header: Option<header::AccessControlAllowOrigin>) -> header::Headers {
|
||||||
let mut headers = header::Headers::new();
|
let mut headers = header::Headers::new();
|
||||||
headers.set(header::AccessControlAllowCredentials);
|
|
||||||
headers.set(header::AccessControlAllowMethods(vec![
|
|
||||||
Method::Options,
|
|
||||||
Method::Post,
|
|
||||||
Method::Get,
|
|
||||||
]));
|
|
||||||
headers.set(header::AccessControlAllowHeaders(vec![
|
|
||||||
UniCase("origin".to_owned()),
|
|
||||||
UniCase("content-type".to_owned()),
|
|
||||||
UniCase("accept".to_owned()),
|
|
||||||
]));
|
|
||||||
|
|
||||||
if let Some(cors_header) = cors::get_cors_header(&self.api.cors_domains, &self.origin) {
|
if let Some(cors_header) = cors_header {
|
||||||
|
headers.set(header::AccessControlAllowCredentials);
|
||||||
|
headers.set(header::AccessControlAllowMethods(vec![
|
||||||
|
Method::Options,
|
||||||
|
Method::Post,
|
||||||
|
Method::Get,
|
||||||
|
]));
|
||||||
|
headers.set(header::AccessControlAllowHeaders(vec![
|
||||||
|
UniCase("origin".to_owned()),
|
||||||
|
UniCase("content-type".to_owned()),
|
||||||
|
UniCase("accept".to_owned()),
|
||||||
|
]));
|
||||||
|
|
||||||
headers.set(cors_header);
|
headers.set(cors_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +117,7 @@ impl RestApiRouter {
|
|||||||
impl server::Handler<net::HttpStream> for RestApiRouter {
|
impl server::Handler<net::HttpStream> for RestApiRouter {
|
||||||
|
|
||||||
fn on_request(&mut self, request: server::Request<net::HttpStream>) -> Next {
|
fn on_request(&mut self, request: server::Request<net::HttpStream>) -> Next {
|
||||||
self.origin = cors::read_origin(&request);
|
self.cors_header = jsonrpc_http_server::cors_header(&request, &self.api.cors_domains).into();
|
||||||
|
|
||||||
if let Method::Options = *request.method() {
|
if let Method::Options = *request.method() {
|
||||||
self.handler = response::empty();
|
self.handler = response::empty();
|
||||||
@ -164,7 +161,7 @@ impl server::Handler<net::HttpStream> for RestApiRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_response(&mut self, res: &mut server::Response) -> Next {
|
fn on_response(&mut self, res: &mut server::Response) -> Next {
|
||||||
*res.headers_mut() = self.response_headers();
|
*res.headers_mut() = Self::response_headers(self.cors_header.take());
|
||||||
self.handler.on_response(res)
|
self.handler.on_response(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,25 +20,27 @@
|
|||||||
#![cfg_attr(feature="nightly", plugin(clippy))]
|
#![cfg_attr(feature="nightly", plugin(clippy))]
|
||||||
|
|
||||||
extern crate base32;
|
extern crate base32;
|
||||||
extern crate hyper;
|
extern crate futures;
|
||||||
extern crate time;
|
extern crate linked_hash_map;
|
||||||
extern crate url as url_lib;
|
extern crate mime_guess;
|
||||||
extern crate unicase;
|
extern crate rand;
|
||||||
|
extern crate rustc_serialize;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
extern crate time;
|
||||||
|
extern crate unicase;
|
||||||
|
extern crate url as url_lib;
|
||||||
extern crate zip;
|
extern crate zip;
|
||||||
extern crate rand;
|
|
||||||
extern crate jsonrpc_core;
|
extern crate jsonrpc_core;
|
||||||
extern crate jsonrpc_http_server;
|
extern crate jsonrpc_http_server;
|
||||||
extern crate mime_guess;
|
extern crate jsonrpc_server_utils;
|
||||||
extern crate rustc_serialize;
|
|
||||||
extern crate ethcore_rpc;
|
extern crate ethcore_rpc;
|
||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
extern crate parity_hash_fetch as hash_fetch;
|
|
||||||
extern crate linked_hash_map;
|
|
||||||
extern crate fetch;
|
extern crate fetch;
|
||||||
extern crate parity_dapps_glue as parity_dapps;
|
extern crate parity_dapps_glue as parity_dapps;
|
||||||
extern crate futures;
|
extern crate parity_hash_fetch as hash_fetch;
|
||||||
extern crate parity_reactor;
|
extern crate parity_reactor;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -68,17 +70,20 @@ mod web;
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use ethcore_rpc::{Metadata};
|
use jsonrpc_core::{Middleware, MetaIoHandler};
|
||||||
|
use jsonrpc_http_server::tokio_core::reactor::Remote as TokioRemote;
|
||||||
|
pub use jsonrpc_http_server::{DomainsValidation, Host, AccessControlAllowOrigin};
|
||||||
|
pub use jsonrpc_http_server::hyper;
|
||||||
|
|
||||||
|
use ethcore_rpc::Metadata;
|
||||||
use fetch::{Fetch, Client as FetchClient};
|
use fetch::{Fetch, Client as FetchClient};
|
||||||
use hash_fetch::urlhint::ContractClient;
|
use hash_fetch::urlhint::ContractClient;
|
||||||
use jsonrpc_core::Middleware;
|
|
||||||
use jsonrpc_core::reactor::RpcHandler;
|
|
||||||
use router::auth::{Authorization, NoAuth, HttpBasicAuth};
|
|
||||||
use parity_reactor::Remote;
|
use parity_reactor::Remote;
|
||||||
|
use router::auth::{Authorization, NoAuth, HttpBasicAuth};
|
||||||
|
|
||||||
use self::apps::{HOME_PAGE, DAPPS_DOMAIN};
|
use self::apps::{HOME_PAGE, DAPPS_DOMAIN};
|
||||||
|
|
||||||
@ -110,8 +115,8 @@ pub struct ServerBuilder<T: Fetch = FetchClient> {
|
|||||||
sync_status: Arc<SyncStatus>,
|
sync_status: Arc<SyncStatus>,
|
||||||
web_proxy_tokens: Arc<WebProxyTokens>,
|
web_proxy_tokens: Arc<WebProxyTokens>,
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<Host>>,
|
||||||
extra_cors: Option<Vec<String>>,
|
extra_cors: Option<Vec<AccessControlAllowOrigin>>,
|
||||||
remote: Remote,
|
remote: Remote,
|
||||||
fetch: Option<T>,
|
fetch: Option<T>,
|
||||||
}
|
}
|
||||||
@ -172,15 +177,15 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
/// Change allowed hosts.
|
/// Change allowed hosts.
|
||||||
/// `None` - All hosts are allowed
|
/// `None` - All hosts are allowed
|
||||||
/// `Some(whitelist)` - Allow only whitelisted hosts (+ listen address)
|
/// `Some(whitelist)` - Allow only whitelisted hosts (+ listen address)
|
||||||
pub fn allowed_hosts(mut self, allowed_hosts: Option<Vec<String>>) -> Self {
|
pub fn allowed_hosts(mut self, allowed_hosts: DomainsValidation<Host>) -> Self {
|
||||||
self.allowed_hosts = allowed_hosts;
|
self.allowed_hosts = allowed_hosts.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extra cors headers.
|
/// Extra cors headers.
|
||||||
/// `None` - no additional CORS URLs
|
/// `None` - no additional CORS URLs
|
||||||
pub fn extra_cors_headers(mut self, cors: Option<Vec<String>>) -> Self {
|
pub fn extra_cors_headers(mut self, cors: DomainsValidation<AccessControlAllowOrigin>) -> Self {
|
||||||
self.extra_cors = cors;
|
self.extra_cors = cors.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +197,7 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
|
|
||||||
/// Asynchronously start server with no authentication,
|
/// Asynchronously start server with no authentication,
|
||||||
/// returns result with `Server` handle on success or an error.
|
/// returns result with `Server` handle on success or an error.
|
||||||
pub fn start_unsecured_http<S: Middleware<Metadata>>(self, addr: &SocketAddr, handler: RpcHandler<Metadata, S>) -> Result<Server, ServerError> {
|
pub fn start_unsecured_http<S: Middleware<Metadata>>(self, addr: &SocketAddr, handler: MetaIoHandler<Metadata, S>, tokio_remote: TokioRemote) -> Result<Server, ServerError> {
|
||||||
let fetch = self.fetch_client()?;
|
let fetch = self.fetch_client()?;
|
||||||
Server::start_http(
|
Server::start_http(
|
||||||
addr,
|
addr,
|
||||||
@ -207,13 +212,14 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
self.sync_status,
|
self.sync_status,
|
||||||
self.web_proxy_tokens,
|
self.web_proxy_tokens,
|
||||||
self.remote,
|
self.remote,
|
||||||
|
tokio_remote,
|
||||||
fetch,
|
fetch,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Asynchronously start server with `HTTP Basic Authentication`,
|
/// Asynchronously start server with `HTTP Basic Authentication`,
|
||||||
/// return result with `Server` handle on success or an error.
|
/// return result with `Server` handle on success or an error.
|
||||||
pub fn start_basic_auth_http<S: Middleware<Metadata>>(self, addr: &SocketAddr, username: &str, password: &str, handler: RpcHandler<Metadata, S>) -> Result<Server, ServerError> {
|
pub fn start_basic_auth_http<S: Middleware<Metadata>>(self, addr: &SocketAddr, username: &str, password: &str, handler: MetaIoHandler<Metadata, S>, tokio_remote: TokioRemote) -> Result<Server, ServerError> {
|
||||||
let fetch = self.fetch_client()?;
|
let fetch = self.fetch_client()?;
|
||||||
Server::start_http(
|
Server::start_http(
|
||||||
addr,
|
addr,
|
||||||
@ -228,6 +234,7 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
self.sync_status,
|
self.sync_status,
|
||||||
self.web_proxy_tokens,
|
self.web_proxy_tokens,
|
||||||
self.remote,
|
self.remote,
|
||||||
|
tokio_remote,
|
||||||
fetch,
|
fetch,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -243,12 +250,11 @@ impl<T: Fetch> ServerBuilder<T> {
|
|||||||
/// Webapps HTTP server.
|
/// Webapps HTTP server.
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
server: Option<hyper::server::Listening>,
|
server: Option<hyper::server::Listening>,
|
||||||
panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
/// Returns a list of allowed hosts or `None` if all hosts are allowed.
|
/// Returns a list of allowed hosts or `None` if all hosts are allowed.
|
||||||
fn allowed_hosts(hosts: Option<Vec<String>>, bind_address: String) -> Option<Vec<String>> {
|
fn allowed_hosts(hosts: Option<Vec<Host>>, bind_address: String) -> Option<Vec<Host>> {
|
||||||
let mut allowed = Vec::new();
|
let mut allowed = Vec::new();
|
||||||
|
|
||||||
match hosts {
|
match hosts {
|
||||||
@ -263,16 +269,19 @@ impl Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of CORS domains for API endpoint.
|
/// Returns a list of CORS domains for API endpoint.
|
||||||
fn cors_domains(signer_address: Option<(String, u16)>, extra_cors: Option<Vec<String>>) -> Vec<String> {
|
fn cors_domains(
|
||||||
|
signer_address: Option<(String, u16)>,
|
||||||
|
extra_cors: Option<Vec<AccessControlAllowOrigin>>,
|
||||||
|
) -> Vec<AccessControlAllowOrigin> {
|
||||||
let basic_cors = match signer_address {
|
let basic_cors = match signer_address {
|
||||||
Some(signer_address) => vec![
|
Some(signer_address) => [
|
||||||
format!("http://{}{}", HOME_PAGE, DAPPS_DOMAIN),
|
format!("http://{}{}", HOME_PAGE, DAPPS_DOMAIN),
|
||||||
format!("http://{}{}:{}", HOME_PAGE, DAPPS_DOMAIN, signer_address.1),
|
format!("http://{}{}:{}", HOME_PAGE, DAPPS_DOMAIN, signer_address.1),
|
||||||
format!("http://{}", address(&signer_address)),
|
format!("http://{}", address(&signer_address)),
|
||||||
format!("https://{}{}", HOME_PAGE, DAPPS_DOMAIN),
|
format!("https://{}{}", HOME_PAGE, DAPPS_DOMAIN),
|
||||||
format!("https://{}{}:{}", HOME_PAGE, DAPPS_DOMAIN, signer_address.1),
|
format!("https://{}{}:{}", HOME_PAGE, DAPPS_DOMAIN, signer_address.1),
|
||||||
format!("https://{}", address(&signer_address)),
|
format!("https://{}", address(&signer_address)),
|
||||||
],
|
].into_iter().map(|val| AccessControlAllowOrigin::Value(val.into())).collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,10 +293,10 @@ impl Server {
|
|||||||
|
|
||||||
fn start_http<A: Authorization + 'static, F: Fetch, T: Middleware<Metadata>>(
|
fn start_http<A: Authorization + 'static, F: Fetch, T: Middleware<Metadata>>(
|
||||||
addr: &SocketAddr,
|
addr: &SocketAddr,
|
||||||
hosts: Option<Vec<String>>,
|
hosts: Option<Vec<Host>>,
|
||||||
extra_cors: Option<Vec<String>>,
|
extra_cors: Option<Vec<AccessControlAllowOrigin>>,
|
||||||
authorization: A,
|
authorization: A,
|
||||||
handler: RpcHandler<Metadata, T>,
|
handler: MetaIoHandler<Metadata, T>,
|
||||||
dapps_path: PathBuf,
|
dapps_path: PathBuf,
|
||||||
extra_dapps: Vec<PathBuf>,
|
extra_dapps: Vec<PathBuf>,
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
@ -295,9 +304,9 @@ impl Server {
|
|||||||
sync_status: Arc<SyncStatus>,
|
sync_status: Arc<SyncStatus>,
|
||||||
web_proxy_tokens: Arc<WebProxyTokens>,
|
web_proxy_tokens: Arc<WebProxyTokens>,
|
||||||
remote: Remote,
|
remote: Remote,
|
||||||
|
tokio_remote: TokioRemote,
|
||||||
fetch: F,
|
fetch: F,
|
||||||
) -> Result<Server, ServerError> {
|
) -> Result<Server, ServerError> {
|
||||||
let panic_handler = Arc::new(Mutex::new(None));
|
|
||||||
let authorization = Arc::new(authorization);
|
let authorization = Arc::new(authorization);
|
||||||
let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new(
|
let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new(
|
||||||
hash_fetch::urlhint::URLHintContract::new(registrar),
|
hash_fetch::urlhint::URLHintContract::new(registrar),
|
||||||
@ -318,7 +327,7 @@ impl Server {
|
|||||||
|
|
||||||
let special = Arc::new({
|
let special = Arc::new({
|
||||||
let mut special = HashMap::new();
|
let mut special = HashMap::new();
|
||||||
special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, cors_domains.clone(), panic_handler.clone()));
|
special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, tokio_remote, cors_domains.clone()));
|
||||||
special.insert(router::SpecialEndpoint::Utils, apps::utils());
|
special.insert(router::SpecialEndpoint::Utils, apps::utils());
|
||||||
special.insert(
|
special.insert(
|
||||||
router::SpecialEndpoint::Api,
|
router::SpecialEndpoint::Api,
|
||||||
@ -346,17 +355,11 @@ impl Server {
|
|||||||
|
|
||||||
Server {
|
Server {
|
||||||
server: Some(l),
|
server: Some(l),
|
||||||
panic_handler: panic_handler,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map_err(ServerError::from)
|
.map_err(ServerError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set callback for panics.
|
|
||||||
pub fn set_panic_handler<F>(&self, handler: F) where F : Fn() -> () + Send + 'static {
|
|
||||||
*self.panic_handler.lock().unwrap() = Some(Box::new(handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
/// Returns address that this server is bound to.
|
/// Returns address that this server is bound to.
|
||||||
pub fn addr(&self) -> &SocketAddr {
|
pub fn addr(&self) -> &SocketAddr {
|
||||||
@ -408,6 +411,7 @@ fn address(address: &(String, u16)) -> String {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod util_tests {
|
mod util_tests {
|
||||||
use super::Server;
|
use super::Server;
|
||||||
|
use jsonrpc_http_server::AccessControlAllowOrigin;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_return_allowed_hosts() {
|
fn should_return_allowed_hosts() {
|
||||||
@ -432,18 +436,18 @@ mod util_tests {
|
|||||||
// when
|
// when
|
||||||
let none = Server::cors_domains(None, None);
|
let none = Server::cors_domains(None, None);
|
||||||
let some = Server::cors_domains(Some(("127.0.0.1".into(), 18180)), None);
|
let some = Server::cors_domains(Some(("127.0.0.1".into(), 18180)), None);
|
||||||
let extra = Server::cors_domains(None, Some(vec!["all".to_owned()]));
|
let extra = Server::cors_domains(None, Some(vec!["all".into()]));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(none, Vec::<String>::new());
|
assert_eq!(none, Vec::<AccessControlAllowOrigin>::new());
|
||||||
assert_eq!(some, vec![
|
assert_eq!(some, vec![
|
||||||
"http://parity.web3.site".to_owned(),
|
"http://parity.web3.site".into(),
|
||||||
"http://parity.web3.site:18180".into(),
|
"http://parity.web3.site:18180".into(),
|
||||||
"http://127.0.0.1:18180".into(),
|
"http://127.0.0.1:18180".into(),
|
||||||
"https://parity.web3.site".into(),
|
"https://parity.web3.site".into(),
|
||||||
"https://parity.web3.site:18180".into(),
|
"https://parity.web3.site:18180".into(),
|
||||||
"https://127.0.0.1:18180".into()
|
"https://127.0.0.1:18180".into(),
|
||||||
]);
|
]);
|
||||||
assert_eq!(extra, vec!["all".to_owned()]);
|
assert_eq!(extra, vec![AccessControlAllowOrigin::Any]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,13 @@ use apps::DAPPS_DOMAIN;
|
|||||||
use hyper::{server, header, StatusCode};
|
use hyper::{server, header, StatusCode};
|
||||||
use hyper::net::HttpStream;
|
use hyper::net::HttpStream;
|
||||||
|
|
||||||
use jsonrpc_http_server::{is_host_header_valid};
|
|
||||||
use handlers::ContentHandler;
|
use handlers::ContentHandler;
|
||||||
|
use jsonrpc_http_server;
|
||||||
|
use jsonrpc_server_utils::hosts;
|
||||||
|
|
||||||
pub fn is_valid(request: &server::Request<HttpStream>, allowed_hosts: &[String], endpoints: Vec<String>) -> bool {
|
pub fn is_valid(req: &server::Request<HttpStream>, allowed_hosts: &Option<Vec<hosts::Host>>) -> bool {
|
||||||
let mut endpoints = endpoints.iter()
|
let header_valid = jsonrpc_http_server::is_host_allowed(req, allowed_hosts);
|
||||||
.map(|endpoint| format!("{}{}", endpoint, DAPPS_DOMAIN))
|
match (header_valid, req.headers().get::<header::Host>()) {
|
||||||
.collect::<Vec<String>>();
|
|
||||||
endpoints.extend_from_slice(allowed_hosts);
|
|
||||||
|
|
||||||
let header_valid = is_host_header_valid(request, &endpoints);
|
|
||||||
|
|
||||||
match (header_valid, request.headers().get::<header::Host>()) {
|
|
||||||
(true, _) => true,
|
(true, _) => true,
|
||||||
(_, Some(host)) => host.hostname.ends_with(DAPPS_DOMAIN),
|
(_, Some(host)) => host.hostname.ends_with(DAPPS_DOMAIN),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -24,14 +24,16 @@ use address;
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use url::{Url, Host};
|
use url::{Url, Host};
|
||||||
use hyper::{self, server, header, Next, Encoder, Decoder, Control, StatusCode};
|
use hyper::{self, server, header, Next, Encoder, Decoder, Control, StatusCode};
|
||||||
use hyper::net::HttpStream;
|
use hyper::net::HttpStream;
|
||||||
|
use jsonrpc_server_utils::hosts;
|
||||||
|
|
||||||
use apps::{self, DAPPS_DOMAIN};
|
use apps::{self, DAPPS_DOMAIN};
|
||||||
use apps::fetcher::Fetcher;
|
use apps::fetcher::Fetcher;
|
||||||
use endpoint::{Endpoint, Endpoints, EndpointPath};
|
use endpoint::{Endpoint, Endpoints, EndpointPath};
|
||||||
use handlers::{self, Redirection, ContentHandler};
|
use handlers::{self, Redirection, ContentHandler};
|
||||||
use self::auth::{Authorization, Authorized};
|
|
||||||
|
|
||||||
/// Special endpoints are accessible on every domain (every dapp)
|
/// Special endpoints are accessible on every domain (every dapp)
|
||||||
#[derive(Debug, PartialEq, Hash, Eq)]
|
#[derive(Debug, PartialEq, Hash, Eq)]
|
||||||
@ -42,18 +44,18 @@ pub enum SpecialEndpoint {
|
|||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Router<A: Authorization + 'static> {
|
pub struct Router<A: auth::Authorization + 'static> {
|
||||||
control: Option<Control>,
|
control: Option<Control>,
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
endpoints: Arc<Endpoints>,
|
endpoints: Arc<Endpoints>,
|
||||||
fetch: Arc<Fetcher>,
|
fetch: Arc<Fetcher>,
|
||||||
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
|
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
|
||||||
authorization: Arc<A>,
|
authorization: Arc<A>,
|
||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<hosts::Host>>,
|
||||||
handler: Box<server::Handler<HttpStream> + Send>,
|
handler: Box<server::Handler<HttpStream> + Send>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
|
impl<A: auth::Authorization + 'static> server::Handler<HttpStream> for Router<A> {
|
||||||
|
|
||||||
fn on_request(&mut self, req: server::Request<HttpStream>) -> Next {
|
fn on_request(&mut self, req: server::Request<HttpStream>) -> Next {
|
||||||
// Choose proper handler depending on path / domain
|
// Choose proper handler depending on path / domain
|
||||||
@ -66,20 +68,18 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
|
|||||||
trace!(target: "dapps", "Routing request to {:?}. Details: {:?}", url, req);
|
trace!(target: "dapps", "Routing request to {:?}. Details: {:?}", url, req);
|
||||||
|
|
||||||
// Validate Host header
|
// Validate Host header
|
||||||
if let Some(ref hosts) = self.allowed_hosts {
|
trace!(target: "dapps", "Validating host headers against: {:?}", self.allowed_hosts);
|
||||||
trace!(target: "dapps", "Validating host headers against: {:?}", hosts);
|
let is_valid = is_utils || host_validation::is_valid(&req, &self.allowed_hosts);
|
||||||
let is_valid = is_utils || host_validation::is_valid(&req, hosts, self.endpoints.keys().cloned().collect());
|
if !is_valid {
|
||||||
if !is_valid {
|
debug!(target: "dapps", "Rejecting invalid host header.");
|
||||||
debug!(target: "dapps", "Rejecting invalid host header.");
|
self.handler = host_validation::host_invalid_response();
|
||||||
self.handler = host_validation::host_invalid_response();
|
return self.handler.on_request(req);
|
||||||
return self.handler.on_request(req);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!(target: "dapps", "Checking authorization.");
|
trace!(target: "dapps", "Checking authorization.");
|
||||||
// Check authorization
|
// Check authorization
|
||||||
let auth = self.authorization.is_authorized(&req);
|
let auth = self.authorization.is_authorized(&req);
|
||||||
if let Authorized::No(handler) = auth {
|
if let auth::Authorized::No(handler) = auth {
|
||||||
debug!(target: "dapps", "Authorization denied.");
|
debug!(target: "dapps", "Authorization denied.");
|
||||||
self.handler = handler;
|
self.handler = handler;
|
||||||
return self.handler.on_request(req);
|
return self.handler.on_request(req);
|
||||||
@ -181,7 +181,7 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: Authorization> Router<A> {
|
impl<A: auth::Authorization> Router<A> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
control: Control,
|
control: Control,
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
@ -189,7 +189,7 @@ impl<A: Authorization> Router<A> {
|
|||||||
endpoints: Arc<Endpoints>,
|
endpoints: Arc<Endpoints>,
|
||||||
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
|
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
|
||||||
authorization: Arc<A>,
|
authorization: Arc<A>,
|
||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<hosts::Host>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
||||||
let handler = special.get(&SpecialEndpoint::Utils)
|
let handler = special.get(&SpecialEndpoint::Utils)
|
||||||
|
@ -14,55 +14,69 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
use hyper;
|
use hyper;
|
||||||
|
|
||||||
use ethcore_rpc::{Metadata, Origin};
|
use ethcore_rpc::{Metadata, Origin};
|
||||||
use jsonrpc_core::Middleware;
|
use jsonrpc_core::{Middleware, MetaIoHandler};
|
||||||
use jsonrpc_core::reactor::RpcHandler;
|
use jsonrpc_http_server::{self as http, AccessControlAllowOrigin, HttpMetaExtractor};
|
||||||
use jsonrpc_http_server::{Rpc, ServerHandler, PanicHandler, AccessControlAllowOrigin, HttpMetaExtractor};
|
use jsonrpc_http_server::tokio_core::reactor::Remote;
|
||||||
use endpoint::{Endpoint, EndpointPath, Handler};
|
use endpoint::{Endpoint, EndpointPath, Handler};
|
||||||
|
|
||||||
pub fn rpc<T: Middleware<Metadata>>(
|
pub fn rpc<T: Middleware<Metadata>>(
|
||||||
handler: RpcHandler<Metadata, T>,
|
handler: MetaIoHandler<Metadata, T>,
|
||||||
cors_domains: Vec<String>,
|
remote: Remote,
|
||||||
panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>,
|
cors_domains: Vec<AccessControlAllowOrigin>,
|
||||||
) -> Box<Endpoint> {
|
) -> Box<Endpoint> {
|
||||||
Box::new(RpcEndpoint {
|
Box::new(RpcEndpoint {
|
||||||
handler: handler,
|
handler: Arc::new(handler),
|
||||||
|
remote: remote,
|
||||||
meta_extractor: Arc::new(MetadataExtractor),
|
meta_extractor: Arc::new(MetadataExtractor),
|
||||||
panic_handler: panic_handler,
|
cors_domain: Some(cors_domains),
|
||||||
cors_domain: Some(cors_domains.into_iter().map(AccessControlAllowOrigin::Value).collect()),
|
|
||||||
// NOTE [ToDr] We don't need to do any hosts validation here. It's already done in router.
|
// NOTE [ToDr] We don't need to do any hosts validation here. It's already done in router.
|
||||||
allowed_hosts: None,
|
allowed_hosts: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RpcEndpoint<T: Middleware<Metadata>> {
|
struct RpcEndpoint<T: Middleware<Metadata>> {
|
||||||
handler: RpcHandler<Metadata, T>,
|
handler: Arc<MetaIoHandler<Metadata, T>>,
|
||||||
|
remote: Remote,
|
||||||
meta_extractor: Arc<HttpMetaExtractor<Metadata>>,
|
meta_extractor: Arc<HttpMetaExtractor<Metadata>>,
|
||||||
panic_handler: Arc<Mutex<Option<Box<Fn() -> () + Send>>>>,
|
|
||||||
cors_domain: Option<Vec<AccessControlAllowOrigin>>,
|
cors_domain: Option<Vec<AccessControlAllowOrigin>>,
|
||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<http::Host>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<T: Middleware<Metadata>> Endpoint for RpcEndpoint<T> {
|
impl<T: Middleware<Metadata>> Endpoint for RpcEndpoint<T> {
|
||||||
fn to_async_handler(&self, _path: EndpointPath, control: hyper::Control) -> Box<Handler> {
|
fn to_async_handler(&self, _path: EndpointPath, control: hyper::Control) -> Box<Handler> {
|
||||||
let panic_handler = PanicHandler { handler: self.panic_handler.clone() };
|
Box::new(http::ServerHandler::new(
|
||||||
Box::new(ServerHandler::new(
|
http::Rpc {
|
||||||
Rpc::new(self.handler.clone(), self.meta_extractor.clone()),
|
handler: self.handler.clone(),
|
||||||
|
remote: self.remote.clone(),
|
||||||
|
extractor: self.meta_extractor.clone(),
|
||||||
|
},
|
||||||
self.cors_domain.clone(),
|
self.cors_domain.clone(),
|
||||||
self.allowed_hosts.clone(),
|
self.allowed_hosts.clone(),
|
||||||
panic_handler,
|
Arc::new(NoopMiddleware),
|
||||||
control,
|
control,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct NoopMiddleware;
|
||||||
|
impl http::RequestMiddleware for NoopMiddleware {
|
||||||
|
fn on_request(&self, request: &http::hyper::server::Request<http::hyper::net::HttpStream>) -> http::RequestMiddlewareAction {
|
||||||
|
http::RequestMiddlewareAction::Proceed {
|
||||||
|
should_continue_on_invalid_cors: request.headers().get::<http::hyper::header::Origin>().is_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct MetadataExtractor;
|
struct MetadataExtractor;
|
||||||
impl HttpMetaExtractor<Metadata> for MetadataExtractor {
|
impl HttpMetaExtractor<Metadata> for MetadataExtractor {
|
||||||
fn read_metadata(&self, request: &hyper::server::Request<hyper::net::HttpStream>) -> Metadata {
|
fn read_metadata(&self, request: &http::hyper::server::Request<http::hyper::net::HttpStream>) -> Metadata {
|
||||||
let dapp_id = request.headers().get::<hyper::header::Origin>()
|
let dapp_id = request.headers().get::<http::hyper::header::Origin>()
|
||||||
.map(|origin| format!("{}://{}", origin.scheme, origin.host))
|
.map(|origin| format!("{}://{}", origin.scheme, origin.host))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
// fallback to custom header, but only if origin is null
|
// fallback to custom header, but only if origin is null
|
||||||
|
@ -33,8 +33,8 @@ fn should_return_error() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned());
|
response.assert_status("HTTP/1.1 404 Not Found");
|
||||||
assert_eq!(response.headers.get(3).unwrap(), "Content-Type: application/json");
|
response.assert_header("Content-Type", "application/json");
|
||||||
assert_eq!(response.body, format!("58\n{}\n0\n\n", r#"{"code":"404","title":"Not Found","detail":"Resource you requested has not been found."}"#));
|
assert_eq!(response.body, format!("58\n{}\n0\n\n", r#"{"code":"404","title":"Not Found","detail":"Resource you requested has not been found."}"#));
|
||||||
assert_security_headers(&response.headers);
|
assert_security_headers(&response.headers);
|
||||||
}
|
}
|
||||||
@ -56,8 +56,8 @@ fn should_serve_apps() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_eq!(response.headers.get(3).unwrap(), "Content-Type: application/json");
|
response.assert_header("Content-Type", "application/json");
|
||||||
assert!(response.body.contains("Parity UI"), response.body);
|
assert!(response.body.contains("Parity UI"), response.body);
|
||||||
assert_security_headers(&response.headers);
|
assert_security_headers(&response.headers);
|
||||||
}
|
}
|
||||||
@ -79,8 +79,8 @@ fn should_handle_ping() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_eq!(response.headers.get(3).unwrap(), "Content-Type: application/json");
|
response.assert_header("Content-Type", "application/json");
|
||||||
assert_eq!(response.body, "0\n\n".to_owned());
|
assert_eq!(response.body, "0\n\n".to_owned());
|
||||||
assert_security_headers(&response.headers);
|
assert_security_headers(&response.headers);
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ fn should_try_to_resolve_dapp() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned());
|
response.assert_status("HTTP/1.1 404 Not Found");
|
||||||
assert_eq!(registrar.calls.lock().len(), 2);
|
assert_eq!(registrar.calls.lock().len(), 2);
|
||||||
assert_security_headers(&response.headers);
|
assert_security_headers(&response.headers);
|
||||||
}
|
}
|
||||||
@ -125,12 +125,8 @@ fn should_return_signer_port_cors_headers() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert!(
|
response.assert_header("Access-Control-Allow-Origin", "http://127.0.0.1:18180");
|
||||||
response.headers_raw.contains("Access-Control-Allow-Origin: http://127.0.0.1:18180"),
|
|
||||||
"CORS header for signer missing: {:?}",
|
|
||||||
response.headers
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -151,12 +147,8 @@ fn should_return_signer_port_cors_headers_for_home_parity() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert!(
|
response.assert_header("Access-Control-Allow-Origin", "http://parity.web3.site");
|
||||||
response.headers_raw.contains("Access-Control-Allow-Origin: http://parity.web3.site"),
|
|
||||||
"CORS header for parity.web3.site missing: {:?}",
|
|
||||||
response.headers
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -178,12 +170,8 @@ fn should_return_signer_port_cors_headers_for_home_parity_with_https() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert!(
|
response.assert_header("Access-Control-Allow-Origin", "https://parity.web3.site");
|
||||||
response.headers_raw.contains("Access-Control-Allow-Origin: https://parity.web3.site"),
|
|
||||||
"CORS header for parity.web3.site missing: {:?}",
|
|
||||||
response.headers
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -204,12 +192,8 @@ fn should_return_signer_port_cors_headers_for_home_parity_with_port() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert!(
|
response.assert_header("Access-Control-Allow-Origin", "http://parity.web3.site:18180");
|
||||||
response.headers_raw.contains("Access-Control-Allow-Origin: http://parity.web3.site:18180"),
|
|
||||||
"CORS header for parity.web3.site missing: {:?}",
|
|
||||||
response.headers
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -114,7 +114,7 @@ impl Fetch for FakeFetch {
|
|||||||
|
|
||||||
let data = response.lock().take().unwrap_or(b"Some content");
|
let data = response.lock().take().unwrap_or(b"Some content");
|
||||||
let cursor = io::Cursor::new(data);
|
let cursor = io::Cursor::new(data);
|
||||||
tx.complete(fetch::Response::from_reader(cursor));
|
tx.send(fetch::Response::from_reader(cursor)).unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
rx.map_err(|_| fetch::Error::Aborted).boxed()
|
rx.map_err(|_| fetch::Error::Aborted).boxed()
|
||||||
|
@ -21,13 +21,12 @@ use std::sync::Arc;
|
|||||||
use env_logger::LogBuilder;
|
use env_logger::LogBuilder;
|
||||||
use ethcore_rpc::Metadata;
|
use ethcore_rpc::Metadata;
|
||||||
use jsonrpc_core::MetaIoHandler;
|
use jsonrpc_core::MetaIoHandler;
|
||||||
use jsonrpc_core::reactor::RpcEventLoop;
|
|
||||||
|
|
||||||
use ServerBuilder;
|
use ServerBuilder;
|
||||||
use Server;
|
use Server;
|
||||||
use fetch::Fetch;
|
use fetch::Fetch;
|
||||||
use devtools::http_client;
|
use devtools::http_client;
|
||||||
use parity_reactor::Remote;
|
use parity_reactor::{EventLoop, Remote};
|
||||||
|
|
||||||
mod registrar;
|
mod registrar;
|
||||||
mod fetch;
|
mod fetch;
|
||||||
@ -48,7 +47,7 @@ fn init_logger() {
|
|||||||
|
|
||||||
pub struct ServerLoop {
|
pub struct ServerLoop {
|
||||||
pub server: Server,
|
pub server: Server,
|
||||||
pub event_loop: RpcEventLoop,
|
pub event_loop: EventLoop,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for ServerLoop {
|
impl Deref for ServerLoop {
|
||||||
@ -70,13 +69,12 @@ pub fn init_server<F, B>(process: F, io: MetaIoHandler<Metadata>, remote: Remote
|
|||||||
|
|
||||||
// TODO [ToDr] When https://github.com/ethcore/jsonrpc/issues/26 is resolved
|
// TODO [ToDr] When https://github.com/ethcore/jsonrpc/issues/26 is resolved
|
||||||
// this additional EventLoop wouldn't be needed, we should be able to re-use remote.
|
// this additional EventLoop wouldn't be needed, we should be able to re-use remote.
|
||||||
let event_loop = RpcEventLoop::spawn();
|
let event_loop = EventLoop::spawn();
|
||||||
let handler = event_loop.handler(Arc::new(io));
|
|
||||||
let server = process(ServerBuilder::new(
|
let server = process(ServerBuilder::new(
|
||||||
&dapps_path, registrar.clone(), remote,
|
&dapps_path, registrar.clone(), remote,
|
||||||
))
|
))
|
||||||
.signer_address(Some(("127.0.0.1".into(), SIGNER_PORT)))
|
.signer_address(Some(("127.0.0.1".into(), SIGNER_PORT)))
|
||||||
.start_unsecured_http(&"127.0.0.1:0".parse().unwrap(), handler).unwrap();
|
.start_unsecured_http(&"127.0.0.1:0".parse().unwrap(), io, event_loop.raw_remote()).unwrap();
|
||||||
(
|
(
|
||||||
ServerLoop { server: server, event_loop: event_loop },
|
ServerLoop { server: server, event_loop: event_loop },
|
||||||
registrar,
|
registrar,
|
||||||
@ -89,12 +87,12 @@ pub fn serve_with_auth(user: &str, pass: &str) -> ServerLoop {
|
|||||||
let mut dapps_path = env::temp_dir();
|
let mut dapps_path = env::temp_dir();
|
||||||
dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading");
|
dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading");
|
||||||
|
|
||||||
let event_loop = RpcEventLoop::spawn();
|
let event_loop = EventLoop::spawn();
|
||||||
let handler = event_loop.handler(Arc::new(MetaIoHandler::default()));
|
let io = MetaIoHandler::default();
|
||||||
let server = ServerBuilder::new(&dapps_path, registrar, Remote::new(event_loop.remote()))
|
let server = ServerBuilder::new(&dapps_path, registrar, event_loop.remote())
|
||||||
.signer_address(Some(("127.0.0.1".into(), SIGNER_PORT)))
|
.signer_address(Some(("127.0.0.1".into(), SIGNER_PORT)))
|
||||||
.allowed_hosts(None)
|
.allowed_hosts(None.into())
|
||||||
.start_basic_auth_http(&"127.0.0.1:0".parse().unwrap(), user, pass, handler).unwrap();
|
.start_basic_auth_http(&"127.0.0.1:0".parse().unwrap(), user, pass, io, event_loop.raw_remote()).unwrap();
|
||||||
ServerLoop {
|
ServerLoop {
|
||||||
server: server,
|
server: server,
|
||||||
event_loop: event_loop,
|
event_loop: event_loop,
|
||||||
@ -102,26 +100,28 @@ pub fn serve_with_auth(user: &str, pass: &str) -> ServerLoop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve_with_rpc(io: MetaIoHandler<Metadata>) -> ServerLoop {
|
pub fn serve_with_rpc(io: MetaIoHandler<Metadata>) -> ServerLoop {
|
||||||
init_server(|builder| builder.allowed_hosts(None), io, Remote::new_sync()).0
|
init_server(|builder| builder.allowed_hosts(None.into()), io, Remote::new_sync()).0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve_hosts(hosts: Option<Vec<String>>) -> ServerLoop {
|
pub fn serve_hosts(hosts: Option<Vec<String>>) -> ServerLoop {
|
||||||
init_server(|builder| builder.allowed_hosts(hosts), Default::default(), Remote::new_sync()).0
|
let hosts = hosts.map(|hosts| hosts.into_iter().map(Into::into).collect());
|
||||||
|
init_server(|builder| builder.allowed_hosts(hosts.into()), Default::default(), Remote::new_sync()).0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve_extra_cors(extra_cors: Option<Vec<String>>) -> ServerLoop {
|
pub fn serve_extra_cors(extra_cors: Option<Vec<String>>) -> ServerLoop {
|
||||||
init_server(|builder| builder.allowed_hosts(None).extra_cors_headers(extra_cors), Default::default(), Remote::new_sync()).0
|
let extra_cors = extra_cors.map(|cors| cors.into_iter().map(Into::into).collect());
|
||||||
|
init_server(|builder| builder.allowed_hosts(None.into()).extra_cors_headers(extra_cors.into()), Default::default(), Remote::new_sync()).0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve_with_registrar() -> (ServerLoop, Arc<FakeRegistrar>) {
|
pub fn serve_with_registrar() -> (ServerLoop, Arc<FakeRegistrar>) {
|
||||||
init_server(|builder| builder.allowed_hosts(None), Default::default(), Remote::new_sync())
|
init_server(|builder| builder.allowed_hosts(None.into()), Default::default(), Remote::new_sync())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve_with_registrar_and_sync() -> (ServerLoop, Arc<FakeRegistrar>) {
|
pub fn serve_with_registrar_and_sync() -> (ServerLoop, Arc<FakeRegistrar>) {
|
||||||
init_server(|builder| {
|
init_server(|builder| {
|
||||||
builder
|
builder
|
||||||
.sync_status(Arc::new(|| true))
|
.sync_status(Arc::new(|| true))
|
||||||
.allowed_hosts(None)
|
.allowed_hosts(None.into())
|
||||||
}, Default::default(), Remote::new_sync())
|
}, Default::default(), Remote::new_sync())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ pub fn serve_with_registrar_and_fetch_and_threads(multi_threaded: bool) -> (Serv
|
|||||||
let fetch = FakeFetch::default();
|
let fetch = FakeFetch::default();
|
||||||
let f = fetch.clone();
|
let f = fetch.clone();
|
||||||
let (server, reg) = init_server(move |builder| {
|
let (server, reg) = init_server(move |builder| {
|
||||||
builder.allowed_hosts(None).fetch(f.clone())
|
builder.allowed_hosts(None.into()).fetch(f.clone())
|
||||||
}, Default::default(), if multi_threaded { Remote::new_thread_per_future() } else { Remote::new_sync() });
|
}, Default::default(), if multi_threaded { Remote::new_thread_per_future() } else { Remote::new_sync() });
|
||||||
|
|
||||||
(server, fetch, reg)
|
(server, fetch, reg)
|
||||||
@ -144,7 +144,7 @@ pub fn serve_with_fetch(web_token: &'static str) -> (ServerLoop, FakeFetch) {
|
|||||||
let f = fetch.clone();
|
let f = fetch.clone();
|
||||||
let (server, _) = init_server(move |builder| {
|
let (server, _) = init_server(move |builder| {
|
||||||
builder
|
builder
|
||||||
.allowed_hosts(None)
|
.allowed_hosts(None.into())
|
||||||
.fetch(f.clone())
|
.fetch(f.clone())
|
||||||
.web_proxy_tokens(Arc::new(move |token| &token == web_token))
|
.web_proxy_tokens(Arc::new(move |token| &token == web_token))
|
||||||
}, Default::default(), Remote::new_sync());
|
}, Default::default(), Remote::new_sync());
|
||||||
@ -153,7 +153,7 @@ pub fn serve_with_fetch(web_token: &'static str) -> (ServerLoop, FakeFetch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve() -> ServerLoop {
|
pub fn serve() -> ServerLoop {
|
||||||
init_server(|builder| builder.allowed_hosts(None), Default::default(), Remote::new_sync()).0
|
init_server(|builder| builder.allowed_hosts(None.into()), Default::default(), Remote::new_sync()).0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request(server: ServerLoop, request: &str) -> http_client::Response {
|
pub fn request(server: ServerLoop, request: &str) -> http_client::Response {
|
||||||
|
@ -32,7 +32,7 @@ fn should_redirect_to_home() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 302 Found".to_owned());
|
response.assert_status("HTTP/1.1 302 Found");
|
||||||
assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180");
|
assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ fn should_redirect_to_home_when_trailing_slash_is_missing() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 302 Found".to_owned());
|
response.assert_status("HTTP/1.1 302 Found");
|
||||||
assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180");
|
assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ fn should_redirect_to_home_for_users_with_cached_redirection() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 302 Found".to_owned());
|
response.assert_status("HTTP/1.1 302 Found");
|
||||||
assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180");
|
assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ fn should_display_404_on_invalid_dapp() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned());
|
response.assert_status("HTTP/1.1 404 Not Found");
|
||||||
assert_security_headers_for_embed(&response.headers);
|
assert_security_headers_for_embed(&response.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ fn should_display_404_on_invalid_dapp_with_domain() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 404 Not Found".to_owned());
|
response.assert_status("HTTP/1.1 404 Not Found");
|
||||||
assert_security_headers_for_embed(&response.headers);
|
assert_security_headers_for_embed(&response.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +134,8 @@ fn should_serve_rpc() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_eq!(response.body, format!("58\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error","data":null},"id":null}"#));
|
assert_eq!(response.body, format!("4C\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -156,8 +156,8 @@ fn should_serve_rpc_at_slash_rpc() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_eq!(response.body, format!("58\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error","data":null},"id":null}"#));
|
assert_eq!(response.body, format!("4C\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ fn should_serve_proxy_pac() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_eq!(response.body, "DD\n\nfunction FindProxyForURL(url, host) {\n\tif (shExpMatch(host, \"parity.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:18180\";\n\t}\n\n\tif (shExpMatch(host, \"*.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:8080\";\n\t}\n\n\treturn \"DIRECT\";\n}\n\n0\n\n".to_owned());
|
assert_eq!(response.body, "DD\n\nfunction FindProxyForURL(url, host) {\n\tif (shExpMatch(host, \"parity.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:18180\";\n\t}\n\n\tif (shExpMatch(host, \"*.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:8080\";\n\t}\n\n\treturn \"DIRECT\";\n}\n\n0\n\n".to_owned());
|
||||||
assert_security_headers(&response.headers);
|
assert_security_headers(&response.headers);
|
||||||
}
|
}
|
||||||
@ -200,7 +200,7 @@ fn should_serve_utils() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(response.status, "HTTP/1.1 200 OK".to_owned());
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_eq!(response.body.contains("function(){"), true);
|
assert_eq!(response.body.contains("function(){"), true);
|
||||||
assert_security_headers(&response.headers);
|
assert_security_headers(&response.headers);
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,8 @@ fn should_extract_metadata() {
|
|||||||
// given
|
// given
|
||||||
let mut io = MetaIoHandler::default();
|
let mut io = MetaIoHandler::default();
|
||||||
io.add_method_with_meta("rpc_test", |_params, meta: Metadata| {
|
io.add_method_with_meta("rpc_test", |_params, meta: Metadata| {
|
||||||
assert_eq!(meta.origin, Origin::Dapps("https://parity.io/".into()));
|
assert_eq!(meta.origin, Origin::Dapps("".into()));
|
||||||
assert_eq!(meta.dapp_id(), "https://parity.io/".into());
|
assert_eq!(meta.dapp_id(), "".into());
|
||||||
future::ok(Value::String("Hello World!".into())).boxed()
|
future::ok(Value::String("Hello World!".into())).boxed()
|
||||||
});
|
});
|
||||||
let server = serve_with_rpc(io);
|
let server = serve_with_rpc(io);
|
||||||
@ -68,7 +68,6 @@ fn should_extract_metadata() {
|
|||||||
POST /rpc/ HTTP/1.1\r\n\
|
POST /rpc/ HTTP/1.1\r\n\
|
||||||
Host: 127.0.0.1:8080\r\n\
|
Host: 127.0.0.1:8080\r\n\
|
||||||
Connection: close\r\n\
|
Connection: close\r\n\
|
||||||
Origin: https://parity.io/\r\n\
|
|
||||||
X-Parity-Origin: https://this.should.be.ignored\r\n\
|
X-Parity-Origin: https://this.should.be.ignored\r\n\
|
||||||
Content-Type: application/json\r\n\
|
Content-Type: application/json\r\n\
|
||||||
Content-Length: {}\r\n\
|
Content-Length: {}\r\n\
|
||||||
|
@ -44,10 +44,8 @@ ethcore-stratum = { path = "../stratum" }
|
|||||||
ethcore-bloom-journal = { path = "../util/bloom" }
|
ethcore-bloom-journal = { path = "../util/bloom" }
|
||||||
hardware-wallet = { path = "../hw" }
|
hardware-wallet = { path = "../hw" }
|
||||||
stats = { path = "../util/stats" }
|
stats = { path = "../util/stats" }
|
||||||
|
num = "0.1"
|
||||||
[dependencies.hyper]
|
hyper = { git = "https://github.com/paritytech/hyper", default-features = false }
|
||||||
git = "https://github.com/ethcore/hyper"
|
|
||||||
default-features = false
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
jit = ["evmjit"]
|
jit = ["evmjit"]
|
||||||
|
@ -135,6 +135,8 @@ pub struct OnDemand {
|
|||||||
orphaned_requests: RwLock<Vec<Pending>>,
|
orphaned_requests: RwLock<Vec<Pending>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RECEIVER_IN_SCOPE: &'static str = "Receiver is still in scope, so it's not dropped; qed";
|
||||||
|
|
||||||
impl OnDemand {
|
impl OnDemand {
|
||||||
/// Create a new `OnDemand` service with the given cache.
|
/// Create a new `OnDemand` service with the given cache.
|
||||||
pub fn new(cache: Arc<Mutex<Cache>>) -> Self {
|
pub fn new(cache: Arc<Mutex<Cache>>) -> Self {
|
||||||
@ -156,7 +158,7 @@ impl OnDemand {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match cached {
|
match cached {
|
||||||
Some(hash) => sender.send(hash).expect("receiver alive here; qed"),
|
Some(hash) => sender.send(hash).expect(RECEIVER_IN_SCOPE),
|
||||||
None => self.dispatch(ctx, Pending::HeaderProof(req, ChtProofSender::Hash(sender))),
|
None => self.dispatch(ctx, Pending::HeaderProof(req, ChtProofSender::Hash(sender))),
|
||||||
}
|
}
|
||||||
receiver
|
receiver
|
||||||
@ -172,7 +174,7 @@ impl OnDemand {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match cached {
|
match cached {
|
||||||
Some(score) => sender.send(score).expect("receiver alive here; qed"),
|
Some(score) => sender.send(score).expect(RECEIVER_IN_SCOPE),
|
||||||
None => self.dispatch(ctx, Pending::HeaderProof(req, ChtProofSender::ChainScore(sender))),
|
None => self.dispatch(ctx, Pending::HeaderProof(req, ChtProofSender::ChainScore(sender))),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +195,7 @@ impl OnDemand {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match cached {
|
match cached {
|
||||||
(Some(hash), Some(score)) => sender.send((hash, score)).expect("receiver alive here; qed"),
|
(Some(hash), Some(score)) => sender.send((hash, score)).expect(RECEIVER_IN_SCOPE),
|
||||||
_ => self.dispatch(ctx, Pending::HeaderProof(req, ChtProofSender::Both(sender))),
|
_ => self.dispatch(ctx, Pending::HeaderProof(req, ChtProofSender::Both(sender))),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +208,7 @@ impl OnDemand {
|
|||||||
pub fn header_by_hash(&self, ctx: &BasicContext, req: request::HeaderByHash) -> Receiver<encoded::Header> {
|
pub fn header_by_hash(&self, ctx: &BasicContext, req: request::HeaderByHash) -> Receiver<encoded::Header> {
|
||||||
let (sender, receiver) = oneshot::channel();
|
let (sender, receiver) = oneshot::channel();
|
||||||
match self.cache.lock().block_header(&req.0) {
|
match self.cache.lock().block_header(&req.0) {
|
||||||
Some(hdr) => sender.send(hdr).expect("receiver alive here; qed"),
|
Some(hdr) => sender.send(hdr).expect(RECEIVER_IN_SCOPE),
|
||||||
None => self.dispatch(ctx, Pending::HeaderByHash(req, sender)),
|
None => self.dispatch(ctx, Pending::HeaderByHash(req, sender)),
|
||||||
}
|
}
|
||||||
receiver
|
receiver
|
||||||
@ -225,7 +227,7 @@ impl OnDemand {
|
|||||||
stream.begin_list(0);
|
stream.begin_list(0);
|
||||||
stream.begin_list(0);
|
stream.begin_list(0);
|
||||||
|
|
||||||
sender.send(encoded::Block::new(stream.out())).expect("receiver alive here; qed");
|
sender.send(encoded::Block::new(stream.out())).expect(RECEIVER_IN_SCOPE);
|
||||||
} else {
|
} else {
|
||||||
match self.cache.lock().block_body(&req.hash) {
|
match self.cache.lock().block_body(&req.hash) {
|
||||||
Some(body) => {
|
Some(body) => {
|
||||||
@ -233,7 +235,7 @@ impl OnDemand {
|
|||||||
stream.append_raw(&req.header.into_inner(), 1);
|
stream.append_raw(&req.header.into_inner(), 1);
|
||||||
stream.append_raw(&body.into_inner(), 2);
|
stream.append_raw(&body.into_inner(), 2);
|
||||||
|
|
||||||
sender.send(encoded::Block::new(stream.out())).expect("receiver alive here; qed");
|
sender.send(encoded::Block::new(stream.out())).expect(RECEIVER_IN_SCOPE);
|
||||||
}
|
}
|
||||||
None => self.dispatch(ctx, Pending::Block(req, sender)),
|
None => self.dispatch(ctx, Pending::Block(req, sender)),
|
||||||
}
|
}
|
||||||
@ -248,10 +250,10 @@ impl OnDemand {
|
|||||||
|
|
||||||
// fast path for empty receipts.
|
// fast path for empty receipts.
|
||||||
if req.0.receipts_root() == SHA3_NULL_RLP {
|
if req.0.receipts_root() == SHA3_NULL_RLP {
|
||||||
sender.send(Vec::new()).expect("receiver alive here; qed");
|
sender.send(Vec::new()).expect(RECEIVER_IN_SCOPE);
|
||||||
} else {
|
} else {
|
||||||
match self.cache.lock().block_receipts(&req.0.hash()) {
|
match self.cache.lock().block_receipts(&req.0.hash()) {
|
||||||
Some(receipts) => sender.send(receipts).expect("receiver alive here; qed"),
|
Some(receipts) => sender.send(receipts).expect(RECEIVER_IN_SCOPE),
|
||||||
None => self.dispatch(ctx, Pending::BlockReceipts(req, sender)),
|
None => self.dispatch(ctx, Pending::BlockReceipts(req, sender)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,7 +275,7 @@ impl OnDemand {
|
|||||||
|
|
||||||
// fast path for no code.
|
// fast path for no code.
|
||||||
if req.code_hash == ::util::sha3::SHA3_EMPTY {
|
if req.code_hash == ::util::sha3::SHA3_EMPTY {
|
||||||
sender.send(Vec::new()).expect("receiver alive here; qed")
|
sender.send(Vec::new()).expect(RECEIVER_IN_SCOPE)
|
||||||
} else {
|
} else {
|
||||||
self.dispatch(ctx, Pending::Code(req, sender));
|
self.dispatch(ctx, Pending::Code(req, sender));
|
||||||
}
|
}
|
||||||
|
@ -189,6 +189,7 @@
|
|||||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
|
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x7fffffffffffff", "pricing": { "modexp": { "divisor": 20 } } } },
|
||||||
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
|
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
|
||||||
"balance": "1337000000000000000000"
|
"balance": "1337000000000000000000"
|
||||||
},
|
},
|
||||||
|
@ -14,11 +14,16 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::cmp::{max, min};
|
||||||
|
use std::io::{self, Read};
|
||||||
|
|
||||||
|
use byteorder::{ByteOrder, BigEndian};
|
||||||
use crypto::sha2::Sha256 as Sha256Digest;
|
use crypto::sha2::Sha256 as Sha256Digest;
|
||||||
use crypto::ripemd160::Ripemd160 as Ripemd160Digest;
|
use crypto::ripemd160::Ripemd160 as Ripemd160Digest;
|
||||||
use crypto::digest::Digest;
|
use crypto::digest::Digest;
|
||||||
use std::cmp::min;
|
use num::{BigUint, Zero, One};
|
||||||
use util::{U256, H256, Hashable, BytesRef};
|
|
||||||
|
use util::{U256, H256, Uint, Hashable, BytesRef};
|
||||||
use ethkey::{Signature, recover as ec_recover};
|
use ethkey::{Signature, recover as ec_recover};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
|
|
||||||
@ -30,8 +35,8 @@ pub trait Impl: Send + Sync {
|
|||||||
|
|
||||||
/// A gas pricing scheme for built-in contracts.
|
/// A gas pricing scheme for built-in contracts.
|
||||||
pub trait Pricer: Send + Sync {
|
pub trait Pricer: Send + Sync {
|
||||||
/// The gas cost of running this built-in for the given size of input data.
|
/// The gas cost of running this built-in for the given input data.
|
||||||
fn cost(&self, in_size: usize) -> U256;
|
fn cost(&self, input: &[u8]) -> U256;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A linear pricing model. This computes a price using a base cost and a cost per-word.
|
/// A linear pricing model. This computes a price using a base cost and a cost per-word.
|
||||||
@ -40,40 +45,94 @@ struct Linear {
|
|||||||
word: usize,
|
word: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A special pricing model for modular exponentiation.
|
||||||
|
struct Modexp {
|
||||||
|
divisor: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl Pricer for Linear {
|
impl Pricer for Linear {
|
||||||
fn cost(&self, in_size: usize) -> U256 {
|
fn cost(&self, input: &[u8]) -> U256 {
|
||||||
U256::from(self.base) + U256::from(self.word) * U256::from((in_size + 31) / 32)
|
U256::from(self.base) + U256::from(self.word) * U256::from((input.len() + 31) / 32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pricing scheme and execution definition for a built-in contract.
|
impl Pricer for Modexp {
|
||||||
|
fn cost(&self, input: &[u8]) -> U256 {
|
||||||
|
let mut reader = input.chain(io::repeat(0));
|
||||||
|
let mut buf = [0; 32];
|
||||||
|
|
||||||
|
// read lengths as U256 here for accurate gas calculation.
|
||||||
|
let mut read_len = || {
|
||||||
|
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
||||||
|
U256::from(H256::from_slice(&buf[..]))
|
||||||
|
};
|
||||||
|
let base_len = read_len();
|
||||||
|
let exp_len = read_len();
|
||||||
|
let mod_len = read_len();
|
||||||
|
|
||||||
|
// floor(max(length_of_MODULUS, length_of_BASE) ** 2 * max(length_of_EXPONENT, 1) / GQUADDIVISOR)
|
||||||
|
// TODO: is saturating the best behavior here?
|
||||||
|
let m = max(mod_len, base_len);
|
||||||
|
match m.overflowing_mul(m) {
|
||||||
|
(_, true) => U256::max_value(),
|
||||||
|
(val, _) => {
|
||||||
|
match val.overflowing_mul(max(exp_len, U256::one())) {
|
||||||
|
(_, true) => U256::max_value(),
|
||||||
|
(val, _) => val / (self.divisor as u64).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pricing scheme, execution definition, and activation block for a built-in contract.
|
||||||
|
///
|
||||||
|
/// Call `cost` to compute cost for the given input, `execute` to execute the contract
|
||||||
|
/// on the given input, and `is_active` to determine whether the contract is active.
|
||||||
|
///
|
||||||
|
/// Unless `is_active` is true,
|
||||||
pub struct Builtin {
|
pub struct Builtin {
|
||||||
pricer: Box<Pricer>,
|
pricer: Box<Pricer>,
|
||||||
native: Box<Impl>,
|
native: Box<Impl>,
|
||||||
|
activate_at: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Builtin {
|
impl Builtin {
|
||||||
/// Simple forwarder for cost.
|
/// Simple forwarder for cost.
|
||||||
pub fn cost(&self, s: usize) -> U256 { self.pricer.cost(s) }
|
pub fn cost(&self, input: &[u8]) -> U256 { self.pricer.cost(input) }
|
||||||
|
|
||||||
/// Simple forwarder for execute.
|
/// Simple forwarder for execute.
|
||||||
pub fn execute(&self, input: &[u8], output: &mut BytesRef) { self.native.execute(input, output) }
|
pub fn execute(&self, input: &[u8], output: &mut BytesRef) { self.native.execute(input, output) }
|
||||||
|
|
||||||
|
/// Whether the builtin is activated at the given block number.
|
||||||
|
pub fn is_active(&self, at: u64) -> bool { at >= self.activate_at }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethjson::spec::Builtin> for Builtin {
|
impl From<ethjson::spec::Builtin> for Builtin {
|
||||||
fn from(b: ethjson::spec::Builtin) -> Self {
|
fn from(b: ethjson::spec::Builtin) -> Self {
|
||||||
let pricer = match b.pricing {
|
let pricer: Box<Pricer> = match b.pricing {
|
||||||
ethjson::spec::Pricing::Linear(linear) => {
|
ethjson::spec::Pricing::Linear(linear) => {
|
||||||
Box::new(Linear {
|
Box::new(Linear {
|
||||||
base: linear.base,
|
base: linear.base,
|
||||||
word: linear.word,
|
word: linear.word,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
ethjson::spec::Pricing::Modexp(exp) => {
|
||||||
|
Box::new(Modexp {
|
||||||
|
divisor: if exp.divisor == 0 {
|
||||||
|
warn!("Zero modexp divisor specified. Falling back to default.");
|
||||||
|
10
|
||||||
|
} else {
|
||||||
|
exp.divisor
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Builtin {
|
Builtin {
|
||||||
pricer: pricer,
|
pricer: pricer,
|
||||||
native: ethereum_builtin(&b.name),
|
native: ethereum_builtin(&b.name),
|
||||||
|
activate_at: b.activate_at.map(Into::into).unwrap_or(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,6 +144,7 @@ fn ethereum_builtin(name: &str) -> Box<Impl> {
|
|||||||
"ecrecover" => Box::new(EcRecover) as Box<Impl>,
|
"ecrecover" => Box::new(EcRecover) as Box<Impl>,
|
||||||
"sha256" => Box::new(Sha256) as Box<Impl>,
|
"sha256" => Box::new(Sha256) as Box<Impl>,
|
||||||
"ripemd160" => Box::new(Ripemd160) as Box<Impl>,
|
"ripemd160" => Box::new(Ripemd160) as Box<Impl>,
|
||||||
|
"modexp" => Box::new(ModexpImpl) as Box<Impl>,
|
||||||
_ => panic!("invalid builtin name: {}", name),
|
_ => panic!("invalid builtin name: {}", name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,6 +155,7 @@ fn ethereum_builtin(name: &str) -> Box<Impl> {
|
|||||||
// - ec recovery
|
// - ec recovery
|
||||||
// - sha256
|
// - sha256
|
||||||
// - ripemd160
|
// - ripemd160
|
||||||
|
// - modexp (EIP198)
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Identity;
|
struct Identity;
|
||||||
@ -108,6 +169,9 @@ struct Sha256;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Ripemd160;
|
struct Ripemd160;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ModexpImpl;
|
||||||
|
|
||||||
impl Impl for Identity {
|
impl Impl for Identity {
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) {
|
||||||
output.write(0, input);
|
output.write(0, input);
|
||||||
@ -166,9 +230,76 @@ impl Impl for Ripemd160 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Impl for ModexpImpl {
|
||||||
|
fn execute(&self, input: &[u8], output: &mut BytesRef) {
|
||||||
|
let mut reader = input.chain(io::repeat(0));
|
||||||
|
let mut buf = [0; 32];
|
||||||
|
|
||||||
|
// read lengths as usize.
|
||||||
|
// ignoring the first 24 bytes might technically lead us to fall out of consensus,
|
||||||
|
// but so would running out of addressable memory!
|
||||||
|
let mut read_len = |reader: &mut io::Chain<&[u8], io::Repeat>| {
|
||||||
|
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
||||||
|
BigEndian::read_u64(&buf[24..]) as usize
|
||||||
|
};
|
||||||
|
|
||||||
|
let base_len = read_len(&mut reader);
|
||||||
|
let exp_len = read_len(&mut reader);
|
||||||
|
let mod_len = read_len(&mut reader);
|
||||||
|
|
||||||
|
// read the numbers themselves.
|
||||||
|
let mut buf = vec![0; max(mod_len, max(base_len, exp_len))];
|
||||||
|
let mut read_num = |len| {
|
||||||
|
reader.read_exact(&mut buf[..len]).expect("reading from zero-extended memory cannot fail; qed");
|
||||||
|
BigUint::from_bytes_be(&buf[..len])
|
||||||
|
};
|
||||||
|
|
||||||
|
let base = read_num(base_len);
|
||||||
|
let exp = read_num(exp_len);
|
||||||
|
let modulus = read_num(mod_len);
|
||||||
|
|
||||||
|
// calculate modexp: exponentiation by squaring.
|
||||||
|
fn modexp(mut base: BigUint, mut exp: BigUint, modulus: BigUint) -> BigUint {
|
||||||
|
match (base == BigUint::zero(), exp == BigUint::zero()) {
|
||||||
|
(_, true) => return BigUint::one(), // n^0 % m
|
||||||
|
(true, false) => return BigUint::zero(), // 0^n % m, n>0
|
||||||
|
(false, false) if modulus <= BigUint::one() => return BigUint::zero(), // a^b % 1 = 0.
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = BigUint::one();
|
||||||
|
base = base % &modulus;
|
||||||
|
|
||||||
|
// fast path for base divisible by modulus.
|
||||||
|
if base == BigUint::zero() { return result }
|
||||||
|
while exp != BigUint::zero() {
|
||||||
|
// exp has to be on the right here to avoid move.
|
||||||
|
if BigUint::one() & &exp == BigUint::one() {
|
||||||
|
result = (result * &base) % &modulus;
|
||||||
|
}
|
||||||
|
|
||||||
|
exp = exp >> 1;
|
||||||
|
base = (base.clone() * base) % &modulus;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
// write output to given memory, left padded and same length as the modulus.
|
||||||
|
let bytes = modexp(base, exp, modulus).to_bytes_be();
|
||||||
|
|
||||||
|
// always true except in the case of zero-length modulus, which leads to
|
||||||
|
// output of length and value 1.
|
||||||
|
if bytes.len() <= mod_len {
|
||||||
|
let res_start = mod_len - bytes.len();
|
||||||
|
output.write(res_start, &bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Builtin, Linear, ethereum_builtin, Pricer};
|
use super::{Builtin, Linear, ethereum_builtin, Pricer, Modexp};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use util::{U256, BytesRef};
|
use util::{U256, BytesRef};
|
||||||
|
|
||||||
@ -295,24 +426,126 @@ mod tests {
|
|||||||
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);*/
|
assert_eq!(&o[..], &(FromHex::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap())[..]);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn modexp() {
|
||||||
|
use rustc_serialize::hex::FromHex;
|
||||||
|
|
||||||
|
let f = Builtin {
|
||||||
|
pricer: Box::new(Modexp { divisor: 20 }),
|
||||||
|
native: ethereum_builtin("modexp"),
|
||||||
|
activate_at: 0,
|
||||||
|
};
|
||||||
|
// fermat's little theorem example.
|
||||||
|
{
|
||||||
|
let input = FromHex::from_hex("\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000001\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000020\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000020\
|
||||||
|
03\
|
||||||
|
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\
|
||||||
|
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let mut output = vec![0u8; 32];
|
||||||
|
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001").unwrap();
|
||||||
|
let expected_cost = 1638;
|
||||||
|
|
||||||
|
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..]));
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
assert_eq!(f.cost(&input[..]), expected_cost.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// second example from EIP: zero base.
|
||||||
|
{
|
||||||
|
let input = FromHex::from_hex("\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000000\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000020\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000020\
|
||||||
|
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e\
|
||||||
|
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let mut output = vec![0u8; 32];
|
||||||
|
let expected = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||||
|
let expected_cost = 1638;
|
||||||
|
|
||||||
|
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..]));
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
assert_eq!(f.cost(&input[..]), expected_cost.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// another example from EIP: zero-padding
|
||||||
|
{
|
||||||
|
let input = FromHex::from_hex("\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000001\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000002\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000020\
|
||||||
|
03\
|
||||||
|
ffff\
|
||||||
|
80"
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let mut output = vec![0u8; 32];
|
||||||
|
let expected = FromHex::from_hex("3b01b01ac41f2d6e917c6d6a221ce793802469026d9ab7578fa2e79e4da6aaab").unwrap();
|
||||||
|
let expected_cost = 102;
|
||||||
|
|
||||||
|
f.execute(&input[..], &mut BytesRef::Fixed(&mut output[..]));
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
assert_eq!(f.cost(&input[..]), expected_cost.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// zero-length modulus.
|
||||||
|
{
|
||||||
|
let input = FromHex::from_hex("\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000001\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000002\
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000000\
|
||||||
|
03\
|
||||||
|
ffff"
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let mut output = vec![];
|
||||||
|
let expected_cost = 0;
|
||||||
|
|
||||||
|
f.execute(&input[..], &mut BytesRef::Flexible(&mut output));
|
||||||
|
assert_eq!(output.len(), 0); // shouldn't have written any output.
|
||||||
|
assert_eq!(f.cost(&input[..]), expected_cost.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn from_unknown_linear() {
|
fn from_unknown_linear() {
|
||||||
let _ = ethereum_builtin("foo");
|
let _ = ethereum_builtin("foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_active() {
|
||||||
|
let pricer = Box::new(Linear { base: 10, word: 20} );
|
||||||
|
let b = Builtin {
|
||||||
|
pricer: pricer as Box<Pricer>,
|
||||||
|
native: ethereum_builtin("identity"),
|
||||||
|
activate_at: 100_000,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(!b.is_active(99_999));
|
||||||
|
assert!(b.is_active(100_000));
|
||||||
|
assert!(b.is_active(100_001));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_named_linear() {
|
fn from_named_linear() {
|
||||||
let pricer = Box::new(Linear { base: 10, word: 20 });
|
let pricer = Box::new(Linear { base: 10, word: 20 });
|
||||||
let b = Builtin {
|
let b = Builtin {
|
||||||
pricer: pricer as Box<Pricer>,
|
pricer: pricer as Box<Pricer>,
|
||||||
native: ethereum_builtin("identity"),
|
native: ethereum_builtin("identity"),
|
||||||
|
activate_at: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(b.cost(0), U256::from(10));
|
assert_eq!(b.cost(&[0; 0]), U256::from(10));
|
||||||
assert_eq!(b.cost(1), U256::from(30));
|
assert_eq!(b.cost(&[0; 1]), U256::from(30));
|
||||||
assert_eq!(b.cost(32), U256::from(30));
|
assert_eq!(b.cost(&[0; 32]), U256::from(30));
|
||||||
assert_eq!(b.cost(33), U256::from(50));
|
assert_eq!(b.cost(&[0; 33]), U256::from(50));
|
||||||
|
|
||||||
let i = [0u8, 1, 2, 3];
|
let i = [0u8, 1, 2, 3];
|
||||||
let mut o = [255u8; 4];
|
let mut o = [255u8; 4];
|
||||||
@ -327,13 +560,14 @@ mod tests {
|
|||||||
pricing: ethjson::spec::Pricing::Linear(ethjson::spec::Linear {
|
pricing: ethjson::spec::Pricing::Linear(ethjson::spec::Linear {
|
||||||
base: 10,
|
base: 10,
|
||||||
word: 20,
|
word: 20,
|
||||||
})
|
}),
|
||||||
|
activate_at: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(b.cost(0), U256::from(10));
|
assert_eq!(b.cost(&[0; 0]), U256::from(10));
|
||||||
assert_eq!(b.cost(1), U256::from(30));
|
assert_eq!(b.cost(&[0; 1]), U256::from(30));
|
||||||
assert_eq!(b.cost(32), U256::from(30));
|
assert_eq!(b.cost(&[0; 32]), U256::from(30));
|
||||||
assert_eq!(b.cost(33), U256::from(50));
|
assert_eq!(b.cost(&[0; 33]), U256::from(50));
|
||||||
|
|
||||||
let i = [0u8, 1, 2, 3];
|
let i = [0u8, 1, 2, 3];
|
||||||
let mut o = [255u8; 4];
|
let mut o = [255u8; 4];
|
||||||
|
@ -189,19 +189,14 @@ pub trait Engine : Sync + Send {
|
|||||||
/// updating consensus state and potentially issuing a new one.
|
/// updating consensus state and potentially issuing a new one.
|
||||||
fn handle_message(&self, _message: &[u8]) -> Result<(), Error> { Err(EngineError::UnexpectedMessage.into()) }
|
fn handle_message(&self, _message: &[u8]) -> Result<(), Error> { Err(EngineError::UnexpectedMessage.into()) }
|
||||||
|
|
||||||
|
/// Attempt to get a handle to a built-in contract.
|
||||||
|
/// Only returns references to activated built-ins.
|
||||||
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
|
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
|
||||||
// from Spec into here and removing the Spec::builtins field.
|
// from Spec into here and removing the Spec::builtins field.
|
||||||
/// Determine whether a particular address is a builtin contract.
|
fn builtin(&self, a: &Address, block_number: ::header::BlockNumber) -> Option<&Builtin> {
|
||||||
fn is_builtin(&self, a: &Address) -> bool { self.builtins().contains_key(a) }
|
self.builtins()
|
||||||
/// Determine the code execution cost of the builtin contract with address `a`.
|
.get(a)
|
||||||
/// Panics if `is_builtin(a)` is not true.
|
.and_then(|b| if b.is_active(block_number) { Some(b) } else { None })
|
||||||
fn cost_of_builtin(&self, a: &Address, input: &[u8]) -> U256 {
|
|
||||||
self.builtins().get(a).expect("queried cost of nonexistent builtin").cost(input.len())
|
|
||||||
}
|
|
||||||
/// Execution the builtin contract `a` on `input` and return `output`.
|
|
||||||
/// Panics if `is_builtin(a)` is not true.
|
|
||||||
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut BytesRef) {
|
|
||||||
self.builtins().get(a).expect("attempted to execute nonexistent builtin").execute(input, output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find out if the block is a proposal block and should not be inserted into the DB.
|
/// Find out if the block is a proposal block and should not be inserted into the DB.
|
||||||
|
@ -261,17 +261,22 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
|||||||
}
|
}
|
||||||
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info);
|
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info);
|
||||||
|
|
||||||
if self.engine.is_builtin(¶ms.code_address) {
|
// if destination is builtin, try to execute it
|
||||||
// if destination is builtin, try to execute it
|
if let Some(builtin) = self.engine.builtin(¶ms.code_address, self.info.number) {
|
||||||
|
// Engines aren't supposed to return builtins until activation, but
|
||||||
|
// prefer to fail rather than silently break consensus.
|
||||||
|
if !builtin.is_active(self.info.number) {
|
||||||
|
panic!("Consensus failure: engine implementation prematurely enabled built-in at {}", params.code_address);
|
||||||
|
}
|
||||||
|
|
||||||
let default = [];
|
let default = [];
|
||||||
let data = if let Some(ref d) = params.data { d as &[u8] } else { &default as &[u8] };
|
let data = if let Some(ref d) = params.data { d as &[u8] } else { &default as &[u8] };
|
||||||
|
|
||||||
let trace_info = tracer.prepare_trace_call(¶ms);
|
let trace_info = tracer.prepare_trace_call(¶ms);
|
||||||
|
|
||||||
let cost = self.engine.cost_of_builtin(¶ms.code_address, data);
|
let cost = builtin.cost(data);
|
||||||
if cost <= params.gas {
|
if cost <= params.gas {
|
||||||
self.engine.execute_builtin(¶ms.code_address, data, &mut output);
|
builtin.execute(data, &mut output);
|
||||||
self.state.discard_checkpoint();
|
self.state.discard_checkpoint();
|
||||||
|
|
||||||
// trace only top level calls to builtins to avoid DDoS attacks
|
// trace only top level calls to builtins to avoid DDoS attacks
|
||||||
|
@ -106,6 +106,7 @@ extern crate ethcore_stratum;
|
|||||||
extern crate ethabi;
|
extern crate ethabi;
|
||||||
extern crate hardware_wallet;
|
extern crate hardware_wallet;
|
||||||
extern crate stats;
|
extern crate stats;
|
||||||
|
extern crate num;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
@ -326,7 +326,7 @@ impl Spec {
|
|||||||
pub fn load<R>(reader: R) -> Result<Self, String> where R: Read {
|
pub fn load<R>(reader: R) -> Result<Self, String> where R: Read {
|
||||||
match ethjson::spec::Spec::load(reader) {
|
match ethjson::spec::Spec::load(reader) {
|
||||||
Ok(spec) => Ok(spec.into()),
|
Ok(spec) => Ok(spec.into()),
|
||||||
_ => Err("Spec json is invalid".into()),
|
Err(e) => Err(format!("Spec json is invalid: {}", e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ethcore = { path = "../ethcore" }
|
ethcore = { path = "../ethcore" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
mime = "0.2"
|
mime = "0.2"
|
||||||
hyper = { default-features = false, git = "https://github.com/ethcore/hyper" }
|
|
||||||
cid = "0.2.1"
|
cid = "0.2.1"
|
||||||
multihash = "0.5"
|
multihash = "0.5"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use {multihash, cid, hyper};
|
use {multihash, cid, http};
|
||||||
use route::Out;
|
use route::Out;
|
||||||
|
|
||||||
pub type Result<T> = ::std::result::Result<T, Error>;
|
pub type Result<T> = ::std::result::Result<T, Error>;
|
||||||
@ -25,7 +25,7 @@ pub enum ServerError {
|
|||||||
/// Wrapped `std::io::Error`
|
/// Wrapped `std::io::Error`
|
||||||
IoError(::std::io::Error),
|
IoError(::std::io::Error),
|
||||||
/// Other `hyper` error
|
/// Other `hyper` error
|
||||||
Other(hyper::error::Error),
|
Other(http::hyper::error::Error),
|
||||||
/// Invalid --ipfs-api-interface
|
/// Invalid --ipfs-api-interface
|
||||||
InvalidInterface
|
InvalidInterface
|
||||||
}
|
}
|
||||||
@ -80,8 +80,8 @@ impl From<::std::io::Error> for ServerError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<hyper::error::Error> for ServerError {
|
impl From<http::hyper::error::Error> for ServerError {
|
||||||
fn from(err: hyper::error::Error) -> ServerError {
|
fn from(err: http::hyper::error::Error) -> ServerError {
|
||||||
ServerError::Other(err)
|
ServerError::Other(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,13 @@
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate mime;
|
extern crate mime;
|
||||||
extern crate hyper;
|
|
||||||
extern crate multihash;
|
extern crate multihash;
|
||||||
extern crate cid;
|
extern crate cid;
|
||||||
|
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate ethcore;
|
extern crate ethcore;
|
||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
extern crate jsonrpc_http_server;
|
extern crate jsonrpc_http_server as http;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod route;
|
mod route;
|
||||||
@ -33,13 +32,13 @@ use std::sync::Arc;
|
|||||||
use std::net::{SocketAddr, IpAddr};
|
use std::net::{SocketAddr, IpAddr};
|
||||||
use error::ServerError;
|
use error::ServerError;
|
||||||
use route::Out;
|
use route::Out;
|
||||||
use jsonrpc_http_server::cors;
|
use http::hyper::server::{Listening, Handler, Request, Response};
|
||||||
use hyper::server::{Listening, Handler, Request, Response};
|
use http::hyper::net::HttpStream;
|
||||||
use hyper::net::HttpStream;
|
use http::hyper::header::{self, Vary, ContentLength, ContentType};
|
||||||
use hyper::header::{Vary, ContentLength, ContentType, AccessControlAllowOrigin};
|
use http::hyper::{Next, Encoder, Decoder, Method, RequestUri, StatusCode};
|
||||||
use hyper::{Next, Encoder, Decoder, Method, RequestUri, StatusCode};
|
|
||||||
use ethcore::client::BlockChainClient;
|
use ethcore::client::BlockChainClient;
|
||||||
|
|
||||||
|
pub use http::{AccessControlAllowOrigin, Host, DomainsValidation};
|
||||||
|
|
||||||
/// Request/response handler
|
/// Request/response handler
|
||||||
pub struct IpfsHandler {
|
pub struct IpfsHandler {
|
||||||
@ -47,12 +46,12 @@ pub struct IpfsHandler {
|
|||||||
out: Out,
|
out: Out,
|
||||||
/// How many bytes from the response have been written
|
/// How many bytes from the response have been written
|
||||||
out_progress: usize,
|
out_progress: usize,
|
||||||
/// Origin request header
|
/// CORS response header
|
||||||
origin: Option<String>,
|
cors_header: Option<header::AccessControlAllowOrigin>,
|
||||||
/// Allowed CORS domains
|
/// Allowed CORS domains
|
||||||
cors_domains: Option<Vec<AccessControlAllowOrigin>>,
|
cors_domains: Option<Vec<AccessControlAllowOrigin>>,
|
||||||
/// Hostnames allowed in the `Host` request header
|
/// Hostnames allowed in the `Host` request header
|
||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<Host>>,
|
||||||
/// Reference to the Blockchain Client
|
/// Reference to the Blockchain Client
|
||||||
client: Arc<BlockChainClient>,
|
client: Arc<BlockChainClient>,
|
||||||
}
|
}
|
||||||
@ -62,50 +61,16 @@ impl IpfsHandler {
|
|||||||
&*self.client
|
&*self.client
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(cors: Option<Vec<String>>, hosts: Option<Vec<String>>, client: Arc<BlockChainClient>) -> Self {
|
pub fn new(cors: DomainsValidation<AccessControlAllowOrigin>, hosts: DomainsValidation<Host>, client: Arc<BlockChainClient>) -> Self {
|
||||||
fn origin_to_header(origin: String) -> AccessControlAllowOrigin {
|
|
||||||
match origin.as_str() {
|
|
||||||
"*" => AccessControlAllowOrigin::Any,
|
|
||||||
"null" | "" => AccessControlAllowOrigin::Null,
|
|
||||||
_ => AccessControlAllowOrigin::Value(origin),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IpfsHandler {
|
IpfsHandler {
|
||||||
out: Out::Bad("Invalid Request"),
|
out: Out::Bad("Invalid Request"),
|
||||||
out_progress: 0,
|
out_progress: 0,
|
||||||
origin: None,
|
cors_header: None,
|
||||||
cors_domains: cors.map(|vec| vec.into_iter().map(origin_to_header).collect()),
|
cors_domains: cors.into(),
|
||||||
allowed_hosts: hosts,
|
allowed_hosts: hosts.into(),
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_host_allowed(&self, req: &Request<HttpStream>) -> bool {
|
|
||||||
match self.allowed_hosts {
|
|
||||||
Some(ref hosts) => jsonrpc_http_server::is_host_header_valid(&req, hosts),
|
|
||||||
None => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_origin_allowed(&self) -> bool {
|
|
||||||
// Check origin header first, no header passed is good news
|
|
||||||
let origin = match self.origin {
|
|
||||||
Some(ref origin) => origin,
|
|
||||||
None => return true,
|
|
||||||
};
|
|
||||||
|
|
||||||
let cors_domains = match self.cors_domains {
|
|
||||||
Some(ref domains) => domains,
|
|
||||||
None => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
cors_domains.iter().any(|domain| match *domain {
|
|
||||||
AccessControlAllowOrigin::Value(ref allowed) => origin == allowed,
|
|
||||||
AccessControlAllowOrigin::Any => true,
|
|
||||||
AccessControlAllowOrigin::Null => origin == "",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement Hyper's HTTP handler
|
/// Implement Hyper's HTTP handler
|
||||||
@ -115,19 +80,20 @@ impl Handler<HttpStream> for IpfsHandler {
|
|||||||
return Next::write();
|
return Next::write();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.origin = cors::read_origin(&req);
|
|
||||||
|
|
||||||
if !self.is_host_allowed(&req) {
|
if !http::is_host_allowed(&req, &self.allowed_hosts) {
|
||||||
self.out = Out::Bad("Disallowed Host header");
|
self.out = Out::Bad("Disallowed Host header");
|
||||||
|
|
||||||
return Next::write();
|
return Next::write();
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.is_origin_allowed() {
|
let cors_header = http::cors_header(&req, &self.cors_domains);
|
||||||
|
if cors_header == http::CorsHeader::Invalid {
|
||||||
self.out = Out::Bad("Disallowed Origin header");
|
self.out = Out::Bad("Disallowed Origin header");
|
||||||
|
|
||||||
return Next::write();
|
return Next::write();
|
||||||
}
|
}
|
||||||
|
self.cors_header = cors_header.into();
|
||||||
|
|
||||||
let (path, query) = match *req.uri() {
|
let (path, query) = match *req.uri() {
|
||||||
RequestUri::AbsolutePath { ref path, ref query } => (path, query.as_ref().map(AsRef::as_ref)),
|
RequestUri::AbsolutePath { ref path, ref query } => (path, query.as_ref().map(AsRef::as_ref)),
|
||||||
@ -176,7 +142,7 @@ impl Handler<HttpStream> for IpfsHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cors_header) = cors::get_cors_header(&self.cors_domains, &self.origin) {
|
if let Some(cors_header) = self.cors_header.take() {
|
||||||
res.headers_mut().set(cors_header);
|
res.headers_mut().set(cors_header);
|
||||||
res.headers_mut().set(Vary::Items(vec!["Origin".into()]));
|
res.headers_mut().set(Vary::Items(vec!["Origin".into()]));
|
||||||
}
|
}
|
||||||
@ -219,11 +185,11 @@ fn write_chunk<W: Write>(transport: &mut W, progress: &mut usize, data: &[u8]) -
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add current interface (default: "127.0.0.1:5001") to list of allowed hosts
|
/// Add current interface (default: "127.0.0.1:5001") to list of allowed hosts
|
||||||
fn include_current_interface(mut hosts: Vec<String>, interface: String, port: u16) -> Vec<String> {
|
fn include_current_interface(mut hosts: Vec<Host>, interface: String, port: u16) -> Vec<Host> {
|
||||||
hosts.push(match port {
|
hosts.push(match port {
|
||||||
80 => interface,
|
80 => interface,
|
||||||
_ => format!("{}:{}", interface, port),
|
_ => format!("{}:{}", interface, port),
|
||||||
});
|
}.into());
|
||||||
|
|
||||||
hosts
|
hosts
|
||||||
}
|
}
|
||||||
@ -231,17 +197,18 @@ fn include_current_interface(mut hosts: Vec<String>, interface: String, port: u1
|
|||||||
pub fn start_server(
|
pub fn start_server(
|
||||||
port: u16,
|
port: u16,
|
||||||
interface: String,
|
interface: String,
|
||||||
cors: Option<Vec<String>>,
|
cors: DomainsValidation<AccessControlAllowOrigin>,
|
||||||
hosts: Option<Vec<String>>,
|
hosts: DomainsValidation<Host>,
|
||||||
client: Arc<BlockChainClient>
|
client: Arc<BlockChainClient>
|
||||||
) -> Result<Listening, ServerError> {
|
) -> Result<Listening, ServerError> {
|
||||||
|
|
||||||
let ip: IpAddr = interface.parse().map_err(|_| ServerError::InvalidInterface)?;
|
let ip: IpAddr = interface.parse().map_err(|_| ServerError::InvalidInterface)?;
|
||||||
let addr = SocketAddr::new(ip, port);
|
let addr = SocketAddr::new(ip, port);
|
||||||
let hosts = hosts.map(move |hosts| include_current_interface(hosts, interface, port));
|
let hosts: Option<Vec<_>> = hosts.into();
|
||||||
|
let hosts: DomainsValidation<_> = hosts.map(move |hosts| include_current_interface(hosts, interface, port)).into();
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
hyper::Server::http(&addr)?
|
http::hyper::Server::http(&addr)?
|
||||||
.handle(move |_| IpfsHandler::new(cors.clone(), hosts.clone(), client.clone()))
|
.handle(move |_| IpfsHandler::new(cors.clone(), hosts.clone(), client.clone()))
|
||||||
.map(|(listening, srv)| {
|
.map(|(listening, srv)| {
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parity.js",
|
"name": "parity.js",
|
||||||
"version": "1.7.19",
|
"version": "1.7.22",
|
||||||
"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>",
|
||||||
|
@ -23,6 +23,7 @@ import CircularProgress from 'material-ui/CircularProgress';
|
|||||||
import { Card, CardText } from 'material-ui/Card';
|
import { Card, CardText } from 'material-ui/Card';
|
||||||
|
|
||||||
import { nullableProptype } from '~/util/proptypes';
|
import { nullableProptype } from '~/util/proptypes';
|
||||||
|
import { api } from '../parity';
|
||||||
|
|
||||||
import styles from './application.css';
|
import styles from './application.css';
|
||||||
import Accounts from '../Accounts';
|
import Accounts from '../Accounts';
|
||||||
@ -39,7 +40,7 @@ export default class Application extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getChildContext () {
|
getChildContext () {
|
||||||
return { muiTheme, api: window.parity.api };
|
return { muiTheme, api };
|
||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -49,7 +50,6 @@ export default class Application extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { api } = window.parity;
|
|
||||||
const { contract, fee } = this.props;
|
const { contract, fee } = this.props;
|
||||||
let warning = null;
|
let warning = null;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
const { api } = window.parity;
|
import { api } from '../parity';
|
||||||
|
|
||||||
export const SET_ACCOUNTS = 'SET_ACCOUNTS';
|
export const SET_ACCOUNTS = 'SET_ACCOUNTS';
|
||||||
export const setAccounts = (accounts) => ({
|
export const setAccounts = (accounts) => ({
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
import Contracts from '~/contracts';
|
import Contracts from '~/contracts';
|
||||||
|
|
||||||
import { loadToken, setTokenPending, deleteToken, setTokenData } from '../Tokens/actions';
|
import { loadToken, setTokenPending, deleteToken, setTokenData } from '../Tokens/actions';
|
||||||
|
import { api } from '../parity';
|
||||||
const { api } = window.parity;
|
|
||||||
|
|
||||||
export const SET_LOADING = 'SET_LOADING';
|
export const SET_LOADING = 'SET_LOADING';
|
||||||
export const setLoading = (isLoading) => ({
|
export const setLoading = (isLoading) => ({
|
||||||
|
@ -16,12 +16,11 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import { api } from '../parity';
|
||||||
import Chip from '../Chip';
|
import Chip from '../Chip';
|
||||||
|
|
||||||
import styles from './status.css';
|
import styles from './status.css';
|
||||||
|
|
||||||
const { api } = window.parity;
|
|
||||||
|
|
||||||
export default class Status extends Component {
|
export default class Status extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
address: PropTypes.string.isRequired,
|
address: PropTypes.string.isRequired,
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
import { URL_TYPE } from '../Inputs/validation';
|
import { URL_TYPE } from '../Inputs/validation';
|
||||||
import { getTokenTotalSupply, urlToHash } from '../utils';
|
import { getTokenTotalSupply, urlToHash } from '../utils';
|
||||||
|
import { api } from '../parity';
|
||||||
|
|
||||||
const { bytesToHex } = window.parity.api.util;
|
const { bytesToHex } = api.util;
|
||||||
|
|
||||||
export const SET_TOKENS_LOADING = 'SET_TOKENS_LOADING';
|
export const SET_TOKENS_LOADING = 'SET_TOKENS_LOADING';
|
||||||
export const setTokensLoading = (isLoading) => ({
|
export const setTokensLoading = (isLoading) => ({
|
||||||
|
@ -77,7 +77,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form {
|
.form {
|
||||||
|
box-sizing: border-box;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
padding: 0.75rem 1.5rem 1.5rem 1.5rem;
|
padding: 0.75rem 1.5rem 1.5rem;
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ export default class SecureApi extends Api {
|
|||||||
this.transport.updateToken(token, false);
|
this.transport.updateToken(token, false);
|
||||||
log.debug('connecting with token', token);
|
log.debug('connecting with token', token);
|
||||||
|
|
||||||
return this.transport.connect()
|
const connectPromise = this.transport.connect()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
log.debug('connected with', token);
|
log.debug('connected with', token);
|
||||||
|
|
||||||
@ -258,26 +258,35 @@ export default class SecureApi extends Api {
|
|||||||
log.debug('did not connect ; error', error);
|
log.debug('did not connect ; error', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the Node is up
|
return false;
|
||||||
return this.isNodeUp()
|
});
|
||||||
.then((isNodeUp) => {
|
|
||||||
// If it's not up, try again in a few...
|
|
||||||
if (!isNodeUp) {
|
|
||||||
const timeout = this.transport.retryTimeout;
|
|
||||||
|
|
||||||
log.debug('node is not up ; will try again in', timeout, 'ms');
|
return Promise
|
||||||
|
.all([
|
||||||
|
connectPromise,
|
||||||
|
this.isNodeUp()
|
||||||
|
])
|
||||||
|
.then(([ connected, isNodeUp ]) => {
|
||||||
|
if (connected) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
// If it's not up, try again in a few...
|
||||||
window.setTimeout(() => {
|
if (!isNodeUp) {
|
||||||
this._connectWithToken(token).then(resolve).catch(reject);
|
const timeout = this.transport.retryTimeout;
|
||||||
}, timeout);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// The token is invalid
|
log.debug('node is not up ; will try again in', timeout, 'ms');
|
||||||
log.debug('tried with a wrong token', token);
|
|
||||||
return false;
|
return new Promise((resolve, reject) => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
this._connectWithToken(token).then(resolve).catch(reject);
|
||||||
|
}, timeout);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// The token is invalid
|
||||||
|
log.debug('tried with a wrong token', token);
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,6 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container > * {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
color: rgba(255, 255, 255, 0.498039);
|
color: rgba(255, 255, 255, 0.498039);
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
top: 11px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import AddIcon from 'material-ui/svg-icons/content/add';
|
|||||||
import RemoveIcon from 'material-ui/svg-icons/content/remove';
|
import RemoveIcon from 'material-ui/svg-icons/content/remove';
|
||||||
|
|
||||||
import { fromWei, toWei } from '~/api/util/wei';
|
import { fromWei, toWei } from '~/api/util/wei';
|
||||||
|
import { bytesToHex } from '~/api/util/format';
|
||||||
import Input from '~/ui/Form/Input';
|
import Input from '~/ui/Form/Input';
|
||||||
import InputAddressSelect from '~/ui/Form/InputAddressSelect';
|
import InputAddressSelect from '~/ui/Form/InputAddressSelect';
|
||||||
import Select from '~/ui/Form/Select';
|
import Select from '~/ui/Form/Select';
|
||||||
@ -68,7 +69,8 @@ export default class TypedInput extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
const { isEth, value } = this.props;
|
const { isEth } = this.props;
|
||||||
|
const value = this.getValue();
|
||||||
|
|
||||||
if (typeof isEth === 'boolean' && value) {
|
if (typeof isEth === 'boolean' && value) {
|
||||||
// Remove formatting commas
|
// Remove formatting commas
|
||||||
@ -95,14 +97,15 @@ export default class TypedInput extends Component {
|
|||||||
const { type } = param;
|
const { type } = param;
|
||||||
|
|
||||||
if (type === ABI_TYPES.ARRAY) {
|
if (type === ABI_TYPES.ARRAY) {
|
||||||
const { accounts, className, label, value = param.default } = this.props;
|
const { accounts, className, label } = this.props;
|
||||||
const { subtype, length } = param;
|
const { subtype, length } = param;
|
||||||
|
const value = this.getValue() || param.default;
|
||||||
|
|
||||||
const fixedLength = !!length;
|
const fixedLength = !!length;
|
||||||
|
|
||||||
const inputs = range(length || value.length).map((_, index) => {
|
const inputs = range(length || value.length).map((_, index) => {
|
||||||
const onChange = (inputValue) => {
|
const onChange = (inputValue) => {
|
||||||
const newValues = [].concat(this.props.value);
|
const newValues = [].concat(value);
|
||||||
|
|
||||||
newValues[index] = inputValue;
|
newValues[index] = inputValue;
|
||||||
this.props.onChange(newValues);
|
this.props.onChange(newValues);
|
||||||
@ -191,7 +194,14 @@ export default class TypedInput extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === ABI_TYPES.BYTES) {
|
if (type === ABI_TYPES.BYTES) {
|
||||||
return this.renderDefault();
|
let value = this.getValue();
|
||||||
|
|
||||||
|
// Convert to hex if it's an array
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value = bytesToHex(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.renderDefault(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the `isEth` prop is present (true or false)
|
// If the `isEth` prop is present (true or false)
|
||||||
@ -260,7 +270,7 @@ export default class TypedInput extends Component {
|
|||||||
: bnValue.toFixed(); // we need a string representation, could be >15 digits
|
: bnValue.toFixed(); // we need a string representation, could be >15 digits
|
||||||
}
|
}
|
||||||
|
|
||||||
renderInteger (value = this.props.value, onChange = this.onChange) {
|
renderInteger (value = this.getValue(), onChange = this.onChange) {
|
||||||
const { allowCopy, className, label, error, hint, min, max, readOnly } = this.props;
|
const { allowCopy, className, label, error, hint, min, max, readOnly } = this.props;
|
||||||
const param = this.getParam();
|
const param = this.getParam();
|
||||||
|
|
||||||
@ -268,7 +278,7 @@ export default class TypedInput extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
allowCopy={ allowCopy }
|
allowCopy={ allowCopy ? value : undefined }
|
||||||
className={ className }
|
className={ className }
|
||||||
label={ label }
|
label={ label }
|
||||||
hint={ hint }
|
hint={ hint }
|
||||||
@ -291,7 +301,7 @@ export default class TypedInput extends Component {
|
|||||||
*
|
*
|
||||||
* @see https://github.com/facebook/react/issues/1549
|
* @see https://github.com/facebook/react/issues/1549
|
||||||
*/
|
*/
|
||||||
renderFloat (value = this.props.value, onChange = this.onChange) {
|
renderFloat (value = this.getValue(), onChange = this.onChange) {
|
||||||
const { allowCopy, className, label, error, hint, min, max, readOnly } = this.props;
|
const { allowCopy, className, label, error, hint, min, max, readOnly } = this.props;
|
||||||
const param = this.getParam();
|
const param = this.getParam();
|
||||||
|
|
||||||
@ -299,7 +309,7 @@ export default class TypedInput extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
allowCopy={ allowCopy }
|
allowCopy={ allowCopy ? value : undefined }
|
||||||
className={ className }
|
className={ className }
|
||||||
label={ label }
|
label={ label }
|
||||||
hint={ hint }
|
hint={ hint }
|
||||||
@ -314,8 +324,8 @@ export default class TypedInput extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDefault () {
|
renderDefault (value = this.getValue()) {
|
||||||
const { allowCopy, className, label, value, error, hint, readOnly } = this.props;
|
const { allowCopy, className, label, error, hint, readOnly } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
@ -332,7 +342,8 @@ export default class TypedInput extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderAddress () {
|
renderAddress () {
|
||||||
const { accounts, allowCopy, className, label, value, error, hint, readOnly } = this.props;
|
const { accounts, allowCopy, className, label, error, hint, readOnly } = this.props;
|
||||||
|
const value = this.getValue();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InputAddressSelect
|
<InputAddressSelect
|
||||||
@ -350,7 +361,8 @@ export default class TypedInput extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderBoolean () {
|
renderBoolean () {
|
||||||
const { allowCopy, className, label, value, error, hint, readOnly } = this.props;
|
const { allowCopy, className, label, error, hint, readOnly } = this.props;
|
||||||
|
const value = this.getValue();
|
||||||
|
|
||||||
if (readOnly) {
|
if (readOnly) {
|
||||||
return this.renderDefault();
|
return this.renderDefault();
|
||||||
@ -441,7 +453,7 @@ export default class TypedInput extends Component {
|
|||||||
onChange(newValues);
|
onChange(newValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
getParam = () => {
|
getParam () {
|
||||||
const { param } = this.props;
|
const { param } = this.props;
|
||||||
|
|
||||||
if (typeof param === 'string') {
|
if (typeof param === 'string') {
|
||||||
@ -450,4 +462,15 @@ export default class TypedInput extends Component {
|
|||||||
|
|
||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the value comes from `decodeMethodInput`,
|
||||||
|
* it can be an object of the shape:
|
||||||
|
* { value: Object, type: String }
|
||||||
|
*/
|
||||||
|
getValue (value = this.props.value) {
|
||||||
|
return value && value.value
|
||||||
|
? value.value
|
||||||
|
: value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,7 @@ class MethodDecoding extends Component {
|
|||||||
key={ index }
|
key={ index }
|
||||||
param={ input.type }
|
param={ input.type }
|
||||||
readOnly
|
readOnly
|
||||||
value={ this.renderValue(input.value) }
|
value={ input.value }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -568,16 +568,6 @@ class MethodDecoding extends Component {
|
|||||||
return inputs;
|
return inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValue (value) {
|
|
||||||
const { api } = this.context;
|
|
||||||
|
|
||||||
if (api.util.isArray(value)) {
|
|
||||||
return api.util.bytesToHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderTokenValue (value) {
|
renderTokenValue (value) {
|
||||||
const { token } = this.props;
|
const { token } = this.props;
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ export function parseAbiType (type) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'bytes') {
|
if (type === 'bytes' || type === 'fixedBytes') {
|
||||||
return {
|
return {
|
||||||
type: BYTES_TYPE,
|
type: BYTES_TYPE,
|
||||||
default: '0x'
|
default: '0x'
|
||||||
|
@ -19,7 +19,7 @@ import moment from 'moment';
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { IdentityIcon, IdentityName, Input, InputAddress } from '~/ui';
|
import { IdentityIcon, IdentityName, TypedInput } from '~/ui';
|
||||||
import ShortenedHash from '~/ui/ShortenedHash';
|
import ShortenedHash from '~/ui/ShortenedHash';
|
||||||
import { txLink } from '~/3rdparty/etherscan/links';
|
import { txLink } from '~/3rdparty/etherscan/links';
|
||||||
|
|
||||||
@ -112,41 +112,16 @@ export default class Event extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderParam (name, param) {
|
renderParam (name, param) {
|
||||||
const { api } = this.context;
|
return (
|
||||||
|
<TypedInput
|
||||||
switch (param.type) {
|
allowCopy
|
||||||
case 'address':
|
className={ styles.input }
|
||||||
return (
|
label={ name }
|
||||||
<InputAddress
|
param={ param.type }
|
||||||
disabled
|
readOnly
|
||||||
text
|
value={ param.value }
|
||||||
className={ styles.input }
|
/>
|
||||||
value={ param.value }
|
);
|
||||||
label={ name }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
default:
|
|
||||||
let value;
|
|
||||||
|
|
||||||
if (api.util.isInstanceOf(param.value, BigNumber)) {
|
|
||||||
value = param.value.toFormat(0);
|
|
||||||
} else if (api.util.isArray(param.value)) {
|
|
||||||
value = api.util.bytesToHex(param.value);
|
|
||||||
} else {
|
|
||||||
value = param.value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Input
|
|
||||||
readOnly
|
|
||||||
allowCopy
|
|
||||||
className={ styles.input }
|
|
||||||
value={ value }
|
|
||||||
label={ name }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
formatBlockTimestamp (block) {
|
formatBlockTimestamp (block) {
|
||||||
|
@ -46,6 +46,12 @@ export default class Events extends Component {
|
|||||||
events: []
|
events: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
shouldComponentUpdate (nextProps) {
|
||||||
|
return (nextProps.events !== this.props.events) ||
|
||||||
|
(nextProps.netVersion !== this.props.netVersion) ||
|
||||||
|
(nextProps.isLoading !== this.props.isLoading);
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { events, isLoading, netVersion } = this.props;
|
const { events, isLoading, netVersion } = this.props;
|
||||||
|
|
||||||
|
@ -138,10 +138,8 @@ class InputQuery extends Component {
|
|||||||
.map((out, index) => ({
|
.map((out, index) => ({
|
||||||
name: out.name,
|
name: out.name,
|
||||||
type: out.type,
|
type: out.type,
|
||||||
value: results[index],
|
value: results[index]
|
||||||
display: this.renderValue(results[index])
|
|
||||||
}))
|
}))
|
||||||
.sort((outA, outB) => outA.display.length - outB.display.length)
|
|
||||||
.map((out, index) => {
|
.map((out, index) => {
|
||||||
const input = (
|
const input = (
|
||||||
<TypedInput
|
<TypedInput
|
||||||
@ -150,7 +148,7 @@ class InputQuery extends Component {
|
|||||||
isEth={ false }
|
isEth={ false }
|
||||||
param={ out.type }
|
param={ out.type }
|
||||||
readOnly
|
readOnly
|
||||||
value={ out.display }
|
value={ out.value }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -195,25 +193,6 @@ class InputQuery extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValue (token) {
|
|
||||||
const { api } = this.context;
|
|
||||||
const { type, value } = token;
|
|
||||||
|
|
||||||
if (value === null || value === undefined) {
|
|
||||||
return 'no data';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'array' || type === 'fixedArray') {
|
|
||||||
return value.map((tok) => this.renderValue(tok));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
return api.util.bytesToHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
onClick = () => {
|
onClick = () => {
|
||||||
const { inputs, values } = this.state;
|
const { inputs, values } = this.state;
|
||||||
const { contract, name, outputs, signature } = this.props;
|
const { contract, name, outputs, signature } = this.props;
|
||||||
|
@ -139,15 +139,14 @@ export default class Queries extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValue (tokenValue, output, key) {
|
renderValue (value, output, key) {
|
||||||
if (typeof tokenValue === 'undefined') {
|
if (typeof value === 'undefined') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { accountsInfo } = this.props;
|
const { accountsInfo } = this.props;
|
||||||
const { name, type } = output;
|
const { name, type } = output;
|
||||||
const label = `${name ? `${name}: ` : ''}${type}`;
|
const label = `${name ? `${name}: ` : ''}${type}`;
|
||||||
const value = this.getTokenValue(tokenValue);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TypedInput
|
<TypedInput
|
||||||
@ -163,25 +162,6 @@ export default class Queries extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTokenValue (token) {
|
|
||||||
const { api } = this.context;
|
|
||||||
const { type, value } = token;
|
|
||||||
|
|
||||||
if (value === null || value === undefined) {
|
|
||||||
return 'no data';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'array' || type === 'fixedArray') {
|
|
||||||
return value.map((tok) => this.getTokenValue(tok));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
return api.util.bytesToHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
_sortEntries (a, b) {
|
_sortEntries (a, b) {
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import styles from './transactionPendingFormConfirm.css';
|
|||||||
|
|
||||||
export default class TransactionPendingFormConfirm extends Component {
|
export default class TransactionPendingFormConfirm extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
account: PropTypes.object.isRequired,
|
account: PropTypes.object,
|
||||||
address: PropTypes.string.isRequired,
|
address: PropTypes.string.isRequired,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
isSending: PropTypes.bool.isRequired,
|
isSending: PropTypes.bool.isRequired,
|
||||||
@ -36,6 +36,7 @@ export default class TransactionPendingFormConfirm extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
account: {},
|
||||||
focus: false
|
focus: false
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ export default class TransactionPendingFormConfirm extends Component {
|
|||||||
|
|
||||||
getPasswordHint () {
|
getPasswordHint () {
|
||||||
const { account } = this.props;
|
const { account } = this.props;
|
||||||
const accountHint = account && account.meta && account.meta.passwordHint;
|
const accountHint = account.meta && account.meta.passwordHint;
|
||||||
|
|
||||||
if (accountHint) {
|
if (accountHint) {
|
||||||
return accountHint;
|
return accountHint;
|
||||||
@ -149,14 +150,16 @@ export default class TransactionPendingFormConfirm extends Component {
|
|||||||
const { account } = this.props;
|
const { account } = this.props;
|
||||||
const { password } = this.state;
|
const { password } = this.state;
|
||||||
|
|
||||||
if (account && account.hardware) {
|
if (account.hardware) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isAccount = account.uuid;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
hint={
|
hint={
|
||||||
account.uuid
|
isAccount
|
||||||
? (
|
? (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='signer.txPendingConfirm.password.unlock.hint'
|
id='signer.txPendingConfirm.password.unlock.hint'
|
||||||
@ -171,7 +174,7 @@ export default class TransactionPendingFormConfirm extends Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
label={
|
label={
|
||||||
account.uuid
|
isAccount
|
||||||
? (
|
? (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='signer.txPendingConfirm.password.unlock.label'
|
id='signer.txPendingConfirm.password.unlock.label'
|
||||||
|
@ -48,7 +48,7 @@ function render (address) {
|
|||||||
|
|
||||||
component = shallow(
|
component = shallow(
|
||||||
<TransactionPendingFormConfirm
|
<TransactionPendingFormConfirm
|
||||||
account={ ACCOUNTS[address] || {} }
|
account={ ACCOUNTS[address] }
|
||||||
address={ address }
|
address={ address }
|
||||||
onConfirm={ onConfirm }
|
onConfirm={ onConfirm }
|
||||||
isSending={ false }
|
isSending={ false }
|
||||||
@ -130,5 +130,9 @@ describe('views/Signer/TransactionPendingFormConfirm', () => {
|
|||||||
it('renders the password', () => {
|
it('renders the password', () => {
|
||||||
expect(instance.renderPassword()).not.to.be.null;
|
expect(instance.renderPassword()).not.to.be.null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders the hint', () => {
|
||||||
|
expect(instance.renderHint()).to.be.null;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -578,6 +578,10 @@ class WriteContract extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderContract (contract) {
|
renderContract (contract) {
|
||||||
|
if (!contract) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { bytecode } = contract;
|
const { bytecode } = contract;
|
||||||
const abi = contract.interface;
|
const abi = contract.interface;
|
||||||
|
|
||||||
|
@ -59,11 +59,11 @@ macro_rules! impl_hash {
|
|||||||
let value = match value.len() {
|
let value = match value.len() {
|
||||||
0 => $inner::from(0),
|
0 => $inner::from(0),
|
||||||
2 if value == "0x" => $inner::from(0),
|
2 if value == "0x" => $inner::from(0),
|
||||||
_ if value.starts_with("0x") => $inner::from_str(&value[2..]).map_err(|_| {
|
_ if value.starts_with("0x") => $inner::from_str(&value[2..]).map_err(|e| {
|
||||||
Error::custom(format!("Invalid hex value {}.", value).as_str())
|
Error::custom(format!("Invalid hex value {}: {}", value, e).as_str())
|
||||||
})?,
|
})?,
|
||||||
_ => $inner::from_str(value).map_err(|_| {
|
_ => $inner::from_str(value).map_err(|e| {
|
||||||
Error::custom(format!("Invalid hex value {}.", value).as_str())
|
Error::custom(format!("Invalid hex value {}: {}", value, e).as_str())
|
||||||
})?,
|
})?,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
//! Spec builtin deserialization.
|
//! Spec builtin deserialization.
|
||||||
|
|
||||||
|
use uint::Uint;
|
||||||
|
|
||||||
/// Linear pricing.
|
/// Linear pricing.
|
||||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||||
pub struct Linear {
|
pub struct Linear {
|
||||||
@ -25,12 +27,22 @@ pub struct Linear {
|
|||||||
pub word: usize,
|
pub word: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pricing for modular exponentiation.
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||||
|
pub struct Modexp {
|
||||||
|
/// Price divisor.
|
||||||
|
pub divisor: usize,
|
||||||
|
}
|
||||||
|
|
||||||
/// Pricing variants.
|
/// Pricing variants.
|
||||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||||
pub enum Pricing {
|
pub enum Pricing {
|
||||||
/// Linear pricing.
|
/// Linear pricing.
|
||||||
#[serde(rename="linear")]
|
#[serde(rename="linear")]
|
||||||
Linear(Linear),
|
Linear(Linear),
|
||||||
|
/// Pricing for modular exponentiation.
|
||||||
|
#[serde(rename="modexp")]
|
||||||
|
Modexp(Modexp),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spec builtin.
|
/// Spec builtin.
|
||||||
@ -40,12 +52,15 @@ pub struct Builtin {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
/// Builtin pricing.
|
/// Builtin pricing.
|
||||||
pub pricing: Pricing,
|
pub pricing: Pricing,
|
||||||
|
/// Activation block.
|
||||||
|
pub activate_at: Option<Uint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use spec::builtin::{Builtin, Pricing, Linear};
|
use spec::builtin::{Builtin, Pricing, Linear, Modexp};
|
||||||
|
use uint::Uint;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn builtin_deserialization() {
|
fn builtin_deserialization() {
|
||||||
@ -56,5 +71,20 @@ mod tests {
|
|||||||
let deserialized: Builtin = serde_json::from_str(s).unwrap();
|
let deserialized: Builtin = serde_json::from_str(s).unwrap();
|
||||||
assert_eq!(deserialized.name, "ecrecover");
|
assert_eq!(deserialized.name, "ecrecover");
|
||||||
assert_eq!(deserialized.pricing, Pricing::Linear(Linear { base: 3000, word: 0 }));
|
assert_eq!(deserialized.pricing, Pricing::Linear(Linear { base: 3000, word: 0 }));
|
||||||
|
assert!(deserialized.activate_at.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn activate_at() {
|
||||||
|
let s = r#"{
|
||||||
|
"name": "late_start",
|
||||||
|
"activate_at": 100000,
|
||||||
|
"pricing": { "modexp": { "divisor": 5 } }
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let deserialized: Builtin = serde_json::from_str(s).unwrap();
|
||||||
|
assert_eq!(deserialized.name, "late_start");
|
||||||
|
assert_eq!(deserialized.pricing, Pricing::Modexp(Modexp { divisor: 5 }));
|
||||||
|
assert_eq!(deserialized.activate_at, Some(Uint(100000.into())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ impl Visitor for UintVisitor {
|
|||||||
type Value = Uint;
|
type Value = Uint;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "a hex encoded uint")
|
write!(formatter, "a hex encoded or decimal uint")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: Error {
|
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: Error {
|
||||||
@ -74,11 +74,11 @@ impl Visitor for UintVisitor {
|
|||||||
let value = match value.len() {
|
let value = match value.len() {
|
||||||
0 => U256::from(0),
|
0 => U256::from(0),
|
||||||
2 if value.starts_with("0x") => U256::from(0),
|
2 if value.starts_with("0x") => U256::from(0),
|
||||||
_ if value.starts_with("0x") => U256::from_str(&value[2..]).map_err(|_| {
|
_ if value.starts_with("0x") => U256::from_str(&value[2..]).map_err(|e| {
|
||||||
Error::custom(format!("Invalid hex value {}.", value).as_str())
|
Error::custom(format!("Invalid hex value {}: {}", value, e).as_str())
|
||||||
})?,
|
})?,
|
||||||
_ => U256::from_dec_str(value).map_err(|_| {
|
_ => U256::from_dec_str(value).map_err(|e| {
|
||||||
Error::custom(format!("Invalid decimal value {}.", value).as_str())
|
Error::custom(format!("Invalid decimal value {}: {:?}", value, e).as_str())
|
||||||
})?
|
})?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,9 +23,8 @@ use ethcore_rpc::informant::RpcStats;
|
|||||||
use ethsync::SyncProvider;
|
use ethsync::SyncProvider;
|
||||||
use hash_fetch::fetch::Client as FetchClient;
|
use hash_fetch::fetch::Client as FetchClient;
|
||||||
use helpers::replace_home;
|
use helpers::replace_home;
|
||||||
use io::PanicHandler;
|
|
||||||
use jsonrpc_core::reactor::Remote;
|
|
||||||
use rpc_apis::{self, SignerService};
|
use rpc_apis::{self, SignerService};
|
||||||
|
use parity_reactor;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
@ -60,11 +59,10 @@ impl Default for Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Dependencies {
|
pub struct Dependencies {
|
||||||
pub panic_handler: Arc<PanicHandler>,
|
|
||||||
pub apis: Arc<rpc_apis::Dependencies>,
|
pub apis: Arc<rpc_apis::Dependencies>,
|
||||||
pub client: Arc<Client>,
|
pub client: Arc<Client>,
|
||||||
pub sync: Arc<SyncProvider>,
|
pub sync: Arc<SyncProvider>,
|
||||||
pub remote: Remote,
|
pub remote: parity_reactor::TokioRemote,
|
||||||
pub fetch: FetchClient,
|
pub fetch: FetchClient,
|
||||||
pub signer: Arc<SignerService>,
|
pub signer: Arc<SignerService>,
|
||||||
pub stats: Arc<RpcStats>,
|
pub stats: Arc<RpcStats>,
|
||||||
@ -137,9 +135,9 @@ mod server {
|
|||||||
use ansi_term::Colour;
|
use ansi_term::Colour;
|
||||||
use ethcore::transaction::{Transaction, Action};
|
use ethcore::transaction::{Transaction, Action};
|
||||||
use ethcore::client::{Client, BlockChainClient, BlockId};
|
use ethcore::client::{Client, BlockChainClient, BlockId};
|
||||||
|
use ethcore_dapps::{AccessControlAllowOrigin, Host};
|
||||||
use ethcore_rpc::is_major_importing;
|
use ethcore_rpc::is_major_importing;
|
||||||
use hash_fetch::urlhint::ContractClient;
|
use hash_fetch::urlhint::ContractClient;
|
||||||
use jsonrpc_core::reactor::RpcHandler;
|
|
||||||
use parity_reactor;
|
use parity_reactor;
|
||||||
use rpc_apis;
|
use rpc_apis;
|
||||||
|
|
||||||
@ -162,6 +160,8 @@ mod server {
|
|||||||
Arc::new(Registrar { client: deps.client.clone() }),
|
Arc::new(Registrar { client: deps.client.clone() }),
|
||||||
parity_reactor::Remote::new(deps.remote.clone()),
|
parity_reactor::Remote::new(deps.remote.clone()),
|
||||||
);
|
);
|
||||||
|
let allowed_hosts: Option<Vec<_>> = allowed_hosts.map(|hosts| hosts.into_iter().map(Host::from).collect());
|
||||||
|
let cors: Option<Vec<_>> = cors.map(|cors| cors.into_iter().map(AccessControlAllowOrigin::from).collect());
|
||||||
|
|
||||||
let sync = deps.sync.clone();
|
let sync = deps.sync.clone();
|
||||||
let client = deps.client.clone();
|
let client = deps.client.clone();
|
||||||
@ -172,8 +172,8 @@ mod server {
|
|||||||
.web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token)))
|
.web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token)))
|
||||||
.extra_dapps(&extra_dapps)
|
.extra_dapps(&extra_dapps)
|
||||||
.signer_address(deps.signer.address())
|
.signer_address(deps.signer.address())
|
||||||
.allowed_hosts(allowed_hosts)
|
.allowed_hosts(allowed_hosts.into())
|
||||||
.extra_cors_headers(cors);
|
.extra_cors_headers(cors.into());
|
||||||
|
|
||||||
let api_set = if all_apis {
|
let api_set = if all_apis {
|
||||||
warn!("{}", Colour::Red.bold().paint("*** INSECURE *** Running Dapps with all APIs exposed."));
|
warn!("{}", Colour::Red.bold().paint("*** INSECURE *** Running Dapps with all APIs exposed."));
|
||||||
@ -183,13 +183,12 @@ mod server {
|
|||||||
rpc_apis::ApiSet::UnsafeContext
|
rpc_apis::ApiSet::UnsafeContext
|
||||||
};
|
};
|
||||||
let apis = rpc_apis::setup_rpc(deps.stats, deps.apis.clone(), api_set);
|
let apis = rpc_apis::setup_rpc(deps.stats, deps.apis.clone(), api_set);
|
||||||
let handler = RpcHandler::new(Arc::new(apis), deps.remote);
|
|
||||||
let start_result = match auth {
|
let start_result = match auth {
|
||||||
None => {
|
None => {
|
||||||
server.start_unsecured_http(url, handler)
|
server.start_unsecured_http(url, apis, deps.remote)
|
||||||
},
|
},
|
||||||
Some((username, password)) => {
|
Some((username, password)) => {
|
||||||
server.start_basic_auth_http(url, &username, &password, handler)
|
server.start_basic_auth_http(url, &username, &password, apis, deps.remote)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -199,13 +198,7 @@ mod server {
|
|||||||
_ => Err(format!("WebApps io error: {}", err)),
|
_ => Err(format!("WebApps io error: {}", err)),
|
||||||
},
|
},
|
||||||
Err(e) => Err(format!("WebApps error: {:?}", e)),
|
Err(e) => Err(format!("WebApps error: {:?}", e)),
|
||||||
Ok(server) => {
|
Ok(server) => Ok(server),
|
||||||
let ph = deps.panic_handler;
|
|
||||||
server.set_panic_handler(move || {
|
|
||||||
ph.notify_all("Panic in WebApp thread.".to_owned());
|
|
||||||
});
|
|
||||||
Ok(server)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,40 +1,59 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use parity_ipfs_api;
|
use parity_ipfs_api::{self, AccessControlAllowOrigin, Host};
|
||||||
use parity_ipfs_api::error::ServerError;
|
use parity_ipfs_api::error::ServerError;
|
||||||
use ethcore::client::BlockChainClient;
|
use ethcore::client::BlockChainClient;
|
||||||
use hyper::server::Listening;
|
use hyper::server::Listening;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub interface: String,
|
pub interface: String,
|
||||||
pub cors: Option<Vec<String>>,
|
pub cors: Option<Vec<String>>,
|
||||||
pub hosts: Option<Vec<String>>,
|
pub hosts: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Configuration {
|
impl Default for Configuration {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Configuration {
|
Configuration {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
port: 5001,
|
port: 5001,
|
||||||
interface: "127.0.0.1".into(),
|
interface: "127.0.0.1".into(),
|
||||||
cors: None,
|
cors: None,
|
||||||
hosts: Some(Vec::new()),
|
hosts: Some(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_server(conf: Configuration, client: Arc<BlockChainClient>) -> Result<Option<Listening>, ServerError> {
|
pub fn start_server(conf: Configuration, client: Arc<BlockChainClient>) -> Result<Option<Listening>, ServerError> {
|
||||||
if !conf.enabled {
|
if !conf.enabled {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
parity_ipfs_api::start_server(
|
let cors = conf.cors.map(|cors| cors.into_iter().map(AccessControlAllowOrigin::from).collect());
|
||||||
conf.port,
|
let hosts = conf.hosts.map(|hosts| hosts.into_iter().map(Host::from).collect());
|
||||||
conf.interface,
|
|
||||||
conf.cors,
|
parity_ipfs_api::start_server(
|
||||||
conf.hosts,
|
conf.port,
|
||||||
client
|
conf.interface,
|
||||||
).map(Some)
|
cors.into(),
|
||||||
|
hosts.into(),
|
||||||
|
client
|
||||||
|
).map(Some)
|
||||||
}
|
}
|
||||||
|
@ -18,19 +18,18 @@ use std::fmt;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::io;
|
use std::io;
|
||||||
use io::PanicHandler;
|
|
||||||
|
|
||||||
use dir::default_data_path;
|
use dir::default_data_path;
|
||||||
use ethcore_rpc::{self as rpc, RpcServerError, IpcServerError, Metadata, Origin};
|
use ethcore_rpc::{self as rpc, HttpServerError, Metadata, Origin, AccessControlAllowOrigin, Host};
|
||||||
use ethcore_rpc::informant::{RpcStats, Middleware};
|
use ethcore_rpc::informant::{RpcStats, Middleware};
|
||||||
use helpers::parity_ipc_path;
|
use helpers::parity_ipc_path;
|
||||||
use hyper;
|
use hyper;
|
||||||
use jsonrpc_core::MetaIoHandler;
|
use jsonrpc_core::MetaIoHandler;
|
||||||
use jsonrpc_core::reactor::{RpcHandler, Remote};
|
|
||||||
use rpc_apis;
|
use rpc_apis;
|
||||||
use rpc_apis::ApiSet;
|
use rpc_apis::ApiSet;
|
||||||
|
use parity_reactor::TokioRemote;
|
||||||
|
|
||||||
pub use ethcore_rpc::{IpcServer, Server as HttpServer};
|
pub use ethcore_rpc::{IpcServer, HttpServer};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct HttpConfiguration {
|
pub struct HttpConfiguration {
|
||||||
@ -84,9 +83,8 @@ impl fmt::Display for IpcConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Dependencies {
|
pub struct Dependencies {
|
||||||
pub panic_handler: Arc<PanicHandler>,
|
|
||||||
pub apis: Arc<rpc_apis::Dependencies>,
|
pub apis: Arc<rpc_apis::Dependencies>,
|
||||||
pub remote: Remote,
|
pub remote: TokioRemote,
|
||||||
pub stats: Arc<RpcStats>,
|
pub stats: Arc<RpcStats>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +100,15 @@ impl rpc::HttpMetaExtractor<Metadata> for RpcExtractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl rpc::IpcMetaExtractor<Metadata> for RpcExtractor {
|
||||||
|
fn extract(&self, _req: &rpc::IpcRequestContext) -> Metadata {
|
||||||
|
let mut metadata = Metadata::default();
|
||||||
|
// TODO [ToDr] Extract proper session id when it's available in context.
|
||||||
|
metadata.origin = Origin::Ipc(1.into());
|
||||||
|
metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_http(conf: HttpConfiguration, deps: &Dependencies) -> Result<Option<HttpServer>, String> {
|
pub fn new_http(conf: HttpConfiguration, deps: &Dependencies) -> Result<Option<HttpServer>, String> {
|
||||||
if !conf.enabled {
|
if !conf.enabled {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
@ -123,12 +130,13 @@ pub fn setup_http_rpc_server(
|
|||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: Option<Vec<String>>,
|
||||||
apis: ApiSet
|
apis: ApiSet
|
||||||
) -> Result<HttpServer, String> {
|
) -> Result<HttpServer, String> {
|
||||||
let apis = setup_apis(apis, dependencies);
|
let handler = setup_apis(apis, dependencies);
|
||||||
let handler = RpcHandler::new(Arc::new(apis), dependencies.remote.clone());
|
let remote = dependencies.remote.clone();
|
||||||
let ph = dependencies.panic_handler.clone();
|
let cors_domains: Option<Vec<_>> = cors_domains.map(|domains| domains.into_iter().map(AccessControlAllowOrigin::from).collect());
|
||||||
let start_result = rpc::start_http(url, cors_domains, allowed_hosts, ph, handler, RpcExtractor);
|
let allowed_hosts: Option<Vec<_>> = allowed_hosts.map(|hosts| hosts.into_iter().map(Host::from).collect());
|
||||||
|
let start_result = rpc::start_http(url, cors_domains.into(), allowed_hosts.into(), handler, remote, RpcExtractor);
|
||||||
match start_result {
|
match start_result {
|
||||||
Err(RpcServerError::IoError(err)) => match err.kind() {
|
Err(HttpServerError::IoError(err)) => match err.kind() {
|
||||||
io::ErrorKind::AddrInUse => Err(format!("RPC address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --jsonrpc-port and --jsonrpc-interface options.", url)),
|
io::ErrorKind::AddrInUse => Err(format!("RPC address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --jsonrpc-port and --jsonrpc-interface options.", url)),
|
||||||
_ => Err(format!("RPC io error: {}", err)),
|
_ => Err(format!("RPC io error: {}", err)),
|
||||||
},
|
},
|
||||||
@ -137,17 +145,16 @@ pub fn setup_http_rpc_server(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Result<Option<IpcServer<Metadata, Middleware>>, String> {
|
pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Result<Option<IpcServer>, String> {
|
||||||
if !conf.enabled { return Ok(None); }
|
if !conf.enabled { return Ok(None); }
|
||||||
Ok(Some(setup_ipc_rpc_server(deps, &conf.socket_addr, conf.apis)?))
|
Ok(Some(setup_ipc_rpc_server(deps, &conf.socket_addr, conf.apis)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_ipc_rpc_server(dependencies: &Dependencies, addr: &str, apis: ApiSet) -> Result<IpcServer<Metadata, Middleware>, String> {
|
pub fn setup_ipc_rpc_server(dependencies: &Dependencies, addr: &str, apis: ApiSet) -> Result<IpcServer, String> {
|
||||||
let apis = setup_apis(apis, dependencies);
|
let handler = setup_apis(apis, dependencies);
|
||||||
let handler = RpcHandler::new(Arc::new(apis), dependencies.remote.clone());
|
let remote = dependencies.remote.clone();
|
||||||
match rpc::start_ipc(addr, handler) {
|
match rpc::start_ipc(addr, handler, remote, RpcExtractor) {
|
||||||
Err(IpcServerError::Io(io_error)) => Err(format!("RPC io error: {}", io_error)),
|
Err(io_error) => Err(format!("RPC io error: {}", io_error)),
|
||||||
Err(any_error) => Err(format!("Rpc error: {:?}", any_error)),
|
|
||||||
Ok(server) => Ok(server)
|
Ok(server) => Ok(server)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,7 +435,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
|||||||
});
|
});
|
||||||
|
|
||||||
let dependencies = rpc::Dependencies {
|
let dependencies = rpc::Dependencies {
|
||||||
panic_handler: panic_handler.clone(),
|
|
||||||
apis: deps_for_rpc_apis.clone(),
|
apis: deps_for_rpc_apis.clone(),
|
||||||
remote: event_loop.raw_remote(),
|
remote: event_loop.raw_remote(),
|
||||||
stats: rpc_stats.clone(),
|
stats: rpc_stats.clone(),
|
||||||
@ -447,7 +446,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
|||||||
|
|
||||||
// the dapps server
|
// the dapps server
|
||||||
let dapps_deps = dapps::Dependencies {
|
let dapps_deps = dapps::Dependencies {
|
||||||
panic_handler: panic_handler.clone(),
|
|
||||||
apis: deps_for_rpc_apis.clone(),
|
apis: deps_for_rpc_apis.clone(),
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
sync: sync_provider.clone(),
|
sync: sync_provider.clone(),
|
||||||
@ -460,7 +458,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
|||||||
|
|
||||||
// the signer server
|
// the signer server
|
||||||
let signer_deps = signer::Dependencies {
|
let signer_deps = signer::Dependencies {
|
||||||
panic_handler: panic_handler.clone(),
|
|
||||||
apis: deps_for_rpc_apis.clone(),
|
apis: deps_for_rpc_apis.clone(),
|
||||||
remote: event_loop.raw_remote(),
|
remote: event_loop.raw_remote(),
|
||||||
rpc_stats: rpc_stats.clone(),
|
rpc_stats: rpc_stats.clone(),
|
||||||
|
@ -26,8 +26,7 @@ use ethcore_rpc::informant::RpcStats;
|
|||||||
use ethcore_rpc;
|
use ethcore_rpc;
|
||||||
use ethcore_signer as signer;
|
use ethcore_signer as signer;
|
||||||
use helpers::replace_home;
|
use helpers::replace_home;
|
||||||
use io::{ForwardPanic, PanicHandler};
|
use parity_reactor::TokioRemote;
|
||||||
use jsonrpc_core::reactor::{RpcHandler, Remote};
|
|
||||||
use rpc_apis;
|
use rpc_apis;
|
||||||
use util::path::restrict_permissions_owner;
|
use util::path::restrict_permissions_owner;
|
||||||
use util::H256;
|
use util::H256;
|
||||||
@ -57,9 +56,8 @@ impl Default for Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Dependencies {
|
pub struct Dependencies {
|
||||||
pub panic_handler: Arc<PanicHandler>,
|
|
||||||
pub apis: Arc<rpc_apis::Dependencies>,
|
pub apis: Arc<rpc_apis::Dependencies>,
|
||||||
pub remote: Remote,
|
pub remote: TokioRemote,
|
||||||
pub rpc_stats: Arc<RpcStats>,
|
pub rpc_stats: Arc<RpcStats>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,9 +141,9 @@ fn do_start(conf: Configuration, deps: Dependencies) -> Result<SignerServer, Str
|
|||||||
}
|
}
|
||||||
let server = server.skip_origin_validation(conf.skip_origin_validation);
|
let server = server.skip_origin_validation(conf.skip_origin_validation);
|
||||||
let server = server.stats(deps.rpc_stats.clone());
|
let server = server.stats(deps.rpc_stats.clone());
|
||||||
let apis = rpc_apis::setup_rpc(deps.rpc_stats, deps.apis, rpc_apis::ApiSet::SafeContext);
|
let handler = rpc_apis::setup_rpc(deps.rpc_stats, deps.apis, rpc_apis::ApiSet::SafeContext);
|
||||||
let handler = RpcHandler::new(Arc::new(apis), deps.remote);
|
let remote = deps.remote.clone();
|
||||||
server.start_with_extractor(addr, handler, StandardExtractor)
|
server.start_with_extractor(addr, handler, remote, StandardExtractor)
|
||||||
};
|
};
|
||||||
|
|
||||||
match start_result {
|
match start_result {
|
||||||
@ -154,10 +152,7 @@ fn do_start(conf: Configuration, deps: Dependencies) -> Result<SignerServer, Str
|
|||||||
_ => Err(format!("Trusted Signer io error: {}", err)),
|
_ => Err(format!("Trusted Signer io error: {}", err)),
|
||||||
},
|
},
|
||||||
Err(e) => Err(format!("Trusted Signer Error: {:?}", e)),
|
Err(e) => Err(format!("Trusted Signer Error: {:?}", e)),
|
||||||
Ok(server) => {
|
Ok(server) => Ok(server),
|
||||||
deps.panic_handler.forward_from(&server);
|
|
||||||
Ok(server)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,18 +10,20 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
order-stat = "0.1"
|
||||||
|
rustc-serialize = "0.3"
|
||||||
semver = "0.5"
|
semver = "0.5"
|
||||||
serde = "0.9"
|
serde = "0.9"
|
||||||
serde_json = "0.9"
|
|
||||||
serde_derive = "0.9"
|
serde_derive = "0.9"
|
||||||
rustc-serialize = "0.3"
|
serde_json = "0.9"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
transient-hashmap = "0.4"
|
transient-hashmap = "0.4"
|
||||||
order-stat = "0.1"
|
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
jsonrpc-ipc-server = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
jsonrpc-macros = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
|
|
||||||
ethcore-io = { path = "../util/io" }
|
ethcore-io = { path = "../util/io" }
|
||||||
ethcore-ipc = { path = "../ipc/rpc" }
|
ethcore-ipc = { path = "../ipc/rpc" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
@ -35,11 +37,12 @@ ethjson = { path = "../json" }
|
|||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
ethcore-light = { path = "../ethcore/light" }
|
ethcore-light = { path = "../ethcore/light" }
|
||||||
parity-updater = { path = "../updater" }
|
parity-updater = { path = "../updater" }
|
||||||
|
parity-reactor = { path = "../util/reactor" }
|
||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
fetch = { path = "../util/fetch" }
|
fetch = { path = "../util/fetch" }
|
||||||
parity-reactor = { path = "../util/reactor" }
|
|
||||||
clippy = { version = "0.0.103", optional = true}
|
|
||||||
stats = { path = "../util/stats" }
|
stats = { path = "../util/stats" }
|
||||||
|
|
||||||
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev"]
|
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev"]
|
||||||
|
111
rpc/src/lib.rs
111
rpc/src/lib.rs
@ -19,31 +19,32 @@
|
|||||||
#![cfg_attr(feature="nightly", feature(plugin))]
|
#![cfg_attr(feature="nightly", feature(plugin))]
|
||||||
#![cfg_attr(feature="nightly", plugin(clippy))]
|
#![cfg_attr(feature="nightly", plugin(clippy))]
|
||||||
|
|
||||||
extern crate semver;
|
|
||||||
extern crate rustc_serialize;
|
|
||||||
extern crate serde;
|
|
||||||
extern crate serde_json;
|
|
||||||
extern crate jsonrpc_core;
|
|
||||||
extern crate jsonrpc_http_server;
|
|
||||||
|
|
||||||
extern crate ethcore_io as io;
|
|
||||||
extern crate ethcore;
|
|
||||||
extern crate ethkey;
|
|
||||||
extern crate ethcrypto as crypto;
|
|
||||||
extern crate ethstore;
|
|
||||||
extern crate ethsync;
|
|
||||||
extern crate ethash;
|
|
||||||
extern crate ethcore_light as light;
|
|
||||||
extern crate transient_hashmap;
|
|
||||||
extern crate jsonrpc_ipc_server as ipc;
|
|
||||||
extern crate ethcore_ipc;
|
|
||||||
extern crate time;
|
|
||||||
extern crate rlp;
|
|
||||||
extern crate fetch;
|
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate order_stat;
|
extern crate order_stat;
|
||||||
extern crate parity_updater as updater;
|
extern crate rustc_serialize;
|
||||||
|
extern crate semver;
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
extern crate time;
|
||||||
|
extern crate transient_hashmap;
|
||||||
|
|
||||||
|
extern crate jsonrpc_core;
|
||||||
|
pub extern crate jsonrpc_http_server as http;
|
||||||
|
pub extern crate jsonrpc_ipc_server as ipc;
|
||||||
|
|
||||||
|
extern crate ethash;
|
||||||
|
extern crate ethcore;
|
||||||
|
extern crate ethcore_io as io;
|
||||||
|
extern crate ethcore_ipc;
|
||||||
|
extern crate ethcore_light as light;
|
||||||
|
extern crate ethcrypto as crypto;
|
||||||
|
extern crate ethkey;
|
||||||
|
extern crate ethstore;
|
||||||
|
extern crate ethsync;
|
||||||
|
extern crate fetch;
|
||||||
extern crate parity_reactor;
|
extern crate parity_reactor;
|
||||||
|
extern crate parity_updater as updater;
|
||||||
|
extern crate rlp;
|
||||||
extern crate stats;
|
extern crate stats;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -60,57 +61,53 @@ extern crate ethjson;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate ethcore_devtools as devtools;
|
extern crate ethcore_devtools as devtools;
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::net::SocketAddr;
|
|
||||||
use io::PanicHandler;
|
|
||||||
use jsonrpc_core::reactor::RpcHandler;
|
|
||||||
|
|
||||||
pub use ipc::{Server as IpcServer, Error as IpcServerError};
|
|
||||||
pub use jsonrpc_http_server::{ServerBuilder, Server, RpcServerError, HttpMetaExtractor};
|
|
||||||
pub mod v1;
|
pub mod v1;
|
||||||
|
|
||||||
|
pub use ipc::{Server as IpcServer, MetaExtractor as IpcMetaExtractor, RequestContext as IpcRequestContext};
|
||||||
|
pub use http::{HttpMetaExtractor, Server as HttpServer, Error as HttpServerError, AccessControlAllowOrigin, Host};
|
||||||
|
|
||||||
pub use v1::{SigningQueue, SignerService, ConfirmationsQueue, NetworkSettings, Metadata, Origin, informant, dispatch};
|
pub use v1::{SigningQueue, SignerService, ConfirmationsQueue, NetworkSettings, Metadata, Origin, informant, dispatch};
|
||||||
pub use v1::block_import::is_major_importing;
|
pub use v1::block_import::is_major_importing;
|
||||||
|
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use http::tokio_core;
|
||||||
|
|
||||||
/// Start http server asynchronously and returns result with `Server` handle on success or an error.
|
/// Start http server asynchronously and returns result with `Server` handle on success or an error.
|
||||||
pub fn start_http<M, T, S>(
|
pub fn start_http<M, S, H, T>(
|
||||||
addr: &SocketAddr,
|
addr: &SocketAddr,
|
||||||
cors_domains: Option<Vec<String>>,
|
cors_domains: http::DomainsValidation<http::AccessControlAllowOrigin>,
|
||||||
allowed_hosts: Option<Vec<String>>,
|
allowed_hosts: http::DomainsValidation<http::Host>,
|
||||||
panic_handler: Arc<PanicHandler>,
|
handler: H,
|
||||||
handler: RpcHandler<M, S>,
|
remote: tokio_core::reactor::Remote,
|
||||||
extractor: T,
|
extractor: T,
|
||||||
) -> Result<Server, RpcServerError> where
|
) -> Result<HttpServer, HttpServerError> where
|
||||||
M: jsonrpc_core::Metadata,
|
M: jsonrpc_core::Metadata,
|
||||||
S: jsonrpc_core::Middleware<M>,
|
S: jsonrpc_core::Middleware<M>,
|
||||||
|
H: Into<jsonrpc_core::MetaIoHandler<M, S>>,
|
||||||
T: HttpMetaExtractor<M>,
|
T: HttpMetaExtractor<M>,
|
||||||
{
|
{
|
||||||
|
http::ServerBuilder::new(handler)
|
||||||
let cors_domains = cors_domains.map(|domains| {
|
.event_loop_remote(remote)
|
||||||
domains.into_iter()
|
.meta_extractor(extractor)
|
||||||
.map(|v| match v.as_str() {
|
|
||||||
"*" => jsonrpc_http_server::AccessControlAllowOrigin::Any,
|
|
||||||
"null" => jsonrpc_http_server::AccessControlAllowOrigin::Null,
|
|
||||||
v => jsonrpc_http_server::AccessControlAllowOrigin::Value(v.into()),
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
});
|
|
||||||
|
|
||||||
ServerBuilder::with_rpc_handler(handler)
|
|
||||||
.meta_extractor(Arc::new(extractor))
|
|
||||||
.cors(cors_domains.into())
|
.cors(cors_domains.into())
|
||||||
.allowed_hosts(allowed_hosts.into())
|
.allowed_hosts(allowed_hosts.into())
|
||||||
.panic_handler(move || {
|
|
||||||
panic_handler.notify_all("Panic in RPC thread.".to_owned());
|
|
||||||
})
|
|
||||||
.start_http(addr)
|
.start_http(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start ipc server asynchronously and returns result with `Server` handle on success or an error.
|
/// Start ipc server asynchronously and returns result with `Server` handle on success or an error.
|
||||||
pub fn start_ipc<M: jsonrpc_core::Metadata, S: jsonrpc_core::Middleware<M>>(
|
pub fn start_ipc<M, S, H, T>(
|
||||||
addr: &str,
|
addr: &str,
|
||||||
handler: RpcHandler<M, S>,
|
handler: H,
|
||||||
) -> Result<ipc::Server<M, S>, ipc::Error> {
|
remote: tokio_core::reactor::Remote,
|
||||||
let server = ipc::Server::with_rpc_handler(addr, handler)?;
|
extractor: T,
|
||||||
server.run_async()?;
|
) -> ::std::io::Result<ipc::Server> where
|
||||||
Ok(server)
|
M: jsonrpc_core::Metadata,
|
||||||
|
S: jsonrpc_core::Middleware<M>,
|
||||||
|
H: Into<jsonrpc_core::MetaIoHandler<M, S>>,
|
||||||
|
T: IpcMetaExtractor<M>,
|
||||||
|
{
|
||||||
|
ipc::ServerBuilder::new(handler)
|
||||||
|
.event_loop_remote(remote)
|
||||||
|
.session_metadata_extractor(extractor)
|
||||||
|
.start(addr)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ pub mod block_import;
|
|||||||
pub mod dispatch;
|
pub mod dispatch;
|
||||||
pub mod fake_sign;
|
pub mod fake_sign;
|
||||||
pub mod informant;
|
pub mod informant;
|
||||||
|
pub mod oneshot;
|
||||||
|
|
||||||
mod network_settings;
|
mod network_settings;
|
||||||
mod poll_manager;
|
mod poll_manager;
|
||||||
|
67
rpc/src/v1/helpers/oneshot.rs
Normal file
67
rpc/src/v1/helpers/oneshot.rs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use jsonrpc_core::Error;
|
||||||
|
use futures::{self, Future};
|
||||||
|
use futures::sync::oneshot;
|
||||||
|
use v1::helpers::errors;
|
||||||
|
|
||||||
|
pub type Res<T> = Result<T, Error>;
|
||||||
|
|
||||||
|
pub struct Sender<T> {
|
||||||
|
sender: oneshot::Sender<Res<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Sender<T> {
|
||||||
|
pub fn send(self, data: Res<T>) {
|
||||||
|
let res = self.sender.send(data);
|
||||||
|
if let Err(_) = res {
|
||||||
|
debug!(target: "rpc", "Responding to a no longer active request.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Receiver<T> {
|
||||||
|
receiver: oneshot::Receiver<Res<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Future for Receiver<T> {
|
||||||
|
type Item = T;
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
|
||||||
|
let res = self.receiver.poll();
|
||||||
|
match res {
|
||||||
|
Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady),
|
||||||
|
Ok(futures::Async::Ready(Ok(res))) => Ok(futures::Async::Ready(res)),
|
||||||
|
Ok(futures::Async::Ready(Err(err))) => Err(err),
|
||||||
|
Err(e) => {
|
||||||
|
debug!(target: "rpc", "Responding to a canceled request: {:?}", e);
|
||||||
|
Err(errors::internal("Request was canceled by client.", e))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn oneshot<T>() -> (Sender<T>, Receiver<T>) {
|
||||||
|
let (tx, rx) = futures::oneshot();
|
||||||
|
|
||||||
|
(Sender {
|
||||||
|
sender: tx,
|
||||||
|
}, Receiver {
|
||||||
|
receiver: rx,
|
||||||
|
})
|
||||||
|
}
|
@ -22,10 +22,10 @@ use util::{U256, Mutex};
|
|||||||
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
|
||||||
use futures::{self, future, BoxFuture, Future};
|
use futures::{future, BoxFuture, Future};
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use v1::helpers::{
|
use v1::helpers::{
|
||||||
errors,
|
errors, oneshot,
|
||||||
DefaultAccount,
|
DefaultAccount,
|
||||||
SIGNING_QUEUE_LIMIT, SigningQueue, ConfirmationPromise, ConfirmationResult, SignerService
|
SIGNING_QUEUE_LIMIT, SigningQueue, ConfirmationPromise, ConfirmationResult, SignerService
|
||||||
};
|
};
|
||||||
@ -188,21 +188,20 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
|
|||||||
meta.origin,
|
meta.origin,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (ready, p) = futures::oneshot();
|
let (ready, p) = oneshot::oneshot();
|
||||||
|
|
||||||
// when dispatch is complete
|
// when dispatch is complete
|
||||||
res.then(move |res| {
|
res.then(move |res| {
|
||||||
// register callback via the oneshot sender.
|
// register callback via the oneshot sender.
|
||||||
handle_dispatch(res, move |response| {
|
handle_dispatch(res, move |response| {
|
||||||
match response {
|
match response {
|
||||||
Ok(RpcConfirmationResponse::Decrypt(data)) => ready.complete(Ok(data)),
|
Ok(RpcConfirmationResponse::Decrypt(data)) => ready.send(Ok(data)),
|
||||||
Err(e) => ready.complete(Err(e)),
|
Err(e) => ready.send(Err(e)),
|
||||||
e => ready.complete(Err(errors::internal("Unexpected result.", e))),
|
e => ready.send(Err(errors::internal("Unexpected result.", e))),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// and wait for that to resolve.
|
p
|
||||||
p.then(|result| futures::done(result.expect("Ready is never dropped nor canceled.")))
|
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,18 +216,18 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
|
|||||||
meta.origin,
|
meta.origin,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (ready, p) = futures::oneshot();
|
let (ready, p) = oneshot::oneshot();
|
||||||
|
|
||||||
res.then(move |res| {
|
res.then(move |res| {
|
||||||
handle_dispatch(res, move |response| {
|
handle_dispatch(res, move |response| {
|
||||||
match response {
|
match response {
|
||||||
Ok(RpcConfirmationResponse::Signature(sig)) => ready.complete(Ok(sig)),
|
Ok(RpcConfirmationResponse::Signature(sig)) => ready.send(Ok(sig)),
|
||||||
Err(e) => ready.complete(Err(e)),
|
Err(e) => ready.send(Err(e)),
|
||||||
e => ready.complete(Err(errors::internal("Unexpected result.", e))),
|
e => ready.send(Err(errors::internal("Unexpected result.", e))),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
p.then(|result| futures::done(result.expect("Ready is never dropped nor canceled.")))
|
p
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,18 +238,18 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
|
|||||||
meta.origin,
|
meta.origin,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (ready, p) = futures::oneshot();
|
let (ready, p) = oneshot::oneshot();
|
||||||
|
|
||||||
res.then(move |res| {
|
res.then(move |res| {
|
||||||
handle_dispatch(res, move |response| {
|
handle_dispatch(res, move |response| {
|
||||||
match response {
|
match response {
|
||||||
Ok(RpcConfirmationResponse::SendTransaction(hash)) => ready.complete(Ok(hash)),
|
Ok(RpcConfirmationResponse::SendTransaction(hash)) => ready.send(Ok(hash)),
|
||||||
Err(e) => ready.complete(Err(e)),
|
Err(e) => ready.send(Err(e)),
|
||||||
e => ready.complete(Err(errors::internal("Unexpected result.", e))),
|
e => ready.send(Err(errors::internal("Unexpected result.", e))),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
p.then(|result| futures::done(result.expect("Ready is never dropped nor canceled.")))
|
p
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,18 +260,18 @@ impl<D: Dispatcher + 'static> EthSigning for SigningQueueClient<D> {
|
|||||||
meta.origin,
|
meta.origin,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (ready, p) = futures::oneshot();
|
let (ready, p) = oneshot::oneshot();
|
||||||
|
|
||||||
res.then(move |res| {
|
res.then(move |res| {
|
||||||
handle_dispatch(res, move |response| {
|
handle_dispatch(res, move |response| {
|
||||||
match response {
|
match response {
|
||||||
Ok(RpcConfirmationResponse::SignTransaction(tx)) => ready.complete(Ok(tx)),
|
Ok(RpcConfirmationResponse::SignTransaction(tx)) => ready.send(Ok(tx)),
|
||||||
Err(e) => ready.complete(Err(e)),
|
Err(e) => ready.send(Err(e)),
|
||||||
e => ready.complete(Err(errors::internal("Unexpected result.", e))),
|
e => ready.send(Err(errors::internal("Unexpected result.", e))),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
p.then(|result| futures::done(result.expect("Ready is never dropped nor canceled.")))
|
p
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl Fetch for TestFetch {
|
|||||||
let (tx, rx) = futures::oneshot();
|
let (tx, rx) = futures::oneshot();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let cursor = io::Cursor::new(b"Some content");
|
let cursor = io::Cursor::new(b"Some content");
|
||||||
tx.complete(fetch::Response::from_reader(cursor));
|
tx.send(fetch::Response::from_reader(cursor)).unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
rx.map_err(|_| fetch::Error::Aborted).boxed()
|
rx.map_err(|_| fetch::Error::Aborted).boxed()
|
||||||
|
@ -901,7 +901,7 @@ fn rpc_eth_send_transaction_with_bad_to() {
|
|||||||
"id": 1
|
"id": 1
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid length.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: expected a hex-encoded hash with 0x prefix."},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(&request), Some(response.into()));
|
assert_eq!(tester.io.handle_request_sync(&request), Some(response.into()));
|
||||||
}
|
}
|
||||||
@ -1084,7 +1084,7 @@ fn rpc_get_work_returns_no_work_if_cant_mine() {
|
|||||||
eth_tester.client.set_queue_size(10);
|
eth_tester.client.set_queue_size(10);
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32001,"message":"Still syncing.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32001,"message":"Still syncing."},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(eth_tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(eth_tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
@ -1142,6 +1142,6 @@ fn rpc_get_work_should_timeout() {
|
|||||||
|
|
||||||
// Request with timeout of 10 seconds. This should fail.
|
// Request with timeout of 10 seconds. This should fail.
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": ["10"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": ["10"], "id": 1}"#;
|
||||||
let err_response = r#"{"jsonrpc":"2.0","error":{"code":-32003,"message":"Work has not changed.","data":null},"id":1}"#;
|
let err_response = r#"{"jsonrpc":"2.0","error":{"code":-32003,"message":"Work has not changed."},"id":1}"#;
|
||||||
assert_eq!(eth_tester.io.handle_request_sync(request), Some(err_response.to_owned()));
|
assert_eq!(eth_tester.io.handle_request_sync(request), Some(err_response.to_owned()));
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,7 @@ fn rpc_parity_unsigned_transactions_count_when_signer_disabled() {
|
|||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available."},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
@ -393,7 +393,7 @@ fn rpc_parity_signer_port() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_signerPort", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_signerPort", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available."},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||||
@ -411,7 +411,7 @@ fn rpc_parity_dapps_port() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsPort", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsPort", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available."},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||||
@ -429,7 +429,7 @@ fn rpc_parity_dapps_interface() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsInterface", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsInterface", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":"127.0.0.1","id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":"127.0.0.1","id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available."},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||||
|
@ -230,7 +230,7 @@ fn should_be_able_to_kill_account() {
|
|||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
|
|
||||||
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_killAccount", "params": ["0xf00baba2f00baba2f00baba2f00baba2f00baba2"], "id": 1}}"#);
|
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_killAccount", "params": ["0xf00baba2f00baba2f00baba2f00baba2f00baba2"], "id": 1}}"#);
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"invalid length 1, expected a tuple of size 2","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: invalid length 1, expected a tuple of size 2."},"id":1}"#;
|
||||||
let res = tester.io.handle_request_sync(&request);
|
let res = tester.io.handle_request_sync(&request);
|
||||||
assert_eq!(res, Some(response.into()));
|
assert_eq!(res, Some(response.into()));
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ fn rpc_trace_call_state_pruned() {
|
|||||||
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||||
|
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ fn rpc_trace_raw_transaction_state_pruned() {
|
|||||||
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||||
|
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ fn rpc_trace_replay_transaction_state_pruned() {
|
|||||||
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||||
|
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
@ -124,13 +124,16 @@ macro_rules! impl_hash {
|
|||||||
type Value = $name;
|
type Value = $name;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "a 0x-prefixed, padded, hex-encoded hash of type {}", stringify!($name))
|
write!(formatter, "a 0x-prefixed, padded, hex-encoded hash with length {}", $size * 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||||
|
|
||||||
|
if value.len() < 2 || &value[0..2] != "0x" {
|
||||||
|
return Err(E::custom("expected a hex-encoded hash with 0x prefix"));
|
||||||
|
}
|
||||||
if value.len() != 2 + $size * 2 {
|
if value.len() != 2 + $size * 2 {
|
||||||
return Err(E::custom("Invalid length."));
|
return Err(E::invalid_length(value.len() - 2, &self));
|
||||||
}
|
}
|
||||||
|
|
||||||
match value[2..].from_hex() {
|
match value[2..].from_hex() {
|
||||||
@ -139,7 +142,7 @@ macro_rules! impl_hash {
|
|||||||
result.copy_from_slice(v);
|
result.copy_from_slice(v);
|
||||||
Ok($name(result))
|
Ok($name(result))
|
||||||
},
|
},
|
||||||
_ => Err(E::custom("Invalid hex value."))
|
Err(e) => Err(E::custom(format!("invalid hex value: {:?}", e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,20 +74,20 @@ macro_rules! impl_uint {
|
|||||||
type Value = $name;
|
type Value = $name;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "a 0x-prefixed, hex-encoded number of type {}", stringify!($name))
|
write!(formatter, "a 0x-prefixed, hex-encoded number of length {}", $size*16)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||||
|
if value.len() < 2 || &value[0..2] != "0x" {
|
||||||
|
return Err(E::custom("expected a hex-encoded numbers with 0x prefix"))
|
||||||
|
}
|
||||||
|
|
||||||
// 0x + len
|
// 0x + len
|
||||||
if value.len() > 2 + $size * 16 || value.len() < 2 {
|
if value.len() > 2 + $size * 16 {
|
||||||
return Err(E::custom("Invalid length."));
|
return Err(E::invalid_length(value.len() - 2, &self));
|
||||||
}
|
}
|
||||||
|
|
||||||
if &value[0..2] != "0x" {
|
$other::from_str(&value[2..]).map($name).map_err(|e| E::custom(&format!("invalid hex value: {:?}", e)))
|
||||||
return Err(E::custom("Use hex encoded numbers with 0x prefix."))
|
|
||||||
}
|
|
||||||
|
|
||||||
$other::from_str(&value[2..]).map($name).map_err(|_| E::custom("Invalid hex value."))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_string<E>(self, value: String) -> Result<Self::Value, E> where E: serde::de::Error {
|
fn visit_string<E>(self, value: String) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
authors = ["Ethcore <admin@ethcore.io>"]
|
authors = ["Ethcore <admin@parity.io>"]
|
||||||
description = "Parity Rpc Client"
|
description = "Parity Rpc Client"
|
||||||
homepage = "http://ethcore.io"
|
homepage = "http://parity.io"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
name = "parity-rpc-client"
|
name = "parity-rpc-client"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -14,8 +14,8 @@ serde = "0.9"
|
|||||||
serde_json = "0.9"
|
serde_json = "0.9"
|
||||||
tempdir = "0.3.5"
|
tempdir = "0.3.5"
|
||||||
url = "1.2.0"
|
url = "1.2.0"
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "mio-upstream-stable" }
|
ws = { git = "https://github.com/paritytech/ws-rs.git", branch = "mio-upstream-stable" }
|
||||||
ethcore-rpc = { path = "../rpc" }
|
ethcore-rpc = { path = "../rpc" }
|
||||||
ethcore-signer = { path = "../signer" }
|
ethcore-signer = { path = "../signer" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
|
@ -83,18 +83,24 @@ impl Handler for RpcHandler {
|
|||||||
}
|
}
|
||||||
fn on_error(&mut self, err: WsError) {
|
fn on_error(&mut self, err: WsError) {
|
||||||
match self.complete.take() {
|
match self.complete.take() {
|
||||||
Some(c) => c.complete(Err(RpcError::WsError(err))),
|
Some(c) => match c.send(Err(RpcError::WsError(err))) {
|
||||||
None => println!("unexpected error: {}", err),
|
Ok(_) => {},
|
||||||
|
Err(_) => warn!(target: "rpc-client", "Unable to notify about error."),
|
||||||
|
},
|
||||||
|
None => warn!(target: "rpc-client", "unexpected error: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_open(&mut self, _: Handshake) -> WsResult<()> {
|
fn on_open(&mut self, _: Handshake) -> WsResult<()> {
|
||||||
match (self.complete.take(), self.out.take()) {
|
match (self.complete.take(), self.out.take()) {
|
||||||
(Some(c), Some(out)) => {
|
(Some(c), Some(out)) => {
|
||||||
c.complete(Ok(Rpc {
|
let res = c.send(Ok(Rpc {
|
||||||
out: out,
|
out: out,
|
||||||
counter: AtomicUsize::new(0),
|
counter: AtomicUsize::new(0),
|
||||||
pending: self.pending.clone(),
|
pending: self.pending.clone(),
|
||||||
}));
|
}));
|
||||||
|
if let Err(_) = res {
|
||||||
|
warn!(target: "rpc-client", "Unable to open a connection.")
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@ -137,9 +143,9 @@ impl Handler for RpcHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.pending.remove(response_id) {
|
match self.pending.remove(response_id) {
|
||||||
Some(c) => c.complete(ret.map_err(|err| {
|
Some(c) => if let Err(_) = c.send(ret.map_err(|err| RpcError::JsonRpc(err))) {
|
||||||
RpcError::JsonRpc(err)
|
warn!(target: "rpc-client", "Unable to send response.")
|
||||||
})),
|
},
|
||||||
None => warn!(
|
None => warn!(
|
||||||
target: "rpc-client",
|
target: "rpc-client",
|
||||||
"warning: unexpected id: {}",
|
"warning: unexpected id: {}",
|
||||||
@ -225,7 +231,7 @@ impl Rpc {
|
|||||||
// both fail and succeed.
|
// both fail and succeed.
|
||||||
let c = once.take()
|
let c = once.take()
|
||||||
.expect("connection closure called only once");
|
.expect("connection closure called only once");
|
||||||
c.complete(Err(RpcError::WsError(err)));
|
let _ = c.send(Err(RpcError::WsError(err)));
|
||||||
},
|
},
|
||||||
// c will complete on the `on_open` event in the Handler
|
// c will complete on the `on_open` event in the Handler
|
||||||
_ => ()
|
_ => ()
|
||||||
|
@ -12,11 +12,12 @@ rustc_version = "0.1"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.3.14"
|
rand = "0.3.14"
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
|
jsonrpc-server-utils = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
parity-dapps-glue = { version = "1.4", optional = true }
|
parity-dapps-glue = { version = "1.4", optional = true }
|
||||||
ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "mio-upstream-stable" }
|
ws = { git = "https://github.com/paritytech/ws-rs.git", branch = "mio-upstream-stable" }
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore-io = { path = "../util/io" }
|
ethcore-io = { path = "../util/io" }
|
||||||
ethcore-rpc = { path = "../rpc" }
|
ethcore-rpc = { path = "../rpc" }
|
||||||
|
@ -30,21 +30,23 @@
|
|||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! extern crate jsonrpc_core;
|
//! extern crate jsonrpc_core;
|
||||||
|
//! extern crate jsonrpc_server_utils;
|
||||||
//! extern crate ethcore_signer;
|
//! extern crate ethcore_signer;
|
||||||
//! extern crate ethcore_rpc;
|
//! extern crate ethcore_rpc;
|
||||||
//!
|
//!
|
||||||
//! use std::sync::Arc;
|
//! use std::sync::Arc;
|
||||||
//! use jsonrpc_core::IoHandler;
|
//! use jsonrpc_core::IoHandler;
|
||||||
//! use jsonrpc_core::reactor::RpcEventLoop;
|
//! use jsonrpc_server_utils::reactor::RpcEventLoop;
|
||||||
//! use ethcore_signer::ServerBuilder;
|
//! use ethcore_signer::ServerBuilder;
|
||||||
//! use ethcore_rpc::ConfirmationsQueue;
|
//! use ethcore_rpc::ConfirmationsQueue;
|
||||||
//!
|
//!
|
||||||
//! fn main() {
|
//! fn main() {
|
||||||
//! let queue = Arc::new(ConfirmationsQueue::default());
|
//! let queue = Arc::new(ConfirmationsQueue::default());
|
||||||
//! let io = Arc::new(IoHandler::new().into());
|
//! let io = IoHandler::default();
|
||||||
//! let event_loop = RpcEventLoop::spawn();
|
//! let event_loop = RpcEventLoop::spawn().unwrap();
|
||||||
|
//! let remote = event_loop.remote();
|
||||||
//! let _server = ServerBuilder::new(queue, "/tmp/authcodes".into())
|
//! let _server = ServerBuilder::new(queue, "/tmp/authcodes".into())
|
||||||
//! .start("127.0.0.1:8084".parse().unwrap(), event_loop.handler(io));
|
//! .start("127.0.0.1:8084".parse().unwrap(), io, remote);
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
@ -57,6 +59,7 @@ extern crate ethcore_util as util;
|
|||||||
extern crate ethcore_rpc as rpc;
|
extern crate ethcore_rpc as rpc;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
extern crate jsonrpc_core;
|
extern crate jsonrpc_core;
|
||||||
|
extern crate jsonrpc_server_utils;
|
||||||
extern crate ws;
|
extern crate ws;
|
||||||
|
|
||||||
extern crate ethcore_devtools as devtools;
|
extern crate ethcore_devtools as devtools;
|
||||||
|
@ -22,7 +22,7 @@ use devtools::RandomTempPath;
|
|||||||
|
|
||||||
use rpc::ConfirmationsQueue;
|
use rpc::ConfirmationsQueue;
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use jsonrpc_core::reactor::RpcEventLoop;
|
use jsonrpc_server_utils::reactor::RpcEventLoop;
|
||||||
use rand;
|
use rand;
|
||||||
|
|
||||||
use ServerBuilder;
|
use ServerBuilder;
|
||||||
@ -70,9 +70,10 @@ pub fn serve() -> (ServerLoop, usize, GuardedAuthCodes) {
|
|||||||
let queue = Arc::new(ConfirmationsQueue::default());
|
let queue = Arc::new(ConfirmationsQueue::default());
|
||||||
let builder = ServerBuilder::new(queue, path.to_path_buf());
|
let builder = ServerBuilder::new(queue, path.to_path_buf());
|
||||||
let port = 35000 + rand::random::<usize>() % 10000;
|
let port = 35000 + rand::random::<usize>() % 10000;
|
||||||
let event_loop = RpcEventLoop::spawn();
|
let event_loop = RpcEventLoop::spawn().unwrap();
|
||||||
let handler = event_loop.handler(Arc::new(IoHandler::default().into()));
|
let io = IoHandler::default();
|
||||||
let server = builder.start(format!("127.0.0.1:{}", port).parse().unwrap(), handler).unwrap();
|
let remote = event_loop.remote();
|
||||||
|
let server = builder.start(format!("127.0.0.1:{}", port).parse().unwrap(), io, remote).unwrap();
|
||||||
let res = ServerLoop {
|
let res = ServerLoop {
|
||||||
server: server,
|
server: server,
|
||||||
event_loop: event_loop,
|
event_loop: event_loop,
|
||||||
|
@ -26,8 +26,8 @@ use std::thread;
|
|||||||
use std;
|
use std;
|
||||||
|
|
||||||
use io::{PanicHandler, OnPanicListener, MayPanic};
|
use io::{PanicHandler, OnPanicListener, MayPanic};
|
||||||
use jsonrpc_core::{Metadata, Middleware};
|
use jsonrpc_core::{Metadata, Middleware, MetaIoHandler};
|
||||||
use jsonrpc_core::reactor::RpcHandler;
|
use jsonrpc_server_utils::tokio_core::reactor::Remote;
|
||||||
use rpc::{ConfirmationsQueue};
|
use rpc::{ConfirmationsQueue};
|
||||||
use rpc::informant::RpcStats;
|
use rpc::informant::RpcStats;
|
||||||
|
|
||||||
@ -92,21 +92,28 @@ impl ServerBuilder {
|
|||||||
|
|
||||||
/// Starts a new `WebSocket` server in separate thread.
|
/// Starts a new `WebSocket` server in separate thread.
|
||||||
/// Returns a `Server` handle which closes the server when droped.
|
/// Returns a `Server` handle which closes the server when droped.
|
||||||
pub fn start<M: Metadata, S: Middleware<M>>(self, addr: SocketAddr, handler: RpcHandler<M, S>) -> Result<Server, ServerError> {
|
pub fn start<M: Metadata, S: Middleware<M>, H: Into<MetaIoHandler<M, S>>>(
|
||||||
self.start_with_extractor(addr, handler, NoopExtractor)
|
self,
|
||||||
|
addr: SocketAddr,
|
||||||
|
handler: H,
|
||||||
|
remote: Remote,
|
||||||
|
) -> Result<Server, ServerError> {
|
||||||
|
self.start_with_extractor(addr, handler, remote, NoopExtractor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a new `WebSocket` server in separate thread.
|
/// Starts a new `WebSocket` server in separate thread.
|
||||||
/// Returns a `Server` handle which closes the server when droped.
|
/// Returns a `Server` handle which closes the server when droped.
|
||||||
pub fn start_with_extractor<M: Metadata, S: Middleware<M>, T: session::MetaExtractor<M>>(
|
pub fn start_with_extractor<M: Metadata, S: Middleware<M>, H: Into<MetaIoHandler<M, S>>, T: session::MetaExtractor<M>>(
|
||||||
self,
|
self,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
handler: RpcHandler<M, S>,
|
handler: H,
|
||||||
|
remote: Remote,
|
||||||
meta_extractor: T,
|
meta_extractor: T,
|
||||||
) -> Result<Server, ServerError> {
|
) -> Result<Server, ServerError> {
|
||||||
Server::start(
|
Server::start(
|
||||||
addr,
|
addr,
|
||||||
handler,
|
handler.into(),
|
||||||
|
remote,
|
||||||
self.queue,
|
self.queue,
|
||||||
self.authcodes_path,
|
self.authcodes_path,
|
||||||
self.skip_origin_validation,
|
self.skip_origin_validation,
|
||||||
@ -136,7 +143,8 @@ impl Server {
|
|||||||
/// Returns a `Server` handle which closes the server when droped.
|
/// Returns a `Server` handle which closes the server when droped.
|
||||||
fn start<M: Metadata, S: Middleware<M>, T: session::MetaExtractor<M>>(
|
fn start<M: Metadata, S: Middleware<M>, T: session::MetaExtractor<M>>(
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
handler: RpcHandler<M, S>,
|
handler: MetaIoHandler<M, S>,
|
||||||
|
remote: Remote,
|
||||||
queue: Arc<ConfirmationsQueue>,
|
queue: Arc<ConfirmationsQueue>,
|
||||||
authcodes_path: PathBuf,
|
authcodes_path: PathBuf,
|
||||||
skip_origin_validation: bool,
|
skip_origin_validation: bool,
|
||||||
@ -156,7 +164,7 @@ impl Server {
|
|||||||
let origin = format!("{}", addr);
|
let origin = format!("{}", addr);
|
||||||
let port = addr.port();
|
let port = addr.port();
|
||||||
let ws = ws::Builder::new().with_settings(config).build(
|
let ws = ws::Builder::new().with_settings(config).build(
|
||||||
session::Factory::new(handler, origin, port, authcodes_path, skip_origin_validation, stats, meta_extractor)
|
session::Factory::new(handler, remote, origin, port, authcodes_path, skip_origin_validation, stats, meta_extractor)
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let panic_handler = PanicHandler::new_in_arc();
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
|
@ -21,8 +21,9 @@ use std::sync::Arc;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use authcode_store::AuthCodes;
|
use authcode_store::AuthCodes;
|
||||||
use jsonrpc_core::{Metadata, Middleware};
|
use jsonrpc_core::{Metadata, Middleware, MetaIoHandler};
|
||||||
use jsonrpc_core::reactor::RpcHandler;
|
use jsonrpc_core::futures::Future;
|
||||||
|
use jsonrpc_server_utils::tokio_core::reactor::Remote;
|
||||||
use rpc::informant::RpcStats;
|
use rpc::informant::RpcStats;
|
||||||
use util::{H256, version};
|
use util::{H256, version};
|
||||||
use ws;
|
use ws;
|
||||||
@ -145,7 +146,8 @@ pub struct Session<M: Metadata, S: Middleware<M>, T> {
|
|||||||
self_origin: String,
|
self_origin: String,
|
||||||
self_port: u16,
|
self_port: u16,
|
||||||
authcodes_path: PathBuf,
|
authcodes_path: PathBuf,
|
||||||
handler: RpcHandler<M, S>,
|
handler: Arc<MetaIoHandler<M, S>>,
|
||||||
|
remote: Remote,
|
||||||
file_handler: Arc<ui::Handler>,
|
file_handler: Arc<ui::Handler>,
|
||||||
stats: Option<Arc<RpcStats>>,
|
stats: Option<Arc<RpcStats>>,
|
||||||
meta_extractor: T,
|
meta_extractor: T,
|
||||||
@ -237,7 +239,7 @@ impl<M: Metadata, S: Middleware<M>, T: MetaExtractor<M>> ws::Handler for Session
|
|||||||
// TODO [ToDr] Move to on_connect
|
// TODO [ToDr] Move to on_connect
|
||||||
let metadata = self.meta_extractor.extract_metadata(&self.session_id);
|
let metadata = self.meta_extractor.extract_metadata(&self.session_id);
|
||||||
|
|
||||||
self.handler.handle_request(req, metadata, move |response| {
|
let future = self.handler.handle_request(req, metadata).map(move |response| {
|
||||||
if let Some(result) = response {
|
if let Some(result) = response {
|
||||||
let res = out.send(result);
|
let res = out.send(result);
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
@ -245,12 +247,14 @@ impl<M: Metadata, S: Middleware<M>, T: MetaExtractor<M>> ws::Handler for Session
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
self.remote.spawn(move |_| future);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Factory<M: Metadata, S: Middleware<M>, T> {
|
pub struct Factory<M: Metadata, S: Middleware<M>, T> {
|
||||||
handler: RpcHandler<M, S>,
|
handler: Arc<MetaIoHandler<M, S>>,
|
||||||
|
remote: Remote,
|
||||||
skip_origin_validation: bool,
|
skip_origin_validation: bool,
|
||||||
self_origin: String,
|
self_origin: String,
|
||||||
self_port: u16,
|
self_port: u16,
|
||||||
@ -262,7 +266,8 @@ pub struct Factory<M: Metadata, S: Middleware<M>, T> {
|
|||||||
|
|
||||||
impl<M: Metadata, S: Middleware<M>, T> Factory<M, S, T> {
|
impl<M: Metadata, S: Middleware<M>, T> Factory<M, S, T> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
handler: RpcHandler<M, S>,
|
handler: MetaIoHandler<M, S>,
|
||||||
|
remote: Remote,
|
||||||
self_origin: String,
|
self_origin: String,
|
||||||
self_port: u16,
|
self_port: u16,
|
||||||
authcodes_path: PathBuf,
|
authcodes_path: PathBuf,
|
||||||
@ -271,7 +276,8 @@ impl<M: Metadata, S: Middleware<M>, T> Factory<M, S, T> {
|
|||||||
meta_extractor: T,
|
meta_extractor: T,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Factory {
|
Factory {
|
||||||
handler: handler,
|
handler: Arc::new(handler),
|
||||||
|
remote: remote,
|
||||||
skip_origin_validation: skip_origin_validation,
|
skip_origin_validation: skip_origin_validation,
|
||||||
self_origin: self_origin,
|
self_origin: self_origin,
|
||||||
self_port: self_port,
|
self_port: self_port,
|
||||||
@ -293,6 +299,7 @@ impl<M: Metadata, S: Middleware<M>, T: MetaExtractor<M>> ws::Factory for Factory
|
|||||||
session_id: 0.into(),
|
session_id: 0.into(),
|
||||||
out: sender,
|
out: sender,
|
||||||
handler: self.handler.clone(),
|
handler: self.handler.clone(),
|
||||||
|
remote: self.remote.clone(),
|
||||||
skip_origin_validation: self.skip_origin_validation,
|
skip_origin_validation: self.skip_origin_validation,
|
||||||
self_origin: self.self_origin.clone(),
|
self_origin: self.self_origin.clone(),
|
||||||
self_port: self.self_port,
|
self_port: self.self_port,
|
||||||
|
@ -11,10 +11,9 @@ ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
jsonrpc-macros = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
jsonrpc-tcp-server = { git = "https://github.com/ethcore/jsonrpc.git", branch = "parity-1.6" }
|
jsonrpc-tcp-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.7" }
|
||||||
mio = { git = "https://github.com/ethcore/mio", branch = "v0.5.x" }
|
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
|
@ -44,8 +44,8 @@ pub use traits::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use jsonrpc_tcp_server::{
|
use jsonrpc_tcp_server::{
|
||||||
Server as JsonRpcServer, RequestContext, MetaExtractor, Dispatcher,
|
Server as JsonRpcServer, ServerBuilder as JsonRpcServerBuilder,
|
||||||
PushMessageError
|
RequestContext, MetaExtractor, Dispatcher, PushMessageError,
|
||||||
};
|
};
|
||||||
use jsonrpc_core::{MetaIoHandler, Params, to_value, Value, Metadata, Compatibility};
|
use jsonrpc_core::{MetaIoHandler, Params, to_value, Value, Metadata, Compatibility};
|
||||||
use jsonrpc_macros::IoDelegate;
|
use jsonrpc_macros::IoDelegate;
|
||||||
@ -57,6 +57,8 @@ use util::{H256, Hashable, RwLock, RwLockReadGuard};
|
|||||||
|
|
||||||
type RpcResult = BoxFuture<jsonrpc_core::Value, jsonrpc_core::Error>;
|
type RpcResult = BoxFuture<jsonrpc_core::Value, jsonrpc_core::Error>;
|
||||||
|
|
||||||
|
const NOTIFY_COUNTER_INITIAL: u32 = 16;
|
||||||
|
|
||||||
struct StratumRpc {
|
struct StratumRpc {
|
||||||
stratum: RwLock<Option<Arc<Stratum>>>,
|
stratum: RwLock<Option<Arc<Stratum>>>,
|
||||||
}
|
}
|
||||||
@ -112,7 +114,7 @@ impl MetaExtractor<SocketMetadata> for PeerMetaExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Stratum {
|
pub struct Stratum {
|
||||||
rpc_server: JsonRpcServer<SocketMetadata>,
|
rpc_server: Option<JsonRpcServer>,
|
||||||
/// Subscribed clients
|
/// Subscribed clients
|
||||||
subscribers: RwLock<Vec<SocketAddr>>,
|
subscribers: RwLock<Vec<SocketAddr>>,
|
||||||
/// List of workers supposed to receive job update
|
/// List of workers supposed to receive job update
|
||||||
@ -129,7 +131,11 @@ pub struct Stratum {
|
|||||||
tcp_dispatcher: Dispatcher,
|
tcp_dispatcher: Dispatcher,
|
||||||
}
|
}
|
||||||
|
|
||||||
const NOTIFY_COUNTER_INITIAL: u32 = 16;
|
impl Drop for Stratum {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.rpc_server.take().map(|server| server.close());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Stratum {
|
impl Stratum {
|
||||||
pub fn start(
|
pub fn start(
|
||||||
@ -148,12 +154,14 @@ impl Stratum {
|
|||||||
let mut handler = MetaIoHandler::<SocketMetadata>::with_compatibility(Compatibility::Both);
|
let mut handler = MetaIoHandler::<SocketMetadata>::with_compatibility(Compatibility::Both);
|
||||||
handler.extend_with(delegate);
|
handler.extend_with(delegate);
|
||||||
|
|
||||||
let server = JsonRpcServer::new(addr.clone(), Arc::new(handler))
|
let server = JsonRpcServerBuilder::new(handler)
|
||||||
.extractor(Arc::new(PeerMetaExtractor) as Arc<MetaExtractor<SocketMetadata>>);
|
.session_meta_extractor(PeerMetaExtractor);
|
||||||
|
let tcp_dispatcher = server.dispatcher();
|
||||||
|
let server = server.start(addr)?;
|
||||||
|
|
||||||
let stratum = Arc::new(Stratum {
|
let stratum = Arc::new(Stratum {
|
||||||
tcp_dispatcher: server.dispatcher(),
|
tcp_dispatcher: tcp_dispatcher,
|
||||||
rpc_server: server,
|
rpc_server: Some(server),
|
||||||
subscribers: RwLock::new(Vec::new()),
|
subscribers: RwLock::new(Vec::new()),
|
||||||
job_que: RwLock::new(HashSet::new()),
|
job_que: RwLock::new(HashSet::new()),
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
@ -162,10 +170,6 @@ impl Stratum {
|
|||||||
notify_counter: RwLock::new(NOTIFY_COUNTER_INITIAL),
|
notify_counter: RwLock::new(NOTIFY_COUNTER_INITIAL),
|
||||||
});
|
});
|
||||||
*rpc.stratum.write() = Some(stratum.clone());
|
*rpc.stratum.write() = Some(stratum.clone());
|
||||||
|
|
||||||
let running_stratum = stratum.clone();
|
|
||||||
::std::thread::spawn(move || running_stratum.rpc_server.run());
|
|
||||||
|
|
||||||
Ok(stratum)
|
Ok(stratum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ use std::thread;
|
|||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use futures::{Future, IntoFuture};
|
use futures::{Future, IntoFuture};
|
||||||
use self::tokio_core::reactor::{Remote as TokioRemote, Timeout};
|
pub use tokio_core::reactor::{Remote as TokioRemote, Timeout};
|
||||||
|
|
||||||
/// Event Loop for futures.
|
/// Event Loop for futures.
|
||||||
/// Wrapper around `tokio::reactor::Core`.
|
/// Wrapper around `tokio::reactor::Core`.
|
||||||
@ -47,7 +47,7 @@ impl EventLoop {
|
|||||||
let remote = rx.recv().expect("tx is transfered to a newly spawned thread.");
|
let remote = rx.recv().expect("tx is transfered to a newly spawned thread.");
|
||||||
|
|
||||||
EventLoop {
|
EventLoop {
|
||||||
remote: Remote{
|
remote: Remote {
|
||||||
inner: Mode::Tokio(remote),
|
inner: Mode::Tokio(remote),
|
||||||
},
|
},
|
||||||
handle: EventLoopHandle {
|
handle: EventLoopHandle {
|
||||||
@ -190,7 +190,7 @@ impl From<EventLoop> for EventLoopHandle {
|
|||||||
|
|
||||||
impl Drop for EventLoopHandle {
|
impl Drop for EventLoopHandle {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.close.take().map(|v| v.complete(()));
|
self.close.take().map(|v| v.send(()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +203,8 @@ impl EventLoopHandle {
|
|||||||
|
|
||||||
/// Finishes this event loop.
|
/// Finishes this event loop.
|
||||||
pub fn close(mut self) {
|
pub fn close(mut self) {
|
||||||
self.close.take()
|
let _ = self.close.take()
|
||||||
.expect("Close is taken only in `close` and `drop`. `close` is consuming; qed").complete(())
|
.expect("Close is taken only in `close` and `drop`. `close` is consuming; qed")
|
||||||
|
.send(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user