diff --git a/Cargo.lock b/Cargo.lock index 95b19ce35..8930a592f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,16 +233,6 @@ dependencies = [ "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cargo_metadata" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cc" version = "1.0.0" @@ -287,14 +277,6 @@ dependencies = [ "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "clippy" -version = "0.0.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clippy_lints 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clippy" version = "0.0.103" @@ -303,29 +285,6 @@ dependencies = [ "clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "clippy" -version = "0.0.163" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clippy_lints" -version = "0.0.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clippy_lints" version = "0.0.103" @@ -340,24 +299,6 @@ dependencies = [ "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "clippy_lints" -version = "0.0.163" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "itertools 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "coco" version = "0.1.1" @@ -542,9 +483,10 @@ dependencies = [ [[package]] name = "ethabi" -version = "2.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -583,9 +525,6 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethcore-devtools 1.9.0", "ethcore-io 1.9.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", - "ethcore-ipc-nano 1.9.0", "ethcore-logger 1.9.0", "ethcore-stratum 1.9.0", "ethcore-util 1.9.0", @@ -601,11 +540,14 @@ dependencies = [ "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", + "kvdb-rocksdb 0.1.0", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", + "memory-cache 0.1.0", "memorydb 0.1.0", "migration 0.1.0", "native-contracts 0.1.0", @@ -676,68 +618,6 @@ dependencies = [ "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ethcore-ipc" -version = "1.9.0" -dependencies = [ - "ethcore-bigint 0.1.3", - "ethcore-devtools 1.9.0", - "ethcore-util 1.9.0", - "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ethcore-ipc-codegen" -version = "1.9.0" -dependencies = [ - "aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ethcore-ipc-hypervisor" -version = "1.2.0" -dependencies = [ - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", - "ethcore-ipc-nano 1.9.0", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ethcore-ipc-nano" -version = "1.9.0" -dependencies = [ - "ethcore-ipc 1.9.0", - "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", -] - -[[package]] -name = "ethcore-ipc-tests" -version = "0.1.0" -dependencies = [ - "ethcore-bytes 0.1.0", - "ethcore-devtools 1.9.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", - "ethcore-ipc-nano 1.9.0", - "ethcore-util 1.9.0", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ethcore-light" version = "1.9.0" @@ -748,8 +628,6 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethcore-devtools 1.9.0", "ethcore-io 1.9.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", "ethcore-network 1.9.0", "ethcore-util 1.9.0", "evm 0.1.0", @@ -758,7 +636,10 @@ dependencies = [ "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", + "kvdb-rocksdb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-cache 0.1.0", "memorydb 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "patricia_trie 0.1.0", @@ -827,14 +708,10 @@ name = "ethcore-secretstore" version = "1.0.0" dependencies = [ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.9.0", "ethcore-bigint 0.1.3", "ethcore-bytes 0.1.0", "ethcore-devtools 1.9.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", - "ethcore-ipc-nano 1.9.0", "ethcore-logger 1.9.0", "ethcore-util 1.9.0", "ethcrypto 0.1.0", @@ -844,6 +721,7 @@ dependencies = [ "hash 0.1.0", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", + "kvdb-rocksdb 0.1.0", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "native-contracts 0.1.0", @@ -867,9 +745,6 @@ dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.1.3", "ethcore-devtools 1.9.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", - "ethcore-ipc-nano 1.9.0", "ethcore-logger 1.9.0", "ethcore-util 1.9.0", "hash 0.1.0", @@ -889,7 +764,6 @@ dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)", "ethcore-bigint 0.1.3", "ethcore-bytes 0.1.0", @@ -899,9 +773,9 @@ dependencies = [ "hashdb 0.1.0", "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", "libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "patricia_trie 0.1.0", @@ -1013,9 +887,6 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethcore-devtools 1.9.0", "ethcore-io 1.9.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", - "ethcore-ipc-nano 1.9.0", "ethcore-light 1.9.0", "ethcore-network 1.9.0", "ethcore-util 1.9.0", @@ -1024,6 +895,7 @@ dependencies = [ "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1047,6 +919,7 @@ dependencies = [ "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-cache 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", @@ -1351,17 +1224,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ipc-common-types" -version = "1.9.0" -dependencies = [ - "ethcore-bigint 0.1.3", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", - "ethcore-util 1.9.0", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ipnetwork" version = "0.12.7" @@ -1385,14 +1247,6 @@ dependencies = [ "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "itertools" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itoa" version = "0.3.4" @@ -1508,10 +1362,26 @@ version = "0.1.0" dependencies = [ "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-bigint 0.1.3", "ethcore-bytes 0.1.0", +] + +[[package]] +name = "kvdb-memorydb" +version = "0.1.0" +dependencies = [ + "kvdb 0.1.0", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.0", +] + +[[package]] +name = "kvdb-rocksdb" +version = "0.1.0" +dependencies = [ + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.1.3", "ethcore-devtools 1.9.0", - "hashdb 0.1.0", + "kvdb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1645,6 +1515,14 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memory-cache" +version = "0.1.0" +dependencies = [ + "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "memorydb" version = "0.1.0" @@ -1662,8 +1540,10 @@ dependencies = [ name = "migration" version = "0.1.0" dependencies = [ + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-devtools 1.9.0", "kvdb 0.1.0", + "kvdb-rocksdb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", ] @@ -1781,29 +1661,11 @@ dependencies = [ "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "nanomsg" -version = "0.5.1" -source = "git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920" -dependencies = [ - "libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "nanomsg-sys 0.5.0 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", -] - -[[package]] -name = "nanomsg-sys" -version = "0.5.0" -source = "git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920" -dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "native-contract-generator" version = "0.1.0" dependencies = [ - "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1812,7 +1674,7 @@ name = "native-contracts" version = "0.1.0" dependencies = [ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.1.3", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "native-contract-generator 0.1.0", @@ -1853,7 +1715,7 @@ dependencies = [ "ethcore-network 1.9.0", "ethcore-util 1.9.0", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "native-contracts 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2065,10 +1927,6 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethcore-devtools 1.9.0", "ethcore-io 1.9.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-hypervisor 1.2.0", - "ethcore-ipc-nano 1.9.0", - "ethcore-ipc-tests 0.1.0", "ethcore-light 1.9.0", "ethcore-logger 1.9.0", "ethcore-network 1.9.0", @@ -2085,6 +1943,7 @@ dependencies = [ "isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", "kvdb 0.1.0", + "kvdb-rocksdb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "migration 0.1.0", "node-filter 1.9.0", @@ -2106,7 +1965,7 @@ dependencies = [ "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.0", - "rpassword 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "rpc-cli 1.4.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2175,7 +2034,7 @@ name = "parity-dapps-glue" version = "1.9.0" dependencies = [ "aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", "quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2189,7 +2048,7 @@ dependencies = [ name = "parity-hash-fetch" version = "1.9.0" dependencies = [ - "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.1.3", "ethcore-bytes 0.1.0", "ethcore-util 1.9.0", @@ -2231,6 +2090,7 @@ dependencies = [ "ethcore-util 1.9.0", "ethkey 0.2.0", "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.0", "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2267,7 +2127,6 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethcore-devtools 1.9.0", "ethcore-io 1.9.0", - "ethcore-ipc 1.9.0", "ethcore-light 1.9.0", "ethcore-logger 1.9.0", "ethcore-network 1.9.0", @@ -2288,7 +2147,7 @@ dependencies = [ "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", "jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", "jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)", - "kvdb 0.1.0", + "kvdb-memorydb 0.1.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2375,21 +2234,19 @@ dependencies = [ name = "parity-updater" version = "1.9.0" dependencies = [ - "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.9.0", "ethcore-bigint 0.1.3", "ethcore-bytes 0.1.0", - "ethcore-ipc 1.9.0", - "ethcore-ipc-codegen 1.9.0", "ethcore-util 1.9.0", "ethsync 1.9.0", "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "ipc-common-types 1.9.0", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.9.0", "parity-reactor 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "path 0.1.0", + "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2615,15 +2472,6 @@ dependencies = [ "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "pulldown-cmark" -version = "0.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "quasi" version = "0.32.0" @@ -2818,23 +2666,12 @@ dependencies = [ [[package]] name = "rpassword" -version = "0.2.3" +version = "1.0.2" 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.31 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rpassword" -version = "0.3.1" -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.31 (registry+https://github.com/rust-lang/crates.io-index)", - "termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rprompt 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2847,9 +2684,14 @@ dependencies = [ "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rpc 1.9.0", "parity-rpc-client 1.4.0", - "rpassword 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rprompt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rust-crypto" version = "0.2.36" @@ -3229,14 +3071,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "termios" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "textwrap" version = "0.8.0" @@ -3514,6 +3348,7 @@ version = "0.1.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.1.3", + "kvdb 0.1.0", "rlp 0.2.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3681,17 +3516,12 @@ dependencies = [ "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" "checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" -"checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34aa7da06f10541fbca6850719cdaa8fa03060a5d2fb33840f149cf8133a00c7" "checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2" "checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32" -"checksum clippy 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad3f3dc94d81a6505eb28bf545b501fc9d7525ee9864df5a4b2b6d82629f038" -"checksum clippy 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "d19bda68c3db98e3a780342f6101b44312fef20a5f13ce756d1202a35922b01b" "checksum clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "ce96ec05bfe018a0d5d43da115e54850ea2217981ff0f2e462780ab9d594651a" -"checksum clippy_lints 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)" = "c058b299bb1289c7e8c063bd49477715c91cb3c3344bcf2e25326860b0675654" -"checksum clippy_lints 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "3d4ed67c69b9bb35169be2538691d290a3aa0cbfd4b9f0bfb7c221fc1d399a96" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" "checksum cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d53b80dde876f47f03cda35303e368a79b91c70b0d65ecba5fd5280944a08591" @@ -3713,7 +3543,7 @@ dependencies = [ "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143" "checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "" -"checksum ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3d62319ee0f35abf20afe8859dd2668195912614346447bb2dee9fb8da7c62" +"checksum ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819a3adef0413a2519cbd9a19a35dd1c20c7a0110705beaba8aa4aa87eda95f" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" @@ -3742,7 +3572,6 @@ dependencies = [ "checksum ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2134e210e2a024b5684f90e1556d5f71a1ce7f8b12e9ac9924c67fb36f63b336" "checksum isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fa500db770a99afe2a0f2229be2a3d09c7ed9d7e4e8440bf71253141994e240f" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" -"checksum itertools 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ab4d6a273c31ef276c917019239588b23bc696f277af8db10742cba3c27ec2f0" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "" "checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "" @@ -3781,8 +3610,6 @@ dependencies = [ "checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958" "checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6" "checksum multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d14363c7695e2e5adbbb8fe139d806a19b8b13f02b9b1fb770fab0c12edaff58" -"checksum nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "" -"checksum nanomsg-sys 0.5.0 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "" "checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" "checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2" @@ -3825,7 +3652,6 @@ dependencies = [ "checksum primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56ea4531dde757b56906493c8604641da14607bf9cdaa80fb9c9cabd2429f8d5" "checksum primal-sieve 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e058e7a369c70c0103d138ef71f052a48b102592aadb8ca38ee80d85d303e1de" "checksum protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "568a15e4d572d9a5e63ae3a55f84328c984842887db179b40b4cc6a608bac6a4" -"checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" "checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3" "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4" @@ -3846,8 +3672,8 @@ dependencies = [ "checksum rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)" = "" "checksum rocksdb-sys 0.3.0 (git+https://github.com/paritytech/rust-rocksdb)" = "" "checksum rotor 0.6.3 (git+https://github.com/tailhook/rotor)" = "" -"checksum rpassword 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "320da1dfcf5c570a6c07ff60bb7cd4cdc986d2ea89caea139f2247371ab6a1df" -"checksum rpassword 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec4bdede957362ec6fdd550f7e79c6d14cad2bc26b2d062786234c6ee0cb27bb" +"checksum rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b273c91bd242ca03ad6d71c143b6f17a48790e61f21a6c78568fa2b6774a24a4" +"checksum rprompt 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1601f32bc5858aae3cbfa1c645c96c4d820cc5c16be0194f089560c00b6eb625" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" @@ -3895,7 +3721,6 @@ dependencies = [ "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209" -"checksum termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a" "checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd" "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" diff --git a/Cargo.toml b/Cargo.toml index cf208330d..ccdb46b56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ clap = "2" time = "0.1" num_cpus = "1.2" number_prefix = "0.2" -rpassword = "0.2.1" +rpassword = "1.0" semver = "0.6" ansi_term = "0.9" parking_lot = "0.4" @@ -39,9 +39,6 @@ ethcore-bytes = { path = "util/bytes" } ethcore-bigint = { path = "util/bigint" } ethcore-io = { path = "util/io" } ethcore-devtools = { path = "devtools" } -ethcore-ipc = { path = "ipc/rpc" } -ethcore-ipc-nano = { path = "ipc/nano" } -ethcore-ipc-hypervisor = { path = "ipc/hypervisor" } ethcore-light = { path = "ethcore/light" } ethcore-logger = { path = "logger" } ethcore-stratum = { path = "stratum" } @@ -64,6 +61,7 @@ panic_hook = { path = "panic_hook" } hash = { path = "util/hash" } migration = { path = "util/migration" } kvdb = { path = "util/kvdb" } +kvdb-rocksdb = { path = "util/kvdb-rocksdb" } parity-dapps = { path = "dapps", optional = true } clippy = { version = "0.0.103", optional = true} @@ -73,7 +71,6 @@ ethcore-secretstore = { path = "secret_store", optional = true } rustc_version = "0.2" [dev-dependencies] -ethcore-ipc-tests = { path = "ipc/tests" } pretty_assertions = "0.1" ipnetwork = "0.12.6" @@ -95,7 +92,6 @@ ui-precompiled = [ ] ui-enabled = ["dapps"] dapps = ["parity-dapps"] -ipc = ["ethcore/ipc", "ethsync/ipc"] jit = ["ethcore/jit"] dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "parity-rpc/dev", "parity-dapps/dev"] json-tests = ["ethcore/json-tests"] diff --git a/dapps/js-glue/Cargo.toml b/dapps/js-glue/Cargo.toml index 843168fb7..76c5457d7 100644 --- a/dapps/js-glue/Cargo.toml +++ b/dapps/js-glue/Cargo.toml @@ -18,7 +18,7 @@ quasi = { version = "0.32", default-features = false } quasi_macros = { version = "0.32", optional = true } syntex = { version = "0.58", optional = true } syntex_syntax = { version = "0.58", optional = true } -clippy = { version = "0.0.90", optional = true } +clippy = { version = "0.0.103", optional = true } [features] dev = ["clippy"] diff --git a/dapps/src/tests/helpers/mod.rs b/dapps/src/tests/helpers/mod.rs index 4ee21c8f4..81ed5ed41 100644 --- a/dapps/src/tests/helpers/mod.rs +++ b/dapps/src/tests/helpers/mod.rs @@ -268,7 +268,7 @@ impl Server { }; let mut allowed_hosts: Option> = allowed_hosts.into(); - allowed_hosts.as_mut().map(|mut hosts| { + allowed_hosts.as_mut().map(|hosts| { hosts.push(format!("http://*.{}:*", DAPPS_DOMAIN).into()); hosts.push(format!("http://*.{}", DAPPS_DOMAIN).into()); }); diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index d9df99f9e..b379c3fea 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -5,10 +5,6 @@ license = "GPL-3.0" name = "ethcore" version = "1.9.0" authors = ["Parity Technologies "] -build = "build.rs" - -[build-dependencies] -"ethcore-ipc-codegen" = { path = "../ipc/codegen" } [dependencies] ansi_term = "0.9" @@ -26,12 +22,11 @@ memorydb = { path = "../util/memorydb" } patricia_trie = { path = "../util/patricia_trie" } ethcore-devtools = { path = "../devtools" } ethcore-io = { path = "../util/io" } -ethcore-ipc = { path = "../ipc/rpc" } -ethcore-ipc-nano = { path = "../ipc/nano" } ethcore-logger = { path = "../logger" } ethcore-stratum = { path = "../stratum" } ethcore-util = { path = "../util" } ethcore-bigint = { path = "../util/bigint" } +memory-cache = { path = "../util/memory_cache" } ethjson = { path = "../json" } ethkey = { path = "../ethkey" } ethstore = { path = "../ethstore" } @@ -56,6 +51,8 @@ rand = "0.3" rlp = { path = "../util/rlp" } rlp_derive = { path = "../util/rlp_derive" } kvdb = { path = "../util/kvdb" } +kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } +kvdb-memorydb = { path = "../util/kvdb-memorydb" } util-error = { path = "../util/error" } snappy = { path = "../util/snappy" } migration = { path = "../util/migration" } @@ -88,4 +85,3 @@ test-heavy = [] dev = ["clippy"] default = [] benches = [] -ipc = [] diff --git a/ethcore/build.rs b/ethcore/build.rs deleted file mode 100644 index 8fe38e757..000000000 --- a/ethcore/build.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen; - -fn main() { - ethcore_ipc_codegen::derive_ipc_cond("src/client/traits.rs", cfg!(feature="ipc")).unwrap(); - ethcore_ipc_codegen::derive_ipc_cond("src/snapshot/snapshot_service_trait.rs", cfg!(feature="ipc")).unwrap(); - ethcore_ipc_codegen::derive_ipc_cond("src/client/chain_notify.rs", cfg!(feature="ipc")).unwrap(); -} diff --git a/ethcore/evm/Cargo.toml b/ethcore/evm/Cargo.toml index 17b866428..5cef517f4 100644 --- a/ethcore/evm/Cargo.toml +++ b/ethcore/evm/Cargo.toml @@ -14,6 +14,7 @@ log = "0.3" vm = { path = "../vm" } hash = { path = "../../util/hash" } parking_lot = "0.4" +memory-cache = { path = "../../util/memory_cache" } [dev-dependencies] rustc-hex = "1.0" diff --git a/ethcore/evm/src/interpreter/shared_cache.rs b/ethcore/evm/src/interpreter/shared_cache.rs index 7b3b33b70..d0386b194 100644 --- a/ethcore/evm/src/interpreter/shared_cache.rs +++ b/ethcore/evm/src/interpreter/shared_cache.rs @@ -19,7 +19,7 @@ use hash::KECCAK_EMPTY; use heapsize::HeapSizeOf; use bigint::hash::H256; use parking_lot::Mutex; -use util::cache::MemoryLruCache; +use memory_cache::MemoryLruCache; use bit_set::BitSet; use super::super::instructions; diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index efc88d60d..7ddbed19e 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -23,6 +23,7 @@ extern crate parking_lot; extern crate heapsize; extern crate vm; extern crate hash; +extern crate memory_cache; #[macro_use] extern crate lazy_static; diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index fb7030bcc..2b56a30bd 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -5,10 +5,6 @@ license = "GPL-3.0" name = "ethcore-light" version = "1.9.0" authors = ["Parity Technologies "] -build = "build.rs" - -[build-dependencies] -"ethcore-ipc-codegen" = { path = "../../ipc/codegen", optional = true } [dependencies] log = "0.3" @@ -20,7 +16,6 @@ memorydb = { path = "../../util/memorydb" } patricia_trie = { path = "../../util/patricia_trie" } ethcore-network = { path = "../../util/network" } ethcore-io = { path = "../../util/io" } -ethcore-ipc = { path = "../../ipc/rpc", optional = true } ethcore-devtools = { path = "../../devtools" } evm = { path = "../evm" } heapsize = "0.4" @@ -40,7 +35,9 @@ stats = { path = "../../util/stats" } hash = { path = "../../util/hash" } triehash = { path = "../../util/triehash" } kvdb = { path = "../../util/kvdb" } +kvdb-rocksdb = { path = "../../util/kvdb-rocksdb" } +kvdb-memorydb = { path = "../../util/kvdb-memorydb" } +memory-cache = { path = "../../util/memory_cache" } [features] default = [] -ipc = ["ethcore-ipc", "ethcore-ipc-codegen"] diff --git a/ethcore/light/build.rs b/ethcore/light/build.rs deleted file mode 100644 index b9c79f778..000000000 --- a/ethcore/light/build.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#[cfg(feature = "ipc")] -extern crate ethcore_ipc_codegen; - -#[cfg(feature = "ipc")] -fn main() { - ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap(); - ethcore_ipc_codegen::derive_ipc_cond("src/provider.rs", true).unwrap(); -} - -#[cfg(not(feature = "ipc"))] -fn main() { } \ No newline at end of file diff --git a/ethcore/light/src/cache.rs b/ethcore/light/src/cache.rs index 65c3a4d0f..8ec6b53af 100644 --- a/ethcore/light/src/cache.rs +++ b/ethcore/light/src/cache.rs @@ -29,7 +29,7 @@ use time::{SteadyTime, Duration}; use heapsize::HeapSizeOf; use bigint::prelude::U256; use bigint::hash::H256; -use util::cache::MemoryLruCache; +use memory_cache::MemoryLruCache; /// Configuration for how much data to cache. #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index c31fd4787..c406da4c9 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -45,7 +45,7 @@ use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp, UntrustedRlp}; use heapsize::HeapSizeOf; use bigint::prelude::U256; use bigint::hash::{H256, H256FastMap, H264}; -use kvdb::{DBTransaction, KeyValueDB}; +use kvdb::{self, DBTransaction, KeyValueDB}; use cache::Cache; use parking_lot::{Mutex, RwLock}; @@ -198,7 +198,7 @@ impl HeaderChain { col: Option, spec: &Spec, cache: Arc>, - ) -> Result { + ) -> Result { let mut live_epoch_proofs = ::std::collections::HashMap::default(); let genesis = ::rlp::encode(&spec.genesis_header()).into_vec(); @@ -240,7 +240,7 @@ impl HeaderChain { let best_block = { let era = match candidates.get(&best_number) { Some(era) => era, - None => return Err(format!("Database corrupt: highest block referenced but no data.")), + None => return Err("Database corrupt: highest block referenced but no data.".into()), }; let best = &era.candidates[0]; @@ -728,13 +728,14 @@ mod tests { use ethcore::header::Header; use ethcore::spec::Spec; use cache::Cache; - use kvdb::{in_memory, KeyValueDB}; + use kvdb::KeyValueDB; + use kvdb_memorydb; use time::Duration; use parking_lot::Mutex; fn make_db() -> Arc { - Arc::new(in_memory(0)) + Arc::new(kvdb_memorydb::create(0)) } #[test] diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index fb0ec3917..a60ad4347 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -36,7 +36,8 @@ use bigint::prelude::U256; use bigint::hash::H256; use futures::{IntoFuture, Future}; -use kvdb::{KeyValueDB, CompactionProfile}; +use kvdb::{self, KeyValueDB}; +use kvdb_rocksdb::CompactionProfile; use self::fetch::ChainDataFetcher; use self::header_chain::{AncestryIter, HeaderChain}; @@ -186,7 +187,7 @@ impl Client { fetcher: T, io_channel: IoChannel, cache: Arc> - ) -> Result { + ) -> Result { Ok(Client { queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, config.check_seal), engine: spec.engine.clone(), @@ -214,7 +215,7 @@ impl Client { io_channel: IoChannel, cache: Arc> ) -> Self { - let db = ::kvdb::in_memory(0); + let db = ::kvdb_memorydb::create(0); Client::new( config, diff --git a/ethcore/light/src/client/service.rs b/ethcore/light/src/client/service.rs index f20d0ad90..b05c7dacb 100644 --- a/ethcore/light/src/client/service.rs +++ b/ethcore/light/src/client/service.rs @@ -25,7 +25,8 @@ use ethcore::db; use ethcore::service::ClientIoMessage; use ethcore::spec::Spec; use io::{IoContext, IoError, IoHandler, IoService}; -use kvdb::{Database, DatabaseConfig}; +use kvdb; +use kvdb_rocksdb::{Database, DatabaseConfig}; use cache::Cache; use parking_lot::Mutex; @@ -36,7 +37,7 @@ use super::{ChainDataFetcher, Client, Config as ClientConfig}; #[derive(Debug)] pub enum Error { /// Database error. - Database(String), + Database(kvdb::Error), /// I/O service error. Io(IoError), } diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index edf655e4d..f9c3d89b8 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -38,21 +38,8 @@ pub mod net; pub mod on_demand; pub mod transaction_queue; pub mod cache; - -#[cfg(not(feature = "ipc"))] pub mod provider; -#[cfg(feature = "ipc")] -pub mod provider { - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/provider.rs")); -} - -#[cfg(feature = "ipc")] -pub mod remote { - pub use provider::LightProviderClient; -} - mod types; pub use self::cache::Cache; @@ -92,9 +79,9 @@ extern crate vm; extern crate hash; extern crate triehash; extern crate kvdb; - -#[cfg(feature = "ipc")] -extern crate ethcore_ipc as ipc; +extern crate kvdb_memorydb; +extern crate kvdb_rocksdb; +extern crate memory_cache; #[cfg(test)] extern crate ethcore_devtools as devtools; diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index 3e2ddcb9d..2e05157ad 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -34,7 +34,6 @@ use transaction_queue::TransactionQueue; use request; /// Defines the operations that a provider for the light subprotocol must fulfill. -#[cfg_attr(feature = "ipc", ipc(client_ident="LightProviderClient"))] pub trait Provider: Send + Sync { /// Provide current blockchain info. fn chain_info(&self) -> BlockChainInfo; @@ -328,7 +327,7 @@ impl Provider for LightProvider { } fn transaction_index(&self, _req: request::CompleteTransactionIndexRequest) - -> Option + -> Option { None } diff --git a/ethcore/light/src/types/mod.rs b/ethcore/light/src/types/mod.rs index 63fe74267..eba551b53 100644 --- a/ethcore/light/src/types/mod.rs +++ b/ethcore/light/src/types/mod.rs @@ -14,11 +14,4 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Types used in the public (IPC) api which require custom code generation. -#![cfg_attr(feature = "ipc", allow(dead_code, unused_assignments, unused_variables))] // codegen issues - -#[cfg(feature = "ipc")] -include!(concat!(env!("OUT_DIR"), "/mod.rs.in")); - -#[cfg(not(feature = "ipc"))] -include!("mod.rs.in"); +pub mod request; diff --git a/ethcore/light/src/types/mod.rs.in b/ethcore/light/src/types/mod.rs.in deleted file mode 100644 index eba551b53..000000000 --- a/ethcore/light/src/types/mod.rs.in +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -pub mod request; diff --git a/ethcore/light/src/types/request/mod.rs b/ethcore/light/src/types/request/mod.rs index 050c79be8..2754e37eb 100644 --- a/ethcore/light/src/types/request/mod.rs +++ b/ethcore/light/src/types/request/mod.rs @@ -204,7 +204,6 @@ pub enum OutputKind { /// Either a hash or a number. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub enum HashOrNumber { /// Block hash variant. Hash(H256), diff --git a/ethcore/native_contracts/Cargo.toml b/ethcore/native_contracts/Cargo.toml index 2f91a4848..2cc88fcdc 100644 --- a/ethcore/native_contracts/Cargo.toml +++ b/ethcore/native_contracts/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Parity Technologies "] build = "build.rs" [dependencies] -ethabi = "2.0" +ethabi = "4.0" futures = "0.1" byteorder = "1.0" ethcore-bigint = { path = "../../util/bigint" } diff --git a/ethcore/native_contracts/generator/Cargo.toml b/ethcore/native_contracts/generator/Cargo.toml index a599e756e..243a5f597 100644 --- a/ethcore/native_contracts/generator/Cargo.toml +++ b/ethcore/native_contracts/generator/Cargo.toml @@ -5,5 +5,5 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -ethabi = "2.0" +ethabi = "4.0" heck = "0.2" diff --git a/ethcore/native_contracts/generator/src/lib.rs b/ethcore/native_contracts/generator/src/lib.rs index 458947313..a8848503e 100644 --- a/ethcore/native_contracts/generator/src/lib.rs +++ b/ethcore/native_contracts/generator/src/lib.rs @@ -21,18 +21,17 @@ //! due to missing crates or name collisions. This will change when //! it can be ported to a procedural macro. -use ethabi::Contract; -use ethabi::spec::{Interface, ParamType, Error as AbiError}; -use heck::SnakeCase; - extern crate ethabi; extern crate heck; +use ethabi::{Contract, ParamType}; +use heck::SnakeCase; + /// Errors in generation. #[derive(Debug)] pub enum Error { /// Bad ABI. - Abi(AbiError), + Abi(ethabi::Error), /// Unsupported parameter type in given function. UnsupportedType(String, ParamType), } @@ -41,13 +40,13 @@ pub enum Error { /// a struct which can be used to call it. // TODO: make this a proc macro when that's possible. pub fn generate_module(struct_name: &str, abi: &str) -> Result { - let contract = Contract::new(Interface::load(abi.as_bytes()).map_err(Error::Abi)?); + let contract = Contract::load(abi.as_bytes()).map_err(Error::Abi)?; let functions = generate_functions(&contract)?; Ok(format!(r##" use byteorder::{{BigEndian, ByteOrder}}; use futures::{{future, Future, IntoFuture}}; -use ethabi::{{Contract, Interface, Token, Event}}; +use ethabi::{{Contract, Token, Event}}; use bigint; type BoxFuture = Box + Send>; @@ -66,8 +65,8 @@ impl {name} {{ /// Create a new instance of `{name}` with an address. /// Calls can be made, given a callback for dispatching calls asynchronously. pub fn new(address: bigint::prelude::H160) -> Self {{ - let contract = Contract::new(Interface::load(ABI.as_bytes()) - .expect("ABI checked at generation-time; qed")); + let contract = Contract::load(ABI.as_bytes()) + .expect("ABI checked at generation-time; qed"); {name} {{ contract: contract, address: address, @@ -92,16 +91,16 @@ impl {name} {{ fn generate_functions(contract: &Contract) -> Result { let mut functions = String::new(); for function in contract.functions() { - let name = function.name(); + let name = &function.name; let snake_name = name.to_snake_case(); - let inputs = function.input_params(); - let outputs = function.output_params(); + let inputs: Vec<_> = function.inputs.iter().map(|i| i.kind.clone()).collect(); + let outputs: Vec<_> = function.outputs.iter().map(|i| i.kind.clone()).collect(); let (input_params, to_tokens) = input_params_codegen(&inputs) - .map_err(|bad_type| Error::UnsupportedType(name.into(), bad_type))?; + .map_err(|bad_type| Error::UnsupportedType(name.clone(), bad_type))?; let (output_type, decode_outputs) = output_params_codegen(&outputs) - .map_err(|bad_type| Error::UnsupportedType(name.into(), bad_type))?; + .map_err(|bad_type| Error::UnsupportedType(name.clone(), bad_type))?; functions.push_str(&format!(r##" /// Call the function "{abi_name}" on the contract. @@ -115,17 +114,17 @@ pub fn {snake_name}(&self, call: F, {params}) -> BoxFuture<{output_type}, U::Future: Send + 'static {{ let function = self.contract.function(r#"{abi_name}"#) - .expect("function existence checked at compile-time; qed"); + .expect("function existence checked at compile-time; qed").clone(); let call_addr = self.address; - let call_future = match function.encode_call({to_tokens}) {{ + let call_future = match function.encode_input(&{to_tokens}) {{ Ok(call_data) => (call)(call_addr, call_data), Err(e) => return Box::new(future::err(format!("Error encoding call: {{:?}}", e))), }}; Box::new(call_future .into_future() - .and_then(move |out| function.decode_output(out).map_err(|e| format!("{{:?}}", e))) + .and_then(move |out| function.decode_output(&out).map_err(|e| format!("{{:?}}", e))) .map(Vec::into_iter) .and_then(|mut outputs| {decode_outputs})) }} @@ -325,7 +324,7 @@ fn detokenize(name: &str, output_type: ParamType) -> String { #[cfg(test)] mod tests { - use ethabi::spec::ParamType; + use ethabi::ParamType; #[test] fn input_types() { diff --git a/ethcore/node_filter/Cargo.toml b/ethcore/node_filter/Cargo.toml index 9ebbf1e18..7879074ff 100644 --- a/ethcore/node_filter/Cargo.toml +++ b/ethcore/node_filter/Cargo.toml @@ -11,10 +11,12 @@ ethcore = { path = ".."} ethcore-util = { path = "../../util" } ethcore-bigint = { path = "../../util/bigint" } ethcore-bytes = { path = "../../util/bytes" } -ethcore-io = { path = "../../util/io" } ethcore-network = { path = "../../util/network" } -kvdb = { path = "../../util/kvdb" } native-contracts = { path = "../native_contracts" } futures = "0.1" log = "0.3" parking_lot = "0.4" + +[dev-dependencies] +kvdb-memorydb = { path = "../../util/kvdb-memorydb" } +ethcore-io = { path = "../../util/io" } diff --git a/ethcore/node_filter/src/lib.rs b/ethcore/node_filter/src/lib.rs index e92dba61d..d2c64cb39 100644 --- a/ethcore/node_filter/src/lib.rs +++ b/ethcore/node_filter/src/lib.rs @@ -24,9 +24,14 @@ extern crate ethcore_network as network; extern crate native_contracts; extern crate futures; extern crate parking_lot; -extern crate kvdb; -#[cfg(test)] extern crate ethcore_io as io; -#[macro_use] extern crate log; + +#[macro_use] +extern crate log; + +#[cfg(test)] +extern crate kvdb_memorydb; +#[cfg(test)] +extern crate ethcore_io as io; use std::sync::Weak; use std::collections::HashMap; @@ -135,7 +140,7 @@ mod test { let contract_addr = Address::from_str("0000000000000000000000000000000000000005").unwrap(); let data = include_bytes!("../res/node_filter.json"); let spec = Spec::load(&::std::env::temp_dir(), &data[..]).unwrap(); - let client_db = Arc::new(::kvdb::in_memory(::ethcore::db::NUM_COLUMNS.unwrap_or(0))); + let client_db = Arc::new(::kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0))); let client = Client::new( ClientConfig::default(), diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index a55cf669f..8e71d5f42 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -1479,7 +1479,8 @@ mod tests { use std::sync::Arc; use rustc_hex::FromHex; use hash::keccak; - use kvdb::{in_memory, KeyValueDB}; + use kvdb::KeyValueDB; + use kvdb_memorydb; use bigint::hash::*; use receipt::{Receipt, TransactionOutcome}; use blockchain::{BlockProvider, BlockChain, Config, ImportRoute}; @@ -1493,7 +1494,7 @@ mod tests { use header::BlockNumber; fn new_db() -> Arc { - Arc::new(in_memory(::db::NUM_COLUMNS.unwrap_or(0))) + Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))) } fn new_chain(genesis: &[u8], db: Arc) -> BlockChain { diff --git a/ethcore/src/client/chain_notify.rs b/ethcore/src/client/chain_notify.rs index 00b744167..5dd2861ae 100644 --- a/ethcore/src/client/chain_notify.rs +++ b/ethcore/src/client/chain_notify.rs @@ -14,12 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ipc::IpcConfig; use bigint::hash::H256; use bytes::Bytes; /// Represents what has to be handled by actor listening to chain events -#[ipc] pub trait ChainNotify : Send + Sync { /// fires when chain has new blocks. fn new_blocks( @@ -57,5 +55,3 @@ pub trait ChainNotify : Send + Sync { // does nothing by default } } - -impl IpcConfig for ChainNotify { } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 1b954b347..366b40747 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -29,7 +29,7 @@ use bytes::Bytes; use util::{Address, journaldb, DBValue}; use util_error::UtilError; use trie::{TrieSpec, TrieFactory, Trie}; -use kvdb::*; +use kvdb::{KeyValueDB, DBTransaction}; // other use bigint::prelude::U256; diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index e629732d5..14efb3ec4 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -21,7 +21,7 @@ use std::fmt::{Display, Formatter, Error as FmtError}; use mode::Mode as IpcMode; use verification::{VerifierType, QueueConfig}; use util::journaldb; -use kvdb::CompactionProfile; +use kvdb_rocksdb::CompactionProfile; pub use std::time::Duration; pub use blockchain::Config as BlockChainConfig; diff --git a/ethcore/src/client/error.rs b/ethcore/src/client/error.rs index aaa9fa83f..d2af13a3b 100644 --- a/ethcore/src/client/error.rs +++ b/ethcore/src/client/error.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use util_error::UtilError; use std::fmt::{Display, Formatter, Error as FmtError}; - +use util_error::UtilError; +use kvdb; use trie::TrieError; /// Client configuration errors. @@ -25,7 +25,7 @@ pub enum Error { /// TrieDB-related error. Trie(TrieError), /// Database error - Database(String), + Database(kvdb::Error), /// Util error Util(UtilError), } diff --git a/ethcore/src/client/evm_test_client.rs b/ethcore/src/client/evm_test_client.rs index ff03554f9..55883e189 100644 --- a/ethcore/src/client/evm_test_client.rs +++ b/ethcore/src/client/evm_test_client.rs @@ -21,8 +21,7 @@ use std::sync::Arc; use bigint::prelude::U256; use bigint::hash::H256; use util::journaldb; -use trie; -use bytes; +use {trie, kvdb_memorydb, bytes}; use kvdb::{self, KeyValueDB}; use {state, state_db, client, executive, trace, transaction, db, spec, pod_state}; use factory::Factories; @@ -39,7 +38,7 @@ pub enum EvmTestError { /// Initialization error. ClientError(::error::Error), /// Low-level database error. - Database(String), + Database(kvdb::Error), /// Post-condition failure, PostCondition(String), } @@ -128,7 +127,7 @@ impl<'a> EvmTestClient<'a> { } fn state_from_spec(spec: &'a spec::Spec, factories: &Factories) -> Result, EvmTestError> { - let db = Arc::new(kvdb::in_memory(db::NUM_COLUMNS.expect("We use column-based DB; qed"))); + let db = Arc::new(kvdb_memorydb::create(db::NUM_COLUMNS.expect("We use column-based DB; qed"))); let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, db::COL_STATE); let mut state_db = state_db::StateDB::new(journal_db, 5 * 1024 * 1024); state_db = spec.ensure_db_good(state_db, factories)?; @@ -150,7 +149,7 @@ impl<'a> EvmTestClient<'a> { } fn state_from_pod(spec: &'a spec::Spec, factories: &Factories, pod_state: pod_state::PodState) -> Result, EvmTestError> { - let db = Arc::new(kvdb::in_memory(db::NUM_COLUMNS.expect("We use column-based DB; qed"))); + let db = Arc::new(kvdb_memorydb::create(db::NUM_COLUMNS.expect("We use column-based DB; qed"))); let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, db::COL_STATE); let state_db = state_db::StateDB::new(journal_db, 5 * 1024 * 1024); let mut state = state::State::new( diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 9377c2f44..2960f303d 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -45,21 +45,6 @@ pub use vm::{LastHashes, EnvInfo}; pub use error::{BlockImportError, TransactionImportError, TransactionImportResult}; pub use verification::VerifierType; -/// IPC interfaces -#[cfg(feature="ipc")] -pub mod remote { - pub use super::traits::RemoteClient; - pub use super::chain_notify::ChainNotifyClient; -} - -mod traits { - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/traits.rs")); -} - -pub mod chain_notify { - //! Chain notify interface - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/chain_notify.rs")); -} +mod traits; +mod chain_notify; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 82f969320..4ee3c420c 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -27,7 +27,7 @@ use bigint::prelude::U256; use bigint::hash::H256; use parking_lot::RwLock; use util::*; -use kvdb::{Database, DatabaseConfig}; +use kvdb_rocksdb::{Database, DatabaseConfig}; use bytes::Bytes; use rlp::*; use ethkey::{Generator, Random}; diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index b4fc60f14..3ff60baf9 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -27,7 +27,6 @@ use evm::{Factory as EvmFactory, Schedule}; use executive::Executed; use filter::Filter; use header::{BlockNumber}; -use ipc::IpcConfig; use log_entry::LocalizedLogEntry; use receipt::LocalizedReceipt; use trace::LocalizedTrace; @@ -49,7 +48,6 @@ use types::block_status::BlockStatus; use types::mode::Mode; use types::pruning_info::PruningInfo; -#[ipc(client_ident="RemoteClient")] /// Blockchain database client. Owns and manages a blockchain and a block queue. pub trait BlockChainClient : Sync + Send { @@ -287,8 +285,6 @@ pub trait BlockChainClient : Sync + Send { fn eip86_transition(&self) -> u64; } -impl IpcConfig for BlockChainClient { } - /// Extended client interface used for mining pub trait MiningBlockChainClient: BlockChainClient { /// Returns OpenBlock prepared for closing. diff --git a/ethcore/src/encoded.rs b/ethcore/src/encoded.rs index 1f7ee98b5..27aca1426 100644 --- a/ethcore/src/encoded.rs +++ b/ethcore/src/encoded.rs @@ -37,7 +37,6 @@ use rlp::Rlp; /// Owning header view. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct Header(Vec); impl HeapSizeOf for Header { @@ -115,7 +114,6 @@ impl Header { /// Owning block body view. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct Body(Vec); impl HeapSizeOf for Body { @@ -175,7 +173,6 @@ impl Body { /// Owning block view. #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] pub struct Block(Vec); impl HeapSizeOf for Block { diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 3ccc79baa..97cc18c03 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -782,7 +782,7 @@ mod tests { use block::*; use error::{Error, BlockError}; use header::Header; - use client::chain_notify::ChainNotify; + use client::ChainNotify; use miner::MinerService; use tests::helpers::*; use account_provider::AccountProvider; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 7489a26e0..695f2a658 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -27,7 +27,7 @@ use parking_lot::{Mutex, RwLock}; use util::*; use bytes::Bytes; -use util::cache::MemoryLruCache; +use memory_cache::MemoryLruCache; use unexpected::Mismatch; use rlp::{UntrustedRlp, RlpStream}; @@ -276,7 +276,7 @@ impl ValidatorSafeContract { .filter(move |l| check_log(l)) .filter_map(|log| { let topics = log.topics.iter().map(|x| x.0.clone()).collect(); - event.decode_log(topics, log.data.clone()).ok() + event.parse_log((topics, log.data.clone()).into()).ok() }); match decoded_events.next() { @@ -285,7 +285,7 @@ impl ValidatorSafeContract { // decode log manually until the native contract generator is // good enough to do it for us. - let validators_token = &matched_event[1].value; + let validators_token = &matched_event.params[1].value; let validators = validators_token.clone().to_array() .and_then(|a| a.into_iter() diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 0146c684a..49b873a47 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -29,7 +29,6 @@ use io::*; use header::BlockNumber; use basic_types::LogBloom; use client::Error as ClientError; -use ipc::binary::{BinaryConvertError, BinaryConvertable}; use snapshot::Error as SnapshotError; use engines::EngineError; use ethkey::Error as EthkeyError; @@ -486,21 +485,3 @@ impl From> for Error where Error: From { Error::from(*err) } } - -binary_fixed_size!(BlockError); -binary_fixed_size!(ImportError); -binary_fixed_size!(TransactionError); - -// TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted. -/*#![feature(concat_idents)] -macro_rules! assimilate { - ($name:ident) => ( - impl From for Error { - fn from(err: concat_idents!($name, Error)) -> Error { - Error:: $name (err) - } - } - ) -} -assimilate!(FromHex); -assimilate!(BaseData);*/ diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 75c321ebe..09b272cb3 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -31,7 +31,7 @@ use machine::EthereumMachine; use super::spec::*; /// Most recent fork block that we support on Mainnet. -pub const FORK_SUPPORTED_FOUNDATION: u64 = 2675000; +pub const FORK_SUPPORTED_FOUNDATION: u64 = 4370000; /// Most recent fork block that we support on Ropsten. pub const FORK_SUPPORTED_ROPSTEN: u64 = 10; diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 9bd0d4c94..e82bc7740 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -57,7 +57,7 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec { }; { - let db = Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); + let db = Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))); let mut config = ClientConfig::default(); config.history = 8; let client = Client::new( diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index a67eb879a..ce2b8d346 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -81,7 +81,6 @@ extern crate ethash; extern crate ethcore_bloom_journal as bloom_journal; extern crate ethcore_devtools as devtools; extern crate ethcore_io as io; -extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_bigint as bigint; extern crate ethcore_bytes as bytes; extern crate ethcore_logger; @@ -113,6 +112,8 @@ extern crate ansi_term; extern crate semantic_version; extern crate unexpected; extern crate kvdb; +extern crate kvdb_rocksdb; +extern crate kvdb_memorydb; extern crate util_error; extern crate snappy; extern crate migration; @@ -129,6 +130,7 @@ extern crate bloomable; extern crate vm; extern crate wasm; extern crate ethcore_util as util; +extern crate memory_cache; #[macro_use] extern crate macros; @@ -136,8 +138,6 @@ extern crate macros; extern crate log; #[macro_use] extern crate lazy_static; -#[macro_use] -extern crate ethcore_ipc as ipc; #[cfg_attr(test, macro_use)] extern crate evm; diff --git a/ethcore/src/machine.rs b/ethcore/src/machine.rs index 2536384e6..667211c52 100644 --- a/ethcore/src/machine.rs +++ b/ethcore/src/machine.rs @@ -263,7 +263,7 @@ impl EthereumMachine { } else if block_number < ext.eip150_transition { Schedule::new_homestead() } else { - /// There's no max_code_size transition so we tie it to eip161abc + // There's no max_code_size transition so we tie it to eip161abc let max_code_size = if block_number >= ext.eip161abc_transition { self.params.max_code_size as usize } else { diff --git a/ethcore/src/migrations/state/v7.rs b/ethcore/src/migrations/state/v7.rs index cbf517d1d..b7c9211ff 100644 --- a/ethcore/src/migrations/state/v7.rs +++ b/ethcore/src/migrations/state/v7.rs @@ -22,8 +22,8 @@ use std::collections::HashMap; use bigint::hash::H256; use util::Address; use bytes::Bytes; -use kvdb::Database; -use migration::{Batch, Config, Error, Migration, SimpleMigration, Progress}; +use kvdb_rocksdb::Database; +use migration::{Batch, Config, Error, ErrorKind, Migration, SimpleMigration, Progress}; use hash::keccak; use std::sync::Arc; @@ -109,7 +109,7 @@ impl OverlayRecentV7 { // walk all journal entries in the database backwards. // find migrations for any possible inserted keys. fn walk_journal(&mut self, source: Arc) -> Result<(), Error> { - if let Some(val) = source.get(None, V7_LATEST_ERA_KEY).map_err(Error::Custom)? { + if let Some(val) = source.get(None, V7_LATEST_ERA_KEY)? { let mut era = decode::(&val); loop { let mut index: usize = 0; @@ -120,7 +120,7 @@ impl OverlayRecentV7 { r.out() }; - if let Some(journal_raw) = source.get(None, &entry_key).map_err(Error::Custom)? { + if let Some(journal_raw) = source.get(None, &entry_key)? { let rlp = Rlp::new(&journal_raw); // migrate all inserted keys. @@ -153,7 +153,7 @@ impl OverlayRecentV7 { // replace all possible inserted/deleted keys with their migrated counterparts // and commit the altered entries. fn migrate_journal(&self, source: Arc, mut batch: Batch, dest: &mut Database) -> Result<(), Error> { - if let Some(val) = source.get(None, V7_LATEST_ERA_KEY).map_err(Error::Custom)? { + if let Some(val) = source.get(None, V7_LATEST_ERA_KEY)? { batch.insert(V7_LATEST_ERA_KEY.into(), val.clone().into_vec(), dest)?; let mut era = decode::(&val); @@ -166,7 +166,7 @@ impl OverlayRecentV7 { r.out() }; - if let Some(journal_raw) = source.get(None, &entry_key).map_err(Error::Custom)? { + if let Some(journal_raw) = source.get(None, &entry_key)? { let rlp = Rlp::new(&journal_raw); let id: H256 = rlp.val_at(0); let mut inserted_keys: Vec<(H256, Bytes)> = Vec::new(); @@ -233,9 +233,9 @@ impl Migration for OverlayRecentV7 { let mut batch = Batch::new(config, col); // check version metadata. - match source.get(None, V7_VERSION_KEY).map_err(Error::Custom)? { + match source.get(None, V7_VERSION_KEY)? { Some(ref version) if decode::(&*version) == DB_VERSION => {} - _ => return Err(Error::MigrationImpossible), // missing or wrong version + _ => return Err(ErrorKind::MigrationImpossible.into()), // missing or wrong version } let mut count = 0; diff --git a/ethcore/src/migrations/v10.rs b/ethcore/src/migrations/v10.rs index 155d6f4c0..f0460dd4a 100644 --- a/ethcore/src/migrations/v10.rs +++ b/ethcore/src/migrations/v10.rs @@ -22,11 +22,12 @@ use state_db::{ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET, StateDB}; use trie::TrieDB; use views::HeaderView; use bloom_journal::Bloom; -use migration::{Error, Migration, Progress, Batch, Config}; +use migration::{Error, Migration, Progress, Batch, Config, ErrorKind}; use util::journaldb; use bigint::hash::H256; use trie::Trie; -use kvdb::{Database, DBTransaction}; +use kvdb::{DBTransaction, ResultExt}; +use kvdb_rocksdb::Database; /// Account bloom upgrade routine. If bloom already present, does nothing. /// If database empty (no best block), does nothing. @@ -59,9 +60,9 @@ pub fn generate_bloom(source: Arc, dest: &mut Database) -> Result<(), source.clone(), journaldb::Algorithm::OverlayRecent, COL_STATE); - let account_trie = TrieDB::new(state_db.as_hashdb(), &state_root).map_err(|e| Error::Custom(format!("Cannot open trie: {:?}", e)))?; - for item in account_trie.iter().map_err(|_| Error::MigrationImpossible)? { - let (ref account_key, _) = item.map_err(|_| Error::MigrationImpossible)?; + let account_trie = TrieDB::new(state_db.as_hashdb(), &state_root).chain_err(|| "Cannot open trie")?; + for item in account_trie.iter().map_err(|_| ErrorKind::MigrationImpossible)? { + let (ref account_key, _) = item.map_err(|_| ErrorKind::MigrationImpossible)?; let account_key_hash = H256::from_slice(account_key); bloom.set(&*account_key_hash); } @@ -72,7 +73,7 @@ pub fn generate_bloom(source: Arc, dest: &mut Database) -> Result<(), trace!(target: "migration", "Generated {} bloom updates", bloom_journal.entries.len()); let mut batch = DBTransaction::new(); - StateDB::commit_bloom(&mut batch, bloom_journal).map_err(|_| Error::Custom("Failed to commit bloom".to_owned()))?; + StateDB::commit_bloom(&mut batch, bloom_journal).chain_err(|| "Failed to commit bloom")?; dest.write(batch)?; trace!(target: "migration", "Finished bloom update"); diff --git a/ethcore/src/migrations/v9.rs b/ethcore/src/migrations/v9.rs index 7c28054fa..39637dc4e 100644 --- a/ethcore/src/migrations/v9.rs +++ b/ethcore/src/migrations/v9.rs @@ -18,7 +18,7 @@ //! This migration consolidates all databases into single one using Column Families. use rlp::{Rlp, RlpStream}; -use kvdb::Database; +use kvdb_rocksdb::Database; use migration::{Batch, Config, Error, Migration, Progress}; use std::sync::Arc; diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index 64773a236..078f02d46 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -19,7 +19,8 @@ use std::sync::Arc; use std::path::Path; use bigint::hash::H256; -use kvdb::{Database, DatabaseConfig, KeyValueDB}; +use kvdb::KeyValueDB; +use kvdb_rocksdb::{Database, DatabaseConfig}; use bytes::Bytes; use io::*; use spec::Spec; @@ -29,12 +30,8 @@ use miner::Miner; use snapshot::{ManifestData, RestorationStatus}; use snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; -use std::sync::atomic::AtomicBool; use ansi_term::Colour; -#[cfg(feature="ipc")] -use nanoipc; - /// Message type for external and internal events #[derive(Clone, PartialEq, Eq, Debug)] pub enum ClientIoMessage { @@ -72,7 +69,7 @@ impl ClientService { spec: &Spec, client_path: &Path, snapshot_path: &Path, - ipc_path: &Path, + _ipc_path: &Path, miner: Arc, ) -> Result { @@ -120,7 +117,6 @@ impl ClientService { spec.engine.register_client(Arc::downgrade(&client) as _); let stop_guard = ::devtools::StopGuard::new(); - run_ipc(ipc_path, client.clone(), snapshot.clone(), stop_guard.share()); Ok(ClientService { io_service: Arc::new(io_service), @@ -228,38 +224,6 @@ impl IoHandler for ClientIoHandler { } } -#[cfg(feature="ipc")] -fn run_ipc(base_path: &Path, client: Arc, snapshot_service: Arc, stop: Arc) { - let mut path = base_path.to_owned(); - path.push("parity-chain.ipc"); - let socket_addr = format!("ipc://{}", path.to_string_lossy()); - let s = stop.clone(); - ::std::thread::spawn(move || { - let mut worker = nanoipc::Worker::new(&(client as Arc)); - worker.add_reqrep(&socket_addr).expect("Ipc expected to initialize with no issues"); - - while !s.load(::std::sync::atomic::Ordering::Relaxed) { - worker.poll(); - } - }); - - let mut path = base_path.to_owned(); - path.push("parity-snapshot.ipc"); - let socket_addr = format!("ipc://{}", path.to_string_lossy()); - ::std::thread::spawn(move || { - let mut worker = nanoipc::Worker::new(&(snapshot_service as Arc<::snapshot::SnapshotService>)); - worker.add_reqrep(&socket_addr).expect("Ipc expected to initialize with no issues"); - - while !stop.load(::std::sync::atomic::Ordering::Relaxed) { - worker.poll(); - } - }); -} - -#[cfg(not(feature="ipc"))] -fn run_ipc(_base_path: &Path, _client: Arc, _snapshot_service: Arc, _stop: Arc) { -} - #[cfg(test)] mod tests { use super::*; diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index e33c47e2c..4a3446e6e 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -72,16 +72,7 @@ mod watcher; #[cfg(test)] mod tests; -/// IPC interfaces -#[cfg(feature="ipc")] -pub mod remote { - pub use super::traits::RemoteSnapshotService; -} - -mod traits { - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/snapshot_service_trait.rs")); -} +mod traits; // Try to have chunks be around 4MB (before compression) const PREFERRED_CHUNK_SIZE: usize = 4 * 1024 * 1024; diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index a53824b1f..ae6a34cfa 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -40,7 +40,7 @@ use parking_lot::{Mutex, RwLock, RwLockReadGuard}; use util_error::UtilError; use bytes::Bytes; use util::journaldb::Algorithm; -use kvdb::{Database, DatabaseConfig}; +use kvdb_rocksdb::{Database, DatabaseConfig}; use snappy; /// Helper for removing directories in case of error. @@ -682,7 +682,7 @@ mod tests { #[test] fn cannot_finish_with_invalid_chunks() { use bigint::hash::H256; - use kvdb::DatabaseConfig; + use kvdb_rocksdb::DatabaseConfig; let spec = get_test_spec(); let dir = RandomTempPath::new(); diff --git a/ethcore/src/snapshot/tests/proof_of_authority.rs b/ethcore/src/snapshot/tests/proof_of_authority.rs index 9634fd531..f15954ce8 100644 --- a/ethcore/src/snapshot/tests/proof_of_authority.rs +++ b/ethcore/src/snapshot/tests/proof_of_authority.rs @@ -31,7 +31,7 @@ use tests::helpers; use transaction::{Transaction, Action, SignedTransaction}; use util::Address; -use kvdb; +use kvdb_memorydb; const PASS: &'static str = ""; const TRANSITION_BLOCK_1: usize = 2; // block at which the contract becomes activated. @@ -238,7 +238,7 @@ fn fixed_to_contract_only() { assert_eq!(client.chain_info().best_block_number, 11); let reader = snapshot_helpers::snap(&*client); - let new_db = kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)); + let new_db = kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)); let spec = spec_fixed_to_contract(); // ensure fresh engine's step matches. @@ -270,7 +270,7 @@ fn fixed_to_contract_to_contract() { assert_eq!(client.chain_info().best_block_number, 16); let reader = snapshot_helpers::snap(&*client); - let new_db = kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)); + let new_db = kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)); let spec = spec_fixed_to_contract(); for _ in 0..16 { spec.engine.step() } diff --git a/ethcore/src/snapshot/tests/proof_of_work.rs b/ethcore/src/snapshot/tests/proof_of_work.rs index 8002e4362..d4df7bb10 100644 --- a/ethcore/src/snapshot/tests/proof_of_work.rs +++ b/ethcore/src/snapshot/tests/proof_of_work.rs @@ -26,7 +26,8 @@ use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use parking_lot::Mutex; use snappy; -use kvdb::{self, KeyValueDB, DBTransaction}; +use kvdb::{KeyValueDB, DBTransaction}; +use kvdb_memorydb; use std::sync::Arc; use std::sync::atomic::AtomicBool; @@ -43,7 +44,7 @@ fn chunk_and_restore(amount: u64) { let mut snapshot_path = new_path.as_path().to_owned(); snapshot_path.push("SNAP"); - let old_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); + let old_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))); let bc = BlockChain::new(Default::default(), &genesis, old_db.clone()); // build the blockchain. @@ -80,7 +81,7 @@ fn chunk_and_restore(amount: u64) { writer.into_inner().finish(manifest.clone()).unwrap(); // restore it. - let new_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); + let new_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))); let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone()); let mut rebuilder = SNAPSHOT_MODE.rebuilder(new_chain, new_db.clone(), &manifest).unwrap(); @@ -127,7 +128,7 @@ fn checks_flag() { let chunk = stream.out(); - let db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); + let db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))); let engine = ::spec::Spec::new_test().engine; let chain = BlockChain::new(Default::default(), &genesis, db.clone()); diff --git a/ethcore/src/snapshot/tests/service.rs b/ethcore/src/snapshot/tests/service.rs index d391883a9..ccaf819b0 100644 --- a/ethcore/src/snapshot/tests/service.rs +++ b/ethcore/src/snapshot/tests/service.rs @@ -27,7 +27,7 @@ use tests::helpers::generate_dummy_client_with_spec_and_data; use devtools::RandomTempPath; use io::IoChannel; -use kvdb::{Database, DatabaseConfig}; +use kvdb_rocksdb::{Database, DatabaseConfig}; struct NoopDBRestore; diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index 175ae4eb8..9f9b434df 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -27,7 +27,7 @@ use error::Error; use rand::{XorShiftRng, SeedableRng}; use bigint::hash::H256; use util::journaldb::{self, Algorithm}; -use kvdb::{Database, DatabaseConfig}; +use kvdb_rocksdb::{Database, DatabaseConfig}; use memorydb::MemoryDB; use parking_lot::Mutex; use devtools::RandomTempPath; diff --git a/ethcore/src/snapshot/snapshot_service_trait.rs b/ethcore/src/snapshot/traits.rs similarity index 95% rename from ethcore/src/snapshot/snapshot_service_trait.rs rename to ethcore/src/snapshot/traits.rs index 8208400df..632a36afa 100644 --- a/ethcore/src/snapshot/snapshot_service_trait.rs +++ b/ethcore/src/snapshot/traits.rs @@ -17,13 +17,11 @@ use super::{ManifestData, RestorationStatus}; use bigint::hash::H256; use bytes::Bytes; -use ipc::IpcConfig; /// The interface for a snapshot network service. /// This handles: /// - restoration of snapshots to temporary databases. /// - responding to queries for snapshot manifests and chunks -#[ipc(client_ident="RemoteSnapshotService")] pub trait SnapshotService : Sync + Send { /// Query the most recent manifest data. fn manifest(&self) -> Option; @@ -54,5 +52,3 @@ pub trait SnapshotService : Sync + Send { /// no-op if currently restoring. fn restore_block_chunk(&self, hash: H256, chunk: Bytes); } - -impl IpcConfig for SnapshotService { } diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index a1696c47b..70a6d9afd 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -671,13 +671,13 @@ impl Spec { pub fn genesis_epoch_data(&self) -> Result, String> { use transaction::{Action, Transaction}; use util::journaldb; - use kvdb; + use kvdb_memorydb; let genesis = self.genesis_header(); let factories = Default::default(); let mut db = journaldb::new( - Arc::new(kvdb::in_memory(0)), + Arc::new(kvdb_memorydb::create(0)), journaldb::Algorithm::Archive, None, ); diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index a2e4dcac4..148c0d8c8 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -17,7 +17,7 @@ use std::collections::{VecDeque, HashSet}; use std::sync::Arc; use lru_cache::LruCache; -use util::cache::MemoryLruCache; +use memory_cache::MemoryLruCache; use util::journaldb::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; use bigint::hash::H256; diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 2f67ece8f..b75f0863a 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -27,7 +27,7 @@ use tests::helpers::*; use types::filter::Filter; use bigint::prelude::U256; use util::*; -use kvdb::{Database, DatabaseConfig}; +use kvdb_rocksdb::{Database, DatabaseConfig}; use devtools::*; use miner::Miner; use spec::Spec; diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 52a0dedc6..cf14915c5 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -232,7 +232,7 @@ pub fn get_test_client_with_blocks(blocks: Vec) -> Arc { } fn new_db() -> Arc<::kvdb::KeyValueDB> { - Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))) + Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))) } pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain { diff --git a/ethcore/src/tests/mod.rs b/ethcore/src/tests/mod.rs index c86240f33..eec71efaf 100644 --- a/ethcore/src/tests/mod.rs +++ b/ethcore/src/tests/mod.rs @@ -18,7 +18,3 @@ pub mod helpers; mod client; mod evm; mod trace; - -#[cfg(feature="ipc")] -mod rpc; - diff --git a/ethcore/src/tests/rpc.rs b/ethcore/src/tests/rpc.rs deleted file mode 100644 index 6444daa56..000000000 --- a/ethcore/src/tests/rpc.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Client RPC tests - -use nanoipc; -use std::sync::Arc; -use std::sync::atomic::{Ordering, AtomicBool}; -use client::{Client, BlockChainClient, ClientConfig, BlockId}; -use client::remote::RemoteClient; -use tests::helpers::*; -use devtools::*; -use miner::Miner; -use crossbeam; -use io::IoChannel; -use util::kvdb::DatabaseConfig; - -pub fn run_test_worker(scope: &crossbeam::Scope, stop: Arc, socket_path: &str) { - let socket_path = socket_path.to_owned(); - scope.spawn(move || { - let temp = RandomTempPath::create_dir(); - let spec = get_test_spec(); - let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); - - let client = Client::new( - ClientConfig::default(), - &spec, - temp.as_path(), - Arc::new(Miner::with_spec(&spec)), - IoChannel::disconnected(), - &db_config - ).unwrap(); - let mut worker = nanoipc::Worker::new(&(client as Arc)); - worker.add_reqrep(&socket_path).unwrap(); - while !stop.load(Ordering::Relaxed) { - worker.poll(); - } - }); -} - -#[test] -fn can_handshake() { - crossbeam::scope(|scope| { - let stop_guard = StopGuard::new(); - let socket_path = "ipc:///tmp/parity-client-rpc-10.ipc"; - run_test_worker(scope, stop_guard.share(), socket_path); - let remote_client = nanoipc::generic_client::>(socket_path).unwrap(); - - assert!(remote_client.handshake().is_ok()); - }) -} - -#[test] -fn can_query_block() { - crossbeam::scope(|scope| { - let stop_guard = StopGuard::new(); - let socket_path = "ipc:///tmp/parity-client-rpc-20.ipc"; - run_test_worker(scope, stop_guard.share(), socket_path); - let remote_client = nanoipc::generic_client::>(socket_path).unwrap(); - - let non_existant_block = remote_client.block_header(BlockId::Number(999)); - - assert!(non_existant_block.is_none()); - }) -} diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index 270d29597..57a745a1a 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -27,7 +27,7 @@ use client::*; use tests::helpers::*; use devtools::RandomTempPath; use client::{BlockChainClient, Client, ClientConfig}; -use kvdb::{Database, DatabaseConfig}; +use kvdb_rocksdb::{Database, DatabaseConfig}; use std::sync::Arc; use header::Header; use miner::Miner; diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index 087acdcc9..9d7136cb1 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -416,7 +416,8 @@ mod tests { use bigint::prelude::U256; use bigint::hash::H256; use util::Address; - use kvdb::{DBTransaction, in_memory, KeyValueDB}; + use kvdb::{DBTransaction, KeyValueDB}; + use kvdb_memorydb; use header::BlockNumber; use trace::{Config, TraceDB, Database as TraceDatabase, DatabaseExtras, ImportRequest}; use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError}; @@ -467,7 +468,7 @@ mod tests { } fn new_db() -> Arc { - Arc::new(in_memory(::db::NUM_COLUMNS.unwrap_or(0))) + Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))) } #[test] diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index 8c48e6a4a..efe9ecfa2 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -30,7 +30,6 @@ use super::error::Error; /// `Call` result. #[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] pub struct CallResult { /// Gas used by call. pub gas_used: U256, @@ -40,7 +39,6 @@ pub struct CallResult { /// `Create` result. #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] pub struct CreateResult { /// Gas used by create. pub gas_used: U256, @@ -59,7 +57,6 @@ impl CreateResult { /// Description of a _call_ action, either a `CALL` operation or a message transction. #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] pub struct Call { /// The sending account. pub from: Address, @@ -99,7 +96,6 @@ impl Call { /// Description of a _create_ action, either a `CREATE` operation or a create transction. #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] pub struct Create { /// The address of the creator. pub from: Address, @@ -132,7 +128,6 @@ impl Create { /// Reward type. #[derive(Debug, PartialEq, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub enum RewardType { /// Block Block, @@ -162,7 +157,6 @@ impl Decodable for RewardType { /// Reward action #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] pub struct Reward { /// Author's address. pub author: Address, @@ -203,7 +197,6 @@ impl Decodable for Reward { /// Suicide action. #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] pub struct Suicide { /// Suicided address. pub address: Address, @@ -223,7 +216,6 @@ impl Suicide { /// Description of an action that we trace; will be either a call or a create. #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] pub enum Action { /// It's a call action. Call(Call), @@ -287,7 +279,6 @@ impl Action { /// The result of the performed action. #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "ipc", binary)] pub enum Res { /// Successful call action result. Call(CallResult), @@ -365,7 +356,6 @@ impl Res { } #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] /// A diff of some chunk of memory. pub struct MemoryDiff { /// Offset into memory the change begins. @@ -375,7 +365,6 @@ pub struct MemoryDiff { } #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] /// A diff of some storage value. pub struct StorageDiff { /// Which key in storage is changed. @@ -385,7 +374,6 @@ pub struct StorageDiff { } #[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] /// A record of an executed VM operation. pub struct VMExecutedOperation { /// The total gas used. @@ -399,7 +387,6 @@ pub struct VMExecutedOperation { } #[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] /// A record of the execution of a single VM operation. pub struct VMOperation { /// The program counter. @@ -413,7 +400,6 @@ pub struct VMOperation { } #[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)] -#[cfg_attr(feature = "ipc", binary)] /// A record of a full VM trace for a CALL/CREATE. pub struct VMTrace { /// The step (i.e. index into operations) at which this trace corresponds. diff --git a/ethcore/src/tx_filter.rs b/ethcore/src/tx_filter.rs index ac40b8ab6..d0bff8dff 100644 --- a/ethcore/src/tx_filter.rs +++ b/ethcore/src/tx_filter.rs @@ -178,7 +178,7 @@ mod test { "#; let spec = Spec::load(&::std::env::temp_dir(), spec_data.as_bytes()).unwrap(); - let client_db = Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0))); + let client_db = Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0))); let client = Client::new( ClientConfig::default(), diff --git a/ethcore/types/src/account_diff.rs b/ethcore/types/src/account_diff.rs index c1eb89d92..ae1cf3e98 100644 --- a/ethcore/types/src/account_diff.rs +++ b/ethcore/types/src/account_diff.rs @@ -51,7 +51,6 @@ impl Diff where T: Eq { } #[derive(Debug, PartialEq, Eq, Clone)] -#[cfg_attr(feature = "ipc", binary)] /// Account diff. pub struct AccountDiff { /// Change in balance, allowed to be `Diff::Same`. @@ -65,7 +64,6 @@ pub struct AccountDiff { } #[derive(Debug, PartialEq, Eq, Clone)] -#[cfg_attr(feature = "ipc", binary)] /// Change in existance type. // TODO: include other types of change. pub enum Existance { diff --git a/ethkey/src/extended.rs b/ethkey/src/extended.rs index 45ed0547f..c545cd3e4 100644 --- a/ethkey/src/extended.rs +++ b/ethkey/src/extended.rs @@ -477,8 +477,8 @@ mod tests { .expect("Seed should be valid H128") .to_vec(); - /// private key from bitcoin test vector - /// xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs + // private key from bitcoin test vector + // xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs let test_private = H256::from_str("e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35") .expect("Private should be decoded ok"); @@ -489,8 +489,8 @@ mod tests { #[test] fn test_vector_1() { - /// xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7 - /// H(0) + // xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7 + // H(0) test_extended( |secret| secret.derive(2147483648.into()), H256::from_str("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea") @@ -500,8 +500,8 @@ mod tests { #[test] fn test_vector_2() { - /// xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs - /// H(0)/1 + // xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs + // H(0)/1 test_extended( |secret| secret.derive(2147483648.into()).derive(1.into()), H256::from_str("3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368") diff --git a/hash-fetch/Cargo.toml b/hash-fetch/Cargo.toml index c52f1e232..7b0e8b7cd 100644 --- a/hash-fetch/Cargo.toml +++ b/hash-fetch/Cargo.toml @@ -22,5 +22,5 @@ native-contracts = { path = "../ethcore/native_contracts" } hash = { path = "../util/hash" } [dev-dependencies] -ethabi = "2.0" +ethabi = "4.0" parking_lot = "0.4" diff --git a/hash-fetch/src/urlhint.rs b/hash-fetch/src/urlhint.rs index e19860e32..0670266df 100644 --- a/hash-fetch/src/urlhint.rs +++ b/hash-fetch/src/urlhint.rs @@ -265,8 +265,8 @@ pub mod tests { // given let registrar = FakeRegistrar::new(); let resolve_result = { - use ethabi::{Encoder, Token}; - Encoder::encode(vec![Token::String(String::new()), Token::FixedBytes(vec![0; 20]), Token::Address([0; 20])]) + use ethabi::{encode, Token}; + encode(&[Token::String(String::new()), Token::FixedBytes(vec![0; 20]), Token::Address([0; 20])]) }; registrar.responses.lock()[1] = Ok(resolve_result); diff --git a/hw/src/trezor.rs b/hw/src/trezor.rs index a89d26f66..239968120 100644 --- a/hw/src/trezor.rs +++ b/hw/src/trezor.rs @@ -201,7 +201,7 @@ impl Manager { where F: Fn() -> Result { let mut err = Error::KeyNotFound; - /// Try to open device a few times. + // Try to open device a few times. for _ in 0..10 { match f() { Ok(handle) => return Ok(handle), diff --git a/ipc-common-types/Cargo.toml b/ipc-common-types/Cargo.toml deleted file mode 100644 index e00949adc..000000000 --- a/ipc-common-types/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -description = "Types that implement IPC and are common to multiple modules." -name = "ipc-common-types" -version = "1.9.0" -license = "GPL-3.0" -authors = ["Parity Technologies "] -build = "build.rs" - -[build-dependencies] -ethcore-ipc-codegen = { path = "../ipc/codegen" } - -[dependencies] -semver = "0.6" -ethcore-ipc = { path = "../ipc/rpc" } -ethcore-util = { path = "../util" } -ethcore-bigint = { path = "../util/bigint" } diff --git a/ipc-common-types/build.rs b/ipc-common-types/build.rs deleted file mode 100644 index 3a51d6a21..000000000 --- a/ipc-common-types/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen; - -fn main() { - ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap(); -} diff --git a/ipc-common-types/src/lib.rs b/ipc-common-types/src/lib.rs deleted file mode 100644 index c1d18a8d7..000000000 --- a/ipc-common-types/src/lib.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Updater for Parity executables - -extern crate semver; -extern crate ethcore_util as util; -extern crate ethcore_bigint as bigint; -extern crate ethcore_ipc as ipc; - -mod types; - -pub use types::*; diff --git a/ipc-common-types/src/types/mod.rs b/ipc-common-types/src/types/mod.rs deleted file mode 100644 index 68dfe0b25..000000000 --- a/ipc-common-types/src/types/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Types used in the public api - -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues -include!(concat!(env!("OUT_DIR"), "/mod.rs.in")); - diff --git a/ipc-common-types/src/types/mod.rs.in b/ipc-common-types/src/types/mod.rs.in deleted file mode 100644 index f137d1d60..000000000 --- a/ipc-common-types/src/types/mod.rs.in +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -pub mod release_track; -pub mod version_info; - -pub use release_track::{ReleaseTrack}; -pub use version_info::{VersionInfo}; \ No newline at end of file diff --git a/ipc/codegen/Cargo.toml b/ipc/codegen/Cargo.toml deleted file mode 100644 index 7b204869a..000000000 --- a/ipc/codegen/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "ethcore-ipc-codegen" -version = "1.9.0" -authors = ["Parity Technologies "] -license = "GPL-3.0" -description = "Macros to auto-generate implementations for ipc call" -build = "build.rs" -keywords = ["ipc", "codegen"] - -[features] -default = ["with-syntex"] -nightly = ["quasi_macros"] -nightly-testing = ["clippy"] -with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"] - -[build-dependencies] -quasi_codegen = { version = "0.32", optional = true } -syntex = { version = "0.58", optional = true } - -[dependencies] -aster = { version = "0.41", default-features = false } -clippy = { version = "^0.*", optional = true } -quasi = { version = "0.32", default-features = false } -quasi_macros = { version = "0.32", optional = true } -syntex = { version = "0.58", optional = true } -syntex_syntax = { version = "0.58", optional = true } diff --git a/ipc/codegen/build.rs b/ipc/codegen/build.rs deleted file mode 100644 index 442abf7df..000000000 --- a/ipc/codegen/build.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - - -#[cfg(feature = "with-syntex")] -mod inner { - extern crate syntex; - extern crate quasi_codegen; - - use std::env; - use std::path::Path; - - pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - - let src = Path::new("src/lib.rs.in"); - let dst = Path::new(&out_dir).join("lib.rs"); - - quasi_codegen::expand(&src, &dst).unwrap(); - } -} - -#[cfg(not(feature = "with-syntex"))] -mod inner { - pub fn main() {} -} - -fn main() { - inner::main(); -} diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs deleted file mode 100644 index 2f4752d97..000000000 --- a/ipc/codegen/src/codegen.rs +++ /dev/null @@ -1,898 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . -use aster; - -use syntax::ast::{ - MetaItem, - Item, - ImplItemKind, - MethodSig, - Arg, - PatKind, - FunctionRetTy, - Ty, - TraitRef, - Ident, - Generics, - TraitItemKind, -}; - -use syntax::ast; -use syntax::codemap::Span; -use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ptr::P; - -pub struct Error; - -const RESERVED_MESSAGE_IDS: u16 = 16; - -pub fn expand_ipc_implementation( - cx: &mut ExtCtxt, - span: Span, - meta_item: &MetaItem, - annotatable: &Annotatable, - push: &mut FnMut(Annotatable) -) { - let item = match *annotatable { - Annotatable::Item(ref item) => item, - _ => { - cx.span_err(meta_item.span, "`#[ipc]` may only be applied to implementations and traits"); - return; - }, - }; - - let builder = aster::AstBuilder::new().span(span); - - let interface_map = match implement_interface(cx, &builder, &item, push, meta_item) { - Ok(interface_map) => interface_map, - Err(Error) => { return; }, - }; - - push_client(cx, &builder, &interface_map, push); - - push(Annotatable::Item(interface_map.item)); -} - -macro_rules! literal { - ($builder:ident, $($arg:tt)*) => { - $builder.expr().lit().str::<&str>(&format!($($arg)*)) - } -} - -fn field_name(builder: &aster::AstBuilder, arg: &Arg) -> ast::Ident { - match arg.pat.node { - PatKind::Ident(_, ref ident, _) => builder.id(ident.node), - _ => { panic!("unexpected param in interface: {:?}", arg.pat.node) } - } -} - -pub fn replace_slice_u8(builder: &aster::AstBuilder, ty: &P) -> P { - if ::syntax::print::pprust::ty_to_string(&strip_ptr(ty)) == "[u8]" { - return builder.ty().id("Vec") - } - ty.clone() -} - -struct NamedSignature<'a> { - sig: &'a MethodSig, - ident: &'a Ident, -} - -fn push_invoke_signature_aster( - builder: &aster::AstBuilder, - named_signature: &NamedSignature, - push: &mut FnMut(Annotatable), -) -> Dispatch { - let inputs = &named_signature.sig.decl.inputs; - let (input_type_name, input_arg_names, input_arg_tys) = if inputs.len() > 0 { - let first_field_name = field_name(builder, &inputs[0]).name.as_str(); - if &*first_field_name == "self" && inputs.len() == 1 { (None, vec![], vec![]) } - else { - let skip = if &*first_field_name == "self" { 2 } else { 1 }; - let name_str = format!("{}_input", named_signature.ident.name.as_str()); - - let mut arg_names = Vec::new(); - let mut arg_tys = Vec::new(); - - let arg_name = format!("{}", field_name(builder, &inputs[skip-1]).name); - let arg_ty = &inputs[skip-1].ty; - - let mut tree = builder.item() - .attr().word("binary") - .attr().word("allow(non_camel_case_types)") - .struct_(name_str.as_str()) - .field(arg_name.as_str()) - .ty().build(replace_slice_u8(builder, &strip_ptr(arg_ty))); - - arg_names.push(arg_name); - arg_tys.push(arg_ty.clone()); - for arg in inputs.iter().skip(skip) { - let arg_name = format!("{}", field_name(builder, &arg)); - let arg_ty = &arg.ty; - - tree = tree.field(arg_name.as_str()).ty().build(replace_slice_u8(builder, &strip_ptr(arg_ty))); - arg_names.push(arg_name); - arg_tys.push(arg_ty.clone()); - } - - push(Annotatable::Item(tree.build())); - (Some(name_str.to_owned()), arg_names, arg_tys) - } - } - else { - (None, vec![], vec![]) - }; - - let return_type_ty = match named_signature.sig.decl.output { - FunctionRetTy::Ty(ref ty) => { - let name_str = format!("{}_output", named_signature.ident.name.as_str()); - let tree = builder.item() - .attr().word("binary") - .attr().word("allow(non_camel_case_types)") - .struct_(name_str.as_str()) - .field(format!("payload")).ty().build(ty.clone()); - push(Annotatable::Item(tree.build())); - Some(ty.clone()) - } - _ => None - }; - - Dispatch { - function_name: format!("{}", named_signature.ident.name.as_str()), - input_type_name: input_type_name, - input_arg_names: input_arg_names, - input_arg_tys: input_arg_tys, - return_type_ty: return_type_ty, - } -} - -struct Dispatch { - function_name: String, - input_type_name: Option, - input_arg_names: Vec, - input_arg_tys: Vec>, - return_type_ty: Option>, -} - -// This is the expanded version of this: -// -// let invoke_serialize_stmt = quote_stmt!(cx, { -// ::bincode::serde::serialize(& $output_type_id { payload: self. $function_name ($hand_param_a, $hand_param_b) }, ::bincode::SizeLimit::Infinite).unwrap() -// }); -// -// But the above does not allow comma-separated expressions for arbitrary number -// of parameters ...$hand_param_a, $hand_param_b, ... $hand_param_n -fn implement_dispatch_arm_invoke_stmt( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - dispatch: &Dispatch, -) -> ast::Stmt -{ - use ::syntax::tokenstream::TokenTree::Token; - let function_name = builder.id(dispatch.function_name.as_str()); - - let input_args_exprs = dispatch.input_arg_names.iter().enumerate().map(|(arg_index, arg_name)| { - let arg_ident = builder.id(arg_name); - let expr = quote_expr!(cx, input. $arg_ident); - if has_ptr(&dispatch.input_arg_tys[arg_index]) { quote_expr!(cx, & $expr) } - else { expr } - }).collect::>>(); - - let ext_cx = &*cx; - ::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts( - ext_cx.parse_sess(), - { - let _sp = ext_cx.call_site(); - let mut tt = ::std::vec::Vec::new(); - - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace))); - - if dispatch.return_type_ty.is_some() { - tt.push(Token(_sp, ::syntax::parse::token::ModSep)); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc")))); - tt.push(Token(_sp, ::syntax::parse::token::ModSep)); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary")))); - tt.push(Token(_sp, ::syntax::parse::token::ModSep)); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize")))); - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); - tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And))); - } - - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self")))); - tt.push(Token(_sp, ::syntax::parse::token::Dot)); - tt.extend(::quasi::ToTokens::to_tokens(&function_name, ext_cx).into_iter()); - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); - - for arg_expr in input_args_exprs { - tt.extend(::quasi::ToTokens::to_tokens(&arg_expr, ext_cx).into_iter()); - tt.push(Token(_sp, ::syntax::parse::token::Comma)); - } - - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); - - if dispatch.return_type_ty.is_some() { - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); - tt.push(Token(_sp, ::syntax::parse::token::Dot)); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap")))); - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); - } - else { - tt.push(Token(_sp, ::syntax::parse::token::Semi)); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Vec")))); - tt.push(Token(_sp, ::syntax::parse::token::ModSep)); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("new")))); - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); - - } - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace))); - - tt - } - )).unwrap() -} - -fn implement_dispatch_arm_invoke( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - dispatch: &Dispatch, - buffer: bool, -) -> P -{ - let deserialize_expr = if buffer { - quote_expr!(cx, - ::ipc::binary::deserialize(buf) - .unwrap_or_else(|e| { panic!("ipc error while deserializing payload, aborting \n payload: {:?}, \n error: {:?}", buf, e); } ) - ) - } else { - quote_expr!(cx, - ::ipc::binary::deserialize_from(r) - .unwrap_or_else(|e| { panic!("ipc error while deserializing payload, aborting \n error: {:?}", e); } ) - ) - }; - - let invoke_serialize_stmt = implement_dispatch_arm_invoke_stmt(cx, builder, dispatch); - dispatch.input_type_name.as_ref().map(|val| { - let input_type_id = builder.id(val.clone().as_str()); - quote_expr!(cx, { - let input: $input_type_id = $deserialize_expr; - $invoke_serialize_stmt - }) - }).unwrap_or(quote_expr!(cx, { $invoke_serialize_stmt })) -} - -/// generates dispatch match for method id -fn implement_dispatch_arm( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - index: u32, - dispatch: &Dispatch, - buffer: bool, -) -> ast::Arm -{ - let index_ident = builder.id(format!("{}", index + (RESERVED_MESSAGE_IDS as u32)).as_str()); - let invoke_expr = implement_dispatch_arm_invoke(cx, builder, dispatch, buffer); - let trace = literal!(builder, "Dispatching: {}", &dispatch.function_name); - quote_arm!(cx, $index_ident => { - trace!(target: "ipc", $trace); - $invoke_expr - }) -} - -fn implement_dispatch_arms( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - dispatches: &[Dispatch], - buffer: bool, -) -> Vec -{ - let mut index = -1; - dispatches.iter() - .map(|dispatch| { index = index + 1; implement_dispatch_arm(cx, builder, index as u32, dispatch, buffer) }).collect() -} - -pub fn strip_ptr(ty: &P) -> P { - if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node { - ptr_mut.ty.clone() - } - else { ty.clone() } -} - -pub fn has_ptr(ty: &P) -> bool { - if let ast::TyKind::Rptr(_, ref _ptr_mut) = ty.node { - true - } - else { false } -} - -/// returns an expression with the body for single operation that is being sent to server -/// operation itself serializes input, writes to socket and waits for socket to respond -/// (the latter only if original method signature returns anyting) -/// -/// assuming expanded class contains method -/// fn commit(&self, f: u32) -> u32 -/// -/// the expanded implementation will generate method for the client like that -/// #[binary] -/// struct Request<'a> { -/// f: &'a u32, -/// } -/// let payload = Request{f: &f,}; -/// let mut socket_ref = self.socket.borrow_mut(); -/// let mut socket = socket_ref.deref_mut(); -/// let serialized_payload = ::bincode::serde::serialize(&payload, ::bincode::SizeLimit::Infinite).unwrap(); -/// ::ipc::invoke(0, &Some(serialized_payload), &mut socket); -/// while !socket.ready().load(::std::sync::atomic::Ordering::Relaxed) { } -/// ::bincode::serde::deserialize_from::<_, u32>(&mut socket, ::bincode::SizeLimit::Infinite).unwrap() -fn implement_client_method_body( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - index: u16, - interface_map: &InterfaceMap, -) -> P -{ - use ::syntax::tokenstream::TokenTree::Token; - - let dispatch = &interface_map.dispatches[index as usize]; - let index_ident = builder.id(format!("{}", index + RESERVED_MESSAGE_IDS).as_str()); - - let request = if dispatch.input_arg_names.len() > 0 { - - let arg_name = dispatch.input_arg_names[0].as_str(); - let static_ty = strip_ptr(&dispatch.input_arg_tys[0]); - let arg_ty = builder - .ty().ref_() - .lifetime("'a") - .ty() - .build(static_ty.clone()); - - let mut tree = builder.item() - .attr().word("binary") - .struct_("Request") - .generics() - .lifetime_name("'a") - .build() - .field(arg_name).ty() - .build(arg_ty); - - for arg_idx in 1..dispatch.input_arg_names.len() { - let arg_name = dispatch.input_arg_names[arg_idx].as_str(); - let static_ty = strip_ptr(&dispatch.input_arg_tys[arg_idx]); - - let arg_ty = builder - .ty().ref_() - .lifetime("'a") - .ty() - .build(static_ty); - tree = tree.field(arg_name).ty().build(arg_ty); - - } - let mut request_serialization_statements = Vec::new(); - - let struct_tree = tree.build(); - let struct_stmt = quote_stmt!(cx, $struct_tree); - request_serialization_statements.push(struct_stmt); - - // actually this is just expanded version of this: - // request_serialization_statements.push(quote_stmt!(cx, let payload = Request { p1: &p1, p2: &p2, ... pn: &pn, })); - // again, cannot dynamically create expression with arbitrary number of comma-separated members - request_serialization_statements.push({ - let ext_cx = &*cx; - ::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts( - ext_cx.parse_sess(), - { - let _sp = ext_cx.call_site(); - let mut tt = ::std::vec::Vec::new(); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("let")))); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("payload")))); - tt.push(Token(_sp, ::syntax::parse::token::Eq)); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Request")))); - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace))); - - for arg in dispatch.input_arg_names.iter() { - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str())))); - tt.push(Token(_sp, ::syntax::parse::token::Colon)); - tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And))); - - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str())))); - tt.push(Token(_sp, ::syntax::parse::token::Comma)); - } - - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace))); - tt - })) - }); - - request_serialization_statements.push( - quote_stmt!(cx, let mut socket = self.socket.write().unwrap(); )); - - request_serialization_statements.push( - quote_stmt!(cx, let serialized_payload = ::ipc::binary::serialize(&payload).unwrap())); - - request_serialization_statements.push( - quote_stmt!(cx, ::ipc::invoke($index_ident, &Some(serialized_payload), &mut *socket))); - - - request_serialization_statements - } - else { - let mut request_serialization_statements = Vec::new(); - request_serialization_statements.push( - quote_stmt!(cx, let mut socket = self.socket.write().unwrap(); )); - request_serialization_statements.push( - quote_stmt!(cx, ::ipc::invoke($index_ident, &None, &mut *socket))); - request_serialization_statements - }; - - let trace = literal!(builder, "Invoking: {}", &dispatch.function_name); - if let Some(ref return_ty) = dispatch.return_type_ty { - let return_expr = quote_expr!(cx, - ::ipc::binary::deserialize_from::<$return_ty, _>(&mut *socket).unwrap() - ); - quote_expr!(cx, { - trace!(target: "ipc", $trace); - $request; - $return_expr - }) - } - else { - quote_expr!(cx, { - trace!(target: "ipc", $trace); - $request - }) - } -} - -/// Generates signature and body (see `implement_client_method_body`) -/// for the client (signature is identical to the original method) -fn implement_client_method( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - index: u16, - interface_map: &InterfaceMap, -) - -> ast::ImplItem -{ - use ::syntax::tokenstream::TokenTree::Token; - - let dispatch = &interface_map.dispatches[index as usize]; - let method_name = builder.id(dispatch.function_name.as_str()); - let body = implement_client_method_body(cx, builder, index, interface_map); - - let ext_cx = &*cx; - // expanded version of this - // pub fn $method_name(&self, p1: p1_ty, p2: p2_ty ... pn: pn_ty, ) [-> return_ty] { $body } - // looks like it's tricky to build function declaration with aster if body already generated - let signature = ::syntax::parse::parser::Parser::parse_impl_item( - &mut ::syntax::parse::new_parser_from_tts( - ext_cx.parse_sess(), - { - let _sp = ext_cx.call_site(); - let mut tt = ::std::vec::Vec::new(); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("fn")))); - tt.extend(::quasi::ToTokens::to_tokens(&method_name, ext_cx).into_iter()); - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); - tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And))); - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self")))); - tt.push(Token(_sp, ::syntax::parse::token::Comma)); - - for arg_idx in 0..dispatch.input_arg_names.len() { - let arg_name = dispatch.input_arg_names[arg_idx].as_str(); - let arg_ty = dispatch.input_arg_tys[arg_idx].clone(); - - tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg_name)))); - tt.push(Token(_sp, ::syntax::parse::token::Colon)); - tt.extend(::quasi::ToTokens::to_tokens(&arg_ty, ext_cx).into_iter()); - tt.push(Token(_sp, ::syntax::parse::token::Comma)); - } - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); - - if let Some(ref return_ty) = dispatch.return_type_ty { - tt.push(Token(_sp, ::syntax::parse::token::RArrow)); - tt.extend(::quasi::ToTokens::to_tokens(return_ty, ext_cx).into_iter()); - } - - tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace))); - tt.extend(::quasi::ToTokens::to_tokens(&body, ext_cx).into_iter()); - tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace))); - - tt - })); - - signature.unwrap() -} - -fn client_generics(builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> Generics { - let ty_param = aster::ty_param::TyParamBuilder::new( - builder.id("S")).trait_bound( - builder.path().global().ids(&["ipc", "IpcSocket"]).build() - ).build().build(); - - builder.from_generics(interface_map.generics.clone()) - .with_ty_param(ty_param) - .build() -} - -fn client_qualified_ident(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P { - let generics = client_generics(builder, interface_map); - aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(cx, builder)) - .with_generics(generics).build() - .build() -} - -fn client_phantom_ident(builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P { - let generics = client_generics(builder, interface_map); - aster::ty::TyBuilder::new().phantom_data() - .tuple().with_tys(generics.ty_params.iter().map(|x| aster::ty::TyBuilder::new().id(x.ident))) - .build() -} - -/// generates client type for specified server type -/// for say `Service` it generates `ServiceClient` -fn push_client_struct(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap, push: &mut FnMut(Annotatable)) { - let generics = client_generics(builder, interface_map); - let client_short_ident = interface_map.ident_map.client_ident(cx, builder); - let phantom = client_phantom_ident(builder, interface_map); - - let client_struct_item = quote_item!(cx, - pub struct $client_short_ident $generics { - socket: ::std::sync::RwLock, - phantom: $phantom, - }); - - push(Annotatable::Item(client_struct_item.expect(&format!("could not generate client struct for {:?}", client_short_ident.name)))); -} - -/// pushes generated code for the client class (type declaration and method invocation implementations) -fn push_client( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - interface_map: &InterfaceMap, - push: &mut FnMut(Annotatable), -) { - push_client_struct(cx, builder, interface_map, push); - push_client_implementation(cx, builder, interface_map, push); - push_with_socket_client_implementation(cx, builder, interface_map, push); -} - -fn push_with_socket_client_implementation( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - interface_map: &InterfaceMap, - push: &mut FnMut(Annotatable)) -{ - let generics = client_generics(builder, interface_map); - let client_ident = client_qualified_ident(cx, builder, interface_map); - let where_clause = &generics.where_clause; - let client_short_ident = interface_map.ident_map.client_ident(cx, builder); - - let implement = quote_item!(cx, - impl $generics ::ipc::WithSocket for $client_ident $where_clause { - fn init(socket: S) -> $client_ident { - $client_short_ident { - socket: ::std::sync::RwLock::new(socket), - phantom: ::std::marker::PhantomData, - } - } - }).unwrap(); - push(Annotatable::Item(implement)); -} - -/// pushes full client side code for the original class exposed via ipc -fn push_client_implementation( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - interface_map: &InterfaceMap, - push: &mut FnMut(Annotatable), -) { - let mut index = -1i32; - let items = interface_map.dispatches.iter() - .map(|_| { index = index + 1; P(implement_client_method(cx, builder, index as u16, interface_map)) }) - .collect::>>(); - - let generics = client_generics(builder, interface_map); - let client_ident = client_qualified_ident(cx, builder, interface_map); - let where_clause = &generics.where_clause; - let endpoint = interface_map.endpoint; - - let handshake_item = quote_impl_item!(cx, - pub fn handshake(&self) -> Result<(), ::ipc::Error> { - let payload = ::ipc::Handshake { - protocol_version: $endpoint::protocol_version(), - api_version: $endpoint::api_version(), - }; - - ::ipc::invoke( - 0, - &Some(::ipc::binary::serialize(&::ipc::BinHandshake::from(payload)).unwrap()), - &mut *self.socket.write().unwrap()); - - let mut result = vec![0u8; 1]; - if try!(self.socket.write().unwrap().read(&mut result).map_err(|_| ::ipc::Error::HandshakeFailed)) == 1 { - match result[0] { - 1 => Ok(()), - _ => Err(::ipc::Error::RemoteServiceUnsupported), - } - } - else { Err(::ipc::Error::HandshakeFailed) } - }).unwrap(); - - let socket_item = quote_impl_item!(cx, - #[cfg(test)] - pub fn socket(&self) -> &::std::sync::RwLock { - &self.socket - }).unwrap(); - - let generic_items = vec![P(handshake_item), P(socket_item)]; - - if interface_map.impl_trait.is_some() { - let trait_ty = builder.id( - ::syntax::print::pprust::path_to_string( - &interface_map.impl_trait.as_ref().unwrap().path)); - - let implement_trait = - quote_item!(cx, - impl $generics $trait_ty for $client_ident $where_clause { - $items - } - ).unwrap(); - push(Annotatable::Item(implement_trait)); - - let implement = - quote_item!(cx, - impl $generics $client_ident $where_clause { - $generic_items - } - ).unwrap(); - push(Annotatable::Item(implement)); - } - else { - let pub_items = items.iter().map(|item| { - let pub_item = item.clone(); - pub_item.map(|mut val| { val.vis = ast::Visibility::Public; val }) - }).collect::>>(); - - let implement = quote_item!(cx, - impl $generics $client_ident $where_clause { - $pub_items - $generic_items - }).unwrap(); - push(Annotatable::Item(implement)); - } - -} - -/// implements dispatching of system handshake invocation (method_num 0) -fn implement_handshake_arm( - cx: &ExtCtxt, -) -> (ast::Arm, ast::Arm) -{ - let handshake_deserialize = quote_stmt!(&cx, - let handshake_payload = ::ipc::binary::deserialize_from::<::ipc::BinHandshake, _>(r).unwrap(); - ); - - let handshake_deserialize_buf = quote_stmt!(&cx, - let handshake_payload = ::ipc::binary::deserialize::<::ipc::BinHandshake>(buf).unwrap(); - ); - - let handshake_serialize = quote_expr!(&cx, - ::ipc::binary::serialize::(&Self::handshake(&handshake_payload.to_semver())).unwrap() - ); - - ( - quote_arm!(&cx, 0 => { - $handshake_deserialize - $handshake_serialize - }), - quote_arm!(&cx, 0 => { - $handshake_deserialize_buf - $handshake_serialize - }), - ) -} - -fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result { - match lit.node { - ast::LitKind::Str(ref s, _) => Ok(format!("{}", s)), - _ => { - cx.span_err( - lit.span, - &format!("ipc client_ident annotation `{}` must be a string, not `{}`", - name, - ::syntax::print::pprust::lit_to_string(lit))); - - return Err(()); - } - } -} - -fn client_ident_renamed(cx: &ExtCtxt, meta_item: &MetaItem) -> Option { - if let ast::MetaItemKind::List(ref list) = meta_item.node { - for nested in list { - match nested.node { - ast::NestedMetaItemKind::MetaItem(ref meta_item) => { - let is_client_ident = &*meta_item.name.as_str() == "client_ident"; - match meta_item.node { - ast::MetaItemKind::NameValue(ref lit) if is_client_ident => { - if let Ok(s) = get_str_from_lit(cx, "client_ident", lit) { - return Some(s); - } - } - _ => { - cx.span_err( - meta_item.span, - &format!("unknown client_ident container attribute `{}`", - ::syntax::print::pprust::meta_item_to_string(&meta_item))); - } - } - }, - _ => {}, - } - } - } - - None -} - -struct InterfaceMap { - pub original_item: Item, - pub item: P, - pub dispatches: Vec, - pub generics: Generics, - pub impl_trait: Option, - pub ident_map: IdentMap, - pub endpoint: Ident, -} - -struct IdentMap { - original_path: ast::Path, - meta_item: MetaItem, -} - -impl IdentMap { - fn ident(&self, builder: &aster::AstBuilder) -> Ident { - builder.id(format!("{}", ::syntax::print::pprust::path_to_string(&self.original_path))) - } - - fn client_ident(&self, cx: &ExtCtxt, builder: &aster::AstBuilder) -> Ident { - if let Some(new_name) = client_ident_renamed(cx, &self.meta_item) { - builder.id(new_name) - } - else { - builder.id(format!("{}Client", self.original_path.segments[0].identifier)) - } - } -} - -fn ty_ident_map(original_ty: &P, meta_item: &MetaItem) -> IdentMap { - let original_path = match original_ty.node { - ::syntax::ast::TyKind::Path(_, ref path) => path.clone(), - _ => { panic!("incompatible implementation"); } - }; - let ident_map = IdentMap { original_path: original_path, meta_item: meta_item.clone() }; - ident_map -} - -/// implements `IpcInterface` for the given class `C` -fn implement_interface( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - item: &Item, - push: &mut FnMut(Annotatable), - meta_item: &MetaItem, -) -> Result { - let (generics, impl_trait, original_ty, dispatch_table) = match item.node { - ast::ItemKind::Impl(_, _, ref generics, ref impl_trait, ref ty, ref impl_items) => { - let mut method_signatures = Vec::new(); - for impl_item in impl_items { - if let ImplItemKind::Method(ref signature, _) = impl_item.node { - method_signatures.push(NamedSignature { ident: &impl_item.ident, sig: signature }); - } - } - - let dispatch_table = method_signatures.iter().map(|named_signature| - push_invoke_signature_aster(builder, named_signature, push)) - .collect::>(); - - (generics, impl_trait.clone(), ty.clone(), dispatch_table) - }, - ast::ItemKind::Trait(_, ref generics, _, ref trait_items) => { - let mut method_signatures = Vec::new(); - for trait_item in trait_items { - if let TraitItemKind::Method(ref signature, _) = trait_item.node { - method_signatures.push(NamedSignature { ident: &trait_item.ident, sig: signature }); - } - } - - let dispatch_table = method_signatures.iter().map(|named_signature| - push_invoke_signature_aster(builder, named_signature, push)) - .collect::>(); - - ( - generics, - Some(ast::TraitRef { - path: builder.path().ids(&[item.ident.name]).build(), - ref_id: item.id, - }), - builder.ty().id(item.ident), - dispatch_table - ) - }, - _ => { - cx.span_err( - item.span, - "`#[ipc]` may only be applied to implementations and traits"); - return Err(Error); - }, - }; - let impl_generics = builder.from_generics(generics.clone()).build(); - let where_clause = &impl_generics.where_clause; - - let dispatch_arms = implement_dispatch_arms(cx, builder, &dispatch_table, false); - let dispatch_arms_buffered = implement_dispatch_arms(cx, builder, &dispatch_table, true); - - let (handshake_arm, handshake_arm_buf) = implement_handshake_arm(cx); - - let ty = ty_ident_map(&original_ty, meta_item).ident(builder); - let (interface_endpoint, host_generics) = match impl_trait { - Some(ref trait_) => (builder.id(::syntax::print::pprust::path_to_string(&trait_.path)), None), - None => (ty, Some(&impl_generics)), - }; - - let ipc_item = quote_item!(cx, - impl $host_generics ::ipc::IpcInterface for $interface_endpoint $where_clause { - fn dispatch(&self, r: &mut R) -> Vec - where R: ::std::io::Read - { - let mut method_num = vec![0u8;2]; - match r.read(&mut method_num) { - Ok(size) if size == 0 => { panic!("method id not supplied" ); } - Err(e) => { panic!("ipc read error: {:?}, aborting", e); } - _ => { } - } - - // method_num is a 16-bit little-endian unsigned number - match method_num[1] as u16 + (method_num[0] as u16)*256 { - // handshake - $handshake_arm - // user methods - $dispatch_arms - _ => vec![] - } - } - - fn dispatch_buf(&self, method_num: u16, buf: &[u8]) -> Vec - { - match method_num { - $handshake_arm_buf - $dispatch_arms_buffered - _ => vec![] - } - } - } - ).unwrap(); - - Ok(InterfaceMap { - ident_map: ty_ident_map(&original_ty, meta_item), - original_item: item.clone(), - item: ipc_item, - dispatches: dispatch_table, - generics: generics.clone(), - impl_trait: impl_trait.clone(), - endpoint: interface_endpoint, - }) -} diff --git a/ipc/codegen/src/lib.rs b/ipc/codegen/src/lib.rs deleted file mode 100644 index 6e7fc441b..000000000 --- a/ipc/codegen/src/lib.rs +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Codegen for IPC RPC - -#![cfg_attr(feature = "nightly-testing", plugin(clippy))] -#![cfg_attr(feature = "nightly-testing", feature(plugin))] -#![cfg_attr(feature = "nightly-testing", allow(used_underscore_binding))] -#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))] -#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))] - -extern crate aster; -extern crate quasi; - -#[cfg(feature = "with-syntex")] -extern crate syntex; - -#[cfg(feature = "with-syntex")] -extern crate syntex_syntax as syntax; - -#[cfg(not(feature = "with-syntex"))] -#[macro_use] -extern crate syntax; - -#[cfg(not(feature = "with-syntex"))] -extern crate rustc_plugin; - -#[cfg(not(feature = "with-syntex"))] -use syntax::feature_gate::AttributeType; - -#[cfg(feature = "with-syntex")] -use syntax::{ast, fold}; - - -#[cfg(feature = "with-syntex")] -include!(concat!(env!("OUT_DIR"), "/lib.rs")); - -#[cfg(not(feature = "with-syntex"))] -include!("lib.rs.in"); - -#[cfg(feature = "with-syntex")] -pub fn expand(src: &std::path::Path, dst: &std::path::Path) { - let mut registry = syntex::Registry::new(); - register(&mut registry); - registry.expand("", src, dst).unwrap(); -} - -#[cfg(feature = "with-syntex")] -struct StripAttributeFolder<'a> { - attr_title: &'a str, -} - -#[cfg(feature = "with-syntex")] -impl<'a> fold::Folder for StripAttributeFolder<'a> { - fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { - let is_self = &*attr.value.name.as_str() == self.attr_title; - - match attr.value.node { - ast::MetaItemKind::List(_) if is_self => { return None; } - ast::MetaItemKind::Word if is_self => { return None; } - _ => {} - } - - Some(attr) - } - - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - fold::noop_fold_mac(mac, self) - } -} - -#[cfg(feature = "with-syntex")] -pub fn register_cleaner_ipc(reg: &mut syntex::Registry) { - #[cfg(feature = "with-syntex")] - fn strip_attributes(krate: ast::Crate) -> ast::Crate { - let mut folder = StripAttributeFolder { attr_title: "ipc" }; - fold::Folder::fold_crate(&mut folder, krate) - } - - reg.add_post_expansion_pass(strip_attributes); -} - -#[cfg(feature = "with-syntex")] -pub fn register_cleaner_binary(reg: &mut syntex::Registry) { - #[cfg(feature = "with-syntex")] - fn strip_attributes(krate: ast::Crate) -> ast::Crate { - let mut folder = StripAttributeFolder { attr_title: "binary" }; - fold::Folder::fold_crate(&mut folder, krate) - } - - reg.add_post_expansion_pass(strip_attributes); -} - -#[cfg(feature = "with-syntex")] -pub fn register(reg: &mut syntex::Registry) { - reg.add_attr("feature(custom_derive)"); - reg.add_attr("feature(custom_attribute)"); - - reg.add_decorator("ipc", codegen::expand_ipc_implementation); - reg.add_decorator("binary", serialization::expand_serialization_implementation); - - register_cleaner_ipc(reg); - register_cleaner_binary(reg); -} - -#[cfg(not(feature = "with-syntex"))] -pub fn register(reg: &mut rustc_plugin::Registry) { - reg.register_syntax_extension( - syntax::parse::token::intern("ipc"), - syntax::ext::base::MultiDecorator( - Box::new(codegen::expand_ipc_implementation))); - reg.register_syntax_extension( - syntax::parse::token::intern("binary"), - syntax::ext::base::MultiDecorator( - Box::new(serialization::expand_serialization_implementation))); - - reg.register_attribute("ipc".to_owned(), AttributeType::Normal); - reg.register_attribute("binary".to_owned(), AttributeType::Normal); -} - -#[derive(Debug)] -pub enum Error { InvalidFileName, ExpandFailure, Io(std::io::Error) } - -impl std::convert::From for Error { - fn from(err: std::io::Error) -> Self { - Error::Io(err) - } -} - -pub fn derive_ipc_cond(src_path: &str, has_feature: bool) -> Result<(), Error> { - if has_feature { derive_ipc(src_path) } - else { cleanup_ipc(src_path) } -} - -pub fn cleanup_ipc(src_path: &str) -> Result<(), Error> { - cleanup(src_path, AttributeKind::Ipc) -} - -pub fn cleanup_binary(src_path: &str) -> Result<(), Error> { - cleanup(src_path, AttributeKind::Binary) -} - -enum AttributeKind { - Ipc, - Binary, -} - -fn cleanup(src_path: &str, attr: AttributeKind) -> Result<(), Error> { - use std::env; - use std::path::{Path, PathBuf}; - - let out_dir = env::var_os("OUT_DIR").unwrap(); - let file_name = PathBuf::from(src_path).file_name().ok_or(Error::InvalidFileName).map(|val| val.to_str().unwrap().to_owned())?; - let mut registry = syntex::Registry::new(); - - match attr { - AttributeKind::Ipc => { register_cleaner_ipc(&mut registry); } - AttributeKind::Binary => { register_cleaner_binary(&mut registry); } - } - - if let Err(_) = registry.expand("", &Path::new(src_path), &Path::new(&out_dir).join(&file_name)) - { - // will be reported by compiler - return Err(Error::ExpandFailure) - } - Ok(()) -} - -pub fn derive_ipc(src_path: &str) -> Result<(), Error> { - use std::env; - use std::path::{Path, PathBuf}; - - let out_dir = env::var_os("OUT_DIR").unwrap(); - let file_name = PathBuf::from(src_path).file_name().ok_or(Error::InvalidFileName).map(|val| val.to_str().unwrap().to_owned())?; - - let final_path = Path::new(&out_dir).join(&file_name); - - let mut intermediate_file_name = file_name.clone(); - intermediate_file_name.push_str(".rpc.in"); - let intermediate_path = Path::new(&out_dir).join(&intermediate_file_name); - - { - let mut registry = syntex::Registry::new(); - register(&mut registry); - if let Err(_) = registry.expand("", &Path::new(src_path), &intermediate_path) { - // will be reported by compiler - return Err(Error::ExpandFailure) - } - } - - { - let mut registry = syntex::Registry::new(); - register(&mut registry); - if let Err(_) = registry.expand("", &intermediate_path, &final_path) { - // will be reported by compiler - return Err(Error::ExpandFailure) - } - } - - Ok(()) -} - -pub fn derive_binary(src_path: &str) -> Result<(), Error> { - use std::env; - use std::path::{Path, PathBuf}; - - let out_dir = env::var_os("OUT_DIR").unwrap(); - let file_name = PathBuf::from(src_path).file_name().ok_or(Error::InvalidFileName).map(|val| val.to_str().unwrap().to_owned())?; - let final_path = Path::new(&out_dir).join(&file_name); - - let mut registry = syntex::Registry::new(); - register(&mut registry); - if let Err(_) = registry.expand("", &Path::new(src_path), &final_path) { - // will be reported by compiler - return Err(Error::ExpandFailure) - } - - Ok(()) -} - -pub fn derive_binary_cond(src_path: &str, has_feature: bool) -> Result<(), Error> { - if has_feature { derive_binary(src_path) } - else { cleanup_binary(src_path) } -} diff --git a/ipc/codegen/src/lib.rs.in b/ipc/codegen/src/lib.rs.in deleted file mode 100644 index c8aa8ebf2..000000000 --- a/ipc/codegen/src/lib.rs.in +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -mod codegen; -mod serialization; diff --git a/ipc/codegen/src/serialization.rs b/ipc/codegen/src/serialization.rs deleted file mode 100644 index fd908725c..000000000 --- a/ipc/codegen/src/serialization.rs +++ /dev/null @@ -1,810 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . -use aster; - -use syntax::ast::{ - MetaItem, - Item, - Ident, -}; - -use syntax::ast; -use syntax::codemap::Span; -use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ptr::P; - -pub struct Error; - -use super::codegen; - -pub fn expand_serialization_implementation( - cx: &mut ExtCtxt, - span: Span, - meta_item: &MetaItem, - annotatable: &Annotatable, - push: &mut FnMut(Annotatable) -) { - let item = match *annotatable { - Annotatable::Item(ref item) => item, - _ => { - cx.span_err(meta_item.span, "`#[derive(Binary)]` may only be applied to structs and enums"); - return; - }, - }; - - let builder = aster::AstBuilder::new().span(span); - - let impl_item = match serialize_item(cx, &builder, &item) { - Ok(item) => item, - Err(Error) => { - // An error occurred, but it should have been reported already. - return; - }, - }; - - push(Annotatable::Item(impl_item)) -} - -fn serialize_item( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - item: &Item, -) -> Result, Error> { - let generics = match item.node { - ast::ItemKind::Struct(_, ref generics) => generics, - ast::ItemKind::Enum(_, ref generics) => generics, - _ => { - cx.span_err( - item.span, - "`#[derive(Binary)]` may only be applied to structs and enums"); - return Err(Error); - }, - }; - - let ty = builder.ty().path() - .segment(item.ident).with_generics(generics.clone()).build() - .build(); - - let where_clause = &generics.where_clause; - - let binary_expressions = try!(binary_expr(cx, - &builder, - &item, - &generics, - ty.clone())); - - let (size_expr, read_expr, write_expr) = - (binary_expressions.size, binary_expressions.read, binary_expressions.write); - - match quote_item!(cx, - impl $generics ::ipc::BinaryConvertable for $ty $where_clause { - fn size(&self) -> usize { - $size_expr - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut ::std::collections::VecDeque) -> Result<(), ::ipc::BinaryConvertError> { - $write_expr - } - - fn from_bytes(buffer: &[u8], length_stack: &mut ::std::collections::VecDeque) -> Result { - $read_expr - } - - fn len_params() -> usize { - 1 - } - }) - { - Some(item) => Ok(item), - None => { - cx.span_err( - item.span, - "syntax error expanding serialization implementation"); - Err(Error) - } - } -} - -#[allow(unreachable_code)] -fn binary_expr( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - item: &Item, - impl_generics: &ast::Generics, - ty: P, -) -> Result { - match item.node { - ast::ItemKind::Struct(ref variant_data, _) => { - binary_expr_item_struct( - cx, - builder, - impl_generics, - ty, - item.span, - variant_data, - ) - }, - ast::ItemKind::Enum(ref enum_def, _) => { - binary_expr_enum( - cx, - builder, - item.ident, - impl_generics, - ty, - item.span, - enum_def, - ) - }, - _ => { - cx.span_bug(item.span, - "expected ItemStruct or ItemEnum in #[derive(Binary)]"); - Err(Error) as Result - }, - } -} - -struct BinaryExpressions { - pub size: P, - pub write: P, - pub read: P, -} - -fn replace_qualified(s: &str) -> String { - if let Some(pos) = s.find("<") { - let mut source = s.to_owned(); - source.insert(pos, ':'); - source.insert(pos, ':'); - source - } - else { s.to_owned() } -} - -fn binary_expr_struct( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - ty: P, - fields: &[ast::StructField], - value_ident: Option, - instance_ident: Option, -) -> Result { - - let size_exprs: Vec> = fields.iter().enumerate().map(|(index, field)| { - let raw_ident = ::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty)); - let index_ident = builder.id(format!("__field{}", index)); - let field_id = match field.ident { - Some(ident) => builder.id(ident), - None => builder.id(format!("{}", index)), - }; - - match raw_ident.as_ref() { - "u8" => { - quote_expr!(cx, 1) - }, - "[u8]" => { - value_ident.and_then(|x| { - Some(quote_expr!(cx, $x. $field_id .len())) - }) - .unwrap_or_else(|| { - quote_expr!(cx, $index_ident .len()) - } - ) - } - _ => { - let field_type_ident = builder.id( - &::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty))); - - let field_type_ident_qualified = builder.id( - replace_qualified(&::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty)))); - - value_ident.and_then(|x| - { - Some(quote_expr!(cx, - match $field_type_ident_qualified::len_params() { - 0 => ::std::mem::size_of::<$field_type_ident>(), - _ => $x. $field_id .size(), - })) - }) - .unwrap_or_else(|| { - quote_expr!(cx, match $field_type_ident_qualified::len_params() { - 0 => ::std::mem::size_of::<$field_type_ident>(), - _ => $index_ident .size(), - }) - }) - } - } - }).collect(); - - let first_size_expr = size_exprs[0].clone(); - let mut total_size_expr = quote_expr!(cx, 0usize + $first_size_expr); - for index in 1..size_exprs.len() { - let next_expr = size_exprs[index].clone(); - total_size_expr = quote_expr!(cx, $total_size_expr + $next_expr); - } - - let mut write_stmts = Vec::::new(); - write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;).expect("stmt1")); - - let mut map_stmts = Vec::::new(); - let field_amount = builder.id(&format!("{}",fields.len())); - map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).expect("stmt2")); - map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).expect("stmt3")); - - let mut post_write_stmts = Vec::::new(); - - for (index, field) in fields.iter().enumerate() { - let field_type_ident = builder.id( - &::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty))); - - let field_type_ident_qualified = builder.id( - replace_qualified(&::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty)))); - - let field_id = match field.ident { - Some(ident) => builder.id(ident), - None => builder.id(format!("{}", index)), - }; - let member_expr = match value_ident { - Some(x) => { - quote_expr!(cx, $x . $field_id) - }, - None => { - let index_ident = builder.id(format!("__field{}", index)); - quote_expr!(cx, $index_ident) - }, - }; - - let raw_ident = ::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty)); - let range_ident = builder.id(format!("r{}", index)); - - let error_message = "Error serializing member: ".to_owned() + &::syntax::print::pprust::expr_to_string(&member_expr); - let _error_message_literal = builder.expr().lit().str::<&str>(&error_message); - - match raw_ident.as_ref() { - "u8" => { - write_stmts.push(quote_stmt!(cx, let next_line = offset + 1;).expect("stmt4")); - write_stmts.push(quote_stmt!(cx, buffer[offset] = $member_expr; ).expect("stm5")); - }, - "[u8]" => { - write_stmts.push(quote_stmt!(cx, let size = $member_expr .len();).unwrap()); - write_stmts.push(quote_stmt!(cx, let next_line = offset + size;).unwrap()); - write_stmts.push(quote_stmt!(cx, length_stack.push_back(size);).unwrap()); - write_stmts.push(quote_stmt!(cx, let $range_ident = offset..next_line; ).unwrap()); - post_write_stmts.push(quote_stmt!(cx, buffer[$range_ident].clone_from_slice($member_expr); ).unwrap()); - } - _ => { - write_stmts.push(quote_stmt!(cx, let next_line = offset + match $field_type_ident_qualified::len_params() { - 0 => ::std::mem::size_of::<$field_type_ident>(), - _ => { let size = $member_expr .size(); length_stack.push_back(size); size }, - }).unwrap()); - write_stmts.push(quote_stmt!(cx, let $range_ident = offset..next_line; ).unwrap()); - post_write_stmts.push(quote_stmt!(cx, - if $range_ident.end - $range_ident.start > 0 { - if let Err(e) = $member_expr .to_bytes(&mut buffer[$range_ident], length_stack) { - return Err(e) - }; - } - ).unwrap()); - } - } - - write_stmts.push(quote_stmt!(cx, offset = next_line; ).unwrap()); - - let field_index = builder.id(&format!("{}", index)); - map_stmts.push(quote_stmt!(cx, map[$field_index] = total;).unwrap()); - - match raw_ident.as_ref() { - "u8" => { - map_stmts.push(quote_stmt!(cx, total += 1;).unwrap()); - }, - "[u8]" => { - map_stmts.push(quote_stmt!(cx, let size = length_stack.pop_front().unwrap();).unwrap()); - map_stmts.push(quote_stmt!(cx, total += size;).unwrap()); - }, - _ => { - map_stmts.push(quote_stmt!(cx, let size = match $field_type_ident_qualified::len_params() { - 0 => ::std::mem::size_of::<$field_type_ident>(), - _ => length_stack.pop_front().unwrap(), - }).unwrap()); - map_stmts.push(quote_stmt!(cx, total += size;).unwrap()); - } - } - }; - - let read_expr = match fields.iter().any(|f| codegen::has_ptr(&f.ty)) { - true => { - // cannot create structs with pointers - quote_expr!(cx, Err(::ipc::binary::BinaryConvertError::not_supported())) - }, - false => { - if value_ident.is_some() { - let instance_create = named_fields_sequence(cx, &ty, fields); - quote_expr!(cx, { $map_stmts; $instance_create; Ok(result) }) - } - else { - let map_variant = P(fields_sequence(cx, &ty, fields, &instance_ident.unwrap_or(builder.id("Self")))); - quote_expr!(cx, { $map_stmts; Ok($map_variant) }) - } - }, - }; - - Ok(BinaryExpressions { - size: total_size_expr, - write: quote_expr!(cx, { $write_stmts; $post_write_stmts; Ok(()) } ), - read: read_expr, - }) -} - -#[allow(unreachable_code)] -fn binary_expr_item_struct( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - _impl_generics: &ast::Generics, - ty: P, - span: Span, - variant_data: &ast::VariantData, -) -> Result { - match *variant_data { - ast::VariantData::Tuple(ref fields, _) => { - binary_expr_struct( - cx, - &builder, - ty, - fields, - Some(builder.id("self")), - None, - ) - }, - ast::VariantData::Struct(ref fields, _) => { - binary_expr_struct( - cx, - &builder, - ty, - fields, - Some(builder.id("self")), - None, - ) - }, - _ => { - cx.span_bug(span, - &format!("#[derive(Binary)] Unsupported struct content, expected tuple/struct, found: {:?}", - variant_data)); - Err(Error) as Result - }, - } -} - -fn binary_expr_enum( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - type_ident: Ident, - impl_generics: &ast::Generics, - ty: P, - span: Span, - enum_def: &ast::EnumDef, -) -> Result { - let arms: Vec<_> = try!(enum_def.variants.iter() - .enumerate() - .map(|(variant_index, variant)| { - binary_expr_variant( - cx, - builder, - type_ident, - impl_generics, - ty.clone(), - span, - variant, - variant_index, - ) - }) - .collect()); - - let (size_arms, write_arms, mut read_arms) = ( - arms.iter().map(|x| x.size.clone()).collect::>(), - arms.iter().map(|x| x.write.clone()).collect::>(), - arms.iter().map(|x| x.read.clone()).collect::>()); - - read_arms.push(quote_arm!(cx, _ => { Err(::ipc::BinaryConvertError::variant(buffer[0])) } )); - - Ok(BinaryExpressions { - size: quote_expr!(cx, 1usize + match *self { $size_arms }), - write: quote_expr!(cx, match *self { $write_arms }; ), - read: quote_expr!(cx, match buffer[0] { $read_arms }), - }) -} - -struct BinaryArm { - size: ast::Arm, - write: ast::Arm, - read: ast::Arm, -} - -fn fields_sequence( - ext_cx: &ExtCtxt, - _ty: &P, - fields: &[ast::StructField], - variant_ident: &ast::Ident, -) -> ast::Expr { - use syntax::parse::token; - use syntax::tokenstream::TokenTree::Token; - - let named_members = fields.iter().any(|f| f.ident.is_some()); - - ::quasi::parse_expr_panic(&mut ::syntax::parse::new_parser_from_tts( - ext_cx.parse_sess(), - { - let _sp = ext_cx.call_site(); - let mut tt = ::std::vec::Vec::new(); - tt.push(Token(_sp, token::Ident(variant_ident.clone()))); - if named_members { - tt.push(Token(_sp, token::OpenDelim(token::Brace))); - } - else { - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - } - - for (idx, field) in fields.iter().enumerate() { - if field.ident.is_some() { - tt.push(Token(_sp, token::Ident(field.ident.clone().unwrap()))); - tt.push(Token(_sp, token::Colon)); - } - - // special case for u8, it just takes byte form sequence - if ::syntax::print::pprust::ty_to_string(&field.ty) == "u8" { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer")))); - - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - - tt.push(Token(_sp, token::Comma)); - continue; - } - - // special case for [u8], it just takes a byte sequence - if ::syntax::print::pprust::ty_to_string(&field.ty) == "[u8]" { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer")))); - - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - tt.push(Token(_sp, token::DotDot)); - - if idx+1 != fields.len() { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - } - - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - - tt.push(Token(_sp, token::Comma)); - continue; - } - - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("try!")))); - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - tt.push( - Token( - _sp, - token::Ident(ext_cx.ident_of(&replace_qualified(&::syntax::print::pprust::ty_to_string(&field.ty)))) - )); - tt.push(Token(_sp, token::ModSep)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("from_bytes")))); - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - - tt.push(Token(_sp, token::BinOp(token::And))); - - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer")))); - - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - tt.push(Token(_sp, token::DotDot)); - - if idx+1 != fields.len() { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - } - - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - - tt.push(Token(_sp, token::Comma)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("length_stack")))); - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - - // name member if it has resulted in the error - tt.push(Token(_sp, token::Dot)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map_err")))); - - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - tt.push(Token(_sp, token::BinOp(token::Or))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e")))); - tt.push(Token(_sp, token::BinOp(token::Or))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e")))); - tt.push(Token(_sp, token::Dot)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("named")))); - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - tt.push(Token(_sp, token::Literal(token::Lit::Str_( - field.ident.unwrap_or(ext_cx.ident_of(&format!("f{}", idx))).name), - None)) - ); - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - - tt.push(Token(_sp, token::Comma)); - } - if named_members { - tt.push(Token(_sp, token::CloseDelim(token::Brace))); - } - else { - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - } - tt - }) - ).unwrap() -} - -fn named_fields_sequence( - ext_cx: &ExtCtxt, - ty: &P, - fields: &[ast::StructField], -) -> ast::Stmt { - use syntax::parse::token; - use syntax::tokenstream::TokenTree::Token; - - ::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts( - ext_cx.parse_sess(), - { - let _sp = ext_cx.call_site(); - let mut tt = ::std::vec::Vec::new(); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("let")))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("result")))); - tt.push(Token(_sp, token::Eq)); - - tt.push(Token( - _sp, - token::Ident( - ext_cx.ident_of(&::syntax::print::pprust::ty_to_string(ty)) - ))); - - tt.push(Token(_sp, token::OpenDelim(token::Brace))); - - for (idx, field) in fields.iter().enumerate() { - tt.push(Token(_sp, match field.ident { - Some(ident) => token::Ident(ident), - None => token::Ident(ext_cx.ident_of(&format!("{}", idx))), - })); - tt.push(Token(_sp, token::Colon)); - - // special case for u8, it just takes byte form sequence - if ::syntax::print::pprust::ty_to_string(&field.ty) == "u8" { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer")))); - - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - - tt.push(Token(_sp, token::Comma)); - continue; - } - - // special case for [u8], it just takes a byte sequence - if ::syntax::print::pprust::ty_to_string(&field.ty) == "[u8]" { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer")))); - - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - tt.push(Token(_sp, token::DotDot)); - - if idx+1 != fields.len() { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - } - - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - - tt.push(Token(_sp, token::Comma)); - continue; - } - - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("try!")))); - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - tt.push(Token( - _sp, - token::Ident( - ext_cx.ident_of(&replace_qualified(&::syntax::print::pprust::ty_to_string(&field.ty))) - ))); - tt.push(Token(_sp, token::ModSep)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("from_bytes")))); - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - - tt.push(Token(_sp, token::BinOp(token::And))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer")))); - - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - tt.push(Token(_sp, token::DotDot)); - if idx + 1 != fields.len() { - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map")))); - tt.push(Token(_sp, token::OpenDelim(token::Bracket))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1))))); - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - } - - tt.push(Token(_sp, token::CloseDelim(token::Bracket))); - - tt.push(Token(_sp, token::Comma)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("length_stack")))); - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - - // name member if it has resulted in the error - tt.push(Token(_sp, token::Dot)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map_err")))); - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - tt.push(Token(_sp, token::BinOp(token::Or))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e")))); - tt.push(Token(_sp, token::BinOp(token::Or))); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e")))); - tt.push(Token(_sp, token::Dot)); - tt.push(Token(_sp, token::Ident(ext_cx.ident_of("named")))); - tt.push(Token(_sp, token::OpenDelim(token::Paren))); - tt.push(Token(_sp, token::Literal(token::Lit::Str_( - field.ident.unwrap_or(ext_cx.ident_of(&format!("f{}", idx))).name), - None)) - ); - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - - tt.push(Token(_sp, token::CloseDelim(token::Paren))); - tt.push(Token(_sp, token::Comma)); - } - - tt.push(Token(_sp, token::CloseDelim(token::Brace))); - tt - }) - ).unwrap() -} - -fn binary_expr_variant( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - type_ident: Ident, - _generics: &ast::Generics, - ty: P, - _span: Span, - variant: &ast::Variant, - variant_index: usize, -) -> Result { - let variant_ident = variant.node.name; - let variant_index_ident = builder.id(format!("{}", variant_index)); - - match variant.node.data { - ast::VariantData::Unit(_) => { - let pat = builder.pat().path() - .id(type_ident).id(variant_ident) - .build(); - - let variant_val = builder.id(format!("{}::{}", type_ident, variant_ident)); - - Ok(BinaryArm { - size: quote_arm!(cx, $pat => { 0usize } ), - write: quote_arm!(cx, $pat => { buffer[0] = $variant_index_ident; Ok(()) } ), - read: quote_arm!(cx, $variant_index_ident => { Ok($variant_val) } ), - }) - }, - ast::VariantData::Tuple(ref fields, _) => { - let field_names: Vec = (0 .. fields.len()) - .map(|i| builder.id(format!("__field{}", i))) - .collect(); - - let pat = builder.pat().enum_() - .id(type_ident).id(variant_ident).build() - .with_pats( - field_names.iter() - .map(|field| builder.pat().ref_id(field)) - ) - .build(); - - let binary_expr = try!(binary_expr_struct( - cx, - &builder, - ty, - fields, - None, - Some(builder.id(format!("{}::{}", type_ident, variant_ident))), - )); - - let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); - Ok(BinaryArm { - size: quote_arm!(cx, $pat => { $size_expr } ), - write: quote_arm!(cx, - $pat => { - buffer[0] = $variant_index_ident; - let buffer = &mut buffer[1..]; - $write_expr - }), - read: quote_arm!(cx, - $variant_index_ident => { - let buffer = &buffer[1..]; - $read_expr - } - ), - }) - }, - ast::VariantData::Struct(ref fields, _) => { - let field_names: Vec<_> = (0 .. fields.len()) - .map(|i| builder.id(format!("__field{}", i))) - .collect(); - - let pat = builder.pat().struct_() - .id(type_ident).id(variant_ident).build() - .with_pats( - field_names.iter() - .zip(fields.iter()) - .map(|(id, field)|(field.ident.unwrap(), builder.pat().ref_id(id)))) - .build(); - - let binary_expr = try!(binary_expr_struct( - cx, - &builder, - ty, - fields, - None, - Some(builder.id(format!("{}::{}", type_ident, variant_ident))), - )); - - let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); - - Ok(BinaryArm { - size: quote_arm!(cx, $pat => { $size_expr } ), - write: quote_arm!(cx, - $pat => { - buffer[0] = $variant_index_ident; - let buffer = &mut buffer[1..]; - $write_expr - }), - read: quote_arm!(cx, - $variant_index_ident => { - let buffer = &buffer[1..]; - $read_expr - } - ), - }) - }, - } -} diff --git a/ipc/hypervisor/Cargo.toml b/ipc/hypervisor/Cargo.toml deleted file mode 100644 index 1db60c904..000000000 --- a/ipc/hypervisor/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "ethcore-ipc-hypervisor" -version = "1.2.0" -authors = ["Parity Technologies "] -license = "GPL-3.0" -build = "build.rs" - -[features] - -[dependencies] -ethcore-ipc = { path = "../rpc" } -nanomsg = { git = "https://github.com/paritytech/nanomsg.rs.git", branch = "parity-1.7" } -ethcore-ipc-nano = { path = "../nano" } -semver = "0.6" -log = "0.3" -time = "0.1" - -[build-dependencies] -ethcore-ipc-codegen = { path = "../codegen" } diff --git a/ipc/hypervisor/build.rs b/ipc/hypervisor/build.rs deleted file mode 100644 index 097aba046..000000000 --- a/ipc/hypervisor/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen; - -fn main() { - ethcore_ipc_codegen::derive_ipc("src/service.rs.in").unwrap(); -} diff --git a/ipc/hypervisor/src/lib.rs b/ipc/hypervisor/src/lib.rs deleted file mode 100644 index b522122b5..000000000 --- a/ipc/hypervisor/src/lib.rs +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Parity interprocess hypervisor module - -#![cfg_attr(feature="dev", allow(used_underscore_binding))] - -extern crate ethcore_ipc as ipc; -extern crate ethcore_ipc_nano as nanoipc; -extern crate semver; -#[macro_use] extern crate log; -extern crate time; - -pub mod service; - -/// Default value for hypervisor ipc listener -pub const HYPERVISOR_IPC_URL: &'static str = "parity-internal-hyper-status.ipc"; - -use std::sync::{Arc,RwLock}; -use service::{HypervisorService, IpcModuleId}; -use std::process::{Command,Child}; -use std::collections::HashMap; - -pub use service::{HypervisorServiceClient, ControlService, CLIENT_MODULE_ID, SYNC_MODULE_ID}; - -pub type BinaryId = &'static str; - -pub struct Hypervisor { - ipc_addr: String, - service: Arc, - ipc_worker: RwLock>, - processes: RwLock>, - modules: HashMap, - pub io_path: String, -} - -/// Boot arguments for binary -pub struct BootArgs { - cli: Option>, - stdin: Option>, -} - -impl BootArgs { - /// New empty boot arguments - pub fn new() -> BootArgs { - BootArgs { - cli: None, - stdin: None, - } - } - - /// Set command-line arguments for boot - pub fn cli(mut self, cli: Vec) -> BootArgs { - self.cli = Some(cli); - self - } - - /// Set std-in stream for boot - pub fn stdin(mut self, stdin: Vec) -> BootArgs { - self.stdin = Some(stdin); - self - } -} - -impl Hypervisor { - /// initializes the Hypervisor service with the open ipc socket for incoming clients - pub fn new() -> Hypervisor { - Hypervisor::with_url(HYPERVISOR_IPC_URL) - } - - pub fn module(mut self, module_id: IpcModuleId, args: BootArgs) -> Hypervisor { - self.modules.insert(module_id, args); - self.service.add_module(module_id); - self - } - - pub fn local_module(self, module_id: IpcModuleId) -> Hypervisor { - self.service.add_module(module_id); - self - } - - pub fn io_path(mut self, directory: &str) -> Hypervisor { - self.io_path = directory.to_owned(); - self - } - - /// Starts with the specified address for the ipc listener and - /// the specified list of modules in form of created service - pub fn with_url(addr: &str) -> Hypervisor { - let service = HypervisorService::new(); - let worker = nanoipc::Worker::new(&service); - Hypervisor{ - ipc_addr: addr.to_owned(), - service: service, - ipc_worker: RwLock::new(worker), - processes: RwLock::new(HashMap::new()), - modules: HashMap::new(), - io_path: "/tmp".to_owned(), - } - } - - /// Since one binary can host multiple modules - /// we match binaries - fn match_module(&self, module_id: &IpcModuleId) -> Option<&BootArgs> { - self.modules.get(module_id) - } - - /// Creates IPC listener and starts all binaries - pub fn start(&self) { - let mut worker = self.ipc_worker.write().unwrap(); - worker.add_reqrep(&self.ipc_addr).unwrap_or_else(|e| panic!("Hypervisor ipc worker can not start - critical! ({:?})", e)); - - for module_id in self.service.module_ids() { - self.start_module(module_id); - } - } - - /// Start binary for the specified module - /// Does nothing when it is already started on module is inside the - /// main binary - fn start_module(&self, module_id: IpcModuleId) { - use std::io::Write; - - self.match_module(&module_id).map(|boot_args| { - let mut processes = self.processes.write().unwrap(); - { - if processes.get(&module_id).is_some() { - // already started for another module - return; - } - } - - let mut command = Command::new(&std::env::current_exe().unwrap()); - command.stderr(std::process::Stdio::inherit()); - - if let Some(ref cli_args) = boot_args.cli { - for arg in cli_args { command.arg(arg); } - } - - command.stdin(std::process::Stdio::piped()); - - trace!(target: "hypervisor", "Spawn executable: {:?}", command); - - let mut child = command.spawn().unwrap_or_else( - |e| panic!("Hypervisor cannot execute command ({:?}): {}", command, e)); - - if let Some(ref std_in) = boot_args.stdin { - trace!(target: "hypervisor", "Pushing std-in payload..."); - child.stdin.as_mut() - .expect("std-in should be piped above") - .write(std_in) - .unwrap_or_else(|e| panic!(format!("Error trying to pipe stdin for {:?}: {:?}", &command, e))); - drop(child.stdin.take()); - } - - processes.insert(module_id, child); - }); - } - - /// Reports if all modules are checked in - pub fn modules_ready(&self) -> bool { - self.service.unchecked_count() == 0 - } - - pub fn modules_shutdown(&self) -> bool { - self.service.running_count() == 0 - } - - /// Waits for every required module to check in - pub fn wait_for_startup(&self) { - let mut worker = self.ipc_worker.write().unwrap(); - while !self.modules_ready() { - worker.poll() - } - } - - /// Waits for every required module to check in - pub fn wait_for_shutdown(&self) -> bool { - use time::{PreciseTime, Duration}; - - let mut worker = self.ipc_worker.write().unwrap(); - let start = PreciseTime::now(); - while !self.modules_shutdown() { - worker.poll(); - if start.to(PreciseTime::now()) > Duration::seconds(30) { - warn!("Some modules failed to shutdown gracefully, they will be terminated."); - break; - } - } - self.modules_shutdown() - } - - /// Shutdown the ipc and all managed child processes - pub fn shutdown(&self) { - let mut childs = self.processes.write().unwrap(); - for (ref module, _) in childs.iter() { - trace!(target: "hypervisor", "Stopping process module: {}", module); - self.service.send_shutdown(**module); - } - trace!(target: "hypervisor", "Waiting for shutdown..."); - if self.wait_for_shutdown() { - trace!(target: "hypervisor", "All modules reported shutdown"); - return; - } - - for (ref module, ref mut process) in childs.iter_mut() { - if self.service.is_running(**module) { - process.kill().unwrap(); - trace!("Terminated {}", module); - } - } - } -} - -impl Drop for Hypervisor { - fn drop(&mut self) { - self.shutdown(); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::sync::atomic::{AtomicBool,Ordering}; - use std::sync::Arc; - use nanoipc; - - #[test] - fn can_init() { - let url = "ipc:///tmp/test-parity-hypervisor-10.ipc"; - let test_module_id = 8080u64; - - let hypervisor = Hypervisor::with_url(url).local_module(test_module_id); - assert_eq!(false, hypervisor.modules_ready()); - } - - #[test] - fn can_wait_for_startup() { - let url = "ipc:///tmp/test-parity-hypervisor-20.ipc"; - let test_module_id = 8080u64; - - let hypervisor_ready = Arc::new(AtomicBool::new(false)); - let hypervisor_ready_local = hypervisor_ready.clone(); - - ::std::thread::spawn(move || { - while !hypervisor_ready.load(Ordering::Relaxed) { } - - let client = nanoipc::fast_client::>(url).unwrap(); - client.handshake().unwrap(); - client.module_ready(test_module_id, url.to_owned()); - }); - - let hypervisor = Hypervisor::with_url(url).local_module(test_module_id); - hypervisor.start(); - hypervisor_ready_local.store(true, Ordering::Relaxed); - hypervisor.wait_for_startup(); - - assert_eq!(true, hypervisor.modules_ready()); - } -} diff --git a/ipc/hypervisor/src/service.rs b/ipc/hypervisor/src/service.rs deleted file mode 100644 index 59040251e..000000000 --- a/ipc/hypervisor/src/service.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Parity interprocess hypervisor IPC service -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues - -include!(concat!(env!("OUT_DIR"), "/service.rs.in")); diff --git a/ipc/hypervisor/src/service.rs.in b/ipc/hypervisor/src/service.rs.in deleted file mode 100644 index 9b881e64c..000000000 --- a/ipc/hypervisor/src/service.rs.in +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use std::sync::{RwLock,Arc}; -use ipc::IpcConfig; -use std::collections::HashMap; -use nanoipc; - -pub type IpcModuleId = u64; - -/// Blockhain database module id -pub const CLIENT_MODULE_ID: IpcModuleId = 2000; - -/// Sync module id -pub const SYNC_MODULE_ID: IpcModuleId = 2100; - -/// IPC service that handles module management -pub struct HypervisorService { - modules: RwLock>, -} - -#[derive(Default)] -pub struct ModuleState { - started: bool, - control_url: String, - shutdown: bool, -} - -#[ipc] -pub trait ControlService { - fn shutdown(&self) -> bool; -} - -#[ipc] -impl HypervisorService { - // return type for making method synchronous - fn module_ready(&self, module_id: u64, control_url: String) -> bool { - let mut modules = self.modules.write().unwrap(); - modules.get_mut(&module_id).map(|module| { - module.started = true; - module.control_url = control_url; - }); - trace!(target: "hypervisor", "Module ready: {}", module_id); - true - } - - // return type for making method synchronous - fn module_shutdown(&self, module_id: u64) -> bool { - let mut modules = self.modules.write().unwrap(); - modules.get_mut(&module_id).map(|module| { - module.shutdown = true; - }); - trace!(target: "hypervisor", "Module shutdown: {}", module_id); - true - } -} - -impl HypervisorService { - /// New service with the default list of modules - pub fn new() -> Arc { - HypervisorService::with_modules(vec![]) - } - - /// New service with list of modules that will report for being ready - pub fn with_modules(module_ids: Vec) -> Arc { - let mut modules = HashMap::new(); - for module_id in module_ids { - modules.insert(module_id, ModuleState::default()); - } - Arc::new(HypervisorService { - modules: RwLock::new(modules), - }) - } - - /// Add the module to the check-list - pub fn add_module(&self, module_id: IpcModuleId) { - self.modules.write().unwrap().insert(module_id, ModuleState::default()); - } - - /// Number of modules still being waited for check-in - pub fn unchecked_count(&self) -> usize { - self.modules.read().unwrap().iter().filter(|&(_, module)| !module.started).count() - } - - /// List of all modules within this service - pub fn module_ids(&self) -> Vec { - self.modules.read().unwrap().iter().map(|(module_id, _)| module_id).cloned().collect() - } - - /// Number of modules started and running - pub fn running_count(&self) -> usize { - self.modules.read().unwrap().iter().filter(|&(_, module)| module.started && !module.shutdown).count() - } - - pub fn is_running(&self, id: IpcModuleId) -> bool { - self.modules.read().unwrap().get(&id).map(|module| module.started && !module.shutdown).unwrap_or(false) - } - - pub fn send_shutdown(&self, module_id: IpcModuleId) { - let modules = self.modules.read().unwrap(); - modules.get(&module_id).map(|module| { - trace!(target: "hypervisor", "Sending shutdown to {}({})", module_id, &module.control_url); - let client = nanoipc::fast_client::>(&module.control_url).unwrap(); - client.shutdown(); - trace!(target: "hypervisor", "Sent shutdown to {}", module_id); - }); - } -} - -impl ::ipc::IpcConfig for HypervisorService {} - -impl ::ipc::IpcConfig for ControlService {} diff --git a/ipc/nano/Cargo.toml b/ipc/nano/Cargo.toml deleted file mode 100644 index bb6fbb0b2..000000000 --- a/ipc/nano/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "ethcore-ipc-nano" -version = "1.9.0" -authors = ["Parity Technologies "] -license = "GPL-3.0" - -[features] - -[dependencies] -ethcore-ipc = { path = "../rpc" } -nanomsg = { git = "https://github.com/paritytech/nanomsg.rs.git", branch = "parity-1.7" } -log = "0.3" -lazy_static = "0.2" diff --git a/ipc/nano/src/lib.rs b/ipc/nano/src/lib.rs deleted file mode 100644 index 9be3d2b1d..000000000 --- a/ipc/nano/src/lib.rs +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! IPC over nanomsg transport - -extern crate ethcore_ipc as ipc; -extern crate nanomsg; -#[macro_use] extern crate log; -#[macro_use] extern crate lazy_static; - -pub use ipc::{WithSocket, IpcInterface, IpcConfig}; -pub use nanomsg::Socket as NanoSocket; - -use std::sync::*; -use nanomsg::{Socket, Protocol, Error, Endpoint, PollRequest, PollFd, PollInOut}; -use std::ops::Deref; - -const POLL_TIMEOUT: isize = 200; -const DEFAULT_CONNECTION_TIMEOUT: isize = 30000; -const DEBUG_CONNECTION_TIMEOUT: isize = 5000; - -/// Generic worker to handle service (binded) sockets -pub struct Worker where S: IpcInterface { - service: Arc, - sockets: Vec<(Socket, Endpoint)>, - polls: Vec, - buf: Vec, -} - -/// struct for guarding `_endpoint` (so that it wont drop) -/// derefs to client `S` -pub struct GuardedSocket where S: WithSocket { - client: Arc, - _endpoint: Endpoint, -} - -impl GuardedSocket where S: WithSocket { - pub fn service(&self) -> Arc { - self.client.clone() - } -} - -impl Deref for GuardedSocket where S: WithSocket { - type Target = Arc; - - fn deref(&self) -> &Arc { - &self.client - } -} - -/// Spawns client <`S`> over specified address -/// creates socket and connects endpoint to it -/// for duplex (paired) connections with the service -pub fn init_duplex_client(socket_addr: &str) -> Result, SocketError> where S: WithSocket { - let mut socket = Socket::new(Protocol::Pair).map_err(|e| { - warn!(target: "ipc", "Failed to create ipc socket: {:?}", e); - SocketError::DuplexLink - })?; - - socket.set_receive_timeout(DEFAULT_CONNECTION_TIMEOUT).unwrap(); - - let endpoint = socket.connect(socket_addr).map_err(|e| { - warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", socket_addr, e); - SocketError::DuplexLink - })?; - - Ok(GuardedSocket { - client: Arc::new(S::init(socket)), - _endpoint: endpoint, - }) -} - -/// Spawns client <`S`> over specified address -/// creates socket and connects endpoint to it -/// for request-reply connections to the service -pub fn client(socket_addr: &str, receive_timeout: Option) -> Result, SocketError> where S: WithSocket { - let mut socket = Socket::new(Protocol::Req).map_err(|e| { - warn!(target: "ipc", "Failed to create ipc socket: {:?}", e); - SocketError::RequestLink - })?; - - if let Some(timeout) = receive_timeout { - socket.set_receive_timeout(timeout).unwrap(); - } - - let endpoint = socket.connect(socket_addr).map_err(|e| { - warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", socket_addr, e); - SocketError::RequestLink - })?; - - trace!(target: "ipc", "Created client for {}", socket_addr); - Ok(GuardedSocket { - client: Arc::new(S::init(socket)), - _endpoint: endpoint, - }) -} - -lazy_static! { - /// Set PARITY_IPC_DEBUG=1 for fail-fast connectivity problems diagnostic - pub static ref DEBUG_FLAG: bool = { - use std::env; - - if let Ok(debug) = env::var("PARITY_IPC_DEBUG") { - debug == "1" || debug.to_uppercase() == "TRUE" - } - else { false } - }; -} - -/// Client with no default timeout on operations -pub fn generic_client(socket_addr: &str) -> Result, SocketError> where S: WithSocket { - if *DEBUG_FLAG { - client(socket_addr, Some(DEBUG_CONNECTION_TIMEOUT)) - } else { - client(socket_addr, None) - } -} - -/// Client over interface that is supposed to give quick almost non-blocking responses -pub fn fast_client(socket_addr: &str) -> Result, SocketError> where S: WithSocket { - if *DEBUG_FLAG { - client(socket_addr, Some(DEBUG_CONNECTION_TIMEOUT)) - } else { - client(socket_addr, Some(DEFAULT_CONNECTION_TIMEOUT)) - } -} - -/// Error occurred while establising socket or endpoint -#[derive(Debug)] -pub enum SocketError { - /// Error establising duplex (paired) socket and/or endpoint - DuplexLink, - /// Error establising duplex (paired) socket and/or endpoint - RequestLink, -} - -impl Worker where S: IpcInterface { - /// New worker over specified `service` - pub fn new(service: &Arc) -> Worker { - Worker:: { - service: service.clone(), - sockets: Vec::new(), - polls: Vec::new(), - buf: Vec::new(), - } - } - - /// Polls all sockets, reads and dispatches method invocations - pub fn poll(&mut self) { - use std::io::Write; - - let mut request = PollRequest::new(&mut self.polls[..]); - let _result_guard = Socket::poll(&mut request, POLL_TIMEOUT); - - for (fd_index, fd) in request.get_fds().iter().enumerate() { - if fd.can_read() { - let (ref mut socket, _) = self.sockets[fd_index]; - unsafe { self.buf.set_len(0); } - match socket.nb_read_to_end(&mut self.buf) { - Ok(method_sign_len) => { - if method_sign_len >= 2 { - - // method_num - let method_num = self.buf[0] as u16 * 256 + self.buf[1] as u16; - // payload - let payload = &self.buf[2..]; - - // dispatching for ipc interface - let result = self.service.dispatch_buf(method_num, payload); - - if let Err(e) = socket.write(&result) { - warn!(target: "ipc", "Failed to write response: {:?}", e); - } - } - else { - warn!(target: "ipc", "Failed to read method signature from socket: unexpected message length({})", method_sign_len); - } - }, - Err(Error::TryAgain) => { - }, - Err(x) => { - warn!(target: "ipc", "Error polling connections {:?}", x); - panic!(); - } - } - } - } - } - - /// Stores nanomsg poll request for reuse - fn rebuild_poll_request(&mut self) { - self.polls = self.sockets.iter() - .map(|&(ref socket, _)| socket.new_pollfd(PollInOut::In)) - .collect::>(); - } - - /// Add exclusive socket for paired client - /// Only one connection over this address is allowed - pub fn add_duplex(&mut self, addr: &str) -> Result<(), SocketError> { - let mut socket = Socket::new(Protocol::Pair).map_err(|e| { - warn!(target: "ipc", "Failed to create ipc socket: {:?}", e); - SocketError::DuplexLink - })?; - - let endpoint = socket.bind(addr).map_err(|e| { - warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", addr, e); - SocketError::DuplexLink - })?; - - self.sockets.push((socket, endpoint)); - - self.rebuild_poll_request(); - - trace!(target: "ipc", "Started duplex worker at {}", addr); - - Ok(()) - } - - /// Add generic socket for request-reply style communications - /// with multiple clients - pub fn add_reqrep(&mut self, addr: &str) -> Result<(), SocketError> { - let mut socket = Socket::new(Protocol::Rep).map_err(|e| { - warn!(target: "ipc", "Failed to create ipc socket: {:?}", e); - SocketError::DuplexLink - })?; - - - let endpoint = socket.bind(addr).map_err(|e| { - warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", addr, e); - SocketError::DuplexLink - })?; - - self.sockets.push((socket, endpoint)); - - self.rebuild_poll_request(); - - trace!(target: "ipc", "Started request-reply worker at {}", addr); - Ok(()) - } -} - -#[cfg(test)] -mod service_tests { - - use super::Worker; - use ipc::*; - use std::io::{Read, Write}; - use std::sync::{Arc, RwLock}; - use nanomsg::{Socket, Protocol, Endpoint}; - - struct TestInvoke { - method_num: u16, - params: Vec, - } - - struct DummyService { - methods_stack: RwLock>, - } - - impl DummyService { - fn new() -> DummyService { - DummyService { methods_stack: RwLock::new(Vec::new()) } - } - } - - impl IpcInterface for DummyService { - fn dispatch(&self, _r: &mut R) -> Vec where R: Read { - vec![] - } - fn dispatch_buf(&self, method_num: u16, buf: &[u8]) -> Vec { - self.methods_stack.write().unwrap().push( - TestInvoke { - method_num: method_num, - params: buf.to_vec(), - }); - vec![] - } - } - - impl IpcConfig for DummyService {} - - fn dummy_write(addr: &str, buf: &[u8]) -> (Socket, Endpoint) { - let mut socket = Socket::new(Protocol::Pair).unwrap(); - let endpoint = socket.connect(addr).unwrap(); - socket.write(buf).unwrap(); - (socket, endpoint) - } - - #[test] - fn can_create_worker() { - let worker = Worker::::new(&Arc::new(DummyService::new())); - assert_eq!(0, worker.sockets.len()); - } - - #[test] - fn can_add_duplex_socket_to_worker() { - let mut worker = Worker::::new(&Arc::new(DummyService::new())); - worker.add_duplex("ipc:///tmp/parity-test10.ipc").unwrap(); - assert_eq!(1, worker.sockets.len()); - } - - #[test] - fn worker_can_poll_empty() { - let service = Arc::new(DummyService::new()); - let mut worker = Worker::::new(&service); - worker.add_duplex("ipc:///tmp/parity-test20.ipc").unwrap(); - worker.poll(); - assert_eq!(0, service.methods_stack.read().unwrap().len()); - } - - #[test] - fn worker_can_poll() { - let url = "ipc:///tmp/parity-test30.ipc"; - - let mut worker = Worker::::new(&Arc::new(DummyService::new())); - worker.add_duplex(url).unwrap(); - - let (_socket, _endpoint) = dummy_write(url, &vec![0, 0, 7, 7, 6, 6]); - worker.poll(); - - assert_eq!(1, worker.service.methods_stack.read().unwrap().len()); - assert_eq!(0, worker.service.methods_stack.read().unwrap()[0].method_num); - assert_eq!([7, 7, 6, 6], worker.service.methods_stack.read().unwrap()[0].params[..]); - } - - #[test] - fn worker_can_poll_long() { - let url = "ipc:///tmp/parity-test40.ipc"; - - let mut worker = Worker::::new(&Arc::new(DummyService::new())); - worker.add_duplex(url).unwrap(); - - let message = [0u8; 1024*1024]; - - let (_socket, _endpoint) = dummy_write(url, &message); - worker.poll(); - - assert_eq!(1, worker.service.methods_stack.read().unwrap().len()); - assert_eq!(0, worker.service.methods_stack.read().unwrap()[0].method_num); - assert_eq!(vec![0u8; 1024*1024-2], worker.service.methods_stack.read().unwrap()[0].params); - } -} diff --git a/ipc/rpc/Cargo.toml b/ipc/rpc/Cargo.toml deleted file mode 100644 index bd33ab618..000000000 --- a/ipc/rpc/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "ethcore-ipc" -version = "1.9.0" -authors = ["Parity Technologies "] -license = "GPL-3.0" - -[features] - -[dependencies] -ethcore-devtools = { path = "../../devtools" } -nanomsg = { git = "https://github.com/paritytech/nanomsg.rs.git", branch = "parity-1.7" } -ethcore-bigint = { path = "../../util/bigint"} -ethcore-util = { path = "../../util" } -semver = "0.6" diff --git a/ipc/rpc/src/binary.rs b/ipc/rpc/src/binary.rs deleted file mode 100644 index 6466acdb1..000000000 --- a/ipc/rpc/src/binary.rs +++ /dev/null @@ -1,1196 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Binary representation of types - -use bigint::prelude::{U256, U512}; -use bigint::hash::{H256, H512, H2048}; -use util::{Address}; -use std::mem; -use std::collections::{VecDeque, BTreeMap}; -use std::ops::Range; -use super::Handshake; - -#[derive(Debug)] -pub enum BinaryConvertErrorKind { - SizeMismatch { - expected: usize, - found: usize, - }, - TargetPayloadEmpty, - UnexpectedVariant(u8), - MissingLengthValue, - InconsistentBoundaries, - NotSupported, -} - -#[derive(Debug)] -pub struct BinaryConvertError { - member_tree: Vec<&'static str>, - kind: BinaryConvertErrorKind, -} - -impl BinaryConvertError { - pub fn size(expected: usize, found: usize) -> BinaryConvertError { - BinaryConvertError { - member_tree: Vec::new(), - kind: BinaryConvertErrorKind::SizeMismatch { - expected: expected, - found: found, - } - } - } - - pub fn empty() -> BinaryConvertError { - BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::TargetPayloadEmpty } - } - - pub fn variant(val: u8) -> BinaryConvertError { - BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::UnexpectedVariant(val) } - } - - pub fn length() -> BinaryConvertError { - BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::MissingLengthValue } - } - - pub fn boundaries() -> BinaryConvertError { - BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::InconsistentBoundaries } - } - - pub fn not_supported() -> BinaryConvertError { - BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::NotSupported } - } - - pub fn named(mut self, name: &'static str) -> BinaryConvertError { - self.member_tree.push(name); - self - } -} - -#[derive(Debug)] -pub enum BinaryError { - Serialization(BinaryConvertError), - Io(::std::io::Error), -} - -impl From<::std::io::Error> for BinaryError { - fn from(err: ::std::io::Error) -> Self { BinaryError::Io(err) } -} - -impl From for BinaryError { - fn from(err: BinaryConvertError) -> Self { BinaryError::Serialization(err) } -} - -pub trait BinaryConvertable : Sized { - fn size(&self) -> usize { - mem::size_of::() - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError>; - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result; - - fn from_empty_bytes() -> Result { - Err(BinaryConvertError::size(mem::size_of::(), 0)) - } - - fn len_params() -> usize { - 0 - } -} - -impl BinaryConvertable for Option where T: BinaryConvertable { - fn size(&self) -> usize { - match * self { None => 0, Some(ref val) => val.size() } - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - match *self { None => Err(BinaryConvertError::empty()), Some(ref val) => val.to_bytes(buffer, length_stack) } - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - if buffer.len() == 0 { return Self::from_empty_bytes(); } - Ok(Some(T::from_bytes(buffer, length_stack)?)) - } - - fn from_empty_bytes() -> Result { - Ok(None) - } - - fn len_params() -> usize { - 1 - } -} - -impl BinaryConvertable for Result<(), E> { - fn size(&self) -> usize { - match *self { - Ok(_) => 0, - Err(ref e) => e.size(), - } - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - match *self { - Ok(_) => Err(BinaryConvertError::empty()), - Err(ref e) => Ok(e.to_bytes(buffer, length_stack)?), - } - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - Ok(Err(E::from_bytes(&buffer, length_stack)?)) - } - - fn from_empty_bytes() -> Result { - Ok(Ok(())) - } - - fn len_params() -> usize { - 1 - } -} - - -impl BinaryConvertable for Result { - fn size(&self) -> usize { - match *self { - Ok(ref r) => r.size(), - Err(_) => 0, - } - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - match *self { - Ok(ref r) => Ok(r.to_bytes(buffer, length_stack)?), - Err(_) => Err(BinaryConvertError::empty()), - } - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - Ok(Ok(R::from_bytes(&buffer, length_stack)?)) - } - - fn from_empty_bytes() -> Result { - Ok(Err(())) - } - - fn len_params() -> usize { - 1 - } -} - -impl BinaryConvertable for Result { - fn size(&self) -> usize { - 1usize + match *self { - Ok(ref r) => r.size(), - Err(ref e) => e.size(), - } - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - match *self { - Ok(ref r) => { - buffer[0] = 0; - if r.size() > 0 { - Ok(r.to_bytes(&mut buffer[1..], length_stack)?) - } - else { Ok(()) } - }, - Err(ref e) => { - buffer[0] = 1; - if e.size() > 0 { - Ok(e.to_bytes(&mut buffer[1..], length_stack)?) - } - else { Ok(()) } - }, - } - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - match buffer[0] { - 0 => { - match buffer.len() { - 1 => Ok(Ok(R::from_empty_bytes()?)), - _ => Ok(Ok(R::from_bytes(&buffer[1..], length_stack)?)), - } - } - 1 => Ok(Err(E::from_bytes(&buffer[1..], length_stack)?)), - _ => Err(BinaryConvertError::variant(buffer[0])) - } - } - - fn len_params() -> usize { - 1 - } -} - -impl BinaryConvertable for BTreeMap where K : BinaryConvertable + Ord, V: BinaryConvertable { - fn size(&self) -> usize { - 0usize + match K::len_params() { - 0 => mem::size_of::() * self.len(), - _ => self.iter().fold(0usize, |acc, (k, _)| acc + k.size()) - } + match V::len_params() { - 0 => mem::size_of::() * self.len(), - _ => self.iter().fold(0usize, |acc, (_, v)| acc + v.size()) - } - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - let mut offset = 0usize; - for (key, val) in self.iter() { - let key_size = match K::len_params() { - 0 => mem::size_of::(), - _ => { let size = key.size(); length_stack.push_back(size); size } - }; - let val_size = match K::len_params() { - 0 => mem::size_of::(), - _ => { let size = val.size(); length_stack.push_back(size); size } - }; - - if key_size > 0 { - let item_end = offset + key_size; - key.to_bytes(&mut buffer[offset..item_end], length_stack)?; - offset = item_end; - } - - if val_size > 0 { - let item_end = offset + key_size; - val.to_bytes(&mut buffer[offset..item_end], length_stack)?; - offset = item_end; - } - } - Ok(()) - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - let mut index = 0; - let mut result = Self::new(); - - if buffer.len() == 0 { return Ok(result); } - - loop { - let key_size = match K::len_params() { - 0 => mem::size_of::(), - _ => length_stack.pop_front().ok_or(BinaryConvertError::length())?, - }; - let key = if key_size == 0 { - K::from_empty_bytes()? - } else { - if index + key_size > buffer.len() { - return Err(BinaryConvertError::boundaries()) - } - K::from_bytes(&buffer[index..index+key_size], length_stack)? - }; - index = index + key_size; - - let val_size = match V::len_params() { - 0 => mem::size_of::(), - _ => length_stack.pop_front().ok_or(BinaryConvertError::length())?, - }; - let val = if val_size == 0 { - V::from_empty_bytes()? - } else { - if index + val_size > buffer.len() { - return Err(BinaryConvertError::boundaries()) - } - V::from_bytes(&buffer[index..index+val_size], length_stack)? - }; - result.insert(key, val); - index = index + val_size; - - if index == buffer.len() { break; } - if index > buffer.len() { - return Err(BinaryConvertError::boundaries()) - } - } - - Ok(result) - } - - fn from_empty_bytes() -> Result { - Ok(Self::new()) - } - - fn len_params() -> usize { - 1 - } -} - -impl BinaryConvertable for VecDeque where T: BinaryConvertable { - fn size(&self) -> usize { - match T::len_params() { - 0 => mem::size_of::() * self.len(), - _ => self.iter().fold(0usize, |acc, t| acc + t.size()), - } - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - let mut offset = 0usize; - for item in self.iter() { - let next_size = match T::len_params() { - 0 => mem::size_of::(), - _ => { let size = item.size(); length_stack.push_back(size); size }, - }; - if next_size > 0 { - let item_end = offset + next_size; - item.to_bytes(&mut buffer[offset..item_end], length_stack)?; - offset = item_end; - } - } - Ok(()) - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - let mut index = 0; - let mut result = Self::with_capacity( - match T::len_params() { - 0 => buffer.len() / mem::size_of::(), - _ => 128, - }); - - if buffer.len() == 0 { return Ok(result); } - - loop { - let next_size = match T::len_params() { - 0 => mem::size_of::(), - _ => length_stack.pop_front().ok_or(BinaryConvertError::length())?, - }; - let item = if next_size == 0 { - T::from_empty_bytes()? - } - else { - if index + next_size > buffer.len() { - return Err(BinaryConvertError::boundaries()) - } - T::from_bytes(&buffer[index..index+next_size], length_stack)? - }; - result.push_back(item); - - index = index + next_size; - if index == buffer.len() { break; } - if index > buffer.len() { - return Err(BinaryConvertError::boundaries()) - } - } - - Ok(result) - } - - fn from_empty_bytes() -> Result { - Ok(Self::new()) - } - - fn len_params() -> usize { - 1 - } -} - -impl BinaryConvertable for Vec where T: BinaryConvertable { - fn size(&self) -> usize { - match T::len_params() { - 0 => mem::size_of::() * self.len(), - _ => self.iter().fold(0usize, |acc, t| acc + t.size()), - } - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - let mut offset = 0usize; - for item in self.iter() { - let next_size = match T::len_params() { - 0 => mem::size_of::(), - _ => { let size = item.size(); length_stack.push_back(size); size }, - }; - if next_size > 0 { - let item_end = offset + next_size; - item.to_bytes(&mut buffer[offset..item_end], length_stack)?; - offset = item_end; - } - } - Ok(()) - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - let mut index = 0; - let mut result = Self::with_capacity( - match T::len_params() { - 0 => buffer.len() / mem::size_of::(), - _ => 128, - }); - - if buffer.len() == 0 { return Ok(result); } - - loop { - let next_size = match T::len_params() { - 0 => mem::size_of::(), - _ => length_stack.pop_front().ok_or(BinaryConvertError::length())?, - }; - let item = if next_size == 0 { - T::from_empty_bytes()? - } - else { - if index + next_size > buffer.len() { - return Err(BinaryConvertError::boundaries()) - } - T::from_bytes(&buffer[index..index+next_size], length_stack)? - }; - result.push(item); - - index = index + next_size; - if index == buffer.len() { break; } - if index > buffer.len() { - return Err(BinaryConvertError::boundaries()) - } - } - - Ok(result) - } - - fn from_empty_bytes() -> Result { - Ok(Self::new()) - } - - fn len_params() -> usize { - 1 - } -} - -impl BinaryConvertable for String { - fn size(&self) -> usize { - self.as_bytes().len() - } - - fn from_empty_bytes() -> Result { - Ok(String::new()) - } - - fn to_bytes(&self, buffer: &mut [u8], _length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - buffer[..].clone_from_slice(self.as_bytes()); - Ok(()) - } - - fn from_bytes(buffer: &[u8], _length_stack: &mut VecDeque) -> Result { - Ok(::std::str::from_utf8(buffer).unwrap().to_owned()) - } - - fn len_params() -> usize { - 1 - } -} - -impl BinaryConvertable for Range where T: BinaryConvertable { - fn size(&self) -> usize { - mem::size_of::() * 2 - } - - fn from_empty_bytes() -> Result { - Err(BinaryConvertError::empty()) - } - - fn to_bytes(&self, buffer: &mut[u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - self.start.to_bytes(&mut buffer[..mem::size_of::()], length_stack)?; - self.end.to_bytes(&mut buffer[mem::size_of::() + 1..], length_stack)?; - Ok(()) - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - Ok(T::from_bytes(&buffer[..mem::size_of::()], length_stack)?..T::from_bytes(&buffer[mem::size_of::()+1..], length_stack)?) - } - - fn len_params() -> usize { - assert_eq!(0, T::len_params()); - 0 - } -} - -impl BinaryConvertable for ::std::cell::RefCell where T: BinaryConvertable { - fn size(&self) -> usize { - self.borrow().size() - } - - fn from_empty_bytes() -> Result { - Ok(::std::cell::RefCell::new(T::from_empty_bytes()?)) - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - Ok(::std::cell::RefCell::new(T::from_bytes(buffer, length_stack)?)) - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - self.borrow().to_bytes(buffer, length_stack)?; - Ok(()) - } - - fn len_params() -> usize { - T::len_params() - } -} - -impl BinaryConvertable for ::std::cell::Cell where T: BinaryConvertable + Copy { - fn size(&self) -> usize { - self.get().size() - } - - fn from_empty_bytes() -> Result { - Ok(::std::cell::Cell::new(T::from_empty_bytes()?)) - } - - fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { - Ok(::std::cell::Cell::new(T::from_bytes(buffer, length_stack)?)) - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - self.get().to_bytes(buffer, length_stack)?; - Ok(()) - } - - fn len_params() -> usize { - T::len_params() - } -} - -impl BinaryConvertable for Vec { - fn size(&self) -> usize { - self.len() - } - - fn from_empty_bytes() -> Result { - Ok(Vec::new()) - } - - fn to_bytes(&self, buffer: &mut [u8], _length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { - buffer[..].clone_from_slice(&self[..]); - Ok(()) - } - - fn from_bytes(buffer: &[u8], _length_stack: &mut VecDeque) -> Result { - let mut res = Self::with_capacity(buffer.len()); - unsafe { res.set_len(buffer.len()) } - res[..].clone_from_slice(&buffer[..]); - Ok(res) - } - - fn len_params() -> usize { - 1 - } -} - -pub fn deserialize_from(r: &mut R) -> Result - where R: ::std::io::Read, - T: BinaryConvertable -{ - let mut fake_stack = VecDeque::new(); - - match T::len_params() { - 0 => { - let fixed_size = mem::size_of::(); - let mut payload_buffer = Vec::with_capacity(fixed_size); - unsafe { payload_buffer.set_len(fixed_size); } - let bytes_read = r.read(&mut payload_buffer)?; - if bytes_read != mem::size_of::() { - return Err(BinaryError::Serialization(BinaryConvertError::size(fixed_size, bytes_read))) - } - Ok(T::from_bytes(&payload_buffer[..], &mut fake_stack)?) - }, - _ => { - let mut payload = Vec::new(); - r.read_to_end(&mut payload)?; - - let stack_len = u64::from_bytes(&payload[0..8], &mut fake_stack)? as usize; - let mut length_stack = VecDeque::::with_capacity(stack_len); - - if stack_len > 0 { - for idx in 0..stack_len { - let stack_item = u64::from_bytes(&payload[8 + idx*8..8 + (idx+1)*8], &mut fake_stack)?; - length_stack.push_back(stack_item as usize); - } - } - - let size = u64::from_bytes(&payload[8+stack_len*8..16+stack_len*8], &mut fake_stack)? as usize; - match size { - 0 => { - Ok(T::from_empty_bytes()?) - }, - _ => { - Ok(T::from_bytes(&payload[16+stack_len*8..], &mut length_stack)?) - } - } - }, - } -} - -pub fn deserialize(buffer: &[u8]) -> Result { - use std::io::Cursor; - let mut buff = Cursor::new(buffer); - deserialize_from::(&mut buff) -} - -pub fn serialize_into(t: &T, w: &mut W) -> Result<(), BinaryError> - where W: ::std::io::Write, - T: BinaryConvertable -{ - let mut fake_stack = VecDeque::new(); - - match T::len_params() { - 0 => { - let fixed_size = mem::size_of::(); - let mut buffer = Vec::with_capacity(fixed_size); - unsafe { buffer.set_len(fixed_size); } - t.to_bytes(&mut buffer[..], &mut fake_stack)?; - w.write(&buffer[..])?; - Ok(()) - }, - _ => { - let mut length_stack = VecDeque::::new(); - let mut size_buffer = [0u8; 8]; - - let size = t.size(); - if size == 0 { - w.write(&size_buffer)?; - w.write(&size_buffer)?; - return Ok(()); - } - - let mut buffer = Vec::with_capacity(size); - unsafe { buffer.set_len(size); } - t.to_bytes(&mut buffer[..], &mut length_stack)?; - - let stack_len = length_stack.len(); - (stack_len as u64).to_bytes(&mut size_buffer[..], &mut fake_stack)?; - w.write(&size_buffer[..])?; - if stack_len > 0 { - let mut header_buffer = Vec::with_capacity(stack_len * 8); - unsafe { header_buffer.set_len(stack_len * 8); }; - (stack_len as u64).to_bytes(&mut header_buffer[0..8], &mut fake_stack)?; - let mut idx = 0; - loop { - match length_stack.pop_front() { - Some(val) => (val as u64).to_bytes(&mut header_buffer[idx * 8..(idx+1) * 8], &mut fake_stack)?, - None => { break; } - } - idx = idx + 1; - } - w.write(&header_buffer[..])?; - } - - (size as u64).to_bytes(&mut size_buffer[..], &mut fake_stack)?; - w.write(&size_buffer[..])?; - - w.write(&buffer[..])?; - - Ok(()) - }, - } -} - -pub fn serialize(t: &T) -> Result, BinaryError> { - use std::io::Cursor; - let mut buff = Cursor::new(Vec::new()); - serialize_into(t, &mut buff)?; - let into_inner = buff.into_inner(); - Ok(into_inner) -} - -#[macro_export] -macro_rules! binary_fixed_size { - ($target_ty: ty) => { - impl BinaryConvertable for $target_ty where $target_ty: Copy { - fn from_bytes(bytes: &[u8], _length_stack: &mut ::std::collections::VecDeque) -> Result { - let size = ::std::mem::size_of::<$target_ty>(); - match bytes.len().cmp(&size) { - ::std::cmp::Ordering::Equal => (), - _ => return Err(BinaryConvertError::size(size, bytes.len())), - }; - let res: Self = unsafe { - let mut temp = ::std::mem::zeroed(); - let temp_ptr = &mut temp as *mut _ as *mut u8; - ::std::ptr::copy_nonoverlapping(bytes.as_ptr(), temp_ptr, size); - - temp - }; - - Ok(res) - } - - fn to_bytes(&self, buffer: &mut [u8], _length_stack: &mut ::std::collections::VecDeque) -> Result<(), BinaryConvertError> { - let sz = ::std::mem::size_of::<$target_ty>(); - let ip: *const $target_ty = self; - let ptr: *const u8 = ip as *const _; - unsafe { - ::std::ptr::copy(ptr, buffer.as_mut_ptr(), sz); - } - Ok(()) - } - } - } -} - -/// Fixed-sized version of Handshake struct -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct BinHandshake { - api_version: BinVersion, - protocol_version: BinVersion, -} - -/// Shorten version of semver Version without `pre` and `build` information -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct BinVersion { - pub major: u64, - pub minor: u64, - pub patch: u64, -} - -impl From for BinHandshake { - fn from(other: Handshake) -> Self { - BinHandshake { - api_version: BinVersion::from(other.api_version), - protocol_version: BinVersion::from(other.protocol_version), - } - } -} - -impl BinHandshake { - pub fn to_semver(self) -> Handshake { - Handshake { - api_version: self.api_version.to_semver(), - protocol_version: self.protocol_version.to_semver(), - } - } -} - -impl BinVersion { - pub fn to_semver(self) -> ::semver::Version { - ::semver::Version { - major: self.major, - minor: self.minor, - patch: self.patch, - pre: vec![], - build: vec![], - } - } -} - -impl From<::semver::Version> for BinVersion { - fn from(other: ::semver::Version) -> Self { - BinVersion { - major: other.major, - minor: other.minor, - patch: other.patch, - } - } -} - -binary_fixed_size!(u16); -binary_fixed_size!(u64); -binary_fixed_size!(u32); -binary_fixed_size!(usize); -binary_fixed_size!(i32); -binary_fixed_size!(bool); -binary_fixed_size!(U256); -binary_fixed_size!(U512); -binary_fixed_size!(H256); -binary_fixed_size!(H512); -binary_fixed_size!(H2048); -binary_fixed_size!(Address); -binary_fixed_size!(BinHandshake); -binary_fixed_size!(BinVersion); - -impl BinaryConvertable for ::semver::Version { - fn from_bytes(bytes: &[u8], length_stack: &mut ::std::collections::VecDeque) -> Result { - BinVersion::from_bytes(bytes, length_stack).map(BinVersion::to_semver) - } - - fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut ::std::collections::VecDeque) -> Result<(), BinaryConvertError> { - BinVersion::from(self.clone()).to_bytes(buffer, length_stack) - } -} - -#[test] -fn vec_serialize() { - let mut v = Vec::new(); - v.push(5u64); - v.push(10u64); - let mut length_stack = VecDeque::new(); - let mut data = Vec::with_capacity(v.size()); - unsafe { data.set_len(v.size()); } - let result = v.to_bytes(&mut data[..], &mut length_stack); - - assert!(result.is_ok()); - assert_eq!(5, data[0]); - assert_eq!(0, data[1]); - assert_eq!(10, data[8]); - assert_eq!(0, data[12]); -} - -#[test] -fn calculates_size() { - let mut v = Vec::new(); - v.push(5u64); - v.push(10u64); - - assert_eq!(16, v.size()); -} - -#[test] -fn vec_deserialize() { - let data = [ - 10u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - ]; - - let mut length_stack = VecDeque::new(); - let vec = Vec::::from_bytes(&data[..], &mut length_stack).unwrap(); - - assert_eq!(vec![10u64, 5u64], vec); -} - -#[test] -fn vec_deserialize_chained() { - let mut v = Vec::new(); - v.push(Some(5u64)); - v.push(Some(10u64)); - v.push(None); - v.push(Some(12u64)); - - let mut length_stack = VecDeque::new(); - let mut data = Vec::with_capacity(v.size()); - unsafe { data.set_len(v.size()); } - let result = v.to_bytes(&mut data[..], &mut length_stack); - - assert!(result.is_ok()); - assert_eq!(4, length_stack.len()); -} - -#[test] -fn vec_serialize_deserialize() { - let mut v = Vec::new(); - v.push(Some(5u64)); - v.push(None); - v.push(Some(10u64)); - v.push(None); - v.push(Some(12u64)); - - - let mut data = Vec::with_capacity(v.size()); - unsafe { data.set_len(v.size()); } - let mut length_stack = VecDeque::new(); - - v.to_bytes(&mut data[..], &mut length_stack).unwrap(); - let de_v = Vec::>::from_bytes(&data[..], &mut length_stack).unwrap(); - - assert_eq!(v, de_v); -} - -#[test] -fn serialize_into_ok() { - use std::io::Cursor; - let mut buff = Cursor::new(vec![0; 128]); - - let mut v = Vec::new(); - v.push(Some(5u64)); - v.push(None); - v.push(Some(10u64)); - v.push(None); - v.push(Some(12u64)); - - serialize_into(&v, &mut buff).unwrap(); - assert_eq!(5, buff.get_ref()[0]); - assert_eq!(8, buff.get_ref()[8]); - assert_eq!(0, buff.get_ref()[16]); - assert_eq!(8, buff.get_ref()[24]); -} - -#[test] -fn deserialize_from_ok() { - use std::io::Cursor; - let mut buff = Cursor::new(vec![ - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 16u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 10u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - ]); - - let vec = deserialize_from::, _>(&mut buff).unwrap(); - - assert_eq!(vec![10u64, 5u64], vec); -} - -#[test] -fn serialize_into_deserialize_from() { - use std::io::{Cursor, SeekFrom, Seek}; - - let mut buff = Cursor::new(Vec::new()); - let mut v = Vec::new(); - v.push(Some(5u64)); - v.push(None); - v.push(Some(10u64)); - v.push(None); - v.push(Some(12u64)); - - serialize_into(&v, &mut buff).unwrap(); - buff.seek(SeekFrom::Start(0)).unwrap(); - let de_v = deserialize_from::>, _>(&mut buff).unwrap(); - assert_eq!(v, de_v); -} - -#[test] -fn serialize_vec_str() { - // empty - let source = Vec::::new(); - let serialized = serialize(&source).unwrap(); - let deserialized = deserialize::>(&serialized).unwrap(); - - assert_eq!(source, deserialized); - - // with few values - let mut source = Vec::::new(); - source.push("val1".to_owned()); - source.push("val2".to_owned()); - let serialized = serialize(&source).unwrap(); - let deserialized = deserialize::>(&serialized).unwrap(); - - assert_eq!(source, deserialized); -} - -#[test] -fn serialize_opt_str() { - // none - let source: Option = None; - let serialized = serialize(&source).unwrap(); - let deserialized = deserialize::>(&serialized).unwrap(); - - assert_eq!(source, deserialized); - - // value - let source: Option = Some("i have value".to_owned()); - let serialized = serialize(&source).unwrap(); - let deserialized = deserialize::>(&serialized).unwrap(); - - assert_eq!(source, deserialized); -} - -#[test] -fn serialize_opt_vec() { - use std::io::Cursor; - - let mut buff = Cursor::new(Vec::new()); - let optional_vec: Option> = None; - serialize_into(&optional_vec, &mut buff).unwrap(); - - assert_eq!(&vec![0u8; 16], buff.get_ref()); -} - -#[test] -fn serialize_opt_vec_payload() { - let optional_vec: Option> = None; - let payload = serialize(&optional_vec).unwrap(); - - assert_eq!(vec![0u8;16], payload); -} - -#[test] -fn deserialize_opt_vec() { - use std::io::Cursor; - let mut buff = Cursor::new(vec![0u8; 16]); - - let vec = deserialize_from::>, _>(&mut buff).unwrap(); - - assert!(vec.is_none()); -} - -#[test] -fn deserialize_simple_err() { - use std::io::Cursor; - let mut buff = Cursor::new(vec![0u8; 16]); - - let result = deserialize_from::, _>(&mut buff).unwrap(); - - assert!(result.is_ok()); -} - -#[test] -fn serialize_opt_vec_in_out() { - use std::io::{Cursor, SeekFrom, Seek}; - - let mut buff = Cursor::new(Vec::new()); - let optional_vec: Option> = None; - serialize_into(&optional_vec, &mut buff).unwrap(); - - buff.seek(SeekFrom::Start(0)).unwrap(); - let vec = deserialize_from::>, _>(&mut buff).unwrap(); - - assert!(vec.is_none()); -} - -#[test] -fn serialize_err_opt_vec_in_out() { - use std::io::{Cursor, SeekFrom, Seek}; - - let mut buff = Cursor::new(Vec::new()); - let optional_vec: Result>, u32> = Ok(None); - serialize_into(&optional_vec, &mut buff).unwrap(); - - buff.seek(SeekFrom::Start(0)).unwrap(); - let vec = deserialize_from::>, u32>, _>(&mut buff).unwrap(); - - assert!(vec.is_ok()); -} - -#[test] -fn serialize_btree() { - use std::io::{Cursor, SeekFrom, Seek}; - - let mut buff = Cursor::new(Vec::new()); - let mut btree = BTreeMap::new(); - btree.insert(1u64, 5u64); - serialize_into(&btree, &mut buff).unwrap(); - - buff.seek(SeekFrom::Start(0)).unwrap(); - let res = deserialize_from::, _>(&mut buff).unwrap(); - - assert_eq!(res[&1u64], 5u64); -} - -#[test] -fn serialize_refcell() { - use std::cell::RefCell; - - let source = RefCell::new(vec![5u32, 12u32, 19u32]); - let serialized = serialize(&source).unwrap(); - let deserialized = deserialize::>>(&serialized).unwrap(); - - assert_eq!(source, deserialized); -} - -#[test] -fn serialize_cell() { - use std::cell::Cell; - use std::str::FromStr; - - let source = Cell::new(U256::from_str("01231231231239999").unwrap()); - let serialized = serialize(&source).unwrap(); - let deserialized = deserialize::>(&serialized).unwrap(); - - assert_eq!(source, deserialized); -} - -#[test] -fn serialize_handshake() { - use std::io::{Cursor, SeekFrom, Seek}; - - let mut buff = Cursor::new(Vec::new()); - - let handshake = Handshake { - api_version: ::semver::Version::parse("1.2.0").unwrap(), - protocol_version: ::semver::Version::parse("1.2.0").unwrap(), - }; - - serialize_into(&BinHandshake::from(handshake.clone()), &mut buff).unwrap(); - - buff.seek(SeekFrom::Start(0)).unwrap(); - let res = deserialize_from::(&mut buff).unwrap().to_semver(); - - assert_eq!(res, handshake); -} - -#[test] -fn serialize_invalid_size() { - // value - let deserialized = deserialize::(&[]); - match deserialized { - Err(BinaryError::Serialization( - BinaryConvertError { - kind: BinaryConvertErrorKind::SizeMismatch { expected: 8, found: 0 }, - member_tree: _ - })) => {}, - other => panic!("Not a size mismatched error but: {:?}", other), - } -} - -#[test] -fn serialize_boundaries() { - // value - let deserialized = deserialize::>( - &[ - // payload header - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - // - 0u8, 0u8, 0u8, 5u8, - 0u8, 0u8, 0u8, 4u8, - 1u8, 1u8, /* not 4 bytes */ - ] - ); - match deserialized { - Err(BinaryError::Serialization( - BinaryConvertError { - kind: BinaryConvertErrorKind::InconsistentBoundaries, - member_tree: _ - })) => {}, - other => panic!("Not an inconsistent boundaries error but: {:?}", other), - } -} - -#[test] -fn serialize_empty_try() { - // value - let mut stack = VecDeque::new(); - let mut data = vec![0u8; 16]; - let sample: Option> = None; - let serialized = sample.to_bytes(&mut data, &mut stack); - match serialized { - Err(BinaryConvertError { - kind: BinaryConvertErrorKind::TargetPayloadEmpty, - member_tree: _ - }) => {}, - other => panic!("Not an error about empty payload to be produced but: {:?}", other), - } -} - -#[test] -fn serialize_not_enough_lengths() { - // value - let deserialized = deserialize::>>( - &[ - // payload header - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, - // does not matter because no length param for the first option - 0u8, - ] - ); - match deserialized { - Err(BinaryError::Serialization( - BinaryConvertError { - kind: BinaryConvertErrorKind::MissingLengthValue, - member_tree: _ - })) => {}, - other => panic!("Not an missing length param error but: {:?}", other), - } -} - -#[test] -fn vec_of_vecs() { - let sample = vec![vec![5u8, 10u8], vec![], vec![9u8, 11u8]]; - let serialized = serialize(&sample).unwrap(); - let deserialized = deserialize::>>(&serialized).unwrap(); - assert_eq!(sample, deserialized); - - // empty - let sample: Vec> = vec![]; - let serialized = serialize(&sample).unwrap(); - let deserialized = deserialize::>>(&serialized).unwrap(); - assert_eq!(sample, deserialized); -} diff --git a/ipc/rpc/src/interface.rs b/ipc/rpc/src/interface.rs deleted file mode 100644 index 846b7c1b6..000000000 --- a/ipc/rpc/src/interface.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! IPC RPC interface - -use std::io::{Read, Write}; -use std::marker::Sync; -use semver::Version; - -#[derive(Debug, PartialEq, Eq, Clone)] -/// Handshake for client and server to negotiate api/protocol version -pub struct Handshake { - pub protocol_version: Version, - pub api_version: Version, -} - -/// Allows to configure custom version and custom handshake response for -/// ipc host -pub trait IpcConfig { - /// Current service api version - /// Should be increased if any of the methods changes signature - fn api_version() -> Version { - Version::parse("1.0.0").unwrap() - } - - /// Current ipc protocol version - /// Should be increased only if signature of system methods changes - fn protocol_version() -> Version { - Version::parse("1.0.0").unwrap() - } - - /// Default handshake requires exact versions match - fn handshake(handshake: &Handshake) -> bool { - handshake.protocol_version == Self::protocol_version() && - handshake.api_version == Self::api_version() - } -} - -/// Error in dispatching or invoking methods via IPC -#[derive(Debug)] -pub enum Error { - UnknownSystemCall, - ClientUnsupported, - RemoteServiceUnsupported, - HandshakeFailed, -} - -/// Allows implementor to be attached to generic worker and dispatch rpc requests -/// over IPC -pub trait IpcInterface : IpcConfig { - /// reads the message from io, dispatches the call and returns serialized result - fn dispatch(&self, r: &mut R) -> Vec where R: Read; - - /// deserializes the payload from buffer, dispatches invoke and returns serialized result - /// (for non-blocking io) - fn dispatch_buf(&self, method_num: u16, buf: &[u8]) -> Vec; -} - -/// serializes method invocation (method_num and parameters) to the stream specified by `w` -pub fn invoke(method_num: u16, params: &Option>, w: &mut W) where W: Write { - // creating buffer to contain all message - let buf_len = match *params { None => 2, Some(ref val) => val.len() + 2 }; - let mut buf = vec![0u8; buf_len]; - - // writing method_num as u16 - buf[1] = (method_num & 255) as u8; - buf[0] = (method_num >> 8) as u8; - - // serializing parameters only if provided with any - if params.is_some() { - buf[2..buf_len].clone_from_slice(params.as_ref().unwrap()); - } - - if w.write(&buf).unwrap() != buf_len - { - // if write was inconsistent - panic!("failed to write to socket"); - } -} - -/// IpcSocket, read/write generalization -pub trait IpcSocket: Read + Write + Sync + Send { -} - -/// Basically something that needs only socket to be spawned -pub trait WithSocket { - fn init(socket: S) -> Self; -} - - -impl IpcSocket for ::devtools::TestSocket {} - -impl IpcSocket for ::nanomsg::Socket {} diff --git a/ipc/rpc/src/lib.rs b/ipc/rpc/src/lib.rs deleted file mode 100644 index c6aff23b5..000000000 --- a/ipc/rpc/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! IPC RPC interface - -extern crate ethcore_devtools as devtools; -extern crate semver; -extern crate nanomsg; -extern crate ethcore_util as util; -extern crate ethcore_bigint as bigint; - -pub mod interface; -pub mod binary; -pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket}; -pub use binary::{BinaryConvertable, BinaryConvertError, BinVersion, BinHandshake}; diff --git a/ipc/tests/Cargo.toml b/ipc/tests/Cargo.toml deleted file mode 100644 index 3bf5dc316..000000000 --- a/ipc/tests/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "ethcore-ipc-tests" -version = "0.1.0" -authors = ["Parity Technologies "] -build = "build.rs" - -[lib] -path = "run.rs" - -[dependencies] -ethcore-ipc = { path = "../rpc" } -ethcore-devtools = { path = "../../devtools" } -semver = "0.6" -nanomsg = { git = "https://github.com/paritytech/nanomsg.rs.git", branch = "parity-1.7" } -ethcore-ipc-nano = { path = "../nano" } -ethcore-util = { path = "../../util" } -ethcore-bytes = { path = "../../util/bytes" } -log = "0.3" - -[build-dependencies] -ethcore-ipc-codegen = { path = "../codegen" } diff --git a/ipc/tests/binary.rs b/ipc/tests/binary.rs deleted file mode 100644 index 6eb1da852..000000000 --- a/ipc/tests/binary.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues - -include!(concat!(env!("OUT_DIR"), "/binary.rs.in")); diff --git a/ipc/tests/binary.rs.in b/ipc/tests/binary.rs.in deleted file mode 100644 index 8b04f683b..000000000 --- a/ipc/tests/binary.rs.in +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - - -use bytes::Bytes; - -#[binary] -pub enum Root { - Top, - Middle(u32, u64), -} - -#[derive(PartialEq, Debug)] -#[binary] -pub struct DoubleRoot { - pub x1: u32, - pub x2: u64, - pub x3: u32, -} - -#[derive(PartialEq, Debug)] -#[binary] -pub struct ReferenceStruct<'a> { - pub ref_data: &'a u64, -} - -#[derive(PartialEq, Debug)] -#[binary] -pub enum EnumWithStruct { - Left, - Right { how_much: u64 }, -} - -#[binary] -pub struct TwoVec { - v1: Vec, - v2: Vec, -} - -#[binary] -struct ChunkSet { - items: Vec, -} - -#[test] -fn opt_two_vec() { - let example: Option = None; - - let serialized = ::ipc::binary::serialize(&example).unwrap(); - assert_eq!(serialized, vec![0u8; 16]); -} - -#[test] -fn enum_with_struct() { - let example = EnumWithStruct::Right { how_much: 15 }; - let serialized = ::ipc::binary::serialize(&example).unwrap(); - let deserialized = ::ipc::binary::deserialize::(&serialized).unwrap(); - assert_eq!(example, deserialized); -} - -#[test] -fn chunks() { - let sample: Vec = vec! [ - 15, 0, 0, 0, 0, 0, 0, 0, 81, 6, 0, 0, 0, 0, 0, 0, - 110, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, - 112, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, - 173, 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, - 112, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, - 107, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, - 114, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, - 114, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, - 81, 6, 0, 0, 0, 0, 0, 0, - - 248, 108, 58, 133, 4, 168, 23, 200, 0, 130, 82, 8, 148, 182, 54, - 177, 224, 198, 163, 123, 250, 122, 157, 158, 75, 138, 30, 7, 83, 91, 141, 56, 46, 136, 2, - 197, 12, 243, 220, 69, 192, 0, 128, 28, 160, 32, 232, 123, 221, 90, 116, 93, 94, 136, 78, - 235, 200, 167, 154, 3, 175, 74, 53, 133, 32, 239, 199, 169, 46, 95, 111, 114, 204, 19, 138, - 15, 167, 160, 103, 72, 60, 241, 165, 248, 130, 213, 45, 166, 249, 102, 83, 87, 98, 153, - 68, 58, 13, 83, 193, 182, 217, 182, 9, 241, 217, 28, 162, 152, 114, 136, 248, 110, 130, 6, - 96, 133, 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, 100, 131, 212, 219, 190, 174, 5, 47, - 105, 201, 11, 11, 210, 108, 207, 242, 164, 74, 218, 19, 135, 6, 10, 36, 24, 30, 64, 0, - 128, 27, 160, 206, 145, 163, 186, 24, 122, 126, 115, 80, 203, 152, 219, 160, 243, 1, 139, - 109, 199, 115, 50, 159, 197, 95, 184, 174, 53, 150, 3, 200, 82, 138, 22, 160, 119, 226, - 202, 208, 136, 165, 174, 240, 216, 222, 27, 214, 12, 213, 250, 68, 214, 144, 120, 53, 158, - 46, 124, 105, 87, 220, 213, 192, 28, 81, 118, 6, 248, 110, 130, 6, 95, 133, 4, 168, 23, - 200, 0, 131, 1, 95, 144, 148, 100, 131, 212, 219, 190, 174, 5, 47, 105, 201, 11, 11, 210, - 108, 207, 242, 164, 74, 218, 19, 135, 6, 10, 36, 24, 30, 64, 0, 128, 27, 160, 19, 172, 66, - 208, 28, 189, 213, 239, 125, 170, 127, 147, 190, 97, 171, 194, 229, 241, 178, 176, 111, - 3, 201, 217, 9, 179, 23, 159, 159, 64, 55, 225, 160, 7, 123, 227, 76, 149, 80, 48, 130, - 122, 23, 165, 175, 24, 89, 228, 128, 25, 106, 160, 195, 82, 204, 206, 150, 83, 70, 127, - 34, 221, 169, 80, 43, 248, 110, 130, 6, 102, 133, 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, - 100, 131, 212, 219, 190, 174, 5, 47, 105, 201, 11, 11, 210, 108, 207, 242, 164, 74, 218, - 19, 135, 6, 10, 36, 24, 30, 64, 0, 128, 27, 160, 29, 6, 237, 5, 67, 42, 51, 65, 172, 133, - 9, 222, 160, 39, 202, 88, 230, 123, 232, 135, 234, 5, 244, 215, 99, 129, 242, 59, 63, 36, - 26, 253, 160, 104, 178, 37, 227, 142, 255, 186, 41, 91, 108, 206, 13, 108, 24, 73, 229, - 96, 224, 142, 230, 93, 214, 27, 60, 119, 149, 119, 56, 62, 5, 204, 179, 248, 171, 129, 136, - 133, 4, 168, 23, 200, 0, 131, 2, 77, 248, 148, 137, 32, 90, 58, 59, 42, 105, 222, 109, 191, - 127, 1, 237, 19, 178, 16, 139, 44, 67, 231, 128, 184, 68, 169, 5, 156, 187, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 105, 4, 134, 47, 167, 212, 79, 177, 44, 91, 97, 85, 184, 182, 222, 59, 231, 242, - 110, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 28, 160, 98, 5, 133, 180, 19, 27, 159, 186, 76, 27, 159, 143, 186, 97, 124, 253, 123, 40, - 87, 35, 184, 115, 99, 176, 68, 85, 191, 210, 218, 132, 220, 52, 160, 48, 160, 79, 26, 47, 127, 253, - 55, 252, 196, 196, 129, 87, 131, 132, 84, 74, 166, 33, 85, 134, 25, 34, 244, 14, 1, 16, 1, 205, 34, - 30, 3, 248, 101, 3, 133, 13, 43, 184, 47, 225, 131, 1, 95, 144, 148, 202, 110, 19, 32, 65, 111, 158, - 204, 235, 91, 252, 213, 35, 215, 54, 91, 165, 67, 183, 171, 1, 128, 28, 160, 182, 194, 27, 223, 136, - 182, 189, 146, 57, 61, 173, 62, 58, 241, 42, 80, 125, 174, 84, 191, 82, 124, 228, 62, 216, 233, 116, - 117, 227, 207, 138, 56, 160, 31, 210, 242, 212, 31, 156, 129, 155, 166, 64, 102, 140, 134, 35, 176, - 137, 201, 206, 213, 199, 238, 132, 185, 145, 220, 217, 151, 80, 243, 93, 71, 211, 248, 110, 130, - 6, 101, 133, 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, 100, 131, 212, 219, 190, 174, 5, 47, 105, - 201, 11, 11, 210, 108, 207, 242, 164, 74, 218, 19, 135, 6, 10, 36, 24, 30, 64, 0, 128, 27, 160, - 86, 37, 61, 45, 13, 251, 9, 19, 188, 242, 233, 83, 77, 137, 28, 185, 141, 105, 217, 54, 182, 156, - 119, 223, 213, 112, 240, 20, 119, 167, 4, 7, 160, 95, 53, 122, 159, 6, 209, 70, 155, 122, 153, 165, - 192, 249, 223, 219, 83, 159, 40, 242, 39, 44, 132, 182, 208, 232, 77, 64, 178, 241, 233, 230, 253, - 248, 110, 130, 6, 99, 133, 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, 100, 131, 212, 219, 190, 174, - 5, 47, 105, 201, 11, 11, 210, 108, 207, 242, 164, 74, 218, 19, 135, 6, 10, 36, 24, 30, 64, 0, 128, - 27, 160, 114, 33, 104, 64, 195, 12, 156, 235, 56, 59, 210, 102, 183, 210, 216, 137, 223, 207, 134, - 63, 65, 36, 204, 121, 38, 175, 214, 106, 184, 197, 26, 173, 160, 39, 94, 238, 34, 106, 190, 22, - 225, 95, 211, 192, 249, 95, 231, 1, 111, 8, 204, 133, 35, 84, 242, 134, 75, 61, 50, 26, 150, 46, - 209, 129, 155, 248, 105, 106, 133, 5, 103, 130, 1, 225, 131, 2, 130, 119, 148, 191, 78, 215, 178, - 127, 29, 102, 101, 70, 227, 13, 116, 213, 13, 23, 61, 32, 188, 167, 84, 128, 132, 60, 207, 214, - 11, 28, 160, 3, 83, 228, 182, 32, 30, 183, 26, 157, 247, 32, 142, 60, 192, 100, 175, 106, 216, - 144, 16, 100, 165, 95, 91, 135, 138, 14, 41, 82, 251, 207, 159, 160, 74, 160, 161, 187, 63, 216, - 18, 23, 64, 172, 216, 238, 192, 134, 191, 204, 206, 236, 197, 134, 116, 130, 15, 85, 113, 173, - 130, 39, 50, 160, 49, 222, 248, 110, 130, 6, 98, 133, 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, - 100, 131, 212, 219, 190, 174, 5, 47, 105, 201, 11, 11, 210, 108, 207, 242, 164, 74, 218, 19, 135, - 6, 10, 36, 24, 30, 64, 0, 128, 28, 160, 138, 12, 20, 188, 112, 66, 91, 30, 216, 44, 24, 124, 242, - 200, 111, 179, 32, 26, 37, 221, 239, 110, 1, 84, 48, 89, 86, 61, 169, 129, 90, 21, 160, 44, 172, - 112, 11, 130, 45, 247, 188, 207, 91, 247, 195, 58, 188, 110, 127, 59, 227, 41, 151, 244, 41, 120, - 68, 185, 238, 41, 236, 195, 141, 38, 16, 248, 112, 131, 5, 238, 44, 133, 4, 168, 23, 200, 0, 131, - 1, 95, 144, 148, 5, 113, 9, 145, 204, 89, 103, 32, 126, 46, 182, 84, 47, 76, 28, 159, 77, 184, - 154, 59, 136, 1, 100, 240, 147, 154, 69, 101, 18, 128, 27, 160, 130, 0, 124, 82, 177, 112, 241, - 14, 47, 186, 67, 117, 176, 187, 147, 94, 4, 177, 218, 198, 55, 59, 245, 9, 142, 95, 88, 220, 63, - 98, 175, 49, 160, 17, 204, 228, 24, 242, 38, 166, 219, 17, 56, 103, 244, 33, 125, 223, 45, 43, - 252, 215, 163, 40, 1, 187, 152, 34, 229, 82, 180, 213, 148, 129, 32, 248, 110, 130, 6, 100, 133, - 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, 100, 131, 212, 219, 190, 174, 5, 47, 105, 201, 11, 11, - 210, 108, 207, 242, 164, 74, 218, 19, 135, 6, 10, 36, 24, 30, 64, 0, 128, 27, 160, 149, 149, 154, - 6, 198, 127, 14, 11, 164, 0, 244, 4, 74, 83, 9, 108, 164, 66, 186, 26, 109, 69, 98, 41, 149, 33, - 238, 137, 23, 175, 124, 226, 160, 39, 249, 210, 237, 52, 83, 110, 229, 138, 84, 199, 64, 19, 209, - 156, 195, 9, 50, 184, 64, 78, 67, 158, 167, 121, 220, 80, 137, 104, 240, 50, 60, 248, 112, 131, 5, - 238, 45, 133, 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, 247, 0, 201, 156, 113, 12, 158, 3, 208, 61, - 221, 91, 236, 235, 235, 195, 40, 46, 100, 73, 136, 13, 230, 68, 67, 114, 161, 197, 100, 128, 27, - 160, 123, 206, 0, 221, 2, 87, 197, 156, 109, 157, 133, 31, 26, 145, 223, 150, 235, 160, 54, 144, - 210, 146, 31, 173, 221, 128, 233, 148, 73, 82, 191, 220, 160, 57, 62, 114, 94, 77, 8, 116, 150, - 51, 112, 241, 70, 149, 157, 209, 193, 213, 109, 248, 102, 177, 27, 132, 226, 77, 141, 128, 122, - 185, 238, 188, 114, 248, 110, 130, 6, 97, 133, 4, 168, 23, 200, 0, 131, 1, 95, 144, 148, 100, - 131, 212, 219, 190, 174, 5, 47, 105, 201, 11, 11, 210, 108, 207, 242, 164, 74, 218, 19, 135, 6, - 10, 36, 24, 30, 64, 0, 128, 28, 160, 53, 222, 41, 101, 73, 44, 103, 26, 39, 165, 120, 194, 128, - 67, 109, 151, 96, 42, 193, 47, 255, 23, 27, 247, 8, 125, 200, 53, 129, 69, 103, 64, 160, 49, 12, - 64, 143, 74, 149, 161, 245, 68, 83, 89, 101, 212, 254, 81, 16, 170, 176, 33, 87, 6, 112, 34, 153, - 6, 192, 98, 126, 188, 17, 199, 155]; - - let chunks = ::ipc::binary::deserialize::(&sample).unwrap(); - let total_length = chunks.items.iter().fold(0usize, |total, item| total + item.len()); - - assert_eq!(1617, total_length); -} diff --git a/ipc/tests/build.rs b/ipc/tests/build.rs deleted file mode 100644 index 7f68b16a8..000000000 --- a/ipc/tests/build.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen as codegen; - -pub fn main() { - codegen::derive_ipc("nested.rs.in").unwrap(); - codegen::derive_ipc("service.rs.in").unwrap(); - codegen::derive_ipc("with_attrs.rs.in").unwrap(); - codegen::derive_binary("binary.rs.in").unwrap(); -} diff --git a/ipc/tests/examples.rs b/ipc/tests/examples.rs deleted file mode 100644 index 8cd2d2ea5..000000000 --- a/ipc/tests/examples.rs +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#[cfg(test)] -mod tests { - - use super::super::service::*; - use super::super::binary::*; - use super::super::nested::{DBClient, DBWriter}; - use ipc::*; - use devtools::*; - use semver::Version; - use std::sync::Arc; - - #[test] - fn call_service() { - // method_num = 0, f = 10 (method Service::commit) - let mut socket = TestSocket::new_ready(vec![ - 0, 16, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, - 10, 0, 0, 0]); - - let service = Arc::new(Service::new()); - assert_eq!(0, *service.commits.read().unwrap()); - - service.dispatch(&mut socket); - - assert_eq!(10, *service.commits.read().unwrap()); - } - - #[test] - fn call_service_client() { - let mut socket = TestSocket::new(); - socket.read_buffer = vec![10, 0, 0, 0]; - let service_client = ServiceClient::init(socket); - - let result = service_client.commit(5); - - assert_eq!( - vec![0, 16, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0], - service_client.socket().write().unwrap().write_buffer.clone()); - assert_eq!(10, result); - } - - #[test] - fn call_service_client_optional() { - let mut socket = TestSocket::new(); - socket.read_buffer = vec![10, 0, 0, 0]; - let service_client = ServiceClient::init(socket); - - let result = service_client.rollback(Some(5), 10); - - assert_eq!(vec![ - 0, 17, - 1, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, - 8, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 10, 0, 0, 0], service_client.socket().write().unwrap().write_buffer.clone()); - assert_eq!(10, result); - } - - #[test] - fn query_default_version() { - let ver = Service::protocol_version(); - assert_eq!(ver, Version::parse("1.0.0").unwrap()); - let ver = Service::api_version(); - assert_eq!(ver, Version::parse("1.0.0").unwrap()); - } - - #[test] - fn call_service_client_handshake() { - let mut socket = TestSocket::new(); - socket.read_buffer = vec![1]; - let service_client = ServiceClient::init(socket); - - let result = service_client.handshake(); - - assert!(result.is_ok()); - } - - #[test] - fn can_use_custom_params() { - let mut socket = TestSocket::new(); - socket.read_buffer = vec![1]; - let service_client = ServiceClient::init(socket); - - let result = service_client.push_custom(CustomData { a: 3, b: 11}); - - assert_eq!(vec![ - // message num.. - 0, 18, - // variable size length-s - 1, 0, 0, 0, 0, 0, 0, 0, - 16, 0, 0, 0, 0, 0, 0, 0, - // total length - 16, 0, 0, 0, 0, 0, 0, 0, - // items - 3, 0, 0, 0, 0, 0, 0, 0, - 11, 0, 0, 0, 0, 0, 0, 0], - service_client.socket().write().unwrap().write_buffer.clone()); - assert_eq!(true, result); - } - - #[test] - fn can_invoke_generic_service() { - let mut socket = TestSocket::new(); - socket.read_buffer = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - let db_client = DBClient::::init(socket); - let result = db_client.write(vec![1u8; 1]); - assert_eq!(vec![0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], - db_client.socket().write().unwrap().write_buffer.clone()); - assert!(result.is_ok()); - } - - #[test] - fn can_handshake_generic_service() { - let mut socket = TestSocket::new(); - socket.read_buffer = vec![1]; - let db_client = DBClient::::init(socket); - - let result = db_client.handshake(); - - assert!(result.is_ok()); - } - - #[test] - fn can_serialize_dummy_structs() { - let mut socket = TestSocket::new(); - - let struct_ = DoubleRoot { x1: 0, x2: 100, x3: 100000}; - let res = ::ipc::binary::serialize_into(&struct_, &mut socket); - - assert!(res.is_ok()); - - let mut read_socket = TestSocket::new_ready(socket.write_buffer.clone()); - let new_struct: DoubleRoot = ::ipc::binary::deserialize_from(&mut read_socket).unwrap(); - - assert_eq!(struct_, new_struct); - } - - #[test] - fn can_call_void_method() { - let mut socket = TestSocket::new(); - socket.read_buffer = vec![1]; - let service_client = ServiceClient::init(socket); - - service_client.void(99); - - assert_eq!(vec![ - 0, 19, - 0, 0, 0, 0, 0, 0, 0, 0, - 8, 0, 0, 0, 0, 0, 0, 0, - 99, 0, 0, 0, 0, 0, 0, 0], - service_client.socket().write().unwrap().write_buffer.clone()); - } -} diff --git a/ipc/tests/nested.rs b/ipc/tests/nested.rs deleted file mode 100644 index ab3f9fc1b..000000000 --- a/ipc/tests/nested.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues -include!(concat!(env!("OUT_DIR"), "/nested.rs.in")); diff --git a/ipc/tests/nested.rs.in b/ipc/tests/nested.rs.in deleted file mode 100644 index e68bec0d7..000000000 --- a/ipc/tests/nested.rs.in +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use std::sync::RwLock; -use ipc::IpcConfig; - -pub struct DB { - pub writes: RwLock, - pub reads: RwLock, - pub holdings: L, -} - -pub trait DBWriter { - fn write(&self, data: Vec) -> Result<(), DBError>; - fn write_slice(&self, data: &[u8]) -> Result<(), DBError>; -} - -impl IpcConfig for DBWriter {} - -#[binary] -pub enum DBError { Write, Read } - -#[ipc] -impl DBWriter for DB { - fn write(&self, data: Vec) -> Result<(), DBError> { - let mut writes = self.writes.write().unwrap(); - *writes = *writes + data.len() as u64; - Ok(()) - } - - fn write_slice(&self, data: &[u8]) -> Result<(), DBError> { - let mut writes = self.writes.write().unwrap(); - *writes = *writes + data.len() as u64; - Ok(()) - } -} - -#[ipc] -trait DBNotify { - fn notify(&self, a: u64, b: u64) -> bool; -} - -impl IpcConfig for DBNotify { } diff --git a/ipc/tests/over_nano.rs b/ipc/tests/over_nano.rs deleted file mode 100644 index 6f45dd245..000000000 --- a/ipc/tests/over_nano.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#[cfg(test)] -mod tests { - - use super::super::service::*; - use super::super::with_attrs::PrettyNamedClient; - use nanoipc; - use std::sync::Arc; - use std::io::Write; - use std::sync::atomic::{Ordering, AtomicBool}; - - fn dummy_write(addr: &str, buf: &[u8]) -> (::nanomsg::Socket, ::nanomsg::Endpoint) { - let mut socket = ::nanomsg::Socket::new(::nanomsg::Protocol::Pair).unwrap(); - let endpoint = socket.connect(addr).unwrap(); - socket.write(buf).unwrap(); - (socket, endpoint) - } - - - fn init_worker(addr: &str) -> nanoipc::Worker { - let mut worker = nanoipc::Worker::::new(&Arc::new(Service::new())); - worker.add_duplex(addr).unwrap(); - worker - } - - #[test] - fn can_create_client() { - let client = nanoipc::init_duplex_client::>("ipc:///tmp/parity-nano-test10.ipc"); - assert!(client.is_ok()); - } - - #[test] - fn can_create_renamed_client() { - let client = nanoipc::init_duplex_client::>("ipc:///tmp/parity-nano-test10.ipc"); - assert!(client.is_ok()); - } - - #[test] - fn can_call_handshake() { - let url = "ipc:///tmp/parity-test-nano-20.ipc"; - let worker_should_exit = Arc::new(AtomicBool::new(false)); - let worker_is_ready = Arc::new(AtomicBool::new(false)); - let c_worker_should_exit = worker_should_exit.clone(); - let c_worker_is_ready = worker_is_ready.clone(); - - ::std::thread::spawn(move || { - let mut worker = init_worker(url); - while !c_worker_should_exit.load(Ordering::Relaxed) { - worker.poll(); - c_worker_is_ready.store(true, Ordering::Relaxed); - } - }); - - while !worker_is_ready.load(Ordering::Relaxed) { } - let client = nanoipc::init_duplex_client::>(url).unwrap(); - - let hs = client.handshake(); - - worker_should_exit.store(true, Ordering::Relaxed); - assert!(hs.is_ok()); - } -} diff --git a/ipc/tests/run.rs b/ipc/tests/run.rs deleted file mode 100644 index 83e502aab..000000000 --- a/ipc/tests/run.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#![allow(dead_code)] - -extern crate ethcore_ipc as ipc; -extern crate ethcore_devtools as devtools; -extern crate semver; -extern crate nanomsg; -extern crate ethcore_ipc_nano as nanoipc; -extern crate ethcore_util as util; -extern crate ethcore_bytes as bytes; -#[macro_use] extern crate log; - -pub mod service; -mod examples; -mod over_nano; -mod nested; -mod binary; -mod with_attrs; diff --git a/ipc/tests/service.rs b/ipc/tests/service.rs deleted file mode 100644 index 56b9915db..000000000 --- a/ipc/tests/service.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues -include!(concat!(env!("OUT_DIR"), "/service.rs.in")); diff --git a/ipc/tests/service.rs.in b/ipc/tests/service.rs.in deleted file mode 100644 index 68d40efc4..000000000 --- a/ipc/tests/service.rs.in +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use std::sync::RwLock; -use ipc::IpcConfig; - -pub struct Service { - pub commits: RwLock, - pub rollbacks: RwLock, -} - -#[binary] -pub struct CustomData { - pub a: u64, - pub b: u64, -} - -#[ipc] -impl Service { - fn commit(&self, f: u32) -> u32 { - let mut lock = self.commits.write().unwrap(); - *lock = *lock + f as usize; - f - } - - pub fn rollback(&self, a: Option, b: u32) -> i32 { - let a_0 = a.unwrap_or_else(|| 0); - let mut lock = self.rollbacks.write().unwrap(); - *lock = *lock + a_0 as usize - b as usize; - (a_0 - b) as i32 - } - - pub fn push_custom(&self, data: CustomData) -> bool { - let mut clock = self.commits.write().unwrap(); - let mut rlock = self.commits.write().unwrap(); - - *clock = data.a as usize; - *rlock = data.b as usize; - - true - } - - pub fn void(&self, a: u64) { - } -} - -impl Service { - pub fn new() -> Service { - Service { - commits: RwLock::new(0usize), - rollbacks: RwLock::new(0usize), - } - } -} - -impl ::ipc::IpcConfig for Service {} diff --git a/ipc/tests/with_attrs.rs b/ipc/tests/with_attrs.rs deleted file mode 100644 index 89f3575f7..000000000 --- a/ipc/tests/with_attrs.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues -include!(concat!(env!("OUT_DIR"), "/with_attrs.rs.in")); diff --git a/ipc/tests/with_attrs.rs.in b/ipc/tests/with_attrs.rs.in deleted file mode 100644 index f18dedf9a..000000000 --- a/ipc/tests/with_attrs.rs.in +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use ipc::IpcConfig; - -pub struct BadlyNamedService; - -#[ipc(client_ident="PrettyNamedClient")] -impl BadlyNamedService { - fn is_zero(&self, x: u64) -> bool { - x == 0 - } -} - -impl IpcConfig for BadlyNamedService {} diff --git a/js/i18n/_default/signer.js b/js/i18n/_default/signer.js index 6ba8fde46..8dde08037 100644 --- a/js/i18n/_default/signer.js +++ b/js/i18n/_default/signer.js @@ -69,7 +69,7 @@ export default { hash: `Hash to be signed: {hashToSign}` }, unknownBinary: `(Unknown binary data)`, - warning: `WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure.` + warning: `WARNING: The consequences of doing this may be grave. Confirm the request only if you are sure.` }, title: `Trusted Signer`, txPending: { diff --git a/js/i18n/zh-Hant-TW/signer.js b/js/i18n/zh-Hant-TW/signer.js index df816d734..82544a54a 100644 --- a/js/i18n/zh-Hant-TW/signer.js +++ b/js/i18n/zh-Hant-TW/signer.js @@ -58,7 +58,7 @@ export default { }, unknownBinary: `(未知二進位制資料)`, // (Unknown binary data) warning: `警告:此操作的結果是不可逆的。請在確認資訊後再通過請求。` - // WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure. + // WARNING: The consequences of doing this may be grave. Confirm the request only if you are sure. }, title: `可信的Signer`, // Trusted Signer txPending: { diff --git a/js/i18n/zh/signer.js b/js/i18n/zh/signer.js index ab3b99e53..ea61eca31 100644 --- a/js/i18n/zh/signer.js +++ b/js/i18n/zh/signer.js @@ -58,7 +58,7 @@ export default { }, unknownBinary: `(未知二进制数据)`, // (Unknown binary data) warning: `警告:此操作的结果是不可逆的。请在确认信息后再通过请求。` - // WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure. + // WARNING: The consequences of doing this may be grave. Confirm the request only if you are sure. }, title: `可信的Signer`, // Trusted Signer txPending: { diff --git a/local-store/Cargo.toml b/local-store/Cargo.toml index db9830c40..e4b97f7a4 100644 --- a/local-store/Cargo.toml +++ b/local-store/Cargo.toml @@ -14,4 +14,7 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" log = "0.3" + +[dev-dependencies] ethkey = { path = "../ethkey" } +kvdb-memorydb = { path = "../util/kvdb-memorydb" } diff --git a/local-store/src/lib.rs b/local-store/src/lib.rs index 61fe54976..694fa7aea 100644 --- a/local-store/src/lib.rs +++ b/local-store/src/lib.rs @@ -44,6 +44,8 @@ extern crate log; #[cfg(test)] extern crate ethkey; +#[cfg(test)] +extern crate kvdb_memorydb; const LOCAL_TRANSACTIONS_KEY: &'static [u8] = &*b"LOCAL_TXS"; @@ -54,7 +56,7 @@ const UPDATE_TIMEOUT_MS: u64 = 15 * 60 * 1000; // once every 15 minutes. #[derive(Debug)] pub enum Error { /// Database errors: these manifest as `String`s. - Database(String), + Database(kvdb::Error), /// JSON errors. Json(::serde_json::Error), } @@ -243,7 +245,7 @@ mod tests { #[test] fn twice_empty() { - let db = Arc::new(::kvdb::in_memory(0)); + let db = Arc::new(::kvdb_memorydb::create(0)); { let store = super::create(db.clone(), None, Dummy(vec![])); @@ -272,7 +274,7 @@ mod tests { PendingTransaction::new(signed, condition) }).collect(); - let db = Arc::new(::kvdb::in_memory(0)); + let db = Arc::new(::kvdb_memorydb::create(0)); { // nothing written yet, will write pending. @@ -311,7 +313,7 @@ mod tests { PendingTransaction::new(signed, None) }); - let db = Arc::new(::kvdb::in_memory(0)); + let db = Arc::new(::kvdb_memorydb::create(0)); { // nothing written, will write bad. let store = super::create(db.clone(), None, Dummy(transactions.clone())); diff --git a/parity/boot.rs b/parity/boot.rs deleted file mode 100644 index e2f5587c2..000000000 --- a/parity/boot.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Parity micro-service helpers - -use nanoipc; -use ipc; -use std; -use std::sync::Arc; -use hypervisor::HypervisorServiceClient; -use hypervisor::service::IpcModuleId; -use ctrlc::CtrlC; -use std::sync::atomic::{AtomicBool, Ordering}; -use nanoipc::{IpcInterface, GuardedSocket, NanoSocket}; -use ipc::WithSocket; -use ethcore_logger::{Config as LogConfig, setup_log}; -use docopt::Docopt; - -#[derive(Debug)] -pub enum BootError { - ReadArgs(std::io::Error), - DecodeArgs(ipc::binary::BinaryError), - DependencyConnect(nanoipc::SocketError), -} - -pub fn host_service(addr: &str, stop_guard: Arc, service: Arc) where T: IpcInterface { - let socket_url = addr.to_owned(); - std::thread::spawn(move || { - let mut worker = nanoipc::Worker::::new(&service); - worker.add_reqrep(&socket_url).unwrap(); - - while !stop_guard.load(Ordering::SeqCst) { - worker.poll(); - } - }); -} - -pub fn payload() -> Result { - use std::io; - use std::io::Read; - - let mut buffer = Vec::new(); - io::stdin().read_to_end(&mut buffer).map_err(BootError::ReadArgs)?; - - ipc::binary::deserialize::(&buffer).map_err(BootError::DecodeArgs) -} - -pub fn register(hv_url: &str, control_url: &str, module_id: IpcModuleId) -> GuardedSocket>{ - let hypervisor_client = nanoipc::fast_client::>(hv_url).unwrap(); - hypervisor_client.handshake().unwrap(); - hypervisor_client.module_ready(module_id, control_url.to_owned()); - - hypervisor_client -} - -pub fn dependency>(url: &str) - -> Result, BootError> -{ - nanoipc::generic_client::(url).map_err(BootError::DependencyConnect) -} - -pub fn main_thread() -> Arc { - let stop = Arc::new(AtomicBool::new(false)); - let ctrc_stop = stop.clone(); - CtrlC::set_handler(move || { - ctrc_stop.store(true, Ordering::Relaxed); - }); - stop -} - -pub fn setup_cli_logger(svc_name: &str) { - let usage = format!(" -Ethcore {} service -Usage: - parity {} [options] - - Options: - -l --logging LOGGING Specify the logging level. Must conform to the same - format as RUST_LOG. - --log-file FILENAME Specify a filename into which logging should be - directed. - --no-color Don't use terminal color codes in output. -", svc_name, svc_name); - - #[derive(Debug, RustcDecodable)] - struct Args { - flag_logging: Option, - flag_log_file: Option, - flag_no_color: bool, - } - - impl Args { - pub fn log_settings(&self) -> LogConfig { - LogConfig { - color: self.flag_no_color || cfg!(windows), - mode: self.flag_logging.clone(), - file: self.flag_log_file.clone(), - } - } - } - - let args: Args = Docopt::new(usage) - .and_then(|d| d.decode()) - .unwrap_or_else(|e| e.exit()); - setup_log(&args.log_settings()).expect("Log initialization failure"); -} diff --git a/parity/helpers.rs b/parity/helpers.rs index da54f6763..1319f45d3 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -21,7 +21,7 @@ use std::fs::File; use bigint::prelude::U256; use bigint::hash::clean_0x; use util::Address; -use kvdb::CompactionProfile; +use kvdb_rocksdb::CompactionProfile; use util::journaldb::Algorithm; use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy}; diff --git a/parity/main.rs b/parity/main.rs index 97ffbca5f..5f6cd4292 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -52,9 +52,6 @@ extern crate toml; extern crate ethcore; extern crate ethcore_devtools as devtools; extern crate ethcore_io as io; -extern crate ethcore_ipc as ipc; -extern crate ethcore_ipc_hypervisor as hypervisor; -extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_light as light; extern crate ethcore_logger; extern crate ethcore_util as util; @@ -63,6 +60,7 @@ extern crate ethcore_bytes as bytes; extern crate ethcore_network as network; extern crate migration as migr; extern crate kvdb; +extern crate kvdb_rocksdb; extern crate ethkey; extern crate ethsync; extern crate node_health; @@ -125,11 +123,6 @@ mod url; mod user_defaults; mod whisper; -#[cfg(feature="ipc")] -mod boot; -#[cfg(feature="ipc")] -mod sync; - #[cfg(feature="stratum")] mod stratum; @@ -203,14 +196,8 @@ fn stratum_main(alt_mains: &mut HashMap) { alt_mains.insert("stratum".to_owned(), stratum::main); } -#[cfg(not(feature="ipc"))] fn sync_main(_: &mut HashMap) {} -#[cfg(feature="ipc")] -fn sync_main(alt_mains: &mut HashMap) { - alt_mains.insert("sync".to_owned(), sync::main); -} - fn updates_path(name: &str) -> PathBuf { let mut dest = PathBuf::from(default_hypervisor_path()); dest.push(name); diff --git a/parity/migration.rs b/parity/migration.rs index 508491a0a..9ccb7131a 100644 --- a/parity/migration.rs +++ b/parity/migration.rs @@ -21,8 +21,9 @@ use std::path::{Path, PathBuf}; use std::fmt::{Display, Formatter, Error as FmtError}; use std::sync::Arc; use util::journaldb::Algorithm; -use migr::{Manager as MigrationManager, Config as MigrationConfig, Error as MigrationError, Migration}; -use kvdb::{CompactionProfile, Database, DatabaseConfig}; +use migr::{self, Manager as MigrationManager, Config as MigrationConfig, Migration}; +use kvdb; +use kvdb_rocksdb::{CompactionProfile, Database, DatabaseConfig}; use ethcore::migrations; use ethcore::db; use ethcore::migrations::Extract; @@ -52,7 +53,7 @@ pub enum Error { /// Migration unexpectadly failed. MigrationFailed, /// Internal migration error. - Internal(MigrationError), + Internal(migr::Error), /// Migration was completed succesfully, /// but there was a problem with io. Io(IoError), @@ -80,11 +81,11 @@ impl From for Error { } } -impl From for Error { - fn from(err: MigrationError) -> Self { - match err { - MigrationError::Io(e) => Error::Io(e), - _ => Error::Internal(err), +impl From for Error { + fn from(err: migr::Error) -> Self { + match err.into() { + migr::ErrorKind::Io(e) => Error::Io(e), + err => Error::Internal(err.into()), } } } @@ -158,7 +159,7 @@ fn consolidate_database( column: Option, extract: Extract, compaction_profile: &CompactionProfile) -> Result<(), Error> { - fn db_error(e: String) -> Error { + fn db_error(e: kvdb::Error) -> Error { warn!("Cannot open Database for consolidation: {:?}", e); Error::MigrationFailed } @@ -283,7 +284,7 @@ mod legacy { use std::path::{Path, PathBuf}; use util::journaldb::Algorithm; use migr::{Manager as MigrationManager}; - use kvdb::CompactionProfile; + use kvdb_rocksdb::CompactionProfile; use ethcore::migrations; /// Blocks database path. diff --git a/parity/modules.rs b/parity/modules.rs index 8613c5ae5..f66f275aa 100644 --- a/parity/modules.rs +++ b/parity/modules.rs @@ -15,167 +15,19 @@ // along with Parity. If not, see . use std::sync::Arc; -use std::path::Path; use ethcore::client::BlockChainClient; -use hypervisor::Hypervisor; use ethsync::{AttachedProtocol, SyncConfig, NetworkConfiguration, NetworkError, Params, ConnectionFilter}; use ethcore::snapshot::SnapshotService; use light::Provider; -#[cfg(not(feature="ipc"))] -use self::no_ipc_deps::*; - -#[cfg(not(feature="ipc"))] +pub use ethsync::{EthSync, SyncProvider, ManageNetwork}; +pub use ethcore::client::ChainNotify; use ethcore_logger::Config as LogConfig; -#[cfg(feature="ipc")] -use self::ipc_deps::*; - -#[cfg(feature="ipc")] -pub mod service_urls { - use std::path::PathBuf; - - pub const CLIENT: &'static str = "parity-chain.ipc"; - pub const SNAPSHOT: &'static str = "parity-snapshot.ipc"; - pub const SYNC: &'static str = "parity-sync.ipc"; - pub const SYNC_NOTIFY: &'static str = "parity-sync-notify.ipc"; - pub const NETWORK_MANAGER: &'static str = "parity-manage-net.ipc"; - pub const SYNC_CONTROL: &'static str = "parity-sync-control.ipc"; - pub const LIGHT_PROVIDER: &'static str = "parity-light-provider.ipc"; - - #[cfg(feature="stratum")] - pub const STRATUM_CONTROL: &'static str = "parity-stratum-control.ipc"; - - pub fn with_base(data_dir: &str, service_path: &str) -> String { - let mut path = PathBuf::from(data_dir); - path.push(service_path); - - format!("ipc://{}", path.to_str().unwrap()) - } -} - -#[cfg(not(feature="ipc"))] -mod no_ipc_deps { - pub use ethsync::{EthSync, SyncProvider, ManageNetwork}; - pub use ethcore::client::ChainNotify; -} - -#[cfg(feature="ipc")] -pub type SyncModules = ( - GuardedSocket>, - GuardedSocket>, - GuardedSocket> -); - -#[cfg(not(feature="ipc"))] pub type SyncModules = (Arc, Arc, Arc); -#[cfg(feature="ipc")] -mod ipc_deps { - pub use ethsync::remote::{SyncClient, NetworkManagerClient}; - pub use ethsync::ServiceConfiguration; - pub use ethcore::client::remote::ChainNotifyClient; - pub use hypervisor::{SYNC_MODULE_ID, BootArgs, HYPERVISOR_IPC_URL}; - pub use nanoipc::{GuardedSocket, NanoSocket, generic_client, fast_client}; - pub use ipc::IpcSocket; - pub use ipc::binary::serialize; - pub use light::remote::LightProviderClient; -} - -#[cfg(feature="ipc")] -pub fn hypervisor(base_path: &Path) -> Option { - Some(Hypervisor - ::with_url(&service_urls::with_base(base_path.to_str().unwrap(), HYPERVISOR_IPC_URL)) - .io_path(base_path.to_str().unwrap())) -} - -#[cfg(not(feature="ipc"))] -pub fn hypervisor(_: &Path) -> Option { - None -} - -#[cfg(feature="ipc")] -fn sync_arguments(io_path: &str, sync_cfg: SyncConfig, net_cfg: NetworkConfiguration, log_settings: &LogConfig) -> BootArgs { - let service_config = ServiceConfiguration { - sync: sync_cfg, - net: net_cfg, - io_path: io_path.to_owned(), - }; - - // initialisation payload is passed via stdin - let service_payload = serialize(&service_config).expect("Any binary-derived struct is serializable by definition"); - - // client service url and logging settings are passed in command line - let mut cli_args = Vec::new(); - cli_args.push("sync".to_owned()); - if !log_settings.color { cli_args.push("--no-color".to_owned()); } - if let Some(ref mode) = log_settings.mode { - cli_args.push("-l".to_owned()); - cli_args.push(mode.to_owned()); - } - if let Some(ref file) = log_settings.file { - cli_args.push("--log-file".to_owned()); - cli_args.push(file.to_owned()); - } - - BootArgs::new().stdin(service_payload).cli(cli_args) -} - -#[cfg(feature="ipc")] -pub fn stratum( - hypervisor_ref: &mut Option, - config: &::ethcore::miner::StratumOptions -) { - use ethcore_stratum; - - let mut hypervisor = hypervisor_ref.take().expect("There should be hypervisor for ipc configuration"); - let args = BootArgs::new().stdin( - serialize(ðcore_stratum::ServiceConfiguration { - io_path: hypervisor.io_path.to_owned(), - port: config.port, - listen_addr: config.listen_addr.to_owned(), - secret: config.secret, - }).expect("Any binary-derived struct is serializable by definition") - ).cli(vec!["stratum".to_owned()]); - hypervisor = hypervisor.module(super::stratum::MODULE_ID, args); - *hypervisor_ref = Some(hypervisor); -} - -#[cfg(feature="ipc")] pub fn sync( - hypervisor_ref: &mut Option, - sync_cfg: SyncConfig, - net_cfg: NetworkConfiguration, - _client: Arc, - _snapshot_service: Arc, - _provider: Arc, - log_settings: &LogConfig, - _attached_protos: Vec, -) -> Result { - let mut hypervisor = hypervisor_ref.take().expect("There should be hypervisor for ipc configuration"); - let args = sync_arguments(&hypervisor.io_path, sync_cfg, net_cfg, log_settings); - hypervisor = hypervisor.module(SYNC_MODULE_ID, args); - - hypervisor.start(); - hypervisor.wait_for_startup(); - - let sync_client = generic_client::>( - &service_urls::with_base(&hypervisor.io_path, service_urls::SYNC)).unwrap(); - let notify_client = generic_client::>( - &service_urls::with_base(&hypervisor.io_path, service_urls::SYNC_NOTIFY)).unwrap(); - let manage_client = generic_client::>( - &service_urls::with_base(&hypervisor.io_path, service_urls::NETWORK_MANAGER)).unwrap(); - let provider_client = generic_client::>( - &service_urls::with_base(&hypervisor.io_path, service_urls::LIGHT_PROVIDER)).unwrap(); - - *hypervisor_ref = Some(hypervisor); - Ok((sync_client, manage_client, notify_client)) -} - -#[cfg(not(feature="ipc"))] -pub fn sync( - _hypervisor: &mut Option, sync_cfg: SyncConfig, net_cfg: NetworkConfiguration, client: Arc, diff --git a/parity/run.rs b/parity/run.rs index e11a176e4..87ab56679 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -579,9 +579,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // set network path. net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned()); - // create supervisor - let mut hypervisor = modules::hypervisor(&cmd.dirs.ipc_path()); - // create client service. let service = ClientService::start( client_config, @@ -661,7 +658,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // create sync object let (sync_provider, manage_network, chain_notify) = modules::sync( - &mut hypervisor, sync_config, net_conf.clone().into(), client.clone(), @@ -868,10 +864,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // just Arc is dropping here, to allow other reference release in its default time drop(informant); - // hypervisor should be shutdown first while everything still works and can be - // terminated gracefully - drop(hypervisor); - Ok(restart) } diff --git a/parity/sync.rs b/parity/sync.rs deleted file mode 100644 index 46bfdc72d..000000000 --- a/parity/sync.rs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Parity sync service - -use std::sync::Arc; -use std::sync::atomic::AtomicBool; -use hypervisor::{SYNC_MODULE_ID, HYPERVISOR_IPC_URL, ControlService}; -use ethcore::client::ChainNotify; -use ethcore::client::remote::RemoteClient; -use ethcore::snapshot::remote::RemoteSnapshotService; -use light::remote::LightProviderClient; -use ethsync::{SyncProvider, EthSync, ManageNetwork, ServiceConfiguration}; -use modules::service_urls; -use boot; -use nanoipc; - -#[derive(Default)] -struct SyncControlService { - pub stop: Arc, -} - -impl ControlService for SyncControlService { - fn shutdown(&self) -> bool { - trace!(target: "hypervisor", "Received shutdown from control service"); - self.stop.store(true, ::std::sync::atomic::Ordering::SeqCst); - true - } -} - -pub fn main() { - boot::setup_cli_logger("sync"); - - let service_config: ServiceConfiguration = boot::payload() - .unwrap_or_else(|e| panic!("Fatal: error reading boot arguments ({:?})", e)); - - let remote_client = dependency!(RemoteClient, &service_urls::with_base(&service_config.io_path, service_urls::CLIENT)); - let remote_snapshot = dependency!(RemoteSnapshotService, &service_urls::with_base(&service_config.io_path, service_urls::SNAPSHOT)); - let remote_provider = dependency!(LightProviderClient, &service_urls::with_base(&service_config.io_path, service_urls::LIGHT_PROVIDER)); - - let sync = EthSync::new(Params { - config: service_config.sync, - chain: remote_client.service().clone(), - snapshot_service: remote_snapshot.service().clone(), - provider: remote_provider.service().clone(), - network_config: service_config.net - attached_protos: Vec::new(), - }).unwrap(); - - let _ = boot::main_thread(); - let service_stop = Arc::new(AtomicBool::new(false)); - - let hypervisor = boot::register( - &service_urls::with_base(&service_config.io_path, HYPERVISOR_IPC_URL), - &service_urls::with_base(&service_config.io_path, service_urls::SYNC_CONTROL), - SYNC_MODULE_ID - ); - - boot::host_service( - &service_urls::with_base(&service_config.io_path, service_urls::SYNC), - service_stop.clone(), - sync.clone() as Arc - ); - boot::host_service( - &service_urls::with_base(&service_config.io_path, service_urls::NETWORK_MANAGER), - service_stop.clone(), - sync.clone() as Arc - ); - boot::host_service( - &service_urls::with_base(&service_config.io_path, service_urls::SYNC_NOTIFY), - service_stop.clone(), - sync.clone() as Arc - ); - - let control_service = Arc::new(SyncControlService::default()); - let as_control = control_service.clone() as Arc; - let mut worker = nanoipc::Worker::::new(&as_control); - let thread_stop = control_service.stop.clone(); - worker.add_reqrep( - &service_urls::with_base(&service_config.io_path, service_urls::SYNC_CONTROL) - ).unwrap(); - - while !thread_stop.load(::std::sync::atomic::Ordering::SeqCst) { - worker.poll(); - } - service_stop.store(true, ::std::sync::atomic::Ordering::SeqCst); - - hypervisor.module_shutdown(SYNC_MODULE_ID); - trace!(target: "hypervisor", "Sync process terminated gracefully"); -} diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index e4351b56f..7ad76a284 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -35,7 +35,6 @@ jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = " jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.8" } ethcore-io = { path = "../util/io" } -ethcore-ipc = { path = "../ipc/rpc" } ethcore-util = { path = "../util" } ethcore-bigint = { path = "../util/bigint" } ethcore-bytes = { path = "../util/bytes" } @@ -57,7 +56,6 @@ rlp = { path = "../util/rlp" } stats = { path = "../util/stats" } vm = { path = "../ethcore/vm" } hash = { path = "../util/hash" } -kvdb = { path = "../util/kvdb" } hardware-wallet = { path = "../hw" } clippy = { version = "0.0.103", optional = true} @@ -66,6 +64,7 @@ pretty_assertions = "0.1" [dev-dependencies] macros = { path = "../util/macros" } ethcore-network = { path = "../util/network" } +kvdb-memorydb = { path = "../util/kvdb-memorydb" } [features] dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev"] diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 2e6d6148f..9636f85cc 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -48,7 +48,6 @@ extern crate ethcore_bigint as bigint; extern crate ethcore_bytes as bytes; extern crate ethcore_devtools as devtools; extern crate ethcore_io as io; -extern crate ethcore_ipc; extern crate ethcore_light as light; extern crate ethcore_util as util; extern crate ethcrypto as crypto; @@ -65,7 +64,6 @@ extern crate rlp; extern crate stats; extern crate hash; extern crate hardware_wallet; -extern crate kvdb; #[macro_use] extern crate log; @@ -85,6 +83,9 @@ extern crate pretty_assertions; #[macro_use] extern crate macros; +#[cfg(test)] +extern crate kvdb_memorydb; + pub extern crate jsonrpc_ws_server as ws; mod authcodes; diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index a2b23f52e..c7f1f2dab 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -33,7 +33,7 @@ use io::IoChannel; use bigint::prelude::U256; use bigint::hash::H256; use util::Address; -use kvdb::in_memory; +use kvdb_memorydb; use jsonrpc_core::IoHandler; use v1::impls::{EthClient, SigningUnsafeClient}; @@ -131,7 +131,7 @@ impl EthTester { let client = Client::new( ClientConfig::default(), &spec, - Arc::new(in_memory(::ethcore::db::NUM_COLUMNS.unwrap_or(0))), + Arc::new(kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0))), miner_service.clone(), IoChannel::disconnected(), ).unwrap(); diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 96329d18c..337ef9513 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -471,7 +471,7 @@ fn rpc_eth_transaction_count() { #[test] fn rpc_eth_transaction_count_next_nonce() { - let tester = EthTester::new_with_options(EthClientOptions::with(|mut options| { + let tester = EthTester::new_with_options(EthClientOptions::with(|options| { options.pending_nonce_from_queue = true; })); tester.miner.increment_last_nonce(1.into()); @@ -1104,7 +1104,7 @@ fn rpc_get_work_returns_correct_work_package() { #[test] fn rpc_get_work_should_not_return_block_number() { - let eth_tester = EthTester::new_with_options(EthClientOptions::with(|mut options| { + let eth_tester = EthTester::new_with_options(EthClientOptions::with(|options| { options.send_block_number_in_get_work = false; })); eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()); diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index e09d95932..a984c64ba 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -164,7 +164,7 @@ pub enum Diff where T: Serialize { Changed(ChangedType), } -impl From> for Diff where T: Eq + ::ethcore_ipc::BinaryConvertable, U: Serialize + From { +impl From> for Diff where T: Eq, U: Serialize + From { fn from(c: account_diff::Diff) -> Self { match c { account_diff::Diff::Same => Diff::Same, @@ -374,7 +374,7 @@ pub enum Action { /// Suicide Suicide(Suicide), /// Reward - Reward(Reward), + Reward(Reward), } impl From for Action { diff --git a/rpc_cli/Cargo.toml b/rpc_cli/Cargo.toml index 5e407cb74..652e9be13 100644 --- a/rpc_cli/Cargo.toml +++ b/rpc_cli/Cargo.toml @@ -8,7 +8,7 @@ version = "1.4.0" [dependencies] futures = "0.1" -rpassword = "0.3.0" +rpassword = "1.0" bigint = "4.0" parity-rpc = { path = "../rpc" } parity-rpc-client = { path = "../rpc_client" } diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index 3e98c62e7..8357b530b 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -4,10 +4,6 @@ name = "ethcore-secretstore" version = "1.0.0" license = "GPL-3.0" authors = ["Parity Technologies "] -build = "build.rs" - -[build-dependencies] -ethcore-ipc-codegen = { path = "../ipc/codegen" } [dependencies] byteorder = "1.0" @@ -26,16 +22,14 @@ tokio-io = "0.1.0" tokio-service = "0.1" tokio-proto = "0.1" url = "1.0" -ethabi = "2.0" ethcore = { path = "../ethcore" } ethcore-bytes = { path = "../util/bytes" } ethcore-devtools = { path = "../devtools" } ethcore-util = { path = "../util" } ethcore-bigint = { path = "../util/bigint" } kvdb = { path = "../util/kvdb" } +kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } hash = { path = "../util/hash" } -ethcore-ipc = { path = "../ipc/rpc" } -ethcore-ipc-nano = { path = "../ipc/nano" } ethcore-logger = { path = "../logger" } ethcrypto = { path = "../ethcrypto" } ethkey = { path = "../ethkey" } diff --git a/secret_store/build.rs b/secret_store/build.rs deleted file mode 100644 index b2b27ea1e..000000000 --- a/secret_store/build.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen; - -fn main() { - ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap(); - ethcore_ipc_codegen::derive_ipc_cond("src/traits.rs", cfg!(feature="ipc")).unwrap(); -} diff --git a/secret_store/src/key_server_cluster/admin_sessions/share_move_session.rs b/secret_store/src/key_server_cluster/admin_sessions/share_move_session.rs index a19a9eee0..d193e9efd 100644 --- a/secret_store/src/key_server_cluster/admin_sessions/share_move_session.rs +++ b/secret_store/src/key_server_cluster/admin_sessions/share_move_session.rs @@ -419,7 +419,7 @@ impl SessionImpl where T: SessionTransport { // find share source { - let mut move_confirmations_to_receive = data.move_confirmations_to_receive.as_mut() + let move_confirmations_to_receive = data.move_confirmations_to_receive.as_mut() .expect("move_confirmations_to_receive are filled during consensus establishing; move confirmations are processed after this; qed"); if !move_confirmations_to_receive.remove(sender) { return Err(Error::InvalidMessage); diff --git a/secret_store/src/key_storage.rs b/secret_store/src/key_storage.rs index ca408dfc1..d45ff20c7 100644 --- a/secret_store/src/key_storage.rs +++ b/secret_store/src/key_storage.rs @@ -18,7 +18,7 @@ use std::path::PathBuf; use std::collections::BTreeMap; use serde_json; use ethkey::{Secret, Public}; -use kvdb::{Database, DatabaseIterator}; +use kvdb_rocksdb::{Database, DatabaseIterator}; use types::all::{Error, ServiceConfiguration, ServerKeyId, NodeId}; use serialization::{SerializablePublic, SerializableSecret}; @@ -132,7 +132,7 @@ impl PersistentKeyStorage { db_path.push("db"); let db_path = db_path.to_str().ok_or(Error::Database("Invalid secretstore path".to_owned()))?; - let db = Database::open_default(&db_path).map_err(Error::Database)?; + let db = Database::open_default(&db_path)?; let db = upgrade_db(db)?; Ok(PersistentKeyStorage { @@ -142,7 +142,7 @@ impl PersistentKeyStorage { } fn upgrade_db(db: Database) -> Result { - let version = db.get(None, DB_META_KEY_VERSION).map_err(Error::Database)?; + let version = db.get(None, DB_META_KEY_VERSION)?; let version = version.and_then(|v| v.get(0).cloned()).unwrap_or(0); match version { 0 => { @@ -164,7 +164,7 @@ fn upgrade_db(db: Database) -> Result { let db_value = serde_json::to_vec(&v2_key).map_err(|e| Error::Database(e.to_string()))?; batch.put(None, &*db_key, &*db_value); } - db.write(batch).map_err(Error::Database)?; + db.write(batch)?; Ok(db) }, 1 => { @@ -184,7 +184,7 @@ fn upgrade_db(db: Database) -> Result { let db_value = serde_json::to_vec(&v2_key).map_err(|e| Error::Database(e.to_string()))?; batch.put(None, &*db_key, &*db_value); } - db.write(batch).map_err(Error::Database)?; + db.write(batch)?; Ok(db) } 2 => Ok(db), @@ -198,7 +198,7 @@ impl KeyStorage for PersistentKeyStorage { let key = serde_json::to_vec(&key).map_err(|e| Error::Database(e.to_string()))?; let mut batch = self.db.transaction(); batch.put(None, &document, &key); - self.db.write(batch).map_err(Error::Database) + self.db.write(batch).map_err(Into::into) } fn update(&self, document: ServerKeyId, key: DocumentKeyShare) -> Result<(), Error> { @@ -206,8 +206,7 @@ impl KeyStorage for PersistentKeyStorage { } fn get(&self, document: &ServerKeyId) -> Result { - self.db.get(None, document) - .map_err(Error::Database)? + self.db.get(None, document)? .ok_or(Error::DocumentNotFound) .map(|key| key.into_vec()) .and_then(|key| serde_json::from_slice::(&key).map_err(|e| Error::Database(e.to_string()))) @@ -217,7 +216,7 @@ impl KeyStorage for PersistentKeyStorage { fn remove(&self, document: &ServerKeyId) -> Result<(), Error> { let mut batch = self.db.transaction(); batch.delete(None, &document); - self.db.write(batch).map_err(Error::Database) + self.db.write(batch).map_err(Into::into) } fn contains(&self, document: &ServerKeyId) -> bool { @@ -293,7 +292,7 @@ pub mod tests { use serde_json; use devtools::RandomTempPath; use ethkey::{Random, Generator, Public, Secret}; - use kvdb::Database; + use kvdb_rocksdb::Database; use types::all::{Error, NodeAddress, ServiceConfiguration, ClusterConfiguration, ServerKeyId}; use super::{DB_META_KEY_VERSION, CURRENT_VERSION, KeyStorage, PersistentKeyStorage, DocumentKeyShare, SerializableDocumentKeyShareV0, SerializableDocumentKeyShareV1, diff --git a/secret_store/src/lib.rs b/secret_store/src/lib.rs index 6aa3bd708..5951be508 100644 --- a/secret_store/src/lib.rs +++ b/secret_store/src/lib.rs @@ -36,28 +36,23 @@ extern crate tokio_service; extern crate tokio_proto; extern crate url; -extern crate ethabi; extern crate ethcore; extern crate ethcore_devtools as devtools; extern crate ethcore_bytes as bytes; extern crate ethcore_util as util; extern crate ethcore_bigint as bigint; -extern crate ethcore_ipc as ipc; extern crate ethcore_logger as logger; extern crate ethcrypto; extern crate ethkey; extern crate native_contracts; extern crate hash; extern crate kvdb; +extern crate kvdb_rocksdb; mod key_server_cluster; mod types; -mod traits { - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/traits.rs")); -} - +mod traits; mod acl_storage; mod http_listener; mod key_server; diff --git a/secret_store/src/traits.rs b/secret_store/src/traits.rs index 1e00f1e05..7ee4c5cc1 100644 --- a/secret_store/src/traits.rs +++ b/secret_store/src/traits.rs @@ -83,6 +83,5 @@ pub trait MessageSigner: ServerKeyGenerator { /// Key server. -#[ipc(client_ident="RemoteKeyServer")] pub trait KeyServer: DocumentKeyServer + MessageSigner + Send + Sync { } diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index ca1f9eb35..7c746f2a0 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -18,10 +18,7 @@ use std::fmt; use std::collections::BTreeMap; use serde_json; -use ethkey; -use bytes; -use bigint; -use key_server_cluster; +use {ethkey, kvdb, bytes, bigint, key_server_cluster}; /// Node id. pub type NodeId = ethkey::Public; @@ -39,8 +36,7 @@ pub type RequestSignature = ethkey::Signature; pub use ethkey::Public; /// Secret store error -#[derive(Debug, Clone, PartialEq)] -#[binary] +#[derive(Debug, PartialEq)] pub enum Error { /// Bad signature is passed BadSignature, @@ -58,7 +54,6 @@ pub enum Error { /// Secret store configuration #[derive(Debug, Clone)] -#[binary] pub struct NodeAddress { /// IP address. pub address: String, @@ -68,7 +63,6 @@ pub struct NodeAddress { /// Secret store configuration #[derive(Debug)] -#[binary] pub struct ServiceConfiguration { /// HTTP listener address. If None, HTTP API is disabled. pub listener_address: Option, @@ -82,7 +76,6 @@ pub struct ServiceConfiguration { /// Key server cluster configuration #[derive(Debug)] -#[binary] pub struct ClusterConfiguration { /// Number of threads reserved by cluster. pub threads: usize, @@ -99,7 +92,6 @@ pub struct ClusterConfiguration { /// Shadow decryption result. #[derive(Clone, Debug, PartialEq)] -#[binary] pub struct EncryptedDocumentKeyShadow { /// Decrypted secret point. It is partially decrypted if shadow decrpytion was requested. pub decrypted_secret: ethkey::Public, @@ -134,6 +126,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: kvdb::Error) -> Self { + Error::Database(err.to_string()) + } +} + impl From for Error { fn from(err: key_server_cluster::Error) -> Self { match err { diff --git a/secret_store/src/types/mod.rs b/secret_store/src/types/mod.rs index 584e78f30..dc5bd3d8a 100644 --- a/secret_store/src/types/mod.rs +++ b/secret_store/src/types/mod.rs @@ -16,5 +16,4 @@ //! Types used in the public api -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues -include!(concat!(env!("OUT_DIR"), "/mod.rs.in")); +pub mod all; diff --git a/secret_store/src/types/mod.rs.in b/secret_store/src/types/mod.rs.in deleted file mode 100644 index 0681e2884..000000000 --- a/secret_store/src/types/mod.rs.in +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -pub mod all; diff --git a/stratum/Cargo.toml b/stratum/Cargo.toml index 8e60854e2..911e2ad0e 100644 --- a/stratum/Cargo.toml +++ b/stratum/Cargo.toml @@ -4,10 +4,6 @@ name = "ethcore-stratum" version = "1.9.0" license = "GPL-3.0" authors = ["Parity Technologies "] -build = "build.rs" - -[build-dependencies] -ethcore-ipc-codegen = { path = "../ipc/codegen" } [dependencies] log = "0.3" @@ -18,8 +14,6 @@ ethcore-util = { path = "../util" } ethcore-bigint = { path = "../util/bigint" } ethcore-devtools = { path = "../devtools" } env_logger = "0.4" -ethcore-ipc = { path = "../ipc/rpc" } -ethcore-ipc-nano = { path = "../ipc/nano" } tokio-core = "0.1" tokio-io = "0.1" parking_lot = "0.4" diff --git a/stratum/build.rs b/stratum/build.rs deleted file mode 100644 index bad927dc1..000000000 --- a/stratum/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen; - -fn main() { - ethcore_ipc_codegen::derive_ipc("src/traits.rs").unwrap(); -} diff --git a/stratum/src/lib.rs b/stratum/src/lib.rs index 527c43f20..229f36acc 100644 --- a/stratum/src/lib.rs +++ b/stratum/src/lib.rs @@ -22,7 +22,6 @@ extern crate jsonrpc_macros; #[macro_use] extern crate log; extern crate ethcore_util as util; extern crate ethcore_bigint as bigint; -extern crate ethcore_ipc as ipc; extern crate hash; extern crate parking_lot; @@ -31,15 +30,10 @@ extern crate parking_lot; #[cfg(test)] extern crate ethcore_logger; #[cfg(test)] extern crate env_logger; -mod traits { - //! Stratum ipc interfaces specification - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/traits.rs")); -} +mod traits; pub use traits::{ JobDispatcher, PushWorkHandler, Error, ServiceConfiguration, - RemoteWorkHandler, RemoteJobDispatcher, }; use jsonrpc_tcp_server::{ diff --git a/stratum/src/traits.rs b/stratum/src/traits.rs index d37000076..8bb497091 100644 --- a/stratum/src/traits.rs +++ b/stratum/src/traits.rs @@ -17,11 +17,9 @@ use std; use std::error::Error as StdError; use bigint::hash::H256; -use ipc::IpcConfig; use jsonrpc_tcp_server::PushMessageError; #[derive(Debug, Clone)] -#[binary] pub enum Error { NoWork, NoWorkers, @@ -43,7 +41,6 @@ impl From for Error { } /// Interface that can provide pow/blockchain-specific responses for the clients -#[ipc(client_ident="RemoteJobDispatcher")] pub trait JobDispatcher: Send + Sync { // json for initial client handshake fn initial(&self) -> Option { None } @@ -56,7 +53,6 @@ pub trait JobDispatcher: Send + Sync { } /// Interface that can handle requests to push job for workers -#[ipc(client_ident="RemoteWorkHandler")] pub trait PushWorkHandler: Send + Sync { /// push the same work package for all workers (`payload`: json of pow-specific set of work specification) fn push_work_all(&self, payload: String) -> Result<(), Error>; @@ -65,13 +61,9 @@ pub trait PushWorkHandler: Send + Sync { fn push_work(&self, payloads: Vec) -> Result<(), Error>; } -#[binary] pub struct ServiceConfiguration { pub io_path: String, pub listen_addr: String, pub port: u16, pub secret: Option, } - -impl IpcConfig for PushWorkHandler { } -impl IpcConfig for JobDispatcher { } diff --git a/sync/Cargo.toml b/sync/Cargo.toml index fa8531b6c..a1941fec4 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -4,13 +4,9 @@ name = "ethsync" version = "1.9.0" license = "GPL-3.0" authors = ["Parity Technologies "] -build = "build.rs" [lib] -[build-dependencies] -ethcore-ipc-codegen = { path = "../ipc/codegen" } - [dependencies] ethcore-util = { path = "../util" } ethcore-bytes = { path = "../util/bytes" } @@ -30,16 +26,16 @@ env_logger = "0.4" time = "0.1.34" rand = "0.3.13" heapsize = "0.4" -ethcore-ipc = { path = "../ipc/rpc" } semver = "0.6" smallvec = { version = "0.4", features = ["heapsizeof"] } -ethcore-ipc-nano = { path = "../ipc/nano" } -ethcore-devtools = { path = "../devtools" } -ethkey = { path = "../ethkey" } parking_lot = "0.4" ipnetwork = "0.12.6" +[dev-dependencies] +ethkey = { path = "../ethkey" } +kvdb-memorydb = { path = "../util/kvdb-memorydb" } +ethcore-devtools = { path = "../devtools" } + [features] default = [] dev = ["clippy", "ethcore/dev", "ethcore-util/dev"] -ipc = ["ethcore-light/ipc"] diff --git a/sync/build.rs b/sync/build.rs deleted file mode 100644 index 7590a1594..000000000 --- a/sync/build.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen; - -#[cfg(feature = "ipc")] -fn main() { - ethcore_ipc_codegen::derive_ipc_cond("src/api.rs", true).unwrap(); -} - -#[cfg(not(feature = "ipc"))] -fn main() {} diff --git a/sync/src/api.rs b/sync/src/api.rs index 642b4472c..48c48880d 100644 --- a/sync/src/api.rs +++ b/sync/src/api.rs @@ -30,7 +30,6 @@ use ethcore::header::BlockNumber; use sync_io::NetSyncIo; use chain::{ChainSync, SyncStatus as EthSyncStatus}; use std::net::{SocketAddr, AddrParseError}; -use ipc::{BinaryConvertable, BinaryConvertError, IpcConfig}; use std::str::FromStr; use parking_lot::RwLock; use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT}; @@ -82,9 +81,6 @@ impl Default for SyncConfig { } } -binary_fixed_size!(SyncConfig); -binary_fixed_size!(EthSyncStatus); - /// Current sync status pub trait SyncProvider: Send + Sync { /// Get sync status @@ -102,7 +98,6 @@ pub trait SyncProvider: Send + Sync { /// Transaction stats #[derive(Debug)] -#[cfg_attr(feature = "ipc", derive(Binary))] pub struct TransactionStats { /// Block number where this TX was first seen. pub first_seen: u64, @@ -112,7 +107,6 @@ pub struct TransactionStats { /// Peer connection information #[derive(Debug)] -#[cfg_attr(feature = "ipc", derive(Binary))] pub struct PeerInfo { /// Public node id pub id: Option, @@ -132,7 +126,6 @@ pub struct PeerInfo { /// Ethereum protocol info. #[derive(Debug)] -#[cfg_attr(feature = "ipc", derive(Binary))] pub struct EthProtocolInfo { /// Protocol version pub version: u32, @@ -144,7 +137,6 @@ pub struct EthProtocolInfo { /// PIP protocol info. #[derive(Debug)] -#[cfg_attr(feature = "ipc", derive(Binary))] pub struct PipProtocolInfo { /// Protocol version pub version: u32, @@ -166,7 +158,6 @@ impl From for PipProtocolInfo { /// Configuration to attach alternate protocol handlers. /// Only works when IPC is disabled. -#[cfg(not(feature = "ipc"))] pub struct AttachedProtocol { /// The protocol handler in question. pub handler: Arc, @@ -178,32 +169,11 @@ pub struct AttachedProtocol { pub versions: &'static [u8], } -/// Attached protocol: disabled in IPC mode. -#[cfg(feature = "ipc")] -#[cfg_attr(feature = "ipc", derive(Binary))] -pub struct AttachedProtocol; - impl AttachedProtocol { - #[cfg(feature = "ipc")] - fn register(&self, network: &NetworkService) { - let res = network.register_protocol( - self.handler.clone(), - self.protocol_id, - self.packet_count, - self.versions - ); - - if let Err(e) = res { - warn!(target: "sync","Error attaching protocol {:?}", protocol_id); - } - } - - #[cfg(not(feature = "ipc"))] fn register(&self, _network: &NetworkService) {} } /// EthSync initialization parameters. -#[cfg_attr(feature = "ipc", derive(Binary))] pub struct Params { /// Configuration. pub config: SyncConfig, @@ -293,7 +263,6 @@ impl EthSync { } } -#[cfg_attr(feature = "ipc", ipc(client_ident="SyncClient"))] impl SyncProvider for EthSync { /// Get sync status fn status(&self) -> EthSyncStatus { @@ -478,9 +447,6 @@ impl LightHandler for TxRelay { } } -impl IpcConfig for ManageNetwork { } -impl IpcConfig for SyncProvider { } - /// Trait for managing network pub trait ManageNetwork : Send + Sync { /// Set to allow unreserved peers to connect @@ -502,7 +468,6 @@ pub trait ManageNetwork : Send + Sync { } -#[cfg_attr(feature = "ipc", ipc(client_ident="NetworkManagerClient"))] impl ManageNetwork for EthSync { fn accept_unreserved_peers(&self) { self.network.set_non_reserved_mode(NonReservedPeerMode::Accept); @@ -547,7 +512,6 @@ impl ManageNetwork for EthSync { } #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "ipc", binary)] /// Network service configuration pub struct NetworkConfiguration { /// Directory path to store general network configuration. None means nothing will be saved @@ -643,7 +607,6 @@ impl From for NetworkConfiguration { /// Configuration for IPC service. #[derive(Debug, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct ServiceConfiguration { /// Sync config. pub sync: SyncConfig, @@ -655,7 +618,6 @@ pub struct ServiceConfiguration { /// Numbers of peers (max, min, active). #[derive(Debug, Clone)] -#[cfg_attr(feature = "ipc", binary)] pub struct PeerNumbers { /// Number of connected peers. pub connected: usize, diff --git a/sync/src/lib.rs b/sync/src/lib.rs index 33b1d021f..091ce5ba9 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -48,6 +48,7 @@ extern crate ethcore_light as light; #[cfg(test)] extern crate ethcore_devtools as devtools; #[cfg(test)] extern crate ethkey; +#[cfg(test)] extern crate kvdb_memorydb; #[macro_use] extern crate macros; @@ -55,8 +56,6 @@ extern crate macros; extern crate log; #[macro_use] extern crate heapsize; -#[macro_use] -extern crate ethcore_ipc as ipc; mod chain; mod blocks; @@ -70,13 +69,6 @@ pub mod light_sync; #[cfg(test)] mod tests; -#[cfg(feature = "ipc")] -mod api { - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/api.rs")); -} - -#[cfg(not(feature = "ipc"))] mod api; pub use api::*; @@ -85,9 +77,3 @@ pub use network::{is_valid_node_url, NonReservedPeerMode, NetworkError, Connecti #[cfg(test)] pub(crate) type Address = bigint::hash::H160; - -/// IPC interfaces -#[cfg(feature="ipc")] -pub mod remote { - pub use api::{SyncClient, NetworkManagerClient}; -} diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index 1fe4fde46..b37ab89ba 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -291,7 +291,7 @@ impl TestNet> { let client = EthcoreClient::new( ClientConfig::default(), &spec, - Arc::new(::kvdb::in_memory(::ethcore::db::NUM_COLUMNS.unwrap_or(0))), + Arc::new(::kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0))), Arc::new(Miner::with_spec_and_accounts(&spec, accounts)), IoChannel::disconnected(), ).unwrap(); diff --git a/updater/Cargo.toml b/updater/Cargo.toml index 9897bf7d0..a67559f68 100644 --- a/updater/Cargo.toml +++ b/updater/Cargo.toml @@ -4,15 +4,12 @@ name = "parity-updater" version = "1.9.0" license = "GPL-3.0" authors = ["Parity Technologies "] -build = "build.rs" - -[build-dependencies] -ethcore-ipc-codegen = { path = "../ipc/codegen" } [dependencies] log = "0.3" -ethabi = "2.0" +ethabi = "4.0" target_info = "0.1" +semver = "0.6" ethcore = { path = "../ethcore" } ethsync = { path = "../sync" } ethcore-util = { path = "../util" } @@ -21,7 +18,5 @@ ethcore-bytes = { path = "../util/bytes" } futures = "0.1" parking_lot = "0.4" parity-hash-fetch = { path = "../hash-fetch" } -ipc-common-types = { path = "../ipc-common-types" } -ethcore-ipc = { path = "../ipc/rpc" } parity-reactor = { path = "../util/reactor" } path = { path = "../util/path" } diff --git a/updater/build.rs b/updater/build.rs deleted file mode 100644 index b962f1e60..000000000 --- a/updater/build.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate ethcore_ipc_codegen; - -fn main() { - ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap(); - ethcore_ipc_codegen::derive_ipc_cond("src/service.rs", cfg!(feature="ipc")).unwrap(); -} diff --git a/updater/src/lib.rs b/updater/src/lib.rs index 9ba948d9f..c0da3b6a1 100644 --- a/updater/src/lib.rs +++ b/updater/src/lib.rs @@ -20,27 +20,23 @@ extern crate ethcore_util as util; extern crate ethcore_bigint as bigint; extern crate ethcore_bytes as bytes; -extern crate ipc_common_types; extern crate parking_lot; extern crate parity_hash_fetch as hash_fetch; extern crate ethcore; extern crate ethabi; extern crate ethsync; -extern crate ethcore_ipc as ipc; extern crate futures; extern crate target_info; extern crate parity_reactor; extern crate path; +extern crate semver; mod updater; mod operations; mod types; -mod service { - #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues - include!(concat!(env!("OUT_DIR"), "/service.rs")); -} +mod service; pub use service::{Service}; -pub use types::all::{ReleaseInfo, OperationsInfo, CapState, VersionInfo, ReleaseTrack}; +pub use types::{ReleaseInfo, OperationsInfo, CapState, VersionInfo, ReleaseTrack}; pub use updater::{Updater, UpdateFilter, UpdatePolicy}; diff --git a/updater/src/operations.rs b/updater/src/operations.rs index 4ec53331c..b9bb01bd7 100644 --- a/updater/src/operations.rs +++ b/updater/src/operations.rs @@ -15,7 +15,7 @@ pub struct Operations { impl Operations { pub fn new(address: util::Address, do_call: F) -> Self where F: Fn(util::Address, Vec) -> Result, String> + Send + Sync + 'static { Operations { - contract: ethabi::Contract::new(ethabi::Interface::load(b"[{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"resetClientOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"isLatest\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"}],\"name\":\"rejectTransaction\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_number\",\"type\":\"uint32\"},{\"name\":\"_name\",\"type\":\"bytes32\"},{\"name\":\"_hard\",\"type\":\"bool\"},{\"name\":\"_spec\",\"type\":\"bytes32\"}],\"name\":\"proposeFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"}],\"name\":\"removeClient\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"release\",\"outputs\":[{\"name\":\"o_forkBlock\",\"type\":\"uint32\"},{\"name\":\"o_track\",\"type\":\"uint8\"},{\"name\":\"o_semver\",\"type\":\"uint24\"},{\"name\":\"o_critical\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_checksum\",\"type\":\"bytes32\"}],\"name\":\"build\",\"outputs\":[{\"name\":\"o_release\",\"type\":\"bytes32\"},{\"name\":\"o_platform\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"rejectFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"client\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"required\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"setClientOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"fork\",\"outputs\":[{\"name\":\"name\",\"type\":\"bytes32\"},{\"name\":\"spec\",\"type\":\"bytes32\"},{\"name\":\"hard\",\"type\":\"bool\"},{\"name\":\"ratified\",\"type\":\"bool\"},{\"name\":\"requiredCount\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_platform\",\"type\":\"bytes32\"},{\"name\":\"_checksum\",\"type\":\"bytes32\"}],\"name\":\"addChecksum\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"}],\"name\":\"confirmTransaction\",\"outputs\":[{\"name\":\"txSuccess\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"proxy\",\"outputs\":[{\"name\":\"requiredCount\",\"type\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\"},{\"name\":\"gas\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"addClient\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"clientOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"proposeTransaction\",\"outputs\":[{\"name\":\"txSuccess\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"grandOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_forkBlock\",\"type\":\"uint32\"},{\"name\":\"_track\",\"type\":\"uint8\"},{\"name\":\"_semver\",\"type\":\"uint24\"},{\"name\":\"_critical\",\"type\":\"bool\"}],\"name\":\"addRelease\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"acceptFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"clientsRequired\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"track\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_r\",\"type\":\"bool\"}],\"name\":\"setClientRequired\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"latestFork\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_track\",\"type\":\"uint8\"}],\"name\":\"latestInTrack\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_platform\",\"type\":\"bytes32\"}],\"name\":\"checksum\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"proposedFork\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"}]").expect("JSON is autogenerated; qed")), + contract: ethabi::Contract::load(b"[{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"resetClientOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"isLatest\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"}],\"name\":\"rejectTransaction\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_number\",\"type\":\"uint32\"},{\"name\":\"_name\",\"type\":\"bytes32\"},{\"name\":\"_hard\",\"type\":\"bool\"},{\"name\":\"_spec\",\"type\":\"bytes32\"}],\"name\":\"proposeFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"}],\"name\":\"removeClient\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"release\",\"outputs\":[{\"name\":\"o_forkBlock\",\"type\":\"uint32\"},{\"name\":\"o_track\",\"type\":\"uint8\"},{\"name\":\"o_semver\",\"type\":\"uint24\"},{\"name\":\"o_critical\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_checksum\",\"type\":\"bytes32\"}],\"name\":\"build\",\"outputs\":[{\"name\":\"o_release\",\"type\":\"bytes32\"},{\"name\":\"o_platform\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"rejectFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"client\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"required\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"setClientOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"fork\",\"outputs\":[{\"name\":\"name\",\"type\":\"bytes32\"},{\"name\":\"spec\",\"type\":\"bytes32\"},{\"name\":\"hard\",\"type\":\"bool\"},{\"name\":\"ratified\",\"type\":\"bool\"},{\"name\":\"requiredCount\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_platform\",\"type\":\"bytes32\"},{\"name\":\"_checksum\",\"type\":\"bytes32\"}],\"name\":\"addChecksum\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"}],\"name\":\"confirmTransaction\",\"outputs\":[{\"name\":\"txSuccess\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"proxy\",\"outputs\":[{\"name\":\"requiredCount\",\"type\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\"},{\"name\":\"gas\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"addClient\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"clientOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"proposeTransaction\",\"outputs\":[{\"name\":\"txSuccess\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"grandOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_forkBlock\",\"type\":\"uint32\"},{\"name\":\"_track\",\"type\":\"uint8\"},{\"name\":\"_semver\",\"type\":\"uint24\"},{\"name\":\"_critical\",\"type\":\"bool\"}],\"name\":\"addRelease\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"acceptFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"clientsRequired\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"track\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_r\",\"type\":\"bool\"}],\"name\":\"setClientRequired\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"latestFork\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_track\",\"type\":\"uint8\"}],\"name\":\"latestInTrack\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_platform\",\"type\":\"bytes32\"}],\"name\":\"checksum\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"proposedFork\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"}]" as &[u8]).expect("JSON is autogenerated; qed"), address: address, do_call: Box::new(do_call), } @@ -26,10 +26,10 @@ impl Operations { #[allow(dead_code)] pub fn reset_client_owner(&self, _client: &str, _new_owner: &util::Address) -> Result<(), String> { let call = self.contract.function("resetClientOwner".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Address(_new_owner.clone().0)] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -38,10 +38,10 @@ impl Operations { #[allow(dead_code)] pub fn is_latest(&self, _client: &str, _release: &bigint::hash::H256) -> Result { let call = self.contract.function("isLatest".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r })) } @@ -50,10 +50,10 @@ impl Operations { #[allow(dead_code)] pub fn reject_transaction(&self, _txid: &bigint::hash::H256) -> Result<(), String> { let call = self.contract.function("rejectTransaction".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_txid.as_ref().to_owned())] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -62,10 +62,10 @@ impl Operations { #[allow(dead_code)] pub fn set_owner(&self, _new_owner: &util::Address) -> Result<(), String> { let call = self.contract.function("setOwner".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::Address(_new_owner.clone().0)] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -74,10 +74,10 @@ impl Operations { #[allow(dead_code)] pub fn propose_fork(&self, _number: u32, _name: &bigint::hash::H256, _hard: bool, _spec: &bigint::hash::H256) -> Result<(), String> { let call = self.contract.function("proposeFork".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_number as u64).to_big_endian(&mut r); r }), ethabi::Token::FixedBytes(_name.as_ref().to_owned()), ethabi::Token::Bool(_hard), ethabi::Token::FixedBytes(_spec.as_ref().to_owned())] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -86,10 +86,10 @@ impl Operations { #[allow(dead_code)] pub fn remove_client(&self, _client: &str) -> Result<(), String> { let call = self.contract.function("removeClient".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned())] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -98,10 +98,10 @@ impl Operations { #[allow(dead_code)] pub fn release(&self, _client: &str, _release: &bigint::hash::H256) -> Result<(u32, u8, u32, bool), String> { let call = self.contract.function("release".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u8 }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r })) } @@ -110,10 +110,10 @@ impl Operations { #[allow(dead_code)] pub fn build(&self, _client: &str, _checksum: &bigint::hash::H256) -> Result<(bigint::hash::H256, bigint::hash::H256), String> { let call = self.contract.function("build".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_checksum.as_ref().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) } @@ -122,10 +122,10 @@ impl Operations { #[allow(dead_code)] pub fn reject_fork(&self) -> Result<(), String> { let call = self.contract.function("rejectFork".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -134,10 +134,10 @@ impl Operations { #[allow(dead_code)] pub fn client(&self, _1: &bigint::hash::H256) -> Result<(util::Address, bool), String> { let call = self.contract.function("client".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_1.as_ref().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_address().ok_or("Invalid type returned")?; util::Address::from(r) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r })) } @@ -146,10 +146,10 @@ impl Operations { #[allow(dead_code)] pub fn set_client_owner(&self, _new_owner: &util::Address) -> Result<(), String> { let call = self.contract.function("setClientOwner".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::Address(_new_owner.clone().0)] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -158,10 +158,10 @@ impl Operations { #[allow(dead_code)] pub fn fork(&self, _1: u32) -> Result<(bigint::hash::H256, bigint::hash::H256, bool, bool, bigint::prelude::U256), String> { let call = self.contract.function("fork".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_1 as u64).to_big_endian(&mut r); r })] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) } @@ -170,10 +170,10 @@ impl Operations { #[allow(dead_code)] pub fn add_checksum(&self, _release: &bigint::hash::H256, _platform: &str, _checksum: &bigint::hash::H256) -> Result<(), String> { let call = self.contract.function("addChecksum".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_release.as_ref().to_owned()), ethabi::Token::FixedBytes(_platform.as_bytes().to_owned()), ethabi::Token::FixedBytes(_checksum.as_ref().to_owned())] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -182,10 +182,10 @@ impl Operations { #[allow(dead_code)] pub fn confirm_transaction(&self, _txid: &bigint::hash::H256) -> Result { let call = self.contract.function("confirmTransaction".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_txid.as_ref().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) } @@ -194,10 +194,10 @@ impl Operations { #[allow(dead_code)] pub fn proxy(&self, _1: &bigint::hash::H256) -> Result<(bigint::prelude::U256, util::Address, Vec, bigint::prelude::U256, bigint::prelude::U256), String> { let call = self.contract.function("proxy".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_1.as_ref().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_address().ok_or("Invalid type returned")?; util::Address::from(r) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bytes().ok_or("Invalid type returned")?; r }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) } @@ -206,10 +206,10 @@ impl Operations { #[allow(dead_code)] pub fn add_client(&self, _client: &str, _owner: &util::Address) -> Result<(), String> { let call = self.contract.function("addClient".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Address(_owner.clone().0)] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -218,10 +218,10 @@ impl Operations { #[allow(dead_code)] pub fn client_owner(&self, _1: &util::Address) -> Result { let call = self.contract.function("clientOwner".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::Address(_1.clone().0)] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) } @@ -230,10 +230,10 @@ impl Operations { #[allow(dead_code)] pub fn propose_transaction(&self, _txid: &bigint::hash::H256, _to: &util::Address, _data: &[u8], _value: bigint::prelude::U256, _gas: bigint::prelude::U256) -> Result { let call = self.contract.function("proposeTransaction".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_txid.as_ref().to_owned()), ethabi::Token::Address(_to.clone().0), ethabi::Token::Bytes(_data.to_owned()), ethabi::Token::Uint({ let mut r = [0u8; 32]; _value.to_big_endian(&mut r); r }), ethabi::Token::Uint({ let mut r = [0u8; 32]; _gas.to_big_endian(&mut r); r })] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) } @@ -242,10 +242,10 @@ impl Operations { #[allow(dead_code)] pub fn grand_owner(&self) -> Result { let call = self.contract.function("grandOwner".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_address().ok_or("Invalid type returned")?; util::Address::from(r) })) } @@ -254,10 +254,10 @@ impl Operations { #[allow(dead_code)] pub fn add_release(&self, _release: &bigint::hash::H256, _fork_block: u32, _track: u8, _semver: u32, _critical: bool) -> Result<(), String> { let call = self.contract.function("addRelease".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_release.as_ref().to_owned()), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_fork_block as u64).to_big_endian(&mut r); r }), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_track as u64).to_big_endian(&mut r); r }), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_semver as u64).to_big_endian(&mut r); r }), ethabi::Token::Bool(_critical)] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -266,10 +266,10 @@ impl Operations { #[allow(dead_code)] pub fn accept_fork(&self) -> Result<(), String> { let call = self.contract.function("acceptFork".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -278,10 +278,10 @@ impl Operations { #[allow(dead_code)] pub fn clients_required(&self) -> Result { let call = self.contract.function("clientsRequired".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 })) } @@ -290,10 +290,10 @@ impl Operations { #[allow(dead_code)] pub fn track(&self, _client: &str, _release: &bigint::hash::H256) -> Result { let call = self.contract.function("track".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u8 })) } @@ -302,10 +302,10 @@ impl Operations { #[allow(dead_code)] pub fn set_client_required(&self, _client: &str, _r: bool) -> Result<(), String> { let call = self.contract.function("setClientRequired".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Bool(_r)] ).map_err(Self::as_string)?; - call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; Ok(()) } @@ -314,10 +314,8 @@ impl Operations { #[allow(dead_code)] pub fn latest_fork(&self) -> Result { let call = self.contract.function("latestFork".into()).map_err(Self::as_string)?; - let data = call.encode_call( - vec![] - ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let data = call.encode_input(&[]).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 })) } @@ -326,10 +324,10 @@ impl Operations { #[allow(dead_code)] pub fn latest_in_track(&self, _client: &str, _track: u8) -> Result { let call = self.contract.function("latestInTrack".into()).map_err(Self::as_string)?; - let data = call.encode_call( - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_track as u64).to_big_endian(&mut r); r })] + let data = call.encode_input(& + &vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_track as u64).to_big_endian(&mut r); r })] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) } @@ -338,10 +336,10 @@ impl Operations { #[allow(dead_code)] pub fn checksum(&self, _client: &str, _release: &bigint::hash::H256, _platform: &str) -> Result { let call = self.contract.function("checksum".into()).map_err(Self::as_string)?; - let data = call.encode_call( + let data = call.encode_input(& vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned()), ethabi::Token::FixedBytes(_platform.as_bytes().to_owned())] ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) } @@ -350,10 +348,8 @@ impl Operations { #[allow(dead_code)] pub fn proposed_fork(&self) -> Result { let call = self.contract.function("proposedFork".into()).map_err(Self::as_string)?; - let data = call.encode_call( - vec![] - ).map_err(Self::as_string)?; - let output = call.decode_output((self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; + let data = call.encode_input(&[]).map_err(Self::as_string)?; + let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; let mut result = output.into_iter().rev().collect::>(); Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 })) } diff --git a/updater/src/service.rs b/updater/src/service.rs index dbc7e0ead..b025eb42e 100644 --- a/updater/src/service.rs +++ b/updater/src/service.rs @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use types::all::{CapState, ReleaseInfo, OperationsInfo}; -use ipc_common_types::VersionInfo; +use types::{CapState, ReleaseInfo, OperationsInfo, VersionInfo}; -#[ipc(client_ident="RemoteUpdater")] pub trait Service: Send + Sync { /// Is the currently running client capable of supporting the current chain? /// We default to true if there's no clear information. diff --git a/updater/src/types/all.rs b/updater/src/types/all.rs index aef1a0ce3..b20b2fa41 100644 --- a/updater/src/types/all.rs +++ b/updater/src/types/all.rs @@ -17,11 +17,10 @@ //! Types used in the public API use bigint::hash::H256; -pub use ipc_common_types::{VersionInfo, ReleaseTrack}; +use types::VersionInfo; /// Information regarding a particular release of Parity #[derive(Debug, Clone, PartialEq)] -#[binary] pub struct ReleaseInfo { /// Information on the version. pub version: VersionInfo, @@ -35,7 +34,6 @@ pub struct ReleaseInfo { /// Information on our operations environment. #[derive(Debug, Clone, PartialEq)] -#[binary] pub struct OperationsInfo { /// Our blockchain's latest fork. pub fork: u64, @@ -51,7 +49,6 @@ pub struct OperationsInfo { /// Information on the current version's consensus capabililty. #[derive(Debug, Clone, Copy, PartialEq)] -#[binary] pub enum CapState { /// Unknown. Unknown, diff --git a/updater/src/types/mod.rs b/updater/src/types/mod.rs index 68dfe0b25..b6d3c6025 100644 --- a/updater/src/types/mod.rs +++ b/updater/src/types/mod.rs @@ -16,6 +16,11 @@ //! Types used in the public api -#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues -include!(concat!(env!("OUT_DIR"), "/mod.rs.in")); +mod all; +mod release_track; +mod version_info; + +pub use self::all::{ReleaseInfo, OperationsInfo, CapState}; +pub use self::release_track::ReleaseTrack; +pub use self::version_info::VersionInfo; diff --git a/updater/src/types/mod.rs.in b/updater/src/types/mod.rs.in deleted file mode 100644 index 0681e2884..000000000 --- a/updater/src/types/mod.rs.in +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -pub mod all; diff --git a/ipc-common-types/src/types/release_track.rs b/updater/src/types/release_track.rs similarity index 96% rename from ipc-common-types/src/types/release_track.rs rename to updater/src/types/release_track.rs index 418f590c8..0eaf85d14 100644 --- a/ipc-common-types/src/types/release_track.rs +++ b/updater/src/types/release_track.rs @@ -20,7 +20,6 @@ use std::fmt; /// A release's track. #[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[binary] pub enum ReleaseTrack { /// Stable track. Stable, @@ -35,7 +34,7 @@ pub enum ReleaseTrack { } impl fmt::Display for ReleaseTrack { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", match *self { ReleaseTrack::Stable => "stable", ReleaseTrack::Beta => "beta", diff --git a/ipc-common-types/src/types/version_info.rs b/updater/src/types/version_info.rs similarity index 94% rename from ipc-common-types/src/types/version_info.rs rename to updater/src/types/version_info.rs index ef386824d..778e57087 100644 --- a/ipc-common-types/src/types/version_info.rs +++ b/updater/src/types/version_info.rs @@ -17,15 +17,13 @@ //! Types used in the public API use std::fmt; -use std::str::FromStr; use semver::{Version}; use bigint::hash::H160; use util::misc::raw_package_info; -use release_track::ReleaseTrack; +use types::ReleaseTrack; /// Version information of a particular release. #[derive(Debug, Clone, PartialEq)] -#[binary] pub struct VersionInfo { /// The track on which it was released. pub track: ReleaseTrack, @@ -48,7 +46,7 @@ impl VersionInfo { VersionInfo { track: raw.0.into(), version: { let mut v = Version::parse(raw.1).expect("Environment variables are known to be valid; qed"); v.build = vec![]; v.pre = vec![]; v }, - hash: H160::from_str(raw.2).unwrap_or_else(|_| H160::zero()), + hash: raw.2.parse::().unwrap_or_else(|_| H160::zero()), } } diff --git a/updater/src/updater.rs b/updater/src/updater.rs index efa34adab..91c9181f8 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -24,13 +24,12 @@ use ethsync::{SyncProvider}; use futures::future; use hash_fetch::{self as fetch, HashFetch}; use hash_fetch::fetch::Client as FetchService; -use ipc_common_types::{VersionInfo, ReleaseTrack}; use operations::Operations; use parity_reactor::Remote; use path::restrict_permissions_owner; use service::{Service}; use target_info::Target; -use types::all::{ReleaseInfo, OperationsInfo, CapState}; +use types::{ReleaseInfo, OperationsInfo, CapState, VersionInfo, ReleaseTrack}; use bigint::hash::{H160, H256}; use util::Address; use bytes::Bytes; diff --git a/util/Cargo.toml b/util/Cargo.toml index 61d8b2335..8dbbd9a76 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -24,10 +24,8 @@ target_info = "0.1" ethcore-bigint = { path = "bigint", features = ["heapsizeof"] } parking_lot = "0.4" tiny-keccak= "1.0" -lru-cache = "0.1.0" ethcore-logger = { path = "../logger" } triehash = { path = "triehash" } -error-chain = "0.11.0-rc.2" hashdb = { path = "hashdb" } patricia_trie = { path = "patricia_trie" } ethcore-bytes = { path = "bytes" } @@ -35,6 +33,9 @@ memorydb = { path = "memorydb" } util-error = { path = "error" } kvdb = { path = "kvdb" } +[dev-dependencies] +kvdb-memorydb = { path = "kvdb-memorydb" } + [features] default = [] dev = ["clippy"] diff --git a/util/error/Cargo.toml b/util/error/Cargo.toml index 5c51a78ca..390a38d4b 100644 --- a/util/error/Cargo.toml +++ b/util/error/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Parity Technologies "] [dependencies] rlp = { path = "../rlp" } +kvdb = { path = "../kvdb" } ethcore-bigint = { path = "../bigint" } -error-chain = "0.11.0-rc.2" +error-chain = "0.11.0" rustc-hex = "1.0" diff --git a/util/error/src/lib.rs b/util/error/src/lib.rs index 3b314456e..0f6c9ad70 100644 --- a/util/error/src/lib.rs +++ b/util/error/src/lib.rs @@ -25,6 +25,7 @@ extern crate error_chain; extern crate ethcore_bigint as bigint; extern crate rlp; extern crate rustc_hex; +extern crate kvdb; use std::fmt; use rustc_hex::FromHexError; @@ -62,6 +63,10 @@ error_chain! { UtilError, ErrorKind, ResultExt, Result; } + links { + Db(kvdb::Error, kvdb::ErrorKind); + } + foreign_links { Io(::std::io::Error); FromHex(FromHexError); diff --git a/util/kvdb-memorydb/Cargo.toml b/util/kvdb-memorydb/Cargo.toml new file mode 100644 index 000000000..9ff69909d --- /dev/null +++ b/util/kvdb-memorydb/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "kvdb-memorydb" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +parking_lot = "0.4" +rlp = { path = "../rlp" } +kvdb = { path = "../kvdb" } diff --git a/util/kvdb-memorydb/src/lib.rs b/util/kvdb-memorydb/src/lib.rs new file mode 100644 index 000000000..7026797ea --- /dev/null +++ b/util/kvdb-memorydb/src/lib.rs @@ -0,0 +1,127 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +extern crate parking_lot; +extern crate kvdb; +extern crate rlp; + +use std::collections::{BTreeMap, HashMap}; +use parking_lot::RwLock; +use kvdb::{DBValue, DBTransaction, KeyValueDB, DBOp, Result}; +use rlp::{RlpType, UntrustedRlp, Compressible}; + +/// A key-value database fulfilling the `KeyValueDB` trait, living in memory. +/// This is generally intended for tests and is not particularly optimized. +#[derive(Default)] +pub struct InMemory { + columns: RwLock, BTreeMap, DBValue>>>, +} + +/// Create an in-memory database with the given number of columns. +/// Columns will be indexable by 0..`num_cols` +pub fn create(num_cols: u32) -> InMemory { + let mut cols = HashMap::new(); + cols.insert(None, BTreeMap::new()); + + for idx in 0..num_cols { + cols.insert(Some(idx), BTreeMap::new()); + } + + InMemory { + columns: RwLock::new(cols) + } +} + +impl KeyValueDB for InMemory { + fn get(&self, col: Option, key: &[u8]) -> Result> { + let columns = self.columns.read(); + match columns.get(&col) { + None => Err(format!("No such column family: {:?}", col).into()), + Some(map) => Ok(map.get(key).cloned()), + } + } + + fn get_by_prefix(&self, col: Option, prefix: &[u8]) -> Option> { + let columns = self.columns.read(); + match columns.get(&col) { + None => None, + Some(map) => + map.iter() + .find(|&(ref k ,_)| k.starts_with(prefix)) + .map(|(_, v)| v.to_vec().into_boxed_slice()) + } + } + + fn write_buffered(&self, transaction: DBTransaction) { + let mut columns = self.columns.write(); + let ops = transaction.ops; + for op in ops { + match op { + DBOp::Insert { col, key, value } => { + if let Some(col) = columns.get_mut(&col) { + col.insert(key.into_vec(), value); + } + }, + DBOp::InsertCompressed { col, key, value } => { + if let Some(col) = columns.get_mut(&col) { + let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks); + let mut value = DBValue::new(); + value.append_slice(&compressed); + col.insert(key.into_vec(), value); + } + }, + DBOp::Delete { col, key } => { + if let Some(col) = columns.get_mut(&col) { + col.remove(&*key); + } + }, + } + } + } + + fn flush(&self) -> Result<()> { + Ok(()) + } + + fn iter<'a>(&'a self, col: Option) -> Box, Box<[u8]>)> + 'a> { + match self.columns.read().get(&col) { + Some(map) => Box::new( // TODO: worth optimizing at all? + map.clone() + .into_iter() + .map(|(k, v)| (k.into_boxed_slice(), v.into_vec().into_boxed_slice())) + ), + None => Box::new(None.into_iter()), + } + } + + fn iter_from_prefix<'a>(&'a self, col: Option, prefix: &'a [u8]) + -> Box, Box<[u8]>)> + 'a> + { + match self.columns.read().get(&col) { + Some(map) => Box::new( + map.clone() + .into_iter() + .skip_while(move |&(ref k, _)| !k.starts_with(prefix)) + .map(|(k, v)| (k.into_boxed_slice(), v.into_vec().into_boxed_slice())) + ), + None => Box::new(None.into_iter()), + } + } + + fn restore(&self, _new_db: &str) -> Result<()> { + Err("Attempted to restore in-memory database".into()) + } +} diff --git a/util/kvdb-rocksdb/Cargo.toml b/util/kvdb-rocksdb/Cargo.toml new file mode 100644 index 000000000..0f1809d14 --- /dev/null +++ b/util/kvdb-rocksdb/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "kvdb-rocksdb" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +log = "0.3" +elastic-array = "0.9" +ethcore-bigint = { path = "../bigint" } +ethcore-devtools = { path = "../../devtools" } +parking_lot = "0.4" +regex = "0.2" +rlp = { path = "../rlp" } +rocksdb = { git = "https://github.com/paritytech/rust-rocksdb" } +kvdb = { path = "../kvdb" } diff --git a/util/kvdb-rocksdb/src/lib.rs b/util/kvdb-rocksdb/src/lib.rs new file mode 100644 index 000000000..45461a60f --- /dev/null +++ b/util/kvdb-rocksdb/src/lib.rs @@ -0,0 +1,806 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +#[macro_use] +extern crate log; + +extern crate elastic_array; +extern crate parking_lot; +extern crate regex; +extern crate rocksdb; + +extern crate ethcore_bigint as bigint; +extern crate ethcore_devtools as devtools; +extern crate kvdb; +extern crate rlp; + +use std::collections::HashMap; +use std::marker::PhantomData; +use std::path::{PathBuf, Path}; +use std::{mem, fs, io}; + +use parking_lot::{Mutex, MutexGuard, RwLock}; +use rocksdb::{ + DB, Writable, WriteBatch, WriteOptions, IteratorMode, DBIterator, + Options, DBCompactionStyle, BlockBasedOptions, Direction, Cache, Column, ReadOptions +}; + +use elastic_array::ElasticArray32; +use rlp::{UntrustedRlp, RlpType, Compressible}; +use kvdb::{KeyValueDB, DBTransaction, DBValue, DBOp, Result}; + +#[cfg(target_os = "linux")] +use regex::Regex; +#[cfg(target_os = "linux")] +use std::process::Command; +#[cfg(target_os = "linux")] +use std::fs::File; + +const DB_BACKGROUND_FLUSHES: i32 = 2; +const DB_BACKGROUND_COMPACTIONS: i32 = 2; +const DB_WRITE_BUFFER_SIZE: usize = 2048 * 1000; + +enum KeyState { + Insert(DBValue), + InsertCompressed(DBValue), + Delete, +} + +/// Compaction profile for the database settings +#[derive(Clone, Copy, PartialEq, Debug)] +pub struct CompactionProfile { + /// L0-L1 target file size + pub initial_file_size: u64, + /// L2-LN target file size multiplier + pub file_size_multiplier: i32, + /// rate limiter for background flushes and compactions, bytes/sec, if any + pub write_rate_limit: Option, +} + +impl Default for CompactionProfile { + /// Default profile suitable for most storage + fn default() -> CompactionProfile { + CompactionProfile::ssd() + } +} + +/// Given output of df command return Linux rotational flag file path. +#[cfg(target_os = "linux")] +pub fn rotational_from_df_output(df_out: Vec) -> Option { + use std::str; + str::from_utf8(df_out.as_slice()) + .ok() + // Get the drive name. + .and_then(|df_str| Regex::new(r"/dev/(sd[:alpha:]{1,2})") + .ok() + .and_then(|re| re.captures(df_str)) + .and_then(|captures| captures.get(1))) + // Generate path e.g. /sys/block/sda/queue/rotational + .map(|drive_path| { + let mut p = PathBuf::from("/sys/block"); + p.push(drive_path.as_str()); + p.push("queue/rotational"); + p + }) +} + +impl CompactionProfile { + /// Attempt to determine the best profile automatically, only Linux for now. + #[cfg(target_os = "linux")] + pub fn auto(db_path: &Path) -> CompactionProfile { + use std::io::Read; + let hdd_check_file = db_path + .to_str() + .and_then(|path_str| Command::new("df").arg(path_str).output().ok()) + .and_then(|df_res| match df_res.status.success() { + true => Some(df_res.stdout), + false => None, + }) + .and_then(rotational_from_df_output); + // Read out the file and match compaction profile. + if let Some(hdd_check) = hdd_check_file { + if let Ok(mut file) = File::open(hdd_check.as_path()) { + let mut buffer = [0; 1]; + if file.read_exact(&mut buffer).is_ok() { + // 0 means not rotational. + if buffer == [48] { return Self::ssd(); } + // 1 means rotational. + if buffer == [49] { return Self::hdd(); } + } + } + } + // Fallback if drive type was not determined. + Self::default() + } + + /// Just default for other platforms. + #[cfg(not(target_os = "linux"))] + pub fn auto(_db_path: &Path) -> CompactionProfile { + Self::default() + } + + /// Default profile suitable for SSD storage + pub fn ssd() -> CompactionProfile { + CompactionProfile { + initial_file_size: 32 * 1024 * 1024, + file_size_multiplier: 2, + write_rate_limit: None, + } + } + + /// Slow HDD compaction profile + pub fn hdd() -> CompactionProfile { + CompactionProfile { + initial_file_size: 192 * 1024 * 1024, + file_size_multiplier: 1, + write_rate_limit: Some(8 * 1024 * 1024), + } + } +} + +/// Database configuration +#[derive(Clone)] +pub struct DatabaseConfig { + /// Max number of open files. + pub max_open_files: i32, + /// Cache sizes (in MiB) for specific columns. + pub cache_sizes: HashMap, usize>, + /// Compaction profile + pub compaction: CompactionProfile, + /// Set number of columns + pub columns: Option, + /// Should we keep WAL enabled? + pub wal: bool, +} + +impl DatabaseConfig { + /// Create new `DatabaseConfig` with default parameters and specified set of columns. + /// Note that cache sizes must be explicitly set. + pub fn with_columns(columns: Option) -> Self { + let mut config = Self::default(); + config.columns = columns; + config + } + + /// Set the column cache size in MiB. + pub fn set_cache(&mut self, col: Option, size: usize) { + self.cache_sizes.insert(col, size); + } +} + +impl Default for DatabaseConfig { + fn default() -> DatabaseConfig { + DatabaseConfig { + cache_sizes: HashMap::new(), + max_open_files: 512, + compaction: CompactionProfile::default(), + columns: None, + wal: true, + } + } +} + +/// Database iterator (for flushed data only) +// The compromise of holding only a virtual borrow vs. holding a lock on the +// inner DB (to prevent closing via restoration) may be re-evaluated in the future. +// +pub struct DatabaseIterator<'a> { + iter: DBIterator, + _marker: PhantomData<&'a Database>, +} + +impl<'a> Iterator for DatabaseIterator<'a> { + type Item = (Box<[u8]>, Box<[u8]>); + + fn next(&mut self) -> Option { + self.iter.next() + } +} + +struct DBAndColumns { + db: DB, + cfs: Vec, +} + +// get column family configuration from database config. +fn col_config(col: u32, config: &DatabaseConfig) -> Options { + // default cache size for columns not specified. + const DEFAULT_CACHE: usize = 2; + + let mut opts = Options::new(); + opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction); + opts.set_target_file_size_base(config.compaction.initial_file_size); + opts.set_target_file_size_multiplier(config.compaction.file_size_multiplier); + opts.set_db_write_buffer_size(DB_WRITE_BUFFER_SIZE); + + let col_opt = config.columns.map(|_| col); + + { + let cache_size = config.cache_sizes.get(&col_opt).cloned().unwrap_or(DEFAULT_CACHE); + let mut block_opts = BlockBasedOptions::new(); + // all goes to read cache. + block_opts.set_cache(Cache::new(cache_size * 1024 * 1024)); + opts.set_block_based_table_factory(&block_opts); + } + + opts +} + +/// Key-Value database. +pub struct Database { + db: RwLock>, + config: DatabaseConfig, + write_opts: WriteOptions, + read_opts: ReadOptions, + path: String, + // Dirty values added with `write_buffered`. Cleaned on `flush`. + overlay: RwLock, KeyState>>>, + // Values currently being flushed. Cleared when `flush` completes. + flushing: RwLock, KeyState>>>, + // Prevents concurrent flushes. + // Value indicates if a flush is in progress. + flushing_lock: Mutex, +} + +impl Database { + /// Open database with default settings. + pub fn open_default(path: &str) -> Result { + Database::open(&DatabaseConfig::default(), path) + } + + /// Open database file. Creates if it does not exist. + pub fn open(config: &DatabaseConfig, path: &str) -> Result { + let mut opts = Options::new(); + if let Some(rate_limit) = config.compaction.write_rate_limit { + opts.set_parsed_options(&format!("rate_limiter_bytes_per_sec={}", rate_limit))?; + } + opts.set_parsed_options(&format!("max_total_wal_size={}", 64 * 1024 * 1024))?; + opts.set_parsed_options("verify_checksums_in_compaction=0")?; + opts.set_parsed_options("keep_log_file_num=1")?; + opts.set_max_open_files(config.max_open_files); + opts.create_if_missing(true); + opts.set_use_fsync(false); + opts.set_db_write_buffer_size(DB_WRITE_BUFFER_SIZE); + + opts.set_max_background_flushes(DB_BACKGROUND_FLUSHES); + opts.set_max_background_compactions(DB_BACKGROUND_COMPACTIONS); + + // compaction settings + opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction); + opts.set_target_file_size_base(config.compaction.initial_file_size); + opts.set_target_file_size_multiplier(config.compaction.file_size_multiplier); + + let mut cf_options = Vec::with_capacity(config.columns.unwrap_or(0) as usize); + let cfnames: Vec<_> = (0..config.columns.unwrap_or(0)).map(|c| format!("col{}", c)).collect(); + let cfnames: Vec<&str> = cfnames.iter().map(|n| n as &str).collect(); + + for col in 0 .. config.columns.unwrap_or(0) { + cf_options.push(col_config(col, &config)); + } + + let mut write_opts = WriteOptions::new(); + if !config.wal { + write_opts.disable_wal(true); + } + let mut read_opts = ReadOptions::new(); + read_opts.set_verify_checksums(false); + + let mut cfs: Vec = Vec::new(); + let db = match config.columns { + Some(columns) => { + match DB::open_cf(&opts, path, &cfnames, &cf_options) { + Ok(db) => { + cfs = cfnames.iter().map(|n| db.cf_handle(n) + .expect("rocksdb opens a cf_handle for each cfname; qed")).collect(); + assert!(cfs.len() == columns as usize); + Ok(db) + } + Err(_) => { + // retry and create CFs + match DB::open_cf(&opts, path, &[], &[]) { + Ok(mut db) => { + cfs = cfnames.iter().enumerate().map(|(i, n)| db.create_cf(n, &cf_options[i])).collect::<::std::result::Result<_, _>>()?; + Ok(db) + }, + err @ Err(_) => err, + } + } + } + }, + None => DB::open(&opts, path) + }; + + let db = match db { + Ok(db) => db, + Err(ref s) if s.starts_with("Corruption:") => { + info!("{}", s); + info!("Attempting DB repair for {}", path); + DB::repair(&opts, path)?; + + match cfnames.is_empty() { + true => DB::open(&opts, path)?, + false => DB::open_cf(&opts, path, &cfnames, &cf_options)? + } + }, + Err(s) => { return Err(s.into()); } + }; + let num_cols = cfs.len(); + Ok(Database { + db: RwLock::new(Some(DBAndColumns{ db: db, cfs: cfs })), + config: config.clone(), + write_opts: write_opts, + overlay: RwLock::new((0..(num_cols + 1)).map(|_| HashMap::new()).collect()), + flushing: RwLock::new((0..(num_cols + 1)).map(|_| HashMap::new()).collect()), + flushing_lock: Mutex::new((false)), + path: path.to_owned(), + read_opts: read_opts, + }) + } + + /// Helper to create new transaction for this database. + pub fn transaction(&self) -> DBTransaction { + DBTransaction::new() + } + + + fn to_overlay_column(col: Option) -> usize { + col.map_or(0, |c| (c + 1) as usize) + } + + /// Commit transaction to database. + pub fn write_buffered(&self, tr: DBTransaction) { + let mut overlay = self.overlay.write(); + let ops = tr.ops; + for op in ops { + match op { + DBOp::Insert { col, key, value } => { + let c = Self::to_overlay_column(col); + overlay[c].insert(key, KeyState::Insert(value)); + }, + DBOp::InsertCompressed { col, key, value } => { + let c = Self::to_overlay_column(col); + overlay[c].insert(key, KeyState::InsertCompressed(value)); + }, + DBOp::Delete { col, key } => { + let c = Self::to_overlay_column(col); + overlay[c].insert(key, KeyState::Delete); + }, + } + }; + } + + /// Commit buffered changes to database. Must be called under `flush_lock` + fn write_flushing_with_lock(&self, _lock: &mut MutexGuard) -> Result<()> { + match *self.db.read() { + Some(DBAndColumns { ref db, ref cfs }) => { + let batch = WriteBatch::new(); + mem::swap(&mut *self.overlay.write(), &mut *self.flushing.write()); + { + for (c, column) in self.flushing.read().iter().enumerate() { + for (ref key, ref state) in column.iter() { + match **state { + KeyState::Delete => { + if c > 0 { + batch.delete_cf(cfs[c - 1], &key)?; + } else { + batch.delete(&key)?; + } + }, + KeyState::Insert(ref value) => { + if c > 0 { + batch.put_cf(cfs[c - 1], &key, value)?; + } else { + batch.put(&key, &value)?; + } + }, + KeyState::InsertCompressed(ref value) => { + let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks); + if c > 0 { + batch.put_cf(cfs[c - 1], &key, &compressed)?; + } else { + batch.put(&key, &value)?; + } + } + } + } + } + } + db.write_opt(batch, &self.write_opts)?; + for column in self.flushing.write().iter_mut() { + column.clear(); + column.shrink_to_fit(); + } + Ok(()) + }, + None => Err("Database is closed".into()) + } + } + + /// Commit buffered changes to database. + pub fn flush(&self) -> Result<()> { + let mut lock = self.flushing_lock.lock(); + // If RocksDB batch allocation fails the thread gets terminated and the lock is released. + // The value inside the lock is used to detect that. + if *lock { + // This can only happen if another flushing thread is terminated unexpectedly. + return Err("Database write failure. Running low on memory perhaps?".into()); + } + *lock = true; + let result = self.write_flushing_with_lock(&mut lock); + *lock = false; + result + } + + /// Commit transaction to database. + pub fn write(&self, tr: DBTransaction) -> Result<()> { + match *self.db.read() { + Some(DBAndColumns { ref db, ref cfs }) => { + let batch = WriteBatch::new(); + let ops = tr.ops; + for op in ops { + match op { + DBOp::Insert { col, key, value } => { + col.map_or_else(|| batch.put(&key, &value), |c| batch.put_cf(cfs[c as usize], &key, &value))? + }, + DBOp::InsertCompressed { col, key, value } => { + let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks); + col.map_or_else(|| batch.put(&key, &compressed), |c| batch.put_cf(cfs[c as usize], &key, &compressed))? + }, + DBOp::Delete { col, key } => { + col.map_or_else(|| batch.delete(&key), |c| batch.delete_cf(cfs[c as usize], &key))? + }, + } + } + db.write_opt(batch, &self.write_opts).map_err(Into::into) + }, + None => Err("Database is closed".into()) + } + } + + /// Get value by key. + pub fn get(&self, col: Option, key: &[u8]) -> Result> { + match *self.db.read() { + Some(DBAndColumns { ref db, ref cfs }) => { + let overlay = &self.overlay.read()[Self::to_overlay_column(col)]; + match overlay.get(key) { + Some(&KeyState::Insert(ref value)) | Some(&KeyState::InsertCompressed(ref value)) => Ok(Some(value.clone())), + Some(&KeyState::Delete) => Ok(None), + None => { + let flushing = &self.flushing.read()[Self::to_overlay_column(col)]; + match flushing.get(key) { + Some(&KeyState::Insert(ref value)) | Some(&KeyState::InsertCompressed(ref value)) => Ok(Some(value.clone())), + Some(&KeyState::Delete) => Ok(None), + None => { + col.map_or_else( + || db.get_opt(key, &self.read_opts).map(|r| r.map(|v| DBValue::from_slice(&v))), + |c| db.get_cf_opt(cfs[c as usize], key, &self.read_opts).map(|r| r.map(|v| DBValue::from_slice(&v)))) + .map_err(Into::into) + }, + } + }, + } + }, + None => Ok(None), + } + } + + /// Get value by partial key. Prefix size should match configured prefix size. Only searches flushed values. + // TODO: support prefix seek for unflushed data + pub fn get_by_prefix(&self, col: Option, prefix: &[u8]) -> Option> { + self.iter_from_prefix(col, prefix).and_then(|mut iter| { + match iter.next() { + // TODO: use prefix_same_as_start read option (not availabele in C API currently) + Some((k, v)) => if k[0 .. prefix.len()] == prefix[..] { Some(v) } else { None }, + _ => None + } + }) + } + + /// Get database iterator for flushed data. + pub fn iter(&self, col: Option) -> Option { + //TODO: iterate over overlay + match *self.db.read() { + Some(DBAndColumns { ref db, ref cfs }) => { + let iter = col.map_or_else( + || db.iterator_opt(IteratorMode::Start, &self.read_opts), + |c| db.iterator_cf_opt(cfs[c as usize], IteratorMode::Start, &self.read_opts) + .expect("iterator params are valid; qed") + ); + + Some(DatabaseIterator { + iter: iter, + _marker: PhantomData, + }) + }, + None => None, + } + } + + fn iter_from_prefix(&self, col: Option, prefix: &[u8]) -> Option { + match *self.db.read() { + Some(DBAndColumns { ref db, ref cfs }) => { + let iter = col.map_or_else(|| db.iterator_opt(IteratorMode::From(prefix, Direction::Forward), &self.read_opts), + |c| db.iterator_cf_opt(cfs[c as usize], IteratorMode::From(prefix, Direction::Forward), &self.read_opts) + .expect("iterator params are valid; qed")); + + Some(DatabaseIterator { + iter: iter, + _marker: PhantomData, + }) + }, + None => None, + } + } + + /// Close the database + fn close(&self) { + *self.db.write() = None; + self.overlay.write().clear(); + self.flushing.write().clear(); + } + + /// Restore the database from a copy at given path. + pub fn restore(&self, new_db: &str) -> Result<()> { + self.close(); + + let mut backup_db = PathBuf::from(&self.path); + backup_db.pop(); + backup_db.push("backup_db"); + + let existed = match fs::rename(&self.path, &backup_db) { + Ok(_) => true, + Err(e) => if let io::ErrorKind::NotFound = e.kind() { + false + } else { + return Err(e.into()); + } + }; + + match fs::rename(&new_db, &self.path) { + Ok(_) => { + // clean up the backup. + if existed { + fs::remove_dir_all(&backup_db)?; + } + } + Err(e) => { + // restore the backup. + if existed { + fs::rename(&backup_db, &self.path)?; + } + return Err(e.into()) + } + } + + // reopen the database and steal handles into self + let db = Self::open(&self.config, &self.path)?; + *self.db.write() = mem::replace(&mut *db.db.write(), None); + *self.overlay.write() = mem::replace(&mut *db.overlay.write(), Vec::new()); + *self.flushing.write() = mem::replace(&mut *db.flushing.write(), Vec::new()); + Ok(()) + } + + /// The number of non-default column families. + pub fn num_columns(&self) -> u32 { + self.db.read().as_ref() + .and_then(|db| if db.cfs.is_empty() { None } else { Some(db.cfs.len()) } ) + .map(|n| n as u32) + .unwrap_or(0) + } + + /// Drop a column family. + pub fn drop_column(&self) -> Result<()> { + match *self.db.write() { + Some(DBAndColumns { ref mut db, ref mut cfs }) => { + if let Some(col) = cfs.pop() { + let name = format!("col{}", cfs.len()); + drop(col); + db.drop_cf(&name)?; + } + Ok(()) + }, + None => Ok(()), + } + } + + /// Add a column family. + pub fn add_column(&self) -> Result<()> { + match *self.db.write() { + Some(DBAndColumns { ref mut db, ref mut cfs }) => { + let col = cfs.len() as u32; + let name = format!("col{}", col); + cfs.push(db.create_cf(&name, &col_config(col, &self.config))?); + Ok(()) + }, + None => Ok(()), + } + } +} + +// duplicate declaration of methods here to avoid trait import in certain existing cases +// at time of addition. +impl KeyValueDB for Database { + fn get(&self, col: Option, key: &[u8]) -> Result> { + Database::get(self, col, key) + } + + fn get_by_prefix(&self, col: Option, prefix: &[u8]) -> Option> { + Database::get_by_prefix(self, col, prefix) + } + + fn write_buffered(&self, transaction: DBTransaction) { + Database::write_buffered(self, transaction) + } + + fn write(&self, transaction: DBTransaction) -> Result<()> { + Database::write(self, transaction) + } + + fn flush(&self) -> Result<()> { + Database::flush(self) + } + + fn iter<'a>(&'a self, col: Option) -> Box, Box<[u8]>)> + 'a> { + let unboxed = Database::iter(self, col); + Box::new(unboxed.into_iter().flat_map(|inner| inner)) + } + + fn iter_from_prefix<'a>(&'a self, col: Option, prefix: &'a [u8]) + -> Box, Box<[u8]>)> + 'a> + { + let unboxed = Database::iter_from_prefix(self, col, prefix); + Box::new(unboxed.into_iter().flat_map(|inner| inner)) + } + + fn restore(&self, new_db: &str) -> Result<()> { + Database::restore(self, new_db) + } +} + +impl Drop for Database { + fn drop(&mut self) { + // write all buffered changes if we can. + let _ = self.flush(); + } +} + +#[cfg(test)] +mod tests { + use bigint::hash::H256; + use super::*; + use devtools::*; + use std::str::FromStr; + + fn test_db(config: &DatabaseConfig) { + let path = RandomTempPath::create_dir(); + let db = Database::open(config, path.as_path().to_str().unwrap()).unwrap(); + let key1 = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); + let key2 = H256::from_str("03c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); + let key3 = H256::from_str("01c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); + + let mut batch = db.transaction(); + batch.put(None, &key1, b"cat"); + batch.put(None, &key2, b"dog"); + db.write(batch).unwrap(); + + assert_eq!(&*db.get(None, &key1).unwrap().unwrap(), b"cat"); + + let contents: Vec<_> = db.iter(None).into_iter().flat_map(|inner| inner).collect(); + assert_eq!(contents.len(), 2); + assert_eq!(&*contents[0].0, &*key1); + assert_eq!(&*contents[0].1, b"cat"); + assert_eq!(&*contents[1].0, &*key2); + assert_eq!(&*contents[1].1, b"dog"); + + let mut batch = db.transaction(); + batch.delete(None, &key1); + db.write(batch).unwrap(); + + assert!(db.get(None, &key1).unwrap().is_none()); + + let mut batch = db.transaction(); + batch.put(None, &key1, b"cat"); + db.write(batch).unwrap(); + + let mut transaction = db.transaction(); + transaction.put(None, &key3, b"elephant"); + transaction.delete(None, &key1); + db.write(transaction).unwrap(); + assert!(db.get(None, &key1).unwrap().is_none()); + assert_eq!(&*db.get(None, &key3).unwrap().unwrap(), b"elephant"); + + assert_eq!(&*db.get_by_prefix(None, &key3).unwrap(), b"elephant"); + assert_eq!(&*db.get_by_prefix(None, &key2).unwrap(), b"dog"); + + let mut transaction = db.transaction(); + transaction.put(None, &key1, b"horse"); + transaction.delete(None, &key3); + db.write_buffered(transaction); + assert!(db.get(None, &key3).unwrap().is_none()); + assert_eq!(&*db.get(None, &key1).unwrap().unwrap(), b"horse"); + + db.flush().unwrap(); + assert!(db.get(None, &key3).unwrap().is_none()); + assert_eq!(&*db.get(None, &key1).unwrap().unwrap(), b"horse"); + } + + #[test] + fn kvdb() { + let path = RandomTempPath::create_dir(); + let _ = Database::open_default(path.as_path().to_str().unwrap()).unwrap(); + test_db(&DatabaseConfig::default()); + } + + #[test] + #[cfg(target_os = "linux")] + fn df_to_rotational() { + use std::path::PathBuf; + // Example df output. + let example_df = vec![70, 105, 108, 101, 115, 121, 115, 116, 101, 109, 32, 32, 32, 32, 32, 49, 75, 45, 98, 108, 111, 99, 107, 115, 32, 32, 32, 32, 32, 85, 115, 101, 100, 32, 65, 118, 97, 105, 108, 97, 98, 108, 101, 32, 85, 115, 101, 37, 32, 77, 111, 117, 110, 116, 101, 100, 32, 111, 110, 10, 47, 100, 101, 118, 47, 115, 100, 97, 49, 32, 32, 32, 32, 32, 32, 32, 54, 49, 52, 48, 57, 51, 48, 48, 32, 51, 56, 56, 50, 50, 50, 51, 54, 32, 32, 49, 57, 52, 52, 52, 54, 49, 54, 32, 32, 54, 55, 37, 32, 47, 10]; + let expected_output = Some(PathBuf::from("/sys/block/sda/queue/rotational")); + assert_eq!(rotational_from_df_output(example_df), expected_output); + } + + #[test] + fn add_columns() { + let config = DatabaseConfig::default(); + let config_5 = DatabaseConfig::with_columns(Some(5)); + + let path = RandomTempPath::create_dir(); + + // open empty, add 5. + { + let db = Database::open(&config, path.as_path().to_str().unwrap()).unwrap(); + assert_eq!(db.num_columns(), 0); + + for i in 0..5 { + db.add_column().unwrap(); + assert_eq!(db.num_columns(), i + 1); + } + } + + // reopen as 5. + { + let db = Database::open(&config_5, path.as_path().to_str().unwrap()).unwrap(); + assert_eq!(db.num_columns(), 5); + } + } + + #[test] + fn drop_columns() { + let config = DatabaseConfig::default(); + let config_5 = DatabaseConfig::with_columns(Some(5)); + + let path = RandomTempPath::create_dir(); + + // open 5, remove all. + { + let db = Database::open(&config_5, path.as_path().to_str().unwrap()).unwrap(); + assert_eq!(db.num_columns(), 5); + + for i in (0..5).rev() { + db.drop_column().unwrap(); + assert_eq!(db.num_columns(), i); + } + } + + // reopen as 0. + { + let db = Database::open(&config, path.as_path().to_str().unwrap()).unwrap(); + assert_eq!(db.num_columns(), 0); + } + } +} diff --git a/util/kvdb/Cargo.toml b/util/kvdb/Cargo.toml index 16c3cb86d..5900d861f 100644 --- a/util/kvdb/Cargo.toml +++ b/util/kvdb/Cargo.toml @@ -4,14 +4,6 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -log = "0.3" -ethcore-bytes = { path = "../bytes" } -ethcore-bigint = { path = "../bigint" } -ethcore-devtools = { path = "../../devtools" } elastic-array = "0.9" -hashdb = { path = "../hashdb" } -parking_lot = "0.4" -regex = "0.2" -rlp = { path = "../rlp" } -rocksdb = { git = "https://github.com/paritytech/rust-rocksdb" } -error-chain = "0.11.0-rc.2" +error-chain = "0.11.0" +ethcore-bytes = { path = "../bytes" } diff --git a/util/kvdb/src/lib.rs b/util/kvdb/src/lib.rs index b78ab1055..c10a392d5 100644 --- a/util/kvdb/src/lib.rs +++ b/util/kvdb/src/lib.rs @@ -16,51 +16,24 @@ //! Key-Value store abstraction with `RocksDB` backend. -#[macro_use] -extern crate log; #[macro_use] extern crate error_chain; - -extern crate ethcore_bytes as bytes; -extern crate ethcore_bigint as bigint; -extern crate ethcore_devtools as devtools; extern crate elastic_array; -extern crate hashdb; -extern crate parking_lot; -extern crate rlp; -extern crate rocksdb; -extern crate regex; +extern crate ethcore_bytes as bytes; -use std::{mem, fs, io}; -use std::collections::{HashMap, BTreeMap}; -use std::marker::PhantomData; -use std::path::{PathBuf, Path}; -use parking_lot::{Mutex, MutexGuard, RwLock}; - -use elastic_array::*; -use hashdb::DBValue; -use rlp::{UntrustedRlp, RlpType, Compressible}; -use rocksdb::{DB, Writable, WriteBatch, WriteOptions, IteratorMode, DBIterator, - Options, DBCompactionStyle, BlockBasedOptions, Direction, Cache, Column, ReadOptions}; +use std::io; +use elastic_array::{ElasticArray128, ElasticArray32}; use bytes::Bytes; -#[cfg(target_os = "linux")] -use regex::Regex; -#[cfg(target_os = "linux")] -use std::process::Command; -#[cfg(target_os = "linux")] -use std::fs::File; - -const DB_BACKGROUND_FLUSHES: i32 = 2; -const DB_BACKGROUND_COMPACTIONS: i32 = 2; -const DB_WRITE_BUFFER_SIZE: usize = 2048 * 1000; - /// Required length of prefixes. pub const PREFIX_LEN: usize = 12; +/// Database value. +pub type DBValue = ElasticArray128; + error_chain! { types { - Error, ErrorKind, ResultExt; + Error, ErrorKind, ResultExt, Result; } foreign_links { @@ -71,11 +44,13 @@ error_chain! { /// Write transaction. Batches a sequence of put/delete operations for efficiency. #[derive(Default, Clone, PartialEq)] pub struct DBTransaction { - ops: Vec, + /// Database operations. + pub ops: Vec, } +/// Database operation. #[derive(Clone, PartialEq)] -enum DBOp { +pub enum DBOp { Insert { col: Option, key: ElasticArray32, @@ -150,12 +125,6 @@ impl DBTransaction { } } -enum KeyState { - Insert(DBValue), - InsertCompressed(DBValue), - Delete, -} - /// Generic key-value database. /// /// This makes a distinction between "buffered" and "flushed" values. Values which have been @@ -179,7 +148,7 @@ pub trait KeyValueDB: Sync + Send { fn transaction(&self) -> DBTransaction { DBTransaction::new() } /// Get a value by key. - fn get(&self, col: Option, key: &[u8]) -> Result, String>; + fn get(&self, col: Option, key: &[u8]) -> Result>; /// Get a value by partial key. Only works for flushed data. fn get_by_prefix(&self, col: Option, prefix: &[u8]) -> Option>; @@ -188,13 +157,13 @@ pub trait KeyValueDB: Sync + Send { fn write_buffered(&self, transaction: DBTransaction); /// Write a transaction of changes to the backing store. - fn write(&self, transaction: DBTransaction) -> Result<(), String> { + fn write(&self, transaction: DBTransaction) -> Result<()> { self.write_buffered(transaction); self.flush() } /// Flush all buffered data. - fn flush(&self) -> Result<(), String>; + fn flush(&self) -> Result<()>; /// Iterate over flushed data for a given column. fn iter<'a>(&'a self, col: Option) -> Box, Box<[u8]>)> + 'a>; @@ -204,849 +173,5 @@ pub trait KeyValueDB: Sync + Send { -> Box, Box<[u8]>)> + 'a>; /// Attempt to replace this database with a new one located at the given path. - fn restore(&self, new_db: &str) -> Result<(), Error>; -} - -/// A key-value database fulfilling the `KeyValueDB` trait, living in memory. -/// This is generally intended for tests and is not particularly optimized. -pub struct InMemory { - columns: RwLock, BTreeMap, DBValue>>>, -} - -/// Create an in-memory database with the given number of columns. -/// Columns will be indexable by 0..`num_cols` -pub fn in_memory(num_cols: u32) -> InMemory { - let mut cols = HashMap::new(); - cols.insert(None, BTreeMap::new()); - - for idx in 0..num_cols { - cols.insert(Some(idx), BTreeMap::new()); - } - - InMemory { - columns: RwLock::new(cols) - } -} - -impl KeyValueDB for InMemory { - fn get(&self, col: Option, key: &[u8]) -> Result, String> { - let columns = self.columns.read(); - match columns.get(&col) { - None => Err(format!("No such column family: {:?}", col)), - Some(map) => Ok(map.get(key).cloned()), - } - } - - fn get_by_prefix(&self, col: Option, prefix: &[u8]) -> Option> { - let columns = self.columns.read(); - match columns.get(&col) { - None => None, - Some(map) => - map.iter() - .find(|&(ref k ,_)| k.starts_with(prefix)) - .map(|(_, v)| v.to_vec().into_boxed_slice()) - } - } - - fn write_buffered(&self, transaction: DBTransaction) { - let mut columns = self.columns.write(); - let ops = transaction.ops; - for op in ops { - match op { - DBOp::Insert { col, key, value } => { - if let Some(col) = columns.get_mut(&col) { - col.insert(key.into_vec(), value); - } - }, - DBOp::InsertCompressed { col, key, value } => { - if let Some(col) = columns.get_mut(&col) { - let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks); - let mut value = DBValue::new(); - value.append_slice(&compressed); - col.insert(key.into_vec(), value); - } - }, - DBOp::Delete { col, key } => { - if let Some(col) = columns.get_mut(&col) { - col.remove(&*key); - } - }, - } - } - } - - fn flush(&self) -> Result<(), String> { Ok(()) } - fn iter<'a>(&'a self, col: Option) -> Box, Box<[u8]>)> + 'a> { - match self.columns.read().get(&col) { - Some(map) => Box::new( // TODO: worth optimizing at all? - map.clone() - .into_iter() - .map(|(k, v)| (k.into_boxed_slice(), v.into_vec().into_boxed_slice())) - ), - None => Box::new(None.into_iter()), - } - } - - fn iter_from_prefix<'a>(&'a self, col: Option, prefix: &'a [u8]) - -> Box, Box<[u8]>)> + 'a> - { - match self.columns.read().get(&col) { - Some(map) => Box::new( - map.clone() - .into_iter() - .skip_while(move |&(ref k, _)| !k.starts_with(prefix)) - .map(|(k, v)| (k.into_boxed_slice(), v.into_vec().into_boxed_slice())) - ), - None => Box::new(None.into_iter()), - } - } - - fn restore(&self, _new_db: &str) -> Result<(), Error> { - Err("Attempted to restore in-memory database".into()) - } -} - -/// Compaction profile for the database settings -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct CompactionProfile { - /// L0-L1 target file size - pub initial_file_size: u64, - /// L2-LN target file size multiplier - pub file_size_multiplier: i32, - /// rate limiter for background flushes and compactions, bytes/sec, if any - pub write_rate_limit: Option, -} - -impl Default for CompactionProfile { - /// Default profile suitable for most storage - fn default() -> CompactionProfile { - CompactionProfile::ssd() - } -} - -/// Given output of df command return Linux rotational flag file path. -#[cfg(target_os = "linux")] -pub fn rotational_from_df_output(df_out: Vec) -> Option { - use std::str; - str::from_utf8(df_out.as_slice()) - .ok() - // Get the drive name. - .and_then(|df_str| Regex::new(r"/dev/(sd[:alpha:]{1,2})") - .ok() - .and_then(|re| re.captures(df_str)) - .and_then(|captures| captures.get(1))) - // Generate path e.g. /sys/block/sda/queue/rotational - .map(|drive_path| { - let mut p = PathBuf::from("/sys/block"); - p.push(drive_path.as_str()); - p.push("queue/rotational"); - p - }) -} - -impl CompactionProfile { - /// Attempt to determine the best profile automatically, only Linux for now. - #[cfg(target_os = "linux")] - pub fn auto(db_path: &Path) -> CompactionProfile { - use std::io::Read; - let hdd_check_file = db_path - .to_str() - .and_then(|path_str| Command::new("df").arg(path_str).output().ok()) - .and_then(|df_res| match df_res.status.success() { - true => Some(df_res.stdout), - false => None, - }) - .and_then(rotational_from_df_output); - // Read out the file and match compaction profile. - if let Some(hdd_check) = hdd_check_file { - if let Ok(mut file) = File::open(hdd_check.as_path()) { - let mut buffer = [0; 1]; - if file.read_exact(&mut buffer).is_ok() { - // 0 means not rotational. - if buffer == [48] { return Self::ssd(); } - // 1 means rotational. - if buffer == [49] { return Self::hdd(); } - } - } - } - // Fallback if drive type was not determined. - Self::default() - } - - /// Just default for other platforms. - #[cfg(not(target_os = "linux"))] - pub fn auto(_db_path: &Path) -> CompactionProfile { - Self::default() - } - - /// Default profile suitable for SSD storage - pub fn ssd() -> CompactionProfile { - CompactionProfile { - initial_file_size: 32 * 1024 * 1024, - file_size_multiplier: 2, - write_rate_limit: None, - } - } - - /// Slow HDD compaction profile - pub fn hdd() -> CompactionProfile { - CompactionProfile { - initial_file_size: 192 * 1024 * 1024, - file_size_multiplier: 1, - write_rate_limit: Some(8 * 1024 * 1024), - } - } -} - -/// Database configuration -#[derive(Clone)] -pub struct DatabaseConfig { - /// Max number of open files. - pub max_open_files: i32, - /// Cache sizes (in MiB) for specific columns. - pub cache_sizes: HashMap, usize>, - /// Compaction profile - pub compaction: CompactionProfile, - /// Set number of columns - pub columns: Option, - /// Should we keep WAL enabled? - pub wal: bool, -} - -impl DatabaseConfig { - /// Create new `DatabaseConfig` with default parameters and specified set of columns. - /// Note that cache sizes must be explicitly set. - pub fn with_columns(columns: Option) -> Self { - let mut config = Self::default(); - config.columns = columns; - config - } - - /// Set the column cache size in MiB. - pub fn set_cache(&mut self, col: Option, size: usize) { - self.cache_sizes.insert(col, size); - } -} - -impl Default for DatabaseConfig { - fn default() -> DatabaseConfig { - DatabaseConfig { - cache_sizes: HashMap::new(), - max_open_files: 512, - compaction: CompactionProfile::default(), - columns: None, - wal: true, - } - } -} - -/// Database iterator (for flushed data only) -// The compromise of holding only a virtual borrow vs. holding a lock on the -// inner DB (to prevent closing via restoration) may be re-evaluated in the future. -// -pub struct DatabaseIterator<'a> { - iter: DBIterator, - _marker: PhantomData<&'a Database>, -} - -impl<'a> Iterator for DatabaseIterator<'a> { - type Item = (Box<[u8]>, Box<[u8]>); - - fn next(&mut self) -> Option { - self.iter.next() - } -} - -struct DBAndColumns { - db: DB, - cfs: Vec, -} - -// get column family configuration from database config. -fn col_config(col: u32, config: &DatabaseConfig) -> Options { - // default cache size for columns not specified. - const DEFAULT_CACHE: usize = 2; - - let mut opts = Options::new(); - opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction); - opts.set_target_file_size_base(config.compaction.initial_file_size); - opts.set_target_file_size_multiplier(config.compaction.file_size_multiplier); - opts.set_db_write_buffer_size(DB_WRITE_BUFFER_SIZE); - - let col_opt = config.columns.map(|_| col); - - { - let cache_size = config.cache_sizes.get(&col_opt).cloned().unwrap_or(DEFAULT_CACHE); - let mut block_opts = BlockBasedOptions::new(); - // all goes to read cache. - block_opts.set_cache(Cache::new(cache_size * 1024 * 1024)); - opts.set_block_based_table_factory(&block_opts); - } - - opts -} - -/// Key-Value database. -pub struct Database { - db: RwLock>, - config: DatabaseConfig, - write_opts: WriteOptions, - read_opts: ReadOptions, - path: String, - // Dirty values added with `write_buffered`. Cleaned on `flush`. - overlay: RwLock, KeyState>>>, - // Values currently being flushed. Cleared when `flush` completes. - flushing: RwLock, KeyState>>>, - // Prevents concurrent flushes. - // Value indicates if a flush is in progress. - flushing_lock: Mutex, -} - -impl Database { - /// Open database with default settings. - pub fn open_default(path: &str) -> Result { - Database::open(&DatabaseConfig::default(), path) - } - - /// Open database file. Creates if it does not exist. - pub fn open(config: &DatabaseConfig, path: &str) -> Result { - let mut opts = Options::new(); - if let Some(rate_limit) = config.compaction.write_rate_limit { - opts.set_parsed_options(&format!("rate_limiter_bytes_per_sec={}", rate_limit))?; - } - opts.set_parsed_options(&format!("max_total_wal_size={}", 64 * 1024 * 1024))?; - opts.set_parsed_options("verify_checksums_in_compaction=0")?; - opts.set_parsed_options("keep_log_file_num=1")?; - opts.set_max_open_files(config.max_open_files); - opts.create_if_missing(true); - opts.set_use_fsync(false); - opts.set_db_write_buffer_size(DB_WRITE_BUFFER_SIZE); - - opts.set_max_background_flushes(DB_BACKGROUND_FLUSHES); - opts.set_max_background_compactions(DB_BACKGROUND_COMPACTIONS); - - // compaction settings - opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction); - opts.set_target_file_size_base(config.compaction.initial_file_size); - opts.set_target_file_size_multiplier(config.compaction.file_size_multiplier); - - let mut cf_options = Vec::with_capacity(config.columns.unwrap_or(0) as usize); - let cfnames: Vec<_> = (0..config.columns.unwrap_or(0)).map(|c| format!("col{}", c)).collect(); - let cfnames: Vec<&str> = cfnames.iter().map(|n| n as &str).collect(); - - for col in 0 .. config.columns.unwrap_or(0) { - cf_options.push(col_config(col, &config)); - } - - let mut write_opts = WriteOptions::new(); - if !config.wal { - write_opts.disable_wal(true); - } - let mut read_opts = ReadOptions::new(); - read_opts.set_verify_checksums(false); - - let mut cfs: Vec = Vec::new(); - let db = match config.columns { - Some(columns) => { - match DB::open_cf(&opts, path, &cfnames, &cf_options) { - Ok(db) => { - cfs = cfnames.iter().map(|n| db.cf_handle(n) - .expect("rocksdb opens a cf_handle for each cfname; qed")).collect(); - assert!(cfs.len() == columns as usize); - Ok(db) - } - Err(_) => { - // retry and create CFs - match DB::open_cf(&opts, path, &[], &[]) { - Ok(mut db) => { - cfs = cfnames.iter().enumerate().map(|(i, n)| db.create_cf(n, &cf_options[i])).collect::>()?; - Ok(db) - }, - err @ Err(_) => err, - } - } - } - }, - None => DB::open(&opts, path) - }; - - let db = match db { - Ok(db) => db, - Err(ref s) if s.starts_with("Corruption:") => { - info!("{}", s); - info!("Attempting DB repair for {}", path); - DB::repair(&opts, path)?; - - match cfnames.is_empty() { - true => DB::open(&opts, path)?, - false => DB::open_cf(&opts, path, &cfnames, &cf_options)? - } - }, - Err(s) => { return Err(s); } - }; - let num_cols = cfs.len(); - Ok(Database { - db: RwLock::new(Some(DBAndColumns{ db: db, cfs: cfs })), - config: config.clone(), - write_opts: write_opts, - overlay: RwLock::new((0..(num_cols + 1)).map(|_| HashMap::new()).collect()), - flushing: RwLock::new((0..(num_cols + 1)).map(|_| HashMap::new()).collect()), - flushing_lock: Mutex::new((false)), - path: path.to_owned(), - read_opts: read_opts, - }) - } - - /// Helper to create new transaction for this database. - pub fn transaction(&self) -> DBTransaction { - DBTransaction::new() - } - - - fn to_overlay_column(col: Option) -> usize { - col.map_or(0, |c| (c + 1) as usize) - } - - /// Commit transaction to database. - pub fn write_buffered(&self, tr: DBTransaction) { - let mut overlay = self.overlay.write(); - let ops = tr.ops; - for op in ops { - match op { - DBOp::Insert { col, key, value } => { - let c = Self::to_overlay_column(col); - overlay[c].insert(key, KeyState::Insert(value)); - }, - DBOp::InsertCompressed { col, key, value } => { - let c = Self::to_overlay_column(col); - overlay[c].insert(key, KeyState::InsertCompressed(value)); - }, - DBOp::Delete { col, key } => { - let c = Self::to_overlay_column(col); - overlay[c].insert(key, KeyState::Delete); - }, - } - }; - } - - /// Commit buffered changes to database. Must be called under `flush_lock` - fn write_flushing_with_lock(&self, _lock: &mut MutexGuard) -> Result<(), String> { - match *self.db.read() { - Some(DBAndColumns { ref db, ref cfs }) => { - let batch = WriteBatch::new(); - mem::swap(&mut *self.overlay.write(), &mut *self.flushing.write()); - { - for (c, column) in self.flushing.read().iter().enumerate() { - for (ref key, ref state) in column.iter() { - match **state { - KeyState::Delete => { - if c > 0 { - batch.delete_cf(cfs[c - 1], &key)?; - } else { - batch.delete(&key)?; - } - }, - KeyState::Insert(ref value) => { - if c > 0 { - batch.put_cf(cfs[c - 1], &key, value)?; - } else { - batch.put(&key, &value)?; - } - }, - KeyState::InsertCompressed(ref value) => { - let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks); - if c > 0 { - batch.put_cf(cfs[c - 1], &key, &compressed)?; - } else { - batch.put(&key, &value)?; - } - } - } - } - } - } - db.write_opt(batch, &self.write_opts)?; - for column in self.flushing.write().iter_mut() { - column.clear(); - column.shrink_to_fit(); - } - Ok(()) - }, - None => Err("Database is closed".to_owned()) - } - } - - /// Commit buffered changes to database. - pub fn flush(&self) -> Result<(), String> { - let mut lock = self.flushing_lock.lock(); - // If RocksDB batch allocation fails the thread gets terminated and the lock is released. - // The value inside the lock is used to detect that. - if *lock { - // This can only happen if another flushing thread is terminated unexpectedly. - return Err("Database write failure. Running low on memory perhaps?".to_owned()); - } - *lock = true; - let result = self.write_flushing_with_lock(&mut lock); - *lock = false; - result - } - - /// Commit transaction to database. - pub fn write(&self, tr: DBTransaction) -> Result<(), String> { - match *self.db.read() { - Some(DBAndColumns { ref db, ref cfs }) => { - let batch = WriteBatch::new(); - let ops = tr.ops; - for op in ops { - match op { - DBOp::Insert { col, key, value } => { - col.map_or_else(|| batch.put(&key, &value), |c| batch.put_cf(cfs[c as usize], &key, &value))? - }, - DBOp::InsertCompressed { col, key, value } => { - let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks); - col.map_or_else(|| batch.put(&key, &compressed), |c| batch.put_cf(cfs[c as usize], &key, &compressed))? - }, - DBOp::Delete { col, key } => { - col.map_or_else(|| batch.delete(&key), |c| batch.delete_cf(cfs[c as usize], &key))? - }, - } - } - db.write_opt(batch, &self.write_opts) - }, - None => Err("Database is closed".to_owned()) - } - } - - /// Get value by key. - pub fn get(&self, col: Option, key: &[u8]) -> Result, String> { - match *self.db.read() { - Some(DBAndColumns { ref db, ref cfs }) => { - let overlay = &self.overlay.read()[Self::to_overlay_column(col)]; - match overlay.get(key) { - Some(&KeyState::Insert(ref value)) | Some(&KeyState::InsertCompressed(ref value)) => Ok(Some(value.clone())), - Some(&KeyState::Delete) => Ok(None), - None => { - let flushing = &self.flushing.read()[Self::to_overlay_column(col)]; - match flushing.get(key) { - Some(&KeyState::Insert(ref value)) | Some(&KeyState::InsertCompressed(ref value)) => Ok(Some(value.clone())), - Some(&KeyState::Delete) => Ok(None), - None => { - col.map_or_else( - || db.get_opt(key, &self.read_opts).map(|r| r.map(|v| DBValue::from_slice(&v))), - |c| db.get_cf_opt(cfs[c as usize], key, &self.read_opts).map(|r| r.map(|v| DBValue::from_slice(&v)))) - }, - } - }, - } - }, - None => Ok(None), - } - } - - /// Get value by partial key. Prefix size should match configured prefix size. Only searches flushed values. - // TODO: support prefix seek for unflushed data - pub fn get_by_prefix(&self, col: Option, prefix: &[u8]) -> Option> { - self.iter_from_prefix(col, prefix).and_then(|mut iter| { - match iter.next() { - // TODO: use prefix_same_as_start read option (not availabele in C API currently) - Some((k, v)) => if k[0 .. prefix.len()] == prefix[..] { Some(v) } else { None }, - _ => None - } - }) - } - - /// Get database iterator for flushed data. - pub fn iter(&self, col: Option) -> Option { - //TODO: iterate over overlay - match *self.db.read() { - Some(DBAndColumns { ref db, ref cfs }) => { - let iter = col.map_or_else( - || db.iterator_opt(IteratorMode::Start, &self.read_opts), - |c| db.iterator_cf_opt(cfs[c as usize], IteratorMode::Start, &self.read_opts) - .expect("iterator params are valid; qed") - ); - - Some(DatabaseIterator { - iter: iter, - _marker: PhantomData, - }) - }, - None => None, - } - } - - fn iter_from_prefix(&self, col: Option, prefix: &[u8]) -> Option { - match *self.db.read() { - Some(DBAndColumns { ref db, ref cfs }) => { - let iter = col.map_or_else(|| db.iterator_opt(IteratorMode::From(prefix, Direction::Forward), &self.read_opts), - |c| db.iterator_cf_opt(cfs[c as usize], IteratorMode::From(prefix, Direction::Forward), &self.read_opts) - .expect("iterator params are valid; qed")); - - Some(DatabaseIterator { - iter: iter, - _marker: PhantomData, - }) - }, - None => None, - } - } - - /// Close the database - fn close(&self) { - *self.db.write() = None; - self.overlay.write().clear(); - self.flushing.write().clear(); - } - - /// Restore the database from a copy at given path. - pub fn restore(&self, new_db: &str) -> Result<(), Error> { - self.close(); - - let mut backup_db = PathBuf::from(&self.path); - backup_db.pop(); - backup_db.push("backup_db"); - - let existed = match fs::rename(&self.path, &backup_db) { - Ok(_) => true, - Err(e) => if let io::ErrorKind::NotFound = e.kind() { - false - } else { - return Err(e.into()); - } - }; - - match fs::rename(&new_db, &self.path) { - Ok(_) => { - // clean up the backup. - if existed { - fs::remove_dir_all(&backup_db)?; - } - } - Err(e) => { - // restore the backup. - if existed { - fs::rename(&backup_db, &self.path)?; - } - return Err(e.into()) - } - } - - // reopen the database and steal handles into self - let db = Self::open(&self.config, &self.path)?; - *self.db.write() = mem::replace(&mut *db.db.write(), None); - *self.overlay.write() = mem::replace(&mut *db.overlay.write(), Vec::new()); - *self.flushing.write() = mem::replace(&mut *db.flushing.write(), Vec::new()); - Ok(()) - } - - /// The number of non-default column families. - pub fn num_columns(&self) -> u32 { - self.db.read().as_ref() - .and_then(|db| if db.cfs.is_empty() { None } else { Some(db.cfs.len()) } ) - .map(|n| n as u32) - .unwrap_or(0) - } - - /// Drop a column family. - pub fn drop_column(&self) -> Result<(), String> { - match *self.db.write() { - Some(DBAndColumns { ref mut db, ref mut cfs }) => { - if let Some(col) = cfs.pop() { - let name = format!("col{}", cfs.len()); - drop(col); - db.drop_cf(&name)?; - } - Ok(()) - }, - None => Ok(()), - } - } - - /// Add a column family. - pub fn add_column(&self) -> Result<(), String> { - match *self.db.write() { - Some(DBAndColumns { ref mut db, ref mut cfs }) => { - let col = cfs.len() as u32; - let name = format!("col{}", col); - cfs.push(db.create_cf(&name, &col_config(col, &self.config))?); - Ok(()) - }, - None => Ok(()), - } - } -} - -// duplicate declaration of methods here to avoid trait import in certain existing cases -// at time of addition. -impl KeyValueDB for Database { - fn get(&self, col: Option, key: &[u8]) -> Result, String> { - Database::get(self, col, key) - } - - fn get_by_prefix(&self, col: Option, prefix: &[u8]) -> Option> { - Database::get_by_prefix(self, col, prefix) - } - - fn write_buffered(&self, transaction: DBTransaction) { - Database::write_buffered(self, transaction) - } - - fn write(&self, transaction: DBTransaction) -> Result<(), String> { - Database::write(self, transaction) - } - - fn flush(&self) -> Result<(), String> { - Database::flush(self) - } - - fn iter<'a>(&'a self, col: Option) -> Box, Box<[u8]>)> + 'a> { - let unboxed = Database::iter(self, col); - Box::new(unboxed.into_iter().flat_map(|inner| inner)) - } - - fn iter_from_prefix<'a>(&'a self, col: Option, prefix: &'a [u8]) - -> Box, Box<[u8]>)> + 'a> - { - let unboxed = Database::iter_from_prefix(self, col, prefix); - Box::new(unboxed.into_iter().flat_map(|inner| inner)) - } - - fn restore(&self, new_db: &str) -> Result<(), Error> { - Database::restore(self, new_db) - } -} - -impl Drop for Database { - fn drop(&mut self) { - // write all buffered changes if we can. - let _ = self.flush(); - } -} - -#[cfg(test)] -mod tests { - use bigint::hash::H256; - use super::*; - use devtools::*; - use std::str::FromStr; - - fn test_db(config: &DatabaseConfig) { - let path = RandomTempPath::create_dir(); - let db = Database::open(config, path.as_path().to_str().unwrap()).unwrap(); - let key1 = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); - let key2 = H256::from_str("03c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); - let key3 = H256::from_str("01c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); - - let mut batch = db.transaction(); - batch.put(None, &key1, b"cat"); - batch.put(None, &key2, b"dog"); - db.write(batch).unwrap(); - - assert_eq!(&*db.get(None, &key1).unwrap().unwrap(), b"cat"); - - let contents: Vec<_> = db.iter(None).into_iter().flat_map(|inner| inner).collect(); - assert_eq!(contents.len(), 2); - assert_eq!(&*contents[0].0, &*key1); - assert_eq!(&*contents[0].1, b"cat"); - assert_eq!(&*contents[1].0, &*key2); - assert_eq!(&*contents[1].1, b"dog"); - - let mut batch = db.transaction(); - batch.delete(None, &key1); - db.write(batch).unwrap(); - - assert!(db.get(None, &key1).unwrap().is_none()); - - let mut batch = db.transaction(); - batch.put(None, &key1, b"cat"); - db.write(batch).unwrap(); - - let mut transaction = db.transaction(); - transaction.put(None, &key3, b"elephant"); - transaction.delete(None, &key1); - db.write(transaction).unwrap(); - assert!(db.get(None, &key1).unwrap().is_none()); - assert_eq!(&*db.get(None, &key3).unwrap().unwrap(), b"elephant"); - - assert_eq!(&*db.get_by_prefix(None, &key3).unwrap(), b"elephant"); - assert_eq!(&*db.get_by_prefix(None, &key2).unwrap(), b"dog"); - - let mut transaction = db.transaction(); - transaction.put(None, &key1, b"horse"); - transaction.delete(None, &key3); - db.write_buffered(transaction); - assert!(db.get(None, &key3).unwrap().is_none()); - assert_eq!(&*db.get(None, &key1).unwrap().unwrap(), b"horse"); - - db.flush().unwrap(); - assert!(db.get(None, &key3).unwrap().is_none()); - assert_eq!(&*db.get(None, &key1).unwrap().unwrap(), b"horse"); - } - - #[test] - fn kvdb() { - let path = RandomTempPath::create_dir(); - let _ = Database::open_default(path.as_path().to_str().unwrap()).unwrap(); - test_db(&DatabaseConfig::default()); - } - - #[test] - #[cfg(target_os = "linux")] - fn df_to_rotational() { - use std::path::PathBuf; - // Example df output. - let example_df = vec![70, 105, 108, 101, 115, 121, 115, 116, 101, 109, 32, 32, 32, 32, 32, 49, 75, 45, 98, 108, 111, 99, 107, 115, 32, 32, 32, 32, 32, 85, 115, 101, 100, 32, 65, 118, 97, 105, 108, 97, 98, 108, 101, 32, 85, 115, 101, 37, 32, 77, 111, 117, 110, 116, 101, 100, 32, 111, 110, 10, 47, 100, 101, 118, 47, 115, 100, 97, 49, 32, 32, 32, 32, 32, 32, 32, 54, 49, 52, 48, 57, 51, 48, 48, 32, 51, 56, 56, 50, 50, 50, 51, 54, 32, 32, 49, 57, 52, 52, 52, 54, 49, 54, 32, 32, 54, 55, 37, 32, 47, 10]; - let expected_output = Some(PathBuf::from("/sys/block/sda/queue/rotational")); - assert_eq!(rotational_from_df_output(example_df), expected_output); - } - - #[test] - fn add_columns() { - let config = DatabaseConfig::default(); - let config_5 = DatabaseConfig::with_columns(Some(5)); - - let path = RandomTempPath::create_dir(); - - // open empty, add 5. - { - let db = Database::open(&config, path.as_path().to_str().unwrap()).unwrap(); - assert_eq!(db.num_columns(), 0); - - for i in 0..5 { - db.add_column().unwrap(); - assert_eq!(db.num_columns(), i + 1); - } - } - - // reopen as 5. - { - let db = Database::open(&config_5, path.as_path().to_str().unwrap()).unwrap(); - assert_eq!(db.num_columns(), 5); - } - } - - #[test] - fn drop_columns() { - let config = DatabaseConfig::default(); - let config_5 = DatabaseConfig::with_columns(Some(5)); - - let path = RandomTempPath::create_dir(); - - // open 5, remove all. - { - let db = Database::open(&config_5, path.as_path().to_str().unwrap()).unwrap(); - assert_eq!(db.num_columns(), 5); - - for i in (0..5).rev() { - db.drop_column().unwrap(); - assert_eq!(db.num_columns(), i); - } - } - - // reopen as 0. - { - let db = Database::open(&config, path.as_path().to_str().unwrap()).unwrap(); - assert_eq!(db.num_columns(), 0); - } - } + fn restore(&self, new_db: &str) -> Result<()>; } diff --git a/util/memory_cache/Cargo.toml b/util/memory_cache/Cargo.toml new file mode 100644 index 000000000..f2b612463 --- /dev/null +++ b/util/memory_cache/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "memory-cache" +version = "0.1.0" +authors = ["Parity Technologies "] +description = "An LRU-cache which operates on memory used" +license = "GPL3" + +[dependencies] +heapsize = "0.4" +lru-cache = "0.1" diff --git a/util/src/cache.rs b/util/memory_cache/src/lib.rs similarity index 98% rename from util/src/cache.rs rename to util/memory_cache/src/lib.rs index e6f204192..af70b0cff 100644 --- a/util/src/cache.rs +++ b/util/memory_cache/src/lib.rs @@ -18,6 +18,9 @@ //! crate. // TODO: push changes upstream in a clean way. +extern crate heapsize; +extern crate lru_cache; + use heapsize::HeapSizeOf; use lru_cache::LruCache; diff --git a/util/migration/Cargo.toml b/util/migration/Cargo.toml index 927ea232d..55b63f133 100644 --- a/util/migration/Cargo.toml +++ b/util/migration/Cargo.toml @@ -7,4 +7,6 @@ authors = ["Parity Technologies "] log = "0.3" macros = { path = "../macros" } kvdb = { path = "../kvdb" } +kvdb-rocksdb = { path = "../kvdb-rocksdb" } ethcore-devtools = { path = "../../devtools" } +error-chain = "0.11.0" diff --git a/util/migration/src/lib.rs b/util/migration/src/lib.rs index e854c12f2..f9d3f7cac 100644 --- a/util/migration/src/lib.rs +++ b/util/migration/src/lib.rs @@ -22,17 +22,46 @@ mod tests; extern crate log; #[macro_use] extern crate macros; +#[macro_use] +extern crate error_chain; extern crate ethcore_devtools as devtools; extern crate kvdb; +extern crate kvdb_rocksdb; use std::collections::BTreeMap; -use std::fs; -use std::fmt; use std::path::{Path, PathBuf}; use std::sync::Arc; +use std::{fs, io}; -use kvdb::{CompactionProfile, Database, DatabaseConfig, DBTransaction}; +use kvdb::DBTransaction; +use kvdb_rocksdb::{CompactionProfile, Database, DatabaseConfig}; + +error_chain! { + types { + Error, ErrorKind, ResultExt, Result; + } + + links { + Db(kvdb::Error, kvdb::ErrorKind); + } + + foreign_links { + Io(io::Error); + } + + errors { + CannotAddMigration { + description("Cannot add migration"), + display("Cannot add migration"), + } + + MigrationImpossible { + description("Migration impossible"), + display("Migration impossible"), + } + } +} /// Migration config. #[derive(Clone)] @@ -70,7 +99,7 @@ impl Batch { } /// Insert a value into the batch, committing if necessary. - pub fn insert(&mut self, key: Vec, value: Vec, dest: &mut Database) -> Result<(), Error> { + pub fn insert(&mut self, key: Vec, value: Vec, dest: &mut Database) -> Result<()> { self.inner.insert(key, value); if self.inner.len() == self.batch_size { self.commit(dest)?; @@ -79,7 +108,7 @@ impl Batch { } /// Commit all the items in the batch to the given database. - pub fn commit(&mut self, dest: &mut Database) -> Result<(), Error> { + pub fn commit(&mut self, dest: &mut Database) -> Result<()> { if self.inner.is_empty() { return Ok(()) } let mut transaction = DBTransaction::new(); @@ -89,43 +118,7 @@ impl Batch { } self.inner.clear(); - dest.write(transaction).map_err(Error::Custom) - } -} - -/// Migration error. -#[derive(Debug)] -pub enum Error { - /// Error returned when it is impossible to add new migration rules. - CannotAddMigration, - /// Error returned when migration from specific version can not be performed. - MigrationImpossible, - /// Io Error. - Io(::std::io::Error), - /// Custom error. - Custom(String), -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - Error::CannotAddMigration => write!(f, "Cannot add migration"), - Error::MigrationImpossible => write!(f, "Migration impossible"), - Error::Io(ref err) => write!(f, "{}", err), - Error::Custom(ref err) => write!(f, "{}", err), - } - } -} - -impl From<::std::io::Error> for Error { - fn from(e: ::std::io::Error) -> Self { - Error::Io(e) - } -} - -impl From for Error { - fn from(e: String) -> Self { - Error::Custom(e) + dest.write(transaction).map_err(Into::into) } } @@ -141,7 +134,7 @@ pub trait Migration: 'static { /// Version of the database after the migration. fn version(&self) -> u32; /// Migrate a source to a destination. - fn migrate(&mut self, source: Arc, config: &Config, destination: &mut Database, col: Option) -> Result<(), Error>; + fn migrate(&mut self, source: Arc, config: &Config, destination: &mut Database, col: Option) -> Result<()>; } /// A simple migration over key-value pairs. @@ -162,7 +155,7 @@ impl Migration for T { fn alters_existing(&self) -> bool { true } - fn migrate(&mut self, source: Arc, config: &Config, dest: &mut Database, col: Option) -> Result<(), Error> { + fn migrate(&mut self, source: Arc, config: &Config, dest: &mut Database, col: Option) -> Result<()> { let mut batch = Batch::new(config, col); let iter = match source.iter(col) { @@ -195,7 +188,7 @@ impl Migration for ChangeColumns { fn columns(&self) -> Option { self.post_columns } fn version(&self) -> u32 { self.version } fn alters_existing(&self) -> bool { false } - fn migrate(&mut self, _: Arc, _: &Config, _: &mut Database, _: Option) -> Result<(), Error> { + fn migrate(&mut self, _: Arc, _: &Config, _: &mut Database, _: Option) -> Result<()> { Ok(()) } } @@ -249,7 +242,7 @@ impl Manager { } /// Adds new migration rules. - pub fn add_migration(&mut self, migration: T) -> Result<(), Error> where T: Migration { + pub fn add_migration(&mut self, migration: T) -> Result<()> where T: Migration { let is_new = match self.migrations.last() { Some(last) => migration.version() > last.version(), None => true, @@ -257,17 +250,19 @@ impl Manager { match is_new { true => Ok(self.migrations.push(Box::new(migration))), - false => Err(Error::CannotAddMigration), + false => Err(ErrorKind::CannotAddMigration.into()), } } /// Performs migration in order, starting with a source path, migrating between two temporary databases, /// and producing a path where the final migration lives. - pub fn execute(&mut self, old_path: &Path, version: u32) -> Result { + pub fn execute(&mut self, old_path: &Path, version: u32) -> Result { let config = self.config.clone(); let migrations = self.migrations_from(version); trace!(target: "migration", "Total migrations to execute for version {}: {}", version, migrations.len()); - if migrations.is_empty() { return Err(Error::MigrationImpossible) }; + if migrations.is_empty() { + return Err(ErrorKind::MigrationImpossible.into()) + }; let columns = migrations.get(0).and_then(|m| m.pre_columns()); @@ -285,8 +280,8 @@ impl Manager { let mut temp_path = old_path.to_path_buf(); // start with the old db. - let old_path_str = old_path.to_str().ok_or(Error::MigrationImpossible)?; - let mut cur_db = Arc::new(Database::open(&db_config, old_path_str).map_err(Error::Custom)?); + let old_path_str = old_path.to_str().ok_or(ErrorKind::MigrationImpossible)?; + let mut cur_db = Arc::new(Database::open(&db_config, old_path_str)?); for migration in migrations { trace!(target: "migration", "starting migration to version {}", migration.version()); @@ -299,8 +294,8 @@ impl Manager { temp_path = temp_idx.path(&db_root); // open the target temporary database. - let temp_path_str = temp_path.to_str().ok_or(Error::MigrationImpossible)?; - let mut new_db = Database::open(&db_config, temp_path_str).map_err(Error::Custom)?; + let temp_path_str = temp_path.to_str().ok_or(ErrorKind::MigrationImpossible)?; + let mut new_db = Database::open(&db_config, temp_path_str)?; match current_columns { // migrate only default column @@ -323,11 +318,11 @@ impl Manager { // we can do this in-place. let goal_columns = migration.columns().unwrap_or(0); while cur_db.num_columns() < goal_columns { - cur_db.add_column().map_err(Error::Custom)?; + cur_db.add_column().map_err(kvdb::Error::from)?; } while cur_db.num_columns() > goal_columns { - cur_db.drop_column().map_err(Error::Custom)?; + cur_db.drop_column().map_err(kvdb::Error::from)?; } } } diff --git a/util/migration/src/tests.rs b/util/migration/src/tests.rs index 6445d58f7..1f712262f 100644 --- a/util/migration/src/tests.rs +++ b/util/migration/src/tests.rs @@ -22,7 +22,7 @@ use std::collections::BTreeMap; use std::sync::Arc; use std::path::{Path, PathBuf}; use {Batch, Config, Error, SimpleMigration, Migration, Manager, ChangeColumns}; -use kvdb::Database; +use kvdb_rocksdb::Database; use devtools::RandomTempPath; fn db_path(path: &Path) -> PathBuf { @@ -229,7 +229,7 @@ fn pre_columns() { #[test] fn change_columns() { - use kvdb::DatabaseConfig; + use kvdb_rocksdb::DatabaseConfig; let mut manager = Manager::new(Config::default()); manager.add_migration(ChangeColumns { diff --git a/util/patricia_trie/src/lib.rs b/util/patricia_trie/src/lib.rs index 745549f42..8c4c0d3ef 100644 --- a/util/patricia_trie/src/lib.rs +++ b/util/patricia_trie/src/lib.rs @@ -28,7 +28,7 @@ extern crate ethcore_logger; #[macro_use] extern crate log; -use std::fmt; +use std::{fmt, error}; use bigint::hash::H256; use keccak::KECCAK_NULL_RLP; use hashdb::{HashDB, DBValue}; @@ -86,6 +86,15 @@ impl fmt::Display for TrieError { } } +impl error::Error for TrieError { + fn description(&self) -> &str { + match *self { + TrieError::InvalidStateRoot(_) => "Invalid state root", + TrieError::IncompleteDatabase(_) => "Incomplete database", + } + } +} + /// Trie result type. Boxed to avoid copying around extra space for `H256`s on successful queries. pub type Result = ::std::result::Result>; diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index 52f80a39f..446a5459c 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -55,13 +55,6 @@ impl ArchiveDB { } } - /// Create a new instance with an anonymous temporary database. - #[cfg(test)] - fn new_temp() -> ArchiveDB { - let backing = Arc::new(::kvdb::in_memory(0)); - Self::new(backing, None) - } - fn payload(&self, key: &H256) -> Option { self.backing.get(self.column, key).expect("Low-level database error. Some issue with your hard disk?") } @@ -206,18 +199,16 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use std::path::Path; use keccak::keccak; use hashdb::{HashDB, DBValue}; use super::*; use journaldb::traits::JournalDB; - use kvdb::Database; - use bigint::hash::H32; + use kvdb_memorydb; #[test] fn insert_same_in_fork() { // history is 1 - let mut jdb = ArchiveDB::new_temp(); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); let x = jdb.insert(b"X"); jdb.commit_batch(1, &keccak(b"1"), None).unwrap(); @@ -239,7 +230,7 @@ mod tests { #[test] fn long_history() { // history is 3 - let mut jdb = ArchiveDB::new_temp(); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); let h = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.contains(&h)); @@ -257,7 +248,7 @@ mod tests { #[test] #[should_panic] fn multiple_owed_removal_not_allowed() { - let mut jdb = ArchiveDB::new_temp(); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); let h = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.contains(&h)); @@ -271,7 +262,7 @@ mod tests { #[test] fn complex() { // history is 1 - let mut jdb = ArchiveDB::new_temp(); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -303,7 +294,7 @@ mod tests { #[test] fn fork() { // history is 1 - let mut jdb = ArchiveDB::new_temp(); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -329,7 +320,7 @@ mod tests { #[test] fn overwrite() { // history is 1 - let mut jdb = ArchiveDB::new_temp(); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); let foo = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -348,7 +339,7 @@ mod tests { #[test] fn fork_same_key() { // history is 1 - let mut jdb = ArchiveDB::new_temp(); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); let foo = jdb.insert(b"foo"); @@ -362,19 +353,13 @@ mod tests { assert!(jdb.contains(&foo)); } - fn new_db(dir: &Path) -> ArchiveDB { - let db = Database::open_default(dir.to_str().unwrap()).unwrap(); - ArchiveDB::new(Arc::new(db), None) - } - #[test] fn reopen() { - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); + let shared_db = Arc::new(kvdb_memorydb::create(0)); let bar = H256::random(); let foo = { - let mut jdb = new_db(&dir); + let mut jdb = ArchiveDB::new(shared_db.clone(), None); // history is 1 let foo = jdb.insert(b"foo"); jdb.emplace(bar.clone(), DBValue::from_slice(b"bar")); @@ -383,13 +368,13 @@ mod tests { }; { - let mut jdb = new_db(&dir); + let mut jdb = ArchiveDB::new(shared_db.clone(), None); jdb.remove(&foo); jdb.commit_batch(1, &keccak(b"1"), Some((0, keccak(b"0")))).unwrap(); } { - let mut jdb = new_db(&dir); + let mut jdb = ArchiveDB::new(shared_db, None); assert!(jdb.contains(&foo)); assert!(jdb.contains(&bar)); jdb.commit_batch(2, &keccak(b"2"), Some((1, keccak(b"1")))).unwrap(); @@ -398,11 +383,10 @@ mod tests { #[test] fn reopen_remove() { - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); + let shared_db = Arc::new(kvdb_memorydb::create(0)); let foo = { - let mut jdb = new_db(&dir); + let mut jdb = ArchiveDB::new(shared_db.clone(), None); // history is 1 let foo = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -416,7 +400,7 @@ mod tests { }; { - let mut jdb = new_db(&dir); + let mut jdb = ArchiveDB::new(shared_db, None); jdb.remove(&foo); jdb.commit_batch(3, &keccak(b"3"), Some((2, keccak(b"2")))).unwrap(); assert!(jdb.contains(&foo)); @@ -428,10 +412,9 @@ mod tests { #[test] fn reopen_fork() { - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); + let shared_db = Arc::new(kvdb_memorydb::create(0)); let (foo, _, _) = { - let mut jdb = new_db(&dir); + let mut jdb = ArchiveDB::new(shared_db.clone(), None); // history is 1 let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -446,7 +429,7 @@ mod tests { }; { - let mut jdb = new_db(&dir); + let mut jdb = ArchiveDB::new(shared_db, None); jdb.commit_batch(2, &keccak(b"2b"), Some((1, keccak(b"1b")))).unwrap(); assert!(jdb.contains(&foo)); } @@ -454,17 +437,17 @@ mod tests { #[test] fn returns_state() { - let temp = ::devtools::RandomTempPath::new(); + let shared_db = Arc::new(kvdb_memorydb::create(0)); let key = { - let mut jdb = new_db(temp.as_path().as_path()); + let mut jdb = ArchiveDB::new(shared_db.clone(), None); let key = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); key }; { - let jdb = new_db(temp.as_path().as_path()); + let jdb = ArchiveDB::new(shared_db, None); let state = jdb.state(&key); assert!(state.is_some()); } @@ -472,9 +455,7 @@ mod tests { #[test] fn inject() { - let temp = ::devtools::RandomTempPath::new(); - - let mut jdb = new_db(temp.as_path().as_path()); + let mut jdb = ArchiveDB::new(Arc::new(kvdb_memorydb::create(0)), None); let key = jdb.insert(b"dog"); jdb.inject_batch().unwrap(); diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index a21a6eedb..5ca023cb0 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -140,13 +140,6 @@ impl EarlyMergeDB { } } - /// Create a new instance with an anonymous temporary database. - #[cfg(test)] - fn new_temp() -> EarlyMergeDB { - let backing = Arc::new(::kvdb::in_memory(0)); - Self::new(backing, None) - } - fn morph_key(key: &H256, index: u8) -> Bytes { let mut ret = (&**key).to_owned(); ret.push(index); @@ -554,19 +547,17 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use std::path::Path; use keccak::keccak; use hashdb::{HashDB, DBValue}; use super::*; use super::super::traits::JournalDB; use ethcore_logger::init_log; - use kvdb::{DatabaseConfig}; - use bigint::hash::H32; + use kvdb_memorydb; #[test] fn insert_same_in_fork() { // history is 1 - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); let x = jdb.insert(b"X"); jdb.commit_batch(1, &keccak(b"1"), None).unwrap(); @@ -595,7 +586,7 @@ mod tests { #[test] fn insert_older_era() { - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0a"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -616,7 +607,7 @@ mod tests { #[test] fn long_history() { // history is 3 - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); let h = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -639,7 +630,7 @@ mod tests { #[test] fn complex() { // history is 1 - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -682,7 +673,7 @@ mod tests { #[test] fn fork() { // history is 1 - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -714,7 +705,7 @@ mod tests { #[test] fn overwrite() { // history is 1 - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -737,7 +728,7 @@ mod tests { #[test] fn fork_same_key_one() { - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -762,7 +753,7 @@ mod tests { #[test] fn fork_same_key_other() { - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -787,7 +778,7 @@ mod tests { #[test] fn fork_ins_del_ins() { - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -818,20 +809,18 @@ mod tests { assert!(jdb.can_reconstruct_refs()); } - fn new_db(path: &Path) -> EarlyMergeDB { - let config = DatabaseConfig::with_columns(Some(1)); - let backing = Arc::new(::kvdb::Database::open(&config, path.to_str().unwrap()).unwrap()); - EarlyMergeDB::new(backing, Some(0)) + fn new_db() -> EarlyMergeDB { + let backing = Arc::new(kvdb_memorydb::create(0)); + EarlyMergeDB::new(backing, None) } #[test] fn reopen() { - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); + let shared_db = Arc::new(kvdb_memorydb::create(0)); let bar = H256::random(); let foo = { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db.clone(), None); // history is 1 let foo = jdb.insert(b"foo"); jdb.emplace(bar.clone(), DBValue::from_slice(b"bar")); @@ -841,14 +830,14 @@ mod tests { }; { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db.clone(), None); jdb.remove(&foo); jdb.commit_batch(1, &keccak(b"1"), Some((0, keccak(b"0")))).unwrap(); assert!(jdb.can_reconstruct_refs()); } { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db, None); assert!(jdb.contains(&foo)); assert!(jdb.contains(&bar)); jdb.commit_batch(2, &keccak(b"2"), Some((1, keccak(b"1")))).unwrap(); @@ -861,7 +850,7 @@ mod tests { fn insert_delete_insert_delete_insert_expunge() { init_log(); - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); // history is 4 let foo = jdb.insert(b"foo"); @@ -887,7 +876,7 @@ mod tests { #[test] fn forked_insert_delete_insert_delete_insert_expunge() { init_log(); - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); // history is 4 let foo = jdb.insert(b"foo"); @@ -933,7 +922,7 @@ mod tests { #[test] fn broken_assert() { - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); // history is 1 let foo = jdb.insert(b"foo"); @@ -962,7 +951,7 @@ mod tests { #[test] fn reopen_test() { - let mut jdb = EarlyMergeDB::new_temp(); + let mut jdb = new_db(); // history is 4 let foo = jdb.insert(b"foo"); @@ -997,13 +986,11 @@ mod tests { fn reopen_remove_three() { init_log(); - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); - + let shared_db = Arc::new(kvdb_memorydb::create(0)); let foo = keccak(b"foo"); { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db.clone(), None); // history is 1 jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -1025,7 +1012,7 @@ mod tests { // incantation to reopen the db }; { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db.clone(), None); jdb.remove(&foo); jdb.commit_batch(4, &keccak(b"4"), Some((2, keccak(b"2")))).unwrap(); @@ -1034,7 +1021,7 @@ mod tests { // incantation to reopen the db }; { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db.clone(), None); jdb.commit_batch(5, &keccak(b"5"), Some((3, keccak(b"3")))).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -1042,7 +1029,7 @@ mod tests { // incantation to reopen the db }; { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db, None); jdb.commit_batch(6, &keccak(b"6"), Some((4, keccak(b"4")))).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -1052,10 +1039,10 @@ mod tests { #[test] fn reopen_fork() { - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); + let shared_db = Arc::new(kvdb_memorydb::create(0)); + let (foo, bar, baz) = { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db.clone(), None); // history is 1 let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -1073,7 +1060,7 @@ mod tests { }; { - let mut jdb = new_db(&dir); + let mut jdb = EarlyMergeDB::new(shared_db, None); jdb.commit_batch(2, &keccak(b"2b"), Some((1, keccak(b"1b")))).unwrap(); assert!(jdb.can_reconstruct_refs()); assert!(jdb.contains(&foo)); @@ -1084,9 +1071,7 @@ mod tests { #[test] fn inject() { - let temp = ::devtools::RandomTempPath::new(); - - let mut jdb = new_db(temp.as_path().as_path()); + let mut jdb = new_db(); let key = jdb.insert(b"dog"); jdb.inject_batch().unwrap(); diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index 687333d67..71ce05696 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -117,13 +117,6 @@ impl OverlayRecentDB { } } - /// Create a new instance with an anonymous temporary database. - #[cfg(test)] - pub fn new_temp() -> OverlayRecentDB { - let backing = Arc::new(::kvdb::in_memory(0)); - Self::new(backing, None) - } - #[cfg(test)] fn can_reconstruct_refs(&self) -> bool { let reconstructed = Self::read_overlay(&*self.backing, self.column); @@ -462,24 +455,22 @@ mod tests { #![cfg_attr(feature="dev", allow(blacklisted_name))] #![cfg_attr(feature="dev", allow(similar_names))] - use std::path::Path; use keccak::keccak; use super::*; use hashdb::{HashDB, DBValue}; use ethcore_logger::init_log; use journaldb::JournalDB; - use kvdb::Database; - use bigint::hash::H32; + use kvdb_memorydb; - fn new_db(path: &Path) -> OverlayRecentDB { - let backing = Arc::new(Database::open_default(path.to_str().unwrap()).unwrap()); + fn new_db() -> OverlayRecentDB { + let backing = Arc::new(kvdb_memorydb::create(0)); OverlayRecentDB::new(backing, None) } #[test] fn insert_same_in_fork() { // history is 1 - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); let x = jdb.insert(b"X"); jdb.commit_batch(1, &keccak(b"1"), None).unwrap(); @@ -509,7 +500,7 @@ mod tests { #[test] fn long_history() { // history is 3 - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); let h = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -532,7 +523,7 @@ mod tests { #[test] fn complex() { // history is 1 - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -575,7 +566,7 @@ mod tests { #[test] fn fork() { // history is 1 - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -607,7 +598,7 @@ mod tests { #[test] fn overwrite() { // history is 1 - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -629,7 +620,7 @@ mod tests { #[test] fn fork_same_key_one() { - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -654,7 +645,7 @@ mod tests { #[test] fn fork_same_key_other() { - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -680,7 +671,7 @@ mod tests { #[test] fn fork_ins_del_ins() { - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -714,12 +705,11 @@ mod tests { #[test] fn reopen() { - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); + let shared_db = Arc::new(kvdb_memorydb::create(0)); let bar = H256::random(); let foo = { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); // history is 1 let foo = jdb.insert(b"foo"); jdb.emplace(bar.clone(), DBValue::from_slice(b"bar")); @@ -729,14 +719,14 @@ mod tests { }; { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); jdb.remove(&foo); jdb.commit_batch(1, &keccak(b"1"), Some((0, keccak(b"0")))).unwrap(); assert!(jdb.can_reconstruct_refs()); } { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); assert!(jdb.contains(&foo)); assert!(jdb.contains(&bar)); jdb.commit_batch(2, &keccak(b"2"), Some((1, keccak(b"1")))).unwrap(); @@ -748,7 +738,7 @@ mod tests { #[test] fn insert_delete_insert_delete_insert_expunge() { init_log(); - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); // history is 4 let foo = jdb.insert(b"foo"); @@ -774,7 +764,7 @@ mod tests { #[test] fn forked_insert_delete_insert_delete_insert_expunge() { init_log(); - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); // history is 4 let foo = jdb.insert(b"foo"); @@ -820,7 +810,7 @@ mod tests { #[test] fn broken_assert() { - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); jdb.commit_batch(1, &keccak(b"1"), Some((0, keccak(b"0")))).unwrap(); @@ -848,7 +838,7 @@ mod tests { #[test] fn reopen_test() { - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); // history is 4 let foo = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -882,13 +872,11 @@ mod tests { fn reopen_remove_three() { init_log(); - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); - + let shared_db = Arc::new(kvdb_memorydb::create(0)); let foo = keccak(b"foo"); { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); // history is 1 jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -910,7 +898,7 @@ mod tests { // incantation to reopen the db }; { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); jdb.remove(&foo); jdb.commit_batch(4, &keccak(b"4"), Some((2, keccak(b"2")))).unwrap(); @@ -919,7 +907,7 @@ mod tests { // incantation to reopen the db }; { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); jdb.commit_batch(5, &keccak(b"5"), Some((3, keccak(b"3")))).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -927,7 +915,7 @@ mod tests { // incantation to reopen the db }; { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db, None); jdb.commit_batch(6, &keccak(b"6"), Some((4, keccak(b"4")))).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -937,10 +925,10 @@ mod tests { #[test] fn reopen_fork() { - let mut dir = ::std::env::temp_dir(); - dir.push(H32::random().hex()); + let shared_db = Arc::new(kvdb_memorydb::create(0)); + let (foo, bar, baz) = { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); // history is 1 let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -958,7 +946,7 @@ mod tests { }; { - let mut jdb = new_db(&dir); + let mut jdb = OverlayRecentDB::new(shared_db, None); jdb.commit_batch(2, &keccak(b"2b"), Some((1, keccak(b"1b")))).unwrap(); assert!(jdb.can_reconstruct_refs()); assert!(jdb.contains(&foo)); @@ -969,7 +957,7 @@ mod tests { #[test] fn insert_older_era() { - let mut jdb = OverlayRecentDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0a"), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -989,9 +977,7 @@ mod tests { #[test] fn inject() { - let temp = ::devtools::RandomTempPath::new(); - - let mut jdb = new_db(temp.as_path().as_path()); + let mut jdb = new_db(); let key = jdb.insert(b"dog"); jdb.inject_batch().unwrap(); @@ -1004,10 +990,10 @@ mod tests { #[test] fn earliest_era() { - let temp = ::devtools::RandomTempPath::new(); + let shared_db = Arc::new(kvdb_memorydb::create(0)); // empty DB - let mut jdb = new_db(temp.as_path().as_path()); + let mut jdb = OverlayRecentDB::new(shared_db.clone(), None); assert!(jdb.earliest_era().is_none()); // single journalled era. @@ -1041,7 +1027,7 @@ mod tests { // reconstructed: no journal entries. drop(jdb); - let jdb = new_db(temp.as_path().as_path()); + let jdb = OverlayRecentDB::new(shared_db, None); assert_eq!(jdb.earliest_era(), None); } } diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index eeca11085..b97940321 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -75,13 +75,6 @@ impl RefCountedDB { column: col, } } - - /// Create a new instance with an anonymous temporary database. - #[cfg(test)] - fn new_temp() -> RefCountedDB { - let backing = Arc::new(::kvdb::in_memory(0)); - Self::new(backing, None) - } } impl HashDB for RefCountedDB { @@ -217,13 +210,19 @@ mod tests { use keccak::keccak; use hashdb::{HashDB, DBValue}; + use kvdb_memorydb; use super::*; use super::super::traits::JournalDB; + fn new_db() -> RefCountedDB { + let backing = Arc::new(kvdb_memorydb::create(0)); + RefCountedDB::new(backing, None) + } + #[test] fn long_history() { // history is 3 - let mut jdb = RefCountedDB::new_temp(); + let mut jdb = new_db(); let h = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); assert!(jdb.contains(&h)); @@ -241,7 +240,7 @@ mod tests { #[test] fn latest_era_should_work() { // history is 3 - let mut jdb = RefCountedDB::new_temp(); + let mut jdb = new_db(); assert_eq!(jdb.latest_era(), None); let h = jdb.insert(b"foo"); jdb.commit_batch(0, &keccak(b"0"), None).unwrap(); @@ -260,7 +259,7 @@ mod tests { #[test] fn complex() { // history is 1 - let mut jdb = RefCountedDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -298,7 +297,7 @@ mod tests { #[test] fn fork() { // history is 1 - let mut jdb = RefCountedDB::new_temp(); + let mut jdb = new_db(); let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -325,7 +324,7 @@ mod tests { #[test] fn inject() { - let mut jdb = RefCountedDB::new_temp(); + let mut jdb = new_db(); let key = jdb.insert(b"dog"); jdb.inject_batch().unwrap(); diff --git a/util/src/lib.rs b/util/src/lib.rs index 863f811c4..c02342668 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -100,7 +100,6 @@ extern crate ethcore_bytes as bytes; extern crate parking_lot; extern crate tiny_keccak; extern crate rlp; -extern crate lru_cache; extern crate heapsize; extern crate ethcore_logger; extern crate hash as keccak; @@ -110,13 +109,15 @@ extern crate patricia_trie as trie; extern crate kvdb; extern crate util_error as error; +#[cfg(test)] +extern crate kvdb_memorydb; + #[macro_use] extern crate log as rlog; pub mod misc; pub mod overlaydb; pub mod journaldb; -pub mod cache; pub use misc::*; pub use hashdb::*; diff --git a/util/src/overlaydb.rs b/util/src/overlaydb.rs index b4c0beb25..6844eb801 100644 --- a/util/src/overlaydb.rs +++ b/util/src/overlaydb.rs @@ -50,7 +50,7 @@ impl OverlayDB { /// Create a new instance of OverlayDB with an anonymous temporary database. #[cfg(test)] pub fn new_temp() -> OverlayDB { - let backing = Arc::new(::kvdb::in_memory(0)); + let backing = Arc::new(::kvdb_memorydb::create(0)); Self::new(backing, None) } diff --git a/util/table/src/lib.rs b/util/table/src/lib.rs index bef453426..78b2c646a 100644 --- a/util/table/src/lib.rs +++ b/util/table/src/lib.rs @@ -247,7 +247,7 @@ mod test { // when { - let mut row = table.row_mut(&1).unwrap(); + let row = table.row_mut(&1).unwrap(); row.remove(&1); row.remove(&2); }