diff --git a/Cargo.lock b/Cargo.lock index c14aada54..4dd27c688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,7 +79,7 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -130,7 +130,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -307,7 +307,10 @@ name = "bstr" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -358,6 +361,14 @@ name = "c_linked_list" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cast" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cc" version = "1.0.47" @@ -576,6 +587,42 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "criterion" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", + "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "criterion-plot" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-channel" version = "0.3.9" @@ -655,6 +702,26 @@ dependencies = [ "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "csv" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "csv-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ct-logs" version = "0.6.0" @@ -669,7 +736,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -708,7 +775,7 @@ dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -768,10 +835,11 @@ dependencies = [ ] [[package]] -name = "darwinia-ethereum-bridge" +name = "darwinia-eth-relay" version = "0.2.0" dependencies = [ "ethash 0.4.0 (git+https://github.com/hammeWang/ethash-rs.git?rev=70a4f078)", + "merkle-patricia-trie 0.1.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.4 (git+https://github.com/darwinia-network/parity-common.git)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1013,6 +1081,18 @@ dependencies = [ "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethbloom" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethbloom" version = "0.8.1" @@ -1026,6 +1106,19 @@ dependencies = [ "tiny-keccak 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethereum-types" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ethbloom 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethereum-types" version = "0.8.0" @@ -1039,6 +1132,14 @@ dependencies = [ "uint 0.8.2 (git+https://github.com/darwinia-network/parity-common.git)", ] +[[package]] +name = "ethereum-types-serialize" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "exit-future" version = "0.1.4" @@ -1078,7 +1179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1122,6 +1223,18 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixed-hash" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixed-hash" version = "0.5.1" @@ -1314,7 +1427,7 @@ dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1666,12 +1779,12 @@ dependencies = [ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1735,6 +1848,14 @@ dependencies = [ "rlp 0.4.4 (git+https://github.com/darwinia-network/parity-common.git)", ] +[[package]] +name = "impl-rlp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "impl-serde" version = "0.2.3" @@ -1758,7 +1879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1792,6 +1913,14 @@ name = "ipnet" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.4" @@ -1817,25 +1946,25 @@ dependencies = [ [[package]] name = "jsonrpc-client-transports" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 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-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1847,31 +1976,31 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-client-transports 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-derive" -version = "14.0.3" +version = "14.0.5" 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)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.12.35 (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)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.5 (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)", @@ -1880,10 +2009,10 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (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.103 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1891,12 +2020,12 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "14.0.3" +version = "14.0.5" 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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.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)", @@ -1906,11 +2035,11 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "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)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.5 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2045,7 +2174,7 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2076,7 +2205,7 @@ dependencies = [ "rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2196,7 +2325,7 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2325,7 +2454,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2404,7 +2533,7 @@ dependencies = [ "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2495,7 +2624,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2513,6 +2642,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "memoffset" @@ -2548,6 +2680,20 @@ dependencies = [ "srml-system 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", ] +[[package]] +name = "merkle-patricia-trie" +version = "0.1.0" +dependencies = [ + "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.4.1 (git+https://github.com/darwinia-network/parity-common.git)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.4.4 (git+https://github.com/darwinia-network/parity-common.git)", + "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "merlin" version = "1.3.0" @@ -2577,9 +2723,10 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.19" +version = "0.6.21" 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)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2599,7 +2746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2610,7 +2757,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2699,7 +2846,7 @@ dependencies = [ "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2773,7 +2920,7 @@ dependencies = [ name = "node-rpc" version = "2.0.0" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 0.2.0", "sr-primitives 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", @@ -2791,7 +2938,7 @@ dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "substrate-rpc 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", @@ -2802,7 +2949,7 @@ name = "node-runtime" version = "0.2.0" dependencies = [ "darwinia-balances 2.0.0", - "darwinia-ethereum-bridge 0.2.0", + "darwinia-eth-relay 0.2.0", "darwinia-kton 0.1.0", "darwinia-staking 0.2.0", "darwinia-support 0.1.0", @@ -3076,7 +3223,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3207,7 +3354,7 @@ dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3307,7 +3454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3317,7 +3464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3544,6 +3691,15 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_xoshiro" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "raw-cpuid" version = "6.1.0" @@ -3611,6 +3767,14 @@ dependencies = [ "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex-automata" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex-syntax" version = "0.6.12" @@ -3761,6 +3925,14 @@ name = "safemem" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "same-file" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "schannel" version = "0.1.16" @@ -3782,7 +3954,7 @@ dependencies = [ "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3876,7 +4048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4015,7 +4187,7 @@ dependencies = [ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4070,7 +4242,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4278,9 +4450,9 @@ name = "srml-contracts-rpc" version = "2.0.0" source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop#d2c4b0dbd89d9588adcbe97320e27f49ee251411" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 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-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", @@ -4487,7 +4659,7 @@ dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "srml-support-procedural-tools 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4499,7 +4671,7 @@ dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "srml-support-procedural-tools-derive 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4509,7 +4681,7 @@ source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia- dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4534,9 +4706,9 @@ name = "srml-system-rpc" version = "2.0.0" source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop#d2c4b0dbd89d9588adcbe97320e27f49ee251411" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 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-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4589,9 +4761,9 @@ name = "srml-transaction-payment-rpc" version = "2.0.0" source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop#d2c4b0dbd89d9588adcbe97320e27f49ee251411" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 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-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", @@ -4632,6 +4804,11 @@ name = "stable_deref_trait" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "static_assertions" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "static_assertions" version = "1.1.0" @@ -4684,7 +4861,7 @@ dependencies = [ "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4807,7 +4984,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5013,7 +5190,7 @@ source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia- dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5085,8 +5262,8 @@ dependencies = [ "substrate-network 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", "substrate-primitives 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", "substrate-telemetry 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5148,7 +5325,7 @@ dependencies = [ "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-application-crypto 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", "substrate-primitives 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5320,8 +5497,8 @@ source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia- dependencies = [ "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 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-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5347,10 +5524,10 @@ source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia- dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 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-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5376,10 +5553,10 @@ name = "substrate-rpc-servers" version = "2.0.0" source = "git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop#d2c4b0dbd89d9588adcbe97320e27f49ee251411" dependencies = [ - "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)", - "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)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5410,7 +5587,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5460,8 +5637,8 @@ dependencies = [ "substrate-transaction-pool-runtime-api 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)", "sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5622,7 +5799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "subtle" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -5637,7 +5814,7 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5652,7 +5829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5782,6 +5959,15 @@ dependencies = [ "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tinytemplate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio" version = "0.1.22" @@ -5789,18 +5975,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5831,7 +6017,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5847,7 +6033,7 @@ dependencies = [ [[package]] name = "tokio-executor" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5876,18 +6062,18 @@ dependencies = [ [[package]] name = "tokio-reactor" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5922,9 +6108,9 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5940,18 +6126,18 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5972,10 +6158,10 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5988,11 +6174,11 @@ dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6087,6 +6273,17 @@ name = "typenum" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "uint" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 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)", +] + [[package]] name = "uint" version = "0.8.2" @@ -6195,6 +6392,15 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "uuid" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vcpkg" version = "0.2.7" @@ -6230,6 +6436,16 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "walkdir" +version = "2.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "want" version = "0.2.0" @@ -6264,7 +6480,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6296,7 +6512,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6311,12 +6527,12 @@ name = "wasm-bindgen-webidl" version = "0.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6329,7 +6545,7 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6449,7 +6665,7 @@ name = "web-sys" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6483,7 +6699,27 @@ dependencies = [ [[package]] name = "websocket" -version = "0.23.0" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket-base 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "websocket-base" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6491,17 +6727,13 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6576,7 +6808,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6649,7 +6881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6690,7 +6922,7 @@ dependencies = [ "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" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -"checksum anyhow 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1072d8f55592084072d2d3cb23a4b680a8543c00f10d446118e85ad3718142" +"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" @@ -6727,6 +6959,7 @@ dependencies = [ "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" +"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" "checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" "checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" @@ -6751,6 +6984,8 @@ dependencies = [ "checksum cranelift-native 0.46.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7ba8a2d69ddd4729199a321bc2f4020e1969a088b468ed6a29dc7a69350be76e" "checksum cranelift-wasm 0.46.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5a802357a6a016bf4c1dcdc6d73a650640eb3b613cc098a1a044a6c3731ca264" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" +"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" "checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" @@ -6760,6 +6995,8 @@ dependencies = [ "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "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" +"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" +"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" "checksum ct-logs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" "checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" "checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" @@ -6785,8 +7022,11 @@ dependencies = [ "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" "checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" "checksum ethash 0.4.0 (git+https://github.com/hammeWang/ethash-rs.git?rev=70a4f078)" = "" +"checksum ethbloom 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3932e82d64d347a045208924002930dc105a138995ccdc1479d0f05f0359f17c" "checksum ethbloom 0.8.1 (git+https://github.com/darwinia-network/parity-common.git)" = "" +"checksum ethereum-types 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b054df51e53f253837ea422681215b42823c02824bde982699d0dceecf6165a1" "checksum ethereum-types 0.8.0 (git+https://github.com/darwinia-network/parity-common.git)" = "" +"checksum ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1873d77b32bc1891a79dad925f2acbc318ee942b38b9110f9dbc5fbeffcea350" "checksum exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" "checksum faerie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "875d78b92b2a4d9e1e2c7eeccfa30a327d2ee6434db3beb8fd6fd92f41898bc4" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" @@ -6796,6 +7036,7 @@ dependencies = [ "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum file-per-thread-logger 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" "checksum finality-grandpa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34754852da8d86bc509715292c73140a5b678656d0b16132acd6737bdb5fd5f8" +"checksum fixed-hash 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a683d1234507e4f3bf2736eeddf0de1dc65996dc0164d57eba0a74bcf29489" "checksum fixed-hash 0.5.1 (git+https://github.com/darwinia-network/parity-common.git)" = "" "checksum fixed-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72fe7539e2c5692c6989f2f9c0457e42f1e5768f96b85c87d273574670ae459f" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" @@ -6862,6 +7103,7 @@ dependencies = [ "checksum impl-codec 0.4.2 (git+https://github.com/darwinia-network/parity-common.git)" = "" "checksum impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" "checksum impl-rlp 0.2.1 (git+https://github.com/darwinia-network/parity-common.git)" = "" +"checksum impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" "checksum impl-serde 0.2.3 (git+https://github.com/darwinia-network/parity-common.git)" = "" "checksum impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" "checksum impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" @@ -6870,17 +7112,18 @@ dependencies = [ "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f4b06b21db0228860c8dfd17d2106c49c7c6bd07477a4036985347d84def04" +"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" "checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414" -"checksum jsonrpc-client-transports 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d389a085cb2184604dff060390cadb8cba1f063c7fd0ad710272c163c88b9f20" -"checksum jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "34651edf3417637cc45e70ed0182ecfa9ced0b7e8131805fccf7400d989845ca" -"checksum jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbaec1d57271ff952f24ca79d37d716cfd749c855b058d9aa5f053a6b8ae4ef" -"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-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-ws-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af36a129cef77a9db8028ac7552d927e1bb7b6928cd96b23dd25cc38bff974ab" +"checksum jsonrpc-client-transports 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0a9ae166c4d1f702d297cd76d4b55758ace80272ffc6dbb139fdc1bf810de40b" +"checksum jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fe3b688648f1ef5d5072229e2d672ecb92cbff7d1c79bcf3fd5898f3f3df0970" +"checksum jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "080dc110be17701097df238fad3c816d4a478a1899dfbcf8ec8957dd40ec7304" +"checksum jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" +"checksum jsonrpc-http-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2d83d348120edee487c560b7cdd2565055d61cda053aa0d0ef0f8b6a18429048" +"checksum jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3453625f0f0f5cd6d6776d389d73b7d70fcc98620b7cbb1cbbb1f6a36e95f39a" +"checksum jsonrpc-server-utils 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "95b7635e618a0edbbe0d2a2bbbc69874277c49383fcf6c3c0414491cfb517d22" +"checksum jsonrpc-ws-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b34faa167c3ac9705aeecb986c0da6056529f348425dbe0441db60a2c4cc41d1" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum keccak-hash 0.4.1 (git+https://github.com/darwinia-network/parity-common.git)" = "" "checksum keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" @@ -6935,7 +7178,7 @@ dependencies = [ "checksum merlin 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" -"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" +"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" @@ -7021,6 +7264,7 @@ dependencies = [ "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" "checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d" "checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd" "checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791" @@ -7028,6 +7272,7 @@ dependencies = [ "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "448e868c6e4cfddfa49b6a72c95906c04e8547465e9536575b95c70a4044f856" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" @@ -7046,6 +7291,7 @@ dependencies = [ "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" "checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" @@ -7117,6 +7363,7 @@ dependencies = [ "checksum srml-transaction-payment-rpc-runtime-api 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)" = "" "checksum srml-utility 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)" = "" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" "checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" "checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" @@ -7180,9 +7427,9 @@ dependencies = [ "checksum substrate-wasm-builder-runner 1.0.4 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)" = "" "checksum substrate-wasm-interface 2.0.0 (git+https://github.com/darwinia-network/substrate.git?branch=darwinia-develop)" = "" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3af2eb31c42e8f0ccf43548232556c42737e01a96db6e1777b0be108e79799" +"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" +"checksum syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f89693ae015201f8de93fd96bde2d065f8bfc3f97ce006d5bc9f900b97c0c7c0" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4b2468c629cffba39c0a4425849ab3cdb03d9dfacba69684609aea04d08ff9" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" @@ -7198,20 +7445,21 @@ dependencies = [ "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" "checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" "checksum tiny-keccak 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" +"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" "checksum tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82c65483db54eb91b4ef3a9389a3364558590faf30ce473141707c0e16fda975" -"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" +"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" "checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d" +"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" "checksum tokio-rustls 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1df2fa53ac211c136832f530ccb081af9af891af22d685a9493e232c7a359bc2" "checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c" -"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" +"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" "checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" "checksum tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" @@ -7226,6 +7474,7 @@ dependencies = [ "checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" +"checksum uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "082df6964410f6aa929a61ddfafc997e4f32c62c22490e439ac351cec827f436" "checksum uint 0.8.2 (git+https://github.com/darwinia-network/parity-common.git)" = "" "checksum uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" @@ -7240,12 +7489,14 @@ dependencies = [ "checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" +"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" "checksum wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "29ae32af33bacd663a9a28241abecf01f2be64e6a185c6139b04f18b6385c5f2" @@ -7267,7 +7518,8 @@ dependencies = [ "checksum webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e664e770ac0110e2384769bcc59ed19e329d81f555916a6e072714957b81b4" "checksum webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a262ae37dd9d60f60dd473d1158f9fbebf110ba7b6a5051c8160460f6043718b" "checksum webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" -"checksum websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b255b190f412e45000c35be7fe9b48b39a2ac5eb90d093d421694e5dae8b335c" +"checksum websocket 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "413b37840b9e27b340ce91b319ede10731de8c72f5bc4cb0206ec1ca4ce581d0" +"checksum websocket-base 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e3810f0d00c4dccb54c30a4eee815e703232819dec7b007db115791c42aa374" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 95c7068ec..86d720d56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "core/merkle-mountain-range", "core/fly-client", "core/sr-eth-primitives", + "core/merkle-patricia-trie", "node/cli", "node/executor", @@ -16,7 +17,7 @@ members = [ "node/runtime", "srml/balances", - "srml/ethereum-bridge", + "srml/eth-relay", "srml/kton", "srml/staking", "srml/support" diff --git a/core/merkle-patricia-trie/Cargo.toml b/core/merkle-patricia-trie/Cargo.toml new file mode 100644 index 000000000..65a74a46c --- /dev/null +++ b/core/merkle-patricia-trie/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "merkle-patricia-trie" +version = "0.1.0" +authors = ["Darwinia Network "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rlp = { git = "https://github.com/darwinia-network/parity-common.git", default-features = false } +hash = { package = "keccak-hash", git = "https://github.com/darwinia-network/parity-common.git", default-features = false } +hashbrown = { version = "0.6.0" } + +[dev-dependencies] +rand = "0.6.3" +hex = "0.3.2" +criterion = "0.2.10" +ethereum-types = "0.5.2" +uuid = { version = "0.7", features = ["serde", "v4"] } + +[features] +default = ["std"] +std = [ + "rlp/std", + "hash/std" +] + +[[bench]] +name = "trie" +harness = false \ No newline at end of file diff --git a/core/merkle-patricia-trie/benches/trie.rs b/core/merkle-patricia-trie/benches/trie.rs new file mode 100644 index 000000000..5ee3a89cd --- /dev/null +++ b/core/merkle-patricia-trie/benches/trie.rs @@ -0,0 +1,99 @@ +use std::rc::Rc; + +use criterion::{criterion_group, criterion_main, Criterion}; +use merkle_patricia_trie::{MemoryDB, MerklePatriciaTrie, Trie}; +use uuid::Uuid; + +fn insert_worse_case_benchmark(c: &mut Criterion) { + c.bench_function("insert one", |b| { + let mut trie = MerklePatriciaTrie::new(Rc::new(MemoryDB::new())); + + b.iter(|| { + let key = Uuid::new_v4().as_bytes().to_vec(); + let value = Uuid::new_v4().as_bytes().to_vec(); + trie.insert(key, value).unwrap() + }) + }); + + c.bench_function("insert 1k", |b| { + let mut trie = MerklePatriciaTrie::new(Rc::new(MemoryDB::new())); + + let (keys, values) = random_data(1000); + b.iter(|| { + for i in 0..keys.len() { + trie.insert(keys[i].clone(), values[i].clone()).unwrap() + } + }); + }); + + c.bench_function("insert 10k", |b| { + let mut trie = MerklePatriciaTrie::new(Rc::new(MemoryDB::new())); + + let (keys, values) = random_data(10000); + b.iter(|| { + for i in 0..keys.len() { + trie.insert(keys[i].clone(), values[i].clone()).unwrap() + } + }); + }); + + c.bench_function("get based 10k", |b| { + let mut trie = MerklePatriciaTrie::new(Rc::new(MemoryDB::new())); + + let (keys, values) = random_data(10000); + for i in 0..keys.len() { + trie.insert(keys[i].clone(), values[i].clone()).unwrap() + } + + b.iter(|| { + let key = trie.get(&keys[7777]).unwrap(); + assert_ne!(key, None); + }); + }); + + c.bench_function("remove 1k", |b| { + let mut trie = MerklePatriciaTrie::new(Rc::new(MemoryDB::new())); + + let (keys, values) = random_data(1000); + for i in 0..keys.len() { + trie.insert(keys[i].clone(), values[i].clone()).unwrap() + } + + b.iter(|| { + for key in keys.iter() { + trie.remove(key).unwrap(); + } + }); + }); + + c.bench_function("remove 10k", |b| { + let mut trie = MerklePatriciaTrie::new(Rc::new(MemoryDB::new())); + + let (keys, values) = random_data(10000); + for i in 0..keys.len() { + trie.insert(keys[i].clone(), values[i].clone()).unwrap() + } + + b.iter(|| { + for key in keys.iter() { + trie.remove(key).unwrap(); + } + }); + }); +} + +fn random_data(n: usize) -> (Vec>, Vec>) { + let mut keys = Vec::with_capacity(n); + let mut values = Vec::with_capacity(n); + for _ in 0..n { + let key = Uuid::new_v4().as_bytes().to_vec(); + let value = Uuid::new_v4().as_bytes().to_vec(); + keys.push(key); + values.push(value); + } + + (keys, values) +} + +criterion_group!(benches, insert_worse_case_benchmark); +criterion_main!(benches); diff --git a/core/merkle-patricia-trie/src/db.rs b/core/merkle-patricia-trie/src/db.rs new file mode 100644 index 000000000..00289a732 --- /dev/null +++ b/core/merkle-patricia-trie/src/db.rs @@ -0,0 +1,52 @@ +use crate::std::*; +use hashbrown::HashMap; + +#[derive(Debug)] +pub struct MemoryDB { + data: RefCell, Vec>>, +} + +impl MemoryDB { + pub fn new() -> Self { + MemoryDB { + data: RefCell::new(HashMap::new()), + } + } + + pub fn get(&self, key: &[u8]) -> Option> { + let data = self.data.borrow(); + if let Some(d) = data.get(key) { + Some(d.clone()) + } else { + None + } + } + + pub fn insert(&self, key: Vec, value: Vec) -> Option> { + self.data.borrow_mut().insert(key, value) + } + + pub fn contains(&self, key: &[u8]) -> bool { + self.data.borrow().contains_key(key) + } + + pub fn remove(&self, key: &[u8]) -> Option> { + self.data.borrow_mut().remove(key) + } + + /// Insert a batch of data into the cache. + pub fn insert_batch(&self, keys: Vec>, values: Vec>) { + for i in 0..keys.len() { + let key = keys[i].clone(); + let value = values[i].clone(); + self.insert(key, value); + } + } + + /// Remove a batch of data into the cache. + pub fn remove_batch(&self, keys: &[Vec]) { + for key in keys { + self.remove(key); + } + } +} diff --git a/core/merkle-patricia-trie/src/error.rs b/core/merkle-patricia-trie/src/error.rs new file mode 100644 index 000000000..6c0047f81 --- /dev/null +++ b/core/merkle-patricia-trie/src/error.rs @@ -0,0 +1,30 @@ +use crate::std::*; +use rlp::DecoderError; + +#[derive(Debug)] +pub enum TrieError { + DB(String), + Decoder(DecoderError), + InvalidData, + InvalidStateRoot, + InvalidProof, +} + +impl fmt::Display for TrieError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let printable = match *self { + TrieError::DB(ref err) => format!("trie error: {:?}", err), + TrieError::Decoder(ref err) => format!("trie error: {:?}", err), + TrieError::InvalidData => "trie error: invalid data".to_owned(), + TrieError::InvalidStateRoot => "trie error: invalid state root".to_owned(), + TrieError::InvalidProof => "trie error: invalid proof".to_owned(), + }; + write!(f, "{}", printable) + } +} + +impl From for TrieError { + fn from(error: DecoderError) -> Self { + TrieError::Decoder(error) + } +} diff --git a/core/merkle-patricia-trie/src/lib.rs b/core/merkle-patricia-trie/src/lib.rs new file mode 100644 index 000000000..52d96e639 --- /dev/null +++ b/core/merkle-patricia-trie/src/lib.rs @@ -0,0 +1,99 @@ +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(feature = "std"))] +extern crate alloc; +#[cfg(not(feature = "std"))] +extern crate core; + +#[cfg(not(feature = "std"))] +mod std { + pub use alloc::borrow::ToOwned; + pub use alloc::format; + pub use alloc::rc::Rc; + pub use alloc::string::String; + pub use alloc::vec; + pub use alloc::vec::Vec; + + pub use core::cell::RefCell; + pub use core::fmt; +} + +#[cfg(feature = "std")] +mod std { + pub use std::cell::RefCell; + pub use std::fmt; + pub use std::rc::Rc; +} + +mod db; +mod error; +mod nibbles; +mod node; +mod proof; +mod tests; +pub mod trie; + +pub use db::MemoryDB; +pub use error::TrieError; +pub use proof::Proof; +pub use trie::{MerklePatriciaTrie, Trie, TrieResult}; + +/// Generates a trie for a vector of key-value tuples +/// +/// ```rust +/// extern crate merkle_patricia_trie as trie; +/// extern crate hex; +/// +/// use trie::{Trie, build_trie}; +/// use hex::FromHex; +/// +/// fn main() { +/// let v = vec![ +/// ("doe", "reindeer"), +/// ("dog", "puppy"), +/// ("dogglesworth", "cat"), +/// ]; +/// +/// let root:Vec = Vec::from_hex("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3").unwrap(); +/// assert_eq!(build_trie(v).unwrap().root().unwrap(), root); +/// } +/// ``` +pub fn build_trie(data: I) -> TrieResult +where + I: IntoIterator, + A: AsRef<[u8]> + Ord, + B: AsRef<[u8]>, +{ + let memdb = std::Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb.clone()); + data.into_iter().for_each(|(key, value)| { + // TODO the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `core::ops::Try`) + trie.insert(key.as_ref().to_vec(), value.as_ref().to_vec()); + }); + trie.root()?; + Ok(trie) +} + +/// Generates a trie for a vector of values +/// +/// ```rust +/// extern crate merkle_patricia_trie as trie; +/// extern crate hex; +/// +/// use trie::{Trie, build_order_trie}; +/// use hex::FromHex; +/// +/// fn main() { +/// let v = &["doe", "reindeer"]; +/// let root:Vec = Vec::from_hex("e766d5d51b89dc39d981b41bda63248d7abce4f0225eefd023792a540bcffee3").unwrap(); +/// assert_eq!(build_order_trie(v).unwrap().root().unwrap(), root); +/// } +/// ``` +pub fn build_order_trie(data: I) -> TrieResult +where + I: IntoIterator, + I::Item: AsRef<[u8]>, +{ + build_trie(data.into_iter().enumerate().map(|(i, v)| (rlp::encode(&i), v))) +} diff --git a/core/merkle-patricia-trie/src/nibbles.rs b/core/merkle-patricia-trie/src/nibbles.rs new file mode 100644 index 000000000..14f4c44ad --- /dev/null +++ b/core/merkle-patricia-trie/src/nibbles.rs @@ -0,0 +1,185 @@ +use crate::std::*; +use core::cmp::min; + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Nibbles { + hex_data: Vec, +} + +impl Nibbles { + pub fn from_hex(hex: Vec) -> Self { + Nibbles { hex_data: hex } + } + + pub fn from_raw(raw: Vec, is_leaf: bool) -> Self { + let mut hex_data = vec![]; + for item in raw.into_iter() { + hex_data.push(item / 16); + hex_data.push(item % 16); + } + if is_leaf { + hex_data.push(16); + } + Nibbles { hex_data } + } + + pub fn from_compact(compact: Vec) -> Self { + let mut hex = vec![]; + let flag = compact[0]; + + let mut is_leaf = false; + match flag >> 4 { + 0x0 => {} + 0x1 => hex.push(flag % 16), + 0x2 => is_leaf = true, + 0x3 => { + is_leaf = true; + hex.push(flag % 16); + } + _ => panic!("invalid data"), + } + + for item in &compact[1..] { + hex.push(item / 16); + hex.push(item % 16); + } + if is_leaf { + hex.push(16); + } + + Nibbles { hex_data: hex } + } + + pub fn is_leaf(&self) -> bool { + self.hex_data[self.hex_data.len() - 1] == 16 + } + + pub fn encode_compact(&self) -> Vec { + let mut compact = vec![]; + let is_leaf = self.is_leaf(); + let mut hex = if is_leaf { + &self.hex_data[0..self.hex_data.len() - 1] + } else { + &self.hex_data[0..] + }; + // node type path length | prefix hexchar + // -------------------------------------------------- + // extension even | 0000 0x0 + // extension odd | 0001 0x1 + // leaf even | 0010 0x2 + // leaf odd | 0011 0x3 + let v = if hex.len() % 2 == 1 { + let v = 0x10 + hex[0]; + hex = &hex[1..]; + v + } else { + 0x00 + }; + + compact.push(v + if is_leaf { 0x20 } else { 0x00 }); + for i in 0..(hex.len() / 2) { + compact.push((hex[i * 2] * 16) + (hex[i * 2 + 1])); + } + + compact + } + + pub fn encode_raw(&self) -> (Vec, bool) { + let mut raw = vec![]; + let is_leaf = self.is_leaf(); + let hex = if is_leaf { + &self.hex_data[0..self.hex_data.len() - 1] + } else { + &self.hex_data[0..] + }; + + for i in 0..(hex.len() / 2) { + raw.push((hex[i * 2] * 16) + (hex[i * 2 + 1])); + } + + (raw, is_leaf) + } + + pub fn len(&self) -> usize { + self.hex_data.len() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn at(&self, i: usize) -> usize { + self.hex_data[i] as usize + } + + pub fn common_prefix(&self, other_partial: &Nibbles) -> usize { + let s = min(self.len(), other_partial.len()); + let mut i = 0usize; + while i < s { + if self.at(i) != other_partial.at(i) { + break; + } + i += 1; + } + i + } + + pub fn offset(&self, index: usize) -> Nibbles { + self.slice(index, self.hex_data.len()) + } + + pub fn slice(&self, start: usize, end: usize) -> Nibbles { + Nibbles::from_hex(self.hex_data[start..end].to_vec()) + } + + pub fn get_data(&self) -> &[u8] { + &self.hex_data + } + + pub fn join(&self, b: &Nibbles) -> Nibbles { + let mut hex_data = vec![]; + hex_data.extend_from_slice(self.get_data()); + hex_data.extend_from_slice(b.get_data()); + Nibbles::from_hex(hex_data) + } + + pub fn extend(&mut self, b: &Nibbles) { + self.hex_data.extend_from_slice(b.get_data()); + } + + pub fn truncate(&mut self, len: usize) { + self.hex_data.truncate(len) + } + + pub fn pop(&mut self) -> Option { + self.hex_data.pop() + } + + pub fn push(&mut self, e: u8) { + self.hex_data.push(e) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_nibble() { + let n = Nibbles::from_raw(b"key1".to_vec(), true); + let compact = n.encode_compact(); + let n2 = Nibbles::from_compact(compact.clone()); + let (raw, is_leaf) = n2.encode_raw(); + + println!( + "source: {:?} \n n: {:?} \n compact: {:?} \n n2: {:?} \n raw: {:?}", + b"key1".to_vec(), + n, + compact, + n2, + raw + ); + assert_eq!(is_leaf, true); + assert_eq!(raw, b"key1"); + } +} diff --git a/core/merkle-patricia-trie/src/node.rs b/core/merkle-patricia-trie/src/node.rs new file mode 100644 index 000000000..b9dc8b1dc --- /dev/null +++ b/core/merkle-patricia-trie/src/node.rs @@ -0,0 +1,92 @@ +use crate::nibbles::Nibbles; +use crate::std::*; + +#[derive(Debug, Clone)] +pub enum Node { + Empty, + Leaf(Rc>), + Extension(Rc>), + Branch(Rc>), + Hash(Rc>), +} + +impl Node { + pub fn from_leaf(key: Nibbles, value: Vec) -> Self { + let leaf = Rc::new(RefCell::new(LeafNode { key, value })); + Node::Leaf(leaf) + } + + pub fn from_branch(children: [Node; 16], value: Option>) -> Self { + let branch = Rc::new(RefCell::new(BranchNode { children, value })); + Node::Branch(branch) + } + + pub fn from_extension(prefix: Nibbles, node: Node) -> Self { + let ext = Rc::new(RefCell::new(ExtensionNode { prefix, node })); + Node::Extension(ext) + } + + pub fn from_hash(hash: Vec) -> Self { + let hash_node = Rc::new(RefCell::new(HashNode { hash })); + Node::Hash(hash_node) + } +} + +#[derive(Debug)] +pub struct LeafNode { + pub key: Nibbles, + pub value: Vec, +} + +#[derive(Debug)] +pub struct BranchNode { + pub children: [Node; 16], + pub value: Option>, +} + +impl BranchNode { + pub fn insert(&mut self, i: usize, n: Node) { + if i == 16 { + match n { + Node::Leaf(leaf) => { + self.value = Some(leaf.borrow().value.clone()); + } + _ => panic!("The n must be leaf node"), + } + } else { + self.children[i] = n + } + } +} + +#[derive(Debug)] +pub struct ExtensionNode { + pub prefix: Nibbles, + pub node: Node, +} + +#[derive(Debug)] +pub struct HashNode { + pub hash: Vec, +} + +pub fn empty_children() -> [Node; 16] { + [ + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + Node::Empty, + ] +} diff --git a/core/merkle-patricia-trie/src/proof.rs b/core/merkle-patricia-trie/src/proof.rs new file mode 100644 index 000000000..400b40c40 --- /dev/null +++ b/core/merkle-patricia-trie/src/proof.rs @@ -0,0 +1,52 @@ +use crate::std::*; +use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; + +#[derive(Clone)] +#[cfg_attr(feature = "std", derive(Debug, PartialEq))] +pub struct Proof { + pub nodes: Vec>, +} + +impl Proof { + pub fn to_rlp(&self) -> Vec { + rlp::encode(self) + } + + pub fn len(&self) -> usize { + self.nodes.len() + } +} + +impl From>> for Proof { + fn from(data: Vec>) -> Proof { + Proof { nodes: data } + } +} + +impl Decodable for Proof { + fn decode(r: &Rlp) -> Result { + Ok(Proof { nodes: r.list_at(0)? }) + } +} + +impl Encodable for Proof { + fn rlp_append(&self, s: &mut RlpStream) { + s.begin_list(1); + s.append_list::, Vec>(&self.nodes); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_encode_decode() { + let nodes = vec![vec![0u8], vec![1], vec![2]]; + let expected = Proof { nodes: nodes }; + let rlp_proof = rlp::encode(&expected); + let out_proof: Proof = rlp::decode(&rlp_proof).unwrap(); + println!("{:?}", out_proof); + assert_eq!(expected, out_proof); + } +} diff --git a/core/merkle-patricia-trie/src/tests.rs b/core/merkle-patricia-trie/src/tests.rs new file mode 100644 index 000000000..e64c094e9 --- /dev/null +++ b/core/merkle-patricia-trie/src/tests.rs @@ -0,0 +1,657 @@ +#[cfg(test)] +mod trie_tests { + use hex::FromHex; + use rand::Rng; + use std::rc::Rc; + + use crate::db::MemoryDB; + use crate::proof::Proof; + use crate::trie::*; + use rlp::{self, Rlp}; + + fn assert_root(data: Vec<(&[u8], &[u8])>, hash: &str) { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(Rc::clone(&memdb)); + for (k, v) in data.into_iter() { + trie.insert(k.to_vec(), v.to_vec()).unwrap(); + } + let r = trie.root().unwrap(); + let rs = format!("0x{}", hex::encode(r.clone())); + assert_eq!(rs.as_str(), hash); + let mut trie = MerklePatriciaTrie::from(Rc::clone(&memdb), &r).unwrap(); + let r2 = trie.root().unwrap(); + let rs2 = format!("0x{}", hex::encode(r2)); + assert_eq!(rs2.as_str(), hash); + } + + #[test] + fn test_root() { + // See: https://github.com/ethereum/tests/blob/develop/TrieTests + // Copy from trietest.json and trieanyorder.json + assert_root( + vec![(b"A", b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")], + "0xd23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab", + ); + assert_root( + vec![(b"doe", b"reindeer"), (b"dog", b"puppy"), (b"dogglesworth", b"cat")], + "0x8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3", + ); + assert_root( + vec![ + (b"do", b"verb"), + (b"horse", b"stallion"), + (b"doge", b"coin"), + (b"dog", b"puppy"), + ], + "0x5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84", + ); + assert_root( + vec![(b"foo", b"bar"), (b"food", b"bass")], + "0x17beaa1648bafa633cda809c90c04af50fc8aed3cb40d16efbddee6fdf63c4c3", + ); + + assert_root( + vec![(b"be", b"e"), (b"dog", b"puppy"), (b"bed", b"d")], + "0x3f67c7a47520f79faa29255d2d3c084a7a6df0453116ed7232ff10277a8be68b", + ); + assert_root( + vec![(b"test", b"test"), (b"te", b"testy")], + "0x8452568af70d8d140f58d941338542f645fcca50094b20f3c3d8c3df49337928", + ); + assert_root( + vec![ + ( + Vec::from_hex("0045").unwrap().as_slice(), + Vec::from_hex("0123456789").unwrap().as_slice(), + ), + ( + Vec::from_hex("4500").unwrap().as_slice(), + Vec::from_hex("9876543210").unwrap().as_slice(), + ), + ], + "0x285505fcabe84badc8aa310e2aae17eddc7d120aabec8a476902c8184b3a3503", + ); + assert_root( + vec![ + (b"do", b"verb"), + (b"ether", b"wookiedoo"), + (b"horse", b"stallion"), + (b"shaman", b"horse"), + (b"doge", b"coin"), + (b"ether", b""), + (b"dog", b"puppy"), + (b"shaman", b""), + ], + "0x5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84", + ); + assert_root( + vec![ + (b"do", b"verb"), + (b"ether", b"wookiedoo"), + (b"horse", b"stallion"), + (b"shaman", b"horse"), + (b"doge", b"coin"), + (b"ether", b""), + (b"dog", b"puppy"), + (b"shaman", b""), + ], + "0x5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84", + ); + assert_root( + vec![ + ( + Vec::from_hex("04110d816c380812a427968ece99b1c963dfbce6") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("095e7baea6a6c7c4c2dfeb977efac326af552d87") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("0a517d755cebbf66312b30fff713666a9cb917e0") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("24dd378f51adc67a50e339e8031fe9bd4aafab36") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("293f982d000532a7861ab122bdc4bbfd26bf9030") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("2cf5732f017b0cf1b1f13a1478e10239716bf6b5") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("31c640b92c21a1f1465c91070b4b3b4d6854195f") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("37f998764813b136ddf5a754f34063fd03065e36") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("37fa399a749c121f8a15ce77e3d9f9bec8020d7a") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("4f36659fa632310b6ec438dea4085b522a2dd077") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("62c01474f089b07dae603491675dc5b5748f7049") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("729af7294be595a0efd7d891c9e51f89c07950c7") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("83e3e5a16d3b696a0314b30b2534804dd5e11197") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("8703df2417e0d7c59d063caa9583cb10a4d20532") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("8dffcd74e5b5923512916c6a64b502689cfa65e1") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("95a4d7cccb5204733874fa87285a176fe1e9e240") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("99b2fcba8120bedd048fe79f5262a6690ed38c39") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("a4202b8b8afd5354e3e40a219bdc17f6001bf2cf") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("a94f5374fce5edbc8e2a8697c15331677e6ebf0b") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("a9647f4a0a14042d91dc33c0328030a7157c93ae") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("aa6cffe5185732689c18f37a7f86170cb7304c2a") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("aae4a2e3c51c04606dcb3723456e58f3ed214f45") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("c37a43e940dfb5baf581a0b82b351d48305fc885") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("d2571607e241ecf590ed94b12d87c94babe36db6") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("f735071cbee190d76b704ce68384fc21e389fbe7") + .unwrap() + .as_slice(), + b"something", + ), + ( + Vec::from_hex("04110d816c380812a427968ece99b1c963dfbce6") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("095e7baea6a6c7c4c2dfeb977efac326af552d87") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("0a517d755cebbf66312b30fff713666a9cb917e0") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("24dd378f51adc67a50e339e8031fe9bd4aafab36") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("293f982d000532a7861ab122bdc4bbfd26bf9030") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("2cf5732f017b0cf1b1f13a1478e10239716bf6b5") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("31c640b92c21a1f1465c91070b4b3b4d6854195f") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("37f998764813b136ddf5a754f34063fd03065e36") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("37fa399a749c121f8a15ce77e3d9f9bec8020d7a") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("4f36659fa632310b6ec438dea4085b522a2dd077") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("62c01474f089b07dae603491675dc5b5748f7049") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("729af7294be595a0efd7d891c9e51f89c07950c7") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("83e3e5a16d3b696a0314b30b2534804dd5e11197") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("8703df2417e0d7c59d063caa9583cb10a4d20532") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("8dffcd74e5b5923512916c6a64b502689cfa65e1") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("95a4d7cccb5204733874fa87285a176fe1e9e240") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("99b2fcba8120bedd048fe79f5262a6690ed38c39") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("a4202b8b8afd5354e3e40a219bdc17f6001bf2cf") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("a94f5374fce5edbc8e2a8697c15331677e6ebf0b") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("a9647f4a0a14042d91dc33c0328030a7157c93ae") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("aa6cffe5185732689c18f37a7f86170cb7304c2a") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("aae4a2e3c51c04606dcb3723456e58f3ed214f45") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("c37a43e940dfb5baf581a0b82b351d48305fc885") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("d2571607e241ecf590ed94b12d87c94babe36db6") + .unwrap() + .as_slice(), + b"", + ), + ( + Vec::from_hex("f735071cbee190d76b704ce68384fc21e389fbe7") + .unwrap() + .as_slice(), + b"", + ), + ], + "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + ); + assert_root( + vec![ + ( + Vec::from_hex("0000000000000000000000000000000000000000000000000000000000000045") + .unwrap() + .as_slice(), + Vec::from_hex("22b224a1420a802ab51d326e29fa98e34c4f24ea") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("0000000000000000000000000000000000000000000000000000000000000046") + .unwrap() + .as_slice(), + Vec::from_hex("67706c2076330000000000000000000000000000000000000000000000000000") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("0000000000000000000000000000000000000000000000000000001234567890") + .unwrap() + .as_slice(), + Vec::from_hex("697c7b8c961b56f675d570498424ac8de1a918f6") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("000000000000000000000000697c7b8c961b56f675d570498424ac8de1a918f6") + .unwrap() + .as_slice(), + Vec::from_hex("1234567890").unwrap().as_slice(), + ), + ( + Vec::from_hex("0000000000000000000000007ef9e639e2733cb34e4dfc576d4b23f72db776b2") + .unwrap() + .as_slice(), + Vec::from_hex("4655474156000000000000000000000000000000000000000000000000000000") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("000000000000000000000000ec4f34c97e43fbb2816cfd95e388353c7181dab1") + .unwrap() + .as_slice(), + Vec::from_hex("4e616d6552656700000000000000000000000000000000000000000000000000") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("4655474156000000000000000000000000000000000000000000000000000000") + .unwrap() + .as_slice(), + Vec::from_hex("7ef9e639e2733cb34e4dfc576d4b23f72db776b2") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("4e616d6552656700000000000000000000000000000000000000000000000000") + .unwrap() + .as_slice(), + Vec::from_hex("ec4f34c97e43fbb2816cfd95e388353c7181dab1") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("0000000000000000000000000000000000000000000000000000001234567890") + .unwrap() + .as_slice(), + Vec::from_hex("").unwrap().as_slice(), + ), + ( + Vec::from_hex("000000000000000000000000697c7b8c961b56f675d570498424ac8de1a918f6") + .unwrap() + .as_slice(), + Vec::from_hex("6f6f6f6820736f2067726561742c207265616c6c6c793f000000000000000000") + .unwrap() + .as_slice(), + ), + ( + Vec::from_hex("6f6f6f6820736f2067726561742c207265616c6c6c793f000000000000000000") + .unwrap() + .as_slice(), + Vec::from_hex("697c7b8c961b56f675d570498424ac8de1a918f6") + .unwrap() + .as_slice(), + ), + ], + "0x9f6221ebb8efe7cff60a716ecb886e67dd042014be444669f0159d8e68b42100", + ); + assert_root( + vec![ + (b"key1aa", b"0123456789012345678901234567890123456789xxx"), + (b"key1", b"0123456789012345678901234567890123456789Very_Long"), + (b"key2bb", b"aval3"), + (b"key2", b"short"), + (b"key3cc", b"aval3"), + (b"key3", b"1234567890123456789012345678901"), + ], + "0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89", + ); + assert_root( + vec![(b"abc", b"123"), (b"abcd", b"abcd"), (b"abc", b"abc")], + "0x7a320748f780ad9ad5b0837302075ce0eeba6c26e3d8562c67ccc0f1b273298a", + ); + } + + // proof test ref: + // - https://github.com/ethereum/go-ethereum/blob/master/trie/proof_test.go + // - https://github.com/ethereum/py-trie/blob/master/tests/test_proof.py + #[test] + fn test_proof_basic() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(Rc::clone(&memdb)); + trie.insert(b"doe".to_vec(), b"reindeer".to_vec()).unwrap(); + trie.insert(b"dog".to_vec(), b"puppy".to_vec()).unwrap(); + trie.insert(b"dogglesworth".to_vec(), b"cat".to_vec()).unwrap(); + let root = trie.root().unwrap(); + let r = format!("0x{}", hex::encode(trie.root().unwrap())); + assert_eq!( + r.as_str(), + "0x8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3" + ); + + // proof of key exists + let proof = trie.get_proof(b"doe").unwrap(); + let expected = vec![ + "e5831646f6a0db6ae1fda66890f6693f36560d36b4dca68b4d838f17016b151efe1d4c95c453", + "f83b8080808080ca20887265696e6465657280a037efd11993cb04a54048c25320e9f29c50a432d28afdf01598b2978ce1ca3068808080808080808080", + ]; + assert_eq!( + proof.clone().nodes.into_iter().map(hex::encode).collect::>(), + expected + ); + let value = MerklePatriciaTrie::verify_proof(root.clone(), b"doe", proof).unwrap(); + assert_eq!(value, Some(b"reindeer".to_vec())); + + // proof of key not exist + let proof = trie.get_proof(b"dogg").unwrap(); + let expected = vec![ + "e5831646f6a0db6ae1fda66890f6693f36560d36b4dca68b4d838f17016b151efe1d4c95c453", + "f83b8080808080ca20887265696e6465657280a037efd11993cb04a54048c25320e9f29c50a432d28afdf01598b2978ce1ca3068808080808080808080", + "e4808080808080ce89376c6573776f72746883636174808080808080808080857075707079", + ]; + assert_eq!( + proof.clone().nodes.into_iter().map(hex::encode).collect::>(), + expected + ); + let value = MerklePatriciaTrie::verify_proof(root.clone(), b"dogg", proof).unwrap(); + assert_eq!(value, None); + + // empty proof + let proof = vec![]; + let value = MerklePatriciaTrie::verify_proof(root.clone(), b"doe", proof.into()); + assert_eq!(value.is_err(), true); + + // bad proof + let proof = vec![b"aaa".to_vec(), b"ccc".to_vec()]; + let value = MerklePatriciaTrie::verify_proof(root.clone(), b"doe", proof.into()); + assert_eq!(value.is_err(), true); + } + + #[test] + fn test_proof_random() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(Rc::clone(&memdb)); + let mut rng = rand::thread_rng(); + let mut keys = vec![]; + for _ in 0..100 { + let random_bytes: Vec = (0..rng.gen_range(2, 30)).map(|_| rand::random::()).collect(); + trie.insert(random_bytes.to_vec(), random_bytes.clone()).unwrap(); + keys.push(random_bytes.clone()); + } + for k in keys.clone().into_iter() { + trie.insert(k.clone(), k.clone()).unwrap(); + } + let root = trie.root().unwrap(); + for k in keys.into_iter() { + let proof = trie.get_proof(&k).unwrap(); + let value = MerklePatriciaTrie::verify_proof(root.clone(), &k, proof) + .unwrap() + .unwrap(); + assert_eq!(value, k); + } + } + + #[test] + fn test_proof_empty_trie() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(Rc::clone(&memdb)); + trie.root().unwrap(); + let proof = trie.get_proof(b"not-exist").unwrap(); + assert_eq!(proof.len(), 0); + } + + #[test] + fn test_proof_one_element() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(Rc::clone(&memdb)); + trie.insert(b"k".to_vec(), b"v".to_vec()).unwrap(); + let root = trie.root().unwrap(); + let proof = trie.get_proof(b"k").unwrap(); + assert_eq!(proof.len(), 1); + let value = MerklePatriciaTrie::verify_proof(root.clone(), b"k", proof.clone()).unwrap(); + assert_eq!(value, Some(b"v".to_vec())); + + // remove key does not affect the verify process + trie.remove(b"k").unwrap(); + let _root = trie.root().unwrap(); + let value = MerklePatriciaTrie::verify_proof(root.clone(), b"k", proof.clone()).unwrap(); + assert_eq!(value, Some(b"v".to_vec())); + } + + #[test] + fn test_ethereum_receipts_proof() { + let rlp_proof: Vec = Vec::from_hex("f9016ef9016bb853f851a009b67a67265063da0dd6a7abad695edb2c439f6b458f2a2ee48a21442fef8a2680808080808080a0a7d4f8b974d21b7244014729b07e9c9f19fdc445da2ceddc089d90cead74be618080808080808080b90113f9011031b9010cf9010901835cdb6eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0").unwrap(); + let expected: Vec = Vec::from_hex("f9010901835cdb6eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0").unwrap(); + let root = Vec::from_hex("7fa081e3e33e53c4d09ae691af3853bb73a7e02c856104fe843172abab85df7b").unwrap(); + + let proof: Proof = rlp::decode(&rlp_proof).unwrap(); + let key = rlp::encode(&1usize); + let value = MerklePatriciaTrie::verify_proof(root.clone(), &key, proof.clone()).unwrap(); + assert!(value.is_some()); + assert_eq!(value.unwrap(), expected); + } + + #[test] + fn test_ethereum_receipts_build_proof() { + // transaction hash 0xb04fcb9822eb21b5ffdbf89df076de58469af66d23c86abe30266e5d3c5e0db2 in ropsten + // build trie + let data = vec![ + Vec::from_hex("f90184018261beb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000040000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000f87bf87994095c5cbf4937d0a21f6f395194e95b6ebe8616b9e1a06ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be770b8400000000000000000000000002e0a521fe69c14d99c8d236d8c3cd5353cc44e720000000000000000000000000000000000000000000000000000000000000000").unwrap(), + Vec::from_hex("f9010901835cdb6eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0").unwrap(), + ]; + let hash = "0x7fa081e3e33e53c4d09ae691af3853bb73a7e02c856104fe843172abab85df7b"; + + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(Rc::clone(&memdb)); + for (k, v) in data.clone().into_iter().enumerate().map(|(i, v)| (rlp::encode(&i), v)) { + trie.insert(k.to_vec(), v.to_vec()).unwrap(); + } + let r = trie.root().unwrap(); + let rs = format!("0x{}", hex::encode(r.clone())); + + assert_eq!(rs.as_str(), hash); + + // check proof + let key = rlp::encode(&1usize); + let proof = trie.get_proof(&key).unwrap(); + let value = MerklePatriciaTrie::verify_proof(r.clone(), &key, proof.clone()).unwrap(); + + assert_eq!(value.unwrap(), data[1]); + } +} diff --git a/core/merkle-patricia-trie/src/trie.rs b/core/merkle-patricia-trie/src/trie.rs new file mode 100644 index 000000000..a1ba47ecf --- /dev/null +++ b/core/merkle-patricia-trie/src/trie.rs @@ -0,0 +1,1058 @@ +use crate::std::*; +use hash::keccak; +use hashbrown::{HashMap, HashSet}; +use rlp::{Prototype, Rlp, RlpStream}; + +use crate::db::MemoryDB; +use crate::error::TrieError; +use crate::nibbles::Nibbles; +use crate::node::{empty_children, BranchNode, Node}; +use crate::proof::Proof; + +pub type TrieResult = Result; + +const LENGTH: usize = 32; + +#[derive(Debug)] +pub struct MerklePatriciaTrie { + root: Node, + root_hash: Vec, + pub db: Rc, + cache: RefCell, Vec>>, + passing_keys: RefCell>>, + gen_keys: RefCell>>, +} + +impl MerklePatriciaTrie { + pub fn new(db: Rc) -> Self { + Self { + root: Node::Empty, + root_hash: hasher_digest(&rlp::NULL_RLP.to_vec()), + + cache: RefCell::new(HashMap::new()), + passing_keys: RefCell::new(HashSet::new()), + gen_keys: RefCell::new(HashSet::new()), + + db, + } + } + + pub fn from(db: Rc, root: &[u8]) -> TrieResult { + match db.get(&root) { + Some(data) => { + let mut trie = Self { + root: Node::Empty, + root_hash: root.to_vec(), + + cache: RefCell::new(HashMap::new()), + passing_keys: RefCell::new(HashSet::new()), + gen_keys: RefCell::new(HashSet::new()), + + db, + }; + + trie.root = trie.decode_node(&data)?; + Ok(trie) + } + None => Err(TrieError::InvalidStateRoot), + } + } +} + +fn hasher_digest(data: &[u8]) -> Vec { + keccak(data).0.to_vec() +} + +pub trait Trie { + /// Returns the value for key stored in the trie. + fn get(&self, key: &[u8]) -> TrieResult>>; + + /// Checks that the key is present in the trie + fn contains(&self, key: &[u8]) -> TrieResult; + + /// Inserts value into trie and modifies it if it exists + fn insert(&mut self, key: Vec, value: Vec) -> TrieResult; + + /// Removes any existing value for key from the trie. + fn remove(&mut self, key: &[u8]) -> TrieResult; + + /// Saves all the nodes in the db, clears the cache data, recalculates the root. + /// Returns the root hash of the trie. + fn root(&mut self) -> TrieResult>; + + /// Prove constructs a merkle proof for key. The result contains all encoded nodes + /// on the path to the value at key. The value itself is also included in the last + /// node and can be retrieved by verifying the proof. + /// + /// If the trie does not contain a value for key, the returned proof contains all + /// nodes of the longest existing prefix of the key (at least the root node), ending + /// with the node that proves the absence of the key. + fn get_proof(&self, key: &[u8]) -> TrieResult; + + /// return value if key exists, None if key not exist, Error if proof is wrong + fn verify_proof(root_hash: Vec, key: &[u8], proof: Proof) -> TrieResult>>; +} + +impl Trie for MerklePatriciaTrie { + /// Returns the value for key stored in the trie. + fn get(&self, key: &[u8]) -> TrieResult>> { + self.get_at(self.root.clone(), &Nibbles::from_raw(key.to_vec(), true)) + } + + /// Checks that the key is present in the trie + fn contains(&self, key: &[u8]) -> TrieResult { + Ok(self + .get_at(self.root.clone(), &Nibbles::from_raw(key.to_vec(), true))? + .map_or(false, |_| true)) + } + + /// Inserts value into trie and modifies it if it exists + fn insert(&mut self, key: Vec, value: Vec) -> TrieResult { + if value.is_empty() { + self.remove(&key)?; + return Ok(false); + } + let root = self.root.clone(); + self.root = self.insert_at(root, Nibbles::from_raw(key, true), value.to_vec())?; + Ok(true) + } + + /// Removes any existing value for key from the trie. + fn remove(&mut self, key: &[u8]) -> TrieResult { + let (n, removed) = self.delete_at(self.root.clone(), &Nibbles::from_raw(key.to_vec(), true))?; + self.root = n; + Ok(removed) + } + + /// Saves all the nodes in the db, clears the cache data, recalculates the root. + /// Returns the root hash of the trie. + fn root(&mut self) -> TrieResult> { + self.commit() + } + + /// Prove constructs a merkle proof for key. The result contains all encoded nodes + /// on the path to the value at key. The value itself is also included in the last + /// node and can be retrieved by verifying the proof. + /// + /// If the trie does not contain a value for key, the returned proof contains all + /// nodes of the longest existing prefix of the key (at least the root node), ending + /// with the node that proves the absence of the key. + fn get_proof(&self, key: &[u8]) -> TrieResult { + let mut path = self.get_path_at(self.root.clone(), &Nibbles::from_raw(key.to_vec(), true))?; + match self.root { + Node::Empty => {} + _ => path.push(self.root.clone()), + } + Ok(Proof { + nodes: path.into_iter().rev().map(|n| self.encode_raw(n)).collect(), + }) + } + + /// return value if key exists, None if key not exist, Error if proof is wrong + /// + /// insert data to memory db, and check root. if value exists, means ok . + fn verify_proof(root_hash: Vec, key: &[u8], proof: Proof) -> TrieResult>> { + let memdb = Rc::new(MemoryDB::new()); + for node_encoded in proof.nodes.into_iter() { + let hash = hasher_digest(&node_encoded); + + if root_hash.eq(&hash) || node_encoded.len() >= LENGTH { + memdb.insert(hash, node_encoded); + } + } + let trie = MerklePatriciaTrie::from(memdb, &root_hash).or(Err(TrieError::InvalidProof))?; + + trie.get(key).or(Err(TrieError::InvalidProof)) + } +} + +impl MerklePatriciaTrie { + pub fn iter(&self) -> TrieIterator { + let mut nodes = Vec::new(); + nodes.push((self.root.clone()).into()); + TrieIterator { + trie: self, + nibble: Nibbles::from_raw(vec![], false), + nodes, + } + } + + fn get_at(&self, n: Node, partial: &Nibbles) -> TrieResult>> { + match n { + Node::Empty => Ok(None), + Node::Leaf(leaf) => { + let borrow_leaf = leaf.borrow(); + + if &borrow_leaf.key == partial { + Ok(Some(borrow_leaf.value.clone())) + } else { + Ok(None) + } + } + Node::Branch(branch) => { + let borrow_branch = branch.borrow(); + + if partial.is_empty() || partial.at(0) == 16 { + Ok(borrow_branch.value.clone()) + } else { + let index = partial.at(0); + self.get_at(borrow_branch.children[index].clone(), &partial.offset(1)) + } + } + Node::Extension(extension) => { + let extension = extension.borrow(); + + let prefix = &extension.prefix; + let match_len = partial.common_prefix(&prefix); + if match_len == prefix.len() { + self.get_at(extension.node.clone(), &partial.offset(match_len)) + } else { + Ok(None) + } + } + Node::Hash(hash_node) => { + let borrow_hash_node = hash_node.borrow(); + let n = self.recover_from_db(&borrow_hash_node.hash)?; + self.get_at(n, partial) + } + } + } + + fn insert_at(&self, n: Node, partial: Nibbles, value: Vec) -> TrieResult { + match n { + Node::Empty => Ok(Node::from_leaf(partial, value)), + Node::Leaf(leaf) => { + let mut borrow_leaf = leaf.borrow_mut(); + + let old_partial = &borrow_leaf.key; + let match_index = partial.common_prefix(old_partial); + if match_index == old_partial.len() { + // replace leaf value + borrow_leaf.value = value; + return Ok(Node::Leaf(leaf.clone())); + } + + let mut branch = BranchNode { + children: empty_children(), + value: None, + }; + + let n = Node::from_leaf(old_partial.offset(match_index + 1), borrow_leaf.value.clone()); + branch.insert(old_partial.at(match_index), n); + + let n = Node::from_leaf(partial.offset(match_index + 1), value); + branch.insert(partial.at(match_index), n); + + if match_index == 0 { + return Ok(Node::Branch(Rc::new(RefCell::new(branch)))); + } + + // if include a common prefix + Ok(Node::from_extension( + partial.slice(0, match_index), + Node::Branch(Rc::new(RefCell::new(branch))), + )) + } + Node::Branch(branch) => { + let mut borrow_branch = branch.borrow_mut(); + + if partial.at(0) == 0x10 { + borrow_branch.value = Some(value); + return Ok(Node::Branch(branch.clone())); + } + + let child = borrow_branch.children[partial.at(0)].clone(); + let new_child = self.insert_at(child, partial.offset(1), value)?; + borrow_branch.children[partial.at(0)] = new_child; + Ok(Node::Branch(branch.clone())) + } + Node::Extension(ext) => { + let mut borrow_ext = ext.borrow_mut(); + + let prefix = &borrow_ext.prefix; + let sub_node = borrow_ext.node.clone(); + let match_index = partial.common_prefix(&prefix); + + if match_index == 0 { + let mut branch = BranchNode { + children: empty_children(), + value: None, + }; + branch.insert( + prefix.at(0), + if prefix.len() == 1 { + sub_node + } else { + Node::from_extension(prefix.offset(1), sub_node) + }, + ); + let node = Node::Branch(Rc::new(RefCell::new(branch))); + + return self.insert_at(node, partial, value); + } + + if match_index == prefix.len() { + let new_node = self.insert_at(sub_node, partial.offset(match_index), value)?; + return Ok(Node::from_extension(prefix.clone(), new_node)); + } + + let new_ext = Node::from_extension(prefix.offset(match_index), sub_node); + let new_node = self.insert_at(new_ext, partial.offset(match_index), value)?; + borrow_ext.prefix = prefix.slice(0, match_index); + borrow_ext.node = new_node; + Ok(Node::Extension(ext.clone())) + } + Node::Hash(hash_node) => { + let borrow_hash_node = hash_node.borrow(); + + self.passing_keys.borrow_mut().insert(borrow_hash_node.hash.to_vec()); + let n = self.recover_from_db(&borrow_hash_node.hash)?; + self.insert_at(n, partial, value) + } + } + } + + fn delete_at(&self, n: Node, partial: &Nibbles) -> TrieResult<(Node, bool)> { + let (new_n, deleted) = match n { + Node::Empty => Ok((Node::Empty, false)), + Node::Leaf(leaf) => { + let borrow_leaf = leaf.borrow(); + + if &borrow_leaf.key == partial { + return Ok((Node::Empty, true)); + } + Ok((Node::Leaf(leaf.clone()), false)) + } + Node::Branch(branch) => { + let mut borrow_branch = branch.borrow_mut(); + + if partial.at(0) == 0x10 { + borrow_branch.value = None; + return Ok((Node::Branch(branch.clone()), true)); + } + + let index = partial.at(0); + let node = borrow_branch.children[index].clone(); + + let (new_n, deleted) = self.delete_at(node, &partial.offset(1))?; + if deleted { + borrow_branch.children[index] = new_n; + } + + Ok((Node::Branch(branch.clone()), deleted)) + } + Node::Extension(ext) => { + let mut borrow_ext = ext.borrow_mut(); + + let prefix = &borrow_ext.prefix; + let match_len = partial.common_prefix(prefix); + + if match_len == prefix.len() { + let (new_n, deleted) = self.delete_at(borrow_ext.node.clone(), &partial.offset(match_len))?; + + if deleted { + borrow_ext.node = new_n; + } + + Ok((Node::Extension(ext.clone()), deleted)) + } else { + Ok((Node::Extension(ext.clone()), false)) + } + } + Node::Hash(hash_node) => { + let hash = hash_node.borrow().hash.clone(); + self.passing_keys.borrow_mut().insert(hash.clone()); + + let n = self.recover_from_db(&hash)?; + self.delete_at(n, partial) + } + }?; + + if deleted { + Ok((self.degenerate(new_n)?, deleted)) + } else { + Ok((new_n, deleted)) + } + } + + fn degenerate(&self, n: Node) -> TrieResult { + match n { + Node::Branch(branch) => { + let borrow_branch = branch.borrow(); + + let mut used_indexs = vec![]; + for (index, node) in borrow_branch.children.iter().enumerate() { + match node { + Node::Empty => continue, + _ => used_indexs.push(index), + } + } + + // if only a value node, transmute to leaf. + if used_indexs.is_empty() && borrow_branch.value.is_some() { + let key = Nibbles::from_raw([].to_vec(), true); + let value = borrow_branch.value.clone().unwrap(); + Ok(Node::from_leaf(key, value)) + // if only one node. make an extension. + } else if used_indexs.len() == 1 && borrow_branch.value.is_none() { + let used_index = used_indexs[0]; + let n = borrow_branch.children[used_index].clone(); + + let new_node = Node::from_extension(Nibbles::from_hex(vec![used_index as u8]), n); + self.degenerate(new_node) + } else { + Ok(Node::Branch(branch.clone())) + } + } + Node::Extension(ext) => { + let borrow_ext = ext.borrow(); + + let prefix = &borrow_ext.prefix; + match borrow_ext.node.clone() { + Node::Extension(sub_ext) => { + let borrow_sub_ext = sub_ext.borrow(); + + let new_prefix = prefix.join(&borrow_sub_ext.prefix); + let new_n = Node::from_extension(new_prefix, borrow_sub_ext.node.clone()); + self.degenerate(new_n) + } + Node::Leaf(leaf) => { + let borrow_leaf = leaf.borrow(); + + let new_prefix = prefix.join(&borrow_leaf.key); + Ok(Node::from_leaf(new_prefix, borrow_leaf.value.clone())) + } + // try again after recovering node from the db. + Node::Hash(hash_node) => { + let hash = hash_node.borrow().hash.clone(); + self.passing_keys.borrow_mut().insert(hash.clone()); + + let new_node = self.recover_from_db(&hash)?; + + let n = Node::from_extension(borrow_ext.prefix.clone(), new_node); + self.degenerate(n) + } + _ => Ok(Node::Extension(ext.clone())), + } + } + _ => Ok(n), + } + } + + // Get nodes path along the key, only the nodes whose encode length is greater than + // hash length are added. + // For embedded nodes whose data are already contained in their parent node, we don't need to + // add them in the path. + // In the code below, we only add the nodes get by `get_node_from_hash`, because they contains + // all data stored in db, including nodes whose encoded data is less than hash length. + fn get_path_at(&self, n: Node, partial: &Nibbles) -> TrieResult> { + match n { + Node::Empty | Node::Leaf(_) => Ok(vec![]), + Node::Branch(branch) => { + let borrow_branch = branch.borrow(); + + if partial.is_empty() || partial.at(0) == 16 { + Ok(vec![]) + } else { + let node = borrow_branch.children[partial.at(0)].clone(); + self.get_path_at(node, &partial.offset(1)) + } + } + Node::Extension(ext) => { + let borrow_ext = ext.borrow(); + + let prefix = &borrow_ext.prefix; + let match_len = partial.common_prefix(prefix); + + if match_len == prefix.len() { + self.get_path_at(borrow_ext.node.clone(), &partial.offset(match_len)) + } else { + Ok(vec![]) + } + } + Node::Hash(hash_node) => { + let n = self.recover_from_db(&hash_node.borrow().hash.clone())?; + let mut rest = self.get_path_at(n.clone(), partial)?; + rest.push(n); + Ok(rest) + } + } + } + + fn commit(&mut self) -> TrieResult> { + let encoded = self.encode_node(self.root.clone()); + let root_hash = if encoded.len() < LENGTH { + let hash = hasher_digest(&encoded); + self.cache.borrow_mut().insert(hash.clone(), encoded); + hash + } else { + encoded + }; + + let mut keys = Vec::with_capacity(self.cache.borrow().len()); + let mut values = Vec::with_capacity(self.cache.borrow().len()); + for (k, v) in self.cache.borrow_mut().drain() { + keys.push(k.to_vec()); + values.push(v); + } + + self.db.insert_batch(keys, values); + + let removed_keys: Vec> = self + .passing_keys + .borrow() + .iter() + .filter(|h| !self.gen_keys.borrow().contains(&h.to_vec())) + .map(|h| h.to_vec()) + .collect(); + + self.db.remove_batch(&removed_keys); + + self.root_hash = root_hash.to_vec(); + self.gen_keys.borrow_mut().clear(); + self.passing_keys.borrow_mut().clear(); + self.root = self.recover_from_db(&root_hash)?; + Ok(root_hash) + } + + fn encode_node(&self, n: Node) -> Vec { + // Returns the hash value directly to avoid double counting. + if let Node::Hash(hash_node) = n { + return hash_node.borrow().hash.clone(); + } + + let data = self.encode_raw(n.clone()); + // Nodes smaller than 32 bytes are stored inside their parent, + // Nodes equal to 32 bytes are returned directly + if data.len() < LENGTH { + data + } else { + let hash = hasher_digest(&data); + self.cache.borrow_mut().insert(hash.clone(), data); + + self.gen_keys.borrow_mut().insert(hash.clone()); + hash + } + } + + fn encode_raw(&self, n: Node) -> Vec { + match n { + Node::Empty => rlp::NULL_RLP.to_vec(), + Node::Leaf(leaf) => { + let borrow_leaf = leaf.borrow(); + + let mut stream = RlpStream::new_list(2); + stream.append(&borrow_leaf.key.encode_compact()); + stream.append(&borrow_leaf.value); + stream.out() + } + Node::Branch(branch) => { + let borrow_branch = branch.borrow(); + + let mut stream = RlpStream::new_list(17); + for i in 0..16 { + let n = borrow_branch.children[i].clone(); + let data = self.encode_node(n); + if data.len() == LENGTH { + stream.append(&data); + } else { + stream.append_raw(&data, 1); + } + } + + match &borrow_branch.value { + Some(v) => stream.append(v), + None => stream.append_empty_data(), + }; + stream.out() + } + Node::Extension(ext) => { + let borrow_ext = ext.borrow(); + + let mut stream = RlpStream::new_list(2); + stream.append(&borrow_ext.prefix.encode_compact()); + let data = self.encode_node(borrow_ext.node.clone()); + if data.len() == LENGTH { + stream.append(&data); + } else { + stream.append_raw(&data, 1); + } + stream.out() + } + Node::Hash(_hash) => unreachable!(), + } + } + + fn decode_node(&self, data: &[u8]) -> TrieResult { + let r = Rlp::new(data); + + match r.prototype()? { + Prototype::Data(0) => Ok(Node::Empty), + // extension node or leaf node + Prototype::List(2) => { + let key = r.at(0)?.data()?; + let key = Nibbles::from_compact(key.to_vec()); + + if key.is_leaf() { + Ok(Node::from_leaf(key, r.at(1)?.data()?.to_vec())) + } else { + let n = self.decode_node(r.at(1)?.as_raw())?; + + Ok(Node::from_extension(key, n)) + } + } + // branch node + Prototype::List(17) => { + let mut nodes = empty_children(); + #[allow(clippy::needless_range_loop)] + for i in 0..nodes.len() { + let rlp_data = r.at(i)?; + let n = self.decode_node(rlp_data.as_raw())?; + nodes[i] = n; + } + + // The last element is a value node. + let value_rlp = r.at(16)?; + let value = if value_rlp.is_empty() { + None + } else { + Some(value_rlp.data()?.to_vec()) + }; + + Ok(Node::from_branch(nodes, value)) + } + _ => { + if r.is_data() && r.size() == LENGTH { + Ok(Node::from_hash(r.data()?.to_vec())) + } else { + Err(TrieError::InvalidData) + } + } + } + } + + fn recover_from_db(&self, key: &[u8]) -> TrieResult { + match self.db.get(key) { + Some(value) => Ok(self.decode_node(&value)?), + None => Ok(Node::Empty), + } + } +} + +#[derive(Clone, Debug)] +enum TraceStatus { + Start, + Doing, + Child(u8), + End, +} + +#[derive(Clone, Debug)] +struct TraceNode { + node: Node, + status: TraceStatus, +} + +impl TraceNode { + fn advance(&mut self) { + self.status = match &self.status { + TraceStatus::Start => TraceStatus::Doing, + TraceStatus::Doing => match self.node { + Node::Branch(_) => TraceStatus::Child(0), + _ => TraceStatus::End, + }, + TraceStatus::Child(i) if *i < 15 => TraceStatus::Child(i + 1), + _ => TraceStatus::End, + } + } +} + +impl From for TraceNode { + fn from(node: Node) -> TraceNode { + TraceNode { + node, + status: TraceStatus::Start, + } + } +} + +pub struct TrieIterator<'a> { + trie: &'a MerklePatriciaTrie, + nibble: Nibbles, + nodes: Vec, +} + +impl<'a> Iterator for TrieIterator<'a> { + type Item = (Vec, Vec); + + fn next(&mut self) -> Option { + loop { + let mut now = self.nodes.last().cloned(); + if let Some(ref mut now) = now { + self.nodes.last_mut().unwrap().advance(); + + match (now.status.clone(), &now.node) { + (TraceStatus::End, node) => { + match *node { + Node::Leaf(ref leaf) => { + let cur_len = self.nibble.len(); + self.nibble.truncate(cur_len - leaf.borrow().key.len()); + } + + Node::Extension(ref ext) => { + let cur_len = self.nibble.len(); + self.nibble.truncate(cur_len - ext.borrow().prefix.len()); + } + + Node::Branch(_) => { + self.nibble.pop(); + } + _ => {} + } + self.nodes.pop(); + } + + (TraceStatus::Doing, Node::Extension(ref ext)) => { + self.nibble.extend(&ext.borrow().prefix); + self.nodes.push((ext.borrow().node.clone()).into()); + } + + (TraceStatus::Doing, Node::Leaf(ref leaf)) => { + self.nibble.extend(&leaf.borrow().key); + return Some((self.nibble.encode_raw().0, leaf.borrow().value.clone())); + } + + (TraceStatus::Doing, Node::Branch(ref branch)) => { + let value = branch.borrow().value.clone(); + if value.is_none() { + continue; + } else { + return Some((self.nibble.encode_raw().0, value.unwrap())); + } + } + + (TraceStatus::Doing, Node::Hash(ref hash_node)) => { + if let Ok(n) = self.trie.recover_from_db(&hash_node.borrow().hash.clone()) { + self.nodes.pop(); + self.nodes.push(n.into()); + } else { + //error!(); + return None; + } + } + + (TraceStatus::Child(i), Node::Branch(ref branch)) => { + if i == 0 { + self.nibble.push(0); + } else { + self.nibble.pop(); + self.nibble.push(i); + } + self.nodes.push((branch.borrow().children[i as usize].clone()).into()); + } + + (_, Node::Empty) => { + self.nodes.pop(); + } + _ => {} + } + } else { + return None; + } + } + } +} + +#[cfg(test)] +mod tests { + use rand::distributions::Alphanumeric; + use rand::seq::SliceRandom; + use rand::{thread_rng, Rng}; + use std::collections::{HashMap, HashSet}; + use std::rc::Rc; + + use ethereum_types; + + use super::*; + use crate::db::MemoryDB; + use core::borrow::Borrow; + + #[test] + fn test_trie_insert() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + } + + #[test] + fn test_trie_get() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + let v = trie.get(b"test").unwrap(); + + assert_eq!(Some(b"test".to_vec()), v) + } + + #[test] + fn test_trie_random_insert() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + + for _ in 0..1000 { + let rand_str: String = thread_rng().sample_iter(&Alphanumeric).take(30).collect(); + let val = rand_str.as_bytes(); + trie.insert(val.to_vec(), val.to_vec()).unwrap(); + + let v = trie.get(val).unwrap(); + assert_eq!(v.map(|v| v.to_vec()), Some(val.to_vec())); + } + } + + #[test] + fn test_trie_contains() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + assert_eq!(true, trie.contains(b"test").unwrap()); + assert_eq!(false, trie.contains(b"test2").unwrap()); + } + + #[test] + fn test_trie_remove() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + let removed = trie.remove(b"test").unwrap(); + assert_eq!(true, removed) + } + + #[test] + fn test_trie_random_remove() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + + for _ in 0..1000 { + let rand_str: String = thread_rng().sample_iter(&Alphanumeric).take(30).collect(); + let val = rand_str.as_bytes(); + trie.insert(val.to_vec(), val.to_vec()).unwrap(); + + let removed = trie.remove(val).unwrap(); + assert_eq!(true, removed); + } + } + + #[test] + fn test_trie_from_root() { + let memdb = Rc::new(MemoryDB::new()); + let root = { + let mut trie = MerklePatriciaTrie::new(memdb.clone()); + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test1".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test2".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test23".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test33".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test44".to_vec(), b"test".to_vec()).unwrap(); + trie.root().unwrap() + }; + + let mut trie = MerklePatriciaTrie::from(Rc::clone(&memdb), &root).unwrap(); + let v1 = trie.get(b"test33").unwrap(); + assert_eq!(Some(b"test".to_vec()), v1); + let v2 = trie.get(b"test44").unwrap(); + assert_eq!(Some(b"test".to_vec()), v2); + let root2 = trie.root().unwrap(); + assert_eq!(hex::encode(root), hex::encode(root2)); + } + + #[test] + fn test_trie_from_root_and_insert() { + let memdb = Rc::new(MemoryDB::new()); + let root = { + let mut trie = MerklePatriciaTrie::new(memdb.clone()); + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test1".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test2".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test23".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test33".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test44".to_vec(), b"test".to_vec()).unwrap(); + trie.commit().unwrap() + }; + + let mut trie = MerklePatriciaTrie::from(Rc::clone(&memdb), &root).unwrap(); + trie.insert(b"test55".to_vec(), b"test55".to_vec()).unwrap(); + trie.commit().unwrap(); + let v = trie.get(b"test55").unwrap(); + assert_eq!(Some(b"test55".to_vec()), v); + } + + #[test] + fn test_trie_from_root_and_delete() { + let memdb = Rc::new(MemoryDB::new()); + let root = { + let mut trie = MerklePatriciaTrie::new(memdb.clone()); + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test1".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test2".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test23".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test33".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test44".to_vec(), b"test".to_vec()).unwrap(); + trie.commit().unwrap() + }; + + let mut trie = MerklePatriciaTrie::from(Rc::clone(&memdb), &root).unwrap(); + let removed = trie.remove(b"test44").unwrap(); + assert_eq!(true, removed); + let removed = trie.remove(b"test33").unwrap(); + assert_eq!(true, removed); + let removed = trie.remove(b"test23").unwrap(); + assert_eq!(true, removed); + } + + #[test] + fn test_multiple_trie_roots() { + let k0: ethereum_types::H256 = 0.into(); + let k1: ethereum_types::H256 = 1.into(); + let v: ethereum_types::H256 = 0x1234.into(); + + let root1 = { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + trie.insert(k0.as_bytes().to_vec(), v.as_bytes().to_vec()).unwrap(); + trie.root().unwrap() + }; + + let root2 = { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + trie.insert(k0.as_bytes().to_vec(), v.as_bytes().to_vec()).unwrap(); + trie.insert(k1.as_bytes().to_vec(), v.as_bytes().to_vec()).unwrap(); + trie.root().unwrap(); + trie.remove(k1.as_ref()).unwrap(); + trie.root().unwrap() + }; + + let root3 = { + let memdb = Rc::new(MemoryDB::new()); + let mut trie1 = MerklePatriciaTrie::new(memdb.clone()); + trie1.insert(k0.as_bytes().to_vec(), v.as_bytes().to_vec()).unwrap(); + trie1.insert(k1.as_bytes().to_vec(), v.as_bytes().to_vec()).unwrap(); + trie1.root().unwrap(); + let root = trie1.root().unwrap(); + let mut trie2 = MerklePatriciaTrie::from(Rc::clone(&memdb), &root).unwrap(); + trie2.remove(&k1.as_bytes().to_vec()).unwrap(); + trie2.root().unwrap() + }; + + assert_eq!(root1, root2); + assert_eq!(root2, root3); + } + + #[test] + fn test_delete_stale_keys_with_random_insert_and_delete() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + + let mut rng = rand::thread_rng(); + let mut keys = vec![]; + for _ in 0..100 { + let random_bytes: Vec = (0..rng.gen_range(2, 30)).map(|_| rand::random::()).collect(); + trie.insert(random_bytes.clone(), random_bytes.clone()).unwrap(); + keys.push(random_bytes.clone()); + } + trie.commit().unwrap(); + let slice = &mut keys; + slice.shuffle(&mut rng); + + for key in slice.iter() { + trie.remove(key).unwrap(); + } + trie.commit().unwrap(); + + println!("{:?}", trie); + let empty_node_key = hasher_digest(&rlp::NULL_RLP); + println!("empty key{:?}", empty_node_key); + let value = trie.db.get(empty_node_key.as_ref()).unwrap(); + assert_eq!(value, &rlp::NULL_RLP) + } + + #[test] + fn insert_full_branch() { + let memdb = Rc::new(MemoryDB::new()); + let mut trie = MerklePatriciaTrie::new(memdb); + + trie.insert(b"test".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test1".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test2".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test23".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test33".to_vec(), b"test".to_vec()).unwrap(); + trie.insert(b"test44".to_vec(), b"test".to_vec()).unwrap(); + trie.root().unwrap(); + + let v = trie.get(b"test").unwrap(); + assert_eq!(Some(b"test".to_vec()), v); + } + + #[test] + fn iterator_trie() { + let memdb = Rc::new(MemoryDB::new()); + let mut root1; + let mut kv = HashMap::new(); + kv.insert(b"test".to_vec(), b"test".to_vec()); + kv.insert(b"test1".to_vec(), b"test1".to_vec()); + kv.insert(b"test11".to_vec(), b"test2".to_vec()); + kv.insert(b"test14".to_vec(), b"test3".to_vec()); + kv.insert(b"test16".to_vec(), b"test4".to_vec()); + kv.insert(b"test18".to_vec(), b"test5".to_vec()); + kv.insert(b"test2".to_vec(), b"test6".to_vec()); + kv.insert(b"test23".to_vec(), b"test7".to_vec()); + kv.insert(b"test9".to_vec(), b"test8".to_vec()); + { + let mut trie = MerklePatriciaTrie::new(memdb.clone()); + let mut kv = kv.clone(); + kv.iter().for_each(|(k, v)| { + trie.insert(k.clone(), v.clone()).unwrap(); + }); + root1 = trie.root().unwrap(); + + trie.iter().for_each(|(k, v)| assert_eq!(kv.remove(&k).unwrap(), v)); + assert!(kv.is_empty()); + } + + { + let mut trie = MerklePatriciaTrie::new(Rc::clone(&memdb)); + let mut kv2 = HashMap::new(); + kv2.insert(b"test".to_vec(), b"test11".to_vec()); + kv2.insert(b"test1".to_vec(), b"test12".to_vec()); + kv2.insert(b"test14".to_vec(), b"test13".to_vec()); + kv2.insert(b"test22".to_vec(), b"test14".to_vec()); + kv2.insert(b"test9".to_vec(), b"test15".to_vec()); + kv2.insert(b"test16".to_vec(), b"test16".to_vec()); + kv2.insert(b"test2".to_vec(), b"test17".to_vec()); + kv2.iter().for_each(|(k, v)| { + trie.insert(k.clone(), v.clone()).unwrap(); + }); + + trie.root().unwrap(); + + let mut kv_delete = HashSet::new(); + kv_delete.insert(b"test".to_vec()); + kv_delete.insert(b"test1".to_vec()); + kv_delete.insert(b"test14".to_vec()); + + kv_delete.iter().for_each(|k| { + trie.remove(&k).unwrap(); + }); + + kv2.retain(|k, _| !kv_delete.contains(k)); + + trie.root().unwrap(); + trie.iter().for_each(|(k, v)| assert_eq!(kv2.remove(&k).unwrap(), v)); + assert!(kv2.is_empty()); + } + + let trie = MerklePatriciaTrie::from(Rc::clone(&memdb), &root1).unwrap(); + trie.iter().for_each(|(k, v)| assert_eq!(kv.remove(&k).unwrap(), v)); + assert!(kv.is_empty()); + } +} diff --git a/core/sr-eth-primitives/Cargo.toml b/core/sr-eth-primitives/Cargo.toml index 43020e065..2271bd211 100644 --- a/core/sr-eth-primitives/Cargo.toml +++ b/core/sr-eth-primitives/Cargo.toml @@ -37,10 +37,6 @@ std = [ "rlp/std", "keccak-hash/std", "primitive-types/std", -# "primitive-types/serde", -# "primitive-types/byteorder", -# "primitive-types/rustc-hex", -# "primitive-types/libc", "ethereum-types/std", "impl-codec/std", "fixed-hash/std", diff --git a/core/sr-eth-primitives/src/header.rs b/core/sr-eth-primitives/src/header.rs index 13f351acb..36a14802a 100644 --- a/core/sr-eth-primitives/src/header.rs +++ b/core/sr-eth-primitives/src/header.rs @@ -1,6 +1,7 @@ use super::*; + +use codec::{Decode, Encode}; use ethbloom::Bloom; -use pow::EthashSeal; use rlp::RlpStream; use sr_primitives::RuntimeDebug; @@ -243,6 +244,54 @@ mod tests { (header1, header2) } + fn ropsten_sequential_header() -> (EthHeader, EthHeader) { + let mixh1 = H256::from(hex!("c4b28f4b671b2e675634f596840d3115ce3df0ab38b6608a69371da16a3455aa")); + let nonce1 = H64::from(hex!("7afbefa403b138fa")); + // #6890091 + // https://api-ropsten.etherscan.io/api?module=proxy&action=eth_getBlockByNumber&tag=0x69226b&boolean=true&apikey=YourApiKeyToken + // https://jsoneditoronline.org/ + let header1 = EthHeader { + parent_hash: H256::from(hex!("8a18726cacb45b078bfe6491510cfa2dd578a70be2a217f416253cf3e94adbd2")), + timestamp: 0x5de5246c, + number: 0x69226b, + author: Address::from(hex!("4ccfb3039b78d3938588157564c9ad559bafab94")), + transactions_root: H256::from(hex!("e3ab46e9eeb65fea6b0b1ffd07587f3ee7741b66f16a0b63a3b0c01900387833")), + uncles_hash: H256::from(hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")), + extra_data: "d983010906846765746889676f312e31312e3133856c696e7578".from_hex().unwrap(), + state_root: H256::from(hex!("de1df18f7da776a86119d17373d252d3591b5a4270e14113701d27c852d25313")), + receipts_root: H256::from(hex!("9c9eb20b6f9176864630f84aa11f33969a355efa85b2eb1e386a5b1ea3599089")), + log_bloom: Bloom::from_str("0420000400000018000400400402044000088100000088000000010000040800202000002000a0000000000200004000800100000200000000000020003400000000000004002000000000080102004400000000010400008001000000000020000000009200100000000000004408040100000010000010022002130002000600048200000000000000004000002410000008000000000008021800100000000704010008080000200081000000004002000000009010c000010082000040400104020200000000040180000000000a803000000000002212000000000061000010000001010000400020000000002000020008008100040000005200000000").unwrap(), + gas_used: 0x769975.into(), + gas_limit: 0x7a1200.into(), + difficulty: 0xf4009f4b_u64.into(), + seal: vec![rlp::encode(&mixh1), rlp::encode(&nonce1)], + hash: Some(H256::from(hex!("1dafbf6a9825241ea5dfa7c3a54781c0784428f2ef3b588748521f83209d3caa"))), + }; + + // # 6890092 + let mixh2 = H256::from(hex!("5a85e328a8bb041a386ffb25db029b7f0df4665a8a55b331b30a576761404fa6")); + let nonce2 = H64::from(hex!("650ea83006bb108d")); + let header2 = EthHeader { + parent_hash: H256::from(hex!("1dafbf6a9825241ea5dfa7c3a54781c0784428f2ef3b588748521f83209d3caa")), + timestamp: 0x5de52488, + number: 0x69226c, + author: Address::from(hex!("4ccfb3039b78d3938588157564c9ad559bafab94")), + transactions_root: H256::from(hex!("cd2672df775af7bcb2b93a478666d500dee3d78e6970c71071dc79642db24719")), + uncles_hash: H256::from(hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")), + extra_data: "d983010906846765746889676f312e31312e3133856c696e7578".from_hex().unwrap(), + state_root: H256::from(hex!("ee6ad25ad26e79004f15b8d423a9952859983ad740924fd13165d6e20953ff3e")), + receipts_root: H256::from(hex!("b2f020ce6615246a711bed61f2f485833943adb734d8e1cddd93d7ae8a641451")), + log_bloom: Bloom::from_str("8211a0050000250240000000010200402002800012890000600004000208230500042a400000000001000040c00080001001100000002000001004004012000010006200800900a03002510844010014a0000000010408600444200000200080000410001a00140004008000150108108000003010126a0110828010810000000200010000800011001000062040221422249420c1040a940002000000400840080000810000800000400000010408000002001018002200020040000000a00000804002800008000000000080800020082002000000002810054100500020000288240880290000510020000204c0304000000000000820088c800200000000").unwrap(), + gas_used: 0x702566.into(), + gas_limit: 0x7a1200.into(), + difficulty: 0xf3c49f25_u64.into(), + seal: vec![rlp::encode(&mixh2), rlp::encode(&nonce2)], + hash: Some(H256::from(hex!("21fe7ebfb3639254a0867995f3d490e186576b42aeea8c60f8e3360c256f7974"))), + }; + + (header1, header2) + } + #[test] fn can_do_proof_of_work_verification_fail() { let mut header: EthHeader = EthHeader::default(); @@ -273,11 +322,26 @@ mod tests { } #[test] - fn can_calculate_difficulty() { + fn can_calculate_difficulty_ropsten() { + let (header1, header2) = ropsten_sequential_header(); + let expected = U256::from_str("f3c49f25").unwrap(); + let mut ethash_params = EthashPartial::ropsten_test(); + // ethash_params.set_difficulty_bomb_delays(0xc3500, 5000000); + assert_eq!(ethash_params.calculate_difficulty(&header2, &header1), expected); + } + + #[test] + fn can_calculate_difficulty_production() { let (header1, header2) = sequential_header(); let expected = U256::from_str("92c07e50de0b9").unwrap(); - let mut ethash_params = EthashPartial::test(); - ethash_params.set_difficulty_bomb_delays(0xc3500, 5000000); + let mut ethash_params = EthashPartial::production(); assert_eq!(ethash_params.calculate_difficulty(&header2, &header1), expected); } + + #[test] + fn can_verify_basic_difficulty_production() { + let header = sequential_header().0; + let ethash_params = EthashPartial::production(); + assert_eq!(ethash_params.verify_block_basic(&header), Ok(())); + } } diff --git a/core/sr-eth-primitives/src/lib.rs b/core/sr-eth-primitives/src/lib.rs index 1244b9925..e5a0723ef 100644 --- a/core/sr-eth-primitives/src/lib.rs +++ b/core/sr-eth-primitives/src/lib.rs @@ -4,8 +4,6 @@ #[macro_use] pub extern crate rlp_derive; -use rstd::vec::Vec; - pub mod encoded; pub mod error; pub mod header; @@ -13,25 +11,12 @@ pub mod pow; pub mod receipt; //pub mod transaction; -use codec::{Decode, Encode}; pub use ethbloom::{Bloom, Input as BloomInput}; -use fixed_hash::construct_fixed_hash; -use impl_codec::impl_fixed_hash_codec; -use impl_rlp::impl_fixed_hash_rlp; - pub use ethereum_types::H64; pub use primitive_types::{H160, H256, U128, U256, U512}; + +use rstd::vec::Vec; + pub type Bytes = Vec; pub type Address = H160; pub type BlockNumber = u64; - -#[derive(Default, Clone, Copy, Eq, PartialEq, Encode, Decode)] -pub struct BestBlock { - height: BlockNumber, // enough for ethereum poa network (kovan) - hash: H256, - total_difficulty: U256, -} - -//construct_fixed_hash! {pub struct H64(8);} -//impl_fixed_hash_rlp!(H64, 8); -//impl_fixed_hash_codec!(H64, 8); diff --git a/core/sr-eth-primitives/src/pow.rs b/core/sr-eth-primitives/src/pow.rs index c70282a26..502b2befd 100644 --- a/core/sr-eth-primitives/src/pow.rs +++ b/core/sr-eth-primitives/src/pow.rs @@ -60,25 +60,56 @@ impl EthashPartial { } } - /// TODO: to find out the exact params, only for testing. - #[cfg(feature = "std")] - pub fn test() -> Self { + pub fn production() -> Self { EthashPartial { minimum_difficulty: U256::from(131072_u128), difficulty_bound_divisor: U256::from(0x0800), - difficulty_increment_divisor: 0x3C, - metropolis_difficulty_increment_divisor: 0x1E, - duration_limit: 0x3C, - homestead_transition: 0x30d40, + difficulty_increment_divisor: 10, + metropolis_difficulty_increment_divisor: 9, + duration_limit: 13, + homestead_transition: 1150000, + difficulty_hardfork_transition: u64::max_value(), + difficulty_hardfork_bound_divisor: U256::from(2048), + bomb_defuse_transition: u64::max_value(), + eip100b_transition: 4370000, + ecip1010_pause_transition: u64::max_value(), + ecip1010_continue_transition: u64::max_value(), + difficulty_bomb_delays: { + let mut m = BTreeMap::new(); + m.insert(4370000, 3000000); + m.insert(7280000, 2000000); + m + }, + expip2_transition: u64::max_value(), + expip2_duration_limit: 30, + progpow_transition: u64::max_value(), + } + } + + /// TODO: to find out the exact ropsten params, only for testing. + #[cfg(feature = "std")] + pub fn ropsten_test() -> Self { + EthashPartial { + minimum_difficulty: U256::from(0x20000), + difficulty_bound_divisor: U256::from(0x0800), + difficulty_increment_divisor: 10, + metropolis_difficulty_increment_divisor: 9, + duration_limit: 0xd, + homestead_transition: 0x0, difficulty_hardfork_transition: 0x59d9, - difficulty_hardfork_bound_divisor: U256::from(0x0200), - bomb_defuse_transition: 0x30d40, - eip100b_transition: 0xC3500, - ecip1010_pause_transition: 0x2dc6c0, - ecip1010_continue_transition: 0x4c4b40, - difficulty_bomb_delays: BTreeMap::::default(), - expip2_transition: 0xc3500, - expip2_duration_limit: 0x1e, + difficulty_hardfork_bound_divisor: U256::from(0x0800), + bomb_defuse_transition: u64::max_value(), + eip100b_transition: 0x19f0a0, + ecip1010_pause_transition: u64::max_value(), + ecip1010_continue_transition: u64::max_value(), + difficulty_bomb_delays: { + let mut m = BTreeMap::new(); + m.insert(0x19f0a0, 0x2dc6c0); + m.insert(0x408b70, 0x1e8480); + m + }, + expip2_transition: u64::max_value(), + expip2_duration_limit: 30, progpow_transition: u64::max_value(), } } diff --git a/core/sr-eth-primitives/src/receipt.rs b/core/sr-eth-primitives/src/receipt.rs index 6e309cd42..e34b2b807 100644 --- a/core/sr-eth-primitives/src/receipt.rs +++ b/core/sr-eth-primitives/src/receipt.rs @@ -7,7 +7,9 @@ use rstd::prelude::*; use codec::{Decode, Encode}; use primitive_types::{H256, U256}; -#[derive(PartialEq, Eq, Clone, Encode, Decode)] +use sr_primitives::RuntimeDebug; + +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub enum TransactionOutcome { /// Status and state root are unknown under EIP-98 rules. Unknown, @@ -17,7 +19,7 @@ pub enum TransactionOutcome { StatusCode(u8), } -#[derive(PartialEq, Eq, Clone, RlpEncodable, RlpDecodable, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, RlpEncodable, RlpDecodable, Encode, Decode, RuntimeDebug)] pub struct LogEntry { /// The address of the contract executing at the point of the `LOG` operation. pub address: Address, @@ -39,7 +41,7 @@ impl LogEntry { } } -#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct Receipt { /// The total gas used in the block following execution of the transaction. pub gas_used: U256, diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 3c6ec6709..645a32e2a 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -52,7 +52,7 @@ version = { package = "sr-version", git = "https://github.com/darwinia-network/s # darwinia balances = { package = "darwinia-balances", path = '../../srml/balances', default-features = false } darwinia-support = { path = "../../srml/support", default-features = false } -ethereum-bridge = { package = "darwinia-ethereum-bridge", path = "../../srml/ethereum-bridge", default-features = false } +eth-relay = { package = "darwinia-eth-relay", path = "../../srml/eth-relay", default-features = false } kton = { package = "darwinia-kton", path = '../../srml/kton', default-features = false } node-primitives = { path = "../primitives", default-features = false } staking = { package = "darwinia-staking", path = "../../srml/staking", default-features = false } @@ -109,7 +109,7 @@ std = [ # darwinia "balances/std", "darwinia-support/std", - "ethereum-bridge/std", + "eth-relay/std", "kton/std", "node-primitives/std", "staking/std", diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 947cb5e71..212d4b226 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -381,11 +381,9 @@ impl staking::Trait for Runtime { type SessionInterface = Self; } -//impl ethereum_bridge::Trait for Runtime { -// type Event = Event; -// type Ring = Balances; -// type Hash = Hash; -//} +impl eth_relay::Trait for Runtime { + type Event = Event; +} construct_runtime!( pub enum Runtime where @@ -419,7 +417,7 @@ construct_runtime!( Sudo: sudo, Utility: utility::{Module, Call, Event}, -// EthereumBridge: ethereum_bridge::{Storage, Module, Event, Call}, + EthRelay: eth_relay::{Storage, Module, Event, Call}, } ); diff --git a/srml/ethereum-bridge/Cargo.toml b/srml/eth-relay/Cargo.toml similarity index 83% rename from srml/ethereum-bridge/Cargo.toml rename to srml/eth-relay/Cargo.toml index b9320c2af..5a3888434 100644 --- a/srml/ethereum-bridge/Cargo.toml +++ b/srml/eth-relay/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "darwinia-ethereum-bridge" +name = "darwinia-eth-relay" version = "0.2.0" -authors = ["Xavier Lau "] +authors = ["Darwinia Network "] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,11 +15,10 @@ system = { package = "srml-system", git = "https://github.com/darwinia-network/ sr-primitives = { git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } support = { package = "srml-support", git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } sr-eth-primitives = { path = "../../core/sr-eth-primitives", default-features = false } -ethash = { git = "https://github.com/hammeWang/ethash-rs.git", rev = "70a4f078", default-features = false} -#merkle-mountain-range = { path = "../../core/merkle-mountain-range", default-features = false } -#web3 = {git = "https://github.com/ABMatrix/rust-web3.git", branch = "develop", default-features = false } rlp = { package = "rlp", git = "https://github.com/darwinia-network/parity-common.git", default-features = false} +ethash = { git = "https://github.com/hammeWang/ethash-rs.git", rev = "70a4f078", default-features = false} +merkle-patricia-trie = { path = "../../core/merkle-patricia-trie", default-features = false} [features] default = ["std"] @@ -33,4 +32,6 @@ std = [ "sr-eth-primitives/std", "ethash/std", "rlp/std", + "ethash/std", + "merkle-patricia-trie/std", ] diff --git a/srml/eth-relay/src/lib.rs b/srml/eth-relay/src/lib.rs new file mode 100644 index 000000000..9e3deefc8 --- /dev/null +++ b/srml/eth-relay/src/lib.rs @@ -0,0 +1,268 @@ +//! prototype module for bridging in ethereum poa blockcahin + +#![recursion_limit = "128"] +#![cfg_attr(not(feature = "std"), no_std)] + +// use blake2::Blake2b; +use codec::{Decode, Encode}; +use rstd::vec::Vec; +use sr_eth_primitives::{ + header::EthHeader, pow::EthashPartial, pow::EthashSeal, receipt::Receipt, BlockNumber as EthBlockNumber, H160, + H256, H64, U128, U256, U512, +}; + +use ethash::{EthereumPatch, LightDAG}; + +use support::{decl_event, decl_module, decl_storage, dispatch::Result, ensure, traits::Currency}; + +use system::ensure_signed; + +use sr_primitives::RuntimeDebug; + +use rlp::{decode, encode}; + +use merkle_patricia_trie::{trie::Trie, MerklePatriciaTrie, Proof}; + +type DAG = LightDAG; + +pub trait Trait: system::Trait { + type Event: From> + Into<::Event>; +} + +/// Familial details concerning a block +#[derive(Default, Clone, Copy, Eq, PartialEq, Encode, Decode)] +pub struct BlockDetails { + /// Block number + pub height: EthBlockNumber, + pub hash: H256, + /// Total difficulty of the block and all its parents + pub total_difficulty: U256, + // /// Parent block hash + // pub parent: H256, + // /// List of children block hashes + // pub children: Vec, + // /// Whether the block is considered finalized + // pub is_finalized: bool, +} + +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct ActionRecord { + pub index: u64, + pub proof: Vec, + pub header_hash: H256, +} + +decl_storage! { + trait Store for Module as EthRelay { + /// Anchor block that works as genesis block + pub BeginHeader get(fn begin_header): Option; + + /// Info of the best block header for now + pub BestHeaderHash get(fn best_header_hash): H256; + + pub HeaderOf get(header_of): map H256 => Option; + + pub HeaderDetailsOf get(header_details_of): map H256 => Option; + + /// Block delay for verify transaction + pub FinalizeNumber get(finalize_number): Option; + + pub ActionOf get(action_of): map T::Hash => Option; + + +// pub BestHashOf get(best_hash_of): map u64 => Option; + +// pub HashsOf get(hashs_of): map u64 => Vec; + +// pub HeaderForIndex get(header_for_index): map H256 => Vec<(u64, T::Hash)>; + } + add_extra_genesis { + config(header): Option>; + build(|config| { + if let Some(h) = &config.header { + let header: EthHeader = rlp::decode(&h).expect("can't deserialize the header"); + + // TODO: initilize other parameters. + >::genesis_header(&header); + } + }); + } +} + +decl_module! { + pub struct Module for enum Call + where + origin: T::Origin + { + fn deposit_event() = default; + + pub fn test_relay_header(origin, header: EthHeader) { + let _relayer = ensure_signed(origin)?; + + >::deposit_event(RawEvent::NewHeader(header)); + } + + pub fn relay_header(origin, header: EthHeader) { + let _relayer = ensure_signed(origin)?; + // 1. There must be a corresponding parent hash + // 2. Update best hash if the current block number is larger than current best block's number (Chain reorg) + + Self::verify_header(&header)?; + + let header_hash = header.hash(); + let block_number = header.number(); + + HeaderOf::insert(header_hash, &header); + + let prev_total_difficulty = Self::header_details_of(header.parent_hash()).unwrap().total_difficulty; + + HeaderDetailsOf::insert(header_hash, BlockDetails { + height: block_number, + hash: header_hash, + total_difficulty: prev_total_difficulty + header.difficulty() + }); + + let best_header_hash = Self::best_header_hash(); + let best_header = Self::header_of(best_header_hash).ok_or("Can not find best header."); + let best_header_details = Self::header_details_of(best_header_hash).unwrap(); + + // TODO: Check total difficulty and reorg if necessary. + if prev_total_difficulty + header.difficulty() > best_header_details.total_difficulty { + BestHeaderHash::mutate(|hash| { + *hash = header_hash; + }); + } + + >::deposit_event(RawEvent::NewHeader(header)); + } + + pub fn test_check_receipt(origin, receipt: Receipt, proof_record: ActionRecord) { + let _relayer = ensure_signed(origin)?; + + >::deposit_event(RawEvent::RelayProof(proof_record)); + } + + pub fn check_receipt(origin, receipt: Receipt, proof_record: ActionRecord) { + let _relayer = ensure_signed(origin)?; + + let header_hash = proof_record.header_hash; + if !HeaderOf::exists(header_hash) { + return Err("This block header does not exist.") + } + + let header = HeaderOf::get(header_hash).unwrap(); + + let proof: Proof = rlp::decode(&proof_record.proof).unwrap(); + let key = rlp::encode(&proof_record.index); + + let value = MerklePatriciaTrie::verify_proof(header.receipts_root().0.to_vec(), &key, proof) + .unwrap(); + assert!(value.is_some()); + + let receipt_encoded = rlp::encode(&receipt); + + assert_eq!(value.unwrap(), receipt_encoded); + // confirm that the block hash is right + // get the receipt MPT trie root from the block header + // Using receipt MPT trie root to verify the proof and index etc. + + >::deposit_event(RawEvent::RelayProof(proof_record)); + } + + // Assuming that there are at least one honest worker submiting headers + // This method may be merged together with relay_header + pub fn challenge_header(origin, header: EthHeader) { + // if header confirmed then return + // if header in unverified header then challenge + } + } +} + +decl_event! { + pub enum Event + where + ::AccountId + { + NewHeader(EthHeader), + RelayProof(ActionRecord), + TODO(AccountId), + } +} + +impl Module { + // TOOD: what is the total difficulty for genesis/begin header + pub fn genesis_header(header: &EthHeader) { + let header_hash = header.hash(); + // let block_number = header.number(); + + HeaderOf::insert(header_hash, header); + + // TODO: initialize the header details, including total difficulty. + + // Initialize the the best hash. + BestHeaderHash::mutate(|hash| { + *hash = header_hash; + }); + + // Initialize the header. + BeginHeader::put(header.clone()); + } + + /// 1. proof of difficulty + /// 2. proof of pow (mixhash) + /// 3. challenge + fn verify_header(header: &EthHeader) -> Result { + // check parent hash, + let parent_hash = header.parent_hash(); + + let number = header.number(); + ensure!( + number >= Self::begin_header().unwrap().number(), + "block nubmer is too small." + ); + + let prev_header = Self::header_of(parent_hash).unwrap(); + + ensure!((prev_header.number() + 1) == number, "Block number does not match."); + + // check difficulty + let ethash_params = EthashPartial::production(); + // ethash_params.set_difficulty_bomb_delays(0xc3500, 5000000); + let result = ethash_params.verify_block_basic(header); + match result { + Ok(_) => (), + Err(e) => { + return Err("Block difficulty verification failed."); + } + }; + + // verify difficulty + let difficulty = ethash_params.calculate_difficulty(header, &prev_header); + ensure!(difficulty == *header.difficulty(), "difficulty verification failed"); + + // verify mixhash + let seal = match EthashSeal::parse_seal(header.seal()) { + Err(e) => { + return Err("Seal parse error."); + } + Ok(x) => x, + }; + + let light_dag = DAG::new(number.into()); + let partial_header_hash = header.bare_hash(); + let mix_hash = light_dag.hashimoto(partial_header_hash, seal.nonce).0; + + if mix_hash != seal.mix_hash { + return Err("Mixhash does not match."); + } + + // ensure!(best_header.height == block_number, "Block height does not match."); + // ensure!(best_header.hash == *header.parent_hash(), "Block hash does not match."); + + Ok(()) + } + + fn _punish(_who: &T::AccountId) -> Result { + unimplemented!() + } +} diff --git a/srml/ethereum-bridge/src/lib.rs b/srml/ethereum-bridge/src/lib.rs deleted file mode 100644 index c3ece7c46..000000000 --- a/srml/ethereum-bridge/src/lib.rs +++ /dev/null @@ -1,157 +0,0 @@ -//! prototype module for bridging in ethereum poa blockcahin - -#![recursion_limit = "128"] -#![cfg_attr(not(feature = "std"), no_std)] - -// use blake2::Blake2b; -use codec::{Decode, Encode}; -use rstd::vec::Vec; -use sr_eth_primitives::{ - header::EthHeader, pow::EthashPartial, BestBlock, BlockNumber as EthBlockNumber, H160, H256, H64, U128, U256, U512, -}; - -use ethash::{EthereumPatch, LightDAG}; -use support::{decl_event, decl_module, decl_storage, dispatch::Result, ensure, traits::Currency}; -use system::ensure_signed; - -use sr_primitives::RuntimeDebug; - -use rlp::{decode, encode}; - -type DAG = LightDAG; - -pub trait Trait: system::Trait { - type Event: From> + Into<::Event>; - // type Hash: rstd::hash::Hash; -} - -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct Proof { - pub nodes: Vec>, -} - -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct ActionRecord { - pub index: u64, - pub proof: Vec, - pub header_hash: H256, -} - -decl_storage! { - trait Store for Module as EthBridge { - /// Anchor block that works as genesis block - pub BeginHeader get(fn begin_header): Option; - /// Info of the best block header for now - pub BestHeader get(fn best_header): BestBlock; - /// - pub BlockList get(fn block_list): map EthBlockNumber => Option; - /// nonce of each block - pub Nonce get(fn nonce): map EthBlockNumber => Option; - - pub HeaderOf get(header_of): map H256 => Option; - -// pub BestHashOf get(best_hash_of): map u64 => Option; -// pub HashsOf get(hashs_of): map u64 => Vec; - - /// Block delay for verify transaction - pub FinalizeNumber get(finalize_number): Option; - - pub ActionOf get(action_of): map T::Hash => Option; - - pub HeaderForIndex get(header_for_index): map H256 => Vec<(u64, T::Hash)>; - } - add_extra_genesis { - config(header): Option>; - build(|config| { - if let Some(h) = &config.header { - let header: EthHeader = rlp::decode(&h).expect("can't deserialize the header"); - BeginHeader::put(header.clone()); - - >::genesis_header(header); - } else { -// BeginNumber::put(config.number); - } - }); - } -} - -decl_module! { - pub struct Module for enum Call - where - origin: T::Origin - { - fn deposit_event() = default; - - pub fn store_block_header(origin, header: EthHeader) { - let _relayer = ensure_signed(origin)?; -// let _ = Self::verify(&header)?; - - >::deposit_event(RawEvent::NewHeader(header)); - } - - pub fn relay_receipt(origin, proof: ActionRecord) { - // confirm that the block hash is right - // get the receipt MPT trie root from the block header - // Using receipt MPT trie root to verify the proof and index etc. - - let _relayer = ensure_signed(origin)?; - - >::deposit_event(RawEvent::RelayProof(proof)); - } - - pub fn submit_header(origin, header: EthHeader) { - // if header confirmed then return - // if header in unverified header then challenge - } - } -} - -decl_event! { - pub enum Event - where - ::AccountId - { - NewHeader(EthHeader), - RelayProof(ActionRecord), - TODO(AccountId), - } -} - -impl Module { - pub fn genesis_header(header: EthHeader) { - unimplemented!() - } - - pub fn adjust_deposit_value() { - unimplemented!() - } - - /// 1. proof of difficulty - /// 2. proof of pow (mixhash) - /// 3. challenge - fn verify(header: &EthHeader, nonce: H64) -> Result { - let number = header.number(); - ensure!( - number >= Self::begin_header().unwrap().number(), - "block nubmer is too small." - ); - let prev_header = Self::block_list(number - 1).ok_or("import ancestor block first."); - - let mut ethash_params = EthashPartial::expanse(); - ethash_params.set_difficulty_bomb_delays(0xc3500, 5000000); - // verify difficulty - // let difficulty = ethash_params.calculate_difficulty(header, &prev_header); - // ensure!(difficulty == header.difficulty(), "difficulty verification failed"); - - // verify mixhash - let light_dag = DAG::new(number.into()); - let partial_header_hash = header.bare_hash(); - let mix_hash = light_dag.hashimoto(partial_header_hash, nonce); - - Ok(()) - } - - fn _punish(_who: &T::AccountId) -> Result { - unimplemented!() - } -} diff --git a/types.json b/types.json index 85b4e0b5f..8a395f06b 100644 --- a/types.json +++ b/types.json @@ -2,10 +2,11 @@ "EpochDuration": "u64", "EraIndex": "u32", "TimeStamp": "u64", - "RingBalanceOf": "u128", "KtonBalanceOf": "u128", "ExtendedBalance": "u128", + "Address": "H160", + "EthBlockNumber": "u64", "StakingBalance": { "_enum": { "Ring": "RingBalanceOf", @@ -62,5 +63,40 @@ "StakingLock": { "staking_amount": "u128", "unbondings": "Vec" + }, + "EthHeader": { + "parent_hash": "H256", + "timestamp": "u64", + "number": "EthBlockNumber", + "auth": "Address", + "transaction_root": "H256", + "uncles_hash": "H256", + "extra_data": "Bytes", + "state_root": "H256", + "receipts_root": "H256", + "log_bloom": "Bloom", + "gas_used": "U256", + "gas_limit": "U256", + "difficulty": "U256", + "seal": "Vec", + "hash": "Option" + }, + "ActionRecord": { + "index": "u64", + "proof": "Vec", + "header_hash": "H256" + }, + "BestBlock": { + "height": "EthBlockNumber", + "hash": "H256", + "total_difficulty": "U256" + }, + "H64": { + "_struct": "[u8; 8]" + }, + "BlockDetails": { + "height": "EthBlockNumber", + "hash": "H256", + "total_difficulty": "U256" } } \ No newline at end of file