Merge branch 'master' into gav-storage-root-verify

This commit is contained in:
Gav
2018-01-30 20:57:33 +01:00
31 changed files with 2689 additions and 154 deletions
+465 -50
View File
@@ -46,7 +46,7 @@ dependencies = [
[[package]]
name = "backtrace"
version = "0.3.3"
version = "0.3.4"
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)",
@@ -98,6 +98,11 @@ name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2-rfc"
version = "0.2.18"
@@ -160,6 +165,11 @@ name = "constant_time_eq"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crossbeam"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crunchy"
version = "0.1.6"
@@ -184,6 +194,11 @@ name = "dtoa"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "edit-distance"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "either"
version = "1.4.0"
@@ -215,7 +230,31 @@ 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.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "eth-secp256k1"
version = "0.5.6"
source = "git+https://github.com/paritytech/rust-secp256k1#b6b67055edc929057e97d64f036c78ad91f58a7f"
dependencies = [
"arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.54 (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)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethcore-bigint"
version = "0.2.1"
source = "git+https://github.com/paritytech/parity.git#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"plain_hasher 0.1.0 (git+https://github.com/paritytech/parity.git)",
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -231,11 +270,44 @@ dependencies = [
"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#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
[[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#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"crossbeam 0.2.10 (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)",
"parking_lot 0.4.8 (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#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"ansi_term 0.9.0 (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.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethcore-logger"
version = "1.9.0"
@@ -245,13 +317,77 @@ dependencies = [
"arrayvec 0.3.24 (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)",
"lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (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#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1 (git+https://github.com/paritytech/parity.git)",
"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)",
"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.33 (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)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"path 0.1.0 (git+https://github.com/paritytech/parity.git)",
"rand 0.3.18 (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_json 1.0.6 (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.38 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethcrypto"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity.git#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)",
"ethcore-bigint 0.2.1 (git+https://github.com/paritytech/parity.git)",
"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.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethkey"
version = "0.3.0"
source = "git+https://github.com/paritytech/parity.git#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"edit-distance 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)",
"ethcore-bigint 0.2.1 (git+https://github.com/paritytech/parity.git)",
"lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (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.18 (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.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fixed-hash"
version = "0.1.0"
@@ -301,6 +437,9 @@ dependencies = [
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"
@@ -355,7 +494,25 @@ 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)",
"httparse 1.2.3 (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)",
"mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (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.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -373,7 +530,29 @@ dependencies = [
"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.18 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (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]]
@@ -385,6 +564,11 @@ dependencies = [
"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"
@@ -395,6 +579,14 @@ dependencies = [
"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"
@@ -403,42 +595,42 @@ 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"
source = "git+https://github.com/paritytech/jsonrpc.git#0eba7e745b0895b4234cd8d89b28e10e2c3c34a4"
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 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.6 (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#0eba7e745b0895b4234cd8d89b28e10e2c3c34a4"
dependencies = [
"hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.0 (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)",
"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#0eba7e745b0895b4234cd8d89b28e10e2c3c34a4"
dependencies = [
"jsonrpc-core 8.0.0 (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.20 (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#0eba7e745b0895b4234cd8d89b28e10e2c3c34a4"
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)",
@@ -448,7 +640,7 @@ dependencies = [
[[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#0eba7e745b0895b4234cd8d89b28e10e2c3c34a4"
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)",
@@ -458,6 +650,16 @@ dependencies = [
"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#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1 (git+https://github.com/paritytech/parity.git)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "keccak-hash"
version = "0.1.0"
@@ -484,7 +686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "0.2.9"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -507,6 +709,11 @@ name = "log"
version = "0.3.8"
source = "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"
@@ -529,12 +736,20 @@ dependencies = [
"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.8 (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]]
@@ -628,6 +843,16 @@ dependencies = [
"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.10 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot"
version = "0.4.8"
@@ -658,6 +883,11 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "path"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity.git#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
[[package]]
name = "patricia-trie"
version = "0.1.0"
@@ -681,6 +911,14 @@ name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plain_hasher"
version = "0.1.0"
source = "git+https://github.com/paritytech/parity.git#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "plain_hasher"
version = "0.1.0"
@@ -695,6 +933,7 @@ 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]]
@@ -725,7 +964,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.8 (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",
]
@@ -752,8 +994,33 @@ dependencies = [
"polkadot-state-machine 0.1.0",
"runtime-std 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.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.20 (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.1 (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.8 (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.18 (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.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -768,8 +1035,8 @@ dependencies = [
"pretty_assertions 0.4.0 (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.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.20 (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)",
@@ -802,7 +1069,7 @@ dependencies = [
name = "polkadot-serializer"
version = "0.1.0"
dependencies = [
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -826,7 +1093,7 @@ 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.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -879,7 +1146,7 @@ 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)",
"lazy_static 0.2.10 (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)",
@@ -929,12 +1196,24 @@ 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)",
"lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (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#dde6baedeca4b2dccaf2eacfbd2453b3d191596e"
dependencies = [
"byteorder 1.1.0 (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 (git+https://github.com/paritytech/parity.git)",
"lazy_static 0.2.10 (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"
@@ -943,7 +1222,7 @@ dependencies = [
"byteorder 1.1.0 (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.10 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -958,6 +1237,18 @@ dependencies = [
"polkadot-state-machine 0.1.0",
]
[[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.33 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.18 (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.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-demangle"
version = "0.1.5"
@@ -969,12 +1260,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"
@@ -999,11 +1287,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"
@@ -1019,12 +1302,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.19"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.19"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1049,9 +1332,14 @@ 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)",
"serde 1.0.20 (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"
@@ -1071,6 +1359,27 @@ 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.1 (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.33 (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.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "stable_deref_trait"
@@ -1082,6 +1391,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.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.11.11"
@@ -1128,7 +1445,7 @@ name = "thread_local"
version = "0.3.4"
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 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1207,6 +1524,11 @@ dependencies = [
"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"
@@ -1225,6 +1547,11 @@ dependencies = [
"rand 0.3.18 (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"
@@ -1237,12 +1564,33 @@ dependencies = [
[[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"
@@ -1266,6 +1614,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"
@@ -1276,6 +1634,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"
@@ -1300,6 +1663,22 @@ 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"
@@ -1312,12 +1691,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"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 backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e"
"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 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"
@@ -1326,17 +1706,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180"
"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.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
"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.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a34f5204fbc13582de418611cf3a7dcdd07c6d312a5b631597ba72c06b9d9c9"
"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.6 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
"checksum ethcore-bigint 0.2.1 (git+https://github.com/paritytech/parity.git)" = "<none>"
"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)" = "<none>"
"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)" = "<none>"
"checksum ethcore-logger 1.9.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
"checksum ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fd5813e49546030be7d134e775088d56b8ff4ab60617b90e93d4f0513da4c5b"
"checksum ethcore-network 1.9.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
"checksum ethcrypto 0.1.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
"checksum ethkey 0.3.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
"checksum fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "<none>"
"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"
@@ -1350,25 +1740,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"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.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 hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
"checksum hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4959ca95f55df4265bff2ad63066147255e6fa733682cf6d1cb5eaff6e53324b"
"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7"
"checksum ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2134e210e2a024b5684f90e1556d5f71a1ce7f8b12e9ac9924c67fb36f63b336"
"checksum isatty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "00c9301a947a2eaee7ce2556b80285dcc89558d07088962e6e8b9c25730f9dc6"
"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)" = "<none>"
"checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "<none>"
"checksum jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "<none>"
"checksum jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "<none>"
"checksum jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "<none>"
"checksum keccak-hash 0.1.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
"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 lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "236eb37a62591d4a41a89b7763d7de3e06ca02d5ab2815446a8bae5d2f8c2d57"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"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 matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
"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 miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
@@ -1379,11 +1777,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
"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 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412"
"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595"
"checksum path 0.1.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
"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 (git+https://github.com/paritytech/parity.git)" = "<none>"
"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 proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0"
@@ -1398,27 +1799,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"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 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)" = "<none>"
"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 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "5a2b181dd2b4a6353e828e44807269a761d3ecbc388a1f5ed3998ea69a516d9c"
"checksum serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "31ce3c16ec18abb97d977f75880986549213b0c18f2695eda8b31eadc96eda4a"
"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 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 snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
"checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
"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"
@@ -1432,18 +1838,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"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)" = "<none>"
"checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80"
"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-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"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"
+2
View File
@@ -6,6 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
error-chain = "0.11"
polkadot-cli = { path = "cli", version = "0.1" }
polkadot-network = { path = "network" }
[workspace]
members = [
@@ -21,6 +22,7 @@ members = [
"serializer",
"state_machine",
"validator",
"network",
]
exclude = [
"wasm-runtime"
+5
View File
@@ -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"];
}
}
+2 -17
View File
@@ -48,14 +48,13 @@ pub fn run<I, T>(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<primitives::block::HeaderHash, Self::Error> {
Ok(0.into())
}
fn header(&self, _hash: &primitives::block::HeaderHash) -> Result<Option<primitives::block::Header>, Self::Error> {
Ok(None)
}
}
+3
View File
@@ -5,5 +5,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
[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" }
+53
View File
@@ -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 <http://www.gnu.org/licenses/>.
//! 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<Self::State>;
/// Append block data to the transaction.
fn import_block(&mut self, header: block::Header, body: Option<block::Body>, 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<Self::BlockImportOperation>;
/// 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<Self::State>;
}
+86
View File
@@ -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 <http://www.gnu.org/licenses/>.
//! 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<Option<block::Header>>;
/// Get block body. Returns `None` if block is not found.
fn body(&self, id: BlockId) -> Result<Option<block::Body>>;
/// Get blockchain info.
fn info(&self) -> Result<Info>;
/// Get block status.
fn status(&self, id: BlockId) -> Result<BlockStatus>;
/// Get block hash by number. Returns `None` if the header is not in the chain.
fn hash(&self, number: block::Number) -> Result<Option<block::HeaderHash>>;
}
/// Block import outcome
pub enum ImportResult<E> {
/// 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,
}
+22 -2
View File
@@ -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<std::error::Error + Send>) {
description("Blockchain error"),
display("Blockchain: {}", e),
}
}
}
@@ -47,3 +54,16 @@ impl From<Box<state_machine::Error>> for Error {
ErrorKind::Execution(e).into()
}
}
impl From<state_machine::backend::Void> for Error {
fn from(_e: state_machine::backend::Void) -> Self {
unreachable!()
}
}
impl Error {
/// Chain a blockchain error.
pub fn from_blockchain(e: Box<std::error::Error + Send>) -> Self {
ErrorKind::Blockchain(e).into()
}
}
+204
View File
@@ -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 <http://www.gnu.org/licenses/>.
//! 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<block::Body>,
}
/// In-memory transaction.
pub struct BlockImportOperation {
pending_block: Option<PendingBlock>,
pending_state: state_machine::backend::InMemory,
}
struct BlockchainStorage {
blocks: HashMap<HeaderHash, Block>,
hashes: HashMap<block::Number, HeaderHash>,
best_hash: HeaderHash,
best_number: block::Number,
genesis_hash: HeaderHash,
}
/// In-memory blockchain. Supports concurrent reads.
pub struct Blockchain {
storage: RwLock<BlockchainStorage>,
}
impl Blockchain {
fn id(&self, id: BlockId) -> Option<HeaderHash> {
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<block::Body>, 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<Option<block::Header>> {
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<Option<block::Body>> {
Ok(self.id(id).and_then(|hash| self.storage.read().blocks.get(&hash).and_then(|b| b.body.clone())))
}
fn info(&self) -> error::Result<blockchain::Info> {
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<BlockStatus> {
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<Option<block::HeaderHash>> {
Ok(self.id(BlockId::Number(number)))
}
}
impl backend::BlockImportOperation for BlockImportOperation {
type State = state_machine::backend::InMemory;
fn state(&self) -> error::Result<Self::State> {
Ok(self.pending_state.clone())
}
fn import_block(&mut self, header: block::Header, body: Option<block::Body>, 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<HashMap<block::HeaderHash, state_machine::backend::InMemory>>,
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<Self::BlockImportOperation> {
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<Self::State> {
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()),
}
}
}
+133 -32
View File
@@ -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<B, E> where B: backend::Backend {
backend: B,
executor: E,
}
/// Returns the hash of latest block.
fn latest_hash(&self) -> Result<block::HeaderHash, Self::Error>;
/// Given a hash return a header
fn header(&self, hash: &block::HeaderHash) -> Result<Option<block::Header>, 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<block::Number>,
/// Best queued block hash.
pub best_queued_hash: Option<block::HeaderHash>,
}
/// 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<B, E> {
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<B, E> Client<B, E> {
/// 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<E>(executor: E) -> error::Result<Client<in_mem::Backend, E>> where E: state_machine::CodeExecutor {
Client::new(in_mem::Backend::new(), executor)
}
impl<B, E> Client<B, E> where
B: Blockchain,
B: backend::Backend,
E: state_machine::CodeExecutor,
error::Error: From<<<B as backend::Backend>::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<Self> {
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<state_machine::backend::InMemory> {
// 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<B::State> {
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<StorageData> {
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<B, E> Client<B, E> where
)?;
Ok(CallResult { return_data: vec![], changes })
}
/// Queue a block for import.
pub fn import_block(&self, header: block::Header, body: Option<block::Body>) -> error::Result<ImportResult> {
// 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<ClientInfo> {
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<BlockStatus> {
// 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<Option<block::HeaderHash>> {
self.backend.blockchain().hash(block_number)
}
/// Get block header by hash.
pub fn header(&self, hash: &block::HeaderHash) -> error::Result<Option<block::Header>> {
self.backend.blockchain().header(BlockId::Hash(*hash))
}
}
+29
View File
@@ -0,0 +1,29 @@
[package]
description = "Polkadot network protocol"
name = "polkadot-network"
version = "0.1.0"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[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"
+263
View File
@@ -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 <http://www.gnu.org/licenses/>.?
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<BlockData>),
}
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<BlockNumber, BlockRangeState>,
peer_requests: HashMap<PeerId, BlockNumber>,
}
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<message::BlockData>, 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<Range<BlockNumber>> {
// 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<BlockData> {
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<message::BlockData> {
(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::<Vec<_>>());
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::<Vec<_>>()[..]);
assert_eq!(drained[30..], blocks[41..81].iter().map(|b| BlockData { block: b.clone(), origin: 1 }).collect::<Vec<_>>()[..]);
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::<Vec<_>>()[..]);
assert_eq!(drained[40..], blocks[121..150].iter().map(|b| BlockData { block: b.clone(), origin: 1 }).collect::<Vec<_>>()[..]);
}
}
+59
View File
@@ -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 <http://www.gnu.org/licenses/>.
//! 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<block::Body>) -> Result<ImportResult, Error>;
/// Get blockchain info.
fn info(&self) -> Result<ClientInfo, Error>;
/// Get block status.
fn block_status(&self, hash: &block::HeaderHash) -> Result<BlockStatus, Error>;
/// Get block hash by number.
fn block_hash(&self, block_number: block::Number) -> Result<Option<block::HeaderHash>, Error>;
}
impl<B, E> Client for PolkadotClient<B, E> where
B: client::backend::Backend + Send + Sync + 'static,
E: state_machine::CodeExecutor + Send + Sync + 'static,
{
fn import(&self, header: block::Header, body: Option<block::Body>) -> Result<ImportResult, Error> {
(self as &Client).import(header, body)
}
fn info(&self) -> Result<ClientInfo, Error> {
(self as &Client).info()
}
fn block_status(&self, hash: &block::HeaderHash) -> Result<BlockStatus, Error> {
(self as &Client).block_status(hash)
}
fn block_hash(&self, block_number: block::Number) -> Result<Option<block::HeaderHash>, Error> {
(self as &Client).block_hash(block_number)
}
}
+30
View File
@@ -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 <http://www.gnu.org/licenses/>.?
use service::Role;
/// Protocol configuration
pub struct ProtocolConfig {
pub roles: Role,
}
impl Default for ProtocolConfig {
fn default() -> ProtocolConfig {
ProtocolConfig {
roles: Role::FULL,
}
}
}
@@ -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 <http://www.gnu.org/licenses/>.
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.?
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<block::HeaderHash, Self::Error> {
Ok(0.into())
error_chain! {
foreign_links {
Network(NetworkError) #[doc = "Devp2p error."];
}
fn header(&self, hash: &block::HeaderHash) -> Result<Option<block::Header>, 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 {
}
}
+78
View File
@@ -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 <http://www.gnu.org/licenses/>.?
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<u8>) -> 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<SessionInfo>;
/// 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<u8>) -> Result<(), NetworkError>{
self.network.send(peer_id, 0, data)
}
fn peer_session_info(&self, peer_id: PeerId) -> Option<SessionInfo> {
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)
}
}
+62
View File
@@ -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 <http://www.gnu.org/licenses/>.?
#![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))
}
+189
View File
@@ -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 <http://www.gnu.org/licenses/>.?
//! 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<u8>;
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<T> From<T> 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<RoleFlags> for Vec<Role> where {
fn from(flags: RoleFlags) -> Vec<Role> {
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<Header>,
/// Block body if requested.
pub body: Option<Body>,
/// Block receipt if requested.
pub receipt: Option<Bytes>,
/// Block message queue if requested.
pub message_queue: Option<Bytes>,
}
#[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<Role>,
/// 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<Signature>,
/// Validator address. Required for the validator role.
pub validator_id: Option<Address>,
/// Parachain id. Required for the collator role.
pub parachain_id: Option<ParachainId>,
}
#[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<BlockAttribute>,
/// Start from this block.
pub from: FromBlock,
/// End at this block. An implementation defined maximum is used when unspecified.
pub to: Option<HeaderHash>,
/// Sequence direction.
pub direction: Direction,
/// Maximum number of block to return. An implementation defined maximum is used when unspecified.
pub max: Option<u32>,
}
#[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<BlockData>,
}
#[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,
}
+347
View File
@@ -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 <http://www.gnu.org/licenses/>.?
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<Client>,
genesis_hash: HeaderHash,
sync: RwLock<ChainSync>,
/// All connected peers
peers: RwLock<HashMap<PeerId, Peer>>,
/// Connected peers pending Status message.
handshaking_peers: RwLock<HashMap<PeerId, time::Instant>>,
}
/// 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<message::BlockRequest>,
/// Request timestamp
request_timestamp: Option<time::Instant>,
/// Holds a set of transactions recently sent to this peer to avoid spamming.
_last_sent_transactions: HashSet<TransactionHash>,
/// 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<NodeId, usize>,
}
impl Protocol {
/// Create a new instance.
pub fn new(config: ProtocolConfig, chain: Arc<Client>) -> error::Result<Protocol> {
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<PeerInfo> {
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<TransactionHash, TransactionStats> {
BTreeMap::new()
}
pub fn chain(&self) -> &Client {
&*self.chain
}
}
+239
View File
@@ -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 <http://www.gnu.org/licenses/>.?
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<PeerInfo>;
/// Get this node id if available.
fn node_id(&self) -> Option<String>;
/// Returns propagation count for pending transactions.
fn transactions_stats(&self) -> BTreeMap<TransactionHash, TransactionStats>;
}
/// Peer connection information
#[derive(Debug)]
pub struct PeerInfo {
/// Public node id
pub id: Option<String>,
/// Node client ID
pub client_version: String,
/// Capabilities
pub capabilities: Vec<String>,
/// Remote endpoint address
pub remote_address: String,
/// Local endpoint address
pub local_address: String,
/// Dot protocol info.
pub dot_info: Option<ProtocolPeerInfo>,
}
/// 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<Client>,
}
/// Polkadot network service. Handles network IO and manages connectivity.
pub struct Service {
/// Network service
network: NetworkService,
/// Devp2p protocol handler
handler: Arc<ProtocolHandler>,
}
impl Service {
/// Creates and register protocol with the network service
pub fn new(params: Params) -> Result<Arc<Service>, 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<PeerInfo> {
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<String> {
self.network.external_url()
}
fn transactions_stats(&self) -> BTreeMap<TransactionHash, TransactionStats> {
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();
}
}
+372
View File
@@ -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 <http://www.gnu.org/licenses/>.?
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<PeerId, PeerSync>,
blocks: BlockCollection,
best_queued_number: BlockNumber,
best_queued_hash: HeaderHash,
required_block_attributes: Vec<message::BlockAttribute>,
}
/// 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<PeerId> = 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<PeerId> = 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));
}
}
View File
+10 -4
View File
@@ -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<u8>);
/// 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 {
+1 -1
View File
@@ -98,7 +98,7 @@ pub struct HeadData(#[serde(with="bytes")] pub Vec<u8>);
pub struct ValidationCode(#[serde(with="bytes")] pub Vec<u8>);
/// 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<u8>);
#[cfg(test)]
+6 -4
View File
@@ -18,6 +18,7 @@
use primitives::block;
use client;
use state_machine;
mod error;
@@ -35,11 +36,12 @@ build_rpc_trait! {
}
}
impl<B> ChainApi for B where
B: client::Blockchain + Send + Sync + 'static,
B::Error: ::std::error::Error + Send,
impl<B, E> ChainApi for client::Client<B, E> where
B: client::backend::Backend + Send + Sync + 'static,
E: state_machine::CodeExecutor + Send + Sync + 'static,
client::error::Error: From<<<B as client::backend::Backend>::State as state_machine::backend::Backend>::Error>,
{
fn header(&self, hash: block::HeaderHash) -> Result<Option<block::Header>> {
self.header(&hash).chain_err(|| "Blockchain error")
client::Client::header(self, &hash).chain_err(|| "Blockchain error")
}
}
+6 -7
View File
@@ -14,28 +14,27 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
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)
);
}
-3
View File
@@ -36,6 +36,3 @@ extern crate assert_matches;
pub mod chain;
pub mod state;
#[cfg(test)]
mod test_helpers;
+2 -1
View File
@@ -42,8 +42,9 @@ build_rpc_trait! {
}
impl<B, E> StateApi for Client<B, E> 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<<<B as client::backend::Backend>::State as state_machine::backend::Backend>::Error>,
{
fn storage(&self, key: StorageKey, block: block::HeaderHash) -> Result<StorageData> {
Ok(self.storage(&block, &key)?)
+7 -5
View File
@@ -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(_)), _))
)
}
+2 -2
View File
@@ -62,7 +62,7 @@ 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.
}
@@ -82,7 +82,7 @@ impl InMemory {
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(&[]))
}
+2 -2
View File
@@ -48,7 +48,7 @@ pub enum Update {
}
// in-memory section of the state.
#[derive(Default)]
#[derive(Default, Clone)]
struct MemoryState {
storage: HashMap<Vec<u8>, Vec<u8>>,
}
@@ -160,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;