diff --git a/Cargo.lock b/Cargo.lock index 291ba89d3ed..823091e8b15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ name = "account-db" version = "0.1.0" dependencies = [ "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -20,7 +20,7 @@ dependencies = [ "common-types 0.1.0", "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -37,7 +37,7 @@ dependencies = [ "rlp_compress 0.1.0", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "trace 0.1.0", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-vm-factories 0.1.0", ] @@ -82,6 +82,14 @@ dependencies = [ "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ahash" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "aho-corasick" version = "0.6.8" @@ -598,6 +606,7 @@ dependencies = [ "parity-crypto 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie-ethereum 0.1.0", "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", @@ -606,6 +615,24 @@ dependencies = [ "vm 0.1.0", ] +[[package]] +name = "const-random" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "const-random-macro" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "criterion" version = "0.3.0" @@ -645,7 +672,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -654,7 +681,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -664,7 +691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -675,7 +702,7 @@ name = "crossbeam-queue" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -685,7 +712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam-utils" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1043,7 +1070,7 @@ dependencies = [ "executive-state 0.1.0", "fetch 0.1.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1067,6 +1094,7 @@ dependencies = [ "registrar 0.0.1", "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1077,7 +1105,7 @@ dependencies = [ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "trace 0.1.0", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-vm-factories 0.1.0", "triehash-ethereum 0.2.0", @@ -1216,7 +1244,7 @@ dependencies = [ "failsafe 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "fastmap 0.1.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -1239,7 +1267,7 @@ dependencies = [ "spec 0.1.0", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "triehash-ethereum 0.2.0", "verification 0.1.0", "vm 0.1.0", @@ -1368,7 +1396,7 @@ dependencies = [ "ethjson 0.1.0", "fetch 0.1.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -1393,7 +1421,7 @@ dependencies = [ "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "trace 0.1.0", "transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", ] @@ -1417,7 +1445,7 @@ dependencies = [ "ethkey 0.4.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1470,8 +1498,8 @@ version = "1.12.0" dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-tcp-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-tcp-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1668,7 +1696,7 @@ dependencies = [ "ethcore 1.12.0", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "evm 0.1.0", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1681,7 +1709,7 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "spec 0.1.0", "trace 0.1.0", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-vm-factories 0.1.0", "vm 0.1.0", ] @@ -1909,7 +1937,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hash-db" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1920,6 +1948,15 @@ dependencies = [ "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hashbrown" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ahash 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hashmap_core" version = "0.1.10" @@ -2224,7 +2261,7 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "fastmap 0.1.0", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2239,7 +2276,7 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2251,7 +2288,7 @@ dependencies = [ [[package]] name = "jsonrpc-derive" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2262,12 +2299,12 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2276,11 +2313,11 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-tokio-ipc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2289,10 +2326,10 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2300,12 +2337,12 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2315,11 +2352,11 @@ dependencies = [ [[package]] name = "jsonrpc-tcp-server" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2327,11 +2364,11 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.0.1" +version = "14.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2352,7 +2389,7 @@ name = "keccak-hasher" version = "0.1.1" dependencies = [ "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "plain_hasher 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2362,7 +2399,7 @@ name = "keccak-hasher" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2525,7 +2562,7 @@ dependencies = [ "account-state 0.1.0", "client-traits 0.1.0", "common-types 0.1.0", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 9.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 9.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2610,7 +2647,7 @@ name = "memory-db" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2987,7 +3024,7 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3065,8 +3102,8 @@ dependencies = [ "common-types 0.1.0", "ethcore 1.12.0", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3146,12 +3183,12 @@ dependencies = [ "fetch 0.1.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ipc-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ipc-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "machine 0.1.0", @@ -3192,8 +3229,8 @@ version = "1.4.0" dependencies = [ "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3393,14 +3430,14 @@ version = "0.1.0" dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", "memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3486,7 +3523,7 @@ dependencies = [ "common-types 0.1.0", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -3498,7 +3535,7 @@ dependencies = [ "rlp 0.4.2 (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.99 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "triehash-ethereum 0.2.0", ] @@ -3854,7 +3891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4216,7 +4253,7 @@ dependencies = [ "account-state 0.1.0", "client-traits 0.1.0", "common-types 0.1.0", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "engine 0.1.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 9.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4230,7 +4267,7 @@ dependencies = [ "ethcore-io 1.12.0", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.4.0", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4248,11 +4285,12 @@ dependencies = [ "rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp_derive 0.1.0", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "snapshot-tests 0.1.0", "spec 0.1.0", "state-db 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "triehash-ethereum 0.2.0", ] @@ -4276,7 +4314,7 @@ dependencies = [ "ethcore-db 0.1.0", "ethcore-io 1.12.0", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -4295,7 +4333,7 @@ dependencies = [ "snapshot 0.1.0", "spec 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "triehash-ethereum 0.2.0", ] @@ -4330,7 +4368,7 @@ dependencies = [ "ethjson 0.1.0", "evm 0.1.0", "executive-state 0.1.0", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "instant-seal 0.1.0", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4368,7 +4406,7 @@ dependencies = [ "ethcore-bloom-journal 0.1.0", "ethcore-db 0.1.0", "ethereum-types 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "journaldb 0.2.0", "keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.1.1", @@ -4633,7 +4671,7 @@ name = "tokio-executor" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4734,7 +4772,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4757,7 +4795,7 @@ name = "tokio-timer" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4862,12 +4900,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trie-db" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4877,7 +4915,7 @@ name = "trie-standardmap" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4889,7 +4927,7 @@ dependencies = [ "evm 0.1.0", "keccak-hasher 0.1.1", "patricia-trie-ethereum 0.1.0", - "trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", "wasm 0.1.0", ] @@ -4899,7 +4937,7 @@ name = "triehash" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5344,6 +5382,7 @@ dependencies = [ "checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" +"checksum ahash 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "b35dfc96a657c1842b4eb73180b65e37152d4b94d0eb5cb51708aee7826950b4" "checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" @@ -5390,6 +5429,8 @@ dependencies = [ "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" "checksum combine 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc1d011beeed29187b8db2ac3925c8dd4d3e87db463dc9d2d2833985388fc5bc" +"checksum const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b641a8c9867e341f3295564203b1c250eb8ce6cb6126e007941f78c4d2ed7fe" +"checksum const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c750ec12b83377637110d5a57f5ae08e895b06c4b16e2bdbf1a94ef717428c59" "checksum criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6" "checksum criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eccdc6ce8bbe352ca89025bee672aa6d24f4eb8c53e3a8b5d1bc58011da072a2" "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" @@ -5397,7 +5438,7 @@ dependencies = [ "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" -"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" @@ -5447,8 +5488,9 @@ dependencies = [ "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum hamming 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" -"checksum hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32c87fec93c4a2d264483ef843ac1930ae7c7999d97d73721305a5188b4c23a4" +"checksum hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" "checksum hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16293646125e09e5bc216d9f73fa81ab31c4f97007d56c036bbf15a58e970540" +"checksum hashbrown 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a" "checksum hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8e04cb7a5051270ef3fa79f8c7604d581ecfa73d520e74f554e45541c4b5881a" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" @@ -5481,14 +5523,14 @@ dependencies = [ "checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" "checksum jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "294eca097d1dc0bf59de5ab9f7eafa5f77129e9f6464c957ed3ddeb705fb4292" "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -"checksum jsonrpc-core 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b392c9e8e43a12e6b21160903f473b1066e57fe18477394a93a1efd25654003" -"checksum jsonrpc-derive 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f79f30bf70049564c507b968162b8fd4bf114514bdacc1e90f9d891f8a66fce3" -"checksum jsonrpc-http-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd3d54c822dc67707f21b15f13995b24eb090501c8ad67782b5484c9be36255b" -"checksum jsonrpc-ipc-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bed0288dfe341a68a5a54d824db5db0cbb9acb8f642cc5e1ac3e58239f24baed" -"checksum jsonrpc-pubsub 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe9faf8ba7ea28c58937cfbca538db1af11a9e72eae1aa8e6a83926b6b4dc46" -"checksum jsonrpc-server-utils 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "629792d44acc93f39800cd4c6524d7f33b30d66f24d3a9374af7ecbe71a4f8bf" -"checksum jsonrpc-tcp-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad0831b17761fa226e54d36284977cab07a29153242e41f67b7fdb2bfd147d5" -"checksum jsonrpc-ws-server 14.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "338664631e75cf752468a0d8ec3ba82df4caaacd942b4c34ea67db2556308e20" +"checksum jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "34651edf3417637cc45e70ed0182ecfa9ced0b7e8131805fccf7400d989845ca" +"checksum jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d5c31575cc70a8b21542599028472c80a9248394aeea4d8918a045a0ab08a3" +"checksum jsonrpc-http-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa54c4c2d88cb5e04b251a5031ba0f2ee8c6ef30970e31228955b89a80c3b611" +"checksum jsonrpc-ipc-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b579cd0840d7db3ebaadf52f6f31ec601a260e78d610e44f68634f919e34497a" +"checksum jsonrpc-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ee1b8da0b9219a231c4b7cbc7110bfdb457cbcd8d90a6224d0b3cab8aae8443" +"checksum jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "87bc3c0a9a282211b2ec14abb3e977de33016bbec495332e9f7be858de7c5117" +"checksum jsonrpc-tcp-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9c7807563cd721401285b59b54358f5b2325b4de6ff6f1de5494a5879e890fc1" +"checksum jsonrpc-ws-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af36a129cef77a9db8028ac7552d927e1bb7b6928cd96b23dd25cc38bff974ab" "checksum keccak-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e563fa6fe52b2686094846118bf2cb2e6f75e6b8cec6c3aba09be8e835c7f998" "checksum keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bf18164fd7ce989041f8fc4a1ae72a8bd1bec3575f2aeaf1d4968fc053aabef" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -5698,7 +5740,7 @@ dependencies = [ "checksum trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe82f2f0bf1991e163e757baf044282823155dd326e70f44ce2186c3c320cc9" "checksum transaction-pool 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "454adc482e32785c3beab9415dd0f3c689f29cc2d16717eb62f6a784d53544b4" "checksum transient-hashmap 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb4b191d033a35edfce392a38cdcf9790b6cebcb30fa690c312c29da4dc433e" -"checksum trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b65d609ae631d808c6c1cc23a622733d5a0b66a7d67e9f5cd5171562a1f4cb5" +"checksum trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0b62d27e8aa1c07414549ac872480ac82380bab39e730242ab08d82d7cc098a" "checksum trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64fda153c00484d640bc91334624be22ead0e5baca917d9fd53ff29bdebcf9b2" "checksum triehash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61d0a66fa2412c7eb7816640e8ea14cf6bd63b6c824e72315b6ca76d33851134" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" diff --git a/Cargo.toml b/Cargo.toml index 4953c356379..49e44cba16b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ ethstore = { path = "accounts/ethstore" } fdlimit = "0.1" futures = "0.1" journaldb = { path = "util/journaldb" } -jsonrpc-core = "14.0.1" +jsonrpc-core = "14.0.3" keccak-hash = "0.4.0" kvdb = "0.1" kvdb-rocksdb = "0.1.5" diff --git a/cli-signer/rpc-client/Cargo.toml b/cli-signer/rpc-client/Cargo.toml index 224ba3bcb6c..c8c568fc199 100644 --- a/cli-signer/rpc-client/Cargo.toml +++ b/cli-signer/rpc-client/Cargo.toml @@ -15,7 +15,7 @@ serde_json = "1.0" url = "2.1.0" matches = "0.1" parking_lot = "0.9" -jsonrpc-core = "14.0.1" -jsonrpc-ws-server = "14.0.1" +jsonrpc-core = "14.0.3" +jsonrpc-ws-server = "14.0.3" parity-rpc = { path = "../../rpc" } keccak-hash = "0.4.0" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index f036010c5ac..ffbcdeaf662 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -51,6 +51,7 @@ rayon = "1.1" registrar = { path = "../util/registrar" } rlp = "0.4.0" rustc-hex = "2" +scopeguard = "1.0.0" serde = "1.0" serde_derive = "1.0" snapshot = { path = "snapshot" } diff --git a/ethcore/engines/authority-round/src/lib.rs b/ethcore/engines/authority-round/src/lib.rs index fd3585fc72c..54980e4f48e 100644 --- a/ethcore/engines/authority-round/src/lib.rs +++ b/ethcore/engines/authority-round/src/lib.rs @@ -33,11 +33,12 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::{cmp, fmt}; -use std::iter::FromIterator; +use std::iter::{self, FromIterator}; use std::ops::Deref; -use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; +use std::sync::atomic::{AtomicU64, AtomicBool, Ordering as AtomicOrdering}; use std::sync::{Weak, Arc}; use std::time::{UNIX_EPOCH, Duration}; +use std::u64; use client_traits::EngineClient; use engine::{Engine, ConstructedVerifier}; @@ -83,12 +84,13 @@ use self::finality::RollingFinality; /// `AuthorityRound` params. pub struct AuthorityRoundParams { - /// Time to wait before next block or authority switching, - /// in seconds. + /// A map defining intervals of blocks with the given times (in seconds) to wait before next + /// block or authority switching. The keys in the map are steps of starting blocks of those + /// periods. The entry at `0` should be defined. /// - /// Deliberately typed as u16 as too high of a value leads - /// to slow block issuance. - pub step_duration: u16, + /// Wait times (durations) are additionally required to be less than 65535 since larger values + /// lead to slow block issuance. + pub step_durations: BTreeMap, /// Starting step, pub start_step: Option, /// Valid validators. @@ -121,11 +123,27 @@ const U16_MAX: usize = ::std::u16::MAX as usize; impl From for AuthorityRoundParams { fn from(p: ethjson::spec::AuthorityRoundParams) -> Self { - let mut step_duration_usize: usize = p.step_duration.into(); - if step_duration_usize > U16_MAX { - step_duration_usize = U16_MAX; - warn!(target: "engine", "step_duration is too high ({}), setting it to {}", step_duration_usize, U16_MAX); - } + let map_step_duration = |u: ethjson::uint::Uint| { + let mut step_duration_usize: usize = u.into(); + if step_duration_usize == 0 { + panic!("AuthorityRoundParams: step duration cannot be 0"); + } + if step_duration_usize > U16_MAX { + warn!(target: "engine", "step duration is too high ({}), setting it to {}", step_duration_usize, U16_MAX); + step_duration_usize = U16_MAX; + } + step_duration_usize as u64 + }; + let step_durations: BTreeMap<_, _> = match p.step_duration { + ethjson::spec::StepDuration::Single(u) => + iter::once((0, map_step_duration(u))).collect(), + ethjson::spec::StepDuration::Transitions(tr) => { + if tr.is_empty() { + panic!("AuthorityRoundParams: step duration transitions cannot be empty"); + } + tr.into_iter().map(|(timestamp, u)| (timestamp.into(), map_step_duration(u))).collect() + } + }; let transition_block_num = p.block_reward_contract_transition.map_or(0, Into::into); let mut br_transitions: BTreeMap<_, _> = p.block_reward_contract_transitions .unwrap_or_default() @@ -151,7 +169,7 @@ impl From for AuthorityRoundParams { ); } AuthorityRoundParams { - step_duration: step_duration_usize as u16, + step_durations, validators: new_validator_set(p.validators), start_step: p.start_step.map(Into::into), validate_score_transition: p.validate_score_transition.map_or(0, Into::into), @@ -169,54 +187,89 @@ impl From for AuthorityRoundParams { } } -// Helper for managing the step. +/// A triple containing the first step number and the starting timestamp of the given step duration. +#[derive(Clone, Debug)] +struct StepDurationInfo { + transition_step: u64, + transition_timestamp: u64, + step_duration: u64, +} + +/// Helper for managing the step. #[derive(Debug)] struct Step { calibrate: bool, // whether calibration is enabled. - inner: AtomicUsize, - duration: u16, + inner: AtomicU64, + /// Planned durations of steps. + durations: Vec, } impl Step { - fn load(&self) -> u64 { self.inner.load(AtomicOrdering::SeqCst) as u64 } + fn load(&self) -> u64 { self.inner.load(AtomicOrdering::SeqCst) } + + /// Finds the remaining duration of the current step. Panics if there was a counter under- or + /// overflow. fn duration_remaining(&self) -> Duration { - let now = unix_now(); - let expected_seconds = self.load() - .checked_add(1) - .and_then(|ctr| ctr.checked_mul(self.duration as u64)) - .map(Duration::from_secs); - - match expected_seconds { - Some(step_end) if step_end > now => step_end - now, - Some(_) => Duration::from_secs(0), - None => { - let ctr = self.load(); - error!(target: "engine", "Step counter is too high: {}, aborting", ctr); - panic!("step counter is too high: {}", ctr) - }, - } + self.opt_duration_remaining().unwrap_or_else(|| { + let ctr = self.load(); + error!(target: "engine", "Step counter under- or overflow: {}, aborting", ctr); + panic!("step counter under- or overflow: {}", ctr) + }) + } + /// Finds the remaining duration of the current step. Returns `None` if there was a counter + /// under- or overflow. + fn opt_duration_remaining(&self) -> Option { + let next_step = self.load().checked_add(1)?; + let StepDurationInfo { transition_step, transition_timestamp, step_duration } = + self.durations.iter() + .take_while(|info| info.transition_step < next_step) + .last() + .expect("durations cannot be empty") + .clone(); + let next_time = transition_timestamp + .checked_add(next_step.checked_sub(transition_step)?.checked_mul(step_duration)?)?; + Some(Duration::from_secs(next_time.saturating_sub(unix_now().as_secs()))) } + /// Increments the step number. + /// + /// Panics if the new step number is `u64::MAX`. fn increment(&self) { - use std::usize; // fetch_add won't panic on overflow but will rather wrap // around, leading to zero as the step counter, which might // lead to unexpected situations, so it's better to shut down. - if self.inner.fetch_add(1, AtomicOrdering::SeqCst) == usize::MAX { - error!(target: "engine", "Step counter is too high: {}, aborting", usize::MAX); - panic!("step counter is too high: {}", usize::MAX); + if self.inner.fetch_add(1, AtomicOrdering::SeqCst) == u64::MAX { + error!(target: "engine", "Step counter is too high: {}, aborting", u64::MAX); + panic!("step counter is too high: {}", u64::MAX); } - } fn calibrate(&self) { if self.calibrate { - let new_step = unix_now().as_secs() / (self.duration as u64); - self.inner.store(new_step as usize, AtomicOrdering::SeqCst); + if self.opt_calibrate().is_none() { + let ctr = self.load(); + error!(target: "engine", "Step counter under- or overflow: {}, aborting", ctr); + panic!("step counter under- or overflow: {}", ctr) + } } } + /// Calibrates the AuRa step number according to the current time. + fn opt_calibrate(&self) -> Option<()> { + let now = unix_now().as_secs(); + let StepDurationInfo { transition_step, transition_timestamp, step_duration } = + self.durations.iter() + .take_while(|info| info.transition_timestamp < now) + .last() + .expect("durations cannot be empty") + .clone(); + let new_step = (now.checked_sub(transition_timestamp)? / step_duration) + .checked_add(transition_step)?; + self.inner.store(new_step, AtomicOrdering::SeqCst); + Some(()) + } + fn check_future(&self, given: u64) -> Result<(), Option>> { const REJECTED_STEP_DRIFT: u64 = 4; @@ -234,7 +287,9 @@ impl Step { Err(None) // wait a bit for blocks in near future } else if given > current { - let d = self.duration as u64; + let d = self.durations.iter().take_while(|info| info.transition_step <= current).last() + .expect("Duration map has at least a 0 entry.") + .step_duration; Err(Some(OutOfBounds { min: None, max: Some(d * current), @@ -730,23 +785,54 @@ impl<'a, A: ?Sized, B> Deref for CowLike<'a, A, B> where B: AsRef { impl AuthorityRound { /// Create a new instance of AuthorityRound engine. pub fn new(our_params: AuthorityRoundParams, machine: Machine) -> Result, Error> { - if our_params.step_duration == 0 { - error!(target: "engine", "Authority Round step duration can't be zero, aborting"); - panic!("authority_round: step duration can't be zero") + if !our_params.step_durations.contains_key(&0) { + error!(target: "engine", "Authority Round step 0 duration is undefined, aborting"); + return Err(Error::Engine(EngineError::Custom(String::from("step 0 duration is undefined")))); + } + if our_params.step_durations.values().any(|v| *v == 0) { + error!(target: "engine", "Authority Round step duration cannot be 0"); + return Err(Error::Engine(EngineError::Custom(String::from("step duration cannot be 0")))); } let should_timeout = our_params.start_step.is_none(); - let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / (our_params.step_duration as u64))); + let initial_step = our_params.start_step.unwrap_or(0); + + let mut durations = Vec::new(); + let mut prev_step = 0u64; + let mut prev_time = 0u64; + let mut prev_dur = our_params.step_durations[&0]; + durations.push(StepDurationInfo { + transition_step: prev_step, + transition_timestamp: prev_time, + step_duration: prev_dur + }); + for (time, dur) in our_params.step_durations.iter().skip(1) { + let (step, time) = next_step_time_duration( + StepDurationInfo{ + transition_step: prev_step, + transition_timestamp: prev_time, + step_duration: prev_dur, + }, *time) + .ok_or(BlockError::TimestampOverflow)?; + durations.push(StepDurationInfo { + transition_step: step, + transition_timestamp: time, + step_duration: *dur + }); + prev_step = step; + prev_time = time; + prev_dur = *dur; + } + + let step = Step { + inner: AtomicU64::new(initial_step), + calibrate: our_params.start_step.is_none(), + durations, + }; + step.calibrate(); let engine = Arc::new( AuthorityRound { transition_service: IoService::<()>::start()?, - step: Arc::new(PermissionedStep { - inner: Step { - inner: AtomicUsize::new(initial_step as usize), - calibrate: our_params.start_step.is_none(), - duration: our_params.step_duration, - }, - can_propose: AtomicBool::new(true), - }), + step: Arc::new(PermissionedStep { inner: step, can_propose: AtomicBool::new(true) }), client: Arc::new(RwLock::new(None)), signer: RwLock::new(None), validators: our_params.validators, @@ -994,8 +1080,10 @@ impl IoHandler<()> for TransitionHandler { } } - let next_run_at = AsMillis::as_millis(&self.step.inner.duration_remaining()) >> 2; - io.register_timer_once(ENGINE_TIMEOUT_TOKEN, Duration::from_millis(next_run_at)) + let next_run_at = Duration::from_millis( + AsMillis::as_millis(&self.step.inner.duration_remaining()) >> 2 + ); + io.register_timer_once(ENGINE_TIMEOUT_TOKEN, next_run_at) .unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e)) } } @@ -1694,12 +1782,27 @@ impl Engine for AuthorityRound { } } +/// A helper accumulator function mapping a step duration and a step duration transition timestamp +/// to the corresponding step number and the correct starting second of the step. +fn next_step_time_duration(info: StepDurationInfo, time: u64) -> Option<(u64, u64)> +{ + let step_diff = time.checked_add(info.step_duration)? + .checked_sub(1)? + .checked_sub(info.transition_timestamp)? + .checked_div(info.step_duration)?; + Some(( + info.transition_step.checked_add(step_diff)?, + step_diff.checked_mul(info.step_duration)?.checked_add(time)?, + )) +} + #[cfg(test)] mod tests { use std::collections::BTreeMap; use std::str::FromStr; use std::sync::Arc; - use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; + use std::sync::atomic::{AtomicUsize, AtomicU64, Ordering as AtomicOrdering}; + use std::time::Duration; use keccak_hash::keccak; use accounts::AccountProvider; use ethereum_types::{Address, H520, H256, U256}; @@ -1726,13 +1829,16 @@ mod tests { use ethjson; use serde_json; - use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score}; + use super::{ + AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, StepDurationInfo, + calculate_score, + }; fn build_aura(f: F) -> Arc where F: FnOnce(&mut AuthorityRoundParams), { let mut params = AuthorityRoundParams { - step_duration: 1, + step_durations: [(0, 1)].to_vec().into_iter().collect(), start_step: Some(1), validators: Box::new(TestSet::default()), validate_score_transition: 0, @@ -2061,29 +2167,67 @@ mod tests { use super::Step; let step = Step { calibrate: false, - inner: AtomicUsize::new(::std::usize::MAX), - duration: 1, + inner: AtomicU64::new(::std::u64::MAX), + durations: [StepDurationInfo { + transition_step: 0, + transition_timestamp: 0, + step_duration: 1, + }].to_vec().into_iter().collect(), }; step.increment(); } #[test] - #[should_panic(expected="counter is too high")] + #[should_panic(expected="step counter under- or overflow")] fn test_counter_duration_remaining_too_high() { use super::Step; let step = Step { calibrate: false, - inner: AtomicUsize::new(::std::usize::MAX), - duration: 1, + inner: AtomicU64::new(::std::u64::MAX), + durations: [StepDurationInfo { + transition_step: 0, + transition_timestamp: 0, + step_duration: 1, + }].to_vec().into_iter().collect(), }; step.duration_remaining(); } #[test] - #[should_panic(expected="authority_round: step duration can't be zero")] + fn test_change_step_duration() { + use super::Step; + use std::thread; + + let now = super::unix_now().as_secs(); + let step = Step { + calibrate: true, + inner: AtomicU64::new(::std::u64::MAX), + durations: [ + StepDurationInfo { transition_step: 0, transition_timestamp: 0, step_duration: 1 }, + StepDurationInfo { transition_step: now, transition_timestamp: now, step_duration: 2 }, + StepDurationInfo { transition_step: now + 1, transition_timestamp: now + 2, step_duration: 4 }, + ].to_vec().into_iter().collect(), + }; + // calibrated step `now` + step.calibrate(); + let duration_remaining = step.duration_remaining(); + assert_eq!(step.inner.load(AtomicOrdering::SeqCst), now); + assert!(duration_remaining <= Duration::from_secs(2)); + thread::sleep(duration_remaining); + step.increment(); + // calibrated step `now + 1` + step.calibrate(); + let duration_remaining = step.duration_remaining(); + assert_eq!(step.inner.load(AtomicOrdering::SeqCst), now + 1); + assert!(duration_remaining > Duration::from_secs(2)); + assert!(duration_remaining <= Duration::from_secs(4)); + } + + #[test] + #[should_panic(expected="called `Result::unwrap()` on an `Err` value: Engine(Custom(\"step duration cannot be 0\"))")] fn test_step_duration_zero() { build_aura(|params| { - params.step_duration = 0; + params.step_durations = [(0, 0)].to_vec().into_iter().collect(); }); } @@ -2473,7 +2617,7 @@ mod tests { #[test] fn test_empty_steps() { let engine = build_aura(|p| { - p.step_duration = 4; + p.step_durations = [(0, 4)].to_vec().into_iter().collect(); p.empty_steps_transition = 0; p.maximum_empty_steps = 0; }); @@ -2507,7 +2651,7 @@ mod tests { let (_spec, tap, accounts) = setup_empty_steps(); let engine = build_aura(|p| { p.validators = Box::new(SimpleList::new(accounts.clone())); - p.step_duration = 4; + p.step_durations = [(0, 4)].to_vec().into_iter().collect(); p.empty_steps_transition = 0; p.maximum_empty_steps = 0; }); @@ -2544,7 +2688,7 @@ mod tests { let (_spec, tap, accounts) = setup_empty_steps(); let engine = build_aura(|p| { p.validators = Box::new(SimpleList::new(accounts.clone())); - p.step_duration = 4; + p.step_durations = [(0, 4)].to_vec().into_iter().collect(); p.empty_steps_transition = 0; p.maximum_empty_steps = 0; }); diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 06f1efe7658..597ee6d3d4e 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -270,14 +270,12 @@ where ClientIoMessage::TakeSnapshot(num) => { let client = self.client.clone(); let snapshot = self.snapshot.clone(); - let res = thread::Builder::new().name("Periodic Snapshot".into()).spawn(move || { if let Err(e) = snapshot.take_snapshot(&*client, num) { match e { EthcoreError::Snapshot(SnapshotError::SnapshotAborted) => info!("Snapshot aborted"), _ => warn!("Failed to take snapshot at block #{}: {}", num, e), } - } }); diff --git a/ethcore/snapshot/Cargo.toml b/ethcore/snapshot/Cargo.toml index 882c9c5c91c..00b9ab6ea10 100644 --- a/ethcore/snapshot/Cargo.toml +++ b/ethcore/snapshot/Cargo.toml @@ -33,6 +33,7 @@ rand_xorshift = "0.2" parking_lot = "0.9" rlp = "0.4.2" rlp_derive = { path = "../../util/rlp-derive" } +scopeguard = "1.0.0" snappy = { package = "parity-snappy", version ="0.1.0" } state-db = { path = "../state-db" } trie-db = "0.15.0" diff --git a/ethcore/snapshot/snapshot-tests/src/account.rs b/ethcore/snapshot/snapshot-tests/src/account.rs index 09707c31156..fd1e5941bfa 100644 --- a/ethcore/snapshot/snapshot-tests/src/account.rs +++ b/ethcore/snapshot/snapshot-tests/src/account.rs @@ -48,7 +48,7 @@ fn encoding_basic() { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let p = Progress::default(); + let p = Progress::new(); let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::from_hash(db.as_hash_db(), keccak(addr)), &mut Default::default(), usize::max_value(), usize::max_value(), &p).unwrap(); let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap(); assert_eq!(from_fat_rlp(&mut AccountDBMut::from_hash(db.as_hash_db_mut(), keccak(addr)), fat_rlp, H256::zero()).unwrap().0, account); @@ -69,7 +69,7 @@ fn encoding_version() { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let p = Progress::default(); + let p = Progress::new(); let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::from_hash(db.as_hash_db(), keccak(addr)), &mut Default::default(), usize::max_value(), usize::max_value(), &p).unwrap(); let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap(); assert_eq!(from_fat_rlp(&mut AccountDBMut::from_hash(db.as_hash_db_mut(), keccak(addr)), fat_rlp, H256::zero()).unwrap().0, account); @@ -96,7 +96,7 @@ fn encoding_storage() { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let p = Progress::default(); + let p = Progress::new(); let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::from_hash(db.as_hash_db(), keccak(addr)), &mut Default::default(), usize::max_value(), usize::max_value(), &p).unwrap(); let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap(); @@ -124,7 +124,7 @@ fn encoding_storage_split() { let thin_rlp = ::rlp::encode(&account); assert_eq!(::rlp::decode::(&thin_rlp).unwrap(), account); - let p = Progress::default(); + let p = Progress::new(); let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::from_hash(db.as_hash_db(), keccak(addr)), &mut Default::default(), 500, 1000, &p).unwrap(); let mut root = KECCAK_NULL_RLP; let mut restored_account = None; @@ -170,8 +170,8 @@ fn encoding_code() { }; let mut used_code = HashSet::new(); - let p1 = Progress::default(); - let p2 = Progress::default(); + let p1 = Progress::new(); + let p2 = Progress::new(); let fat_rlp1 = to_fat_rlps(&keccak(&addr1), &account1, &AccountDB::from_hash(db.as_hash_db(), keccak(addr1)), &mut used_code, usize::max_value(), usize::max_value(), &p1).unwrap(); let fat_rlp2 = to_fat_rlps(&keccak(&addr2), &account2, &AccountDB::from_hash(db.as_hash_db(), keccak(addr2)), &mut used_code, usize::max_value(), usize::max_value(), &p2).unwrap(); assert_eq!(used_code.len(), 1); diff --git a/ethcore/snapshot/snapshot-tests/src/helpers.rs b/ethcore/snapshot/snapshot-tests/src/helpers.rs index afc4979068d..0c419dd71bb 100644 --- a/ethcore/snapshot/snapshot-tests/src/helpers.rs +++ b/ethcore/snapshot/snapshot-tests/src/helpers.rs @@ -27,7 +27,8 @@ use client_traits::ChainInfo; use common_types::{ ids::BlockId, basic_account::BasicAccount, - errors::EthcoreError + errors::EthcoreError, + snapshot::Progress, }; use engine::Engine; use ethcore::client::Client; @@ -145,7 +146,7 @@ pub fn snap(client: &Client) -> (Box, TempDir) { let tempdir = TempDir::new("").unwrap(); let path = tempdir.path().join("file"); let writer = PackedWriter::new(&path).unwrap(); - let progress = Default::default(); + let progress = Progress::new(); let hash = client.chain_info().best_block_hash; client.take_snapshot(writer, BlockId::Hash(hash), &progress).unwrap(); diff --git a/ethcore/snapshot/snapshot-tests/src/proof_of_work.rs b/ethcore/snapshot/snapshot-tests/src/proof_of_work.rs index 81dcfe2cd5b..9d01432fff3 100644 --- a/ethcore/snapshot/snapshot-tests/src/proof_of_work.rs +++ b/ethcore/snapshot/snapshot-tests/src/proof_of_work.rs @@ -74,7 +74,7 @@ fn chunk_and_restore(amount: u64) { &bc, best_hash, &writer, - &Progress::default() + &Progress::new() ).unwrap(); let manifest = ManifestData { diff --git a/ethcore/snapshot/snapshot-tests/src/service.rs b/ethcore/snapshot/snapshot-tests/src/service.rs index b2e7a98256f..ebedd5472c9 100644 --- a/ethcore/snapshot/snapshot-tests/src/service.rs +++ b/ethcore/snapshot/snapshot-tests/src/service.rs @@ -278,7 +278,7 @@ fn keep_ancient_blocks() { &bc, best_hash, &writer, - &Progress::default() + &Progress::new() ).unwrap(); let state_db = client.state_db().journal_db().boxed_clone(); let start_header = bc.block_header_data(&best_hash).unwrap(); @@ -287,7 +287,7 @@ fn keep_ancient_blocks() { state_db.as_hash_db(), &state_root, &writer, - &Progress::default(), + &Progress::new(), None, 0 ).unwrap(); diff --git a/ethcore/snapshot/snapshot-tests/src/state.rs b/ethcore/snapshot/snapshot-tests/src/state.rs index 4cccd0d82e9..ef905796404 100644 --- a/ethcore/snapshot/snapshot-tests/src/state.rs +++ b/ethcore/snapshot/snapshot-tests/src/state.rs @@ -62,7 +62,7 @@ fn snap_and_restore() { let mut state_hashes = Vec::new(); for part in 0..SNAPSHOT_SUBPARTS { - let mut hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), Some(part), 0).unwrap(); + let mut hashes = chunk_state(&old_db, &state_root, &writer, &Progress::new(), Some(part), 0).unwrap(); state_hashes.append(&mut hashes); } @@ -133,7 +133,7 @@ fn get_code_from_prev_chunk() { let mut make_chunk = |acc, hash| { let mut db = journaldb::new_memory_db(); AccountDBMut::from_hash(&mut db, hash).insert(EMPTY_PREFIX, &code[..]); - let p = Progress::default(); + let p = Progress::new(); let fat_rlp = to_fat_rlps(&hash, &acc, &AccountDB::from_hash(&db, hash), &mut used_code, usize::max_value(), usize::max_value(), &p).unwrap(); let mut stream = RlpStream::new_list(1); stream.append_raw(&fat_rlp[0], 1); @@ -178,7 +178,7 @@ fn checks_flag() { let state_root = producer.state_root(); let writer = Mutex::new(PackedWriter::new(&snap_file).unwrap()); - let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), None, 0).unwrap(); + let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::new(), None, 0).unwrap(); writer.into_inner().finish(ManifestData { version: 2, diff --git a/ethcore/snapshot/snapshot-tests/src/watcher.rs b/ethcore/snapshot/snapshot-tests/src/watcher.rs index d7cf35ced3e..95e932a2a35 100644 --- a/ethcore/snapshot/snapshot-tests/src/watcher.rs +++ b/ethcore/snapshot/snapshot-tests/src/watcher.rs @@ -41,8 +41,8 @@ impl Oracle for TestOracle { struct TestBroadcast(Option); impl Broadcast for TestBroadcast { - fn take_at(&self, num: Option) { - if num != self.0 { + fn request_snapshot_at(&self, num: u64) { + if Some(num) != self.0 { panic!("Watcher broadcast wrong number. Expected {:?}, found {:?}", self.0, num); } } diff --git a/ethcore/snapshot/src/consensus/work.rs b/ethcore/snapshot/src/consensus/work.rs index fede7e9d624..819e95ca063 100644 --- a/ethcore/snapshot/src/consensus/work.rs +++ b/ethcore/snapshot/src/consensus/work.rs @@ -178,7 +178,7 @@ impl<'a> PowWorker<'a> { let parent_hash = last_header.parent_hash(); let parent_total_difficulty = last_details.total_difficulty - last_header.difficulty(); - trace!(target: "snapshot", "parent last written block: {}", parent_hash); + trace!(target: "snapshot", "parent last written block: #{}/{}", parent_number, parent_hash); let num_entries = self.rlps.len(); let mut rlp_stream = RlpStream::new_list(3 + num_entries); diff --git a/ethcore/snapshot/src/lib.rs b/ethcore/snapshot/src/lib.rs index e6797a661a9..406aeeddb93 100644 --- a/ethcore/snapshot/src/lib.rs +++ b/ethcore/snapshot/src/lib.rs @@ -129,35 +129,34 @@ pub fn take_snapshot( let state_root = start_header.state_root(); let block_number = start_header.number(); - info!("Taking snapshot starting at block {}", block_number); - + info!("Taking snapshot starting at block #{}/{:?}", block_number, block_hash); let version = chunker.current_version(); let writer = Mutex::new(writer); let (state_hashes, block_hashes) = thread::scope(|scope| -> Result<(Vec, Vec), Error> { let writer = &writer; - let block_guard = scope.spawn(move |_| { + let tb = scope.builder().name("Snapshot Worker - Blocks".to_string()); + let block_guard = tb.spawn(move |_| { chunk_secondary(chunker, chain, block_hash, writer, p) - }); + })?; // The number of threads must be between 1 and SNAPSHOT_SUBPARTS assert!(processing_threads >= 1, "Cannot use less than 1 threads for creating snapshots"); - let num_threads: usize = cmp::min(processing_threads, SNAPSHOT_SUBPARTS); + let num_threads = cmp::min(processing_threads, SNAPSHOT_SUBPARTS); info!(target: "snapshot", "Using {} threads for Snapshot creation.", num_threads); - let mut state_guards = Vec::with_capacity(num_threads as usize); + let mut state_guards = Vec::with_capacity(num_threads); for thread_idx in 0..num_threads { - let state_guard = scope.spawn(move |_| -> Result, Error> { + let tb = scope.builder().name(format!("Snapshot Worker #{} - State", thread_idx).to_string()); + let state_guard = tb.spawn(move |_| -> Result, Error> { let mut chunk_hashes = Vec::new(); - for part in (thread_idx..SNAPSHOT_SUBPARTS).step_by(num_threads) { - debug!(target: "snapshot", "Chunking part {} in thread {}", part, thread_idx); + debug!(target: "snapshot", "Chunking part {} of the state at {} in thread {}", part, block_number, thread_idx); let mut hashes = chunk_state(state_db, &state_root, writer, p, Some(part), thread_idx)?; chunk_hashes.append(&mut hashes); } - Ok(chunk_hashes) - }); + })?; state_guards.push(state_guard); } @@ -169,7 +168,8 @@ pub fn take_snapshot( state_hashes.extend(part_state_hashes); } - debug!(target: "snapshot", "Took a snapshot of {} accounts", p.accounts.load(Ordering::SeqCst)); + info!("Took a snapshot at #{} of {} accounts", block_number, p.accounts()); + Ok((state_hashes, block_hashes)) }).expect("Sub-thread never panics; qed")?; @@ -218,7 +218,7 @@ pub fn chunk_secondary<'a>( trace!(target: "snapshot", "wrote secondary chunk. hash: {:x}, size: {}, uncompressed size: {}", hash, size, raw_data.len()); - progress.size.fetch_add(size as u64, Ordering::SeqCst); + progress.update(0, size); chunk_hashes.push(hash); Ok(()) }; @@ -275,8 +275,7 @@ impl<'a> StateChunker<'a> { self.writer.lock().write_state_chunk(hash, compressed)?; trace!(target: "snapshot", "Thread {} wrote state chunk. size: {}, uncompressed size: {}", self.thread_idx, compressed_size, raw_data.len()); - self.progress.accounts.fetch_add(num_entries, Ordering::SeqCst); - self.progress.size.fetch_add(compressed_size as u64, Ordering::SeqCst); + self.progress.update(num_entries, compressed_size); self.hashes.push(hash); self.cur_size = 0; @@ -327,7 +326,7 @@ pub fn chunk_state<'a>( if let Some(part) = part { assert!(part < 16, "Wrong chunk state part number (must be <16) in snapshot creation."); - let part_offset = MAX_SNAPSHOT_SUBPARTS / SNAPSHOT_SUBPARTS; + let part_offset = MAX_SNAPSHOT_SUBPARTS / SNAPSHOT_SUBPARTS; // 16 let mut seek_from = vec![0; 32]; seek_from[0] = (part * part_offset) as u8; account_iter.seek(&seek_from)?; @@ -349,7 +348,15 @@ pub fn chunk_state<'a>( let account = ::rlp::decode(&*account_data)?; let account_db = AccountDB::from_hash(db, account_key_hash); - let fat_rlps = account::to_fat_rlps(&account_key_hash, &account, &account_db, &mut used_code, PREFERRED_CHUNK_SIZE - chunker.chunk_size(), PREFERRED_CHUNK_SIZE, progress)?; + let fat_rlps = account::to_fat_rlps( + &account_key_hash, + &account, + &account_db, + &mut used_code, + PREFERRED_CHUNK_SIZE - chunker.chunk_size(), + PREFERRED_CHUNK_SIZE, + progress + )?; for (i, fat_rlp) in fat_rlps.into_iter().enumerate() { if i > 0 { chunker.write_chunk()?; diff --git a/ethcore/snapshot/src/service.rs b/ethcore/snapshot/src/service.rs index 141a32360c9..da84482db71 100644 --- a/ethcore/snapshot/src/service.rs +++ b/ethcore/snapshot/src/service.rs @@ -39,7 +39,7 @@ use ethcore_io::IoChannel; use journaldb::Algorithm; use keccak_hash::keccak; use kvdb::DBTransaction; -use log::{error, info, trace, warn}; +use log::{debug, error, info, trace, warn}; use parking_lot::{Mutex, RwLock, RwLockReadGuard}; use snappy; use trie_db::TrieError; @@ -212,7 +212,7 @@ impl Restoration { } self.guard.disarm(); - trace!(target: "snapshot", "restoration finalised correctly"); + trace!(target: "snapshot", "Restoration finalised correctly"); Ok(()) } @@ -280,7 +280,7 @@ impl Service where C: SnapshotClient + ChainInfo { state_chunks: AtomicUsize::new(0), block_chunks: AtomicUsize::new(0), client: params.client, - progress: Default::default(), + progress: Progress::new(), taking_snapshot: AtomicBool::new(false), restoring_snapshot: AtomicBool::new(false), }; @@ -413,7 +413,10 @@ impl Service where C: SnapshotClient + ChainInfo { Some(x) => x, None => return Ok(0), }; - + info!(target: "snapshot", "Migrating blocks from old db to new. Start: #{}/{:?}, Target: #{}/{:?}", + self.client.block_number(BlockId::Hash(start_hash)).unwrap_or_default(), start_hash, + self.client.block_number(BlockId::Hash(target_hash)).unwrap_or_default(), target_hash, + ); let mut batch = DBTransaction::new(); let mut parent_hash = start_hash; while parent_hash != target_hash { @@ -455,10 +458,10 @@ impl Service where C: SnapshotClient + ChainInfo { next_chain.commit(); next_db.key_value().flush().expect("DB flush failed."); batch = DBTransaction::new(); - } - if block_number % 10_000 == 0 { - info!(target: "snapshot", "Block restoration at #{}", block_number); + if block_number % 10_000 == 0 { + info!(target: "snapshot", "Block restoration at #{}", block_number); + } } } @@ -483,11 +486,13 @@ impl Service where C: SnapshotClient + ChainInfo { if self.progress.done() || !self.taking_snapshot.load(Ordering::SeqCst) { return } let p = &self.progress; - info!("Snapshot: {} accounts {} blocks {} bytes", p.accounts(), p.blocks(), p.size()); + info!("Snapshot: {} accounts, {} blocks, {} bytes", p.accounts(), p.blocks(), p.bytes()); + let rate = p.rate(); + debug!(target: "snapshot", "Current progress rate: {:.0} acc/s, {:.0} bytes/s (compressed)", rate.0, rate.1); } /// Take a snapshot at the block with the given number. - /// calling this while a restoration is in progress or vice versa + /// Calling this while a restoration is in progress or vice versa /// will lead to a race condition where the first one to finish will /// have their produced snapshot overwritten. pub fn take_snapshot(&self, client: &C, num: u64) -> Result<(), Error> { @@ -497,45 +502,40 @@ impl Service where C: SnapshotClient + ChainInfo { } info!("Taking snapshot at #{}", num); - self.progress.reset(); - - let temp_dir = self.temp_snapshot_dir(); - let snapshot_dir = self.snapshot_dir(); + { + scopeguard::defer! {{ + self.taking_snapshot.store(false, Ordering::SeqCst); + }} + let start_time = std::time::Instant::now(); + self.progress.reset(); + + let temp_dir = self.temp_snapshot_dir(); + let snapshot_dir = self.snapshot_dir(); - let _ = fs::remove_dir_all(&temp_dir); + let _ = fs::remove_dir_all(&temp_dir); // expected to fail - let writer = LooseWriter::new(temp_dir.clone())?; + let writer = LooseWriter::new(temp_dir.clone())?; - let guard = Guard::new(temp_dir.clone()); - let res = client.take_snapshot(writer, BlockId::Number(num), &self.progress); - self.taking_snapshot.store(false, Ordering::SeqCst); - if let Err(e) = res { - if client.chain_info().best_block_number >= num + client.pruning_history() { - // The state we were snapshotting was pruned before we could finish. - info!("Periodic snapshot failed: block state pruned. Run with a longer `--pruning-history` or with `--no-periodic-snapshot`"); - return Err(e); - } else { - return Err(e); - } - } + let guard = Guard::new(temp_dir.clone()); + let _ = client.take_snapshot(writer, BlockId::Number(num), &self.progress)?; + info!("Finished taking snapshot at #{}, in {:.0?}", num, start_time.elapsed()); - info!("Finished taking snapshot at #{}", num); + // destroy the old snapshot reader. + let mut reader = self.reader.write(); + *reader = None; - let mut reader = self.reader.write(); + if snapshot_dir.exists() { + trace!(target: "snapshot", "Removing previous snapshot at {:?}", &snapshot_dir); + fs::remove_dir_all(&snapshot_dir)?; + } - // destroy the old snapshot reader. - *reader = None; + fs::rename(temp_dir, &snapshot_dir)?; + trace!(target: "snapshot", "Moved new snapshot into place at {:?}", &snapshot_dir); + *reader = Some(LooseReader::new(snapshot_dir)?); - if snapshot_dir.exists() { - fs::remove_dir_all(&snapshot_dir)?; + guard.disarm(); + Ok(()) } - - fs::rename(temp_dir, &snapshot_dir)?; - - *reader = Some(LooseReader::new(snapshot_dir)?); - - guard.disarm(); - Ok(()) } /// Initialize the restoration synchronously. @@ -654,13 +654,19 @@ impl Service where C: SnapshotClient + ChainInfo { Ok(()) } - /// Import a previous chunk at the given path. Returns whether the block was imported or not - fn import_prev_chunk(&self, restoration: &mut Option, manifest: &ManifestData, file: io::Result) -> Result { + /// Import a previous chunk at the given path. Returns whether the chunk was imported or not + fn import_prev_chunk( + &self, + restoration: &mut Option, + manifest: &ManifestData, + file: io::Result + ) -> Result { let file = file?; let path = file.path(); let mut file = File::open(path.clone())?; - let mut buffer = Vec::new(); + let filesize = file.metadata()?.len(); + let mut buffer = Vec::with_capacity(filesize as usize + 1); // +1 for EOF file.read_to_end(&mut buffer)?; let hash = keccak(&buffer); @@ -670,6 +676,7 @@ impl Service where C: SnapshotClient + ChainInfo { } else if manifest.state_hashes.contains(&hash) { true } else { + warn!(target: "snapshot", "Hash of the content of {:?} not present in the manifest block/state hashes.", path); return Ok(false); }; @@ -680,11 +687,10 @@ impl Service where C: SnapshotClient + ChainInfo { Ok(true) } - // finalize the restoration. this accepts an already-locked - // restoration as an argument -- so acquiring it again _will_ - // lead to deadlock. + // Finalize the restoration. This accepts an already-locked restoration as an argument -- so + // acquiring it again _will_ lead to deadlock. fn finalize_restoration(&self, rest: &mut Option) -> Result<(), Error> { - trace!(target: "snapshot", "finalizing restoration"); + trace!(target: "snapshot", "Finalizing restoration"); *self.status.lock() = RestorationStatus::Finalizing; let recover = rest.as_ref().map_or(false, |rest| rest.writer.is_some()); @@ -695,7 +701,7 @@ impl Service where C: SnapshotClient + ChainInfo { .unwrap_or(Ok(()))?; let migrated_blocks = self.migrate_blocks()?; - info!(target: "snapshot", "Migrated {} ancient blocks", migrated_blocks); + info!(target: "snapshot", "Migrated {} ancient blocks from the old DB", migrated_blocks); // replace the Client's database with the new one (restart the Client). self.client.restore_db(&*self.restoration_db().to_string_lossy())?; @@ -707,11 +713,11 @@ impl Service where C: SnapshotClient + ChainInfo { let snapshot_dir = self.snapshot_dir(); if snapshot_dir.exists() { - trace!(target: "snapshot", "removing old snapshot dir at {}", snapshot_dir.to_string_lossy()); + trace!(target: "snapshot", "Removing old snapshot dir at {}", snapshot_dir.to_string_lossy()); fs::remove_dir_all(&snapshot_dir)?; } - trace!(target: "snapshot", "copying restored snapshot files over"); + trace!(target: "snapshot", "Copying restored snapshot files over"); fs::rename(self.temp_recovery_dir(), &snapshot_dir)?; *reader = Some(LooseReader::new(snapshot_dir)?); diff --git a/ethcore/snapshot/src/traits.rs b/ethcore/snapshot/src/traits.rs index 4e064d20c59..21a15673e9d 100644 --- a/ethcore/snapshot/src/traits.rs +++ b/ethcore/snapshot/src/traits.rs @@ -136,7 +136,7 @@ pub trait SnapshotComponents: Send { /// Snapshot related functionality pub trait SnapshotClient: BlockChainClient + BlockInfo + DatabaseRestore + BlockChainReset { /// Take a snapshot at the given block. - /// If the ID given is "latest", this will default to 1000 blocks behind. + /// If the BlockId is 'Latest', this will default to 1000 blocks behind. fn take_snapshot( &self, writer: W, @@ -148,7 +148,7 @@ pub trait SnapshotClient: BlockChainClient + BlockInfo + DatabaseRestore + Block /// Helper trait for broadcasting a block to take a snapshot at. pub trait Broadcast: Send + Sync { /// Start a snapshot from the given block number. - fn take_at(&self, num: Option); + fn request_snapshot_at(&self, num: u64); } diff --git a/ethcore/snapshot/src/watcher.rs b/ethcore/snapshot/src/watcher.rs index d6d9bcef8c0..34ed5189bbd 100644 --- a/ethcore/snapshot/src/watcher.rs +++ b/ethcore/snapshot/src/watcher.rs @@ -49,16 +49,11 @@ impl Oracle for StandardOracle } impl Broadcast for Mutex>> { - fn take_at(&self, num: Option) { - let num = match num { - Some(n) => n, - None => return, - }; - - trace!(target: "snapshot_watcher", "Snapshot requested at block #{}", num); - + fn request_snapshot_at(&self, num: u64) { if let Err(e) = self.lock().send(ClientIoMessage::TakeSnapshot(num)) { - warn!("Snapshot watcher disconnected from IoService: {}", e); + warn!(target: "snapshot_watcher", "Snapshot watcher disconnected from IoService: {}", e); + } else { + trace!(target: "snapshot_watcher", "Snapshot requested at block #{}", num); } } } @@ -68,7 +63,10 @@ impl Broadcast for Mutex>> { pub struct Watcher { oracle: Box, broadcast: Box, + // How often we attempt to take a snapshot: only snapshot on blocknumbers that are multiples of + // `period`. Always set to `SNAPSHOT_PERIOD`, i.e. 5000. period: u64, + // Start snapshots `history` blocks from the tip. Always set to `SNAPSHOT_HISTORY`, i.e. 100. history: u64, } @@ -106,18 +104,22 @@ impl ChainNotify for Watcher { fn new_blocks(&self, new_blocks: NewBlocks) { if self.oracle.is_major_importing() || new_blocks.has_more_blocks_to_import { return } - trace!(target: "snapshot_watcher", "{} imported", new_blocks.imported.len()); - + // Decide if it's time for a snapshot: the highest of the imported blocks is a multiple of 5000? let highest = new_blocks.imported.into_iter() + // Convert block hashes to block numbers for all newly imported blocks .filter_map(|h| self.oracle.to_number(h)) - .filter(|&num| num >= self.period + self.history) - .map(|num| num - self.history) - .filter(|num| num % self.period == 0) + // Subtract `history` (i.e. `SNAPSHOT_HISTORY`, i.e. 100) from the block numbers to stay + // clear of reorgs. + .map(|num| num.saturating_sub(self.history) ) + // …filter out blocks that do not fall on the a multiple of `period`. This regulates the + // frequency of snapshots and ensures more snapshots are produced from similar points in + // the chain. + .filter(|num| num % self.period == 0 ) + // Pick newest of the candidates: this is where we want to snapshot from. .fold(0, ::std::cmp::max); - match highest { - 0 => self.broadcast.take_at(None), - _ => self.broadcast.take_at(Some(highest)), + if highest > 0 { + self.broadcast.request_snapshot_at(highest); } } } diff --git a/ethcore/spec/src/spec.rs b/ethcore/spec/src/spec.rs index 79f1bdd41b8..093e6905dbe 100644 --- a/ethcore/spec/src/spec.rs +++ b/ethcore/spec/src/spec.rs @@ -252,7 +252,7 @@ impl fmt::Display for SpecHardcodedSync { writeln!(f, "{{")?; writeln!(f, r#"header": "{:?},"#, self.header)?; writeln!(f, r#"total_difficulty": "{:?},"#, self.total_difficulty)?; - writeln!(f, r#"chts": {:#?}"#, self.chts.iter().map(|x| format!(r#"{}"#, x)).collect::>())?; + writeln!(f, r#"chts": {:#?}"#, self.chts.iter().map(|x| format!(r#"{:?}"#, x)).collect::>())?; writeln!(f, "}}") } } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 4527dba8152..c1c450486fe 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -20,7 +20,7 @@ use std::convert::TryFrom; use std::io::{BufRead, BufReader}; use std::str::from_utf8; use std::sync::{Arc, Weak}; -use std::sync::atomic::{AtomicBool, AtomicI64, Ordering as AtomicOrdering}; +use std::sync::atomic::{AtomicBool, AtomicI64, Ordering as AtomicOrdering, Ordering, AtomicU64}; use std::time::{Duration, Instant}; use ansi_term::Colour; @@ -204,6 +204,9 @@ pub struct Client { /// Database pruning strategy to use for StateDB pruning: journaldb::Algorithm, + /// Don't prune the state we're currently snapshotting + snapshotting_at: AtomicU64, + /// Client uses this to store blocks, traces, etc. db: RwLock>, @@ -780,6 +783,7 @@ impl Client { tracedb, engine, pruning: config.pruning.clone(), + snapshotting_at: AtomicU64::new(0), db: RwLock::new(db.clone()), state_db: RwLock::new(state_db), report: RwLock::new(Default::default()), @@ -964,13 +968,15 @@ impl Client { return Ok(()) } - let number = match state_db.journal_db().latest_era() { + let latest_era = match state_db.journal_db().latest_era() { Some(n) => n, None => return Ok(()), }; - // prune all ancient eras until we're below the memory target, - // but have at least the minimum number of states. + // Prune all ancient eras until we're below the memory target (default: 32Mb), + // but have at least the minimum number of states, i.e. `history`. + // If a snapshot is under way, no pruning happens and memory consumption is allowed to + // increase above the memory target until the snapshot has finished. loop { let needs_pruning = state_db.journal_db().journal_size() >= self.config.history_mem; @@ -979,17 +985,27 @@ impl Client { } match state_db.journal_db().earliest_era() { - Some(era) if era + self.history <= number => { - trace!(target: "client", "Pruning state for ancient era {}", era); - match chain.block_hash(era) { + Some(earliest_era) if earliest_era + self.history <= latest_era => { + let freeze_at = self.snapshotting_at.load(Ordering::SeqCst); + if freeze_at > 0 && freeze_at == earliest_era { + // Note: journal_db().mem_used() can be used for a more accurate memory + // consumption measurement but it can be expensive so sticking with the + // faster `journal_size()` instead. + trace!(target: "pruning", "Pruning is paused at era {} (snapshot under way); earliest era={}, latest era={}, journal_size={} – Not pruning.", + freeze_at, earliest_era, latest_era, state_db.journal_db().journal_size()); + break; + } + trace!(target: "pruning", "Pruning state for ancient era #{}; latest era={}, journal_size={}", + earliest_era, latest_era, state_db.journal_db().journal_size()); + match chain.block_hash(earliest_era) { Some(ancient_hash) => { let mut batch = DBTransaction::new(); - state_db.mark_canonical(&mut batch, era, &ancient_hash)?; + state_db.mark_canonical(&mut batch, earliest_era, &ancient_hash)?; self.db.read().key_value().write_buffered(batch); state_db.journal_db().flush(); } None => - debug!(target: "client", "Missing expected hash for block {}", era), + debug!(target: "pruning", "Missing expected hash for block {}", earliest_era), } } _ => break, // means that every era is kept, no pruning necessary. @@ -2533,48 +2549,61 @@ impl SnapshotClient for Client { return Err(EthcoreError::Snapshot(SnapshotError::SnapshotsUnsupported)); } let db = self.state_db.read().journal_db().boxed_clone(); - let best_block_number = self.chain_info().best_block_number; - let block_number = self.block_number(at).ok_or_else(|| SnapshotError::InvalidStartingBlock(at))?; - if db.is_prunable() && self.pruning_info().earliest_state > block_number { + let block_number = self.block_number(at).ok_or_else(|| SnapshotError::InvalidStartingBlock(at))?; + let earliest_era = db.earliest_era().unwrap_or(0); + if db.is_prunable() && earliest_era > block_number { return Err(SnapshotError::OldBlockPrunedDB.into()); } - let history = cmp::min(self.history, 1000); - let start_hash = match at { + let (actual_block_nr, block_hash) = match at { BlockId::Latest => { - let start_num = match db.earliest_era() { - Some(era) => cmp::max(era, best_block_number.saturating_sub(history)), - None => best_block_number.saturating_sub(history), - }; + // Start `self.history` blocks from the best block, but no further back than 1000 + // blocks (or earliest era, whichever is greatest). + let history = cmp::min(self.history, 1000); + let best_block_number = self.chain_info().best_block_number; + let start_num = cmp::max(earliest_era, best_block_number.saturating_sub(history)); match self.block_hash(BlockId::Number(start_num)) { - Some(h) => h, - None => return Err(SnapshotError::InvalidStartingBlock(at).into()), + Some(hash) => (start_num, hash), + None => { + error!(target: "snapshot", "Can't take snapshot at {:?}: missing hash for the starting block #{}", at, start_num); + return Err(SnapshotError::InvalidStartingBlock(at).into()) + }, } } _ => match self.block_hash(at) { - Some(hash) => hash, + Some(hash) => (block_number, hash), None => return Err(SnapshotError::InvalidStartingBlock(at).into()), }, }; let processing_threads = self.config.snapshot.processing_threads; - let chunker = snapshot::chunker(self.engine.snapshot_mode()).ok_or_else(|| SnapshotError::SnapshotsUnsupported)?; - snapshot::take_snapshot( - chunker, - &self.chain.read(), - start_hash, - db.as_hash_db(), - writer, - p, - processing_threads, - )?; - Ok(()) + trace!(target: "snapshot", "Snapshot requested at block {:?}. Using block #{}/{:?}. Earliest block: #{}, earliest state era #{}. Using {} threads.", + at, actual_block_nr, block_hash, self.pruning_info().earliest_chain, earliest_era, processing_threads, + ); + // Stop pruning from happening while the snapshot is under way. + self.snapshotting_at.store(actual_block_nr, Ordering::SeqCst); + { + scopeguard::defer! {{ + trace!(target: "snapshot", "Re-enabling pruning."); + self.snapshotting_at.store(0, Ordering::SeqCst) + }}; + let chunker = snapshot::chunker(self.engine.snapshot_mode()).ok_or_else(|| SnapshotError::SnapshotsUnsupported)?; + // Spawn threads and take snapshot + snapshot::take_snapshot( + chunker, + &self.chain.read(), + block_hash, + db.as_hash_db(), + writer, + p, + processing_threads, + )?; + Ok(()) + } } - - } impl ImportExportBlocks for Client { diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index 5a1c2b87e75..23104c48b56 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -90,7 +90,7 @@ pub struct ClientConfig { pub history: u64, /// Ideal memory usage for state pruning history. pub history_mem: usize, - /// Check seal valididity on block import + /// Check seal validity on block import pub check_seal: bool, /// Maximal number of transactions queued for verification in a separate thread. pub transaction_verification_queue_size: usize, diff --git a/ethcore/types/Cargo.toml b/ethcore/types/Cargo.toml index 509b9d13dd7..dd1dff2fb5a 100644 --- a/ethcore/types/Cargo.toml +++ b/ethcore/types/Cargo.toml @@ -15,6 +15,7 @@ parity-bytes = "0.1" parity-crypto = { version = "0.4.2", features = ["publickey"] } parity-util-mem = "0.2.0" parity-snappy = "0.1" +parking_lot = "0.9.0" patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } rlp = "0.4.0" rlp_derive = { path = "../../util/rlp-derive" } diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 58ca86cae94..ab17b8837db 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -40,6 +40,7 @@ extern crate parity_crypto; #[macro_use] extern crate derive_more; extern crate keccak_hash as hash; +extern crate parking_lot; extern crate parity_bytes as bytes; extern crate patricia_trie_ethereum as ethtrie; extern crate rlp; diff --git a/ethcore/types/src/snapshot.rs b/ethcore/types/src/snapshot.rs index ea2a8a1ebe7..8f49a11ebaa 100644 --- a/ethcore/types/src/snapshot.rs +++ b/ethcore/types/src/snapshot.rs @@ -16,11 +16,13 @@ //! Snapshot type definitions -use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU64, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::time::Instant; +use bytes::Bytes; use ethereum_types::H256; +use parking_lot::RwLock; use rlp::{Rlp, RlpStream, DecoderError}; -use bytes::Bytes; /// Modes of snapshotting pub enum Snapshotting { @@ -39,31 +41,53 @@ pub enum Snapshotting { } /// A progress indicator for snapshots. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Progress { /// Number of accounts processed so far - pub accounts: AtomicUsize, + accounts: AtomicUsize, + // Number of accounts processed at last tick. + prev_accounts: AtomicUsize, /// Number of blocks processed so far pub blocks: AtomicUsize, /// Size in bytes of a all compressed chunks processed so far - pub size: AtomicU64, + bytes: AtomicUsize, + // Number of bytes processed at last tick. + prev_bytes: AtomicUsize, /// Signals that the snapshotting process is completed pub done: AtomicBool, /// Signal snapshotting process to abort pub abort: AtomicBool, + + last_tick: RwLock, } impl Progress { + /// Create a new progress tracker. + pub fn new() -> Progress { + Progress { + accounts: AtomicUsize::new(0), + prev_accounts: AtomicUsize::new(0), + blocks: AtomicUsize::new(0), + bytes: AtomicUsize::new(0), + prev_bytes: AtomicUsize::new(0), + abort: AtomicBool::new(false), + done: AtomicBool::new(false), + last_tick: RwLock::new(Instant::now()), + } + } + /// Reset the progress. pub fn reset(&self) { self.accounts.store(0, Ordering::Release); self.blocks.store(0, Ordering::Release); - self.size.store(0, Ordering::Release); + self.bytes.store(0, Ordering::Release); self.abort.store(false, Ordering::Release); // atomic fence here to ensure the others are written first? // logs might very rarely get polluted if not. self.done.store(false, Ordering::Release); + + *self.last_tick.write() = Instant::now(); } /// Get the number of accounts snapshotted thus far. @@ -73,10 +97,37 @@ impl Progress { pub fn blocks(&self) -> usize { self.blocks.load(Ordering::Acquire) } /// Get the written size of the snapshot in bytes. - pub fn size(&self) -> u64 { self.size.load(Ordering::Acquire) } + pub fn bytes(&self) -> usize { self.bytes.load(Ordering::Acquire) } /// Whether the snapshot is complete. pub fn done(&self) -> bool { self.done.load(Ordering::Acquire) } + + /// Return the progress rate over the last tick (i.e. since last update). + pub fn rate(&self) -> (f64, f64) { + let last_tick = *self.last_tick.read(); + let dt = last_tick.elapsed().as_secs_f64(); + if dt < 1.0 { + return (0f64, 0f64); + } + let delta_acc = self.accounts.load(Ordering::Relaxed) + .saturating_sub(self.prev_accounts.load(Ordering::Relaxed)); + let delta_bytes = self.bytes.load(Ordering::Relaxed) + .saturating_sub(self.prev_bytes.load(Ordering::Relaxed)); + (delta_acc as f64 / dt, delta_bytes as f64 / dt) + } + + /// Update state progress counters and set the last tick. + pub fn update(&self, accounts_delta: usize, bytes_delta: usize) { + *self.last_tick.write() = Instant::now(); + self.prev_accounts.store( + self.accounts.fetch_add(accounts_delta, Ordering::SeqCst), + Ordering::SeqCst + ); + self.prev_bytes.store( + self.bytes.fetch_add(bytes_delta, Ordering::SeqCst), + Ordering::SeqCst + ); + } } /// Manifest data. diff --git a/ipfs/Cargo.toml b/ipfs/Cargo.toml index 79ad7e26c93..adb42f9e5a0 100644 --- a/ipfs/Cargo.toml +++ b/ipfs/Cargo.toml @@ -12,8 +12,8 @@ common-types = { path = "../ethcore/types" } ethcore = { path = "../ethcore" } bytes = { package = "parity-bytes", version = "0.1"} ethereum-types = "0.8.0" -jsonrpc-core = "14.0.1" -http = { package = "jsonrpc-http-server", version = "14.0.1"} +jsonrpc-core = "14.0.3" +http = { package = "jsonrpc-http-server", version = "14.0.3"} rlp = "0.4.0" cid = "0.3" multihash = "0.8" diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 0a31203f62f..ba5ad63b39b 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -41,7 +41,7 @@ use std::collections::BTreeMap; use crate::{bytes::Bytes, hash::Address, uint::Uint}; use serde::Deserialize; -use super::ValidatorSet; +use super::{StepDuration, ValidatorSet}; /// Authority params deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -49,7 +49,7 @@ use super::ValidatorSet; #[serde(rename_all = "camelCase")] pub struct AuthorityRoundParams { /// Block duration, in seconds. - pub step_duration: Uint, + pub step_duration: StepDuration, /// Valid authorities pub validators: ValidatorSet, /// Starting step. Determined automatically if not specified. @@ -107,7 +107,7 @@ pub struct AuthorityRound { #[cfg(test)] mod tests { - use super::{Address, Uint}; + use super::{Address, Uint, StepDuration}; use ethereum_types::{U256, H160}; use crate::spec::{validator_set::ValidatorSet, authority_round::AuthorityRound}; use std::str::FromStr; @@ -129,7 +129,7 @@ mod tests { }"#; let deserialized: AuthorityRound = serde_json::from_str(s).unwrap(); - assert_eq!(deserialized.params.step_duration, Uint(U256::from(0x02))); + assert_eq!(deserialized.params.step_duration, StepDuration::Single(Uint(U256::from(2)))); assert_eq!( deserialized.params.validators, ValidatorSet::List(vec![Address(H160::from_str("c6d9d2cd449a754c494264e1809c50e34d64562b").unwrap())]), diff --git a/json/src/spec/mod.rs b/json/src/spec/mod.rs index e2569c28685..75b8014559c 100644 --- a/json/src/spec/mod.rs +++ b/json/src/spec/mod.rs @@ -32,6 +32,7 @@ pub mod null_engine; pub mod instant_seal; pub mod hardcoded_sync; pub mod clique; +pub mod step_duration; pub use self::account::Account; pub use self::builtin::{Builtin, Pricing, Linear}; @@ -49,3 +50,4 @@ pub use self::clique::{Clique, CliqueParams}; pub use self::null_engine::{NullEngine, NullEngineParams}; pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::hardcoded_sync::HardcodedSync; +pub use self::step_duration::StepDuration; diff --git a/json/src/spec/step_duration.rs b/json/src/spec/step_duration.rs new file mode 100644 index 00000000000..628e2dd7d23 --- /dev/null +++ b/json/src/spec/step_duration.rs @@ -0,0 +1,36 @@ +// Copyright 2015-2019 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 . + +//! Step duration configuration parameter + +use std::collections::BTreeMap; + +use serde::Deserialize; + +use crate::uint::Uint; + +/// Step duration can be specified either as a `Uint` (in seconds), in which case it will be +/// constant, or as a list of pairs consisting of a timestamp of type `Uint` and a duration, in +/// which case the duration of a step will be determined by a mapping arising from that list. +#[derive(Debug, PartialEq, Deserialize)] +#[serde(deny_unknown_fields)] +#[serde(untagged)] +pub enum StepDuration { + /// Duration of all steps. + Single(Uint), + /// Step duration transitions: a mapping of timestamp to step durations. + Transitions(BTreeMap), +} diff --git a/miner/stratum/Cargo.toml b/miner/stratum/Cargo.toml index 9fbb54f937d..971dd440049 100644 --- a/miner/stratum/Cargo.toml +++ b/miner/stratum/Cargo.toml @@ -8,8 +8,8 @@ authors = ["Parity Technologies "] [dependencies] ethereum-types = "0.8.0" keccak-hash = "0.4.0" -jsonrpc-core = "14.0.1" -jsonrpc-tcp-server = "14.0.1" +jsonrpc-core = "14.0.3" +jsonrpc-tcp-server = "14.0.3" log = "0.4" parking_lot = "0.9" diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 008da39ef38..a3fa2239524 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -33,7 +33,7 @@ use ethcore::{ }; use ethcore_service::ClientService; use cache::CacheConfig; -use informant::{Informant, FullNodeInformantData, MillisecondDuration}; +use informant::{Informant, FullNodeInformantData}; use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_bool}; use helpers::{to_client_config, execute_upgrades}; use dir::Directories; @@ -294,13 +294,13 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> { } client.flush_queue(); - let ms = timer.elapsed().as_milliseconds(); + let elapsed = timer.elapsed(); let report = client.report(); info!("Import completed in {} seconds, {} headers, {} hdr/s", - ms / 1000, + elapsed.as_secs(), report.blocks_imported, - (report.blocks_imported * 1000) as u64 / ms, + (report.blocks_imported as u128 * 1000) / elapsed.as_millis(), ); Ok(()) @@ -415,16 +415,16 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { user_defaults.save(&user_defaults_path)?; let report = client.report(); - - let ms = timer.elapsed().as_milliseconds(); + let elapsed = timer.elapsed(); + let ms = timer.elapsed().as_millis(); info!("Import completed in {} seconds, {} blocks, {} blk/s, {} transactions, {} tx/s, {} Mgas, {} Mgas/s", - ms / 1000, + elapsed.as_secs(), report.blocks_imported, - (report.blocks_imported * 1000) as u64 / ms, + (report.blocks_imported as u128 * 1000) / ms, report.transactions_applied, - (report.transactions_applied * 1000) as u64 / ms, + (report.transactions_applied as u128 * 1000) / ms, report.gas_processed / 1_000_000, - (report.gas_processed / (ms * 1000)).low_u64(), + report.gas_processed / (ms * 1000), ); Ok(()) } diff --git a/parity/export_hardcoded_sync.rs b/parity/export_hardcoded_sync.rs index ba01965c062..3d914f8537a 100644 --- a/parity/export_hardcoded_sync.rs +++ b/parity/export_hardcoded_sync.rs @@ -96,7 +96,7 @@ pub fn execute(cmd: ExportHsyncCmd) -> Result { let hs = service.client().read_hardcoded_sync() .map_err(|e| format!("Error reading hardcoded sync: {}", e))?; if let Some(hs) = hs { - Ok(format!("{}", hs)) + Ok(hs.to_string()) } else { Err("Error: cannot generate hardcoded sync because the database is empty.".into()) } diff --git a/parity/informant.rs b/parity/informant.rs index 38f02d45859..b53ffe14eff 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -14,14 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -extern crate ansi_term; -use self::ansi_term::Colour::{White, Yellow, Green, Cyan, Blue}; -use self::ansi_term::{Colour, Style}; - -use std::sync::{Arc}; +use std::sync::Arc; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::time::{Instant, Duration}; +use ansi_term::Colour::{White, Yellow, Green, Cyan, Blue}; +use ansi_term::{Colour, Style}; use atty; use ethcore::client::Client; use client_traits::{BlockInfo, ChainInfo, BlockChainClient, ChainNotify}; @@ -55,18 +53,6 @@ pub fn format_bytes(b: usize) -> String { } } -/// Something that can be converted to milliseconds. -pub trait MillisecondDuration { - /// Get the value in milliseconds. - fn as_milliseconds(&self) -> u64; -} - -impl MillisecondDuration for Duration { - fn as_milliseconds(&self) -> u64 { - self.as_secs() * 1000 + self.subsec_nanos() as u64 / 1_000_000 - } -} - #[derive(Default)] struct CacheSizes { sizes: ::std::collections::BTreeMap<&'static str, usize>, @@ -308,13 +294,13 @@ impl Informant { paint(White.bold(), format!("{}", chain_info.best_block_hash)), if self.target.executes_transactions() { format!("{} blk/s {} tx/s {} Mgas/s", - paint(Yellow.bold(), format!("{:7.2}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_milliseconds() as f64)), - paint(Yellow.bold(), format!("{:6.1}", (client_report.transactions_applied * 1000) as f64 / elapsed.as_milliseconds() as f64)), - paint(Yellow.bold(), format!("{:6.1}", (client_report.gas_processed / 1000).low_u64() as f64 / elapsed.as_milliseconds() as f64)) + paint(Yellow.bold(), format!("{:7.2}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_millis() as f64)), + paint(Yellow.bold(), format!("{:6.1}", (client_report.transactions_applied * 1000) as f64 / elapsed.as_millis() as f64)), + paint(Yellow.bold(), format!("{:6.1}", (client_report.gas_processed / 1000).low_u64() as f64 / elapsed.as_millis() as f64)) ) } else { format!("{} hdr/s", - paint(Yellow.bold(), format!("{:6.1}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_milliseconds() as f64)) + paint(Yellow.bold(), format!("{:6.1}", (client_report.blocks_imported * 1000) as f64 / elapsed.as_millis() as f64)) ) }, paint(Green.bold(), format!("{:5}", queue_info.unverified_queue_size)), @@ -401,7 +387,7 @@ impl ChainNotify for Informant { Colour::White.bold().paint(format!("{}", header_view.hash())), Colour::Yellow.bold().paint(format!("{}", block.transactions_count())), Colour::Yellow.bold().paint(format!("{:.2}", header_view.gas_used().low_u64() as f32 / 1000000f32)), - Colour::Purple.bold().paint(format!("{}", new_blocks.duration.as_milliseconds())), + Colour::Purple.bold().paint(format!("{}", new_blocks.duration.as_millis())), Colour::Blue.bold().paint(format!("{:.2}", size as f32 / 1024f32)), if skipped > 0 { format!(" + another {} block(s) containing {} tx(s)", diff --git a/parity/run.rs b/parity/run.rs index 891424eebb2..98781943134 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -68,10 +68,10 @@ use signer; use db; use registrar::RegistrarClient; -// how often to take periodic snapshots. +// How often we attempt to take a snapshot: only snapshot on blocknumbers that are multiples of this. const SNAPSHOT_PERIOD: u64 = 5000; -// how many blocks to wait before starting a periodic snapshot. +// Start snapshots `history` blocks from the tip. Should be smaller than `SNAPSHOT_HISTORY`. const SNAPSHOT_HISTORY: u64 = 100; // Number of minutes before a given gas price corpus should expire. diff --git a/parity/snapshot_cmd.rs b/parity/snapshot_cmd.rs index bd41400a3cd..8a9157ad62c 100644 --- a/parity/snapshot_cmd.rs +++ b/parity/snapshot_cmd.rs @@ -257,18 +257,18 @@ impl SnapshotCommand { let writer = PackedWriter::new(&file_path) .map_err(|e| format!("Failed to open snapshot writer: {}", e))?; - let progress = Arc::new(Progress::default()); + let progress = Arc::new(Progress::new()); let p = progress.clone(); let informant_handle = ::std::thread::spawn(move || { ::std::thread::sleep(Duration::from_secs(5)); let mut last_size = 0; while !p.done() { - let cur_size = p.size(); + let cur_size = p.bytes(); if cur_size != last_size { last_size = cur_size; let bytes = ::informant::format_bytes(cur_size as usize); - info!("Snapshot: {} accounts {} blocks {}", p.accounts(), p.blocks(), bytes); + info!("Snapshot: {} accounts (state), {} blocks, {} bytes", p.accounts(), p.blocks(), bytes); } ::std::thread::sleep(Duration::from_secs(5)); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 3e927f699b0..3b8abd49484 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -28,12 +28,12 @@ tokio-timer = "0.1" transient-hashmap = "0.4" itertools = "0.5" -jsonrpc-core = "14.0.1" -jsonrpc-derive = "14.0.1" -jsonrpc-http-server = "14.0.1" -jsonrpc-ws-server = "14.0.1" -jsonrpc-ipc-server = "14.0.1" -jsonrpc-pubsub = "14.0.1" +jsonrpc-core = "14.0.3" +jsonrpc-derive = "14.0.3" +jsonrpc-http-server = "14.0.3" +jsonrpc-ws-server = "14.0.3" +jsonrpc-ipc-server = "14.0.3" +jsonrpc-pubsub = "14.0.3" client-traits = { path = "../ethcore/client-traits" } common-types = { path = "../ethcore/types" } diff --git a/secret-store/Cargo.toml b/secret-store/Cargo.toml index 24af2a798f6..37a8e1a5fae 100644 --- a/secret-store/Cargo.toml +++ b/secret-store/Cargo.toml @@ -38,7 +38,7 @@ tokio = "0.1.22" tokio-io = "0.1" tokio-service = "0.1" url = "2.1.0" -jsonrpc-server-utils = "14.0.1" +jsonrpc-server-utils = "14.0.3" [dev-dependencies] env_logger = "0.5" diff --git a/util/journaldb/src/lib.rs b/util/journaldb/src/lib.rs index 0024b3638c0..739c25807a1 100644 --- a/util/journaldb/src/lib.rs +++ b/util/journaldb/src/lib.rs @@ -84,8 +84,8 @@ pub trait JournalDB: HashDB { /// Get backing database. fn backing(&self) -> &Arc; - /// Clear internal strucutres. This should called after changes have been written - /// to the backing strage + /// Clear internal structure. This should be called after changes have been written + /// to the backing storage. fn flush(&self) {} /// Consolidate all the insertions and deletions in the given memory overlay. diff --git a/util/journaldb/src/overlayrecentdb.rs b/util/journaldb/src/overlayrecentdb.rs index 0c0f92d5eb0..6ea285cd173 100644 --- a/util/journaldb/src/overlayrecentdb.rs +++ b/util/journaldb/src/overlayrecentdb.rs @@ -228,10 +228,10 @@ impl OverlayRecentDB { JournalOverlay { backing_overlay: overlay, pending_overlay: HashMap::default(), - journal: journal, - latest_era: latest_era, - earliest_era: earliest_era, - cumulative_size: cumulative_size, + journal, + latest_era, + earliest_era, + cumulative_size, } } @@ -264,7 +264,6 @@ impl JournalDB for OverlayRecentDB { fn journal_size(&self) -> usize { self.journal_overlay.read().cumulative_size - } fn is_empty(&self) -> bool { @@ -351,7 +350,7 @@ impl JournalDB for OverlayRecentDB { let mut ops = 0; // apply old commits' details - if let Some(ref mut records) = journal_overlay.journal.get_mut(&end_era) { + if let Some(records) = journal_overlay.journal.get_mut(&end_era) { let mut canon_insertions: Vec<(H256, DBValue)> = Vec::new(); let mut canon_deletions: Vec = Vec::new(); let mut overlay_deletions: Vec = Vec::new();