Minimal switch of substrate-node to GRANDPA /Aura (#1128)

* add beginnings of SRML grandpa library

* get srml-grandpa compiling

* tests for srml-grandpa

* add optional session integration to grandpa SRML

* start integration into node runtime

* Allow extracting pending change from header digest

* Make it compile on wasm

* make tests compile again

* Move Authority Key fetching into service, simplify service factory construction

* Generalize Authority Consensus Setup system

* Add Authority Setup Docs

* Allow CLI params to be extensible

 - move params to structopts
 - split parsing and default command execution
 - add custom config to node
 - extended parsing of custom config
 - extending params via structop's flatten

* Minor fixes on cli extension params:
 - added docs
 - re-add actual app name, rather than node-name
 - make strategy and subcommand optional

* better cli params

* synchronize GRANDPA and normal node authorities

* Implement grandpa::network for gossip consensus

* run_grandpa in Node

* Fix missed merge error

* Integrate grandpa import queue

* more specific type def

* link up linkhalf and import block

* make grandpa future send

* get compiling

* Fix new params convention and license header

* get it running

* rebuild node runtime WASM

* change logging level

* Update node/cli/src/params.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/cli/src/params.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/cli/src/lib.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/runtime/src/lib.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/cli/src/lib.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Clean up and Fixme for mutable config

* Move GrandpaService Integration into grandpa, feature gated but on per default

* Fixing grandpa runtime module test

* Update wasm runtime hashes for tests

* GRANDPA: use post-header hash when logging scheduled changes

* add an extra bit of logging to authorities

* fixing missing constrain

* remove old code

* move `NewAuthorities` to an event in srml-grandpa

* fix node-executor tests to use grandpa log

* Remove GossipConsensus from tests, use newly provided sync-feature, fixes tests

* Update to latest wasm runtimes

* address grumbles

* address grumbles

* only derive deserialize when using std

* Clean up use of Deserialize
This commit is contained in:
Robert Habermeier
2018-11-21 18:42:50 +01:00
committed by GitHub
parent 84da9d4a02
commit 11fe84a742
59 changed files with 1694 additions and 696 deletions
+185 -116
View File
@@ -40,12 +40,11 @@ dependencies = [
[[package]]
name = "aio-limited"
version = "0.1.0"
source = "git+https://github.com/paritytech/aio-limited.git#a7c0bd6944902b1c9fb2bcf4f8fe1412c824b5b9"
source = "git+https://github.com/paritytech/aio-limited.git#f01b01501c87c93d3005f9120cc35d0e576fa7a3"
dependencies = [
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -85,7 +84,7 @@ name = "arrayvec"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -354,7 +353,7 @@ dependencies = [
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"simplelog 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -396,11 +395,11 @@ dependencies = [
[[package]]
name = "crossbeam-deque"
version = "0.6.1"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -411,21 +410,21 @@ dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
version = "0.5.2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -443,6 +442,14 @@ name = "crossbeam-utils"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crossbeam-utils"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crunchy"
version = "0.1.6"
@@ -516,7 +523,7 @@ dependencies = [
"chashmap 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -586,7 +593,7 @@ dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -642,9 +649,9 @@ name = "failure_derive"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -710,7 +717,7 @@ name = "fs-swap"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -784,7 +791,7 @@ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -825,6 +832,14 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "heck"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hex"
version = "0.3.2"
@@ -894,12 +909,12 @@ dependencies = [
"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.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hyper"
version = "0.12.13"
version = "0.12.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -989,21 +1004,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "jsonrpc-core"
version = "9.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git#a39139f92e7c92bddbd67372c556aad110f02e89"
source = "git+https://github.com/paritytech/jsonrpc.git#62d739e807c536575c1c885479706bffed3a8880"
dependencies = [
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jsonrpc-http-server"
version = "9.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git#a39139f92e7c92bddbd67372c556aad110f02e89"
source = "git+https://github.com/paritytech/jsonrpc.git#62d739e807c536575c1c885479706bffed3a8880"
dependencies = [
"hyper 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
"jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1014,7 +1029,7 @@ dependencies = [
[[package]]
name = "jsonrpc-macros"
version = "9.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git#a39139f92e7c92bddbd67372c556aad110f02e89"
source = "git+https://github.com/paritytech/jsonrpc.git#62d739e807c536575c1c885479706bffed3a8880"
dependencies = [
"jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
"jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
@@ -1024,7 +1039,7 @@ dependencies = [
[[package]]
name = "jsonrpc-pubsub"
version = "9.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git#a39139f92e7c92bddbd67372c556aad110f02e89"
source = "git+https://github.com/paritytech/jsonrpc.git#62d739e807c536575c1c885479706bffed3a8880"
dependencies = [
"jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1034,12 +1049,12 @@ dependencies = [
[[package]]
name = "jsonrpc-server-utils"
version = "9.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git#a39139f92e7c92bddbd67372c556aad110f02e89"
source = "git+https://github.com/paritytech/jsonrpc.git#62d739e807c536575c1c885479706bffed3a8880"
dependencies = [
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1050,7 +1065,7 @@ dependencies = [
[[package]]
name = "jsonrpc-ws-server"
version = "9.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git#a39139f92e7c92bddbd67372c556aad110f02e89"
source = "git+https://github.com/paritytech/jsonrpc.git#62d739e807c536575c1c885479706bffed3a8880"
dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
@@ -1126,11 +1141,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazycell"
@@ -1196,7 +1208,7 @@ dependencies = [
"multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"multistream-select 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1233,7 +1245,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1253,7 +1265,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1280,7 +1292,7 @@ dependencies = [
"multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1364,7 +1376,7 @@ dependencies = [
"libp2p-peerstore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"protobuf 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1386,7 +1398,7 @@ dependencies = [
"hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)",
@@ -1518,7 +1530,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1666,7 +1678,7 @@ name = "native-tls"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1704,7 +1716,9 @@ dependencies = [
name = "node-cli"
version = "0.1.0"
dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"node-executor 0.1.0",
@@ -1715,9 +1729,11 @@ dependencies = [
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0",
"sr-primitives 0.1.0",
"structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-cli 0.3.0",
"substrate-client 0.1.0",
"substrate-consensus-aura 0.1.0",
"substrate-finality-grandpa 0.1.0",
"substrate-keystore 0.1.0",
"substrate-network 0.1.0",
"substrate-primitives 0.1.0",
@@ -1740,6 +1756,7 @@ dependencies = [
"srml-balances 0.1.0",
"srml-consensus 0.1.0",
"srml-contract 0.1.0",
"srml-grandpa 0.1.0",
"srml-session 0.1.0",
"srml-staking 0.1.0",
"srml-support 0.1.0",
@@ -1791,6 +1808,7 @@ dependencies = [
"srml-council 0.1.0",
"srml-democracy 0.1.0",
"srml-executive 0.1.0",
"srml-grandpa 0.1.0",
"srml-session 0.1.0",
"srml-staking 0.1.0",
"srml-support 0.1.0",
@@ -1806,7 +1824,7 @@ dependencies = [
[[package]]
name = "nodrop"
version = "0.1.12"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1873,7 +1891,7 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1926,8 +1944,8 @@ name = "parity-codec-derive"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2091,7 +2109,7 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "0.4.20"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2099,7 +2117,7 @@ dependencies = [
[[package]]
name = "protobuf"
version = "2.1.2"
version = "2.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2140,10 +2158,10 @@ dependencies = [
[[package]]
name = "quote"
version = "0.6.9"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2201,7 +2219,7 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2215,7 +2233,7 @@ version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2247,12 +2265,12 @@ dependencies = [
[[package]]
name = "regex"
version = "1.0.5"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2267,7 +2285,7 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2357,7 +2375,7 @@ dependencies = [
[[package]]
name = "ryu"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2383,7 +2401,7 @@ name = "schannel"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2440,18 +2458,18 @@ name = "serde_derive"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.32"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2541,7 +2559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2588,7 +2606,7 @@ dependencies = [
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0",
"sr-std 0.1.0",
"substrate-primitives 0.1.0",
@@ -2768,6 +2786,25 @@ dependencies = [
"substrate-primitives 0.1.0",
]
[[package]]
name = "srml-grandpa"
version = "0.1.0"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0",
"sr-primitives 0.1.0",
"sr-std 0.1.0",
"srml-session 0.1.0",
"srml-support 0.1.0",
"srml-system 0.1.0",
"substrate-finality-grandpa-primitives 0.1.0",
"substrate-primitives 0.1.0",
]
[[package]]
name = "srml-metadata"
version = "0.1.0"
@@ -2937,11 +2974,11 @@ name = "stdweb-derive"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.16 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2950,13 +2987,13 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base-x 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2982,6 +3019,26 @@ name = "strsim"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "structopt"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "structopt-derive"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "subkey"
version = "0.1.0"
@@ -3016,12 +3073,13 @@ dependencies = [
"exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 0.1.0",
"structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-client 0.1.0",
"substrate-network 0.1.0",
"substrate-primitives 0.1.0",
@@ -3159,7 +3217,7 @@ dependencies = [
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3193,6 +3251,7 @@ dependencies = [
"substrate-keyring 0.1.0",
"substrate-network 0.1.0",
"substrate-primitives 0.1.0",
"substrate-service 0.3.0",
"substrate-test-client 0.1.0",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3214,7 +3273,7 @@ name = "substrate-keyring"
version = "0.1.0"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-primitives 0.1.0",
]
@@ -3228,7 +3287,7 @@ dependencies = [
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-primitives 0.1.0",
"subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3276,7 +3335,7 @@ dependencies = [
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3325,7 +3384,7 @@ dependencies = [
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 0.1.0",
"sr-version 0.1.0",
"substrate-client 0.1.0",
@@ -3355,7 +3414,7 @@ name = "substrate-serializer"
version = "0.1.0"
dependencies = [
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3365,13 +3424,13 @@ dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0",
"sr-primitives 0.1.0",
@@ -3440,7 +3499,7 @@ dependencies = [
name = "substrate-telemetry"
version = "0.3.0"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3559,18 +3618,18 @@ name = "syn"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.16"
version = "0.15.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3579,9 +3638,9 @@ name = "synstructure"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3592,7 +3651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3683,7 +3742,7 @@ name = "thread_local"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3780,7 +3839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3819,7 +3878,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3847,7 +3906,7 @@ name = "tokio-threadpool"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4033,6 +4092,11 @@ name = "unicode-normalization"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-segmentation"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-width"
version = "0.1.5"
@@ -4075,7 +4139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.7.1"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4126,7 +4190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -4177,7 +4241,7 @@ dependencies = [
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4239,7 +4303,7 @@ dependencies = [
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4257,7 +4321,7 @@ dependencies = [
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4282,7 +4346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "yamux"
version = "0.1.0"
source = "git+https://github.com/paritytech/yamux#966f2730f7a32150f282eef29fd2aecb14d7b9fa"
source = "git+https://github.com/paritytech/yamux#8f3d16e7645447645d3552a52159d56c8a01de27"
dependencies = [
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4343,11 +4407,12 @@ dependencies = [
"checksum criterion-stats 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c71521cb4c7b7eac76b540e75447fb0172c4234d6333729001b886aaa21d6da4"
"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1"
"checksum crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe1b6f945f824c7a25afe44f62e25d714c0cc523f8e99d8db5cd1026e1269d3"
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9"
"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
"checksum crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c55913cc2799171a550e307918c0a360e8c16004820291bf3b638969b4a01816"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
"checksum crypto-mac 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0999b4ff4d3446d4ddb19a63e9e00c1876e75cd7000d20e57a693b4b3f08d958"
@@ -4394,6 +4459,7 @@ dependencies = [
"checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "<none>"
"checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "<none>"
"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
"checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95"
"checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a"
@@ -4402,7 +4468,7 @@ dependencies = [
"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c"
"checksum hyper 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "95ffee0d1d30de4313fdaaa485891ce924991d45bbc18adfc8ac5b1639e62fbb"
"checksum hyper 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2f60ae467ef4fc5eba9a34d31648c9c8ed902faf45a217f6734ce9ea64779ac7"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903"
@@ -4425,7 +4491,7 @@ dependencies = [
"checksum kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06cf755dc587839ba34d3cbe3f12b6ad55850fbcdfe67336157a021a1a5c43ae"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
@@ -4470,7 +4536,7 @@ dependencies = [
"checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum nohash-hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27593c72432b8cec9ae79e92792a73c38341064d525b6b612a9fccf8b7d17407"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
@@ -4505,28 +4571,28 @@ dependencies = [
"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8"
"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a"
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
"checksum protobuf 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e95ac45a1e122e1b62c3f23bbe51574c39d06d1c8c5a2a5676de497d0a84a34"
"checksum proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "88dae56b29da695d783ea7fc5a90de281f79eb38407e77f6d674dd8befc4ac47"
"checksum protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "671a9cce836bd3635b40b2b0a72783481755ee988c493891f4e974b45264cc9d"
"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07"
"checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5"
"checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
"checksum quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5829244f52738cfee93b3a165c1911388675be000c888d2fae620dee8fa5b"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa"
"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473"
"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341"
"checksum regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee84f70c8c08744ea9641a731c7fadb475bf2ecc52d7f627feb833e0b3990467"
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
"checksum regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fbc557aac2b708fe84121caf261346cc2eed71978024337e42eb46b8a252ac6e"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rhododendron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a09bc21b21795c366c8bf0e87afb71175f5f736b3a5b279b6f4e81839d0a877b"
"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c"
@@ -4537,7 +4603,7 @@ dependencies = [
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "<none>"
"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
"checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
@@ -4550,7 +4616,7 @@ dependencies = [
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811"
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
"checksum sha1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "171698ce4ec7cbb93babeb3190021b4d72e96ccb98e33d277ae4ea959d6f2d9e"
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
@@ -4575,11 +4641,13 @@ dependencies = [
"checksum stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30dc6118470d69ce0fdcf7e6f95e95853f7f4f72f80d835d4519577c323814ab"
"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "41c4a2479a078509940d82773d90ff824a8c89533ab3b59cd3ce8b0c0e369c02"
"checksum structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5352090cfae7a2c85e1a31146268b53396106c88ca5d6ccee2e3fae83b6e35c2"
"checksum subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7f6353c2ee5407358d063a14cccc1630804527090a6fb5a9489ce4924280fb"
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum syn 0.15.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0b78d53b5e1b6e63129140b1336877c3bddbae398c7956150396bdad0e28676c"
"checksum syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)" = "8886c8d2774e853fcd7d9d2131f6e40ba46c9c0e358e4d57178452abd6859bb0"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum sysinfo 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "11c5f6e8a7a7146f26ffed9a5ff8bab2706f1ac8a413a415e1d211b819d5c24d"
"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
@@ -4627,13 +4695,14 @@ dependencies = [
"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum unsigned-varint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5c1441164e5da61f00acd15f5a9e61939693c2c6e8b9fae36a220b82de7e212"
"checksum unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8abc4b7d8158bdfbbaaccc35331ed3c30c2673e99000d7ae665a2eb6576f4"
"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
+1
View File
@@ -48,6 +48,7 @@ members = [
"srml/democracy",
"srml/example",
"srml/executive",
"srml/grandpa",
"srml/metadata",
"core/sr-primitives",
"srml/session",
+2 -5
View File
@@ -3,10 +3,9 @@ name = "substrate-cli"
version = "0.3.0"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Substrate CLI interface."
build = "build.rs"
[dependencies]
clap = { version = "~2.32", features = ["yaml"] }
clap = "~2.32"
backtrace = "0.3"
env_logger = "0.5"
error-chain = "0.12"
@@ -30,6 +29,4 @@ substrate-primitives = { path = "../../core/primitives" }
substrate-service = { path = "../../core/service" }
substrate-telemetry = { path = "../../core/telemetry" }
names = "0.11.0"
[build-dependencies]
clap = "~2.32"
structopt = "0.2.13"
-253
View File
@@ -1,253 +0,0 @@
name: {name}
author: {author}
about: {description}
args:
- log:
short: l
long: log
value_name: LOG_PATTERN
help: Sets a custom logging filter
takes_value: true
- base-path:
long: base-path
short: d
value_name: PATH
help: Specify custom base path
takes_value: true
- keystore-path:
long: keystore-path
value_name: PATH
help: Specify custom keystore path
takes_value: true
- key:
long: key
value_name: STRING
help: Specify additional key seed
takes_value: true
- node-key:
long: node-key
value_name: KEY
help: Specify node secret key (64-character hex string)
takes_value: true
- validator:
long: validator
help: Enable validator mode
takes_value: false
- light:
long: light
help: Run in light client mode
takes_value: false
- dev:
long: dev
help: Run in development mode; implies --chain=dev --validator --key Alice
takes_value: false
- listen-addr:
long: listen-addr
value_name: LISTEN_ADDR
help: Listen on this multiaddress
takes_value: true
multiple: true
- port:
long: port
value_name: PORT
help: Specify p2p protocol TCP port. Only used if --listen-addr is not specified.
takes_value: true
- rpc-external:
long: rpc-external
help: Listen to all RPC interfaces (default is local)
takes_value: false
- ws-external:
long: ws-external
help: Listen to all Websocket interfaces (default is local)
takes_value: false
- rpc-port:
long: rpc-port
value_name: PORT
help: Specify HTTP RPC server TCP port
takes_value: true
- ws-port:
long: ws-port
value_name: PORT
help: Specify WebSockets RPC server TCP port
takes_value: true
- bootnodes:
long: bootnodes
value_name: URL
help: Specify a list of bootnodes
takes_value: true
multiple: true
- reserved-nodes:
long: reserved-nodes
value_name: URL
help: Specify a list of reserved node addresses
takes_value: true
multiple: true
- out-peers:
long: out-peers
value_name: OUT_PEERS
help: Specify the number of outgoing connections we're trying to maintain
takes_value: true
- in-peers:
long: in-peers
value_name: IN_PEERS
help: Specify the maximum number of incoming connections we're accepting
takes_value: true
- chain:
long: chain
value_name: CHAIN_SPEC
help: Specify the chain specification (one of dev, local or staging)
takes_value: true
- pruning:
long: pruning
value_name: PRUNING_MODE
help: Specify the pruning mode, a number of blocks to keep or "archive". Default is 256.
takes_value: true
- name:
long: name
value_name: NAME
help: The human-readable name for this node, as reported to the telemetry server, if enabled
takes_value: true
- telemetry:
short: t
long: telemetry
help: Should connect to the Substrate telemetry server (telemetry is off by default on local chains)
takes_value: false
- no-telemetry:
long: no-telemetry
help: Should not connect to the Substrate telemetry server (telemetry is on by default on global chains)
takes_value: false
- telemetry-url:
long: telemetry-url
value_name: TELEMETRY_URL
help: The URL of the telemetry server. Implies --telemetry
takes_value: true
- execution:
long: execution
value_name: STRATEGY
help: The means of execution used when calling into the runtime. Can be either wasm, native or both.
subcommands:
- build-spec:
about: Build a spec.json file, outputing to stdout
args:
- raw:
long: raw
help: Force raw genesis storage output.
takes_value: false
- chain:
long: chain
value_name: CHAIN_SPEC
help: Specify the chain specification (one of dev, local or staging)
takes_value: true
- dev:
long: dev
help: Specify the development chain
takes_value: false
- export-blocks:
about: Export blocks to a file
args:
- OUTPUT:
index: 1
help: Output file name or stdout if unspecified.
required: false
- chain:
long: chain
value_name: CHAIN_SPEC
help: Specify the chain specification.
takes_value: true
- dev:
long: dev
help: Specify the development chain
takes_value: false
- base-path:
long: base-path
short: d
value_name: PATH
help: Specify custom base path.
takes_value: true
- from:
long: from
value_name: BLOCK
help: Specify starting block number. 1 by default.
takes_value: true
- to:
long: to
value_name: BLOCK
help: Specify last block number. Best block by default.
takes_value: true
- json:
long: json
help: Use JSON output rather than binary.
takes_value: false
- import-blocks:
about: Import blocks from file.
args:
- INPUT:
index: 1
help: Input file or stdin if unspecified.
required: false
- chain:
long: chain
value_name: CHAIN_SPEC
help: Specify the chain specification.
takes_value: true
- dev:
long: dev
help: Specify the development chain
takes_value: false
- base-path:
long: base-path
short: d
value_name: PATH
help: Specify custom base path.
takes_value: true
- execution:
long: execution
value_name: STRATEGY
help: The means of execution used when executing blocks. Can be either wasm, native or both.
- api-execution:
long: api-execution
value_name: STRATEGY
help: The means of execution used when calling into the runtime. Can be either wasm, native or both.
- max-heap-pages:
long: max-heap-pages
value_name: COUNT
help: The maximum number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing.
- revert:
about: Revert chain to the previous state
args:
- NUM:
index: 1
help: Number of blocks to revert. Default is 256.
- chain:
long: chain
value_name: CHAIN_SPEC
help: Specify the chain specification.
takes_value: true
- dev:
long: dev
help: Specify the development chain
takes_value: false
- base-path:
long: base-path
short: d
value_name: PATH
help: Specify custom base path.
takes_value: true
- purge-chain:
about: Remove the whole chain data.
args:
- chain:
long: chain
value_name: CHAIN_SPEC
help: Specify the chain specification.
takes_value: true
- dev:
long: dev
help: Specify the development chain
takes_value: false
- base-path:
long: base-path
short: d
value_name: PATH
help: Specify custom base path.
takes_value: true
+93 -77
View File
@@ -50,7 +50,10 @@ extern crate clap;
extern crate error_chain;
#[macro_use]
extern crate log;
#[macro_use]
extern crate structopt;
mod params;
pub mod error;
pub mod informant;
mod panic_hook;
@@ -72,6 +75,8 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;
use names::{Generator, Name};
use regex::Regex;
use structopt::StructOpt;
pub use params::{CoreParams, CoreCommands, ExecutionStrategy};
use futures::Future;
@@ -90,11 +95,11 @@ pub struct VersionInfo {
}
/// CLI Action
pub enum Action<F: ServiceFactory, E: IntoExit> {
pub enum Action<E> {
/// Substrate handled the command. No need to do anything.
ExecutedInternally,
/// Service mode requested. Caller should start the service.
RunService((FactoryFullConfiguration<F>, E)),
RunService(E),
}
/// Something that can be converted into an exit signal.
@@ -117,7 +122,7 @@ fn load_spec<F, G>(matches: &clap::ArgMatches, factory: F) -> Result<ChainSpec<G
}
fn base_path(matches: &clap::ArgMatches) -> PathBuf {
matches.value_of("base-path")
matches.value_of("base_path")
.map(|x| Path::new(x).to_owned())
.unwrap_or_else(default_base_path)
}
@@ -145,84 +150,42 @@ fn is_node_name_valid(_name: &str) -> Result<(), &str> {
Ok(())
}
/// Parse command line arguments and execute commands or return service configuration.
///
/// IANA unassigned port ranges that we could use:
/// 6717-6766 Unassigned
/// 8504-8553 Unassigned
/// 9556-9591 Unassigned
/// 9803-9874 Unassigned
/// 9926-9949 Unassigned
pub fn prepare_execution<F, I, T, E, S>(
args: I,
exit: E,
version: VersionInfo,
spec_factory: S,
impl_name: &'static str,
) -> error::Result<Action<F, E>>
/// Parse command line arguments
pub fn parse_args_default<'a, I, T>(args: I, version: VersionInfo) -> clap::ArgMatches<'a>
where
I: IntoIterator<Item = T>,
T: Into<std::ffi::OsString> + Clone,
E: IntoExit,
F: ServiceFactory,
S: FnOnce(&str) -> Result<Option<ChainSpec<FactoryGenesis<F>>>, String>,
{
panic_hook::set();
let full_version = service::config::full_version_from_strs(
version.version,
version.commit
);
let yaml = format!(include_str!("./cli.yml"),
name = version.executable_name,
description = version.description,
author = version.author,
);
let yaml = &clap::YamlLoader::load_from_str(&yaml).expect("Invalid yml file")[0];
let matches = match clap::App::from_yaml(yaml)
match CoreParams::clap()
.name(version.executable_name)
.author(version.author)
.about(version.description)
.version(&(full_version + "\n")[..])
.get_matches_from_safe(args) {
Ok(m) => m,
Err(e) => e.exit(),
};
// TODO [ToDr] Split parameters parsing from actual execution.
let log_pattern = matches.value_of("log").unwrap_or("");
init_logger(log_pattern);
fdlimit::raise_fd_limit();
if let Some(matches) = matches.subcommand_matches("build-spec") {
let spec = load_spec(&matches, spec_factory)?;
build_spec::<F>(matches, spec)?;
return Ok(Action::ExecutedInternally);
}
}
if let Some(matches) = matches.subcommand_matches("export-blocks") {
let spec = load_spec(&matches, spec_factory)?;
export_blocks::<F, _>(matches, spec, exit.into_exit())?;
return Ok(Action::ExecutedInternally);
}
if let Some(matches) = matches.subcommand_matches("import-blocks") {
let spec = load_spec(&matches, spec_factory)?;
import_blocks::<F, _>(matches, spec, exit.into_exit())?;
return Ok(Action::ExecutedInternally);
}
if let Some(matches) = matches.subcommand_matches("revert") {
let spec = load_spec(&matches, spec_factory)?;
revert_chain::<F>(matches, spec)?;
return Ok(Action::ExecutedInternally);
}
if let Some(matches) = matches.subcommand_matches("purge-chain") {
let spec = load_spec(&matches, spec_factory)?;
purge_chain::<F>(matches, spec)?;
return Ok(Action::ExecutedInternally);
}
/// Parse clap::Matches into config and chain specification
pub fn parse_matches<'a, F, S>(
spec_factory: S,
version: VersionInfo,
impl_name: &'static str,
matches: &clap::ArgMatches<'a>
) -> error::Result<(ChainSpec<<F as service::ServiceFactory>::Genesis>, FactoryFullConfiguration<F>)>
where
F: ServiceFactory,
S: FnOnce(&str) -> Result<Option<ChainSpec<FactoryGenesis<F>>>, String>,
{
let spec = load_spec(&matches, spec_factory)?;
let mut config = service::Configuration::default_with_spec(spec);
let mut config = service::Configuration::default_with_spec(spec.clone());
config.impl_name = impl_name;
config.impl_commit = version.commit;
@@ -284,14 +247,14 @@ where
config.network.config_path = Some(network_path(&base_path, config.chain_spec.id()).to_string_lossy().into());
config.network.net_config_path = config.network.config_path.clone();
config.network.reserved_nodes.extend(matches
.values_of("reserved-nodes")
.values_of("reserved_nodes")
.map_or(Default::default(), |v| v.map(|n| n.to_owned()).collect::<Vec<_>>()));
if !config.network.reserved_nodes.is_empty() {
config.network.non_reserved_mode = NonReservedPeerMode::Deny;
}
config.network.listen_addresses = Vec::new();
for addr in matches.values_of("listen-addr").unwrap_or_default() {
for addr in matches.values_of("listen_addr").unwrap_or_default() {
let addr = addr.parse().map_err(|_| "Invalid listen multiaddress")?;
config.network.listen_addresses.push(addr);
}
@@ -310,17 +273,17 @@ where
config.network.public_addresses = Vec::new();
config.network.client_version = config.client_id();
config.network.use_secret = match matches.value_of("node-key").map(H256::from_str) {
config.network.use_secret = match matches.value_of("node_key").map(H256::from_str) {
Some(Ok(secret)) => Some(secret.into()),
Some(Err(err)) => return Err(format!("Error parsing node key: {}", err).into()),
None => None,
};
let in_peers = match matches.value_of("in-peers") {
let in_peers = match matches.value_of("in_peers") {
Some(in_peers) => in_peers.parse().map_err(|_| "Invalid in-peers value specified.")?,
None => 25,
};
let out_peers = match matches.value_of("out-peers") {
let out_peers = match matches.value_of("out_peers") {
Some(out_peers) => out_peers.parse().map_err(|_| "Invalid out-peers value specified.")?,
None => 25,
};
@@ -334,20 +297,73 @@ where
config.keys.push("Alice".into());
}
let rpc_interface: &str = if matches.is_present("rpc-external") { "0.0.0.0" } else { "127.0.0.1" };
let ws_interface: &str = if matches.is_present("ws-external") { "0.0.0.0" } else { "127.0.0.1" };
let rpc_interface: &str = if matches.is_present("rpc_external") { "0.0.0.0" } else { "127.0.0.1" };
let ws_interface: &str = if matches.is_present("ws_external") { "0.0.0.0" } else { "127.0.0.1" };
config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), "rpc-port", &matches)?);
config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), "ws-port", &matches)?);
config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), "rpc_port", &matches)?);
config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), "ws_port", &matches)?);
// Override telemetry
if matches.is_present("no-telemetry") {
if matches.is_present("no_telemetry") {
config.telemetry_url = None;
} else if let Some(url) = matches.value_of("telemetry-url") {
} else if let Some(url) = matches.value_of("telemetry_url") {
config.telemetry_url = Some(url.to_owned());
}
Ok(Action::RunService((config, exit)))
Ok((spec, config))
}
//
// IANA unassigned port ranges that we could use:
// 6717-6766 Unassigned
// 8504-8553 Unassigned
// 9556-9591 Unassigned
// 9803-9874 Unassigned
// 9926-9949 Unassigned
/// execute default commands or return service configuration
pub fn execute_default<'a, F, E>(
spec: ChainSpec<FactoryGenesis<F>>,
exit: E,
matches: &clap::ArgMatches<'a>
) -> error::Result<Action<E>>
where
E: IntoExit,
F: ServiceFactory,
{
panic_hook::set();
let log_pattern = matches.value_of("log").unwrap_or("");
init_logger(log_pattern);
fdlimit::raise_fd_limit();
if let Some(matches) = matches.subcommand_matches("build_spec") {
build_spec::<F>(matches, spec)?;
return Ok(Action::ExecutedInternally);
}
if let Some(matches) = matches.subcommand_matches("export_blocks") {
export_blocks::<F, _>(matches, spec, exit.into_exit())?;
return Ok(Action::ExecutedInternally);
}
if let Some(matches) = matches.subcommand_matches("import_blocks") {
import_blocks::<F, _>(matches, spec, exit.into_exit())?;
return Ok(Action::ExecutedInternally);
}
if let Some(matches) = matches.subcommand_matches("revert") {
revert_chain::<F>(matches, spec)?;
return Ok(Action::ExecutedInternally);
}
if let Some(matches) = matches.subcommand_matches("purge_chain") {
purge_chain::<F>(matches, spec)?;
return Ok(Action::ExecutedInternally);
}
Ok(Action::RunService(exit))
}
fn build_spec<F>(matches: &clap::ArgMatches, spec: ChainSpec<FactoryGenesis<F>>) -> error::Result<()>
+216
View File
@@ -0,0 +1,216 @@
// Copyright 2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "Substrate")]
pub struct CoreParams {
#[structopt(short = "l", long = "log", value_name = "LOG_PATTERN", help = "Sets a custom logging filter")]
log: Option<String>,
#[structopt(long = "base-path", short = "d", value_name = "PATH", help = "Specify custom base path", parse(from_os_str))]
base_path: Option<PathBuf>,
#[structopt(long = "keystore-path", value_name = "PATH", help = "Specify custom keystore path", parse(from_os_str))]
keystore_path: Option<PathBuf>,
#[structopt(long = "key", value_name = "STRING", help = "Specify additional key seed")]
key: Option<String>,
#[structopt(long = "node-key", value_name = "KEY", help = "Specify node secret key (64-character hex string)")]
node_key: Option<String>,
#[structopt(long = "validator",help = "Enable validator mode")]
validator: bool,
#[structopt(long = "light", help = "Run in light client mode")]
light: bool,
#[structopt(long = "dev", help = "Run in development mode; implies --chain=dev --validator --key Alice")]
dev: bool,
#[structopt(long = "listen-addr", value_name = "LISTEN_ADDR", help = "Listen on this multiaddress")]
listen_addr: Vec<String>,
#[structopt(long = "port", value_name = "PORT", help = "Specify p2p protocol TCP port. Only used if --listen-addr is not specified.")]
port: Option<u32>,
#[structopt(long = "rpc-external", help = "Listen to all RPC interfaces (default is local)")]
rpc_external: bool,
#[structopt(long = "ws-external", help = "Listen to all Websocket interfaces (default is local)")]
ws_external: bool,
#[structopt(long = "rpc-port", value_name = "PORT", help = "Specify HTTP RPC server TCP port")]
rpc_port: Option<u32>,
#[structopt(long = "ws-port", value_name = "PORT", help = "Specify WebSockets RPC server TCP port")]
ws_port: Option<u32>,
#[structopt(long = "bootnodes", value_name = "URL", help = "Specify a list of bootnodes")]
bootnodes: Vec<String>,
#[structopt(long = "reserved-nodes", value_name = "URL", help = "Specify a list of reserved node addresses")]
reserved_nodes: Vec<String>,
#[structopt(long = "out-peers", value_name = "OUT_PEERS", help = "Specify the number of outgoing connections we're trying to maintain")]
out_peers: Option<u8>,
#[structopt(long = "in-peers", value_name = "IN_PEERS", help = "Specify the maximum number of incoming connections we're accepting")]
in_peers: Option<u8>,
#[structopt(long = "chain", value_name = "CHAIN_SPEC", help = "Specify the chain specification (one of dev, local or staging)")]
chain: Option<String>,
#[structopt(long = "pruning", value_name = "PRUNING_MODE", help = "Specify the pruning mode, a number of blocks to keep or 'archive'. Default is 256.")]
pruning: Option<u32>,
#[structopt(long = "name", value_name = "NAME", help = "The human-readable name for this node, as reported to the telemetry server, if enabled")]
name: Option<String>,
#[structopt(short = "t", long = "telemetry", help = "Should connect to the Substrate telemetry server (telemetry is off by default on local chains)")]
telemetry: bool,
#[structopt(long = "no-telemetry", help = "Should not connect to the Substrate telemetry server (telemetry is on by default on global chains)")]
no_telemetry: bool,
#[structopt(long = "telemetry-url", value_name = "TELEMETRY_URL", help = "The URL of the telemetry server. Implies --telemetry")]
telemetry_url: Option<String>,
#[structopt(long = "execution", value_name = "STRATEGY", help = "The means of execution used when calling into the runtime. Can be either wasm, native or both.")]
execution: Option<ExecutionStrategy>,
#[structopt(subcommand)]
cmds: Option<CoreCommands>,
}
#[derive(Debug, StructOpt)]
pub enum ExecutionStrategy {
Native,
Wasm,
Both,
}
impl Default for ExecutionStrategy {
fn default() -> Self {
ExecutionStrategy::Both
}
}
impl std::str::FromStr for ExecutionStrategy {
type Err = String;
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"native" => Ok(ExecutionStrategy::Native),
"wasm" | "webassembly" => Ok(ExecutionStrategy::Wasm),
"both" => Ok(ExecutionStrategy::Both),
_ => Err("Please specify either 'native', 'wasm' or 'both".to_owned())
}
}
}
#[derive(Debug, StructOpt)]
pub enum CoreCommands {
#[structopt(name = "build-spec", about = "Build a spec.json file, outputing to stdout")]
BuildSpec {
#[structopt(long = "raw", help = "Force raw genesis storage output.")]
raw: bool,
#[structopt(long = "chain", value_name = "CHAIN_SPEC", help = "Specify the chain specification (one of dev, local or staging)")]
chain: Option<String>,
#[structopt(long = "dev", help = "Specify the development chain")]
dev: bool,
},
#[structopt(name = "export-blocks", about = "Export blocks to a file")]
ExportBlocks {
#[structopt(help = "Output file name or stdout if unspecified.", parse(from_os_str))]
OUTPUT: Option<PathBuf>,
#[structopt(long = "chain", value_name = "CHAIN_SPEC", help = "Specify the chain specification.")]
chain: Option<String>,
#[structopt(long = "dev", help = "Specify the development chain")]
dev: bool,
#[structopt(long = "base-path", short = "d", value_name = "PATH", help = "Specify custom base path.")]
base_path: Option<String>,
#[structopt(long = "from", value_name = "BLOCK", help = "Specify starting block number. 1 by default.")]
from: Option<u128>,
#[structopt(long = "to", value_name = "BLOCK", help = "Specify last block number. Best block by default.")]
to: Option<u128>,
#[structopt(long = "json", help = "Use JSON output rather than binary.")]
json: bool,
},
#[structopt(name = "import-blocks", about = "Import blocks from file.")]
ImportBlocks {
#[structopt(help = "Input file or stdin if unspecified.", parse(from_os_str))]
INPUT: Option<PathBuf>,
#[structopt(long = "chain", value_name = "CHAIN_SPEC", help = "Specify the chain specification.")]
chain: Option<String>,
#[structopt(long = "dev", help = "Specify the development chain")]
dev: bool,
#[structopt(long = "base-path", short = "d", value_name = "PATH", help = "Specify custom base path.", parse(from_os_str))]
base_path: Option<PathBuf>,
#[structopt(long = "execution", value_name = "STRATEGY", help = "The means of execution used when executing blocks. Can be either wasm, native or both.")]
execution: ExecutionStrategy,
#[structopt(long = "api-execution", value_name = "STRATEGY", help = "The means of execution used when calling into the runtime. Can be either wasm, native or both.")]
api_execution: ExecutionStrategy,
#[structopt(long = "max-heap-pages", value_name = "COUNT", help = "The maximum number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing.")]
max_heap_pages: Option<u32>,
},
#[structopt(name = "revert", about = "Revert chain to the previous state")]
Revert {
#[structopt(help = "Number of blocks to revert. Default is 256.")]
NUM: Option<u32>,
#[structopt(long = "chain", value_name = "CHAIN_SPEC", help = "Specify the chain specification.")]
chain: Option<String>,
#[structopt(long = "dev", help = "Specify the development chain")]
dev: bool,
#[structopt(long = "base-path", short = "d", value_name = "PATH", help = "Specify custom base path.", parse(from_os_str))]
base_path: Option<PathBuf>,
},
#[structopt(name = "purge-chain", about = "Remove the whole chain data.")]
PurgeChain {
#[structopt(long = "chain", value_name = "CHAIN_SPEC", help = "Specify the chain specification.")]
chain: Option<String>,
#[structopt(long = "dev", help = "Specify the development chain")]
dev: bool,
#[structopt(long = "base-path", short = "d", value_name = "PATH", help = "Specify custom base path.", parse(from_os_str))]
base_path: Option<PathBuf>
}
}
@@ -1,7 +1,25 @@
// Copyright 2017-2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Block import helpers.
use primitives::AuthorityId;
use runtime_primitives::traits::{Block as BlockT, DigestItemFor};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, DigestItemFor};
use runtime_primitives::Justification;
use std::borrow::Cow;
/// Block import result.
#[derive(Debug)]
@@ -89,6 +107,24 @@ impl<Block: BlockT> ImportBlock<Block> {
self.auxiliary,
)
}
/// Get a handle to full header (with post-digests applied).
pub fn post_header(&self) -> Cow<Block::Header> {
use runtime_primitives::traits::Digest;
if self.post_digests.is_empty() {
Cow::Borrowed(&self.header)
} else {
Cow::Owned({
let mut hdr = self.header.clone();
for digest_item in &self.post_digests {
hdr.digest_mut().push(digest_item.clone());
}
hdr
})
}
}
}
@@ -101,4 +137,4 @@ pub trait BlockImport<B: BlockT> {
block: ImportBlock<B>,
new_authorities: Option<Vec<AuthorityId>>
) -> Result<ImportResult, Self::Error>;
}
}
+7 -1
View File
@@ -4,13 +4,15 @@ version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
futures = "0.1.17"
futures = "0.1"
parity-codec = "2.1"
parity-codec-derive = "2.0"
sr-primitives = { path = "../sr-primitives" }
substrate-consensus-common = { path = "../consensus/common" }
substrate-primitives = { path = "../primitives" }
substrate-client = { path = "../client" }
substrate-network = { path = "../network" }
substrate-service = { path = "../service", optional = true }
log = "0.4"
parking_lot = "0.4"
tokio = "0.1.7"
@@ -25,3 +27,7 @@ substrate-network = { path = "../network", features = ["test-helpers"] }
substrate-keyring = { path = "../keyring" }
substrate-test-client = { path = "../test-client"}
env_logger = "0.5"
[features]
default = ["service-integration"]
service-integration = ["substrate-service"]
@@ -17,6 +17,10 @@
//! Primitives for GRANDPA integration, suitable for WASM compilation.
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
#[cfg(not(feature = "std"))]
extern crate alloc;
extern crate substrate_primitives;
extern crate sr_primitives;
@@ -57,6 +61,14 @@ pub mod id {
pub const GRANDPA_API: ApiId = *b"fgrandpa";
}
/// Well-known storage keys for GRANDPA.
pub mod well_known_keys {
/// The key for the authorities and weights vector in storage.
pub const AUTHORITY_PREFIX: &[u8] = b":grandpa:auth:";
/// The key for the authorities count.
pub const AUTHORITY_COUNT: &[u8] = b":grandpa:auth:len";
}
decl_runtime_apis! {
/// APIs for integrating the GRANDPA finality gadget into runtimes.
/// This should be implemented on the runtime side.
@@ -76,6 +88,10 @@ decl_runtime_apis! {
///
/// No change should be scheduled if one is already and the delay has not
/// passed completely.
///
/// This should be a pure function: i.e. as long as the runtime can interpret
/// the digest type it should return the same result regardless of the current
/// state.
fn grandpa_pending_change(digest: DigestFor<Block>)
-> Option<ScheduledChange<NumberFor<Block>>>;
@@ -50,7 +50,9 @@ impl<H, N> SharedAuthoritySet<H, N> {
}
impl<H: Eq, N> SharedAuthoritySet<H, N>
where N: Add<Output=N> + Ord + Clone + Debug
where
N: Add<Output=N> + Ord + Clone + Debug,
H: Debug
{
/// Get the earliest limit-block number, if any.
pub(crate) fn current_limit(&self) -> Option<N> {
@@ -103,7 +105,9 @@ impl<H, N> AuthoritySet<H, N> {
}
impl<H: Eq, N> AuthoritySet<H, N>
where N: Add<Output=N> + Ord + Clone + Debug,
where
N: Add<Output=N> + Ord + Clone + Debug,
H: Debug
{
/// Note an upcoming pending transition.
pub(crate) fn add_pending_change(&mut self, pending: PendingChange<H, N>) {
@@ -152,7 +156,11 @@ impl<H: Eq, N> AuthoritySet<H, N>
// check if the block that signalled the change is canonical in
// our chain.
if canonical(change.canon_height.clone())? == change.canon_hash {
let canonical_at_height = canonical(change.canon_height.clone())?;
debug!(target: "afg", "Evaluating potential set change at block {:?}. Our canonical hash is {:?}",
(&change.canon_height, &change.canon_hash), canonical_at_height);
if canonical_at_height == change.canon_hash {
// apply this change: make the set canonical
info!(target: "finality", "Applying authority set change scheduled at block #{:?}",
change.canon_height);
+98 -18
View File
@@ -55,6 +55,7 @@ extern crate futures;
extern crate substrate_client as client;
extern crate sr_primitives as runtime_primitives;
extern crate substrate_consensus_common as consensus_common;
extern crate substrate_network as network;
extern crate substrate_primitives;
extern crate tokio;
extern crate parking_lot;
@@ -64,8 +65,8 @@ extern crate substrate_finality_grandpa_primitives as fg_primitives;
#[macro_use]
extern crate log;
#[cfg(test)]
extern crate substrate_network as network;
#[cfg(feature="service-integration")]
extern crate substrate_service as service;
#[cfg(test)]
extern crate substrate_keyring as keyring;
@@ -86,7 +87,7 @@ use client::{Client, error::Error as ClientError, ImportNotifications, backend::
use client::blockchain::HeaderBackend;
use client::runtime_api::TaggedTransactionQueue;
use codec::{Encode, Decode};
use consensus_common::{BlockImport, ImportBlock, ImportResult};
use consensus_common::{BlockImport, ImportBlock, ImportResult, Authorities};
use runtime_primitives::traits::{
NumberFor, Block as BlockT, Header as HeaderT, DigestFor, ProvideRuntimeApi
};
@@ -98,6 +99,8 @@ use tokio::timer::Interval;
use grandpa::Error as GrandpaError;
use grandpa::{voter, round::State as RoundState, Equivocation, BlockNumberOps};
use network::{Service as NetworkService, ExHashT};
use network::consensus_gossip::{ConsensusMessage};
use std::collections::{VecDeque, HashMap};
use std::sync::Arc;
use std::time::{Instant, Duration};
@@ -108,6 +111,11 @@ pub use fg_primitives::ScheduledChange;
mod authorities;
#[cfg(feature="service-integration")]
mod service_integration;
#[cfg(feature="service-integration")]
pub use service_integration::{LinkHalfForService, BlockImportForService};
#[cfg(test)]
mod tests;
@@ -173,7 +181,7 @@ impl From<GrandpaError> for Error {
/// handle to a gossip service or similar.
///
/// Intended to be a lightweight handle such as an `Arc`.
pub trait Network: Clone {
pub trait Network : Clone {
/// A stream of input messages for a topic.
type In: Stream<Item=Vec<u8>,Error=()>;
@@ -188,6 +196,52 @@ pub trait Network: Clone {
fn drop_messages(&self, round: u64, set_id: u64);
}
/// Bridge between NetworkService, gossiping consensus messages and Grandpa
pub struct NetworkBridge<B: BlockT, S: network::specialization::NetworkSpecialization<B>, H: ExHashT> {
service: Arc<NetworkService<B, S, H>>
}
impl<B: BlockT, S: network::specialization::NetworkSpecialization<B>, H: ExHashT> NetworkBridge<B, S, H> {
/// Create a new NetworkBridge to the given NetworkService
pub fn new(service: Arc<NetworkService<B, S, H>>) -> Self {
NetworkBridge { service }
}
}
impl<B: BlockT, S: network::specialization::NetworkSpecialization<B>, H: ExHashT> Clone for NetworkBridge<B, S, H> {
fn clone(&self) -> Self {
NetworkBridge {
service: Arc::clone(&self.service)
}
}
}
fn message_topic<B: BlockT>(round: u64, set_id: u64) -> B::Hash {
use runtime_primitives::traits::Hash as HashT;
<<B::Header as HeaderT>::Hashing as HashT>::hash(format!("{}-{}", set_id, round).as_bytes())
}
impl<B: BlockT, S: network::specialization::NetworkSpecialization<B>, H: ExHashT> Network for NetworkBridge<B, S, H> {
type In = mpsc::UnboundedReceiver<ConsensusMessage>;
fn messages_for(&self, round: u64, set_id: u64) -> Self::In {
self.service.consensus_gossip().write().messages_for(message_topic::<B>(round, set_id))
}
fn send_message(&self, round: u64, set_id: u64, message: Vec<u8>) {
let topic = message_topic::<B>(round, set_id);
let gossip = self.service.consensus_gossip();
self.service.with_spec(move |_s, context|{
gossip.write().multicast(context, topic, message);
});
}
fn drop_messages(&self, round: u64, set_id: u64) {
let topic = message_topic::<B>(round, set_id);
self.service.consensus_gossip().write().collect_garbage(|t| t == &topic);
}
}
/// Something which can determine if a block is known.
pub trait BlockStatus<Block: BlockT> {
/// Return `Ok(Some(number))` or `Ok(None)` depending on whether the block
@@ -523,7 +577,7 @@ impl<Block: BlockT<Hash=H256>, B, E, N, RA> grandpa::Chain<Block::Hash, NumberFo
// once blocks are finalized that make that transition irrelevant or activate it,
// we will proceed onwards. most of the time there will be no pending transition.
let limit = self.authority_set.current_limit();
trace!(target: "afg", "Finding best chain containing block {:?} with number limit {:?}", block, limit);
debug!(target: "afg", "Finding best chain containing block {:?} with number limit {:?}", block, limit);
match self.inner.best_containing(block, limit) {
Ok(Some(hash)) => {
@@ -583,22 +637,22 @@ impl<B, E, Block: BlockT<Hash=H256>, N, RA> voter::Environment<Block::Hash, Numb
Block: 'static,
B: Backend<Block, Blake2Hasher> + 'static,
E: CallExecutor<Block, Blake2Hasher> + 'static + Send + Sync,
N: Network + 'static,
N::In: 'static,
N: Network + 'static + Send,
N::In: 'static + Send,
RA: 'static + Send + Sync,
NumberFor<Block>: BlockNumberOps,
{
type Timer = Box<Future<Item = (), Error = Self::Error>>;
type Timer = Box<dyn Future<Item = (), Error = Self::Error> + Send>;
type Id = AuthorityId;
type Signature = ed25519::Signature;
type In = Box<Stream<
type In = Box<dyn Stream<
Item = ::grandpa::SignedMessage<Block::Hash, NumberFor<Block>, Self::Signature, Self::Id>,
Error = Self::Error,
>>;
type Out = Box<Sink<
> + Send>;
type Out = Box<dyn Sink<
SinkItem = ::grandpa::Message<Block::Hash, NumberFor<Block>>,
SinkError = Self::Error,
>>;
> + Send>;
type Error = ExitOrError<Block::Hash, NumberFor<Block>>;
#[allow(unreachable_code)]
@@ -689,6 +743,8 @@ impl<B, E, Block: BlockT<Hash=H256>, N, RA> voter::Environment<Block::Hash, Numb
return Ok(());
}
debug!(target: "afg", "Finalizing blocks up to ({:?}, {})", number, hash);
// lock must be held through writing to DB to avoid race
let mut authority_set = self.authority_set.inner().write();
let client = &self.inner;
@@ -768,8 +824,6 @@ impl<B, E, Block: BlockT<Hash=H256>, N, RA> voter::Environment<Block::Hash, Numb
}
}
/// A block-import handler for GRANDPA.
///
/// This scans each imported block for signals of changing authority set.
@@ -806,7 +860,7 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, PRA> BlockImport<Block>
// until the block is written to prevent a race if we need to restore
// the old authority set on error.
let just_in_case = maybe_change.map(|change| {
let hash = block.header.hash();
let hash = block.post_header().hash();
let number = block.header.number().clone();
let mut authorities = self.authority_set.inner().write();
@@ -834,12 +888,38 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, PRA> BlockImport<Block>
}
}
impl<B, E, Block: BlockT<Hash=H256>, RA, PRA> Authorities<Block> for GrandpaBlockImport<B, E, Block, RA, PRA>
where
B: Backend<Block, Blake2Hasher> + 'static,
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
RA: TaggedTransactionQueue<Block>, // necessary for client to import `BlockImport`.
{
type Error = <Client<B, E, Block, RA> as Authorities<Block>>::Error;
fn authorities(&self, at: &BlockId<Block>) -> Result<Vec<AuthorityId>, Self::Error> {
self.inner.authorities_at(at)
}
}
/// Half of a link between a block-import worker and a the background voter.
// This should remain non-clone.
pub struct LinkHalf<B, E, Block: BlockT<Hash=H256>, RA> {
client: Arc<Client<B, E, Block, RA>>,
authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
}
impl<B, E, Block: BlockT<Hash=H256>, RA> Clone for LinkHalf<B, E, Block, RA>
where
B: Backend<Block, Blake2Hasher> + 'static,
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
RA: TaggedTransactionQueue<Block>, // necessary for client to import `BlockImport`.
{
fn clone(&self) -> Self {
LinkHalf {
client: self.client.clone(),
authority_set: self.authority_set.clone()
}
}
}
/// Make block importer and link half necessary to tie the background voter
/// to it.
@@ -895,12 +975,12 @@ pub fn run_grandpa<B, E, Block: BlockT<Hash=H256>, N, RA>(
config: Config,
link: LinkHalf<B, E, Block, RA>,
network: N,
) -> ::client::error::Result<impl Future<Item=(),Error=()>> where
) -> ::client::error::Result<impl Future<Item=(),Error=()> + Send + 'static> where
Block::Hash: Ord,
B: Backend<Block, Blake2Hasher> + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
N: Network + 'static,
N::In: 'static,
N: Network + Send + Sync + 'static,
N::In: Send + 'static,
NumberFor<Block>: BlockNumberOps,
DigestFor<Block>: Encode,
RA: Send + Sync + 'static,
@@ -0,0 +1,40 @@
// Copyright 2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
/// Integrate grandpa finality with substrate service
use client;
use service::{FullBackend, FullExecutor, ServiceFactory};
pub type BlockImportForService<F> = ::GrandpaBlockImport<
FullBackend<F>,
FullExecutor<F>,
<F as ServiceFactory>::Block,
<F as ServiceFactory>::RuntimeApi,
client::Client<
FullBackend<F>,
FullExecutor<F>,
<F as ServiceFactory>::Block,
<F as ServiceFactory>::RuntimeApi
>,
>;
pub type LinkHalfForService<F> = ::LinkHalf<
FullBackend<F>,
FullExecutor<F>,
<F as ServiceFactory>::Block,
<F as ServiceFactory>::RuntimeApi
>;
+17 -5
View File
@@ -158,11 +158,15 @@ fn make_topic(round: u64, set_id: u64) -> Hash {
}
impl Network for MessageRouting {
type In = Box<Stream<Item=Vec<u8>,Error=()>>;
type In = Box<Stream<Item=Vec<u8>,Error=()> + Send>;
fn messages_for(&self, round: u64, set_id: u64) -> Self::In {
let messages = self.inner.lock().peer(self.peer_id)
.with_spec(|spec, _| spec.gossip.messages_for(make_topic(round, set_id)));
let inner = self.inner.lock();
let peer = inner.peer(self.peer_id);
let mut gossip = peer.consensus_gossip().write();
let messages = peer.with_spec(move |_, _| {
gossip.messages_for(make_topic(round, set_id))
});
let messages = messages.map_err(
move |_| panic!("Messages for round {} dropped too early", round)
@@ -179,8 +183,12 @@ impl Network for MessageRouting {
fn drop_messages(&self, round: u64, set_id: u64) {
let topic = make_topic(round, set_id);
self.inner.lock().peer(self.peer_id)
.with_spec(|spec, _| spec.gossip.collect_garbage(|t| t == &topic));
let inner = self.inner.lock();
let peer = inner.peer(self.peer_id);
let mut gossip = peer.consensus_gossip().write();
peer.with_spec(move |_, _| {
gossip.collect_garbage(|t| t == &topic)
});
}
}
@@ -318,6 +326,8 @@ fn finalize_3_voters_no_observers() {
.take_while(|n| Ok(n.header.number() < &20))
.for_each(|_| Ok(()))
);
fn assert_send<T: Send>(_: &T) { }
let voter = run_grandpa(
Config {
gossip_duration: TEST_GOSSIP_DURATION,
@@ -328,6 +338,8 @@ fn finalize_3_voters_no_observers() {
MessageRouting::new(net.clone(), peer_id),
).expect("all in order with client and network");
assert_send(&voter);
runtime.spawn(voter);
}
+3 -55
View File
@@ -24,14 +24,11 @@ use rand::{self, Rng};
use network_libp2p::NodeIndex;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Hash, HashFor};
use runtime_primitives::generic::BlockId;
use message::generic::{Message, ConsensusMessage};
pub use message::generic::{Message, ConsensusMessage};
use protocol::Context;
use config::Roles;
use specialization::NetworkSpecialization;
use StatusMessage;
use generic_message;
// TODO: Add additional spam/DoS attack protection.
// FIXME: Add additional spam/DoS attack protection: https://github.com/paritytech/substrate/issues/1115
const MESSAGE_LIFETIME: Duration = Duration::from_secs(600);
struct PeerConsensus<H> {
@@ -55,10 +52,7 @@ pub struct ConsensusGossip<B: BlockT> {
session_start: Option<B::Hash>,
}
impl<B: BlockT> ConsensusGossip<B>
where
B::Header: HeaderT<Number=u64>
{
impl<B: BlockT> ConsensusGossip<B> {
/// Create a new instance.
pub fn new() -> Self {
ConsensusGossip {
@@ -262,52 +256,6 @@ where
}
}
impl<Block: BlockT> NetworkSpecialization<Block> for ConsensusGossip<Block> where
Block::Header: HeaderT<Number=u64>
{
fn status(&self) -> Vec<u8> {
Vec::new()
}
fn on_connect(&mut self, ctx: &mut Context<Block>, who: NodeIndex, status: StatusMessage<Block>) {
self.new_peer(ctx, who, status.roles);
}
fn on_disconnect(&mut self, ctx: &mut Context<Block>, who: NodeIndex) {
self.peer_disconnected(ctx, who);
}
fn on_message(
&mut self,
ctx: &mut Context<Block>,
who: NodeIndex,
message: &mut Option<::message::Message<Block>>
) {
match message.take() {
Some(generic_message::Message::Consensus(topic, msg)) => {
trace!(target: "gossip", "Consensus message from {}: {:?}", who, msg);
self.on_incoming(ctx, who, topic, msg);
}
r => *message = r,
}
}
fn on_abort(&mut self) {
self.abort();
}
fn maintain_peers(&mut self, _ctx: &mut Context<Block>) {
self.collect_garbage(|_| true);
}
fn on_block_imported(
&mut self,
_ctx: &mut Context<Block>,
_hash: <Block as BlockT>::Hash,
_header: &<Block as BlockT>::Header)
{}
}
#[cfg(test)]
mod tests {
use runtime_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper};
+1 -1
View File
@@ -65,7 +65,7 @@ pub mod specialization;
pub mod test;
pub use chain::Client as ClientHandle;
pub use service::{Service, FetchFuture, TransactionPool, ManageNetwork, SyncProvider};
pub use service::{Service, FetchFuture, TransactionPool, ManageNetwork, SyncProvider, ExHashT};
pub use protocol::{ProtocolStatus, PeerInfo, Context};
pub use sync::{Status as SyncStatus, SyncState};
pub use network_libp2p::{NodeIndex, ProtocolId, Severity, Protocol};
+17
View File
@@ -27,6 +27,7 @@ use codec::{Encode, Decode};
use message::{self, Message};
use message::generic::Message as GenericMessage;
use consensus_gossip::ConsensusGossip;
use specialization::NetworkSpecialization;
use sync::{ChainSync, Status as SyncStatus, SyncState};
use service::{TransactionPool, ExHashT};
@@ -57,6 +58,7 @@ pub struct Protocol<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> {
genesis_hash: B::Hash,
sync: Arc<RwLock<ChainSync<B>>>,
specialization: RwLock<S>,
consensus_gossip: RwLock<ConsensusGossip<B>>,
context_data: ContextData<B, H>,
// Connected peers pending Status message.
handshaking_peers: RwLock<HashMap<NodeIndex, time::Instant>>,
@@ -207,6 +209,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
genesis_hash: info.chain.genesis_hash,
sync: Arc::new(RwLock::new(sync)),
specialization: RwLock::new(specialization),
consensus_gossip: RwLock::new(ConsensusGossip::new()),
handshaking_peers: RwLock::new(HashMap::new()),
transaction_pool: transaction_pool,
};
@@ -221,6 +224,11 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
&self.sync
}
pub(crate) fn consensus_gossip<'a>(&'a self) -> &'a RwLock<ConsensusGossip<B>> {
&self.consensus_gossip
}
/// Returns protocol status
pub fn status(&self) -> ProtocolStatus<B> {
let sync = self.sync.read();
@@ -278,6 +286,9 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
GenericMessage::RemoteHeaderResponse(response) => self.on_remote_header_response(io, who, response),
GenericMessage::RemoteChangesRequest(request) => self.on_remote_changes_request(io, who, request),
GenericMessage::RemoteChangesResponse(response) => self.on_remote_changes_response(io, who, response),
GenericMessage::Consensus(topic, msg) => {
self.consensus_gossip.write().on_incoming(&mut ProtocolContext::new(&self.context_data, io), who, topic, msg);
},
other => self.specialization.write().on_message(&mut ProtocolContext::new(&self.context_data, io), who, &mut Some(other)),
}
}
@@ -297,6 +308,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
pub fn on_peer_disconnected(&self, io: &mut SyncIo, peer: NodeIndex) {
trace!(target: "sync", "Disconnecting {}: {}", peer, io.peer_debug_info(peer));
// lock all the the peer lists so that add/remove peer events are in order
let mut sync = self.sync.write();
let mut spec = self.specialization.write();
@@ -309,6 +321,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
};
if removed {
let mut context = ProtocolContext::new(&self.context_data, io);
self.consensus_gossip.write().peer_disconnected(&mut context, peer);
sync.peer_disconnected(&mut context, peer);
spec.on_disconnect(&mut context, peer);
self.on_demand.as_ref().map(|s| s.on_disconnect(peer));
@@ -391,6 +404,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
/// Perform time based maintenance.
pub fn tick(&self, io: &mut SyncIo) {
self.consensus_gossip.write().collect_garbage(|_| true);
self.maintain_peers(io);
self.on_demand.as_ref().map(|s| s.maintain_peers(io));
}
@@ -478,6 +492,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
let mut context = ProtocolContext::new(&self.context_data, io);
self.on_demand.as_ref().map(|s| s.on_connect(who, status.roles, status.best_number));
self.sync.write().new_peer(&mut context, who);
self.consensus_gossip.write().new_peer(&mut context, who, status.roles);
self.specialization.write().on_connect(&mut context, who, status);
}
@@ -555,10 +570,12 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
let mut spec = self.specialization.write();
let mut peers = self.context_data.peers.write();
let mut handshaking_peers = self.handshaking_peers.write();
let mut consensus_gossip = self.consensus_gossip.write();
sync.clear();
spec.on_abort();
peers.clear();
handshaking_peers.clear();
consensus_gossip.abort();
}
pub fn stop(&self) {
+10 -4
View File
@@ -19,11 +19,12 @@ use std::sync::Arc;
use std::{io, thread};
use std::time::Duration;
use futures::{self, Future, Stream, stream, sync::oneshot};
use parking_lot::Mutex;
use parking_lot::{Mutex, RwLock};
use network_libp2p::{ProtocolId, PeerId, NetworkConfiguration, ErrorKind};
use network_libp2p::{start_service, Service as NetworkService, ServiceEvent as NetworkServiceEvent};
use network_libp2p::{RegisteredProtocol, parse_str_addr, Protocol as Libp2pProtocol};
use io::NetSyncIo;
use consensus_gossip::ConsensusGossip;
use protocol::{self, Protocol, ProtocolContext, Context, ProtocolStatus};
use config::Params;
use error::Error;
@@ -44,6 +45,7 @@ pub trait SyncProvider<B: BlockT>: Send + Sync {
fn status(&self) -> ProtocolStatus<B>;
}
/// Minimum Requirements for a Hash within Networking
pub trait ExHashT: ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static {}
impl<T> ExHashT for T where T: ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static {}
@@ -82,9 +84,8 @@ impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> Service<B, S,
pub fn new<I: 'static + ImportQueue<B>>(
params: Params<B, S, H>,
protocol_id: ProtocolId,
import_queue: I,
import_queue: Arc<I>,
) -> Result<Arc<Service<B, S, H>>, Error> {
let import_queue = Arc::new(import_queue);
let handler = Arc::new(Protocol::new(
params.config,
params.chain,
@@ -101,7 +102,7 @@ impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> Service<B, S,
network,
protocol_id,
handler,
bg_thread: Some(thread),
bg_thread: Some(thread)
});
// connect the import-queue to the network service.
@@ -131,6 +132,11 @@ impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> Service<B, S,
{
self.handler.with_spec(&mut NetSyncIo::new(&self.network, self.protocol_id), f)
}
/// access the underlying consensus gossip handler
pub fn consensus_gossip<'a>(&'a self) -> &'a RwLock<ConsensusGossip<B>> {
self.handler.consensus_gossip()
}
}
impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> ::consensus::SyncOracle for Service<B, S, H> {
+15 -20
View File
@@ -58,31 +58,23 @@ impl ExecuteInContext<Block> for DummyContextExecutor {
}
/// The test specialization.
pub struct DummySpecialization {
/// Consensus gossip handle.
pub gossip: ConsensusGossip<Block>,
}
pub struct DummySpecialization { }
impl NetworkSpecialization<Block> for DummySpecialization {
fn status(&self) -> Vec<u8> { vec![] }
fn on_connect(&mut self, ctx: &mut Context<Block>, peer_id: NodeIndex, status: ::message::Status<Block>) {
self.gossip.new_peer(ctx, peer_id, status.roles);
fn on_connect(&mut self, _ctx: &mut Context<Block>, _peer_id: NodeIndex, _status: ::message::Status<Block>) {
}
fn on_disconnect(&mut self, ctx: &mut Context<Block>, peer_id: NodeIndex) {
self.gossip.peer_disconnected(ctx, peer_id);
fn on_disconnect(&mut self, _ctx: &mut Context<Block>, _peer_id: NodeIndex) {
}
fn on_message(
&mut self,
ctx: &mut Context<Block>,
peer_id: NodeIndex,
message: &mut Option<::message::Message<Block>>
_ctx: &mut Context<Block>,
_peer_id: NodeIndex,
_message: &mut Option<::message::Message<Block>>
) {
if let Some(::message::generic::Message::Consensus(topic, data)) = message.take() {
self.gossip.on_incoming(ctx, peer_id, topic, data);
}
}
}
@@ -179,6 +171,10 @@ impl<V: 'static + Verifier<Block>, D> Peer<V, D> {
self.sync.on_peer_connected(&mut TestIo::new(&self.queue, Some(other)), other);
}
pub fn consensus_gossip(&self) -> &RwLock<ConsensusGossip<Block>> {
self.sync.consensus_gossip()
}
/// Called on disconnect from other indicated peer.
fn on_disconnect(&self, other: NodeIndex) {
let mut io = TestIo::new(&self.queue, Some(other));
@@ -233,9 +229,10 @@ impl<V: 'static + Verifier<Block>, D> Peer<V, D> {
/// Push a message into the gossip network and relay to peers.
/// `TestNet::sync_step` needs to be called to ensure it's propagated.
pub fn gossip_message(&self, topic: Hash, data: Vec<u8>) {
self.sync.with_spec(&mut TestIo::new(&self.queue, None), |spec, ctx| {
spec.gossip.multicast(ctx, topic, data);
})
let gossip = self.sync.consensus_gossip();
self.sync.with_spec(&mut TestIo::new(&self.queue, None), move |_s, context|{
gossip.write().multicast(context, topic, data);
});
}
/// Add blocks to the peer -- edit the block before adding
@@ -363,9 +360,7 @@ pub trait TestNetFactory: Sized {
let (block_import, data) = self.make_block_import(client.clone());
let import_queue = Arc::new(SyncImportQueue::new(verifier, block_import));
let specialization = DummySpecialization {
gossip: ConsensusGossip::new(),
};
let specialization = DummySpecialization { };
let sync = Protocol::new(
config.clone(),
client.clone(),
+3 -2
View File
@@ -87,14 +87,15 @@ pub fn export_blocks<F, E, W>(config: FactoryFullConfiguration<F>, exit: E, mut
}
/// Import blocks from a binary stream.
pub fn import_blocks<F, E, R>(config: FactoryFullConfiguration<F>, exit: E, mut input: R) -> error::Result<()>
pub fn import_blocks<F, E, R>(mut config: FactoryFullConfiguration<F>, exit: E, mut input: R) -> error::Result<()>
where F: ServiceFactory, E: Future<Item=(),Error=()> + Send + 'static, R: Read,
{
struct DummyLink;
impl<B: Block> Link<B> for DummyLink { }
let client = new_client::<F>(&config)?;
let queue = components::FullComponents::<F>::build_import_queue(&config, client.clone())?;
// FIXME: this shouldn't need a mutable config. https://github.com/paritytech/substrate/issues/1134
let queue = components::FullComponents::<F>::build_import_queue(&mut config, client.clone())?;
queue.start(DummyLink)?;
let (exit_send, exit_recv) = std::sync::mpsc::channel();
+5 -5
View File
@@ -266,7 +266,7 @@ pub trait ServiceFactory: 'static + Sized {
/// ImportQueue for a full client
fn build_full_import_queue(
config: &FactoryFullConfiguration<Self>,
config: &mut FactoryFullConfiguration<Self>,
_client: Arc<FullClient<Self>>
) -> Result<Self::FullImportQueue, error::Error> {
if let Some(name) = config.chain_spec.consensus_engine() {
@@ -281,7 +281,7 @@ pub trait ServiceFactory: 'static + Sized {
/// ImportQueue for a light client
fn build_light_import_queue(
config: &FactoryFullConfiguration<Self>,
config: &mut FactoryFullConfiguration<Self>,
_client: Arc<LightClient<Self>>
) -> Result<Self::LightImportQueue, error::Error> {
if let Some(name) = config.chain_spec.consensus_engine() {
@@ -336,7 +336,7 @@ pub trait Components: Sized + 'static {
/// instance of import queue for clients
fn build_import_queue(
config: &FactoryFullConfiguration<Self::Factory>,
config: &mut FactoryFullConfiguration<Self::Factory>,
client: Arc<ComponentClient<Self>>
) -> Result<Self::ImportQueue, error::Error>;
}
@@ -409,7 +409,7 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
}
fn build_import_queue(
config: &FactoryFullConfiguration<Self::Factory>,
config: &mut FactoryFullConfiguration<Self::Factory>,
client: Arc<ComponentClient<Self>>
) -> Result<Self::ImportQueue, error::Error> {
Factory::build_full_import_queue(config, client)
@@ -485,7 +485,7 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
}
fn build_import_queue(
config: &FactoryFullConfiguration<Self::Factory>,
config: &mut FactoryFullConfiguration<Self::Factory>,
client: Arc<ComponentClient<Self>>
) -> Result<Self::ImportQueue, error::Error> {
Factory::build_light_import_queue(config, client)
+58 -17
View File
@@ -103,6 +103,8 @@ pub struct Service<Components: components::Components> {
keystore: Keystore,
exit: ::exit_future::Exit,
signal: Option<Signal>,
/// Configuration of this Service
pub config: FactoryFullConfiguration<Components::Factory>,
proposer: Arc<ProposerFactory<ComponentClient<Components>, Components::TransactionPoolApi>>,
_rpc_http: Option<rpc::HttpServer>,
_rpc_ws: Option<Mutex<rpc::WsServer>>, // WsServer is not `Sync`, but the service needs to be.
@@ -129,7 +131,7 @@ impl<Components> Service<Components>
{
/// Creates a new service.
pub fn new(
config: FactoryFullConfiguration<Components::Factory>,
mut config: FactoryFullConfiguration<Components::Factory>,
task_executor: TaskExecutor,
)
-> Result<Self, error::Error>
@@ -159,7 +161,7 @@ impl<Components> Service<Components>
};
let (client, on_demand) = Components::build_client(&config, executor)?;
let import_queue = Components::build_import_queue(&config, client.clone())?;
let import_queue = Arc::new(Components::build_import_queue(&mut config, client.clone())?);
let best_header = client.best_block_header()?;
let version = config.full_version();
@@ -168,7 +170,7 @@ impl<Components> Service<Components>
let network_protocol = <Components::Factory>::build_network_protocol(&config)?;
let transaction_pool = Arc::new(
Components::build_transaction_pool(config.transaction_pool, client.clone())?
Components::build_transaction_pool(config.transaction_pool.clone(), client.clone())?
);
let transaction_pool_adapter = TransactionPoolAdapter::<Components> {
imports_external_transactions: !(config.roles == Roles::LIGHT),
@@ -177,19 +179,30 @@ impl<Components> Service<Components>
};
let network_params = Components::CreateNetworkParams::create_network_params(
client.clone(), config.roles, config.network, on_demand.clone(),
transaction_pool_adapter, network_protocol
client.clone(),
config.roles,
config.network.clone(),
on_demand.clone(),
transaction_pool_adapter,
network_protocol,
);
let mut protocol_id = network::ProtocolId::default();
let protocol_id_full = config.chain_spec.protocol_id().unwrap_or(DEFAULT_PROTOCOL_ID).as_bytes();
if protocol_id_full.len() > protocol_id.len() {
warn!("Protocol ID truncated to {} chars", protocol_id.len());
}
let id_len = protocol_id_full.len().min(protocol_id.len());
&mut protocol_id[0..id_len].copy_from_slice(&protocol_id_full[0..id_len]);
let protocol_id = {
let protocol_id_full = config.chain_spec.protocol_id().unwrap_or(DEFAULT_PROTOCOL_ID).as_bytes();
let mut protocol_id = network::ProtocolId::default();
if protocol_id_full.len() > protocol_id.len() {
warn!("Protocol ID truncated to {} chars", protocol_id.len());
}
let id_len = protocol_id_full.len().min(protocol_id.len());
&mut protocol_id[0..id_len].copy_from_slice(&protocol_id_full[0..id_len]);
protocol_id
};
let network = network::Service::new(network_params, protocol_id, import_queue)?;
let network = network::Service::new(
network_params,
protocol_id,
import_queue
)?;
on_demand.map(|on_demand| on_demand.set_service_link(Arc::downgrade(&network)));
{
@@ -244,7 +257,7 @@ impl<Components> Service<Components>
});
// Telemetry
let telemetry = match config.telemetry_url {
let telemetry = match config.telemetry_url.clone() {
Some(url) => {
let is_authority = config.roles == Roles::AUTHORITY;
let pubkey = format!("{}", public_key);
@@ -276,6 +289,7 @@ impl<Components> Service<Components>
transaction_pool: transaction_pool,
signal: Some(signal),
keystore: keystore,
config,
proposer,
exit,
_rpc_http: rpc_http,
@@ -283,6 +297,23 @@ impl<Components> Service<Components>
_telemetry: telemetry,
})
}
/// give the authority key, if we are an authority and have a key
pub fn authority_key(&self) -> Option<primitives::ed25519::Pair> {
if self.config.roles != Roles::AUTHORITY { return None }
let keystore = &self.keystore;
if let Ok(Some(Ok(key))) = keystore.contents().map(|keys| keys.get(0)
.map(|k| keystore.load(k, "")))
{
Some(key)
} else {
None
}
}
pub fn config(&self) -> &FactoryFullConfiguration<Components::Factory> {
&self.config
}
}
impl<Components> Service<Components> where Components: components::Components {
@@ -466,6 +497,9 @@ impl<C: Components> network::TransactionPool<ComponentExHash<C>, ComponentBlock<
/// Configuration = (),
/// FullService = Service<FullComponents<Self>>
/// { |config, executor| Service::<FullComponents<Factory>>::new(config, executor) },
/// // Setup as Consensus Authority (if the role and key are given)
/// AuthoritySetup = {
/// |service: Self::FullService, executor: TaskExecutor, key: Arc<Pair>| { Ok(service) }},
/// LightService = Service<LightComponents<Self>>
/// { |config, executor| Service::<LightComponents<Factory>>::new(config, executor) },
/// // Declare the import queue. The import queue is special as it takes two initializers.
@@ -491,6 +525,7 @@ macro_rules! construct_service_factory {
Genesis = $genesis:ty,
Configuration = $config:ty,
FullService = $full_service:ty { $( $full_service_init:tt )* },
AuthoritySetup = { $( $authority_setup:tt )* },
LightService = $light_service:ty { $( $light_service_init:tt )* },
FullImportQueue = $full_import_queue:ty
{ $( $full_import_queue_init:tt )* },
@@ -539,14 +574,14 @@ macro_rules! construct_service_factory {
}
fn build_full_import_queue(
config: &$crate::FactoryFullConfiguration<Self>,
config: &mut $crate::FactoryFullConfiguration<Self>,
client: $crate::Arc<$crate::FullClient<Self>>,
) -> $crate::Result<Self::FullImportQueue, $crate::Error> {
( $( $full_import_queue_init )* ) (config, client)
}
fn build_light_import_queue(
config: &FactoryFullConfiguration<Self>,
config: &mut FactoryFullConfiguration<Self>,
client: Arc<$crate::LightClient<Self>>,
) -> Result<Self::LightImportQueue, $crate::Error> {
( $( $light_import_queue_init )* ) (config, client)
@@ -565,7 +600,13 @@ macro_rules! construct_service_factory {
executor: $crate::TaskExecutor
) -> Result<Self::FullService, $crate::Error>
{
( $( $full_service_init )* ) (config, executor)
( $( $full_service_init )* ) (config, executor.clone()).and_then(|service| {
if let Some(key) = (&service).authority_key() {
($( $authority_setup )*)(service, executor, Arc::new(key))
} else {
Ok(service)
}
})
}
}
}
@@ -24,7 +24,7 @@ use traits::{self, Member, DigestItem as DigestItemT, MaybeSerializeDebug};
use substrate_primitives::hash::H512 as Signature;
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
pub struct Digest<Item> {
pub logs: Vec<Item>,
}
@@ -57,7 +57,7 @@ impl<Item> traits::Digest for Digest<Item> where
/// Digest item that is able to encode/decode 'system' digest items and
/// provide opaque access to other items.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
pub enum DigestItem<Hash, AuthorityId> {
/// System digest item announcing that authorities set has been changed
/// in the block. Contains the new set of authorities.
+4 -4
View File
@@ -354,7 +354,7 @@ macro_rules! impl_outer_log {
/// Wrapper for all possible log entries for the `$trait` runtime. Provides binary-compatible
/// `Encode`/`Decode` implementations with the corresponding `generic::DigestItem`.
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
$(#[$attr])*
#[allow(non_camel_case_types)]
pub struct $name($internal);
@@ -362,7 +362,7 @@ macro_rules! impl_outer_log {
/// All possible log entries for the `$trait` runtime. `Encode`/`Decode` implementations
/// are auto-generated => it is not binary-compatible with `generic::DigestItem`.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
$(#[$attr])*
#[allow(non_camel_case_types)]
pub enum InternalLog {
@@ -482,7 +482,7 @@ mod tests {
use super::RuntimeT;
pub type Log<R> = RawLog<<R as RuntimeT>::AuthorityId>;
#[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
#[derive(Serialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<AuthorityId> { A1(AuthorityId), AuthoritiesChange(Vec<AuthorityId>), A3(AuthorityId) }
}
@@ -490,7 +490,7 @@ mod tests {
use super::RuntimeT;
pub type Log<R> = RawLog<<R as RuntimeT>::AuthorityId>;
#[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
#[derive(Serialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<AuthorityId> { B1(AuthorityId), B2(AuthorityId) }
}
+19 -4
View File
@@ -26,7 +26,7 @@ pub use substrate_primitives::{H256, AuthorityId};
pub type DigestItem = GenDigestItem<H256, u64>;
#[derive(Default, PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
#[derive(Default, PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode)]
pub struct Digest {
pub logs: Vec<DigestItem>,
}
@@ -48,7 +48,7 @@ impl traits::Digest for Digest {
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Header {
@@ -98,15 +98,30 @@ impl traits::Header for Header {
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
impl<'a> Deserialize<'a> for Header {
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
let r = <Vec<u8>>::deserialize(de)?;
Decode::decode(&mut &r[..]).ok_or(DeError::custom("Invalid value passed into decode"))
}
}
#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)]
pub struct ExtrinsicWrapper<Xt>(Xt);
impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt> where Xt: Serialize {
impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt> {
fn is_signed(&self) -> Option<bool> {
None
}
}
#[cfg(feature = "std")]
impl<Xt: Encode> serde::Serialize for ExtrinsicWrapper<Xt>
{
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
}
}
impl<Xt> From<Xt> for ExtrinsicWrapper<Xt> {
fn from(xt: Xt) -> Self {
ExtrinsicWrapper(xt)
+5 -5
View File
@@ -544,8 +544,8 @@ pub trait Applyable: Sized + Send + Sync {
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
/// each `Codec`.
pub trait Digest: Member + MaybeSerializeDebug + Default {
type Hash: Member + MaybeSerializeDebug;
pub trait Digest: Member + MaybeSerializeDebugButNotDeserialize + Default {
type Hash: Member + MaybeSerializeDebugButNotDeserialize;
type Item: DigestItem<Hash = Self::Hash>;
/// Get reference to all digest items.
@@ -567,9 +567,9 @@ pub trait Digest: Member + MaybeSerializeDebug + Default {
/// for casting member to 'system' log items, known to substrate.
///
/// If the runtime does not supports some 'system' items, use `()` as a stub.
pub trait DigestItem: Codec + Member + MaybeSerializeDebug {
type Hash: Member + MaybeSerializeDebug;
type AuthorityId: Member + MaybeSerializeDebug;
pub trait DigestItem: Codec + Member + MaybeSerializeDebugButNotDeserialize {
type Hash: Member + MaybeSerializeDebugButNotDeserialize;
type AuthorityId: Member + MaybeSerializeDebugButNotDeserialize;
/// Returns Some if the entry is the `AuthoritiesChange` entry.
fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]>;
+13 -2
View File
@@ -18,6 +18,9 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate serde;
extern crate sr_std as rstd;
extern crate parity_codec as codec;
extern crate sr_primitives as runtime_primitives;
@@ -89,7 +92,7 @@ pub fn native_version() -> NativeVersion {
/// Calls in transactions.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct Transfer {
pub from: AccountId,
pub to: AccountId,
@@ -99,12 +102,20 @@ pub struct Transfer {
/// Extrinsic for test-runtime.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct Extrinsic {
pub transfer: Transfer,
pub signature: Ed25519Signature,
}
#[cfg(feature = "std")]
impl serde::Serialize for Extrinsic
{
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
}
}
impl BlindCheckable for Extrinsic {
type Checked = Self;
+9
View File
@@ -3,10 +3,12 @@ name = "node-cli"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Substrate node implementation in Rust."
build = "build.rs"
[dependencies]
log = "0.4"
tokio = "0.1.7"
futures = "0.1"
exit-future = "0.1"
substrate-cli = { path = "../../core/cli" }
parity-codec = { version = "2.1" }
@@ -22,9 +24,16 @@ substrate-service = { path = "../../core/service" }
substrate-transaction-pool = { path = "../../core/transaction-pool" }
substrate-network = { path = "../../core/network" }
substrate-consensus-aura = { path = "../../core/consensus/aura" }
substrate-finality-grandpa = { path = "../../core/finality-grandpa" }
sr-primitives = { path = "../../core/sr-primitives" }
node-executor = { path = "../executor" }
structopt = "0.2.13"
substrate-keystore = { path = "../../core/keystore" }
[dev-dependencies]
substrate-service-test = { path = "../../core/service/test" }
[build-dependencies]
substrate-cli = { path = "../../core/cli" }
structopt = "0.2.13"
clap = "~2.32"
@@ -17,11 +17,18 @@
#[macro_use]
extern crate clap;
extern crate substrate_cli as cli;
#[macro_use]
extern crate structopt;
use std::fs;
use std::env;
use clap::Shell;
use std::path::Path;
include!("src/params.rs");
fn main() {
build_shell_completion();
}
@@ -37,7 +44,6 @@ fn build_shell_completion() {
/// Build the shell auto-completion for a given Shell
fn build_completion(shell: &Shell) {
let yml = load_yaml!("src/cli.yml");
let outdir = match env::var_os("OUT_DIR") {
None => return,
@@ -51,9 +57,9 @@ fn build_completion(shell: &Shell) {
fs::create_dir(&path).ok();
let mut app = clap::App::from_yaml(&yml);
let mut app = Params::clap();
app.gen_completions(
"polkadot",
"substrate-node",
*shell,
&path);
}
+9 -1
View File
@@ -20,7 +20,7 @@ use primitives::{AuthorityId, ed25519};
use node_primitives::AccountId;
use node_runtime::{ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig,
SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig,
UpgradeKeyConfig, ContractConfig, Permill, Perbill};
UpgradeKeyConfig, ContractConfig, GrandpaConfig, Permill, Perbill};
pub use node_runtime::GenesisConfig;
use substrate_service;
@@ -140,6 +140,10 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
key: endowed_accounts[0].clone(),
_genesis_phantom_data: Default::default(),
}),
grandpa: Some(GrandpaConfig {
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
_genesis_phantom_data: Default::default(),
})
}
}
@@ -269,6 +273,10 @@ pub fn testnet_genesis(
key: upgrade_key,
_genesis_phantom_data: Default::default(),
}),
grandpa: Some(GrandpaConfig {
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
_genesis_phantom_data: Default::default(),
})
}
}
-12
View File
@@ -1,12 +0,0 @@
name: substrate-node
author: "Parity Team <admin@parity.io>"
about: Substrate Node Rust Implementation
args:
- log:
short: l
value_name: LOG_PATTERN
help: Sets a custom logging
takes_value: true
subcommands:
- validator:
about: Run validator node
+36 -2
View File
@@ -34,6 +34,7 @@ extern crate substrate_transaction_pool as transaction_pool;
extern crate substrate_network as network;
extern crate substrate_consensus_aura as consensus;
extern crate substrate_client as client;
extern crate substrate_finality_grandpa as grandpa;
extern crate node_primitives;
#[macro_use]
extern crate substrate_service;
@@ -42,14 +43,19 @@ extern crate substrate_keystore;
#[macro_use]
extern crate log;
#[macro_use]
extern crate structopt;
pub use cli::error;
pub mod chain_spec;
mod service;
mod params;
use tokio::runtime::Runtime;
pub use cli::{VersionInfo, IntoExit};
use substrate_service::{ServiceFactory, Roles as ServiceRoles};
use params::{Params as NodeParams};
use structopt::StructOpt;
use std::ops::Deref;
/// The chain specification option.
@@ -100,9 +106,37 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
T: Into<std::ffi::OsString> + Clone,
E: IntoExit,
{
match cli::prepare_execution::<service::Factory, _, _, _, _>(args, exit, version, load_spec, "substrate-node")? {
let full_version = substrate_service::config::full_version_from_strs(
version.version,
version.commit
);
let matches = match NodeParams::clap()
.name(version.executable_name)
.author(version.author)
.about(version.description)
.version(&(full_version + "\n")[..])
.get_matches_from_safe(args) {
Ok(m) => m,
Err(e) => e.exit(),
};
let (spec, mut config) = cli::parse_matches::<service::Factory, _>(load_spec, version, "substrate-node", &matches)?;
if matches.is_present("grandpa_authority_only") {
config.custom.grandpa_authority = true;
config.custom.grandpa_authority_only = true;
// Authority Setup is only called if validator is set as true
config.roles = ServiceRoles::AUTHORITY;
} else if matches.is_present("grandpa_authority") {
config.custom.grandpa_authority = true;
// Authority Setup is only called if validator is set as true
config.roles = ServiceRoles::AUTHORITY;
}
match cli::execute_default::<service::Factory, _>(spec, exit, &matches)? {
cli::Action::ExecutedInternally => (),
cli::Action::RunService((config, exit)) => {
cli::Action::RunService(exit) => {
info!("Substrate Node");
info!(" version {}", config.full_version());
info!(" by Parity Technologies, 2017, 2018");
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
use structopt::StructOpt;
use cli::CoreParams;
/// Extend params for Node
#[derive(Debug, StructOpt)]
pub struct Params {
/// Should run as a GRANDPA authority node
#[structopt(long = "grandpa-authority", help = "Run Node as a GRANDPA authority, implies --validator")]
grandpa_authority: bool,
/// Should run as a GRANDPA authority node only
#[structopt(long = "grandpa-authority-only", help = "Run Node as a GRANDPA authority only, don't as a usual validator, implies --grandpa-authority")]
grandpa_authority_only: bool,
#[structopt(flatten)]
core: CoreParams
}
+76 -38
View File
@@ -24,12 +24,14 @@ use node_runtime::{GenesisConfig, ClientWithApi};
use node_primitives::Block;
use substrate_service::{
FactoryFullConfiguration, LightComponents, FullComponents, FullBackend,
FullClient, LightClient, LightBackend, FullExecutor, LightExecutor,
Roles, TaskExecutor,
FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, TaskExecutor
};
use node_executor;
use consensus::{import_queue, start_aura, Config as AuraConfig, AuraImportQueue, NothingExtra};
use primitives::ed25519::Pair;
use client;
use std::time::Duration;
use grandpa;
const AURA_SLOT_DURATION: u64 = 6;
@@ -38,6 +40,29 @@ construct_simple_protocol! {
pub struct NodeProtocol where Block = Block { }
}
/// Node specific configuration
pub struct NodeConfig<F: substrate_service::ServiceFactory> {
/// should run as a grandpa authority
pub grandpa_authority: bool,
/// should run as a grandpa authority only, don't validate as usual
pub grandpa_authority_only: bool,
/// grandpa connection to import block
// FIXME: rather than putting this on the config, let's have an actual intermediate setup state
// https://github.com/paritytech/substrate/issues/1134
pub grandpa_link_half: Option<grandpa::LinkHalfForService<F>>,
}
impl<F> Default for NodeConfig<F> where F: substrate_service::ServiceFactory {
fn default() -> NodeConfig<F> {
NodeConfig {
grandpa_authority: false,
grandpa_authority_only: false,
grandpa_link_half: None
}
}
}
construct_service_factory! {
struct Factory {
Block = Block,
@@ -49,49 +74,62 @@ construct_service_factory! {
LightTransactionPoolApi = transaction_pool::ChainApi<client::Client<LightBackend<Self>, LightExecutor<Self>, Block, ClientWithApi>, Block>
{ |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) },
Genesis = GenesisConfig,
Configuration = (),
Configuration = NodeConfig<Self>,
FullService = FullComponents<Self>
{ |config: FactoryFullConfiguration<Self>, executor: TaskExecutor| {
let is_auth = config.roles == Roles::AUTHORITY;
FullComponents::<Factory>::new(config, executor.clone()).map(move |service|{
if is_auth {
if let Ok(Some(Ok(key))) = service.keystore().contents()
.map(|keys| keys.get(0).map(|k| service.keystore().load(k, "")))
{
info!("Using authority key {}", key.public());
let task = start_aura(
AuraConfig {
local_key: Some(Arc::new(key)),
slot_duration: AURA_SLOT_DURATION,
},
service.client(),
service.proposer(),
service.network(),
);
{ |config: FactoryFullConfiguration<Self>, executor: TaskExecutor|
FullComponents::<Factory>::new(config, executor) },
AuthoritySetup = {
|service: Self::FullService, executor: TaskExecutor, key: Arc<Pair>| {
if service.config.custom.grandpa_authority {
info!("Running Grandpa session as Authority {}", key.public());
let link_half = service.config().custom.grandpa_link_half.as_ref().take()
.expect("Link Half is present for Full Services or setup failed before. qed");
let grandpa_fut = grandpa::run_grandpa(
grandpa::Config {
gossip_duration: Duration::new(4, 0), // FIXME: make this available through chainspec?
local_key: Some(key.clone()),
name: Some(service.config().name.clone())
},
(*link_half).clone(),
grandpa::NetworkBridge::new(service.network())
)?;
executor.spawn(task);
}
}
service
})
executor.spawn(grandpa_fut);
}
if !service.config.custom.grandpa_authority_only {
info!("Using authority key {}", key.public());
executor.spawn(start_aura(
AuraConfig {
local_key: Some(key),
slot_duration: AURA_SLOT_DURATION,
},
service.client(),
service.proposer(),
service.network(),
));
}
Ok(service)
}
},
LightService = LightComponents<Self>
{ |config, executor| <LightComponents<Factory>>::new(config, executor) },
FullImportQueue = AuraImportQueue<Self::Block, FullClient<Self>, NothingExtra>
{ |config, client| Ok(import_queue(
AuraConfig {
local_key: None,
slot_duration: 5
},
client,
NothingExtra,
))
},
FullImportQueue = AuraImportQueue<Self::Block, grandpa::BlockImportForService<Self>, NothingExtra>
{ |config: &mut FactoryFullConfiguration<Self> , client: Arc<FullClient<Self>>| {
let (block_import, link_half) = grandpa::block_import::<_, _, _, ClientWithApi, FullClient<Self>>(client.clone(), client)?;
config.custom.grandpa_link_half = Some(link_half);
Ok(import_queue(
AuraConfig {
local_key: None,
slot_duration: 5
},
Arc::new(block_import),
NothingExtra,
))
}},
LightImportQueue = AuraImportQueue<Self::Block, LightClient<Self>, NothingExtra>
{ |config, client| Ok(import_queue(
AuraConfig {
{ |ref mut config, client| Ok(
import_queue(AuraConfig {
local_key: None,
slot_duration: 5
},
+1
View File
@@ -28,6 +28,7 @@ srml-consensus = { path = "../../srml/consensus" }
srml-timestamp = { path = "../../srml/timestamp" }
srml-treasury = { path = "../../srml/treasury" }
srml-contract = { path = "../../srml/contract" }
srml-grandpa = { path = "../../srml/grandpa" }
wabt = "0.4"
[features]
+43 -14
View File
@@ -36,6 +36,7 @@ extern crate node_runtime;
#[cfg(test)] extern crate srml_timestamp as timestamp;
#[cfg(test)] extern crate srml_treasury as treasury;
#[cfg(test)] extern crate srml_contract as contract;
#[cfg(test)] extern crate srml_grandpa as grandpa;
#[cfg(test)] extern crate node_primitives;
#[cfg(test)] extern crate parity_codec as codec;
#[cfg(test)] extern crate sr_io as runtime_io;
@@ -66,7 +67,7 @@ mod tests {
use system::{EventRecord, Phase};
use node_runtime::{Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances,
BuildStorage, GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System,
SystemConfig, Event, Log};
SystemConfig, GrandpaConfig, Event, Log};
use wabt;
const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm");
@@ -262,14 +263,26 @@ mod tests {
treasury: Some(Default::default()),
contract: Some(Default::default()),
upgrade_key: Some(Default::default()),
grandpa: Some(GrandpaConfig {
authorities: vec![ // set these so no GRANDPA events fire when session changes
(Alice.to_raw_public().into(), 1),
(Bob.to_raw_public().into(), 1),
(Charlie.to_raw_public().into(), 1),
],
_genesis_phantom_data: Default::default(),
}),
}.build_storage().unwrap().0)
}
fn changes_trie_log(changes_root: Hash) -> Log {
Log::from(system::RawLog::ChangesTrieRoot::<Hash>(changes_root))
}
fn construct_block(
number: BlockNumber,
parent_hash: Hash,
state_root: Hash,
changes_root: Option<Hash>,
logs: Vec<Log>,
extrinsics: Vec<CheckedExtrinsic>
) -> (Vec<u8>, Hash) {
use trie::ordered_trie_root;
@@ -281,8 +294,8 @@ mod tests {
.into();
let mut digest = generic::Digest::<Log>::default();
if let Some(changes_root) = changes_root {
digest.push(Log::from(system::RawLog::ChangesTrieRoot::<Hash>(changes_root)));
for item in logs {
digest.push(item);
}
let header = Header {
@@ -302,14 +315,16 @@ mod tests {
1,
GENESIS_HASH.into(),
if support_changes_trie {
hex!("a998cf2956b526aecc0887903df66457e640bb2debfd7976b5c7696da31cdaef").into()
hex!("df90128fe9ee27bd61d90308cc25ad262e518d4ba09e5077558be2389780d8e5").into()
} else {
hex!("2caffd5fcc42934e6b758613ff0a7e624a8c5b7c67b7c405bf6985a7e3a19701").into()
hex!("3cb0654b6c47c6532108695327fc68e22f2e67a4b20029c3c9d05a285f9e80a2").into()
},
if support_changes_trie {
Some(hex!("1f8f44dcae8982350c14dee720d34b147e73279f5a2ce1f9781195a991970978").into())
vec![changes_trie_log(
hex!("1f8f44dcae8982350c14dee720d34b147e73279f5a2ce1f9781195a991970978").into(),
)]
} else {
None
vec![]
},
vec![
CheckedExtrinsic {
@@ -328,8 +343,14 @@ mod tests {
construct_block(
2,
block1(false).1,
hex!("72b2afc379ce2161aef95ef6f86a2321867f12b046703ea0af5aed158c2a4f30").into(),
None,
hex!("612d3e3c542b4ce62105f2f1fbc4fef1652d5ba38401795115042bee56a50752").into(),
vec![ // session changes here, so we add a grandpa change signal log.
Log::from(::grandpa::RawLog::AuthoritiesChangeSignal(0, vec![
(Keyring::One.to_raw_public().into(), 1),
(Keyring::Two.to_raw_public().into(), 1),
([3u8; 32].into(), 1),
]))
],
vec![
CheckedExtrinsic {
signed: None,
@@ -351,8 +372,8 @@ mod tests {
construct_block(
1,
GENESIS_HASH.into(),
hex!("5f4461c584ce91dd6862313fd075ffc26dc702fcc1183634ee7b0c5de8b5b4d1").into(),
None,
hex!("17df8f360a4a1bd8d5dc23f05b044f5b14ece43555f97d2058ded47d5e7fb64d").into(),
vec![],
vec![
CheckedExtrinsic {
signed: None,
@@ -460,6 +481,14 @@ mod tests {
phase: Phase::Finalization,
event: Event::staking(staking::RawEvent::Reward(0))
},
EventRecord {
phase: Phase::Finalization,
event: Event::grandpa(::grandpa::RawEvent::NewAuthorities(vec![
(Keyring::One.to_raw_public().into(), 1),
(Keyring::Two.to_raw_public().into(), 1),
([3u8; 32].into(), 1),
])),
},
EventRecord {
phase: Phase::Finalization,
event: Event::treasury(treasury::RawEvent::Spending(0))
@@ -633,8 +662,8 @@ mod tests {
let b = construct_block(
1,
GENESIS_HASH.into(),
hex!("9885d4297ce0341ec07957d1de32848460565a17ef2ea400df0e2326634914ae").into(),
None,
hex!("81f45b36d1c8f667ac948bc48f8fb61d12aae87d841b6303ab0320ca906d01d2").into(),
vec![],
vec![
CheckedExtrinsic {
signed: None,
+1 -1
View File
@@ -77,7 +77,7 @@ pub type BlockId = generic::BlockId<Block>;
/// Opaque, encoded, unchecked extrinsic.
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
pub struct UncheckedExtrinsic(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl traits::Extrinsic for UncheckedExtrinsic {
+2
View File
@@ -23,6 +23,7 @@ srml-contract = { path = "../../srml/contract" }
srml-council = { path = "../../srml/council" }
srml-democracy = { path = "../../srml/democracy" }
srml-executive = { path = "../../srml/executive" }
srml-grandpa = { path = "../../srml/grandpa" }
sr-primitives = { path = "../../core/sr-primitives" }
srml-session = { path = "../../srml/session" }
srml-staking = { path = "../../srml/staking" }
@@ -46,6 +47,7 @@ std = [
"srml-council/std",
"srml-democracy/std",
"srml-executive/std",
"srml-grandpa/std",
"sr-primitives/std",
"srml-session/std",
"srml-staking/std",
+26 -10
View File
@@ -47,6 +47,7 @@ extern crate srml_contract as contract;
extern crate srml_council as council;
extern crate srml_democracy as democracy;
extern crate srml_executive as executive;
extern crate srml_grandpa as grandpa;
extern crate srml_session as session;
extern crate srml_staking as staking;
extern crate srml_system as system;
@@ -56,7 +57,6 @@ extern crate srml_upgrade_key as upgrade_key;
#[macro_use]
extern crate sr_version as version;
extern crate node_primitives;
extern crate substrate_finality_grandpa_primitives;
#[cfg(feature = "std")]
use codec::{Encode, Decode};
@@ -65,6 +65,7 @@ use substrate_primitives::u32_trait::{_2, _4};
use node_primitives::{
AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature
};
use grandpa::fg_primitives::{runtime::GrandpaApi, ScheduledChange, id::*};
#[cfg(feature = "std")]
use node_primitives::Block as GBlock;
use client::{block_builder::api::runtime::*, runtime_api::{runtime::*, id::*}};
@@ -85,7 +86,6 @@ use council::seats as council_seats;
#[cfg(any(feature = "std", test))]
use version::NativeVersion;
use substrate_primitives::OpaqueMetadata;
use substrate_finality_grandpa_primitives::{runtime::GrandpaApi, ScheduledChange};
#[cfg(any(feature = "std", test))]
pub use runtime_primitives::BuildStorage;
@@ -109,7 +109,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
apis: apis_vec!([
(BLOCK_BUILDER, 1),
(TAGGED_TRANSACTION_QUEUE, 1),
(METADATA, 1)
(METADATA, 1),
(GRANDPA_API, 1),
]),
};
@@ -165,7 +166,7 @@ impl Convert<AccountId, SessionKey> for SessionKeyConversion {
impl session::Trait for Runtime {
type ConvertAccountIdToSessionKey = SessionKeyConversion;
type OnSessionChange = Staking;
type OnSessionChange = (Staking, grandpa::SyncedAuthorities<Runtime>);
type Event = Event;
}
@@ -209,6 +210,12 @@ impl upgrade_key::Trait for Runtime {
type Event = Event;
}
impl grandpa::Trait for Runtime {
type SessionKey = SessionKey;
type Log = Log;
type Event = Event;
}
construct_runtime!(
pub enum Runtime with Log(InternalLog: DigestItem<Hash, SessionKey>) where
Block = Block,
@@ -225,6 +232,7 @@ construct_runtime!(
CouncilVoting: council_voting,
CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin},
CouncilSeats: council_seats::{Config<T>},
Grandpa: grandpa::{Module, Storage, Config<T>, Log(), Event<T>},
Treasury: treasury,
Contract: contract::{Module, Call, Config<T>, Event<T>},
UpgradeKey: upgrade_key,
@@ -463,15 +471,23 @@ impl_runtime_apis! {
}
}
impl GrandpaApi<Block> for ClientWithApi {
fn grandpa_pending_change(_digest: DigestFor<Block>)
-> Option<ScheduledChange<NumberFor<Block>>> {
unimplemented!("Robert, where is the impl?")
impl GrandpaApi<Block> for Runtime {
fn grandpa_pending_change(digest: DigestFor<Block>)
-> Option<ScheduledChange<NumberFor<Block>>>
{
for log in digest.logs.iter().filter_map(|l| match l {
Log(InternalLog::grandpa(grandpa_signal)) => Some(grandpa_signal),
_=> None
}) {
if let Some(change) = Grandpa::scrape_digest_change(log) {
return Some(change);
}
}
None
}
fn grandpa_authorities() -> Vec<(SessionKey, u64)> {
unimplemented!("Robert, where is the impl?")
Grandpa::grandpa_authorities()
}
}
}
+20 -1
View File
@@ -513,6 +513,7 @@ dependencies = [
"srml-council 0.1.0",
"srml-democracy 0.1.0",
"srml-executive 0.1.0",
"srml-grandpa 0.1.0",
"srml-session 0.1.0",
"srml-staking 0.1.0",
"srml-support 0.1.0",
@@ -521,7 +522,6 @@ dependencies = [
"srml-treasury 0.1.0",
"srml-upgrade-key 0.1.0",
"substrate-client 0.1.0",
"substrate-finality-grandpa-primitives 0.1.0",
"substrate-primitives 0.1.0",
]
@@ -1061,6 +1061,25 @@ dependencies = [
"srml-system 0.1.0",
]
[[package]]
name = "srml-grandpa"
version = "0.1.0"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0",
"sr-primitives 0.1.0",
"sr-std 0.1.0",
"srml-session 0.1.0",
"srml-support 0.1.0",
"srml-system 0.1.0",
"substrate-finality-grandpa-primitives 0.1.0",
"substrate-primitives 0.1.0",
]
[[package]]
name = "srml-metadata"
version = "0.1.0"
+3 -3
View File
@@ -12,7 +12,6 @@ safe-mix = { version = "1.0", default-features = false }
parity-codec-derive = { version = "2.1" }
parity-codec = { version = "2.1", default-features = false }
substrate-primitives = { path = "../../../core/primitives", default-features = false }
substrate-finality-grandpa-primitives = { path = "../../../core/finality-grandpa/primitives", default-features = false }
substrate-client = { path = "../../../core/client", default-features = false }
sr-std = { path = "../../../core/sr-std", default-features = false }
srml-support = { path = "../../../srml/support", default-features = false }
@@ -29,6 +28,7 @@ srml-system = { path = "../../../srml/system", default-features = false }
srml-timestamp = { path = "../../../srml/timestamp", default-features = false }
srml-treasury = { path = "../../../srml/treasury", default-features = false }
srml-upgrade-key = { path = "../../../srml/upgrade-key", default-features = false }
srml-grandpa = { path = "../../../srml/grandpa", default-features = false }
sr-version = { path = "../../../core/sr-version", default-features = false }
node-primitives = { path = "../../primitives", default-features = false }
@@ -39,8 +39,8 @@ std = [
"parity-codec/std",
"substrate-primitives/std",
"substrate-client/std",
"substrate-finality-grandpa-primitives/std",
"sr-std/std",
"sr-primitives/std",
"srml-support/std",
"srml-balances/std",
"srml-consensus/std",
@@ -48,13 +48,13 @@ std = [
"srml-council/std",
"srml-democracy/std",
"srml-executive/std",
"sr-primitives/std",
"srml-session/std",
"srml-staking/std",
"srml-system/std",
"srml-timestamp/std",
"srml-treasury/std",
"srml-upgrade-key/std",
"srml-grandpa/std",
"sr-version/std",
"node-primitives/std",
]
+1 -1
View File
@@ -273,7 +273,7 @@ decl_storage! {
}
/// Whatever happened about the hint given when creating the new account.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", derive(Debug))]
#[derive(Encode, Decode, PartialEq, Eq, Clone, Copy)]
pub enum NewAccountOutcome {
NoHint,
+1 -1
View File
@@ -29,7 +29,7 @@ impl_outer_origin!{
}
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Runtime;
impl system::Trait for Runtime {
type Origin = Origin;
+1 -1
View File
@@ -75,7 +75,7 @@ pub type Log<T> = RawLog<
>;
/// A logs in this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<SessionKey> {
/// Authorities set has been changed. Contains the new set of authorities.
+1 -1
View File
@@ -28,7 +28,7 @@ impl_outer_origin!{
}
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Test;
impl Trait for Test {
const NOTE_OFFLINE_POSITION: u32 = 1;
+1 -1
View File
@@ -75,7 +75,7 @@ mod tests {
}
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Test;
impl system::Trait for Test {
type Origin = Origin;
+1 -1
View File
@@ -322,7 +322,7 @@ mod tests {
}
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Test;
impl system::Trait for Test {
type Origin = Origin;
+35
View File
@@ -0,0 +1,35 @@
[package]
name = "srml-grandpa"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default-features = false }
serde_derive = { version = "1.0", optional = true }
parity-codec = { version = "2.1", default-features = false }
parity-codec-derive = { version = "2.1", default-features = false }
substrate-primitives = { path = "../../core/primitives", default-features = false }
substrate-finality-grandpa-primitives = { path = "../../core/finality-grandpa/primitives", default-features = false }
sr-std = { path = "../../core/sr-std", default-features = false }
sr-io = { path = "../../core/sr-io", default-features = false }
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
srml-support = { path = "../support", default-features = false }
srml-system = { path = "../system", default-features = false }
srml-session = { path = "../session", default-features = false }
[features]
default = ["std"]
std = [
"serde/std",
"serde_derive",
"parity-codec/std",
"substrate-primitives/std",
"substrate-finality-grandpa-primitives/std",
"sr-std/std",
"sr-io/std",
"srml-support/std",
"sr-primitives/std",
"srml-system/std",
"srml-session/std",
]
+303
View File
@@ -0,0 +1,303 @@
// Copyright 2017-2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
//! GRANDPA Consensus module for runtime.
//!
//! This manages the GRANDPA authority set ready for the native code.
//! These authorities are only for GRANDPA finality, not for consensus overall.
//!
//! In the future, it will also handle misbehavior reports, and on-chain
//! finality notifications.
//!
//! For full integration with GRANDPA, the `GrandpaApi` should be implemented.
//! The necessary items are re-exported via the `fg_primitives` crate.
#![cfg_attr(not(feature = "std"), no_std)]
#[allow(unused_imports)]
#[macro_use]
extern crate sr_std as rstd;
#[macro_use]
extern crate srml_support as runtime_support;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
extern crate parity_codec;
#[macro_use]
extern crate parity_codec_derive;
extern crate sr_primitives as primitives;
extern crate parity_codec as codec;
extern crate srml_system as system;
extern crate srml_session as session;
extern crate substrate_primitives;
#[cfg(test)]
extern crate sr_io as runtime_io;
// re-export since this is necessary for `impl_apis` in runtime.
pub extern crate substrate_finality_grandpa_primitives as fg_primitives;
use rstd::prelude::*;
use fg_primitives::ScheduledChange;
use runtime_support::Parameter;
use runtime_support::dispatch::Result;
use runtime_support::storage::StorageValue;
use runtime_support::storage::unhashed::StorageVec;
use primitives::traits::{CurrentHeight, Convert};
use substrate_primitives::AuthorityId;
use system::ensure_signed;
#[cfg(feature = "std")]
use primitives::traits::MaybeSerializeDebug;
#[cfg(not(feature = "std"))]
use primitives::traits::MaybeSerializeDebugButNotDeserialize;
mod mock;
mod tests;
struct AuthorityStorageVec<S: codec::Codec + Default>(rstd::marker::PhantomData<S>);
impl<S: codec::Codec + Default> StorageVec for AuthorityStorageVec<S> {
type Item = (S, u64);
const PREFIX: &'static [u8] = ::fg_primitives::well_known_keys::AUTHORITY_PREFIX;
}
/// The log type of this crate, projected from module trait type.
pub type Log<T> = RawLog<
<T as system::Trait>::BlockNumber,
<T as Trait>::SessionKey,
>;
/// Logs which can be scanned by GRANDPA for authorities change events.
pub trait GrandpaChangeSignal<N> {
/// Try to cast the log entry as a contained signal.
fn as_signal(&self) -> Option<ScheduledChange<N>>;
}
/// A logs in this module.
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<N, SessionKey> {
/// Authorities set change has been signalled. Contains the new set of authorities
/// and the delay in blocks before applying.
AuthoritiesChangeSignal(N, Vec<(SessionKey, u64)>),
}
impl<N: Clone, SessionKey> RawLog<N, SessionKey> {
/// Try to cast the log entry as a contained signal.
pub fn as_signal(&self) -> Option<(N, &[(SessionKey, u64)])> {
match *self {
RawLog::AuthoritiesChangeSignal(ref n, ref signal) => Some((n.clone(), signal)),
}
}
}
impl<N, SessionKey> GrandpaChangeSignal<N> for RawLog<N, SessionKey>
where N: Clone, SessionKey: Clone + Into<AuthorityId>,
{
fn as_signal(&self) -> Option<ScheduledChange<N>> {
RawLog::as_signal(self).map(|(delay, next_authorities)| ScheduledChange {
delay,
next_authorities: next_authorities.iter()
.cloned()
.map(|(k, w)| (k.into(), w))
.collect(),
})
}
}
pub trait Trait: system::Trait {
/// Type for all log entries of this module.
type Log: From<Log<Self>> + Into<system::DigestItemOf<Self>>;
/// The session key type used by authorities.
#[cfg(not(feature = "std"))]
type SessionKey: Parameter + Default + MaybeSerializeDebugButNotDeserialize;
/// The session key type used by authorities.
#[cfg(feature = "std")]
type SessionKey: Parameter + Default + MaybeSerializeDebug;
/// The event type of this module.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
/// A stored pending change.
#[derive(Encode, Decode)]
pub struct StoredPendingChange<N, SessionKey> {
/// The block number this was scheduled at.
pub scheduled_at: N,
/// The delay in blocks until it will be applied.
pub delay: N,
/// The next authority set.
pub next_authorities: Vec<(SessionKey, u64)>,
}
/// GRANDPA events.
decl_event!(
pub enum Event<T> where <T as Trait>::SessionKey {
/// New authority set has been applied.
NewAuthorities(Vec<(SessionKey, u64)>),
}
);
decl_storage! {
trait Store for Module<T: Trait> as GrandpaFinality {
// Pending change: (signalled at, scheduled change).
PendingChange get(pending_change): Option<StoredPendingChange<T::BlockNumber, T::SessionKey>>;
}
add_extra_genesis {
config(authorities): Vec<(T::SessionKey, u64)>;
build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, config: &GenesisConfig<T>| {
use codec::{Encode, KeyedVec};
let auth_count = config.authorities.len() as u32;
config.authorities.iter().enumerate().for_each(|(i, v)| {
storage.insert((i as u32).to_keyed_vec(
::fg_primitives::well_known_keys::AUTHORITY_PREFIX),
v.encode()
);
});
storage.insert(
::fg_primitives::well_known_keys::AUTHORITY_COUNT.to_vec(),
auth_count.encode(),
);
});
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn deposit_event() = default;
/// Report some misbehaviour.
fn report_misbehavior(origin, _report: Vec<u8>) -> Result {
ensure_signed(origin)?;
// TODO: https://github.com/paritytech/substrate/issues/1112
Ok(())
}
fn on_finalise(block_number: T::BlockNumber) {
if let Some(pending_change) = <PendingChange<T>>::get() {
if block_number == pending_change.scheduled_at {
Self::deposit_log(RawLog::AuthoritiesChangeSignal(
pending_change.delay,
pending_change.next_authorities.clone(),
));
}
if block_number == pending_change.scheduled_at + pending_change.delay {
Self::deposit_event(
RawEvent::NewAuthorities(pending_change.next_authorities.clone())
);
<AuthorityStorageVec<T::SessionKey>>::set_items(pending_change.next_authorities);
<PendingChange<T>>::kill();
}
}
}
}
}
impl<T: Trait> Module<T> {
/// Get the current set of authorities, along with their respective weights.
pub fn grandpa_authorities() -> Vec<(T::SessionKey, u64)> {
<AuthorityStorageVec<T::SessionKey>>::items()
}
/// Schedule a change in the authorities.
///
/// The change will be applied at the end of execution of the block
/// `in_blocks` after the current block. This value may be 0, in which
/// case the change is applied at the end of the current block.
///
/// No change should be signalled while any change is pending. Returns
/// an error if a change is already pending.
pub fn schedule_change(
next_authorities: Vec<(T::SessionKey, u64)>,
in_blocks: T::BlockNumber,
) -> Result {
if Self::pending_change().is_none() {
let scheduled_at = system::ChainContext::<T>::default().current_height();
<PendingChange<T>>::put(StoredPendingChange {
delay: in_blocks,
scheduled_at,
next_authorities,
});
Ok(())
} else {
Err("Attempt to signal GRANDPA change with one already pending.")
}
}
/// Deposit one of this module's logs.
fn deposit_log(log: Log<T>) {
<system::Module<T>>::deposit_log(<T as Trait>::Log::from(log).into());
}
}
impl<T: Trait> Module<T> where AuthorityId: core::convert::From<<T as Trait>::SessionKey> {
/// See if the digest contains any scheduled change.
pub fn scrape_digest_change(log: &Log<T>)
-> Option<ScheduledChange<T::BlockNumber>>
{
<Log<T> as GrandpaChangeSignal<T::BlockNumber>>::as_signal(log)
}
}
/// Helper for authorities being synchronized with the general session authorities.
///
/// This is not the only way to manage an authority set for GRANDPA, but it is
/// a convenient one. When this is used, no other mechanism for altering authority
/// sets should be.
pub struct SyncedAuthorities<T>(::rstd::marker::PhantomData<T>);
// TODO: remove when https://github.com/rust-lang/rust/issues/26925 is fixed
impl<T> Default for SyncedAuthorities<T> {
fn default() -> Self {
SyncedAuthorities(::rstd::marker::PhantomData)
}
}
impl<X, T> session::OnSessionChange<X> for SyncedAuthorities<T> where
T: Trait,
T: session::Trait,
<T as session::Trait>::ConvertAccountIdToSessionKey: Convert<
<T as system::Trait>::AccountId,
<T as Trait>::SessionKey,
>,
{
fn on_session_change(_: X, _: bool) {
use primitives::traits::Zero;
let next_authorities = <session::Module<T>>::validators()
.into_iter()
.map(T::ConvertAccountIdToSessionKey::convert)
.map(|key| (key, 1)) // evenly-weighted.
.collect::<Vec<(<T as Trait>::SessionKey, u64)>>();
// instant changes
let last_authorities = <Module<T>>::grandpa_authorities();
if next_authorities != last_authorities {
let _ = <Module<T>>::schedule_change(next_authorities, Zero::zero());
}
}
}
+79
View File
@@ -0,0 +1,79 @@
// Copyright 2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Test utilities
#![cfg(test)]
use primitives::{BuildStorage, testing::{Digest, DigestItem, Header}};
use primitives::generic::DigestItem as GenDigestItem;
use runtime_io;
use substrate_primitives::{H256, Blake2Hasher};
use parity_codec::Encode;
use {system, GenesisConfig, Trait, Module, RawLog};
impl_outer_origin!{
pub enum Origin for Test {}
}
impl From<RawLog<u64, u64>> for DigestItem {
fn from(log: RawLog<u64, u64>) -> DigestItem {
GenDigestItem::Other(log.encode())
}
}
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Debug, Decode, Encode)]
pub struct Test;
impl Trait for Test {
type Log = DigestItem;
type SessionKey = u64;
type Event = TestEvent;
}
impl system::Trait for Test {
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = ::primitives::traits::BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
type Event = TestEvent;
type Log = DigestItem;
}
mod grandpa {
pub use ::Event;
}
impl_outer_event!{
pub enum TestEvent for Test {
grandpa<T>,
}
}
pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities<Blake2Hasher> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
t.extend(GenesisConfig::<Test> {
_genesis_phantom_data: Default::default(),
authorities,
}.build_storage().unwrap().0);
t.into()
}
pub type System = system::Module<Test>;
pub type Grandpa = Module<Test>;
+108
View File
@@ -0,0 +1,108 @@
// Copyright 2017-2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Tests for the module.
#![cfg(test)]
use primitives::{testing, traits::OnFinalise};
use primitives::traits::Header;
use runtime_io::with_externalities;
use mock::{Grandpa, System, new_test_ext};
use system::{EventRecord, Phase};
use {RawLog, RawEvent};
#[test]
fn authorities_change_logged() {
with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || {
System::initialise(&1, &Default::default(), &Default::default());
Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 0).unwrap();
System::note_finished_extrinsics();
Grandpa::on_finalise(1);
let header = System::finalise();
assert_eq!(header.digest, testing::Digest {
logs: vec![
RawLog::AuthoritiesChangeSignal(0, vec![(4, 1), (5, 1), (6, 1)]).into(),
],
});
assert_eq!(System::events(), vec![
EventRecord {
phase: Phase::Finalization,
event: RawEvent::NewAuthorities(vec![(4, 1), (5, 1), (6, 1)]).into(),
},
]);
});
}
#[test]
fn authorities_change_logged_after_delay() {
with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || {
System::initialise(&1, &Default::default(), &Default::default());
Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 1).unwrap();
Grandpa::on_finalise(1);
let header = System::finalise();
assert_eq!(header.digest, testing::Digest {
logs: vec![
RawLog::AuthoritiesChangeSignal(1, vec![(4, 1), (5, 1), (6, 1)]).into(),
],
});
// no change at this height.
assert_eq!(System::events(), vec![]);
System::initialise(&2, &header.hash(), &Default::default());
System::note_finished_extrinsics();
Grandpa::on_finalise(2);
let _header = System::finalise();
assert_eq!(System::events(), vec![
EventRecord {
phase: Phase::Finalization,
event: RawEvent::NewAuthorities(vec![(4, 1), (5, 1), (6, 1)]).into(),
},
]);
});
}
#[test]
fn cannot_schedule_change_when_one_pending() {
with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || {
System::initialise(&1, &Default::default(), &Default::default());
Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 1).unwrap();
assert!(Grandpa::pending_change().is_some());
assert!(Grandpa::schedule_change(vec![(5, 1)], 1).is_err());
Grandpa::on_finalise(1);
let header = System::finalise();
System::initialise(&2, &header.hash(), &Default::default());
assert!(Grandpa::pending_change().is_some());
assert!(Grandpa::schedule_change(vec![(5, 1)], 1).is_err());
Grandpa::on_finalise(2);
let header = System::finalise();
System::initialise(&3, &header.hash(), &Default::default());
assert!(Grandpa::pending_change().is_none());
assert!(Grandpa::schedule_change(vec![(5, 1)], 1).is_ok());
Grandpa::on_finalise(3);
let _header = System::finalise();
});
}
+9
View File
@@ -55,6 +55,15 @@ impl<T> OnSessionChange<T> for () {
fn on_session_change(_: T, _: bool) {}
}
impl<T, A, B> OnSessionChange<T> for (A, B)
where T: Clone, A: OnSessionChange<T>, B: OnSessionChange<T>
{
fn on_session_change(time_elapsed: T, should_reward: bool) {
A::on_session_change(time_elapsed.clone(), should_reward);
B::on_session_change(time_elapsed, should_reward);
}
}
pub trait Trait: timestamp::Trait {
type ConvertAccountIdToSessionKey: Convert<Self::AccountId, Self::SessionKey>;
type OnSessionChange: OnSessionChange<Self::Moment>;
+1 -1
View File
@@ -30,7 +30,7 @@ impl_outer_origin!{
}
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Test;
impl consensus::Trait for Test {
const NOTE_OFFLINE_POSITION: u32 = 1;
+3
View File
@@ -56,6 +56,9 @@ impl<T> Parameter for T where T: Codec + Clone + Eq {}
/// Declare a struct for this module, then implement dispatch logic to create a pairing of several
/// dispatch traits and enums.
///
/// The `on_finalise` function is special, since it can either take no parameters,
/// or one parameter, which has the runtime's block number type.
#[macro_export]
macro_rules! decl_module {
(
+1 -1
View File
@@ -197,7 +197,7 @@ mod tests {
type EventModule = event_module::Module<TestRuntime>;
type EventModule2 = event_module2::Module<TestRuntime>;
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct TestRuntime;
impl_outer_event! {
@@ -622,8 +622,8 @@ macro_rules! __generate_genesis_config {
// final build storage call
[$call:expr]
) => {
#[derive(Serialize, Deserialize)]
#[cfg(feature = "std")]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<$traitinstance: $traittype> {
+1 -1
View File
@@ -154,7 +154,7 @@ pub type Log<T> = RawLog<
>;
/// A logs in this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<Hash> {
/// Changes trie has been computed for this block. Contains the root of