diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index fc0129dbdb..dbaf8cd6fe 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -1,9 +1,9 @@ [[package]] name = "aho-corasick" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -11,13 +11,18 @@ name = "ansi_term" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ansi_term" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayvec" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", + "odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -35,27 +40,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "atty" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -63,8 +65,8 @@ name = "backtrace-sys" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -72,7 +74,16 @@ name = "base64" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -81,9 +92,9 @@ name = "bigint" version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -95,7 +106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "0.9.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -109,21 +120,21 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -133,12 +144,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" -version = "2.27.1" +version = "2.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -161,18 +172,14 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "crunchy" -version = "0.1.6" +name = "crossbeam" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "dbghelp-sys" -version = "0.2.0" +name = "crunchy" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "difference" @@ -184,6 +191,11 @@ name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "edit-distance" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "either" version = "1.4.0" @@ -194,7 +206,7 @@ name = "elastic-array" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -202,8 +214,8 @@ name = "env_logger" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -215,7 +227,29 @@ name = "error-chain" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "eth-secp256k1" +version = "0.5.7" +source = "git+https://github.com/paritytech/rust-secp256k1#6370d63adf4e8c91e2eae9225eef4b4e0294c5d0" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethbloom" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -224,41 +258,163 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethcore-bytes" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" + [[package]] name = "ethcore-bytes" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ethcore-io" +version = "1.9.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +dependencies = [ + "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethcore-logger" +version = "1.9.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +dependencies = [ + "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethcore-logger" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "isatty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethcore-network" +version = "1.9.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +dependencies = [ + "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bytes 0.1.0 (git+https://github.com/paritytech/parity.git)", + "ethcore-io 1.9.0 (git+https://github.com/paritytech/parity.git)", + "ethcore-logger 1.9.0 (git+https://github.com/paritytech/parity.git)", + "ethcrypto 0.1.0 (git+https://github.com/paritytech/parity.git)", + "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ethkey 0.3.0 (git+https://github.com/paritytech/parity.git)", + "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (git+https://github.com/paritytech/parity.git)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "path 0.1.0 (git+https://github.com/paritytech/parity.git)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.1 (git+https://github.com/paritytech/parity.git)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethcrypto" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +dependencies = [ + "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", + "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ethkey 0.3.0 (git+https://github.com/paritytech/parity.git)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethereum-types" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ethbloom 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethkey" +version = "0.3.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", + "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fixed-hash" -version = "0.1.0" -source = "git+https://github.com/paritytech/primitives.git#940a287e1e2c0a899ce27926d206c4c2925d009d" +version = "0.1.2" +source = "git+https://github.com/paritytech/primitives.git#30f15bb3387faf40f519dd56a5768cb3d3fe3638" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fixed-hash" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -269,49 +425,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fuchsia-zircon" -version = "0.2.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fuchsia-zircon-sys" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "futures" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-cpupool" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gcc" version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "globset" -version = "0.1.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -325,59 +482,131 @@ dependencies = [ [[package]] name = "heapsize" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "httparse" -version = "1.2.3" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.6" +version = "0.10.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hyper" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "idna" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "igd" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "iovec" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ipnetwork" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "isatty" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.3.4" @@ -385,70 +614,80 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jsonrpc-core" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966" +version = "8.0.1" +source = "git+https://github.com/paritytech/jsonrpc.git#d1e2cc48d962510328f7373509fb494a85dbeae8" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966" +source = "git+https://github.com/paritytech/jsonrpc.git#d1e2cc48d962510328f7373509fb494a85dbeae8" dependencies = [ - "hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "hyper 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", "jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-macros" version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966" +source = "git+https://github.com/paritytech/jsonrpc.git#d1e2cc48d962510328f7373509fb494a85dbeae8" dependencies = [ - "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", "jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-pubsub" version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966" +source = "git+https://github.com/paritytech/jsonrpc.git#d1e2cc48d962510328f7373509fb494a85dbeae8" dependencies = [ - "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-server-utils" version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966" +source = "git+https://github.com/paritytech/jsonrpc.git#d1e2cc48d962510328f7373509fb494a85dbeae8" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "keccak-hash" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +dependencies = [ + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "keccak-hash" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -467,30 +706,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "0.2.9" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazycell" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.33" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "log" -version = "0.3.8" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "matches" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "1.0.2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -502,31 +762,39 @@ dependencies = [ "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mime" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mime" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mio" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.1 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -548,6 +816,7 @@ dependencies = [ name = "native-runtime" version = "0.1.0" dependencies = [ + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-runtime-codec 0.1.0", "polkadot-runtime-std 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -560,7 +829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -572,20 +841,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num-traits" -version = "0.1.40" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "odds" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -601,32 +870,55 @@ name = "parity-wasm" version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-wordlist" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "path" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" + [[package]] name = "patricia-trie" version = "0.1.0" @@ -638,9 +930,9 @@ dependencies = [ "ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -664,13 +956,14 @@ version = "0.1.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-cli 0.1.0", + "polkadot-network 0.1.0", ] [[package]] name = "polkadot-candidate-agreement" version = "0.1.0" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -679,10 +972,10 @@ dependencies = [ name = "polkadot-cli" version = "0.1.0" dependencies = [ - "clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-client 0.1.0", "polkadot-executor 0.1.0", "polkadot-primitives 0.1.0", @@ -694,7 +987,10 @@ name = "polkadot-client" version = "0.1.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", + "polkadot-serializer 0.1.0", "polkadot-state-machine 0.1.0", ] @@ -702,7 +998,7 @@ dependencies = [ name = "polkadot-collator" version = "0.1.0" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", ] @@ -711,9 +1007,8 @@ name = "polkadot-executor" version = "0.1.0" dependencies = [ "assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "native-runtime 0.1.0", "parity-wasm 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", @@ -722,8 +1017,34 @@ dependencies = [ "polkadot-serializer 0.1.0", "polkadot-state-machine 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "polkadot-network" +version = "0.1.0" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-io 1.9.0 (git+https://github.com/paritytech/parity.git)", + "ethcore-network 1.9.0 (git+https://github.com/paritytech/parity.git)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "polkadot-client 0.1.0", + "polkadot-primitives 0.1.0", + "polkadot-serializer 0.1.0", + "polkadot-state-machine 0.1.0", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -731,16 +1052,16 @@ name = "polkadot-primitives" version = "0.1.0" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)", + "fixed-hash 0.1.2 (git+https://github.com/paritytech/primitives.git)", "polkadot-runtime-codec 0.1.0", "polkadot-serializer 0.1.0", - "pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.1.0 (git+https://github.com/paritytech/primitives.git)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -752,7 +1073,7 @@ version = "0.1.0" dependencies = [ "assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", "polkadot-client 0.1.0", "polkadot-executor 0.1.0", @@ -764,7 +1085,7 @@ dependencies = [ name = "polkadot-rpc-servers" version = "0.1.0" dependencies = [ - "jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", "jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", "polkadot-rpc 0.1.0", ] @@ -783,22 +1104,24 @@ dependencies = [ "pwasm-alloc 0.1.0", "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "polkadot-serializer" version = "0.1.0" dependencies = [ - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "polkadot-state-machine" version = "0.1.0" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", @@ -812,18 +1135,31 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", "polkadot-serializer 0.1.0", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pretty_assertions" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro-hack" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack-impl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pwasm-alloc" version = "0.1.0" @@ -843,11 +1179,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -864,15 +1210,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.31" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -880,32 +1226,32 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "relay" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -914,24 +1260,48 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rlp" +version = "0.2.1" +source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rlp" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-demangle" version = "0.1.5" @@ -943,12 +1313,9 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "rustc_version" -version = "0.1.7" +name = "rustc-serialize" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "rustc_version" @@ -973,11 +1340,6 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "semver" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "semver" version = "0.6.0" @@ -993,22 +1355,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.19" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.19" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1017,15 +1379,20 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "slab" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "slab" version = "0.3.0" @@ -1045,6 +1412,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "smallvec" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "snappy" +version = "0.1.0" +source = "git+https://github.com/paritytech/rust-snappy#858eac97192ea25d18d3f3626a8cc13ca0b175bb" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)", +] + +[[package]] +name = "snappy-sys" +version = "0.1.0" +source = "git+https://github.com/paritytech/rust-snappy#858eac97192ea25d18d3f3626a8cc13ca0b175bb" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "stable_deref_trait" @@ -1056,6 +1449,14 @@ name = "strsim" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "subtle" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.11.11" @@ -1084,8 +1485,8 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1099,39 +1500,38 @@ dependencies = [ [[package]] name = "thread_local" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "time" -version = "0.1.38" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tiny-keccak" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "tokio-core" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1142,9 +1542,9 @@ name = "tokio-io" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1152,14 +1552,14 @@ name = "tokio-proto" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1169,7 +1569,7 @@ name = "tokio-service" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1177,10 +1577,15 @@ name = "tokio-timer" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "triehash" version = "0.1.0" @@ -1196,27 +1601,64 @@ name = "twox-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "uint" +version = "0.1.0" +source = "git+https://github.com/paritytech/primitives.git#30f15bb3387faf40f519dd56a5768cb3d3fe3638" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uint" version = "0.1.0" -source = "git+https://github.com/paritytech/primitives.git#940a287e1e2c0a899ce27926d206c4c2925d009d" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicase" -version = "2.0.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicase" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.4" @@ -1240,6 +1682,16 @@ name = "untrusted" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "url" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1250,6 +1702,11 @@ name = "vec_map" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "version_check" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "void" version = "1.0.2" @@ -1260,11 +1717,30 @@ name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -1274,144 +1750,210 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "xml-rs" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xmltree" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "yaml-rust" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" +"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" -"checksum arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e003cbf6e0e1c43a0fc8df2ea8ea24174514d35cbcf60c35ca6112e0139f65e2" +"checksum arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "06f59fe10306bb78facd90d28c2038ad23ffaaefa85bac43c8a434cde383334f" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e772942dccdf11b368c31e044e4fca9189f80a773d2f0808379de65894cbf57" -"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" -"checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983" +"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859" +"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" +"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" "checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" -"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" -"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" +"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" +"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" +"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180" +"checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" -"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" +"checksum edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3bd26878c3d921f89797a4e1a1711919f999a9f6946bb6f5a4ffda126d297b7e" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +"checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "" +"checksum ethbloom 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5f7fb5d27fb017f21c15d1e0b953831b58581c9942a5e5614fd2b6603697b7" "checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5" +"checksum ethcore-bytes 0.1.0 (git+https://github.com/paritytech/parity.git)" = "" "checksum ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3977c772cd6c5c22e1c7cfa208e4c3b746bd6c3a6c8eeec0999a6b2103015ad5" +"checksum ethcore-io 1.9.0 (git+https://github.com/paritytech/parity.git)" = "" +"checksum ethcore-logger 1.9.0 (git+https://github.com/paritytech/parity.git)" = "" "checksum ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fd5813e49546030be7d134e775088d56b8ff4ab60617b90e93d4f0513da4c5b" -"checksum fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "" +"checksum ethcore-network 1.9.0 (git+https://github.com/paritytech/parity.git)" = "" +"checksum ethcrypto 0.1.0 (git+https://github.com/paritytech/parity.git)" = "" +"checksum ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2adaa5b8ceafcce0bc3a68ef116ca5702958cc97d70a6eb008aeddb569b092b3" +"checksum ethkey 0.3.0 (git+https://github.com/paritytech/parity.git)" = "" +"checksum fixed-hash 0.1.2 (git+https://github.com/paritytech/primitives.git)" = "" +"checksum fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4b54d107faeb66084eca7c506aa50b6b7cb9eb9a1f1f633ae2ca3af55620c191" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" -"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" -"checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" -"checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0bab5b5e94f5c31fc764ba5dd9ad16568aae5d4825538c01d6bca680c9bf94a7" +"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" -"checksum globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90d069fe6beb9be359ef505650b3f73228c5591a3c4b1f32be2f4f44459ffa3a" +"checksum globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "464627f948c3190ae3d04b1bc6d7dca2f785bda0ac01278e6db129ad383dbeb6" "checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5" -"checksum heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54fab2624374e5137ae4df13bf32b0b269cb804df42d13a51221bbd431d1a237" -"checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b45eac8b696d59491b079bd04fcb0f3488c0f6ed62dcb36bcfea8a543e9cdc3" -"checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" -"checksum isatty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "00c9301a947a2eaee7ce2556b80285dcc89558d07088962e6e8b9c25730f9dc6" +"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +"checksum hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd546ef520ab3745f1aae5f2cdc6de9e6498e94d1ab138b9eb3ddfbf335847fb" +"checksum hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea76da4c7f1a54d01d54985566d3fdd960b2bbd7b970da024821c883c2d9631" +"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" +"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" +"checksum hyper 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)" = "6a82c41828dd6f271f4d6ebc3f1db78239a4b2b3d355dfdb5f8bbf55f004463a" +"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" +"checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2134e210e2a024b5684f90e1556d5f71a1ce7f8b12e9ac9924c67fb36f63b336" +"checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2" +"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" -"checksum jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)" = "" "checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" "checksum jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" "checksum jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" "checksum jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum keccak-hash 0.1.0 (git+https://github.com/paritytech/parity.git)" = "" "checksum keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f300c1f149cd9ca5214eed24f6e713a597517420fb8b15499824aa916259ec1" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5" -"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" -"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" -"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" -"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" +"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" +"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" +"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013b7e4c5e10c764936ebc6bd3662d8e3c92292d267bf6a42ef3f5cad9c793ee" +"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" -"checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" +"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" -"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba" +"checksum num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9936036cc70fe4a8b2d338ab665900323290efb03983c86cbe235ae800ad8017" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" +"checksum odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-wasm 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)" = "235801e9531998c4bb307f4ea6833c9f40a4cf132895219ac8c2cd25a9b310f7" +"checksum parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0dec124478845b142f68b446cbee953d14d4b41f1bc0425024417720dce693" "checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" -"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595" +"checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412" +"checksum parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f35048d735bb93dd115a0030498785971aab3234d311fbe273d020084d26bd8" +"checksum path 0.1.0 (git+https://github.com/paritytech/parity.git)" = "" "checksum patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2f638d79aba5c4a71a4f373df6e3cd702250a53b7f0ed4da1e2a7be9737ae" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995" -"checksum pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94b6bbc8a323d89a019c4cdde21850522fb8405e97add70827177fc2f86c1495" +"checksum pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28ea5118e2f41bfbc974b28d88c07621befd1fa5d6ec23549be96302a1a59dd2" +"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0" +"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" +"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" -"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" +"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" -"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" -"checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" +"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" +"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" +"checksum rlp 0.2.1 (git+https://github.com/paritytech/parity.git)" = "" "checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9" +"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" -"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "0c9cab69e16835717c9b8bd13c29f92b6aa34fe32ce2866b1ab481cf2da8442a" -"checksum serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3bdafe3e71710131a919735916caa5b18c2754ad0d33d8ae5d586ccc804a403e" -"checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" -"checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" +"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" +"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" +"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" +"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb" +"checksum slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dbdd334bd28d328dad1c41b0ea662517883d8880d8533895ef96c8003dec9c4" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c" +"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" +"checksum snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "" +"checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b811576c12506ff3f6da145585dc833edc32ee34c9fc021127d90e8134cc05c" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" -"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292" -"checksum tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c843a027f7c1df5f81e7734a0df3f67bf329411781ebf36393ce67beef6071e3" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e9241752647ca572f12c9b520a5d360d9099360c527770647e694001646a1d0" +"checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8" "checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7" "checksum twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "475352206e7a290c5fccc27624a163e8d0d115f7bb60ca18a64fc9ce056d7435" +"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum uint 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "" -"checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80" +"checksum uint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91ed1e25ded4e37e0967b1f12d5f910b32f979768d4f48e2f6ca7b6e7130b44e" +"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" +"checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" +"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562" +"checksum xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "472a9d37c7c53ab2391161df5b89b1f3bf76dab6ab150d7941ecbdd832282082" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/substrate/Cargo.toml b/substrate/Cargo.toml index 55573fddec..2c4d8703e9 100644 --- a/substrate/Cargo.toml +++ b/substrate/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Parity Technologies "] [dependencies] error-chain = "0.11" polkadot-cli = { path = "cli", version = "0.1" } +polkadot-network = { path = "network" } [workspace] members = [ @@ -15,6 +16,7 @@ members = [ "environmental", "executor", "native-runtime", + "network", "primitives", "rpc-servers", "rpc", diff --git a/substrate/cli/src/error.rs b/substrate/cli/src/error.rs index c4e8cbcc5e..6b1e2b6024 100644 --- a/substrate/cli/src/error.rs +++ b/substrate/cli/src/error.rs @@ -16,9 +16,14 @@ //! Initialization errors. +use client; + error_chain! { foreign_links { Io(::std::io::Error) #[doc="IO error"]; Cli(::clap::Error) #[doc="CLI error"]; } + links { + Client(client::error::Error, client::error::ErrorKind) #[doc="Client error"]; + } } diff --git a/substrate/cli/src/lib.rs b/substrate/cli/src/lib.rs index 73168b73b4..d396a7c69e 100644 --- a/substrate/cli/src/lib.rs +++ b/substrate/cli/src/lib.rs @@ -48,14 +48,13 @@ pub fn run(args: I) -> error::Result<()> where let yaml = load_yaml!("./cli.yml"); let matches = clap::App::from_yaml(yaml).version(crate_version!()).get_matches_from_safe(args)?; - // TODO [ToDr] Split paremeters parsing from actual execution. + // TODO [ToDr] Split parameters parsing from actual execution. let log_pattern = matches.value_of("log").unwrap_or(""); init_logger(log_pattern); // Create client - let blockchain = DummyBlockchain; let executor = executor::executor(); - let client = client::Client::new(blockchain, executor); + let client = client::new_in_mem(executor)?; let address = "127.0.0.1:9933".parse().unwrap(); let handler = rpc::rpc_handler(client); @@ -96,17 +95,3 @@ fn init_logger(pattern: &str) { builder.init().expect("Logger initialized only once."); } -#[derive(Debug, Default)] -struct DummyBlockchain; - -impl client::Blockchain for DummyBlockchain { - type Error = (); - - fn latest_hash(&self) -> Result { - Ok(0.into()) - } - - fn header(&self, _hash: &primitives::block::HeaderHash) -> Result, Self::Error> { - Ok(None) - } -} diff --git a/substrate/client/Cargo.toml b/substrate/client/Cargo.toml index 399e2ca823..8b5f728a2b 100644 --- a/substrate/client/Cargo.toml +++ b/substrate/client/Cargo.toml @@ -5,5 +5,8 @@ authors = ["Parity Technologies "] [dependencies] error-chain = "0.11" +log = "0.3" +parking_lot = "0.4" polkadot-primitives = { path = "../primitives", version = "0.1" } polkadot-state-machine = { path = "../state-machine", version = "0.1" } +polkadot-serializer = { path = "../serializer", version = "0.1" } diff --git a/substrate/client/src/backend.rs b/substrate/client/src/backend.rs new file mode 100644 index 0000000000..76422528e7 --- /dev/null +++ b/substrate/client/src/backend.rs @@ -0,0 +1,53 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Polkadot Client data backend + +use state_machine; +use error; +use primitives::block; +use blockchain::{self, BlockId}; + +/// Block insertion transction. Keeps hold if the inseted block state and data. +pub trait BlockImportOperation { + /// Associated state backend type. + type State: state_machine::backend::Backend; + + /// Returns pending state. + fn state(&self) -> error::Result; + /// Append block data to the transaction. + fn import_block(&mut self, header: block::Header, body: Option, is_new_best: bool) -> error::Result<()>; +} + +/// Client backend. Manages the data layer. +pub trait Backend { + /// Associated block insertion transaction type. + type BlockImportOperation: BlockImportOperation; + /// Associated blockchain backend type. + type Blockchain: blockchain::Backend; + /// Associated state backend type. + type State: state_machine::backend::Backend; + + /// Begin a new block insertion transaction with given parent block id. + fn begin_transaction(&self, block: BlockId) -> error::Result; + /// Commit block insertion. + fn commit_transaction(&self, transaction: Self::BlockImportOperation) -> error::Result<()>; + /// Returns reference to blockchain backend. + fn blockchain(&self) -> &Self::Blockchain; + /// Returns state backend for specified block. + fn state_at(&self, block: BlockId) -> error::Result; +} + diff --git a/substrate/client/src/blockchain.rs b/substrate/client/src/blockchain.rs new file mode 100644 index 0000000000..d8881fe5cf --- /dev/null +++ b/substrate/client/src/blockchain.rs @@ -0,0 +1,86 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Polkadot blockchain trait + +use std::fmt::{Display, Formatter, Error as FmtError}; +use primitives::block; +use error::Result; + +/// Block indentification. +#[derive(Debug, Clone, Copy)] +pub enum BlockId { + /// Identify by block header hash. + Hash(block::HeaderHash), + /// Identify by block number. + Number(block::Number), +} + +impl Display for BlockId { + fn fmt(&self, f: &mut Formatter) -> ::std::result::Result<(), FmtError> { + match *self { + BlockId::Hash(h) => h.fmt(f), + BlockId::Number(n) => n.fmt(f), + } + } +} + +/// Blockchain database backend. Does not perform any validation. +pub trait Backend: Send + Sync { + /// Get block header. Returns `None` if block is not found. + fn header(&self, id: BlockId) -> Result>; + /// Get block body. Returns `None` if block is not found. + fn body(&self, id: BlockId) -> Result>; + /// Get blockchain info. + fn info(&self) -> Result; + /// Get block status. + fn status(&self, id: BlockId) -> Result; + /// Get block hash by number. Returns `None` if the header is not in the chain. + fn hash(&self, number: block::Number) -> Result>; +} + +/// Block import outcome +pub enum ImportResult { + /// Imported successfully. + Imported, + /// Block already exists, skippped. + AlreadyInChain, + /// Unknown parent. + UnknownParent, + /// Other errror. + Err(E), +} + +/// Blockchain info +#[derive(Debug)] +pub struct Info { + /// Best block hash. + pub best_hash: block::HeaderHash, + /// Best block number. + pub best_number: block::Number, + /// Genesis block hash. + pub genesis_hash: block::HeaderHash, +} + +/// Block status. +#[derive(Debug, PartialEq, Eq)] +pub enum BlockStatus { + /// Already in the blockchain. + InChain, + /// Not in the queue or the blockchain. + Unknown, +} + diff --git a/substrate/client/src/error.rs b/substrate/client/src/error.rs index b24b4753b1..0059804914 100644 --- a/substrate/client/src/error.rs +++ b/substrate/client/src/error.rs @@ -16,8 +16,9 @@ //! Polkadot client possible errors. -use primitives::block; +use std; use state_machine; +use blockchain; error_chain! { errors { @@ -28,7 +29,7 @@ error_chain! { } /// Unknown block. - UnknownBlock(h: block::HeaderHash) { + UnknownBlock(h: blockchain::BlockId) { description("unknown block"), display("UnknownBlock: {}", h), } @@ -38,6 +39,12 @@ error_chain! { description("execution error"), display("Execution: {}", e), } + + /// Blockchain error. + Blockchain(e: Box) { + description("Blockchain error"), + display("Blockchain: {}", e), + } } } @@ -47,3 +54,16 @@ impl From> for Error { ErrorKind::Execution(e).into() } } + +impl From for Error { + fn from(_e: state_machine::backend::Void) -> Self { + unreachable!() + } +} + +impl Error { + /// Chain a blockchain error. + pub fn from_blockchain(e: Box) -> Self { + ErrorKind::Blockchain(e).into() + } +} diff --git a/substrate/client/src/in_mem.rs b/substrate/client/src/in_mem.rs new file mode 100644 index 0000000000..cd8d7da6f9 --- /dev/null +++ b/substrate/client/src/in_mem.rs @@ -0,0 +1,204 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! In memory client backend + +use std::collections::HashMap; +use parking_lot::RwLock; +use state_machine; +use error; +use backend; +use primitives; +use ser; +use primitives::block::{self, HeaderHash}; +use blockchain::{self, BlockId, BlockStatus}; + +fn header_hash(header: &primitives::block::Header) -> primitives::block::HeaderHash { + primitives::hash(&ser::to_vec(header)) +} + +struct PendingBlock { + block: Block, + is_best: bool, +} + +struct Block { + header: block::Header, + body: Option, +} + +/// In-memory transaction. +pub struct BlockImportOperation { + pending_block: Option, + pending_state: state_machine::backend::InMemory, +} + +struct BlockchainStorage { + blocks: HashMap, + hashes: HashMap, + best_hash: HeaderHash, + best_number: block::Number, + genesis_hash: HeaderHash, +} + +/// In-memory blockchain. Supports concurrent reads. +pub struct Blockchain { + storage: RwLock, +} + +impl Blockchain { + fn id(&self, id: BlockId) -> Option { + match id { + BlockId::Hash(h) => Some(h), + BlockId::Number(n) => self.storage.read().hashes.get(&n).cloned(), + } + } + + fn new() -> Blockchain { + Blockchain { + storage: RwLock::new( + BlockchainStorage { + blocks: HashMap::new(), + hashes: HashMap::new(), + best_hash: HeaderHash::default(), + best_number: 0, + genesis_hash: HeaderHash::default(), + }) + } + } + + fn insert(&self, hash: HeaderHash, header: block::Header, body: Option, is_new_best: bool) { + let number = header.number; + let mut storage = self.storage.write(); + storage.blocks.insert(hash, Block { + header: header, + body: body, + }); + storage.hashes.insert(number, hash); + if is_new_best { + storage.best_hash = hash; + storage.best_number = number; + } + if number == 0 { + storage.genesis_hash = hash; + } + } +} + +impl blockchain::Backend for Blockchain { + fn header(&self, id: BlockId) -> error::Result> { + Ok(self.id(id).and_then(|hash| self.storage.read().blocks.get(&hash).map(|b| b.header.clone()))) + } + + fn body(&self, id: BlockId) -> error::Result> { + Ok(self.id(id).and_then(|hash| self.storage.read().blocks.get(&hash).and_then(|b| b.body.clone()))) + } + + fn info(&self) -> error::Result { + let storage = self.storage.read(); + Ok(blockchain::Info { + best_hash: storage.best_hash, + best_number: storage.best_number, + genesis_hash: storage.genesis_hash, + }) + } + + fn status(&self, id: BlockId) -> error::Result { + match self.id(id).map_or(false, |hash| self.storage.read().blocks.contains_key(&hash)) { + true => Ok(BlockStatus::InChain), + false => Ok(BlockStatus::Unknown), + } + } + + fn hash(&self, number: block::Number) -> error::Result> { + Ok(self.id(BlockId::Number(number))) + } +} + +impl backend::BlockImportOperation for BlockImportOperation { + type State = state_machine::backend::InMemory; + + fn state(&self) -> error::Result { + Ok(self.pending_state.clone()) + } + + fn import_block(&mut self, header: block::Header, body: Option, is_new_best: bool) -> error::Result<()> { + assert!(self.pending_block.is_none(), "Only one block per transaction is allowed"); + self.pending_block = Some(PendingBlock { + block: Block { + header: header, + body: body, + }, + is_best: is_new_best, + }); + Ok(()) + } +} + +/// In-memory backend. Keeps all states and blocks in memory. Useful for testing. +pub struct Backend { + states: RwLock>, + blockchain: Blockchain, +} + +impl Backend { + /// Create a new instance of in-mem backend. + pub fn new() -> Backend { + Backend { + states: RwLock::new(HashMap::new()), + blockchain: Blockchain::new(), + } + } +} + +impl backend::Backend for Backend { + type BlockImportOperation = BlockImportOperation; + type Blockchain = Blockchain; + type State = state_machine::backend::InMemory; + + fn begin_transaction(&self, block: BlockId) -> error::Result { + let state = match block { + BlockId::Hash(h) if h.is_zero() => Self::State::default(), + _ => self.state_at(block)?, + }; + + Ok(BlockImportOperation { + pending_block: None, + pending_state: state, + }) + } + + fn commit_transaction(&self, transaction: Self::BlockImportOperation) -> error::Result<()> { + if let Some(pending_block) = transaction.pending_block { + let hash = header_hash(&pending_block.block.header); + self.states.write().insert(hash, transaction.pending_state); + self.blockchain.insert(hash, pending_block.block.header, pending_block.block.body, pending_block.is_best); + } + Ok(()) + } + + fn blockchain(&self) -> &Blockchain { + &self.blockchain + } + + fn state_at(&self, block: BlockId) -> error::Result { + match self.blockchain.id(block).and_then(|id| self.states.read().get(&id).cloned()) { + Some(state) => Ok(state), + None => Err(error::ErrorKind::UnknownBlock(block).into()), + } + } +} + diff --git a/substrate/client/src/lib.rs b/substrate/client/src/lib.rs index 242e12765e..2773085ece 100644 --- a/substrate/client/src/lib.rs +++ b/substrate/client/src/lib.rs @@ -20,28 +20,43 @@ extern crate polkadot_primitives as primitives; extern crate polkadot_state_machine as state_machine; +extern crate polkadot_serializer as ser; -#[macro_use] -extern crate error_chain; +extern crate parking_lot; +#[macro_use] extern crate error_chain; +#[macro_use] extern crate log; pub mod error; +pub mod blockchain; +pub mod backend; +pub mod in_mem; + +pub use blockchain::Info as ChainInfo; +pub use blockchain::BlockId; use primitives::{block}; use primitives::contract::{CallData, StorageKey, StorageData}; -use state_machine::backend::Backend; -use self::error::ResultExt; +use blockchain::Backend as BlockchainBackend; +use backend::BlockImportOperation; +use state_machine::backend::Backend as StateBackend; -/// Blockchain access -pub trait Blockchain { - /// Error Type - type Error; +/// Polkadot Client +#[derive(Debug)] +pub struct Client where B: backend::Backend { + backend: B, + executor: E, +} - /// Returns the hash of latest block. - fn latest_hash(&self) -> Result; - - /// Given a hash return a header - fn header(&self, hash: &block::HeaderHash) -> Result, Self::Error>; +/// Client info +#[derive(Debug)] +pub struct ClientInfo { + /// Best block hash. + pub chain: ChainInfo, + /// Best block number in the queue. + pub best_queued_number: Option, + /// Best queued block hash. + pub best_queued_hash: Option, } /// Information regarding the result of a call. @@ -52,39 +67,77 @@ pub struct CallResult { pub changes: state_machine::OverlayedChanges, } -/// Polkadot Client +/// Block import result. #[derive(Debug)] -pub struct Client { - blockchain: B, - executor: E, +pub enum ImportResult { + /// Added to the import queue. + Queued, + /// Already in the import queue. + AlreadyQueued, + /// Already in the blockchain. + AlreadyInChain, + /// Block or parent is known to be bad. + KnownBad, + /// Block parent is not in the chain. + UnknownParent, } -impl Client { - /// Creates new Polkadot Client with given blockchain and code executor. - pub fn new(blockchain: B, executor: E) -> Self { - Client { - blockchain, - executor, - } - } +/// Block status. +#[derive(Debug, PartialEq, Eq)] +pub enum BlockStatus { + /// Added to the import queue. + Queued, + /// Already in the blockchain. + InChain, + /// Block or parent is known to be bad. + KnownBad, + /// Not in the queue or the blockchain. + Unknown, +} + + +/// Create an instance of in-memory client. +pub fn new_in_mem(executor: E) -> error::Result> where E: state_machine::CodeExecutor { + Client::new(in_mem::Backend::new(), executor) } impl Client where - B: Blockchain, + B: backend::Backend, E: state_machine::CodeExecutor, + error::Error: From<<::State as state_machine::backend::Backend>::Error>, { + /// Creates new Polkadot Client with given blockchain and code executor. + pub fn new(backend: B, executor: E) -> error::Result { + if backend.blockchain().header(BlockId::Number(0))?.is_none() { + trace!("Empty database, writing genesis block"); + // TODO: spec + let genesis_header = block::Header { + parent_hash: Default::default(), + number: 0, + state_root: Default::default(), + parachain_activity: Default::default(), + logs: Default::default(), + }; - fn state_at(&self, _hash: &block::HeaderHash) -> error::Result { - // TODO [ToDr] Actually retrieve the state. - Ok(state_machine::backend::InMemory::default()) + let mut tx = backend.begin_transaction(BlockId::Hash(block::HeaderHash::default()))?; + tx.import_block(genesis_header, None, true)?; + backend.commit_transaction(tx)?; + } + Ok(Client { + backend, + executor, + }) + } + + fn state_at(&self, hash: &block::HeaderHash) -> error::Result { + self.backend.state_at(BlockId::Hash(*hash)) } /// Return single storage entry of contract under given address in state in a block of given hash. pub fn storage(&self, hash: &block::HeaderHash, key: &StorageKey) -> error::Result { - self.state_at(hash)? + Ok(self.state_at(hash)? .storage(&key.0) - .map(|x| StorageData(x.to_vec())) - .chain_err(|| error::ErrorKind::Backend) + .map(|x| StorageData(x.to_vec()))?) } /// Execute a call to a contract on top of state in a block of given hash. @@ -103,4 +156,52 @@ impl Client where )?; Ok(CallResult { return_data: vec![], changes }) } + + /// Queue a block for import. + pub fn import_block(&self, header: block::Header, body: Option) -> error::Result { + // TODO: import lock + // TODO: validate block + match self.backend.blockchain().status(BlockId::Hash(header.parent_hash))? { + blockchain::BlockStatus::InChain => (), + blockchain::BlockStatus::Unknown => return Ok(ImportResult::UnknownParent), + } + + let mut transaction = self.backend.begin_transaction(BlockId::Number(header.number))?; + let mut _state = transaction.state()?; + // TODO: execute block on _state + + let is_new_best = header.number == self.backend.blockchain().info()?.best_number + 1; + transaction.import_block(header, body, is_new_best)?; + self.backend.commit_transaction(transaction)?; + Ok(ImportResult::Queued) + } + + /// Get blockchain info. + pub fn info(&self) -> error::Result { + let info = self.backend.blockchain().info().map_err(|e| error::Error::from_blockchain(Box::new(e)))?; + Ok(ClientInfo { + chain: info, + best_queued_hash: None, + best_queued_number: None, + }) + } + + /// Get block status. + pub fn block_status(&self, hash: &block::HeaderHash) -> error::Result { + // TODO: more efficient implementation + match self.backend.blockchain().header(BlockId::Hash(*hash)).map_err(|e| error::Error::from_blockchain(Box::new(e)))?.is_some() { + true => Ok(BlockStatus::InChain), + false => Ok(BlockStatus::Unknown), + } + } + + /// Get block hash by number. + pub fn block_hash(&self, block_number: block::Number) -> error::Result> { + self.backend.blockchain().hash(block_number) + } + + /// Get block header by hash. + pub fn header(&self, hash: &block::HeaderHash) -> error::Result> { + self.backend.blockchain().header(BlockId::Hash(*hash)) + } } diff --git a/substrate/executor/Cargo.toml b/substrate/executor/Cargo.toml index 19bab5c0d5..ee9f9e4759 100644 --- a/substrate/executor/Cargo.toml +++ b/substrate/executor/Cargo.toml @@ -16,8 +16,7 @@ parity-wasm = "0.15.0" byteorder = "1.1" rustc-hex = "1.0.0" native-runtime = { path = "../native-runtime", version = "0.1" } - -libc = { version = "0.2.33" } +triehash = "0.1.0" [dev-dependencies] assert_matches = "1.1" diff --git a/substrate/executor/src/lib.rs b/substrate/executor/src/lib.rs index 21dc94efbe..c6a9837a8d 100644 --- a/substrate/executor/src/lib.rs +++ b/substrate/executor/src/lib.rs @@ -38,7 +38,7 @@ extern crate parity_wasm; extern crate byteorder; extern crate rustc_hex; extern crate native_runtime; -extern crate libc; +extern crate triehash; #[macro_use] extern crate error_chain; diff --git a/substrate/executor/src/native_executor.rs b/substrate/executor/src/native_executor.rs index d47719662c..0ecd91be35 100644 --- a/substrate/executor/src/native_executor.rs +++ b/substrate/executor/src/native_executor.rs @@ -42,8 +42,9 @@ impl CodeExecutor for NativeExecutor { mod tests { use super::*; use codec::KeyedVec; - use native_runtime::support::{one, two, TestExternalities, StaticHexInto}; + use native_runtime::support::{one, two, StaticHexInto}; use native_runtime::runtime::staking::balance; + use state_machine::TestExternalities; use primitives::twox_128; const BLOATY_CODE: &[u8] = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index 01601ac379..7819a8fde5 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -29,6 +29,7 @@ use wasm_utils::{MemoryInstance, UserDefinedElements, AddModuleWithoutFullDependentInstance}; use primitives::{ed25519, blake2_256, twox_128, twox_256}; use primitives::hexdisplay::HexDisplay; +use triehash::ordered_trie_root; struct Heap { end: u32, @@ -66,15 +67,26 @@ impl<'e, E: Externalities> FunctionExecutor<'e, E> { } trait WritePrimitive { - fn write_primitive(&self, offset: u32, t: T); + fn write_primitive(&self, offset: u32, t: T) -> ::std::result::Result<(), DummyUserError>; } impl WritePrimitive for MemoryInstance { - fn write_primitive(&self, offset: u32, t: u32) { + fn write_primitive(&self, offset: u32, t: u32) -> ::std::result::Result<(), DummyUserError> { use byteorder::{LittleEndian, ByteOrder}; let mut r = [0u8; 4]; LittleEndian::write_u32(&mut r, t); - let _ = self.set(offset, &r); + self.set(offset, &r).map_err(|_| DummyUserError) + } +} + +trait ReadPrimitive { + fn read_primitive(&self, offset: u32) -> ::std::result::Result; +} + +impl ReadPrimitive for MemoryInstance { + fn read_primitive(&self, offset: u32) -> ::std::result::Result { + use byteorder::{LittleEndian, ByteOrder}; + Ok(LittleEndian::read_u32(&self.get(offset, 4).map_err(|_| DummyUserError)?)) } } @@ -95,29 +107,29 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, println!("Runtime: {}", number); }, ext_memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 => { - if let (Ok(sl1), Ok(sl2)) - = (this.memory.get(s1, n as usize), this.memory.get(s2, n as usize)) { - match sl1.cmp(&sl2) { - Ordering::Greater => 1, - Ordering::Less => -1, - Ordering::Equal => 0, - } - } else { - return Err(DummyUserError.into()); + let sl1 = this.memory.get(s1, n as usize).map_err(|_| DummyUserError)?; + let sl2 = this.memory.get(s2, n as usize).map_err(|_| DummyUserError)?; + match sl1.cmp(&sl2) { + Ordering::Greater => 1, + Ordering::Less => -1, + Ordering::Equal => 0, } }, ext_memcpy(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { - let _ = this.memory.copy_nonoverlapping(src as usize, dest as usize, count as usize); + this.memory.copy_nonoverlapping(src as usize, dest as usize, count as usize) + .map_err(|_| DummyUserError)?; println!("memcpy {} from {}, {} bytes", dest, src, count); dest }, ext_memmove(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { - let _ = this.memory.copy(src as usize, dest as usize, count as usize); + this.memory.copy(src as usize, dest as usize, count as usize) + .map_err(|_| DummyUserError)?; println!("memmove {} from {}, {} bytes", dest, src, count); dest }, ext_memset(dest: *mut u8, val: u32, count: usize) -> *mut u8 => { - let _ = this.memory.clear(dest as usize, val as u8, count as usize); + this.memory.clear(dest as usize, val as u8, count as usize) + .map_err(|_| DummyUserError)?; println!("memset {} with {}, {} bytes", dest, val, count); dest }, @@ -136,90 +148,80 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, } }, ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { - let (offset, written) = if let Ok(key) = this.memory.get(key_data, key_len as usize) { - if let Ok(value) = this.ext.storage(&key) { - let offset = this.heap.allocate(value.len() as u32) as u32; - let _ = this.memory.set(offset, &value); - (offset, value.len() as u32) - } else { (0, 0) } - } else { (0, 0) }; + let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; - this.memory.write_primitive(written_out, written); - offset as u32 + let offset = this.heap.allocate(value.len() as u32) as u32; + this.memory.set(offset, &value).map_err(|_| DummyUserError)?; + + this.memory.write_primitive(written_out, value.len() as u32)?; + offset }, ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32 => { - if let Ok(key) = this.memory.get(key_data, key_len as usize) { - if let Ok(value) = this.ext.storage(&key) { - let value = &value[value_offset as usize..]; - let written = ::std::cmp::min(value_len as usize, value.len()); - let _ = this.memory.set(value_data, &value[..written]); - written as u32 - } else { 0 } - } else { 0 } + let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; + let value = &value[value_offset as usize..]; + let written = ::std::cmp::min(value_len as usize, value.len()); + this.memory.set(value_data, &value[..written]).map_err(|_| DummyUserError)?; + written as u32 + }, + ext_storage_root(result: *mut u8) => { + let r = this.ext.storage_root(); + this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; + }, + ext_enumerated_trie_root(values_data: *const u8, _values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8) => { + let values = (0..lens_len) + .map(|i| this.memory.read_primitive(lens_data + i * 4)) + .collect::<::std::result::Result, DummyUserError>>()? + .into_iter() + .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) + .map(|(offset, len)| + this.memory.get(values_data + offset, len as usize) + .map_err(|_| DummyUserError) + ) + .collect::<::std::result::Result, DummyUserError>>()?; + let r = ordered_trie_root(values.into_iter()); + this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; }, ext_chain_id() -> u64 => { this.ext.chain_id() }, ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { - let maybe_value = if len == 0 { - Ok(vec![]) + let result = if len == 0 { + twox_128(&[0u8; 0]) } else { - this.memory.get(data, len as usize) + twox_128(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) }; - let result = if let Ok(value) = maybe_value { - twox_128(&value) - } else { - [0; 16] - }; - let _ = this.memory.set(out, &result); + this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, ext_twox_256(data: *const u8, len: u32, out: *mut u8) => { - let maybe_value = if len == 0 { - Ok(vec![]) + let result = if len == 0 { + twox_256(&[0u8; 0]) } else { - this.memory.get(data, len as usize) + twox_256(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) }; - let result = if let Ok(value) = maybe_value { - twox_256(&value) - } else { - [0; 32] - }; - let _ = this.memory.set(out, &result); + this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => { - let maybe_value = if len == 0 { - Ok(vec![]) + let result = if len == 0 { + blake2_256(&[0u8; 0]) } else { - this.memory.get(data, len as usize) + blake2_256(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) }; - let result = if let Ok(value) = maybe_value { - blake2_256(&value) - } else { - [0; 32] - }; - let _ = this.memory.set(out, &result); + this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32 => { - (||{ - let mut sig = [0u8; 64]; - if let Err(_) = this.memory.get_into(sig_data, &mut sig[..]) { - return 2; - }; - let mut pubkey = [0u8; 32]; - if let Err(_) = this.memory.get_into(pubkey_data, &mut pubkey[..]) { - return 3; - }; + let mut sig = [0u8; 64]; + this.memory.get_into(sig_data, &mut sig[..]).map_err(|_| DummyUserError)?; + let mut pubkey = [0u8; 32]; + this.memory.get_into(pubkey_data, &mut pubkey[..]).map_err(|_| DummyUserError)?; + let msg = this.memory.get(msg_data, msg_len as usize).map_err(|_| DummyUserError)?; - if let Ok(msg) = this.memory.get(msg_data, msg_len as usize) { - if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) { - 0 - } else { - 5 - } - } else { - 4 - } - })() + if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) { + 0 + } else { + 5 + } } => <'e, E: Externalities + 'e> ); @@ -281,7 +283,8 @@ mod tests { use primitives::{blake2_256, twox_128}; use runtime_std; use codec::KeyedVec; - use native_runtime::support::{one, two, StaticHexInto, TestExternalities}; + use state_machine::TestExternalities; + use native_runtime::support::{one, two, StaticHexInto}; use native_runtime::runtime::staking::balance; #[test] @@ -380,6 +383,16 @@ mod tests { ); } + #[test] + fn enumerated_trie_root_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_enumerated_trie_root", &CallData(vec![])).unwrap(), + ordered_trie_root(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]).0.to_vec() + ); + } + fn tx() -> Vec { "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000".convert() } #[test] diff --git a/substrate/native-runtime/Cargo.toml b/substrate/native-runtime/Cargo.toml index 12ff2a1e10..9081c3d198 100644 --- a/substrate/native-runtime/Cargo.toml +++ b/substrate/native-runtime/Cargo.toml @@ -7,6 +7,7 @@ authors = ["Parity Technologies "] polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1" } polkadot-runtime-std = { path = "../runtime-std", version = "0.1" } rustc-hex = "1.0" +hex-literal = "0.1.0" [features] default = ["std"] diff --git a/substrate/network/Cargo.toml b/substrate/network/Cargo.toml new file mode 100644 index 0000000000..d3b62e4a4c --- /dev/null +++ b/substrate/network/Cargo.toml @@ -0,0 +1,29 @@ +[package] +description = "Polkadot network protocol" +name = "polkadot-network" +version = "0.1.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] + +[lib] + +[dependencies] +ethcore-network = { git = "https://github.com/paritytech/parity.git" } +ethcore-io = { git = "https://github.com/paritytech/parity.git" } +polkadot-primitives = { path = "../primitives" } +polkadot-client = { path = "../client" } +polkadot-state-machine = { path = "../state-machine" } +polkadot-serializer = { path = "../serializer" } +log = "0.3" +env_logger = "0.4" +rand = "0.3" +heapsize = "0.4" +semver = "0.6" +smallvec = { version = "0.4", features = ["heapsizeof"] } +parking_lot = "0.4" +ipnetwork = "0.12" +error-chain = "0.11" +bitflags = "1.0" +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" diff --git a/substrate/network/src/blocks.rs b/substrate/network/src/blocks.rs new file mode 100644 index 0000000000..52a72e022f --- /dev/null +++ b/substrate/network/src/blocks.rs @@ -0,0 +1,263 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +use std::mem; +use std::cmp; +use std::ops::Range; +use std::collections::{HashMap, BTreeMap}; +use std::collections::hash_map::Entry; +use network::PeerId; +use primitives::block::{Number as BlockNumber}; +use message; + +const MAX_PARALLEL_DOWNLOADS: u32 = 1; + +/// Block data with origin. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct BlockData { + pub block: message::BlockData, + pub origin: PeerId, +} + +#[derive(Debug)] +enum BlockRangeState { + Downloading { + len: BlockNumber, + downloading: u32, + }, + Complete(Vec), +} + +impl BlockRangeState { + pub fn len(&self) -> BlockNumber { + match *self { + BlockRangeState::Downloading { len, .. } => len, + BlockRangeState::Complete(ref blocks) => blocks.len() as BlockNumber, + } + } +} + +/// A collection of blocks being downloaded. +#[derive(Default)] +pub struct BlockCollection { + /// Downloaded blocks. + blocks: BTreeMap, + peer_requests: HashMap, +} + +impl BlockCollection { + /// Create a new instance. + pub fn new() -> BlockCollection { + BlockCollection { + blocks: BTreeMap::new(), + peer_requests: HashMap::new(), + } + } + + /// Clear everything. + pub fn clear(&mut self) { + self.blocks.clear(); + self.peer_requests.clear(); + } + + /// Insert a set of blocks into collection. + pub fn insert(&mut self, start: BlockNumber, blocks: Vec, peer_id: PeerId) { + if blocks.is_empty() { + return; + } + + match self.blocks.get(&start) { + Some(&BlockRangeState::Downloading { .. }) => { + trace!(target: "sync", "Ignored block data still marked as being downloaded: {}", start); + debug_assert!(false); + return; + }, + Some(&BlockRangeState::Complete(ref existing)) if existing.len() >= blocks.len() => { + trace!(target: "sync", "Ignored block data already downloaded: {}", start); + return; + }, + _ => (), + } + + self.blocks.insert(start, BlockRangeState::Complete(blocks.into_iter().map(|b| BlockData { origin: peer_id, block: b }).collect())); + } + + /// Returns a set of block hashes that require a header download. The returned set is marked as being downloaded. + pub fn needed_blocks(&mut self, peer_id: PeerId, count: usize, peer_best: BlockNumber, common: BlockNumber) -> Option> { + // First block number that we need to download + let first_different = common + 1; + let count = count as BlockNumber; + let (mut range, downloading) = { + let mut downloading_iter = self.blocks.iter().peekable(); + let mut prev: Option<(&BlockNumber, &BlockRangeState)> = None; + loop { + let next = downloading_iter.next(); + break match &(prev, next) { + &(Some((start, &BlockRangeState::Downloading { ref len, downloading })), _) if downloading < MAX_PARALLEL_DOWNLOADS => + (*start .. *start + *len, downloading), + &(Some((start, r)), Some((next_start, _))) if start + r.len() < *next_start => + (*start + r.len() .. cmp::min(*next_start, *start + count), 0), // gap + &(Some((start, r)), None) => + (start + r.len() .. start + r.len() + count, 0), // last range + &(None, None) => + (first_different .. first_different + count, 0), // empty + &(None, Some((start, _))) if *start > first_different => + (first_different .. cmp::min(first_different + count, *start), 0), // gap at the start + _ => { + prev = next; + continue + }, + } + } + }; + + // crop to peers best + if range.start >= peer_best { + return None; + } + range.end = cmp::min(peer_best, range.end); + + self.peer_requests.insert(peer_id, range.start); + self.blocks.insert(range.start, BlockRangeState::Downloading{ len: range.end - range.start, downloading: downloading + 1 }); + Some(range) + } + + /// Get a valid chain of blocks ordered in descending order and ready for importing into blockchain. + pub fn drain(&mut self, from: BlockNumber) -> Vec { + let mut drained = Vec::new(); + let mut ranges = Vec::new(); + { + let mut prev = from; + for (start, range_data) in &mut self.blocks { + match range_data { + &mut BlockRangeState::Complete(ref mut blocks) if *start <= prev => { + prev = *start + blocks.len() as BlockNumber; + let mut blocks = mem::replace(blocks, Vec::new()); + drained.append(&mut blocks); + ranges.push(*start); + }, + _ => break, + } + } + } + for r in ranges { + self.blocks.remove(&r); + } + trace!(target: "sync", "Drained {} blocks", drained.len()); + drained + } + + pub fn clear_peer_download(&mut self, peer_id: PeerId) { + match self.peer_requests.entry(peer_id) { + Entry::Occupied(entry) => { + let start = entry.remove(); + let remove = match self.blocks.get_mut(&start) { + Some(&mut BlockRangeState::Downloading { ref mut downloading, .. }) if *downloading > 1 => { + *downloading = *downloading - 1; + false + }, + Some(&mut BlockRangeState::Downloading { .. }) => { + true + }, + _ => { + debug_assert!(false); + false + } + }; + if remove { + self.blocks.remove(&start); + } + }, + _ => (), + } + } +} + +#[cfg(test)] +mod test { + use super::{BlockCollection, BlockData}; + use message; + use primitives::block::{HeaderHash}; + + fn is_empty(bc: &BlockCollection) -> bool { + bc.blocks.is_empty() && + bc.peer_requests.is_empty() + } + + fn generate_blocks(n: usize) -> Vec { + (0 .. n).map(|_| message::BlockData { + hash: HeaderHash::random(), + header: None, + body: None, + message_queue: None, + receipt: None, + }).collect() + } + + #[test] + fn create_clear() { + let mut bc = BlockCollection::new(); + assert!(is_empty(&bc)); + bc.insert(1, generate_blocks(100), 0); + assert!(!is_empty(&bc)); + bc.clear(); + assert!(is_empty(&bc)); + } + + #[test] + fn insert_blocks() { + let mut bc = BlockCollection::new(); + assert!(is_empty(&bc)); + let peer0 = 0; + let peer1 = 1; + let peer2 = 2; + + let blocks = generate_blocks(150); + assert_eq!(bc.needed_blocks(peer0, 40, 150, 0), Some(1 .. 41)); + assert_eq!(bc.needed_blocks(peer1, 40, 150, 0), Some(41 .. 81)); + assert_eq!(bc.needed_blocks(peer2, 40, 150, 0), Some(81 .. 121)); + + bc.clear_peer_download(peer1); + bc.insert(41, blocks[41..81].to_vec(), peer1); + assert_eq!(bc.drain(1), vec![]); + assert_eq!(bc.needed_blocks(peer1, 40, 150, 0), Some(121 .. 150)); + bc.clear_peer_download(peer0); + bc.insert(1, blocks[1..11].to_vec(), peer0); + + assert_eq!(bc.needed_blocks(peer0, 40, 150, 0), Some(11 .. 41)); + assert_eq!(bc.drain(1), blocks[1..11].iter().map(|b| BlockData { block: b.clone(), origin: 0 }).collect::>()); + + bc.clear_peer_download(peer0); + bc.insert(11, blocks[11..41].to_vec(), peer0); + + let drained = bc.drain(12); + assert_eq!(drained[..30], blocks[11..41].iter().map(|b| BlockData { block: b.clone(), origin: 0 }).collect::>()[..]); + assert_eq!(drained[30..], blocks[41..81].iter().map(|b| BlockData { block: b.clone(), origin: 1 }).collect::>()[..]); + + bc.clear_peer_download(peer2); + assert_eq!(bc.needed_blocks(peer2, 40, 150, 80), Some(81 .. 121)); + bc.clear_peer_download(peer2); + bc.insert(81, blocks[81..121].to_vec(), peer2); + bc.clear_peer_download(peer1); + bc.insert(121, blocks[121..150].to_vec(), peer1); + + assert_eq!(bc.drain(80), vec![]); + let drained = bc.drain(81); + assert_eq!(drained[..40], blocks[81..121].iter().map(|b| BlockData { block: b.clone(), origin: 2 }).collect::>()[..]); + assert_eq!(drained[40..], blocks[121..150].iter().map(|b| BlockData { block: b.clone(), origin: 1 }).collect::>()[..]); + } +} + diff --git a/substrate/network/src/chain.rs b/substrate/network/src/chain.rs new file mode 100644 index 0000000000..c125434710 --- /dev/null +++ b/substrate/network/src/chain.rs @@ -0,0 +1,59 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Blockchain access trait + +use client::{self, Client as PolkadotClient, ImportResult, ClientInfo, BlockStatus}; +use client::error::Error; +use state_machine; +use primitives::block; + +pub trait Client : Send + Sync { + /// Given a hash return a header + fn import(&self, header: block::Header, body: Option) -> Result; + + /// Get blockchain info. + fn info(&self) -> Result; + + /// Get block status. + fn block_status(&self, hash: &block::HeaderHash) -> Result; + + /// Get block hash by number. + fn block_hash(&self, block_number: block::Number) -> Result, Error>; +} + +impl Client for PolkadotClient where + B: client::backend::Backend + Send + Sync + 'static, + E: state_machine::CodeExecutor + Send + Sync + 'static, +{ + fn import(&self, header: block::Header, body: Option) -> Result { + (self as &Client).import(header, body) + } + + fn info(&self) -> Result { + (self as &Client).info() + } + + fn block_status(&self, hash: &block::HeaderHash) -> Result { + (self as &Client).block_status(hash) + } + + fn block_hash(&self, block_number: block::Number) -> Result, Error> { + (self as &Client).block_hash(block_number) + } +} + + diff --git a/substrate/network/src/config.rs b/substrate/network/src/config.rs new file mode 100644 index 0000000000..b826213280 --- /dev/null +++ b/substrate/network/src/config.rs @@ -0,0 +1,30 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +use service::Role; + +/// Protocol configuration +pub struct ProtocolConfig { + pub roles: Role, +} + +impl Default for ProtocolConfig { + fn default() -> ProtocolConfig { + ProtocolConfig { + roles: Role::FULL, + } + } +} diff --git a/substrate/rpc/src/test_helpers.rs b/substrate/network/src/error.rs similarity index 54% rename from substrate/rpc/src/test_helpers.rs rename to substrate/network/src/error.rs index 6d2e23485b..9583a29861 100644 --- a/substrate/rpc/src/test_helpers.rs +++ b/substrate/network/src/error.rs @@ -12,34 +12,20 @@ // GNU General Public License for more details. // You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . +// along with Polkadot. If not, see .? +use network::Error as NetworkError; use client; -use primitives::{block, parachain}; -/// Temporary dummy blockchain implementation for tests. -#[derive(Debug, Default)] -pub struct Blockchain; - -impl client::Blockchain for Blockchain { - type Error = ::std::io::Error; - - fn latest_hash(&self) -> Result { - Ok(0.into()) +error_chain! { + foreign_links { + Network(NetworkError) #[doc = "Devp2p error."]; } - fn header(&self, hash: &block::HeaderHash) -> Result, Self::Error> { - Ok(if hash != &0.into() { - None - } else { - Some(block::Header { - parent_hash: 0.into(), - number: 0, - state_root: 0.into(), - parachain_activity: parachain::Activity(vec![0]), - logs: vec![], - }) - }) + links { + Client(client::error::Error, client::error::ErrorKind); + } + + errors { } } - diff --git a/substrate/network/src/io.rs b/substrate/network/src/io.rs new file mode 100644 index 0000000000..339e80e9ad --- /dev/null +++ b/substrate/network/src/io.rs @@ -0,0 +1,78 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +use network::{NetworkContext, PeerId, Error as NetworkError, SessionInfo}; + +/// IO interface for the syncing handler. +/// Provides peer connection management and an interface to the blockchain client. +pub trait SyncIo { + /// Disable a peer + fn disable_peer(&mut self, peer_id: PeerId); + /// Disconnect peer + fn disconnect_peer(&mut self, peer_id: PeerId); + /// Send a packet to a peer. + fn send(&mut self, peer_id: PeerId, data: Vec) -> Result<(), NetworkError>; + /// Returns peer identifier string + fn peer_info(&self, peer_id: PeerId) -> String { + peer_id.to_string() + } + /// Returns information on p2p session + fn peer_session_info(&self, peer_id: PeerId) -> Option; + /// Check if the session is expired + fn is_expired(&self) -> bool; +} + +/// Wraps `NetworkContext` and the blockchain client +pub struct NetSyncIo<'s, 'h> where 'h: 's { + network: &'s NetworkContext<'h>, +} + +impl<'s, 'h> NetSyncIo<'s, 'h> { + /// Creates a new instance from the `NetworkContext` and the blockchain client reference. + pub fn new(network: &'s NetworkContext<'h>) -> NetSyncIo<'s, 'h> { + NetSyncIo { + network: network, + } + } +} + +impl<'s, 'h> SyncIo for NetSyncIo<'s, 'h> { + fn disable_peer(&mut self, peer_id: PeerId) { + self.network.disable_peer(peer_id); + } + + fn disconnect_peer(&mut self, peer_id: PeerId) { + self.network.disconnect_peer(peer_id); + } + + fn send(&mut self, peer_id: PeerId, data: Vec) -> Result<(), NetworkError>{ + self.network.send(peer_id, 0, data) + } + + fn peer_session_info(&self, peer_id: PeerId) -> Option { + self.network.session_info(peer_id) + } + + fn is_expired(&self) -> bool { + self.network.is_expired() + } + + fn peer_info(&self, peer_id: PeerId) -> String { + self.network.peer_client_version(peer_id) + } +} + + diff --git a/substrate/network/src/lib.rs b/substrate/network/src/lib.rs new file mode 100644 index 0000000000..10a6eb6065 --- /dev/null +++ b/substrate/network/src/lib.rs @@ -0,0 +1,62 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +#![warn(missing_docs)] + +//! Implements polkadot protocol version as specified here: +//! https://github.com/paritytech/polkadot/wiki/Network-protocol + +extern crate ethcore_network as network; +extern crate ethcore_io as core_io; +extern crate env_logger; +extern crate rand; +extern crate semver; +extern crate parking_lot; +extern crate smallvec; +extern crate ipnetwork; +extern crate polkadot_primitives as primitives; +extern crate polkadot_client as client; +extern crate polkadot_state_machine as state_machine; +extern crate polkadot_serializer as ser; +extern crate serde; +extern crate serde_json; +#[macro_use] extern crate serde_derive; +#[macro_use] extern crate log; +#[macro_use] extern crate bitflags; +#[macro_use] extern crate error_chain; + +mod service; +mod sync; +mod protocol; +mod io; +mod message; +mod error; +mod config; +mod chain; +mod blocks; + +#[cfg(test)] +mod test; + +pub use service::Service; +pub use protocol::{ProtocolStatus}; +pub use network::{NonReservedPeerMode, ConnectionFilter, ConnectionDirection, NetworkConfiguration}; + +// TODO: move it elsewhere +fn header_hash(header: &primitives::block::Header) -> primitives::block::HeaderHash { + primitives::hash(&ser::to_vec(header)) +} + diff --git a/substrate/network/src/message.rs b/substrate/network/src/message.rs new file mode 100644 index 0000000000..ff0c678b0b --- /dev/null +++ b/substrate/network/src/message.rs @@ -0,0 +1,189 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +//! Network packet message types. These get serialized and put into the lower level protocol payload. + +use std::borrow::Borrow; +use primitives::parachain::Id as ParachainId; +use primitives::Address; +use primitives::block::{Number as BlockNumber, HeaderHash, Header, Body}; +use service::Role as RoleFlags; + +pub type RequestId = u64; +type Bytes = Vec; + +type Signature = ::primitives::hash::H256; //TODO: + +/// Configured node role. +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum Role { + /// Full relay chain client with no additional responsibilities. + Full, + /// Relay chain light client. + Light, + /// Parachain validator. + Validator, + /// Parachain collator. + Collator, +} + +impl From for RoleFlags where T: Borrow<[Role]> { + fn from(roles: T) -> RoleFlags { + let mut flags = RoleFlags::NONE; + let roles: &[Role] = roles.borrow(); + for r in roles { + match *r { + Role::Full => flags = flags | RoleFlags::FULL, + Role::Light => flags = flags | RoleFlags::LIGHT, + Role::Validator => flags = flags | RoleFlags::VALIDATOR, + Role::Collator => flags = flags | RoleFlags::COLLATOR, + } + } + flags + } +} + +impl From for Vec where { + fn from(flags: RoleFlags) -> Vec { + let mut roles = Vec::new(); + if !(flags & RoleFlags::FULL).is_empty() { + roles.push(Role::Full); + } + if !(flags & RoleFlags::LIGHT).is_empty() { + roles.push(Role::Light); + } + if !(flags & RoleFlags::VALIDATOR).is_empty() { + roles.push(Role::Validator); + } + if !(flags & RoleFlags::COLLATOR).is_empty() { + roles.push(Role::Collator); + } + roles + } +} + +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Copy, Clone)] +/// Bits of block data and associated artefacts to request. +pub enum BlockAttribute { + /// Include block header. + Header, + /// Include block body. + Body, + /// Include block receipt. + Receipt, + /// Include block message queue. + MessageQueue, +} + +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +/// Block data sent in the response. +pub struct BlockData { + /// Block header hash. + pub hash: HeaderHash, + /// Block header if requested. + pub header: Option
, + /// Block body if requested. + pub body: Option, + /// Block receipt if requested. + pub receipt: Option, + /// Block message queue if requested. + pub message_queue: Option, +} + +#[serde(untagged)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +/// Identifies starting point of a block sequence. +pub enum FromBlock { + /// Start with given hash. + Hash(HeaderHash), + /// Start with given block number. + Number(BlockNumber), +} + +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +/// Block enumeration direction. +pub enum Direction { + /// Enumerate in ascending order (from child to parent). + Ascending, + /// Enumerate in descendfing order (from parent to canonical child). + Descending, +} + +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +/// A network message. +pub enum Message { + /// Status packet. + Status(Status), + /// Block request. + BlockRequest(BlockRequest), + /// Block response. + BlockResponse(BlockResponse), + /// Block announce. + BlockAnnounce(BlockAnnounce), +} + +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Status { + /// Protocol version. + pub version: u32, + /// Supported roles. + pub roles: Vec, + /// Best block number. + pub best_number: BlockNumber, + /// Best block hash. + pub best_hash: HeaderHash, + /// Genesis block hash. + pub genesis_hash: HeaderHash, + /// Signatue of `best_hash` made with validator address. Required for the validator role. + pub validator_signature: Option, + /// Validator address. Required for the validator role. + pub validator_id: Option
, + /// Parachain id. Required for the collator role. + pub parachain_id: Option, +} + +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +/// Request block data from a peer. +pub struct BlockRequest { + /// Unique request id. + pub id: RequestId, + /// Bits of block data to request. + pub fields: Vec, + /// Start from this block. + pub from: FromBlock, + /// End at this block. An implementation defined maximum is used when unspecified. + pub to: Option, + /// Sequence direction. + pub direction: Direction, + /// Maximum number of block to return. An implementation defined maximum is used when unspecified. + pub max: Option, +} + +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +/// Response to `BlockRequest` +pub struct BlockResponse { + /// Id of a request this response was made for. + pub id: RequestId, + /// Block data for the requested sequence. + pub blocks: Vec, +} + +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +/// Announce a new complete relay chain block on the network. +pub struct BlockAnnounce { + /// New block header. + pub header: Header, +} diff --git a/substrate/network/src/protocol.rs b/substrate/network/src/protocol.rs new file mode 100644 index 0000000000..3b0a5a801a --- /dev/null +++ b/substrate/network/src/protocol.rs @@ -0,0 +1,347 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +use std::collections::{HashMap, HashSet, BTreeMap}; +use std::mem; +use std::sync::Arc; +use parking_lot::RwLock; +use serde_json; +use std::time; +use primitives::block::{HeaderHash, TransactionHash, Number as BlockNumber, Header}; +use network::{PeerId, NodeId}; + +use message::{self, Message}; +use sync::{ChainSync, Status as SyncStatus}; +use service::Role; +use config::ProtocolConfig; +use chain::Client; +use io::SyncIo; +use error; + +const REQUEST_TIMEOUT_SEC: u64 = 15; +const PROTOCOL_VERSION: u32 = 0; + +// Lock must always be taken in order declared here. +pub struct Protocol { + config: ProtocolConfig, + chain: Arc, + genesis_hash: HeaderHash, + sync: RwLock, + /// All connected peers + peers: RwLock>, + /// Connected peers pending Status message. + handshaking_peers: RwLock>, +} + +/// Syncing status and statistics +#[derive(Clone, Copy)] +pub struct ProtocolStatus { + /// Sync status. + pub sync: SyncStatus, + /// Total number of connected peers + pub num_peers: usize, + /// Total number of active peers. + pub num_active_peers: usize, +} + +/// Peer information +struct Peer { + /// Protocol version + protocol_version: u32, + /// Roles + roles: Role, + /// Peer best block hash + best_hash: HeaderHash, + /// Peer best block number + best_number: BlockNumber, + /// Pending block request if any + block_request: Option, + /// Request timestamp + request_timestamp: Option, + /// Holds a set of transactions recently sent to this peer to avoid spamming. + _last_sent_transactions: HashSet, + /// Request counter, + request_id: message::RequestId, +} + +#[derive(Debug)] +pub struct PeerInfo { + /// Roles + pub roles: Role, + /// Protocol version + pub protocol_version: u32, + /// Peer best block hash + pub best_hash: HeaderHash, + /// Peer best block number + pub best_number: BlockNumber, +} + +/// Transaction stats +#[derive(Debug)] +pub struct TransactionStats { + /// Block number where this TX was first seen. + pub first_seen: u64, + /// Peers it was propagated to. + pub propagated_to: BTreeMap, +} + +impl Protocol { + /// Create a new instance. + pub fn new(config: ProtocolConfig, chain: Arc) -> error::Result { + let info = chain.info()?; + let protocol = Protocol { + config: config, + chain: chain, + genesis_hash: info.chain.genesis_hash, + sync: RwLock::new(ChainSync::new(&info)), + peers: RwLock::new(HashMap::new()), + handshaking_peers: RwLock::new(HashMap::new()), + }; + Ok(protocol) + } + + /// Returns protocol status + pub fn status(&self) -> ProtocolStatus { + let sync = self.sync.read(); + let peers = self.peers.read(); + ProtocolStatus { + sync: sync.status(), + num_peers: peers.values().count(), + num_active_peers: peers.values().filter(|p| p.block_request.is_some()).count(), + } + } + + pub fn handle_packet(&self, io: &mut SyncIo, peer_id: PeerId, data: &[u8]) { + let message: Message = match serde_json::from_slice(data) { + Ok(m) => m, + Err(e) => { + debug!("Invalid packet from {}: {}", peer_id, e); + io.disable_peer(peer_id); + return; + } + }; + + match message { + Message::Status(s) => self.on_status_message(io, peer_id, s), + Message::BlockRequest(r) => self.on_block_request(io, peer_id, r), + Message::BlockResponse(r) => { + let request = { + let mut peers = self.peers.write(); + if let Some(ref mut peer) = peers.get_mut(&peer_id) { + peer.request_timestamp = None; + match mem::replace(&mut peer.block_request, None) { + Some(r) => r, + None => { + debug!("Unexpected response packet from {}", peer_id); + io.disable_peer(peer_id); + return; + } + } + } else { + debug!("Unexpected packet from {}", peer_id); + io.disable_peer(peer_id); + return; + } + }; + if request.id != r.id { + trace!("Ignoring mismatched response packet from {}", peer_id); + return; + } + self.on_block_response(io, peer_id, request, r); + }, + Message::BlockAnnounce(announce) => { + self.on_block_announce(io, peer_id, announce); + } + } + } + + pub fn send_message(&self, io: &mut SyncIo, peer_id: PeerId, mut message: Message) { + let mut peers = self.peers.write(); + if let Some(ref mut peer) = peers.get_mut(&peer_id) { + match &mut message { + &mut Message::BlockRequest(ref mut r) => { + peer.block_request = Some(r.clone()); + peer.request_timestamp = Some(time::Instant::now()); + r.id = peer.request_id; + peer.request_id = peer.request_id + 1; + }, + _ => (), + } + } + let data = serde_json::to_vec(&message).expect("Serializer is infallible; qed"); + if let Err(e) = io.send(peer_id, data) { + debug!(target:"sync", "Error sending message: {:?}", e); + io.disconnect_peer(peer_id); + } + } + + /// Called when a new peer is connected + pub fn on_peer_connected(&self, io: &mut SyncIo, peer_id: PeerId) { + trace!(target: "sync", "Connected {}: {}", peer_id, io.peer_info(peer_id)); + self.handshaking_peers.write().insert(peer_id, time::Instant::now()); + self.send_status(io, peer_id); + } + + /// Called by peer when it is disconnecting + pub fn on_peer_disconnected(&self, io: &mut SyncIo, peer: PeerId) { + trace!(target: "sync", "Disconnecting {}: {}", peer, io.peer_info(peer)); + let removed = { + let mut peers = self.peers.write(); + let mut handshaking_peers = self.handshaking_peers.write(); + handshaking_peers.remove(&peer); + peers.remove(&peer).is_some() + }; + if removed { + self.sync.write().peer_disconnected(io, self, peer); + } + } + + pub fn on_block_request(&self, _io: &mut SyncIo, _peer_id: PeerId, _request: message::BlockRequest) { + } + + pub fn on_block_response(&self, io: &mut SyncIo, peer_id: PeerId, request: message::BlockRequest, response: message::BlockResponse) { + // TODO: validate response + self.sync.write().on_block_data(io, self, peer_id, request, response); + } + + pub fn tick(&self, io: &mut SyncIo) { + self.maintain_peers(io); + } + + fn maintain_peers(&self, io: &mut SyncIo) { + let tick = time::Instant::now(); + let mut aborting = Vec::new(); + { + let peers = self.peers.read(); + let handshaking_peers = self.handshaking_peers.read(); + for (peer_id, timestamp) in peers.iter() + .filter_map(|(id, peer)| peer.request_timestamp.as_ref().map(|r| (id, r))) + .chain(handshaking_peers.iter()) { + if (tick - *timestamp).as_secs() > REQUEST_TIMEOUT_SEC { + trace!(target:"sync", "Timeout {}", peer_id); + io.disconnect_peer(*peer_id); + aborting.push(*peer_id); + } + } + } + for p in aborting { + self.on_peer_disconnected(io, p); + } + } + + pub fn peer_info(&self, peer: PeerId) -> Option { + self.peers.read().get(&peer).map(|p| { + PeerInfo { + roles: p.roles, + protocol_version: p.protocol_version, + best_hash: p.best_hash, + best_number: p.best_number, + } + }) + } + + /// Called by peer to report status + fn on_status_message(&self, io: &mut SyncIo, peer_id: PeerId, status: message::Status) { + trace!(target: "sync", "New peer {} {:?}", peer_id, status); + if io.is_expired() { + trace!(target: "sync", "Status packet from expired session {}:{}", peer_id, io.peer_info(peer_id)); + return; + } + + { + let mut peers = self.peers.write(); + let mut handshaking_peers = self.handshaking_peers.write(); + if peers.contains_key(&peer_id) { + debug!(target: "sync", "Unexpected status packet from {}:{}", peer_id, io.peer_info(peer_id)); + return; + } + if status.genesis_hash != self.genesis_hash { + io.disable_peer(peer_id); + trace!(target: "sync", "Peer {} genesis hash mismatch (ours: {}, theirs: {})", peer_id, self.genesis_hash, status.genesis_hash); + return; + } + if status.version != PROTOCOL_VERSION { + io.disable_peer(peer_id); + trace!(target: "sync", "Peer {} unsupported eth protocol ({})", peer_id, status.version); + return; + } + + let peer = Peer { + protocol_version: status.version, + roles: status.roles.into(), + best_hash: status.best_hash, + best_number: status.best_number, + block_request: None, + request_timestamp: None, + _last_sent_transactions: HashSet::new(), + request_id: 0, + }; + peers.insert(peer_id.clone(), peer); + handshaking_peers.remove(&peer_id); + debug!(target: "sync", "Connected {} {}", peer_id, io.peer_info(peer_id)); + } + self.sync.write().new_peer(io, self, peer_id); + } + + /// Send Status message + fn send_status(&self, io: &mut SyncIo, peer_id: PeerId) { + if let Ok(info) = self.chain.info() { + let status = message::Status { + version: PROTOCOL_VERSION, + genesis_hash: info.chain.genesis_hash, + roles: self.config.roles.into(), + best_number: info.chain.best_number, + best_hash: info.chain.best_hash, + validator_signature: None, + validator_id: None, + parachain_id: None, + }; + self.send_message(io, peer_id, Message::Status(status)) + } + } + + pub fn abort(&self) { + let mut sync = self.sync.write(); + let mut peers = self.peers.write(); + let mut handshaking_peers = self.handshaking_peers.write(); + sync.clear(); + peers.clear(); + handshaking_peers.clear(); + } + + pub fn on_block_announce(&self, io: &mut SyncIo, peer_id: PeerId, announce: message::BlockAnnounce) { + let header = announce.header; + self.sync.write().on_block_announce(io, self, peer_id, &header); + } + + pub fn on_block_imported(&self, header: &Header) { + self.sync.write().update_chain_info(&header); + } + + pub fn on_new_transactions(&self) { + } + + pub fn transactions_stats(&self) -> BTreeMap { + BTreeMap::new() + } + + pub fn chain(&self) -> &Client { + &*self.chain + } +} + + + diff --git a/substrate/network/src/service.rs b/substrate/network/src/service.rs new file mode 100644 index 0000000000..11b4cae18e --- /dev/null +++ b/substrate/network/src/service.rs @@ -0,0 +1,239 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +use std::sync::Arc; +use std::collections::{BTreeMap}; +use std::io; +use network::{NetworkProtocolHandler, NetworkService, NetworkContext, HostInfo, PeerId, ProtocolId, +NetworkConfiguration , NonReservedPeerMode, ErrorKind}; +use primitives::block::{TransactionHash, Header}; +use core_io::{TimerToken}; +use io::NetSyncIo; +use protocol::{Protocol, ProtocolStatus, PeerInfo as ProtocolPeerInfo, TransactionStats}; +use config::{ProtocolConfig}; +use error::Error; +use chain::Client; + +/// Polkadot devp2p protocol id +pub const DOT_PROTOCOL_ID: ProtocolId = *b"dot"; + +bitflags! { + pub struct Role: u32 { + const NONE = 0b00000000; + const FULL = 0b00000001; + const LIGHT = 0b00000010; + const VALIDATOR = 0b00000100; + const COLLATOR = 0b00001000; + } +} + +/// Sync status +pub trait SyncProvider: Send + Sync { + /// Get sync status + fn status(&self) -> ProtocolStatus; + /// Get peers information + fn peers(&self) -> Vec; + /// Get this node id if available. + fn node_id(&self) -> Option; + /// Returns propagation count for pending transactions. + fn transactions_stats(&self) -> BTreeMap; +} + +/// Peer connection information +#[derive(Debug)] +pub struct PeerInfo { + /// Public node id + pub id: Option, + /// Node client ID + pub client_version: String, + /// Capabilities + pub capabilities: Vec, + /// Remote endpoint address + pub remote_address: String, + /// Local endpoint address + pub local_address: String, + /// Dot protocol info. + pub dot_info: Option, +} + +/// Service initialization parameters. +pub struct Params { + /// Configuration. + pub config: ProtocolConfig, + /// Network layer configuration. + pub network_config: NetworkConfiguration, + /// Polkadot relay chain access point. + pub chain: Arc, +} + +/// Polkadot network service. Handles network IO and manages connectivity. +pub struct Service { + /// Network service + network: NetworkService, + /// Devp2p protocol handler + handler: Arc, +} + +impl Service { + /// Creates and register protocol with the network service + pub fn new(params: Params) -> Result, Error> { + + let service = NetworkService::new(params.network_config.clone(), None)?; + + let sync = Arc::new(Service { + network: service, + handler: Arc::new(ProtocolHandler { + protocol: Protocol::new(params.config, params.chain.clone())?, + }), + }); + + Ok(sync) + } + + /// Called when a new block is imported by the client. + pub fn on_block_imported(&self, header: &Header) { + self.handler.protocol.on_block_imported(header) + } + + /// Called when new transactons are imported by the client. + pub fn on_new_transactions(&self) { + self.handler.protocol.on_new_transactions() + } + + fn start(&self) { + match self.network.start().map_err(Into::into) { + Err(ErrorKind::Io(ref e)) if e.kind() == io::ErrorKind::AddrInUse => + warn!("Network port {:?} is already in use, make sure that another instance of Polkadot client is not running or change the port using the --port option.", self.network.config().listen_address.expect("Listen address is not set.")), + Err(err) => warn!("Error starting network: {}", err), + _ => {}, + }; + self.network.register_protocol(self.handler.clone(), DOT_PROTOCOL_ID, 1, &[0u8]) + .unwrap_or_else(|e| warn!("Error registering polkadot protocol: {:?}", e)); + } + + fn stop(&self) { + self.handler.protocol.abort(); + self.network.stop().unwrap_or_else(|e| warn!("Error stopping network: {:?}", e)); + } +} + +impl SyncProvider for Service { + /// Get sync status + fn status(&self) -> ProtocolStatus { + self.handler.protocol.status() + } + + /// Get sync peers + fn peers(&self) -> Vec { + self.network.with_context_eval(DOT_PROTOCOL_ID, |ctx| { + let peer_ids = self.network.connected_peers(); + + peer_ids.into_iter().filter_map(|peer_id| { + let session_info = match ctx.session_info(peer_id) { + None => return None, + Some(info) => info, + }; + + Some(PeerInfo { + id: session_info.id.map(|id| id.hex()), + client_version: session_info.client_version, + capabilities: session_info.peer_capabilities.into_iter().map(|c| c.to_string()).collect(), + remote_address: session_info.remote_address, + local_address: session_info.local_address, + dot_info: self.handler.protocol.peer_info(peer_id), + }) + }).collect() + }).unwrap_or_else(Vec::new) + } + + fn node_id(&self) -> Option { + self.network.external_url() + } + + fn transactions_stats(&self) -> BTreeMap { + self.handler.protocol.transactions_stats() + } +} + +struct ProtocolHandler { + /// Protocol handler + protocol: Protocol, +} + +impl NetworkProtocolHandler for ProtocolHandler { + fn initialize(&self, io: &NetworkContext, _host_info: &HostInfo) { + io.register_timer(0, 1000).expect("Error registering sync timer"); + } + + fn read(&self, io: &NetworkContext, peer: &PeerId, _packet_id: u8, data: &[u8]) { + self.protocol.handle_packet(&mut NetSyncIo::new(io), *peer, data); + } + + fn connected(&self, io: &NetworkContext, peer: &PeerId) { + self.protocol.on_peer_connected(&mut NetSyncIo::new(io), *peer); + } + + fn disconnected(&self, io: &NetworkContext, peer: &PeerId) { + self.protocol.on_peer_disconnected(&mut NetSyncIo::new(io), *peer); + } + + fn timeout(&self, io: &NetworkContext, _timer: TimerToken) { + self.protocol.tick(&mut NetSyncIo::new(io)); + } +} + +/// Trait for managing network +pub trait ManageNetwork : Send + Sync { + /// Set to allow unreserved peers to connect + fn accept_unreserved_peers(&self); + /// Set to deny unreserved peers to connect + fn deny_unreserved_peers(&self); + /// Remove reservation for the peer + fn remove_reserved_peer(&self, peer: String) -> Result<(), String>; + /// Add reserved peer + fn add_reserved_peer(&self, peer: String) -> Result<(), String>; + /// Start network + fn start_network(&self); + /// Stop network + fn stop_network(&self); +} + + +impl ManageNetwork for Service { + fn accept_unreserved_peers(&self) { + self.network.set_non_reserved_mode(NonReservedPeerMode::Accept); + } + + fn deny_unreserved_peers(&self) { + self.network.set_non_reserved_mode(NonReservedPeerMode::Deny); + } + + fn remove_reserved_peer(&self, peer: String) -> Result<(), String> { + self.network.remove_reserved_peer(&peer).map_err(|e| format!("{:?}", e)) + } + + fn add_reserved_peer(&self, peer: String) -> Result<(), String> { + self.network.add_reserved_peer(&peer).map_err(|e| format!("{:?}", e)) + } + + fn start_network(&self) { + self.start(); + } + + fn stop_network(&self) { + self.stop(); + } +} diff --git a/substrate/network/src/sync.rs b/substrate/network/src/sync.rs new file mode 100644 index 0000000000..ec5b1ee67b --- /dev/null +++ b/substrate/network/src/sync.rs @@ -0,0 +1,372 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see .? + +use std::collections::HashMap; +use io::SyncIo; +use protocol::Protocol; +use network::PeerId; +use client::{ImportResult, BlockStatus, ClientInfo}; +use primitives::block::{HeaderHash, Number as BlockNumber, Header}; +use blocks::{self, BlockCollection}; +use message::{self, Message}; +use super::header_hash; + +// Maximum parallel requests for a block. +const MAX_BLOCK_DOWNLOAD: usize = 1; + +struct PeerSync { + pub common_hash: HeaderHash, + pub common_number: BlockNumber, + pub best_hash: HeaderHash, + pub best_number: BlockNumber, + pub state: PeerSyncState, +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub enum PeerSyncState { + AncestorSearch(BlockNumber), + Available, + DownloadingNew(BlockNumber), + DownloadingStale(HeaderHash), +} + +/// Relay chain sync strategy. +pub struct ChainSync { + genesis_hash: HeaderHash, + peers: HashMap, + blocks: BlockCollection, + best_queued_number: BlockNumber, + best_queued_hash: HeaderHash, + required_block_attributes: Vec, +} + +/// Syncing status and statistics +#[derive(Clone, Copy)] +pub struct Status; + +impl ChainSync { + pub fn new(info: &ClientInfo) -> ChainSync { + ChainSync { + genesis_hash: info.chain.genesis_hash, + peers: HashMap::new(), + blocks: BlockCollection::new(), + best_queued_hash: info.best_queued_hash.unwrap_or(info.chain.best_hash), + best_queued_number: info.best_queued_number.unwrap_or(info.chain.best_number), + required_block_attributes: vec![message::BlockAttribute::Header, message::BlockAttribute::Body], + } + } + + /// Returns sync status + pub fn status(&self) -> Status { + Status + } + + pub fn new_peer(&mut self, io: &mut SyncIo, protocol: &Protocol, peer_id: PeerId) { + if let Some(info) = protocol.peer_info(peer_id) { + match (protocol.chain().block_status(&info.best_hash), info.best_number) { + (Err(e), _) => { + debug!(target:"sync", "Error reading blockchain: {:?}", e); + io.disconnect_peer(peer_id); + }, + (Ok(BlockStatus::KnownBad), _) => { + debug!(target:"sync", "New peer with known bad best block {} ({}).", info.best_hash, info.best_number); + io.disable_peer(peer_id); + }, + (Ok(BlockStatus::Unknown), 0) => { + debug!(target:"sync", "New peer with unkown genesis hash {} ({}).", info.best_hash, info.best_number); + io.disable_peer(peer_id); + }, + (Ok(BlockStatus::Unknown), _) => { + debug!(target:"sync", "New peer with unkown best hash {} ({}), searching for common ancestor.", info.best_hash, info.best_number); + self.peers.insert(peer_id, PeerSync { + common_hash: self.genesis_hash, + common_number: 0, + best_hash: info.best_hash, + best_number: info.best_number, + state: PeerSyncState::AncestorSearch(info.best_number - 1), + }); + Self::request_ancestry(io, protocol, peer_id, info.best_number - 1) + }, + (Ok(BlockStatus::Queued), _) | (Ok(BlockStatus::InChain), _) => { + debug!(target:"sync", "New peer with known best hash {} ({}).", info.best_hash, info.best_number); + self.peers.insert(peer_id, PeerSync { + common_hash: info.best_hash, + common_number: info.best_number, + best_hash: info.best_hash, + best_number: info.best_number, + state: PeerSyncState::Available, + }); + } + } + } + } + + pub fn on_block_data(&mut self, io: &mut SyncIo, protocol: &Protocol, peer_id: PeerId, _request: message::BlockRequest, response: message::BlockResponse) { + let count = response.blocks.len(); + let mut imported: usize = 0; + let new_blocks = if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + match peer.state { + PeerSyncState::DownloadingNew(start_block) => { + self.blocks.clear_peer_download(peer_id); + peer.state = PeerSyncState::Available; + + self.blocks.insert(start_block, response.blocks, peer_id); + self.blocks.drain(self.best_queued_number + 1) + }, + PeerSyncState::DownloadingStale(_) => { + peer.state = PeerSyncState::Available; + response.blocks.into_iter().map(|b| blocks::BlockData { + origin: peer_id, + block: b + }).collect() + }, + PeerSyncState::AncestorSearch(n) => { + match response.blocks.get(0) { + Some(ref block) => { + match protocol.chain().block_hash(n) { + Ok(Some(block_hash)) if block_hash == block.hash => { + peer.common_hash = block.hash; + peer.common_number = n; + peer.state = PeerSyncState::Available; + trace!(target:"sync", "Found common ancestor for peer {}: {} ({})", peer_id, block.hash, n); + vec![] + }, + Ok(_) if n > 0 => { + let n = n - 1; + peer.state = PeerSyncState::AncestorSearch(n); + Self::request_ancestry(io, protocol, peer_id, n); + return; + }, + Ok(_) => { // genesis mismatch + io.disable_peer(peer_id); + return; + }, + Err(e) => { + debug!(target:"sync", "Error reading blockchain: {:?}", e); + io.disconnect_peer(peer_id); + return; + } + } + }, + None => { + trace!(target:"sync", "Invalid response when searching for ancestor from {}", peer_id); + io.disconnect_peer(peer_id); + return; + } + } + }, + PeerSyncState::Available => Vec::new(), + } + } else { + vec![] + }; + + // Blocks in the response/drain should be in ascending order. + for block in new_blocks { + let origin = block.origin; + let block = block.block; + if let Some(header) = block.header { + let number = header.number; + let hash = header_hash(&header); + let parent = header.parent_hash; + let result = protocol.chain().import(header, block.body); + match result { + Ok(ImportResult::AlreadyInChain) => { + trace!(target: "sync", "Block already in chain {}: {:?}", number, hash); + self.block_imported(&hash, number); + }, + Ok(ImportResult::AlreadyQueued) => { + trace!(target: "sync", "Block already queued {}: {:?}", number, hash); + self.block_imported(&hash, number); + }, + Ok(ImportResult::Queued) => { + trace!(target: "sync", "Block queued {}: {:?}", number, hash); + self.block_imported(&hash, number); + imported = imported + 1; + }, + Ok(ImportResult::UnknownParent) => { + debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent); + self.restart(io, protocol); + return; + }, + Ok(ImportResult::KnownBad) => { + debug!(target: "sync", "Bad block {}: {:?}", number, hash); + io.disable_peer(origin); //TODO: use persistent ID + self.restart(io, protocol); + return; + } + Err(e) => { + debug!(target: "sync", "Error importing block {}: {:?}: {:?}", number, hash, e); + self.restart(io, protocol); + return; + } + } + } + } + trace!(target: "sync", "Imported {} of {}", imported, count); + self.maintain_sync(io, protocol); + } + + fn maintain_sync(&mut self, io: &mut SyncIo, protocol: &Protocol) { + let peers: Vec = self.peers.keys().map(|p| *p).collect(); + for peer in peers { + self.download_new(io, protocol, peer); + } + } + + fn block_imported(&mut self, hash: &HeaderHash, number: BlockNumber) { + if number > self.best_queued_number { + self.best_queued_number = number; + self.best_queued_hash = *hash; + } + // Update common blocks + for (_, peer) in self.peers.iter_mut() { + if peer.best_number >= number { + peer.common_number = number; + peer.common_hash = *hash; + } + } + } + + pub fn update_chain_info(&mut self, best_header: &Header ) { + let hash = header_hash(&best_header); + self.block_imported(&hash, best_header.number) + } + + pub fn on_block_announce(&mut self, io: &mut SyncIo, protocol: &Protocol, peer_id: PeerId, header: &Header) { + let hash = header_hash(&header); + if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + if header.number > peer.best_number { + peer.best_number = header.number; + peer.best_hash = hash; + } + } else { + return; + } + + if !self.is_known_or_already_downloading(protocol, &hash) { + let stale = header.number <= self.best_queued_number; + if stale { + if !self.is_known_or_already_downloading(protocol, &header.parent_hash) { + trace!(target: "sync", "Ignoring unkown stale block announce from {}: {} {:?}", peer_id, hash, header); + } else { + trace!(target: "sync", "Downloading new stale block announced from {}: {} {:?}", peer_id, hash, header); + self.download_stale(io, protocol, peer_id, &hash); + } + } else { + trace!(target: "sync", "Downloading new block announced from {}: {} {:?}", peer_id, hash, header); + self.download_new(io, protocol, peer_id); + } + } else { + trace!(target: "sync", "Known block announce from {}: {}", peer_id, hash); + } + } + + fn is_known_or_already_downloading(&self, protocol: &Protocol, hash: &HeaderHash) -> bool { + self.peers.iter().any(|(_, p)| p.state == PeerSyncState::DownloadingStale(*hash)) + || protocol.chain().block_status(hash).ok().map_or(false, |s| s != BlockStatus::Unknown) + } + + pub fn peer_disconnected(&mut self, io: &mut SyncIo, protocol: &Protocol, peer_id: PeerId) { + self.blocks.clear_peer_download(peer_id); + self.peers.remove(&peer_id); + self.maintain_sync(io, protocol); + } + + pub fn restart(&mut self, io: &mut SyncIo, protocol: &Protocol) { + self.blocks.clear(); + let ids: Vec = self.peers.keys().map(|p| *p).collect(); + for id in ids { + self.new_peer(io, protocol, id); + } + match protocol.chain().info() { + Ok(info) => { + self.best_queued_hash = info.best_queued_hash.unwrap_or(info.chain.best_hash); + self.best_queued_number = info.best_queued_number.unwrap_or(info.chain.best_number); + }, + Err(e) => { + debug!(target:"sync", "Error reading blockchain: {:?}", e); + self.best_queued_hash = self.genesis_hash; + self.best_queued_number = 0; + } + } + } + + pub fn clear(&mut self) { + self.blocks.clear(); + self.peers.clear(); + } + + // Download old block. + fn download_stale(&mut self, io: &mut SyncIo, protocol: &Protocol, peer_id: PeerId, hash: &HeaderHash) { + if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + match peer.state { + PeerSyncState::Available => { + let request = message::BlockRequest { + id: 0, + fields: self.required_block_attributes.clone(), + from: message::FromBlock::Hash(*hash), + to: None, + direction: message::Direction::Ascending, + max: Some(1), + }; + peer.state = PeerSyncState::DownloadingStale(*hash); + protocol.send_message(io, peer_id, Message::BlockRequest(request)); + }, + _ => (), + } + } + } + + // Issue a request for a peer to download new blocks, if any are available + fn download_new(&mut self, io: &mut SyncIo, protocol: &Protocol, peer_id: PeerId) { + if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + match peer.state { + PeerSyncState::Available => { + if let Some(range) = self.blocks.needed_blocks(peer_id, MAX_BLOCK_DOWNLOAD, peer.common_number, peer.best_number) { + let request = message::BlockRequest { + id: 0, + fields: self.required_block_attributes.clone(), + from: message::FromBlock::Number(range.start), + to: None, + direction: message::Direction::Ascending, + max: Some((range.end - range.start) as u32), + }; + peer.state = PeerSyncState::DownloadingNew(range.start); + protocol.send_message(io, peer_id, Message::BlockRequest(request)); + } + }, + _ => (), + } + } + } + + fn request_ancestry(io: &mut SyncIo, protocol: &Protocol, peer_id: PeerId, block: BlockNumber) { + let request = message::BlockRequest { + id: 0, + fields: vec![message::BlockAttribute::Header], + from: message::FromBlock::Number(block), + to: None, + direction: message::Direction::Ascending, + max: Some(1), + }; + protocol.send_message(io, peer_id, Message::BlockRequest(request)); + } +} + + + + diff --git a/substrate/network/src/test/mod.rs b/substrate/network/src/test/mod.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/substrate/primitives/src/block.rs b/substrate/primitives/src/block.rs index 8cd077fd78..eb2c7785c2 100644 --- a/substrate/primitives/src/block.rs +++ b/substrate/primitives/src/block.rs @@ -20,24 +20,30 @@ use bytes; use hash::H256; use parachain; +/// Used to refer to a block number. +pub type Number = u64; + /// Hash used to refer to a block hash. pub type HeaderHash = H256; +/// Hash used to refer to a transaction hash. +pub type TransactionHash = H256; + /// Execution log (event) -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct Log(#[serde(with="bytes")] pub Vec); /// A relay chain block header. /// /// https://github.com/w3f/polkadot-spec/blob/master/spec.md#header -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] pub struct Header { /// Block parent's hash. pub parent_hash: HeaderHash, /// Block number. - pub number: u64, + pub number: Number, /// State root after this transition. pub state_root: H256, /// Parachain activity bitfield @@ -50,7 +56,7 @@ pub struct Header { /// /// Included candidates should be sorted by parachain ID, and without duplicate /// IDs. -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] pub struct Body { diff --git a/substrate/primitives/src/hash.rs b/substrate/primitives/src/hash.rs index 0b56d5757f..b6711cdfcb 100644 --- a/substrate/primitives/src/hash.rs +++ b/substrate/primitives/src/hash.rs @@ -37,11 +37,11 @@ macro_rules! impl_serde { } } -impl_hash!(H160, 20); +construct_hash!(H160, 20); impl_serde!(H160, 20); -impl_hash!(H256, 32); +construct_hash!(H256, 32); impl_serde!(H256, 32); -impl_hash!(H512, 64); +construct_hash!(H512, 64); impl_serde!(H512, 64); #[cfg(test)] diff --git a/substrate/primitives/src/parachain.rs b/substrate/primitives/src/parachain.rs index ed44134ce2..cecbbb1dbb 100644 --- a/substrate/primitives/src/parachain.rs +++ b/substrate/primitives/src/parachain.rs @@ -98,7 +98,7 @@ pub struct HeadData(#[serde(with="bytes")] pub Vec); pub struct ValidationCode(#[serde(with="bytes")] pub Vec); /// Activitiy bit field -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)] pub struct Activity(#[serde(with="bytes")] pub Vec); #[cfg(test)] diff --git a/substrate/rpc/src/chain/mod.rs b/substrate/rpc/src/chain/mod.rs index 86b00795ec..519bdefb4a 100644 --- a/substrate/rpc/src/chain/mod.rs +++ b/substrate/rpc/src/chain/mod.rs @@ -18,6 +18,7 @@ use primitives::block; use client; +use state_machine; mod error; @@ -35,11 +36,12 @@ build_rpc_trait! { } } -impl ChainApi for B where - B: client::Blockchain + Send + Sync + 'static, - B::Error: ::std::error::Error + Send, +impl ChainApi for client::Client where + B: client::backend::Backend + Send + Sync + 'static, + E: state_machine::CodeExecutor + Send + Sync + 'static, + client::error::Error: From<<::State as state_machine::backend::Backend>::Error>, { fn header(&self, hash: block::HeaderHash) -> Result> { - self.header(&hash).chain_err(|| "Blockchain error") + client::Client::header(self, &hash).chain_err(|| "Blockchain error") } } diff --git a/substrate/rpc/src/chain/tests.rs b/substrate/rpc/src/chain/tests.rs index 00208b9598..bf2f3afdac 100644 --- a/substrate/rpc/src/chain/tests.rs +++ b/substrate/rpc/src/chain/tests.rs @@ -14,28 +14,27 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use primitives::parachain; +use polkadot_executor as executor; +use client; use super::*; -use test_helpers::Blockchain; - #[test] fn should_return_header() { - let state = Blockchain::default(); + let client = client::new_in_mem(executor::executor()).unwrap(); assert_matches!( - ChainApi::header(&state, 0.into()), + ChainApi::header(&client, "11265ce45dd2baaaf071f6df8c5a44f0ed1d85a50e71451ff2d4345e57d12e3a".into()), Ok(Some(ref x)) if x == &block::Header { parent_hash: 0.into(), number: 0, state_root: 0.into(), - parachain_activity: parachain::Activity(vec![0]), + parachain_activity: Default::default(), logs: vec![], } ); assert_matches!( - ChainApi::header(&state, 5.into()), + ChainApi::header(&client, 5.into()), Ok(None) ); } diff --git a/substrate/rpc/src/lib.rs b/substrate/rpc/src/lib.rs index 5061ffb56d..b18f503547 100644 --- a/substrate/rpc/src/lib.rs +++ b/substrate/rpc/src/lib.rs @@ -36,6 +36,3 @@ extern crate assert_matches; pub mod chain; pub mod state; - -#[cfg(test)] -mod test_helpers; diff --git a/substrate/rpc/src/state/mod.rs b/substrate/rpc/src/state/mod.rs index 113fe4849b..12905b7545 100644 --- a/substrate/rpc/src/state/mod.rs +++ b/substrate/rpc/src/state/mod.rs @@ -42,8 +42,9 @@ build_rpc_trait! { } impl StateApi for Client where - B: client::Blockchain + Send + Sync + 'static, + B: client::backend::Backend + Send + Sync + 'static, E: state_machine::CodeExecutor + Send + Sync + 'static, + client::error::Error: From<<::State as state_machine::backend::Backend>::Error>, { fn storage(&self, key: StorageKey, block: block::HeaderHash) -> Result { Ok(self.storage(&block, &key)?) diff --git a/substrate/rpc/src/state/tests.rs b/substrate/rpc/src/state/tests.rs index 20051d4144..b62221adea 100644 --- a/substrate/rpc/src/state/tests.rs +++ b/substrate/rpc/src/state/tests.rs @@ -18,14 +18,15 @@ use super::*; use polkadot_executor as executor; use self::error::{Error, ErrorKind}; -use test_helpers::Blockchain; +use client; #[test] fn should_return_storage() { - let client = Client::new(Blockchain::default(), executor::executor()); + let client = client::new_in_mem(executor::executor()).unwrap(); + let genesis_hash = "11265ce45dd2baaaf071f6df8c5a44f0ed1d85a50e71451ff2d4345e57d12e3a".into(); assert_matches!( - StateApi::storage(&client, StorageKey(vec![10]), 0.into()), + StateApi::storage(&client, StorageKey(vec![10]), genesis_hash), Ok(ref x) if x.0.is_empty() ) } @@ -34,10 +35,11 @@ fn should_return_storage() { #[ignore] // TODO: [ToDr] reenable once we can properly mock the wasm executor env fn should_call_contract() { // TODO [ToDr] Fix test after we are able to mock state. - let client = Client::new(Blockchain::default(), executor::executor()); + let client = client::new_in_mem(executor::executor()).unwrap(); + let genesis_hash = "11265ce45dd2baaaf071f6df8c5a44f0ed1d85a50e71451ff2d4345e57d12e3a".into(); assert_matches!( - StateApi::call(&client, "balanceOf".into(), CallData(vec![1,2,3]), 0.into()), + StateApi::call(&client, "balanceOf".into(), CallData(vec![1,2,3]), genesis_hash), Err(Error(ErrorKind::Client(client::error::ErrorKind::Execution(_)), _)) ) } diff --git a/substrate/runtime-std/Cargo.toml b/substrate/runtime-std/Cargo.toml index 56721a6352..8a672e93a4 100644 --- a/substrate/runtime-std/Cargo.toml +++ b/substrate/runtime-std/Cargo.toml @@ -13,9 +13,10 @@ pwasm-libc = { path = "../wasm-runtime/pwasm-libc", version = "0.1" } environmental = { path = "../environmental", version = "0.1", optional = true } polkadot-state-machine = { path = "../state-machine", version = "0.1", optional = true } polkadot-primitives = { path = "../primitives", version = "0.1", optional = true } +triehash = { version = "0.1", optional = true } [features] default = ["std"] -std = ["environmental", "polkadot-state-machine", "polkadot-primitives"] +std = ["environmental", "polkadot-state-machine", "polkadot-primitives", "triehash"] nightly = [] strict = [] diff --git a/substrate/runtime-std/with_std.rs b/substrate/runtime-std/with_std.rs index a23f8e13d7..19a3cd04a3 100644 --- a/substrate/runtime-std/with_std.rs +++ b/substrate/runtime-std/with_std.rs @@ -20,6 +20,7 @@ extern crate environmental; extern crate polkadot_state_machine; extern crate polkadot_primitives as primitives; +extern crate triehash; use std::fmt; use primitives::ed25519; @@ -31,7 +32,7 @@ pub use std::boxed; pub use std::slice; pub use std::mem; -pub use polkadot_state_machine::{Externalities, ExternalitiesError}; +pub use polkadot_state_machine::{Externalities, ExternalitiesError, TestExternalities}; use primitives::hexdisplay::HexDisplay; // TODO: use the real error, not NoError. @@ -84,6 +85,18 @@ pub fn chain_id() -> u64 { ).unwrap_or(0) } +/// "Commit" all existing operations and get the resultant storage root. +pub fn storage_root() -> [u8; 32] { + ext::with(|ext| + ext.storage_root() + ).unwrap_or([0u8; 32]) +} + +/// "Commit" all existing operations and get the resultant storage root. +pub fn enumerated_trie_root(serialised_values: &[&[u8]]) -> [u8; 32] { + triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0 +} + /// Conduct a Keccak-256 hash of the given data. pub use primitives::{blake2_256, twox_128, twox_256}; @@ -134,23 +147,6 @@ macro_rules! impl_stubs { #[cfg(test)] mod tests { use super::*; - use std::collections::HashMap; - - #[derive(Debug, Default)] - struct TestExternalities { - storage: HashMap, Vec>, - } - impl Externalities for TestExternalities { - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - - fn chain_id(&self) -> u64 { 42 } - } macro_rules! map { ($( $name:expr => $value:expr ),*) => ( diff --git a/substrate/runtime-std/without_std.rs b/substrate/runtime-std/without_std.rs index 8d1e589faa..d49bcdbcaa 100644 --- a/substrate/runtime-std/without_std.rs +++ b/substrate/runtime-std/without_std.rs @@ -33,6 +33,8 @@ extern "C" { fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; + fn ext_storage_root(result: *mut u8); + fn ext_enumerated_trie_root(values_data: *const u8, values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8); fn ext_chain_id() -> u64; fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); @@ -67,6 +69,30 @@ pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> us } } +/// The current storage's root. +pub fn storage_root() -> [u8; 32] { + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_storage_root(result.as_mut_ptr()); + } + result +} + +/// A trie root calculated from enumerated values. +pub fn enumerated_trie_root(values: &[&[u8]]) -> [u8; 32] { + let lens = values.iter().map(|v| (v.len() as u32).to_le()).collect::>(); + let values = values.iter().fold(Vec::new(), |mut acc, sl| { acc.extend_from_slice(sl); acc }); + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_enumerated_trie_root( + values.as_ptr(), values.len() as u32, + lens.as_ptr(), lens.len() as u32, + result.as_mut_ptr() + ); + } + result +} + /// The current relay chain identifier. pub fn chain_id() -> u64 { unsafe { @@ -77,7 +103,6 @@ pub fn chain_id() -> u64 { /// Conduct a 256-bit Blake2 hash. pub fn blake2_256(data: &[u8]) -> [u8; 32] { let mut result: [u8; 32] = Default::default(); - // guaranteed to write into result. unsafe { ext_blake2_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); } @@ -87,7 +112,6 @@ pub fn blake2_256(data: &[u8]) -> [u8; 32] { /// Conduct four XX hashes to give a 256-bit result. pub fn twox_256(data: &[u8]) -> [u8; 32] { let mut result: [u8; 32] = Default::default(); - // guaranteed to write into result. unsafe { ext_twox_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); } @@ -97,7 +121,6 @@ pub fn twox_256(data: &[u8]) -> [u8; 32] { /// Conduct two XX hashes to give a 128-bit result. pub fn twox_128(data: &[u8]) -> [u8; 16] { let mut result: [u8; 16] = Default::default(); - // guaranteed to write into result. unsafe { ext_twox_128(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); } diff --git a/substrate/state-machine/Cargo.toml b/substrate/state-machine/Cargo.toml index 458bae8e1e..65c6feed54 100644 --- a/substrate/state-machine/Cargo.toml +++ b/substrate/state-machine/Cargo.toml @@ -11,3 +11,4 @@ patricia-trie = "0.1.0" memorydb = "0.1.1" triehash = "0.1" byteorder = "1.1" +hex-literal = "0.1.0" diff --git a/substrate/state-machine/src/backend.rs b/substrate/state-machine/src/backend.rs index ee6b0bbe80..5057339ce9 100644 --- a/substrate/state-machine/src/backend.rs +++ b/substrate/state-machine/src/backend.rs @@ -40,6 +40,9 @@ pub trait Backend { /// Commit updates to the backend and get new state. fn commit(&mut self, changes: I) -> Committed where I: IntoIterator; + + /// Get all key/value pairs into a Vec. + fn pairs(&self) -> Vec<(&[u8], &[u8])>; } /// Error impossible. @@ -59,15 +62,27 @@ impl error::Error for Void { /// In-memory backend. Fully recomputes tries on each commit but useful for /// tests. -#[derive(Default)] +#[derive(Default, Clone)] pub struct InMemory { inner: MemoryState, // keeps all the state in memory. } +#[cfg(test)] +impl InMemory { + /// Create a new instance from a given storage map. + pub fn from(storage: ::std::collections::HashMap, Vec>) -> Self { + InMemory { + inner: MemoryState { + storage + } + } + } +} + impl Backend for InMemory { type Error = Void; - fn storage(&self, key: &[u8]) -> Result<&[u8], Void> { + fn storage(&self, key: &[u8]) -> Result<&[u8], Self::Error> { Ok(self.inner.storage(key).unwrap_or(&[])) } @@ -87,6 +102,10 @@ impl Backend for InMemory { storage_tree_root, } } + + fn pairs(&self) -> Vec<(&[u8], &[u8])> { + self.inner.storage.iter().map(|(k, v)| (&k[..], &v[..])).collect() + } } // TODO: DB-based backend diff --git a/substrate/state-machine/src/ext.rs b/substrate/state-machine/src/ext.rs index 764c51de10..1beca17fa6 100644 --- a/substrate/state-machine/src/ext.rs +++ b/substrate/state-machine/src/ext.rs @@ -17,7 +17,7 @@ //! Conrete externalities implementation. use std::{error, fmt}; - +use triehash::trie_root; use backend::Backend; use {Externalities, ExternalitiesError, OverlayedChanges}; @@ -75,4 +75,15 @@ impl<'a, B: 'a> Externalities for Ext<'a, B> fn chain_id(&self) -> u64 { 42 } + + fn storage_root(&self) -> [u8; 32] { + let mut all_pairs = self.backend.pairs(); + all_pairs.extend( + self.overlay.committed.storage.iter() + .chain(self.overlay.prospective.storage.iter()) + .map(|(k, v)| (&k[..], &v[..])) + ); + + trie_root(all_pairs.into_iter().map(|(k, v)| (k.to_vec(), v.to_vec()))).0 + } } diff --git a/substrate/state-machine/src/lib.rs b/substrate/state-machine/src/lib.rs index cd7f9291bb..e497a20474 100644 --- a/substrate/state-machine/src/lib.rs +++ b/substrate/state-machine/src/lib.rs @@ -19,6 +19,8 @@ #![warn(missing_docs)] extern crate polkadot_primitives as primitives; +#[macro_use] +extern crate hex_literal; extern crate hashdb; extern crate memorydb; @@ -35,6 +37,9 @@ use primitives::contract::{CallData}; pub mod backend; mod ext; +mod testing; + +pub use testing::TestExternalities; /// Updates to be committed to the state. pub enum Update { @@ -43,7 +48,7 @@ pub enum Update { } // in-memory section of the state. -#[derive(Default)] +#[derive(Default, Clone)] struct MemoryState { storage: HashMap, Vec>, } @@ -141,6 +146,9 @@ pub trait Externalities { /// Get the identity of the chain. fn chain_id(&self) -> u64; + /// Get the trie root of the current storage map. + fn storage_root(&self) -> [u8; 32]; + /// Get the current set of authorities from storage. fn authorities(&self) -> Result, ExternalitiesError> { (0..self.storage(b"con:aut:len")?.into_iter() @@ -152,7 +160,7 @@ pub trait Externalities { } /// Code execution engine. -pub trait CodeExecutor: Sized { +pub trait CodeExecutor: Sized + Send + Sync { /// Externalities error type. type Error: Error; @@ -210,8 +218,9 @@ pub fn execute( #[cfg(test)] mod tests { - use std::collections::HashMap; - use super::{OverlayedChanges, Externalities, ExternalitiesError}; + use super::*; + use super::backend::InMemory; + use super::ext::Ext; #[test] fn overlayed_storage_works() { @@ -238,22 +247,6 @@ mod tests { assert!(overlayed.storage(&key).is_none()); } - #[derive(Debug, Default)] - struct TestExternalities { - storage: HashMap, Vec>, - } - impl Externalities for TestExternalities { - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - - fn chain_id(&self) -> u64 { 42 } - } - #[test] fn authorities_call_works() { let mut ext = TestExternalities::default(); @@ -273,4 +266,34 @@ mod tests { ext.set_storage(b"con:aut:\x01\0\0\0".to_vec(), b"second".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]])); } + + macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) + } + + #[test] + fn overlayed_storage_root_works() { + let mut backend = InMemory::from(map![ + b"doe".to_vec() => b"reindeer".to_vec(), + b"dog".to_vec() => b"puppyXXX".to_vec(), + b"dogglesworth".to_vec() => b"catXXX".to_vec() + ]); + let mut overlay = OverlayedChanges { + committed: MemoryState { storage: map![ + b"dog".to_vec() => b"puppy".to_vec(), + b"dogglesworth".to_vec() => b"catYYY".to_vec() + ], }, + prospective: MemoryState { storage: map![ + b"dogglesworth".to_vec() => b"cat".to_vec() + ], }, + }; + let ext = Ext { + backend: &mut backend, + overlay: &mut overlay, + }; + const ROOT: [u8; 32] = hex!("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"); + assert_eq!(ext.storage_root(), ROOT); + } } diff --git a/substrate/state-machine/src/testing.rs b/substrate/state-machine/src/testing.rs new file mode 100644 index 0000000000..1c9c4dfcf8 --- /dev/null +++ b/substrate/state-machine/src/testing.rs @@ -0,0 +1,68 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Test implementation for Externalities. + +use std::collections::HashMap; +use super::{Externalities, ExternalitiesError}; +use triehash::trie_root; + +/// Simple HashMap based Externalities impl. +#[derive(Debug, Default)] +pub struct TestExternalities { + /// The storage. + pub storage: HashMap, Vec>, +} + +impl TestExternalities { + /// Create a new instance with empty storage. + pub fn new() -> Self { + TestExternalities { + storage: HashMap::new(), + } + } +} + +impl Externalities for TestExternalities { + fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { + Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) + } + + fn set_storage(&mut self, key: Vec, value: Vec) { + self.storage.insert(key, value); + } + + fn chain_id(&self) -> u64 { 42 } + + fn storage_root(&self) -> [u8; 32] { + trie_root(self.storage.clone()).0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn commit_should_work() { + let mut ext = TestExternalities::new(); + ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec()); + ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); + ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); + const ROOT: [u8; 32] = hex!("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"); + assert_eq!(ext.storage_root(), ROOT); + } +} diff --git a/substrate/wasm-runtime/Cargo.lock b/substrate/wasm-runtime/Cargo.lock index 3fd66a2355..05d122c8b1 100644 --- a/substrate/wasm-runtime/Cargo.lock +++ b/substrate/wasm-runtime/Cargo.lock @@ -194,6 +194,23 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hex-literal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "isatty" version = "0.1.6" @@ -381,6 +398,7 @@ dependencies = [ "pwasm-alloc 0.1.0", "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -389,12 +407,26 @@ version = "0.1.0" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro-hack" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack-impl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pwasm-alloc" version = "0.1.0" @@ -748,6 +780,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +"checksum hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd546ef520ab3745f1aae5f2cdc6de9e6498e94d1ab138b9eb3ddfbf335847fb" +"checksum hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea76da4c7f1a54d01d54985566d3fdd960b2bbd7b970da024821c883c2d9631" "checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2" "checksum keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f300c1f149cd9ca5214eed24f6e713a597517420fb8b15499824aa916259ec1" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -766,6 +800,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f35048d735bb93dd115a0030498785971aab3234d311fbe273d020084d26bd8" "checksum patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2f638d79aba5c4a71a4f373df6e3cd702250a53b7f0ed4da1e2a7be9737ae" "checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995" +"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0" +"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" diff --git a/substrate/wasm-runtime/polkadot/src/lib.rs b/substrate/wasm-runtime/polkadot/src/lib.rs index f2414c738d..27900b9807 100644 --- a/substrate/wasm-runtime/polkadot/src/lib.rs +++ b/substrate/wasm-runtime/polkadot/src/lib.rs @@ -26,6 +26,10 @@ extern crate rustc_hex; extern crate polkadot_runtime_codec as codec; +#[cfg(test)] +#[macro_use] +extern crate hex_literal; + #[macro_use] pub mod support; pub mod primitives; diff --git a/substrate/wasm-runtime/polkadot/src/runtime/governance.rs b/substrate/wasm-runtime/polkadot/src/runtime/governance.rs index 4f7f6d8688..49605ce3ef 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/governance.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/governance.rs @@ -114,9 +114,9 @@ pub mod internal { #[cfg(test)] mod tests { use super::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, TestExternalities, with_env}; + use support::{one, two, with_env}; use primitives::{AccountID, InternalFunction}; use runtime::{staking, session}; diff --git a/substrate/wasm-runtime/polkadot/src/runtime/session.rs b/substrate/wasm-runtime/polkadot/src/runtime/session.rs index 0402816fdc..6cda783beb 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/session.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/session.rs @@ -132,9 +132,9 @@ mod tests { use super::public::*; use super::privileged::*; use super::internal::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, TestExternalities, with_env}; + use support::{one, two, with_env}; use primitives::AccountID; use runtime::{consensus, session}; diff --git a/substrate/wasm-runtime/polkadot/src/runtime/staking.rs b/substrate/wasm-runtime/polkadot/src/runtime/staking.rs index d9bb971647..df8d4d632f 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/staking.rs @@ -206,9 +206,9 @@ mod tests { use super::public::*; use super::privileged::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, TestExternalities, with_env}; + use support::{one, two, with_env}; use primitives::AccountID; use runtime::{staking, session}; diff --git a/substrate/wasm-runtime/polkadot/src/runtime/system.rs b/substrate/wasm-runtime/polkadot/src/runtime/system.rs index a6bf24718e..8df20f138e 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/system.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/system.rs @@ -18,8 +18,8 @@ //! and depositing logs. use runtime_std::prelude::*; -use runtime_std::{mem, print}; -use codec::KeyedVec; +use runtime_std::{mem, print, storage_root, enumerated_trie_root}; +use codec::{KeyedVec, Slicable}; use support::{Hashable, storage, with_env}; use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder}; use runtime::{staking, session}; @@ -74,13 +74,11 @@ pub mod internal { "Parent hash should be valid." ); - // TODO: check transaction trie root represents the transactions. - // this requires non-trivial changes to the externals API or compiling trie rooting into wasm - // so will wait until a little later. - - // store the header hash in storage. - let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT); - storage::put(&header_hash_key, &header.blake2_256()); + // check transaction trie root represents the transactions. + let txs = block.transactions.iter().map(Slicable::to_vec).collect::>(); + let txs_root = enumerated_trie_root(&txs.iter().map(Vec::as_slice).collect::>()); +// println!("TR: {}", ::support::HexDisplay::from(&txs_root)); + assert!(header.transaction_root == txs_root, "Transaction trie root must be valid."); // execute transactions block.transactions.iter().for_each(execute_transaction); @@ -91,9 +89,14 @@ pub mod internal { // any final checks final_checks(&block); - // TODO: check storage root. - // this requires non-trivial changes to the externals API or compiling trie rooting into wasm - // so will wait until a little later. + + // check storage root. + assert!(header.state_root == storage_root(), "Storage root must match that calculated."); + + // store the header hash in storage; we can't do it before otherwise there would be a + // cyclic dependency. + let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT); + storage::put(&header_hash_key, &header.blake2_256()); } /// Execute a given transaction. @@ -127,10 +130,10 @@ mod tests { use super::*; use super::internal::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{Joiner, KeyedVec, Slicable}; - use support::{StaticHexInto, TestExternalities, HexDisplay, one, two}; - use primitives::{UncheckedTransaction, Transaction, Function}; + use support::{StaticHexInto, HexDisplay, one, two}; + use primitives::{UncheckedTransaction, Transaction, Function, Header, Digest}; use runtime::staking; #[test] @@ -162,4 +165,105 @@ mod tests { assert_eq!(staking::balance(&two), 69); }); } + + fn new_test_ext() -> TestExternalities { + let one = one(); + let two = two(); + let three = [3u8; 32]; + + TestExternalities { storage: map![ + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), + twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), + twox_128(b"ses:len").to_vec() => vec![].join(&2u64), + twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), + twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), + twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), + twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), + twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], } + } + + #[test] + fn block_import_works() { + let one = one(); + let two = two(); + + let mut t = new_test_ext(); + + let tx = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&two).join(&69u64), + }, + signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), + }; + + let h = Header { + parent_hash: [69u8; 32], + number: 1, + state_root: hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db"), + transaction_root: hex!("91fab88ad8c30a6d05ad8e0cf9ab139bf1b8cdddc69abd51cdfa6d2699038af1"), + digest: Digest { logs: vec![], }, + }; + + let b = Block { + header: h, + transactions: vec![tx], + }; + + with_externalities(&mut t, || { + execute_block(b); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } + + #[test] + #[should_panic] + fn block_import_of_bad_state_root_fails() { + let one = one(); + let two = two(); + + let mut t = new_test_ext(); + + let tx = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&two).join(&69u64), + }, + signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), + }; + // tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000 + // sig: 679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a + + let h = Header { + parent_hash: [69u8; 32], + number: 1, + state_root: [0u8; 32], + transaction_root: [0u8; 32], // Unchecked currently. + digest: Digest { logs: vec![], }, + }; + + let b = Block { + header: h, + transactions: vec![tx], + }; + + with_externalities(&mut t, || { + execute_block(b); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } } diff --git a/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs b/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs index f0a798d112..abc3fab5b9 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -42,10 +42,9 @@ mod tests { use super::*; use super::public::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use runtime::timestamp; use codec::{Joiner, KeyedVec}; - use support::TestExternalities; #[test] fn timestamp_works() { diff --git a/substrate/wasm-runtime/polkadot/src/support/mod.rs b/substrate/wasm-runtime/polkadot/src/support/mod.rs index 07c62c3a92..652fb82aa6 100644 --- a/substrate/wasm-runtime/polkadot/src/support/mod.rs +++ b/substrate/wasm-runtime/polkadot/src/support/mod.rs @@ -28,7 +28,9 @@ mod testing; pub use self::environment::with_env; pub use self::storage::StorageVec; pub use self::hashable::Hashable; + #[cfg(feature = "std")] pub use self::statichex::{StaticHexConversion, StaticHexInto}; + #[cfg(feature = "std")] -pub use self::testing::{AsBytesRef, HexDisplay, TestExternalities, one, two}; +pub use self::testing::{AsBytesRef, HexDisplay, one, two}; diff --git a/substrate/wasm-runtime/polkadot/src/support/storage.rs b/substrate/wasm-runtime/polkadot/src/support/storage.rs index bf9d605eb5..9e6494f126 100644 --- a/substrate/wasm-runtime/polkadot/src/support/storage.rs +++ b/substrate/wasm-runtime/polkadot/src/support/storage.rs @@ -146,9 +146,8 @@ pub trait StorageVec { mod tests { use super::*; use std::collections::HashMap; - use runtime_std::with_externalities; - use support::{TestExternalities, HexDisplay}; - use runtime_std::{storage, twox_128}; + use support::HexDisplay; + use runtime_std::{storage, twox_128, TestExternalities, with_externalities}; #[test] fn integers_can_be_stored() { diff --git a/substrate/wasm-runtime/polkadot/src/support/testing.rs b/substrate/wasm-runtime/polkadot/src/support/testing.rs index e0e1a336c8..a2c8579c96 100644 --- a/substrate/wasm-runtime/polkadot/src/support/testing.rs +++ b/substrate/wasm-runtime/polkadot/src/support/testing.rs @@ -16,30 +16,9 @@ //! Testing helpers. -use std::collections::HashMap; -use runtime_std::{Externalities, ExternalitiesError}; use primitives::AccountID; use super::statichex::StaticHexInto; -#[derive(Debug, Default)] -/// Simple externaties implementation. -pub struct TestExternalities { - /// The storage map. - pub storage: HashMap, Vec>, -} - -impl Externalities for TestExternalities { - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - - fn chain_id(&self) -> u64 { 42 } -} - #[macro_export] macro_rules! map { ($( $name:expr => $value:expr ),*) => ( diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 7fdbe868b7..1e0d5c637b 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index 726801e8a2..31e295da64 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index a1127c4e66..1b4fd44e92 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm index f8244dc3a2..58bc742f46 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/wasm-runtime/test/src/lib.rs b/substrate/wasm-runtime/test/src/lib.rs index b0b7f0a4bb..a97f5029f1 100644 --- a/substrate/wasm-runtime/test/src/lib.rs +++ b/substrate/wasm-runtime/test/src/lib.rs @@ -8,7 +8,10 @@ use alloc::vec::Vec; #[macro_use] extern crate polkadot_runtime_std as runtime_std; -use runtime_std::{set_storage, storage, print, blake2_256, twox_128, twox_256, ed25519_verify}; +use runtime_std::{ + set_storage, storage, print, blake2_256, + twox_128, twox_256, ed25519_verify, enumerated_trie_root +}; fn test_blake2_256(input: &[u8]) -> Vec { blake2_256(&input).to_vec() @@ -29,6 +32,10 @@ fn test_ed25519_verify(input: &[u8]) -> Vec { [ed25519_verify(sig, &msg[..], pubkey) as u8].to_vec() } +fn test_enumerated_trie_root(_input: &[u8]) -> Vec { + enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() +} + fn test_data_in(input: &[u8]) -> Vec { print("set_storage"); set_storage(b"input", &input); @@ -59,4 +66,4 @@ fn test_conditional_panic(input: &[u8]) -> Vec { } impl_stubs!(test_data_in, test_empty_return, test_panic, test_conditional_panic, - test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify); + test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify, test_enumerated_trie_root);