Merge remote-tracking branch 'origin/master' into dapps-accounts-rpc
This commit is contained in:
commit
d455ac4a40
99
Cargo.lock
generated
99
Cargo.lock
generated
@ -3,6 +3,7 @@ name = "parity"
|
||||
version = "1.5.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"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)",
|
||||
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -42,7 +43,7 @@ dependencies = [
|
||||
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -58,6 +59,17 @@ name = "ansi_term"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "app_dirs"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.3.16"
|
||||
@ -196,7 +208,7 @@ source = "git+https://github.com/ethcore/rust-ctrlc.git#f4927770f89eca80ec250911
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -277,7 +289,7 @@ name = "ethash"
|
||||
version = "1.5.0"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha3 0.1.0",
|
||||
]
|
||||
@ -395,7 +407,7 @@ dependencies = [
|
||||
"crossbeam 0.2.9 (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 (git+https://github.com/ethcore/mio)",
|
||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -500,7 +512,7 @@ dependencies = [
|
||||
"libc 0.2.16 (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 (git+https://github.com/ethcore/mio)",
|
||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 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)",
|
||||
"rlp 0.1.0",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -597,7 +609,7 @@ dependencies = [
|
||||
"libc 0.2.16 (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)",
|
||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 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)",
|
||||
"regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.1.0",
|
||||
@ -659,7 +671,7 @@ dependencies = [
|
||||
"itertools 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 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)",
|
||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -688,7 +700,7 @@ dependencies = [
|
||||
"ethkey 0.2.0",
|
||||
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 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)",
|
||||
"rlp 0.1.0",
|
||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -845,7 +857,7 @@ 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)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -864,7 +876,7 @@ version = "4.0.0"
|
||||
source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec331058ba65e224a"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -925,7 +937,7 @@ name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1026,7 +1038,7 @@ dependencies = [
|
||||
"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.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1042,7 +1054,7 @@ dependencies = [
|
||||
"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.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1057,7 +1069,7 @@ dependencies = [
|
||||
"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)",
|
||||
"slab 0.2.0 (git+https://github.com/carllerche/slab?rev=5476efcafb)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1073,7 +1085,7 @@ dependencies = [
|
||||
"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)",
|
||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1083,7 +1095,7 @@ 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.6 (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)",
|
||||
]
|
||||
|
||||
@ -1094,7 +1106,7 @@ 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)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1123,7 +1135,7 @@ dependencies = [
|
||||
"cfg-if 0.1.0 (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.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (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)",
|
||||
]
|
||||
|
||||
@ -1262,6 +1274,15 @@ name = "odds"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ole32-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.2.2"
|
||||
@ -1300,14 +1321,14 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git#175003ae159b126302fd1a90dd875dc86d7adba0"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git#762c6d10f8640a6c4b875d776490282680bfe3e2"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1323,7 +1344,7 @@ dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1546,7 +1567,7 @@ dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1650,6 +1671,15 @@ dependencies = [
|
||||
"gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell32-sys"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.1.1"
|
||||
@ -1785,7 +1815,7 @@ version = "0.2.14"
|
||||
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)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1794,7 +1824,7 @@ version = "0.4.4"
|
||||
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)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1829,7 +1859,7 @@ 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)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1925,7 +1955,7 @@ name = "vecio"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.6 (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)",
|
||||
]
|
||||
|
||||
@ -1956,7 +1986,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.6"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -1984,10 +2014,15 @@ name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xdg"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.3.4"
|
||||
@ -2018,6 +2053,7 @@ dependencies = [
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67077478f0a03952bed2e6786338d400d40c25e9836e08ad50af96607317fd03"
|
||||
"checksum ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f46cd5b1d660c938e3f92dfe7a73d832b3281479363dd0cd9c1c2fbf60f7962"
|
||||
"checksum app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7d1c0d48a81bbb13043847f957971f4d87c81542d80ece5e84ba3cba4058fd4"
|
||||
"checksum arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "16e3bdb2f54b3ace0285975d59a97cf8ed3855294b2b6bc651fcf22a9c352975"
|
||||
"checksum aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07d344974f0a155f091948aa389fb1b912d3a58414fbdb9c8d446d193ee3496a"
|
||||
"checksum aster 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4df293303e8a52e1df7984ac1415e195f5fcbf51e4bb7bda54557861a3954a08"
|
||||
@ -2104,10 +2140,11 @@ dependencies = [
|
||||
"checksum num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "51fedae97a05f7353612fe017ab705a37e6db8f4d67c5c6fe739a9e70d6eed09"
|
||||
"checksum number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "084d05f4bf60621a9ac9bde941a410df548f4de9545f06e5ee9d3aef4b97cd77"
|
||||
"checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1"
|
||||
"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c"
|
||||
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
|
||||
"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
|
||||
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "<none>"
|
||||
"checksum parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc5847584161f273e69edc63c1a86254a22f570a0b5dd87aa6f9773f6f7d125"
|
||||
"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621"
|
||||
"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
|
||||
"checksum phf 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "447d9d45f2e0b4a9b532e808365abf18fc211be6ca217202fcd45236ef12f026"
|
||||
"checksum phf_codegen 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8af7ae7c3f75a502292b491e5cc0a1f69e3407744abe6e57e2a3b712bb82f01d"
|
||||
@ -2145,6 +2182,7 @@ dependencies = [
|
||||
"checksum serde_codegen_internals 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f877e2781ed0a323295d1c9f0e26556117b5a11489fc47b1848dfb98b3173d21"
|
||||
"checksum serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e10f8a9d94b06cf5d3bef66475f04c8ff90950f1be7004c357ff9472ccbaebc"
|
||||
"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 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>"
|
||||
@ -2185,10 +2223,11 @@ dependencies = [
|
||||
"checksum vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56b639f935488eb40f06d17c3e3bcc3054f6f75d264e187b1107c8d1cba8d31c"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum webpki 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "813503a5985585e0812d430cd1328ee322f47f66629c8ed4ecab939cf9e92f91"
|
||||
"checksum winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfaaa8fbdaa618fa6914b59b2769d690dd7521920a18d84b42d254678dd5fd4"
|
||||
"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 ws 0.5.3 (git+https://github.com/ethcore/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 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 xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "472a9d37c7c53ab2391161df5b89b1f3bf76dab6ab150d7941ecbdd832282082"
|
||||
"checksum zip 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "3ceb33a75b3d0608942302eed325b59d2c3ed777cc6c01627ae14e5697c6a31c"
|
||||
|
@ -28,6 +28,7 @@ isatty = "0.1"
|
||||
toml = "0.2"
|
||||
serde = "0.8.0"
|
||||
serde_json = "0.8.0"
|
||||
app_dirs = "1.1.1"
|
||||
hyper = { version = "0.9", default-features = false }
|
||||
ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" }
|
||||
fdlimit = "0.1"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Ethereum Classic",
|
||||
"forkName": "classic",
|
||||
"dataDir": "classic",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Expanse",
|
||||
"forkName": "expanse",
|
||||
"dataDir": "expanse",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "Frontier/Homestead",
|
||||
"dataDir": "ethereum",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "Morden",
|
||||
"dataDir": "test",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "Ropsten",
|
||||
"dataDir": "test",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
|
@ -90,6 +90,8 @@ pub struct TestBlockChainClient {
|
||||
pub ancient_block: RwLock<Option<(H256, u64)>>,
|
||||
/// First block info.
|
||||
pub first_block: RwLock<Option<(H256, u64)>>,
|
||||
/// Traces to return
|
||||
pub traces: RwLock<Option<Vec<LocalizedTrace>>>,
|
||||
}
|
||||
|
||||
/// Used for generating test client blocks.
|
||||
@ -151,6 +153,7 @@ impl TestBlockChainClient {
|
||||
latest_block_timestamp: RwLock::new(10_000_000),
|
||||
ancient_block: RwLock::new(None),
|
||||
first_block: RwLock::new(None),
|
||||
traces: RwLock::new(None),
|
||||
};
|
||||
client.add_blocks(1, EachBlockWith::Nothing); // add genesis block
|
||||
client.genesis_hash = client.last_hash.read().clone();
|
||||
@ -654,19 +657,19 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
}
|
||||
|
||||
fn filter_traces(&self, _filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
|
||||
unimplemented!();
|
||||
self.traces.read().clone()
|
||||
}
|
||||
|
||||
fn trace(&self, _trace: TraceId) -> Option<LocalizedTrace> {
|
||||
unimplemented!();
|
||||
self.traces.read().clone().and_then(|vec| vec.into_iter().next())
|
||||
}
|
||||
|
||||
fn transaction_traces(&self, _trace: TransactionId) -> Option<Vec<LocalizedTrace>> {
|
||||
unimplemented!();
|
||||
self.traces.read().clone()
|
||||
}
|
||||
|
||||
fn block_traces(&self, _trace: BlockId) -> Option<Vec<LocalizedTrace>> {
|
||||
unimplemented!();
|
||||
self.traces.read().clone()
|
||||
}
|
||||
|
||||
fn queue_transactions(&self, transactions: Vec<Bytes>, _peer_id: usize) {
|
||||
|
@ -661,10 +661,10 @@ mod tests {
|
||||
use block::*;
|
||||
use error::{Error, BlockError};
|
||||
use header::Header;
|
||||
use io::IoChannel;
|
||||
use env_info::EnvInfo;
|
||||
use tests::helpers::*;
|
||||
use account_provider::AccountProvider;
|
||||
use io::IoService;
|
||||
use service::ClientIoMessage;
|
||||
use spec::Spec;
|
||||
use engines::{Engine, EngineError, Seal};
|
||||
@ -904,10 +904,9 @@ mod tests {
|
||||
let proposal = Some(b.header().bare_hash());
|
||||
|
||||
// Register IoHandler remembers messages.
|
||||
let io_service = IoService::<ClientIoMessage>::start().unwrap();
|
||||
let test_io = TestIo::new();
|
||||
io_service.register_handler(test_io.clone()).unwrap();
|
||||
engine.register_message_channel(io_service.channel());
|
||||
let channel = IoChannel::to_handler(Arc::downgrade(&(test_io.clone() as Arc<IoHandler<ClientIoMessage>>)));
|
||||
engine.register_message_channel(channel);
|
||||
|
||||
let prevote_current = vote(&engine, |mh| tap.sign(v0, None, mh).map(H520::from), h, r, Step::Prevote, proposal);
|
||||
|
||||
@ -915,9 +914,6 @@ mod tests {
|
||||
|
||||
let prevote_future = vote(&engine, |mh| tap.sign(v0, None, mh).map(H520::from), h + 1, r, Step::Prevote, proposal);
|
||||
|
||||
// Wait a bit for async stuff.
|
||||
::std::thread::sleep(::std::time::Duration::from_millis(500));
|
||||
|
||||
// Relays all valid present and future messages.
|
||||
assert!(test_io.received.read().contains(&ClientIoMessage::BroadcastMessage(prevote_current)));
|
||||
assert!(test_io.received.read().contains(&ClientIoMessage::BroadcastMessage(precommit_current)));
|
||||
@ -941,9 +937,8 @@ mod tests {
|
||||
|
||||
// Register IoHandler remembers messages.
|
||||
let test_io = TestIo::new();
|
||||
let io_service = IoService::<ClientIoMessage>::start().unwrap();
|
||||
io_service.register_handler(test_io.clone()).unwrap();
|
||||
engine.register_message_channel(io_service.channel());
|
||||
let channel = IoChannel::to_handler(Arc::downgrade(&(test_io.clone() as Arc<IoHandler<ClientIoMessage>>)));
|
||||
engine.register_message_channel(channel);
|
||||
|
||||
// Propose
|
||||
let (b, mut seal) = propose_default(&spec, v1.clone());
|
||||
@ -956,11 +951,12 @@ mod tests {
|
||||
vote(&engine, |mh| tap.sign(v1, None, mh).map(H520::from), h, r, Step::Precommit, proposal);
|
||||
vote(&engine, |mh| tap.sign(v0, None, mh).map(H520::from), h, r, Step::Precommit, proposal);
|
||||
|
||||
// Wait a bit for async stuff.
|
||||
::std::thread::sleep(::std::time::Duration::from_millis(500));
|
||||
|
||||
seal[2] = precommit_signatures(&tap, h, r, Some(b.header().bare_hash()), v1, v0);
|
||||
assert!(test_io.received.read().contains(&ClientIoMessage::SubmitSeal(proposal.unwrap(), seal)));
|
||||
let first = test_io.received.read().contains(&ClientIoMessage::SubmitSeal(proposal.unwrap(), seal.clone()));
|
||||
seal[2] = precommit_signatures(&tap, h, r, Some(b.header().bare_hash()), v0, v1);
|
||||
let second = test_io.received.read().contains(&ClientIoMessage::SubmitSeal(proposal.unwrap(), seal));
|
||||
|
||||
assert!(first ^ second);
|
||||
engine.stop();
|
||||
}
|
||||
}
|
||||
|
@ -81,9 +81,6 @@ impl ClientService {
|
||||
panic_handler.forward_from(&io_service);
|
||||
|
||||
info!("Configured for {} using {} engine", Colour::White.bold().paint(spec.name.clone()), Colour::Yellow.bold().paint(spec.engine.name()));
|
||||
if spec.fork_name.is_some() {
|
||||
warn!("Your chain is an alternative fork. {}", Colour::Red.bold().paint("TRANSACTIONS MAY BE REPLAYED ON THE MAINNET!"));
|
||||
}
|
||||
|
||||
let mut db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS);
|
||||
|
||||
|
@ -66,8 +66,8 @@ pub struct Spec {
|
||||
pub name: String,
|
||||
/// What engine are we using for this?
|
||||
pub engine: Arc<Engine>,
|
||||
/// The fork identifier for this chain. Only needed to distinguish two chains sharing the same genesis.
|
||||
pub fork_name: Option<String>,
|
||||
/// Name of the subdir inside the main data dir to use for chain data and settings.
|
||||
pub data_dir: String,
|
||||
|
||||
/// Known nodes on the network in enode format.
|
||||
pub nodes: Vec<String>,
|
||||
@ -110,10 +110,10 @@ impl From<ethjson::spec::Spec> for Spec {
|
||||
let GenericSeal(seal_rlp) = g.seal.into();
|
||||
let params = CommonParams::from(s.params);
|
||||
Spec {
|
||||
name: s.name.into(),
|
||||
name: s.name.clone().into(),
|
||||
params: params.clone(),
|
||||
engine: Spec::engine(s.engine, params, builtins),
|
||||
fork_name: s.fork_name.map(Into::into),
|
||||
data_dir: s.data_dir.unwrap_or(s.name).into(),
|
||||
nodes: s.nodes.unwrap_or_else(Vec::new),
|
||||
parent_hash: g.parent_hash,
|
||||
transactions_root: g.transactions_root,
|
||||
|
@ -21,7 +21,7 @@ use super::trace::{Action, Res};
|
||||
use header::BlockNumber;
|
||||
|
||||
/// Localized trace.
|
||||
#[derive(Debug, PartialEq, Binary)]
|
||||
#[derive(Debug, PartialEq, Clone, Binary)]
|
||||
pub struct LocalizedTrace {
|
||||
/// Type of action performed by a transaction.
|
||||
pub action: Action,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "parity.js",
|
||||
"version": "0.2.122",
|
||||
"version": "0.2.124",
|
||||
"main": "release/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"author": "Parity Team <admin@parity.io>",
|
||||
|
@ -18,7 +18,8 @@ import { bytesToHex, hex2Ascii } from '~/api/util/format';
|
||||
|
||||
import ABI from './abi/certifier.json';
|
||||
|
||||
const ZERO = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||
const ZERO20 = '0x0000000000000000000000000000000000000000';
|
||||
const ZERO32 = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||
|
||||
export default class BadgeReg {
|
||||
constructor (api, registry) {
|
||||
@ -26,32 +27,57 @@ export default class BadgeReg {
|
||||
this._registry = registry;
|
||||
|
||||
registry.getContract('badgereg');
|
||||
this.certifiers = {}; // by name
|
||||
this.certifiers = []; // by id
|
||||
this.contracts = {}; // by name
|
||||
}
|
||||
|
||||
fetchCertifier (name) {
|
||||
if (this.certifiers[name]) {
|
||||
return Promise.resolve(this.certifiers[name]);
|
||||
certifierCount () {
|
||||
return this._registry.getContract('badgereg')
|
||||
.then((badgeReg) => {
|
||||
return badgeReg.instance.badgeCount.call({}, [])
|
||||
.then((count) => count.valueOf());
|
||||
});
|
||||
}
|
||||
|
||||
fetchCertifier (id) {
|
||||
if (this.certifiers[id]) {
|
||||
return Promise.resolve(this.certifiers[id]);
|
||||
}
|
||||
return this._registry.getContract('badgereg')
|
||||
.then((badgeReg) => {
|
||||
return badgeReg.instance.fromName.call({}, [name])
|
||||
.then(([ id, address ]) => {
|
||||
return Promise.all([
|
||||
badgeReg.instance.meta.call({}, [id, 'TITLE']),
|
||||
badgeReg.instance.meta.call({}, [id, 'IMG'])
|
||||
])
|
||||
.then(([ title, img ]) => {
|
||||
title = bytesToHex(title);
|
||||
title = title === ZERO ? null : hex2Ascii(title);
|
||||
if (bytesToHex(img) === ZERO) img = null;
|
||||
return badgeReg.instance.badge.call({}, [ id ]);
|
||||
})
|
||||
.then(([ address, name ]) => {
|
||||
if (address === ZERO20) {
|
||||
throw new Error(`Certifier ${id} does not exist.`);
|
||||
}
|
||||
|
||||
const data = { address, name, title, icon: img };
|
||||
this.certifiers[name] = data;
|
||||
return data;
|
||||
});
|
||||
});
|
||||
name = bytesToHex(name);
|
||||
name = name === ZERO32
|
||||
? null
|
||||
: hex2Ascii(name);
|
||||
return this.fetchMeta(id)
|
||||
.then(({ title, icon }) => {
|
||||
const data = { address, id, name, title, icon };
|
||||
this.certifiers[id] = data;
|
||||
return data;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fetchMeta (id) {
|
||||
return this._registry.getContract('badgereg')
|
||||
.then((badgeReg) => {
|
||||
return Promise.all([
|
||||
badgeReg.instance.meta.call({}, [id, 'TITLE']),
|
||||
badgeReg.instance.meta.call({}, [id, 'IMG'])
|
||||
]);
|
||||
})
|
||||
.then(([ title, icon ]) => {
|
||||
title = bytesToHex(title);
|
||||
title = title === ZERO32 ? null : hex2Ascii(title);
|
||||
if (bytesToHex(icon) === ZERO32) icon = null;
|
||||
return { title, icon };
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import ActionDone from 'material-ui/svg-icons/action/done';
|
||||
import ActionDoneAll from 'material-ui/svg-icons/action/done-all';
|
||||
import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward';
|
||||
@ -35,14 +36,15 @@ import ParityLogo from '../../../assets/images/parity-logo-black-no-text.svg';
|
||||
|
||||
const STAGE_NAMES = ['welcome', 'terms', 'new account', 'recovery', 'completed'];
|
||||
|
||||
export default class FirstRun extends Component {
|
||||
class FirstRun extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired,
|
||||
store: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
visible: PropTypes.bool,
|
||||
hasAccounts: PropTypes.bool.isRequired,
|
||||
visible: PropTypes.bool.isRequired,
|
||||
onClose: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
@ -109,6 +111,7 @@ export default class FirstRun extends Component {
|
||||
}
|
||||
|
||||
renderDialogActions () {
|
||||
const { hasAccounts } = this.props;
|
||||
const { canCreate, stage, hasAcceptedTnc } = this.state;
|
||||
|
||||
switch (stage) {
|
||||
@ -130,13 +133,26 @@ export default class FirstRun extends Component {
|
||||
);
|
||||
|
||||
case 2:
|
||||
return (
|
||||
const buttons = [
|
||||
<Button
|
||||
icon={ <ActionDone /> }
|
||||
label='Create'
|
||||
key='create'
|
||||
disabled={ !canCreate }
|
||||
onClick={ this.onCreate } />
|
||||
);
|
||||
onClick={ this.onCreate }
|
||||
/>
|
||||
];
|
||||
if (hasAccounts) {
|
||||
buttons.unshift(
|
||||
<Button
|
||||
icon={ <NavigationArrowForward /> }
|
||||
label='Skip'
|
||||
key='skip'
|
||||
onClick={ this.skipAccountCreation }
|
||||
/>
|
||||
);
|
||||
}
|
||||
return buttons;
|
||||
|
||||
case 3:
|
||||
return [
|
||||
@ -219,6 +235,10 @@ export default class FirstRun extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
skipAccountCreation = () => {
|
||||
this.setState({ stage: this.state.stage + 2 });
|
||||
}
|
||||
|
||||
newError = (error) => {
|
||||
const { store } = this.context;
|
||||
|
||||
@ -232,3 +252,9 @@ export default class FirstRun extends Component {
|
||||
print(recoveryPage({ phrase, name, identity, address, logo: ParityLogo }));
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return { hasAccounts: state.personal.hasAccounts };
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(FirstRun);
|
||||
|
@ -14,10 +14,18 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export const fetchCertifiers = () => ({
|
||||
type: 'fetchCertifiers'
|
||||
});
|
||||
|
||||
export const fetchCertifications = (address) => ({
|
||||
type: 'fetchCertifications', address
|
||||
});
|
||||
|
||||
export const addCertification = (address, name, title, icon) => ({
|
||||
type: 'addCertification', address, name, title, icon
|
||||
export const addCertification = (address, id, name, title, icon) => ({
|
||||
type: 'addCertification', address, id, name, title, icon
|
||||
});
|
||||
|
||||
export const removeCertification = (address, id) => ({
|
||||
type: 'removeCertification', address, id
|
||||
});
|
||||
|
@ -14,38 +14,90 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import Contracts from '~/contracts';
|
||||
import { addCertification } from './actions';
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
const knownCertifiers = [ 'smsverification' ];
|
||||
import ABI from '~/contracts/abi/certifier.json';
|
||||
import Contract from '~/api/contract';
|
||||
import Contracts from '~/contracts';
|
||||
import { addCertification, removeCertification } from './actions';
|
||||
|
||||
export default class CertificationsMiddleware {
|
||||
toMiddleware () {
|
||||
return (store) => (next) => (action) => {
|
||||
if (action.type !== 'fetchCertifications') {
|
||||
return next(action);
|
||||
}
|
||||
const api = Contracts.get()._api;
|
||||
const badgeReg = Contracts.get().badgeReg;
|
||||
const contract = new Contract(api, ABI);
|
||||
const Confirmed = contract.events.find((e) => e.name === 'Confirmed');
|
||||
const Revoked = contract.events.find((e) => e.name === 'Revoked');
|
||||
|
||||
const { address } = action;
|
||||
const badgeReg = Contracts.get().badgeReg;
|
||||
let certifiers = [];
|
||||
let accounts = []; // these are addresses
|
||||
|
||||
knownCertifiers.forEach((name) => {
|
||||
badgeReg.fetchCertifier(name)
|
||||
.then((cert) => {
|
||||
return badgeReg.checkIfCertified(cert.address, address)
|
||||
.then((isCertified) => {
|
||||
if (isCertified) {
|
||||
const { name, title, icon } = cert;
|
||||
store.dispatch(addCertification(address, name, title, icon));
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err) {
|
||||
console.error(`Failed to check if ${address} certified by ${name}:`, err);
|
||||
const fetchConfirmedEvents = (dispatch) => {
|
||||
if (certifiers.length === 0 || accounts.length === 0) return;
|
||||
api.eth.getLogs({
|
||||
fromBlock: 0,
|
||||
toBlock: 'latest',
|
||||
address: certifiers.map((c) => c.address),
|
||||
topics: [ [ Confirmed.signature, Revoked.signature ], accounts ]
|
||||
})
|
||||
.then((logs) => contract.parseEventLogs(logs))
|
||||
.then((logs) => {
|
||||
logs.forEach((log) => {
|
||||
const certifier = certifiers.find((c) => c.address === log.address);
|
||||
if (!certifier) {
|
||||
throw new Error(`Could not find certifier at ${log.address}.`);
|
||||
}
|
||||
const { id, name, title, icon } = certifier;
|
||||
|
||||
if (log.event === 'Revoked') {
|
||||
dispatch(removeCertification(log.params.who.value, id));
|
||||
} else {
|
||||
dispatch(addCertification(log.params.who.value, id, name, title, icon));
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to fetch Confirmed events:', err);
|
||||
});
|
||||
};
|
||||
|
||||
return (store) => (next) => (action) => {
|
||||
switch (action.type) {
|
||||
case 'fetchCertifiers':
|
||||
badgeReg.certifierCount().then((count) => {
|
||||
new Array(+count).fill(null).forEach((_, id) => {
|
||||
badgeReg.fetchCertifier(id)
|
||||
.then((cert) => {
|
||||
if (!certifiers.some((c) => c.id === cert.id)) {
|
||||
certifiers = certifiers.concat(cert);
|
||||
fetchConfirmedEvents(store.dispatch);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.warn(`Could not fetch certifier ${id}:`, err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
case 'fetchCertifications':
|
||||
const { address } = action;
|
||||
|
||||
if (!accounts.includes(address)) {
|
||||
accounts = accounts.concat(address);
|
||||
fetchConfirmedEvents(store.dispatch);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'setVisibleAccounts':
|
||||
const { addresses } = action;
|
||||
accounts = uniq(accounts.concat(addresses));
|
||||
fetchConfirmedEvents(store.dispatch);
|
||||
|
||||
break;
|
||||
default:
|
||||
next(action);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -17,17 +17,27 @@
|
||||
const initialState = {};
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
if (action.type !== 'addCertification') {
|
||||
return state;
|
||||
if (action.type === 'addCertification') {
|
||||
const { address, id, name, icon, title } = action;
|
||||
const certifications = state[address] || [];
|
||||
|
||||
if (certifications.some((c) => c.id === id)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const newCertifications = certifications.concat({
|
||||
id, name, icon, title
|
||||
});
|
||||
return { ...state, [address]: newCertifications };
|
||||
}
|
||||
|
||||
const { address, name, icon, title } = action;
|
||||
const certifications = state[address] || [];
|
||||
if (action.type === 'removeCertification') {
|
||||
const { address, id } = action;
|
||||
const certifications = state[address] || [];
|
||||
|
||||
if (certifications.some((c) => c.name === name)) {
|
||||
return state;
|
||||
const newCertifications = certifications.filter((c) => c.id !== id);
|
||||
return { ...state, [address]: newCertifications };
|
||||
}
|
||||
const newCertifications = certifications.concat({ name, icon, title });
|
||||
|
||||
return { ...state, [address]: newCertifications };
|
||||
return state;
|
||||
};
|
||||
|
@ -16,10 +16,8 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { hashToImageUrl } from '~/redux/providers/imagesReducer';
|
||||
import { fetchCertifications } from '~/redux/providers/certifications/actions';
|
||||
|
||||
import defaultIcon from '../../../assets/images/certifications/unknown.svg';
|
||||
|
||||
@ -29,14 +27,7 @@ class Certifications extends Component {
|
||||
static propTypes = {
|
||||
account: PropTypes.string.isRequired,
|
||||
certifications: PropTypes.array.isRequired,
|
||||
dappsUrl: PropTypes.string.isRequired,
|
||||
|
||||
fetchCertifications: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
const { account, fetchCertifications } = this.props;
|
||||
fetchCertifications(account);
|
||||
dappsUrl: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -73,15 +64,13 @@ function mapStateToProps (_, initProps) {
|
||||
|
||||
return (state) => {
|
||||
const certifications = state.certifications[account] || [];
|
||||
return { certifications };
|
||||
};
|
||||
}
|
||||
const dappsUrl = state.api.dappsUrl;
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ fetchCertifications }, dispatch);
|
||||
return { certifications, dappsUrl };
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
null
|
||||
)(Certifications);
|
||||
|
@ -23,10 +23,6 @@ import Certifications from '~/ui/Certifications';
|
||||
import styles from './header.css';
|
||||
|
||||
export default class Header extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
account: PropTypes.object,
|
||||
balance: PropTypes.object,
|
||||
@ -44,7 +40,6 @@ export default class Header extends Component {
|
||||
};
|
||||
|
||||
render () {
|
||||
const { api } = this.context;
|
||||
const { account, balance, className, children, hideName } = this.props;
|
||||
const { address, meta, uuid } = account;
|
||||
|
||||
@ -85,7 +80,6 @@ export default class Header extends Component {
|
||||
balance={ balance } />
|
||||
<Certifications
|
||||
account={ account.address }
|
||||
dappsUrl={ api.dappsUrl }
|
||||
/>
|
||||
</div>
|
||||
{ children }
|
||||
|
@ -31,6 +31,7 @@ import shapeshiftBtn from '~/../assets/images/shapeshift-btn.png';
|
||||
import Header from './Header';
|
||||
import Transactions from './Transactions';
|
||||
import { setVisibleAccounts } from '~/redux/providers/personalActions';
|
||||
import { fetchCertifiers, fetchCertifications } from '~/redux/providers/certifications/actions';
|
||||
|
||||
import SMSVerificationStore from '~/modals/Verification/sms-store';
|
||||
import EmailVerificationStore from '~/modals/Verification/email-store';
|
||||
@ -44,6 +45,8 @@ class Account extends Component {
|
||||
|
||||
static propTypes = {
|
||||
setVisibleAccounts: PropTypes.func.isRequired,
|
||||
fetchCertifiers: PropTypes.func.isRequired,
|
||||
fetchCertifications: PropTypes.func.isRequired,
|
||||
images: PropTypes.object.isRequired,
|
||||
|
||||
params: PropTypes.object,
|
||||
@ -63,6 +66,7 @@ class Account extends Component {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.props.fetchCertifiers();
|
||||
this.setVisibleAccounts();
|
||||
}
|
||||
|
||||
@ -80,9 +84,10 @@ class Account extends Component {
|
||||
}
|
||||
|
||||
setVisibleAccounts (props = this.props) {
|
||||
const { params, setVisibleAccounts } = props;
|
||||
const { params, setVisibleAccounts, fetchCertifications } = props;
|
||||
const addresses = [ params.address ];
|
||||
setVisibleAccounts(addresses);
|
||||
fetchCertifications(params.address);
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -353,7 +358,9 @@ function mapStateToProps (state) {
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({
|
||||
setVisibleAccounts
|
||||
setVisibleAccounts,
|
||||
fetchCertifiers,
|
||||
fetchCertifications
|
||||
}, dispatch);
|
||||
}
|
||||
|
||||
|
@ -15,22 +15,29 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { Container } from '~/ui';
|
||||
import { fetchCertifiers, fetchCertifications } from '~/redux/providers/certifications/actions';
|
||||
|
||||
import Summary from '../Summary';
|
||||
import styles from './list.css';
|
||||
|
||||
export default class List extends Component {
|
||||
class List extends Component {
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object,
|
||||
walletsOwners: PropTypes.object,
|
||||
balances: PropTypes.object,
|
||||
link: PropTypes.string,
|
||||
search: PropTypes.array,
|
||||
certifications: PropTypes.object.isRequired,
|
||||
empty: PropTypes.bool,
|
||||
link: PropTypes.string,
|
||||
order: PropTypes.string,
|
||||
orderFallback: PropTypes.string,
|
||||
search: PropTypes.array,
|
||||
walletsOwners: PropTypes.object,
|
||||
|
||||
fetchCertifiers: PropTypes.func.isRequired,
|
||||
fetchCertifications: PropTypes.func.isRequired,
|
||||
handleAddSearchToken: PropTypes.func
|
||||
};
|
||||
|
||||
@ -42,8 +49,16 @@ export default class List extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
const { accounts, fetchCertifiers, fetchCertifications } = this.props;
|
||||
fetchCertifiers();
|
||||
for (let address in accounts) {
|
||||
fetchCertifications(address);
|
||||
}
|
||||
}
|
||||
|
||||
renderAccounts () {
|
||||
const { accounts, balances, link, empty, handleAddSearchToken, walletsOwners } = this.props;
|
||||
const { accounts, balances, empty, link, walletsOwners, handleAddSearchToken } = this.props;
|
||||
|
||||
if (empty) {
|
||||
return (
|
||||
@ -72,7 +87,9 @@ export default class List extends Component {
|
||||
account={ account }
|
||||
balance={ balance }
|
||||
owners={ owners }
|
||||
handleAddSearchToken={ handleAddSearchToken } />
|
||||
handleAddSearchToken={ handleAddSearchToken }
|
||||
showCertifications
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@ -207,3 +224,20 @@ export default class List extends Component {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { certifications } = state;
|
||||
return { certifications };
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({
|
||||
fetchCertifiers,
|
||||
fetchCertifications
|
||||
}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(List);
|
||||
|
@ -21,6 +21,7 @@ import { isEqual } from 'lodash';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
|
||||
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags, Input } from '~/ui';
|
||||
import Certifications from '~/ui/Certifications';
|
||||
import { nullableProptype } from '~/util/proptypes';
|
||||
|
||||
import styles from '../accounts.css';
|
||||
@ -36,12 +37,14 @@ export default class Summary extends Component {
|
||||
link: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
noLink: PropTypes.bool,
|
||||
showCertifications: PropTypes.bool,
|
||||
handleAddSearchToken: PropTypes.func,
|
||||
owners: nullableProptype(PropTypes.array)
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
noLink: false
|
||||
noLink: false,
|
||||
showCertifications: false
|
||||
};
|
||||
|
||||
shouldComponentUpdate (nextProps) {
|
||||
@ -115,6 +118,7 @@ export default class Summary extends Component {
|
||||
|
||||
{ this.renderOwners() }
|
||||
{ this.renderBalance() }
|
||||
{ this.renderCertifications() }
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@ -181,4 +185,15 @@ export default class Summary extends Component {
|
||||
<Balance balance={ balance } />
|
||||
);
|
||||
}
|
||||
|
||||
renderCertifications () {
|
||||
const { showCertifications, account } = this.props;
|
||||
if (!showCertifications) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Certifications account={ account.address } />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,17 @@
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
|
||||
const showFirstRun = window.localStorage.getItem('showFirstRun') !== '0';
|
||||
|
||||
export default class Store {
|
||||
@observable firstrunVisible = showFirstRun;
|
||||
@observable firstrunVisible = false;
|
||||
|
||||
constructor (api) {
|
||||
this._api = api;
|
||||
|
||||
const value = window.localStorage.getItem('showFirstRun');
|
||||
if (value) {
|
||||
this.firstrunVisible = JSON.parse(value);
|
||||
}
|
||||
|
||||
this._checkAccounts();
|
||||
}
|
||||
|
||||
@ -33,7 +36,7 @@ export default class Store {
|
||||
|
||||
@action toggleFirstrun = (visible = false) => {
|
||||
this.firstrunVisible = visible;
|
||||
window.localStorage.setItem('showFirstRun', visible ? '1' : '0');
|
||||
window.localStorage.setItem('showFirstRun', JSON.stringify(!!visible));
|
||||
}
|
||||
|
||||
_checkAccounts () {
|
||||
|
@ -27,8 +27,8 @@ pub struct Spec {
|
||||
/// Spec name.
|
||||
pub name: String,
|
||||
/// Special fork name.
|
||||
#[serde(rename="forkName")]
|
||||
pub fork_name: Option<String>,
|
||||
#[serde(rename="dataDir")]
|
||||
pub data_dir: Option<String>,
|
||||
/// Engine.
|
||||
pub engine: Engine,
|
||||
/// Spec params.
|
||||
@ -57,6 +57,7 @@ mod tests {
|
||||
fn spec_deserialization() {
|
||||
let s = r#"{
|
||||
"name": "Morden",
|
||||
"dataDir": "morden",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
|
@ -14,23 +14,32 @@
|
||||
// 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::path::PathBuf;
|
||||
use ethcore::ethstore::{EthStore, SecretStore, import_accounts, read_geth_accounts};
|
||||
use ethcore::ethstore::dir::DiskDirectory;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use helpers::{password_prompt, password_from_file};
|
||||
use params::SpecType;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum AccountCmd {
|
||||
New(NewAccount),
|
||||
List(String),
|
||||
List(ListAccounts),
|
||||
Import(ImportAccounts),
|
||||
ImportFromGeth(ImportFromGethAccounts)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ListAccounts {
|
||||
pub path: String,
|
||||
pub spec: SpecType,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct NewAccount {
|
||||
pub iterations: u32,
|
||||
pub path: String,
|
||||
pub spec: SpecType,
|
||||
pub password_file: Option<String>,
|
||||
}
|
||||
|
||||
@ -38,6 +47,7 @@ pub struct NewAccount {
|
||||
pub struct ImportAccounts {
|
||||
pub from: Vec<String>,
|
||||
pub to: String,
|
||||
pub spec: SpecType,
|
||||
}
|
||||
|
||||
/// Parameters for geth accounts' import
|
||||
@ -47,18 +57,22 @@ pub struct ImportFromGethAccounts {
|
||||
pub testnet: bool,
|
||||
/// directory to import accounts to
|
||||
pub to: String,
|
||||
pub spec: SpecType,
|
||||
}
|
||||
|
||||
pub fn execute(cmd: AccountCmd) -> Result<String, String> {
|
||||
match cmd {
|
||||
AccountCmd::New(new_cmd) => new(new_cmd),
|
||||
AccountCmd::List(path) => list(path),
|
||||
AccountCmd::List(list_cmd) => list(list_cmd),
|
||||
AccountCmd::Import(import_cmd) => import(import_cmd),
|
||||
AccountCmd::ImportFromGeth(import_geth_cmd) => import_geth(import_geth_cmd)
|
||||
}
|
||||
}
|
||||
|
||||
fn keys_dir(path: String) -> Result<DiskDirectory, String> {
|
||||
fn keys_dir(path: String, spec: SpecType) -> Result<DiskDirectory, String> {
|
||||
let spec = try!(spec.spec());
|
||||
let mut path = PathBuf::from(&path);
|
||||
path.push(spec.data_dir);
|
||||
DiskDirectory::create(path).map_err(|e| format!("Could not open keys directory: {}", e))
|
||||
}
|
||||
|
||||
@ -75,15 +89,15 @@ fn new(n: NewAccount) -> Result<String, String> {
|
||||
None => try!(password_prompt()),
|
||||
};
|
||||
|
||||
let dir = Box::new(try!(keys_dir(n.path)));
|
||||
let dir = Box::new(try!(keys_dir(n.path, n.spec)));
|
||||
let secret_store = Box::new(try!(secret_store(dir, Some(n.iterations))));
|
||||
let acc_provider = AccountProvider::new(secret_store);
|
||||
let new_account = try!(acc_provider.new_account(&password).map_err(|e| format!("Could not create new account: {}", e)));
|
||||
Ok(format!("{:?}", new_account))
|
||||
}
|
||||
|
||||
fn list(path: String) -> Result<String, String> {
|
||||
let dir = Box::new(try!(keys_dir(path)));
|
||||
fn list(list_cmd: ListAccounts) -> Result<String, String> {
|
||||
let dir = Box::new(try!(keys_dir(list_cmd.path, list_cmd.spec)));
|
||||
let secret_store = Box::new(try!(secret_store(dir, None)));
|
||||
let acc_provider = AccountProvider::new(secret_store);
|
||||
let accounts = acc_provider.accounts();
|
||||
@ -96,7 +110,7 @@ fn list(path: String) -> Result<String, String> {
|
||||
}
|
||||
|
||||
fn import(i: ImportAccounts) -> Result<String, String> {
|
||||
let to = try!(keys_dir(i.to));
|
||||
let to = try!(keys_dir(i.to, i.spec));
|
||||
let mut imported = 0;
|
||||
for path in &i.from {
|
||||
let from = DiskDirectory::at(path);
|
||||
@ -109,7 +123,7 @@ fn import_geth(i: ImportFromGethAccounts) -> Result<String, String> {
|
||||
use std::io::ErrorKind;
|
||||
use ethcore::ethstore::Error;
|
||||
|
||||
let dir = Box::new(try!(keys_dir(i.to)));
|
||||
let dir = Box::new(try!(keys_dir(i.to, i.spec)));
|
||||
let secret_store = Box::new(try!(secret_store(dir, None)));
|
||||
let geth_accounts = read_geth_accounts(i.testnet);
|
||||
match secret_store.import_geth_accounts(geth_accounts, i.testnet) {
|
||||
|
@ -64,11 +64,19 @@ impl FromStr for DataFormat {
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum BlockchainCmd {
|
||||
Kill(KillBlockchain),
|
||||
Import(ImportBlockchain),
|
||||
Export(ExportBlockchain),
|
||||
ExportState(ExportState),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct KillBlockchain {
|
||||
pub spec: SpecType,
|
||||
pub dirs: Directories,
|
||||
pub pruning: Pruning,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ImportBlockchain {
|
||||
pub spec: SpecType,
|
||||
@ -128,6 +136,7 @@ pub struct ExportState {
|
||||
|
||||
pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
|
||||
match cmd {
|
||||
BlockchainCmd::Kill(kill_cmd) => kill_db(kill_cmd),
|
||||
BlockchainCmd::Import(import_cmd) => execute_import(import_cmd),
|
||||
BlockchainCmd::Export(export_cmd) => execute_export(export_cmd),
|
||||
BlockchainCmd::ExportState(export_cmd) => execute_export_state(export_cmd),
|
||||
@ -140,9 +149,6 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
||||
// Setup panic handler
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
|
||||
// create dirs used by parity
|
||||
try!(cmd.dirs.create_dirs(false, false));
|
||||
|
||||
// load spec file
|
||||
let spec = try!(cmd.spec.spec());
|
||||
|
||||
@ -150,7 +156,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
// database paths
|
||||
let db_dirs = cmd.dirs.database(genesis_hash, spec.fork_name.clone());
|
||||
let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir.clone());
|
||||
|
||||
// user defaults path
|
||||
let user_defaults_path = db_dirs.user_defaults_path();
|
||||
@ -174,7 +180,10 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
||||
let snapshot_path = db_dirs.snapshot_path();
|
||||
|
||||
// execute upgrades
|
||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||
|
||||
// create dirs used by parity
|
||||
try!(cmd.dirs.create_dirs(false, false));
|
||||
|
||||
// prepare client config
|
||||
let mut client_config = to_client_config(
|
||||
@ -311,9 +320,6 @@ fn start_client(
|
||||
wal: bool,
|
||||
cache_config: CacheConfig) -> Result<ClientService, String> {
|
||||
|
||||
// create dirs used by parity
|
||||
try!(dirs.create_dirs(false, false));
|
||||
|
||||
// load spec file
|
||||
let spec = try!(spec.spec());
|
||||
|
||||
@ -321,7 +327,7 @@ fn start_client(
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
// database paths
|
||||
let db_dirs = dirs.database(genesis_hash, spec.fork_name.clone());
|
||||
let db_dirs = dirs.database(genesis_hash, None, spec.data_dir.clone());
|
||||
|
||||
// user defaults path
|
||||
let user_defaults_path = db_dirs.user_defaults_path();
|
||||
@ -345,7 +351,10 @@ fn start_client(
|
||||
let snapshot_path = db_dirs.snapshot_path();
|
||||
|
||||
// execute upgrades
|
||||
try!(execute_upgrades(&db_dirs, algorithm, compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||
try!(execute_upgrades(&db_dirs, algorithm, compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||
|
||||
// create dirs used by parity
|
||||
try!(dirs.create_dirs(false, false));
|
||||
|
||||
// prepare client config
|
||||
let client_config = to_client_config(&cache_config, Mode::Active, tracing, fat_db, compaction, wal, VMType::default(), "".into(), algorithm, pruning_history, true);
|
||||
@ -473,6 +482,18 @@ fn execute_export_state(cmd: ExportState) -> Result<String, String> {
|
||||
Ok("Export completed.".into())
|
||||
}
|
||||
|
||||
pub fn kill_db(cmd: KillBlockchain) -> Result<String, String> {
|
||||
let spec = try!(cmd.spec.spec());
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir);
|
||||
let user_defaults_path = db_dirs.user_defaults_path();
|
||||
let user_defaults = try!(UserDefaults::load(&user_defaults_path));
|
||||
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
|
||||
let dir = db_dirs.db_path(algorithm);
|
||||
try!(fs::remove_dir_all(&dir).map_err(|e| format!("Error removing database: {:?}", e)));
|
||||
Ok("Database deleted.".to_owned())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::DataFormat;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#[macro_use]
|
||||
mod usage;
|
||||
use dir::default_data_path;
|
||||
|
||||
usage! {
|
||||
{
|
||||
@ -36,6 +37,8 @@ usage! {
|
||||
cmd_ui: bool,
|
||||
cmd_tools: bool,
|
||||
cmd_hash: bool,
|
||||
cmd_kill: bool,
|
||||
cmd_db: bool,
|
||||
|
||||
// Arguments
|
||||
arg_pid_file: String,
|
||||
@ -80,8 +83,8 @@ usage! {
|
||||
flag_mode_timeout: u64 = 300u64, or |c: &Config| otry!(c.parity).mode_timeout.clone(),
|
||||
flag_mode_alarm: u64 = 3600u64, or |c: &Config| otry!(c.parity).mode_alarm.clone(),
|
||||
flag_chain: String = "homestead", or |c: &Config| otry!(c.parity).chain.clone(),
|
||||
flag_db_path: String = "$HOME/.parity", or |c: &Config| otry!(c.parity).db_path.clone(),
|
||||
flag_keys_path: String = "$HOME/.parity/keys", or |c: &Config| otry!(c.parity).keys_path.clone(),
|
||||
flag_db_path: String = default_data_path(), or |c: &Config| otry!(c.parity).db_path.clone(),
|
||||
flag_keys_path: String = "$DATA/keys", or |c: &Config| otry!(c.parity).keys_path.clone(),
|
||||
flag_identity: String = "", or |c: &Config| otry!(c.parity).identity.clone(),
|
||||
|
||||
// -- Account Options
|
||||
@ -100,7 +103,7 @@ usage! {
|
||||
or |c: &Config| otry!(c.ui).port.clone(),
|
||||
flag_ui_interface: String = "local",
|
||||
or |c: &Config| otry!(c.ui).interface.clone(),
|
||||
flag_ui_path: String = "$HOME/.parity/signer",
|
||||
flag_ui_path: String = "$DATA/signer",
|
||||
or |c: &Config| otry!(c.ui).path.clone(),
|
||||
// NOTE [todr] For security reasons don't put this to config files
|
||||
flag_ui_no_validation: bool = false, or |_| None,
|
||||
@ -156,7 +159,7 @@ usage! {
|
||||
// IPC
|
||||
flag_no_ipc: bool = false,
|
||||
or |c: &Config| otry!(c.ipc).disable.clone(),
|
||||
flag_ipc_path: String = "$HOME/.parity/jsonrpc.ipc",
|
||||
flag_ipc_path: String = "$DATA/jsonrpc.ipc",
|
||||
or |c: &Config| otry!(c.ipc).path.clone(),
|
||||
flag_ipc_apis: String = "web3,eth,net,parity,parity_accounts,traces,rpc",
|
||||
or |c: &Config| otry!(c.ipc).apis.clone().map(|vec| vec.join(",")),
|
||||
@ -170,7 +173,7 @@ usage! {
|
||||
or |c: &Config| otry!(c.dapps).interface.clone(),
|
||||
flag_dapps_hosts: String = "none",
|
||||
or |c: &Config| otry!(c.dapps).hosts.clone().map(|vec| vec.join(",")),
|
||||
flag_dapps_path: String = "$HOME/.parity/dapps",
|
||||
flag_dapps_path: String = "$DATA/dapps",
|
||||
or |c: &Config| otry!(c.dapps).path.clone(),
|
||||
flag_dapps_user: Option<String> = None,
|
||||
or |c: &Config| otry!(c.dapps).user.clone().map(Some),
|
||||
@ -271,7 +274,7 @@ usage! {
|
||||
or |c: &Config| otry!(c.vm).jit.clone(),
|
||||
|
||||
// -- Miscellaneous Options
|
||||
flag_config: String = "$HOME/.parity/config.toml", or |_| None,
|
||||
flag_config: String = "$DATA/config.toml", or |_| None,
|
||||
flag_logging: Option<String> = None,
|
||||
or |c: &Config| otry!(c.misc).logging.clone().map(Some),
|
||||
flag_log_file: Option<String> = None,
|
||||
@ -512,6 +515,8 @@ mod tests {
|
||||
cmd_ui: false,
|
||||
cmd_tools: false,
|
||||
cmd_hash: false,
|
||||
cmd_db: false,
|
||||
cmd_kill: false,
|
||||
|
||||
// Arguments
|
||||
arg_pid_file: "".into(),
|
||||
@ -665,7 +670,7 @@ mod tests {
|
||||
|
||||
// -- Miscellaneous Options
|
||||
flag_version: false,
|
||||
flag_config: "$HOME/.parity/config.toml".into(),
|
||||
flag_config: "$DATA/config.toml".into(),
|
||||
flag_logging: Some("own_tx=trace".into()),
|
||||
flag_log_file: Some("/var/log/parity.log".into()),
|
||||
flag_no_color: false,
|
||||
|
@ -145,7 +145,7 @@ macro_rules! usage {
|
||||
}
|
||||
|
||||
let config_file = raw_args.flag_config.clone().unwrap_or_else(|| raw_args.clone().into_args(Config::default()).flag_config);
|
||||
let config_file = replace_home(&config_file);
|
||||
let config_file = replace_home("", &config_file);
|
||||
let config = match (fs::File::open(&config_file), raw_args.flag_config.is_some()) {
|
||||
// Load config file
|
||||
(Ok(mut file), _) => {
|
||||
|
@ -15,6 +15,7 @@ Usage:
|
||||
parity snapshot <file> [options]
|
||||
parity restore [ <file> ] [options]
|
||||
parity tools hash <file>
|
||||
parity db kill [options]
|
||||
|
||||
Operating Options:
|
||||
--mode MODE Set the operating mode. MODE can be one of:
|
||||
@ -282,10 +283,8 @@ Import/Export Options:
|
||||
(default: {flag_format:?} = Import: auto, Export: binary)
|
||||
--no-seal-check Skip block seal check. (default: {flag_no_seal_check})
|
||||
--at BLOCK Export state at the given block, which may be an
|
||||
index, hash, or 'latest'. Note that taking snapshots at
|
||||
non-recent blocks will only work with --pruning archive
|
||||
(default: {flag_at})
|
||||
--no-storage Don't export account storge. (default: {flag_no_storage})
|
||||
index, hash, or 'latest'. (default: {flag_at})
|
||||
--no-storage Don't export account storage. (default: {flag_no_storage})
|
||||
--no-code Don't export account code. (default: {flag_no_code})
|
||||
--min-balance WEI Don't export accounts with balance less than specified.
|
||||
(default: {flag_min_balance:?})
|
||||
|
@ -38,9 +38,9 @@ use dir::Directories;
|
||||
use dapps::Configuration as DappsConfiguration;
|
||||
use signer::{Configuration as SignerConfiguration};
|
||||
use run::RunCmd;
|
||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, ExportState, DataFormat};
|
||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
|
||||
use presale::ImportWallet;
|
||||
use account::{AccountCmd, NewAccount, ImportAccounts, ImportFromGethAccounts};
|
||||
use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts};
|
||||
use snapshot::{self, SnapshotCommand};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -107,20 +107,32 @@ impl Configuration {
|
||||
Cmd::SignerToken(signer_conf)
|
||||
} else if self.args.cmd_tools && self.args.cmd_hash {
|
||||
Cmd::Hash(self.args.arg_file)
|
||||
} else if self.args.cmd_db && self.args.cmd_kill {
|
||||
Cmd::Blockchain(BlockchainCmd::Kill(KillBlockchain {
|
||||
spec: spec,
|
||||
dirs: dirs,
|
||||
pruning: pruning,
|
||||
}))
|
||||
} else if self.args.cmd_account {
|
||||
let account_cmd = if self.args.cmd_new {
|
||||
let new_acc = NewAccount {
|
||||
iterations: self.args.flag_keys_iterations,
|
||||
path: dirs.keys,
|
||||
spec: spec,
|
||||
password_file: self.args.flag_password.first().cloned(),
|
||||
};
|
||||
AccountCmd::New(new_acc)
|
||||
} else if self.args.cmd_list {
|
||||
AccountCmd::List(dirs.keys)
|
||||
let list_acc = ListAccounts {
|
||||
path: dirs.keys,
|
||||
spec: spec,
|
||||
};
|
||||
AccountCmd::List(list_acc)
|
||||
} else if self.args.cmd_import {
|
||||
let import_acc = ImportAccounts {
|
||||
from: self.args.arg_path.clone(),
|
||||
to: dirs.keys,
|
||||
spec: spec,
|
||||
};
|
||||
AccountCmd::Import(import_acc)
|
||||
} else {
|
||||
@ -130,6 +142,7 @@ impl Configuration {
|
||||
} else if self.args.flag_import_geth_keys {
|
||||
let account_cmd = AccountCmd::ImportFromGeth(
|
||||
ImportFromGethAccounts {
|
||||
spec: spec,
|
||||
to: dirs.keys,
|
||||
testnet: self.args.flag_testnet
|
||||
}
|
||||
@ -139,6 +152,7 @@ impl Configuration {
|
||||
let presale_cmd = ImportWallet {
|
||||
iterations: self.args.flag_keys_iterations,
|
||||
path: dirs.keys,
|
||||
spec: spec,
|
||||
wallet_path: self.args.arg_path.first().unwrap().clone(),
|
||||
password_file: self.args.flag_password.first().cloned(),
|
||||
};
|
||||
@ -530,7 +544,7 @@ impl Configuration {
|
||||
ret.snapshot_peers = self.snapshot_peers();
|
||||
ret.allow_ips = try!(self.allow_ips());
|
||||
ret.max_pending_peers = self.max_pending_peers();
|
||||
let mut net_path = PathBuf::from(self.directories().db);
|
||||
let mut net_path = PathBuf::from(self.directories().data);
|
||||
net_path.push("network");
|
||||
ret.config_path = Some(net_path.to_str().unwrap().to_owned());
|
||||
ret.reserved_nodes = try!(self.init_reserved_nodes());
|
||||
@ -624,18 +638,11 @@ impl Configuration {
|
||||
fn directories(&self) -> Directories {
|
||||
use util::path;
|
||||
|
||||
let db_path = replace_home(self.args.flag_datadir.as_ref().unwrap_or(&self.args.flag_db_path));
|
||||
let data_path = replace_home("", self.args.flag_datadir.as_ref().unwrap_or(&self.args.flag_db_path));
|
||||
|
||||
let keys_path = replace_home(
|
||||
if self.args.flag_testnet {
|
||||
"$HOME/.parity/testnet_keys"
|
||||
} else {
|
||||
&self.args.flag_keys_path
|
||||
}
|
||||
);
|
||||
|
||||
let dapps_path = replace_home(&self.args.flag_dapps_path);
|
||||
let ui_path = replace_home(&self.args.flag_ui_path);
|
||||
let keys_path = replace_home(&data_path, &self.args.flag_keys_path);
|
||||
let dapps_path = replace_home(&data_path, &self.args.flag_dapps_path);
|
||||
let ui_path = replace_home(&data_path, &self.args.flag_ui_path);
|
||||
|
||||
if self.args.flag_geth && !cfg!(windows) {
|
||||
let geth_root = if self.args.flag_testnet { path::ethereum::test() } else { path::ethereum::default() };
|
||||
@ -644,7 +651,7 @@ impl Configuration {
|
||||
}
|
||||
|
||||
if cfg!(feature = "ipc") && !cfg!(feature = "windows") {
|
||||
let mut path_buf = PathBuf::from(db_path.clone());
|
||||
let mut path_buf = PathBuf::from(data_path.clone());
|
||||
path_buf.push("ipc");
|
||||
let ipc_path = path_buf.to_str().unwrap();
|
||||
::std::fs::create_dir_all(ipc_path).unwrap_or_else(
|
||||
@ -654,7 +661,7 @@ impl Configuration {
|
||||
|
||||
Directories {
|
||||
keys: keys_path,
|
||||
db: db_path,
|
||||
data: data_path,
|
||||
dapps: dapps_path,
|
||||
signer: ui_path,
|
||||
}
|
||||
@ -664,7 +671,7 @@ impl Configuration {
|
||||
if self.args.flag_geth {
|
||||
geth_ipc_path(self.args.flag_testnet)
|
||||
} else {
|
||||
parity_ipc_path(&self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone()))
|
||||
parity_ipc_path(&self.directories().data, &self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -732,12 +739,14 @@ mod tests {
|
||||
use ethcore_rpc::NetworkSettings;
|
||||
use ethcore::client::{VMType, BlockId};
|
||||
use ethcore::miner::{MinerOptions, PrioritizationStrategy};
|
||||
use helpers::{replace_home, default_network_config};
|
||||
use helpers::{default_network_config};
|
||||
use run::RunCmd;
|
||||
use dir::Directories;
|
||||
use signer::{Configuration as SignerConfiguration};
|
||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat, ExportState};
|
||||
use presale::ImportWallet;
|
||||
use account::{AccountCmd, NewAccount, ImportAccounts};
|
||||
use params::SpecType;
|
||||
use account::{AccountCmd, NewAccount, ImportAccounts, ListAccounts};
|
||||
use devtools::{RandomTempPath};
|
||||
use std::io::Write;
|
||||
use std::fs::{File, create_dir};
|
||||
@ -764,8 +773,9 @@ mod tests {
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Account(AccountCmd::New(NewAccount {
|
||||
iterations: 10240,
|
||||
path: replace_home("$HOME/.parity/keys"),
|
||||
path: Directories::default().keys,
|
||||
password_file: None,
|
||||
spec: SpecType::default(),
|
||||
})));
|
||||
}
|
||||
|
||||
@ -774,7 +784,10 @@ mod tests {
|
||||
let args = vec!["parity", "account", "list"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Account(
|
||||
AccountCmd::List(replace_home("$HOME/.parity/keys")),
|
||||
AccountCmd::List(ListAccounts {
|
||||
path: Directories::default().keys,
|
||||
spec: SpecType::default(),
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
@ -784,7 +797,8 @@ mod tests {
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Account(AccountCmd::Import(ImportAccounts {
|
||||
from: vec!["my_dir".into(), "another_dir".into()],
|
||||
to: replace_home("$HOME/.parity/keys"),
|
||||
to: Directories::default().keys,
|
||||
spec: SpecType::default(),
|
||||
})));
|
||||
}
|
||||
|
||||
@ -794,9 +808,10 @@ mod tests {
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::ImportPresaleWallet(ImportWallet {
|
||||
iterations: 10240,
|
||||
path: replace_home("$HOME/.parity/keys"),
|
||||
path: Directories::default().keys,
|
||||
wallet_path: "my_wallet.json".into(),
|
||||
password_file: Some("pwd".into()),
|
||||
spec: SpecType::default(),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -895,7 +910,7 @@ mod tests {
|
||||
fn test_command_signer_new_token() {
|
||||
let args = vec!["parity", "signer", "new-token"];
|
||||
let conf = parse(&args);
|
||||
let expected = replace_home("$HOME/.parity/signer");
|
||||
let expected = Directories::default().signer;
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::SignerToken(SignerConfiguration {
|
||||
enabled: true,
|
||||
signer_path: expected,
|
||||
|
@ -20,6 +20,7 @@ use rpc_apis;
|
||||
use ethcore::client::Client;
|
||||
use ethsync::SyncProvider;
|
||||
use helpers::replace_home;
|
||||
use dir::default_data_path;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Configuration {
|
||||
@ -34,6 +35,7 @@ pub struct Configuration {
|
||||
|
||||
impl Default for Configuration {
|
||||
fn default() -> Self {
|
||||
let data_dir = default_data_path();
|
||||
Configuration {
|
||||
enabled: true,
|
||||
interface: "127.0.0.1".into(),
|
||||
@ -41,7 +43,7 @@ impl Default for Configuration {
|
||||
hosts: Some(Vec::new()),
|
||||
user: None,
|
||||
pass: None,
|
||||
dapps_path: replace_home("$HOME/.parity/dapps"),
|
||||
dapps_path: replace_home(&data_dir, "$DATA/dapps"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
118
parity/dir.rs
118
parity/dir.rs
@ -19,6 +19,7 @@ use std::path::{PathBuf, Path};
|
||||
use util::{H64, H256};
|
||||
use util::journaldb::Algorithm;
|
||||
use helpers::replace_home;
|
||||
use app_dirs::{AppInfo, get_app_root, AppDataType};
|
||||
|
||||
// this const is irrelevent cause we do have migrations now,
|
||||
// but we still use it for backwards compatibility
|
||||
@ -26,7 +27,7 @@ const LEGACY_CLIENT_DB_VER_STR: &'static str = "5.3";
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Directories {
|
||||
pub db: String,
|
||||
pub data: String,
|
||||
pub keys: String,
|
||||
pub signer: String,
|
||||
pub dapps: String,
|
||||
@ -34,18 +35,19 @@ pub struct Directories {
|
||||
|
||||
impl Default for Directories {
|
||||
fn default() -> Self {
|
||||
let data_dir = default_data_path();
|
||||
Directories {
|
||||
db: replace_home("$HOME/.parity"),
|
||||
keys: replace_home("$HOME/.parity/keys"),
|
||||
signer: replace_home("$HOME/.parity/signer"),
|
||||
dapps: replace_home("$HOME/.parity/dapps"),
|
||||
data: replace_home(&data_dir, "$DATA"),
|
||||
keys: replace_home(&data_dir, "$DATA/keys"),
|
||||
signer: replace_home(&data_dir, "$DATA/signer"),
|
||||
dapps: replace_home(&data_dir, "$DATA/dapps"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Directories {
|
||||
pub fn create_dirs(&self, dapps_enabled: bool, signer_enabled: bool) -> Result<(), String> {
|
||||
try!(fs::create_dir_all(&self.db).map_err(|e| e.to_string()));
|
||||
try!(fs::create_dir_all(&self.data).map_err(|e| e.to_string()));
|
||||
try!(fs::create_dir_all(&self.keys).map_err(|e| e.to_string()));
|
||||
if signer_enabled {
|
||||
try!(fs::create_dir_all(&self.signer).map_err(|e| e.to_string()));
|
||||
@ -57,20 +59,38 @@ impl Directories {
|
||||
}
|
||||
|
||||
/// Database paths.
|
||||
pub fn database(&self, genesis_hash: H256, fork_name: Option<String>) -> DatabaseDirectories {
|
||||
pub fn database(&self, genesis_hash: H256, fork_name: Option<String>, spec_name: String) -> DatabaseDirectories {
|
||||
DatabaseDirectories {
|
||||
path: self.db.clone(),
|
||||
path: self.data.clone(),
|
||||
genesis_hash: genesis_hash,
|
||||
fork_name: fork_name,
|
||||
spec_name: spec_name,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the ipc sockets path
|
||||
pub fn ipc_path(&self) -> PathBuf {
|
||||
let mut dir = Path::new(&self.db).to_path_buf();
|
||||
let mut dir = Path::new(&self.data).to_path_buf();
|
||||
dir.push("ipc");
|
||||
dir
|
||||
}
|
||||
|
||||
// TODO: remove in 1.7
|
||||
pub fn legacy_keys_path(&self, testnet: bool) -> PathBuf {
|
||||
let mut dir = Path::new(&self.data).to_path_buf();
|
||||
if testnet {
|
||||
dir.push("testnet_keys");
|
||||
} else {
|
||||
dir.push("keys");
|
||||
}
|
||||
dir
|
||||
}
|
||||
|
||||
pub fn keys_path(&self, spec_name: &str) -> PathBuf {
|
||||
let mut dir = PathBuf::from(&self.keys);
|
||||
dir.push(spec_name);
|
||||
dir
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -78,52 +98,103 @@ pub struct DatabaseDirectories {
|
||||
pub path: String,
|
||||
pub genesis_hash: H256,
|
||||
pub fork_name: Option<String>,
|
||||
pub spec_name: String,
|
||||
}
|
||||
|
||||
impl DatabaseDirectories {
|
||||
/// Base DB directory for the given fork.
|
||||
pub fn fork_path(&self) -> PathBuf {
|
||||
// TODO: remove in 1.7
|
||||
pub fn legacy_fork_path(&self) -> PathBuf {
|
||||
let mut dir = Path::new(&self.path).to_path_buf();
|
||||
dir.push(format!("{:?}{}", H64::from(self.genesis_hash), self.fork_name.as_ref().map(|f| format!("-{}", f)).unwrap_or_default()));
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get the root path for database
|
||||
pub fn version_path(&self, pruning: Algorithm) -> PathBuf {
|
||||
let mut dir = self.fork_path();
|
||||
dir.push(format!("v{}-sec-{}", LEGACY_CLIENT_DB_VER_STR, pruning.as_internal_name_str()));
|
||||
pub fn spec_root_path(&self) -> PathBuf {
|
||||
let mut dir = Path::new(&self.path).to_path_buf();
|
||||
dir.push("chains");
|
||||
dir.push(&self.spec_name);
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get the path for the databases given the genesis_hash and information on the databases.
|
||||
pub fn client_path(&self, pruning: Algorithm) -> PathBuf {
|
||||
let mut dir = self.version_path(pruning);
|
||||
let mut dir = self.db_root_path();
|
||||
dir.push(pruning.as_internal_name_str());
|
||||
dir.push("db");
|
||||
dir
|
||||
}
|
||||
|
||||
pub fn db_root_path(&self) -> PathBuf {
|
||||
let mut dir = self.spec_root_path();
|
||||
dir.push("db");
|
||||
dir.push(H64::from(self.genesis_hash).hex());
|
||||
dir
|
||||
}
|
||||
|
||||
pub fn db_path(&self, pruning: Algorithm) -> PathBuf {
|
||||
let mut dir = self.db_root_path();
|
||||
dir.push(pruning.as_internal_name_str());
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get the root path for database
|
||||
// TODO: remove in 1.7
|
||||
pub fn legacy_version_path(&self, pruning: Algorithm) -> PathBuf {
|
||||
let mut dir = self.legacy_fork_path();
|
||||
dir.push(format!("v{}-sec-{}", LEGACY_CLIENT_DB_VER_STR, pruning.as_internal_name_str()));
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get user defaults path
|
||||
// TODO: remove in 1.7
|
||||
pub fn legacy_user_defaults_path(&self) -> PathBuf {
|
||||
let mut dir = self.legacy_fork_path();
|
||||
dir.push("user_defaults");
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get user defaults path
|
||||
// TODO: remove in 1.7
|
||||
pub fn legacy_snapshot_path(&self) -> PathBuf {
|
||||
let mut dir = self.legacy_fork_path();
|
||||
dir.push("snapshot");
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get user defaults path
|
||||
// TODO: remove in 1.7
|
||||
pub fn legacy_network_path(&self) -> PathBuf {
|
||||
let mut dir = self.legacy_fork_path();
|
||||
dir.push("network");
|
||||
dir
|
||||
}
|
||||
|
||||
pub fn user_defaults_path(&self) -> PathBuf {
|
||||
let mut dir = self.fork_path();
|
||||
let mut dir = self.spec_root_path();
|
||||
dir.push("user_defaults");
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get the path for the snapshot directory given the genesis hash and fork name.
|
||||
pub fn snapshot_path(&self) -> PathBuf {
|
||||
let mut dir = self.fork_path();
|
||||
let mut dir = self.db_root_path();
|
||||
dir.push("snapshot");
|
||||
dir
|
||||
}
|
||||
|
||||
/// Get the path for the network directory.
|
||||
pub fn network_path(&self) -> PathBuf {
|
||||
let mut dir = self.fork_path();
|
||||
let mut dir = self.spec_root_path();
|
||||
dir.push("network");
|
||||
dir
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_data_path() -> String {
|
||||
let app_info = AppInfo { name: "parity", author: "parity" };
|
||||
get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity".to_owned())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Directories;
|
||||
@ -131,11 +202,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_default_directories() {
|
||||
let data_dir = super::default_data_path();
|
||||
let expected = Directories {
|
||||
db: replace_home("$HOME/.parity"),
|
||||
keys: replace_home("$HOME/.parity/keys"),
|
||||
signer: replace_home("$HOME/.parity/signer"),
|
||||
dapps: replace_home("$HOME/.parity/dapps"),
|
||||
data: replace_home(&data_dir, "$DATA"),
|
||||
keys: replace_home(&data_dir, "$DATA/keys"),
|
||||
signer: replace_home(&data_dir, "$DATA/signer"),
|
||||
dapps: replace_home(&data_dir, "$DATA/dapps"),
|
||||
};
|
||||
assert_eq!(expected, Directories::default());
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientCo
|
||||
use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy};
|
||||
use cache::CacheConfig;
|
||||
use dir::DatabaseDirectories;
|
||||
use upgrade::upgrade;
|
||||
use upgrade::{upgrade, upgrade_data_paths};
|
||||
use migration::migrate;
|
||||
use ethsync::is_valid_node_url;
|
||||
|
||||
@ -132,9 +132,10 @@ pub fn to_price(s: &str) -> Result<f32, String> {
|
||||
}
|
||||
|
||||
/// Replaces `$HOME` str with home directory path.
|
||||
pub fn replace_home(arg: &str) -> String {
|
||||
pub fn replace_home(base: &str, arg: &str) -> String {
|
||||
// the $HOME directory on mac os should be `~/Library` or `~/Library/Application Support`
|
||||
let r = arg.replace("$HOME", env::home_dir().unwrap().to_str().unwrap());
|
||||
let r = r.replace("$DATA", base );
|
||||
r.replace("/", &::std::path::MAIN_SEPARATOR.to_string() )
|
||||
}
|
||||
|
||||
@ -159,13 +160,13 @@ pub fn geth_ipc_path(testnet: bool) -> String {
|
||||
}
|
||||
|
||||
/// Formats and returns parity ipc path.
|
||||
pub fn parity_ipc_path(s: &str) -> String {
|
||||
pub fn parity_ipc_path(base: &str, s: &str) -> String {
|
||||
// Windows path should not be hardcoded here.
|
||||
if cfg!(windows) {
|
||||
return r"\\.\pipe\parity.jsonrpc".to_owned();
|
||||
}
|
||||
|
||||
replace_home(s)
|
||||
replace_home(base, s)
|
||||
}
|
||||
|
||||
/// Validates and formats bootnodes option.
|
||||
@ -187,7 +188,7 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
|
||||
pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
|
||||
use ethsync::{NetworkConfiguration, AllowIP};
|
||||
NetworkConfiguration {
|
||||
config_path: Some(replace_home("$HOME/.parity/network")),
|
||||
config_path: Some(replace_home(&::dir::default_data_path(), "$DATA/network")),
|
||||
net_config_path: None,
|
||||
listen_address: Some("0.0.0.0:30303".into()),
|
||||
public_address: None,
|
||||
@ -261,6 +262,8 @@ pub fn execute_upgrades(
|
||||
compaction_profile: CompactionProfile
|
||||
) -> Result<(), String> {
|
||||
|
||||
upgrade_data_paths(dirs, pruning);
|
||||
|
||||
match upgrade(Some(&dirs.path)) {
|
||||
Ok(upgrades_applied) if upgrades_applied > 0 => {
|
||||
debug!("Executed {} upgrade scripts - ok", upgrades_applied);
|
||||
@ -271,7 +274,7 @@ pub fn execute_upgrades(
|
||||
_ => {},
|
||||
}
|
||||
|
||||
let client_path = dirs.version_path(pruning);
|
||||
let client_path = dirs.db_path(pruning);
|
||||
migrate(&client_path, pruning, compaction_profile).map_err(|e| format!("{}", e))
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ extern crate ansi_term;
|
||||
extern crate regex;
|
||||
extern crate isatty;
|
||||
extern crate toml;
|
||||
extern crate app_dirs;
|
||||
|
||||
#[macro_use]
|
||||
extern crate ethcore_util as util;
|
||||
|
@ -76,6 +76,14 @@ impl SpecType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn legacy_fork_name(&self) -> Option<String> {
|
||||
match *self {
|
||||
SpecType::Classic => Some("classic".to_owned()),
|
||||
SpecType::Expanse => Some("expanse".to_owned()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -18,11 +18,13 @@ use ethcore::ethstore::{PresaleWallet, EthStore};
|
||||
use ethcore::ethstore::dir::DiskDirectory;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use helpers::{password_prompt, password_from_file};
|
||||
use params::SpecType;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ImportWallet {
|
||||
pub iterations: u32,
|
||||
pub path: String,
|
||||
pub spec: SpecType,
|
||||
pub wallet_path: String,
|
||||
pub password_file: Option<String>,
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ use ethcore_rpc::{RpcServerError, RpcServer as Server, IpcServerError};
|
||||
use rpc_apis;
|
||||
use rpc_apis::ApiSet;
|
||||
use helpers::parity_ipc_path;
|
||||
use dir::default_data_path;
|
||||
|
||||
pub use ethcore_rpc::{IpcServer, Server as HttpServer};
|
||||
|
||||
@ -58,9 +59,10 @@ pub struct IpcConfiguration {
|
||||
|
||||
impl Default for IpcConfiguration {
|
||||
fn default() -> Self {
|
||||
let data_dir = default_data_path();
|
||||
IpcConfiguration {
|
||||
enabled: true,
|
||||
socket_addr: parity_ipc_path("$HOME/.parity/jsonrpc.ipc"),
|
||||
socket_addr: parity_ipc_path(&data_dir, "$DATA/jsonrpc.ipc"),
|
||||
apis: ApiSet::IpcContext,
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ use params::{
|
||||
tracing_switch_to_bool, fatdb_switch_to_bool, mode_switch_to_bool
|
||||
};
|
||||
use helpers::{to_client_config, execute_upgrades, passwords_from_files};
|
||||
use upgrade::upgrade_key_location;
|
||||
use dir::Directories;
|
||||
use cache::CacheConfig;
|
||||
use user_defaults::UserDefaults;
|
||||
@ -129,9 +130,6 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
||||
// increase max number of open files
|
||||
raise_fd_limit();
|
||||
|
||||
// create dirs used by parity
|
||||
try!(cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.signer_conf.enabled));
|
||||
|
||||
// load spec
|
||||
let spec = try!(cmd.spec.spec());
|
||||
|
||||
@ -139,7 +137,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
// database paths
|
||||
let db_dirs = cmd.dirs.database(genesis_hash, spec.fork_name.clone());
|
||||
let db_dirs = cmd.dirs.database(genesis_hash, cmd.spec.legacy_fork_name(), spec.data_dir.clone());
|
||||
|
||||
// user defaults path
|
||||
let user_defaults_path = db_dirs.user_defaults_path();
|
||||
@ -166,7 +164,10 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
||||
let snapshot_path = db_dirs.snapshot_path();
|
||||
|
||||
// execute upgrades
|
||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||
|
||||
// create dirs used by parity
|
||||
try!(cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.signer_conf.enabled));
|
||||
|
||||
// run in daemon mode
|
||||
if let Some(pid_file) = cmd.daemon {
|
||||
@ -217,7 +218,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
||||
let passwords = try!(passwords_from_files(&cmd.acc_conf.password_files));
|
||||
|
||||
// prepare account provider
|
||||
let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf, &passwords)));
|
||||
let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)));
|
||||
|
||||
// let the Engine access the accounts
|
||||
spec.engine.register_account_provider(account_provider.clone());
|
||||
@ -449,11 +450,13 @@ fn daemonize(_pid_file: String) -> Result<(), String> {
|
||||
Err("daemon is no supported on windows".into())
|
||||
}
|
||||
|
||||
fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig, passwords: &[String]) -> Result<AccountProvider, String> {
|
||||
fn prepare_account_provider(dirs: &Directories, data_dir: &str, cfg: AccountsConfig, passwords: &[String]) -> Result<AccountProvider, String> {
|
||||
use ethcore::ethstore::EthStore;
|
||||
use ethcore::ethstore::dir::DiskDirectory;
|
||||
|
||||
let dir = Box::new(try!(DiskDirectory::create(dirs.keys.clone()).map_err(|e| format!("Could not open keys directory: {}", e))));
|
||||
let path = dirs.keys_path(data_dir);
|
||||
upgrade_key_location(&dirs.legacy_keys_path(cfg.testnet), &path);
|
||||
let dir = Box::new(try!(DiskDirectory::create(&path).map_err(|e| format!("Could not open keys directory: {}", e))));
|
||||
let account_service = AccountProvider::new(Box::new(
|
||||
try!(EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e)))
|
||||
));
|
||||
|
@ -23,6 +23,7 @@ use util::path::restrict_permissions_owner;
|
||||
use rpc_apis;
|
||||
use ethcore_signer as signer;
|
||||
use helpers::replace_home;
|
||||
use dir::default_data_path;
|
||||
pub use ethcore_signer::Server as SignerServer;
|
||||
|
||||
const CODES_FILENAME: &'static str = "authcodes";
|
||||
@ -38,11 +39,12 @@ pub struct Configuration {
|
||||
|
||||
impl Default for Configuration {
|
||||
fn default() -> Self {
|
||||
let data_dir = default_data_path();
|
||||
Configuration {
|
||||
enabled: true,
|
||||
port: 8180,
|
||||
interface: "127.0.0.1".into(),
|
||||
signer_path: replace_home("$HOME/.parity/signer"),
|
||||
signer_path: replace_home(&data_dir, "$DATA/signer"),
|
||||
skip_origin_validation: false,
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ impl SnapshotCommand {
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
// database paths
|
||||
let db_dirs = self.dirs.database(genesis_hash, spec.fork_name.clone());
|
||||
let db_dirs = self.dirs.database(genesis_hash, None, spec.data_dir.clone());
|
||||
|
||||
// user defaults path
|
||||
let user_defaults_path = db_dirs.user_defaults_path();
|
||||
@ -167,7 +167,7 @@ impl SnapshotCommand {
|
||||
let snapshot_path = db_dirs.snapshot_path();
|
||||
|
||||
// execute upgrades
|
||||
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.db_root_path().as_path())));
|
||||
|
||||
// prepare client config
|
||||
let client_config = to_client_config(&self.cache_config, Mode::Active, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
|
||||
|
@ -18,10 +18,14 @@
|
||||
|
||||
use semver::Version;
|
||||
use std::collections::*;
|
||||
use std::fs::{File, create_dir_all};
|
||||
use std::fs::{self, File, create_dir_all};
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{PathBuf, Path};
|
||||
use dir::{DatabaseDirectories, default_data_path};
|
||||
use helpers::replace_home;
|
||||
use util::journaldb::Algorithm;
|
||||
|
||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
||||
#[derive(Debug)]
|
||||
@ -126,3 +130,84 @@ pub fn upgrade(db_path: Option<&str>) -> Result<usize, Error> {
|
||||
upgrade_from_version(ver)
|
||||
})
|
||||
}
|
||||
|
||||
fn file_exists(path: &Path) -> bool {
|
||||
match fs::metadata(&path) {
|
||||
Err(ref e) if e.kind() == io::ErrorKind::NotFound => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn upgrade_key_location(from: &PathBuf, to: &PathBuf) {
|
||||
let mut parent = to.clone();
|
||||
parent.pop();
|
||||
match fs::create_dir_all(&parent).and_then(|()| fs::read_dir(from)) {
|
||||
Ok(entries) => {
|
||||
let files: Vec<_> = entries.filter_map(|f| f.ok().and_then(|f| if f.file_type().ok().map_or(false, |f| f.is_file()) { f.file_name().to_str().map(|s| s.to_owned()) } else { None })).collect();
|
||||
let mut num: usize = 0;
|
||||
for name in files {
|
||||
let mut from = from.clone();
|
||||
from.push(&name);
|
||||
let mut to = to.clone();
|
||||
to.push(&name);
|
||||
if !file_exists(&to) {
|
||||
if let Err(e) = fs::rename(&from, &to) {
|
||||
debug!("Error upgrading key {:?}: {:?}", from, e);
|
||||
} else {
|
||||
num += 1;
|
||||
}
|
||||
} else {
|
||||
debug!("Skipped upgrading key {:?}", from);
|
||||
}
|
||||
}
|
||||
if num > 0 {
|
||||
info!("Moved {} keys from {} to {}", num, from.to_string_lossy(), to.to_string_lossy());
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("Error moving keys from {:?} to {:?}: {:?}", from, to, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn upgrade_dir_location(source: &PathBuf, dest: &PathBuf) {
|
||||
if file_exists(&source) {
|
||||
if !file_exists(&dest) {
|
||||
let mut parent = dest.clone();
|
||||
parent.pop();
|
||||
if let Err(e) = fs::create_dir_all(&parent).and_then(|()| fs::rename(&source, &dest)) {
|
||||
debug!("Skipped path {:?} -> {:?} :{:?}", source, dest, e);
|
||||
} else {
|
||||
info!("Moved {} to {}", source.to_string_lossy(), dest.to_string_lossy());
|
||||
}
|
||||
} else {
|
||||
debug!("Skipped upgrading directory {:?}, Destination already exists at {:?}", source, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn upgrade_user_defaults(dirs: &DatabaseDirectories) {
|
||||
let source = dirs.legacy_user_defaults_path();
|
||||
let dest = dirs.user_defaults_path();
|
||||
if file_exists(&source) {
|
||||
if !file_exists(&dest) {
|
||||
if let Err(e) = fs::rename(&source, &dest) {
|
||||
debug!("Skipped upgrading user defaults {:?}:{:?}", dest, e);
|
||||
}
|
||||
} else {
|
||||
debug!("Skipped upgrading user defaults {:?}, File exists at {:?}", source, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn upgrade_data_paths(dirs: &DatabaseDirectories, pruning: Algorithm) {
|
||||
let legacy_root_path = replace_home("", "$HOME/.parity");
|
||||
let default_path = default_data_path();
|
||||
if legacy_root_path != dirs.path && dirs.path == default_path {
|
||||
upgrade_dir_location(&PathBuf::from(legacy_root_path), &PathBuf::from(&dirs.path));
|
||||
}
|
||||
upgrade_dir_location(&dirs.legacy_version_path(pruning), &dirs.db_path(pruning));
|
||||
upgrade_dir_location(&dirs.legacy_snapshot_path(), &dirs.snapshot_path());
|
||||
upgrade_dir_location(&dirs.legacy_network_path(), &dirs.network_path());
|
||||
upgrade_user_defaults(&dirs);
|
||||
}
|
||||
|
@ -17,14 +17,14 @@
|
||||
//! Traces api implementation.
|
||||
|
||||
use std::sync::{Weak, Arc};
|
||||
use jsonrpc_core::*;
|
||||
use serde;
|
||||
|
||||
use rlp::{UntrustedRlp, View};
|
||||
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId};
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
|
||||
|
||||
use jsonrpc_core::Error;
|
||||
use jsonrpc_macros::Trailing;
|
||||
use v1::traits::Traces;
|
||||
use v1::helpers::{errors, CallRequest as CRequest};
|
||||
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
||||
@ -37,22 +37,6 @@ fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns number of different parameters in given `Params` object.
|
||||
fn params_len(params: &Params) -> usize {
|
||||
match params {
|
||||
&Params::Array(ref vec) => vec.len(),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialize request parameters with optional third parameter `BlockNumber` defaulting to `BlockNumber::Latest`.
|
||||
fn from_params_default_third<F1, F2>(params: Params) -> Result<(F1, F2, BlockNumber, ), Error> where F1: serde::de::Deserialize, F2: serde::de::Deserialize {
|
||||
match params_len(¶ms) {
|
||||
2 => from_params::<(F1, F2, )>(params).map(|(f1, f2)| (f1, f2, BlockNumber::Latest)),
|
||||
_ => from_params::<(F1, F2, BlockNumber)>(params)
|
||||
}
|
||||
}
|
||||
|
||||
/// Traces api implementation.
|
||||
pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
||||
client: Weak<C>,
|
||||
@ -91,90 +75,77 @@ impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
||||
}
|
||||
|
||||
impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M: MinerService + 'static {
|
||||
fn filter(&self, params: Params) -> Result<Value, Error> {
|
||||
fn filter(&self, filter: TraceFilter) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(TraceFilter,)>(params)
|
||||
.and_then(|(filter, )| {
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.filter_traces(filter.into());
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(to_value(&traces))
|
||||
})
|
||||
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.filter_traces(filter.into());
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(traces)
|
||||
}
|
||||
|
||||
fn block_traces(&self, params: Params) -> Result<Value, Error> {
|
||||
fn block_traces(&self, block_number: BlockNumber) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(BlockNumber,)>(params)
|
||||
.and_then(|(block_number,)| {
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.block_traces(block_number.into());
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(to_value(&traces))
|
||||
})
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.block_traces(block_number.into());
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(traces)
|
||||
}
|
||||
|
||||
fn transaction_traces(&self, params: Params) -> Result<Value, Error> {
|
||||
fn transaction_traces(&self, transaction_hash: H256) -> Result<Vec<LocalizedTrace>, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256,)>(params)
|
||||
.and_then(|(transaction_hash,)| {
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.transaction_traces(TransactionId::Hash(transaction_hash.into()));
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(to_value(&traces))
|
||||
})
|
||||
|
||||
let client = take_weak!(self.client);
|
||||
let traces = client.transaction_traces(TransactionId::Hash(transaction_hash.into()));
|
||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
||||
Ok(traces)
|
||||
}
|
||||
|
||||
fn trace(&self, params: Params) -> Result<Value, Error> {
|
||||
fn trace(&self, transaction_hash: H256, address: Vec<Index>) -> Result<Option<LocalizedTrace>, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256, Vec<Index>)>(params)
|
||||
.and_then(|(transaction_hash, address)| {
|
||||
let client = take_weak!(self.client);
|
||||
let id = TraceId {
|
||||
transaction: TransactionId::Hash(transaction_hash.into()),
|
||||
address: address.into_iter().map(|i| i.value()).collect()
|
||||
};
|
||||
let trace = client.trace(id);
|
||||
let trace = trace.map(LocalizedTrace::from);
|
||||
Ok(to_value(&trace))
|
||||
})
|
||||
let client = take_weak!(self.client);
|
||||
let id = TraceId {
|
||||
transaction: TransactionId::Hash(transaction_hash.into()),
|
||||
address: address.into_iter().map(|i| i.value()).collect()
|
||||
};
|
||||
let trace = client.trace(id);
|
||||
let trace = trace.map(LocalizedTrace::from);
|
||||
|
||||
Ok(trace)
|
||||
}
|
||||
|
||||
fn call(&self, params: Params) -> Result<Value, Error> {
|
||||
fn call(&self, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
||||
try!(self.active());
|
||||
from_params_default_third(params)
|
||||
.and_then(|(request, flags, block)| {
|
||||
let request = CallRequest::into(request);
|
||||
let signed = try!(self.sign_call(request));
|
||||
match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
||||
Ok(e) => Ok(to_value(&TraceResults::from(e))),
|
||||
_ => Ok(Value::Null),
|
||||
}
|
||||
})
|
||||
let block = block.0;
|
||||
|
||||
let request = CallRequest::into(request);
|
||||
let signed = try!(self.sign_call(request));
|
||||
Ok(match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
||||
Ok(e) => Some(TraceResults::from(e)),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
fn raw_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
||||
try!(self.active());
|
||||
from_params_default_third(params)
|
||||
.and_then(|(raw_transaction, flags, block)| {
|
||||
let raw_transaction = Bytes::to_vec(raw_transaction);
|
||||
match UntrustedRlp::new(&raw_transaction).as_val() {
|
||||
Ok(signed) => match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
||||
Ok(e) => Ok(to_value(&TraceResults::from(e))),
|
||||
_ => Ok(Value::Null),
|
||||
},
|
||||
Err(e) => Err(errors::invalid_params("Transaction is not valid RLP", e)),
|
||||
}
|
||||
})
|
||||
let block = block.0;
|
||||
|
||||
let raw_transaction = Bytes::to_vec(raw_transaction);
|
||||
match UntrustedRlp::new(&raw_transaction).as_val() {
|
||||
Ok(signed) => Ok(match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
||||
Ok(e) => Some(TraceResults::from(e)),
|
||||
_ => None,
|
||||
}),
|
||||
Err(e) => Err(errors::invalid_params("Transaction is not valid RLP", e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn replay_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<Option<TraceResults>, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256, _)>(params)
|
||||
.and_then(|(transaction_hash, flags)| {
|
||||
match take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags)) {
|
||||
Ok(e) => Ok(to_value(&TraceResults::from(e))),
|
||||
_ => Ok(Value::Null),
|
||||
}
|
||||
})
|
||||
|
||||
Ok(match take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags)) {
|
||||
Ok(e) => Some(TraceResults::from(e)),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,14 @@
|
||||
//! method calls properly.
|
||||
|
||||
mod eth;
|
||||
mod manage_network;
|
||||
mod net;
|
||||
mod web3;
|
||||
mod personal;
|
||||
mod parity;
|
||||
mod parity_accounts;
|
||||
mod parity_set;
|
||||
mod personal;
|
||||
mod rpc;
|
||||
mod signer;
|
||||
mod signing;
|
||||
mod manage_network;
|
||||
mod traces;
|
||||
mod web3;
|
||||
|
145
rpc/src/v1/tests/mocked/traces.rs
Normal file
145
rpc/src/v1/tests/mocked/traces.rs
Normal file
@ -0,0 +1,145 @@
|
||||
// Copyright 2015, 2016 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 ethcore::executed::{CallType, Executed};
|
||||
use ethcore::trace::trace::{Action, Res, Call};
|
||||
use ethcore::trace::LocalizedTrace;
|
||||
use ethcore::client::{TestBlockChainClient};
|
||||
|
||||
use jsonrpc_core::{IoHandler, GenericIoHandler};
|
||||
use v1::tests::helpers::{TestMinerService};
|
||||
use v1::{Traces, TracesClient};
|
||||
|
||||
struct Tester {
|
||||
_client: Arc<TestBlockChainClient>,
|
||||
_miner: Arc<TestMinerService>,
|
||||
io: IoHandler,
|
||||
}
|
||||
|
||||
fn io() -> Tester {
|
||||
let client = Arc::new(TestBlockChainClient::new());
|
||||
*client.traces.write() = Some(vec![LocalizedTrace {
|
||||
action: Action::Call(Call {
|
||||
from: 0xf.into(),
|
||||
to: 0x10.into(),
|
||||
value: 0x1.into(),
|
||||
gas: 0x100.into(),
|
||||
input: vec![1, 2, 3],
|
||||
call_type: CallType::Call,
|
||||
}),
|
||||
result: Res::None,
|
||||
subtraces: 0,
|
||||
trace_address: vec![0],
|
||||
transaction_number: 0,
|
||||
transaction_hash: 5.into(),
|
||||
block_number: 10,
|
||||
block_hash: 10.into(),
|
||||
}]);
|
||||
*client.execution_result.write() = Some(Ok(Executed {
|
||||
gas: 20_000.into(),
|
||||
gas_used: 10_000.into(),
|
||||
refunded: 0.into(),
|
||||
cumulative_gas_used: 10_000.into(),
|
||||
logs: vec![],
|
||||
contracts_created: vec![],
|
||||
output: vec![1, 2, 3],
|
||||
trace: vec![],
|
||||
vm_trace: None,
|
||||
state_diff: None,
|
||||
}));
|
||||
let miner = Arc::new(TestMinerService::default());
|
||||
let traces = TracesClient::new(&client, &miner);
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(traces.to_delegate());
|
||||
|
||||
Tester {
|
||||
_client: client,
|
||||
_miner: miner,
|
||||
io: io,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_filter() {
|
||||
let tester = io();
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_filter","params": [{}],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_block() {
|
||||
let tester = io();
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_block","params": ["0x10"],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_transaction() {
|
||||
let tester = io();
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_transaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005"],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_get() {
|
||||
let tester = io();
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_get","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["0","0","0"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_call() {
|
||||
let tester = io();
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_raw_transaction() {
|
||||
let tester = io();
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_trace_replay_transaction() {
|
||||
let tester = io();
|
||||
|
||||
let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
@ -16,43 +16,39 @@
|
||||
|
||||
//! Traces specific rpc interface.
|
||||
|
||||
use std::sync::Arc;
|
||||
use jsonrpc_core::{Params, Value, Error, IoDelegate};
|
||||
use jsonrpc_core::Error;
|
||||
use jsonrpc_macros::Trailing;
|
||||
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
||||
|
||||
/// Traces specific rpc interface.
|
||||
pub trait Traces: Sized + Send + Sync + 'static {
|
||||
/// Returns traces matching given filter.
|
||||
fn filter(&self, _: Params) -> Result<Value, Error>;
|
||||
build_rpc_trait! {
|
||||
/// Traces specific rpc interface.
|
||||
pub trait Traces {
|
||||
/// Returns traces matching given filter.
|
||||
#[rpc(name = "trace_filter")]
|
||||
fn filter(&self, TraceFilter) -> Result<Vec<LocalizedTrace>, Error>;
|
||||
|
||||
/// Returns transaction trace at given index.
|
||||
fn trace(&self, _: Params) -> Result<Value, Error>;
|
||||
/// Returns transaction trace at given index.
|
||||
#[rpc(name = "trace_get")]
|
||||
fn trace(&self, H256, Vec<Index>) -> Result<Option<LocalizedTrace>, Error>;
|
||||
|
||||
/// Returns all traces of given transaction.
|
||||
fn transaction_traces(&self, _: Params) -> Result<Value, Error>;
|
||||
/// Returns all traces of given transaction.
|
||||
#[rpc(name = "trace_transaction")]
|
||||
fn transaction_traces(&self, H256) -> Result<Vec<LocalizedTrace>, Error>;
|
||||
|
||||
/// Returns all traces produced at given block.
|
||||
fn block_traces(&self, _: Params) -> Result<Value, Error>;
|
||||
/// Returns all traces produced at given block.
|
||||
#[rpc(name = "trace_block")]
|
||||
fn block_traces(&self, BlockNumber) -> Result<Vec<LocalizedTrace>, Error>;
|
||||
|
||||
/// Executes the given call and returns a number of possible traces for it.
|
||||
fn call(&self, _: Params) -> Result<Value, Error>;
|
||||
/// Executes the given call and returns a number of possible traces for it.
|
||||
#[rpc(name = "trace_call")]
|
||||
fn call(&self, CallRequest, Vec<String>, Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error>;
|
||||
|
||||
/// Executes the given raw transaction and returns a number of possible traces for it.
|
||||
fn raw_transaction(&self, _: Params) -> Result<Value, Error>;
|
||||
/// Executes the given raw transaction and returns a number of possible traces for it.
|
||||
#[rpc(name = "trace_rawTransaction")]
|
||||
fn raw_transaction(&self, Bytes, Vec<String>, Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error>;
|
||||
|
||||
/// Executes the transaction with the given hash and returns a number of possible traces for it.
|
||||
fn replay_transaction(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Should be used to convert object to io delegate.
|
||||
fn to_delegate(self) -> IoDelegate<Self> {
|
||||
let mut delegate = IoDelegate::new(Arc::new(self));
|
||||
delegate.add_method("trace_filter", Traces::filter);
|
||||
delegate.add_method("trace_get", Traces::trace);
|
||||
delegate.add_method("trace_transaction", Traces::transaction_traces);
|
||||
delegate.add_method("trace_block", Traces::block_traces);
|
||||
delegate.add_method("trace_call", Traces::call);
|
||||
delegate.add_method("trace_rawTransaction", Traces::raw_transaction);
|
||||
delegate.add_method("trace_replayTransaction", Traces::replay_transaction);
|
||||
|
||||
delegate
|
||||
/// Executes the transaction with the given hash and returns a number of possible traces for it.
|
||||
#[rpc(name = "trace_replayTransaction")]
|
||||
fn replay_transaction(&self, H256, Vec<String>) -> Result<Option<TraceResults>, Error>;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user