ChainSpec extensions (#3692)

* Add some chainspec tests and make sure we validate it.

* Manual implementation of Extension + Forks definitions.

* Move chain spec to separate crate.

* Allow using ChainSpec with extensions.

* Renames.

* Implement Extension derive.

* Implement Extension for Forks.

* Support specifying fork blocks.

* make for_blocks work

* Support forks correctly.

* Add a bunch of docs.

* Make fork blocks optional.

* Add missing docs.

* Fix build.

* Use struct for check_block params.

* Fix tests?

* Clean up.
This commit is contained in:
Tomasz Drwięga
2019-09-28 19:05:36 +02:00
committed by Gavin Wood
parent c555b9bf88
commit 667ee95f5d
39 changed files with 1368 additions and 336 deletions
+95 -68
View File
@@ -285,7 +285,7 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -357,7 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -522,7 +522,7 @@ dependencies = [
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -627,7 +627,7 @@ dependencies = [
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -797,7 +797,7 @@ name = "erased-serde"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1377,7 +1377,7 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1385,7 +1385,7 @@ name = "impl-serde"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1459,7 +1459,7 @@ dependencies = [
"jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1473,7 +1473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1519,7 +1519,7 @@ dependencies = [
"jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2354,6 +2354,7 @@ dependencies = [
"node-runtime 2.0.0",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"srml-authority-discovery 0.1.0",
@@ -2368,6 +2369,7 @@ dependencies = [
"structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-authority-discovery 2.0.0",
"substrate-basic-authorship 2.0.0",
"substrate-chain-spec 2.0.0",
"substrate-cli 2.0.0",
"substrate-client 2.0.0",
"substrate-client-db 2.0.0",
@@ -2426,7 +2428,7 @@ version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-client 2.0.0",
@@ -2448,7 +2450,7 @@ dependencies = [
"node-runtime 2.0.0",
"node-testing 2.0.0",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"substrate-client 2.0.0",
"substrate-keyring 2.0.0",
@@ -2479,7 +2481,7 @@ dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
"sr-std 2.0.0",
@@ -2554,7 +2556,7 @@ version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -2762,7 +2764,7 @@ dependencies = [
"data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2790,7 +2792,7 @@ dependencies = [
"bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3611,7 +3613,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3626,7 +3628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.97"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3649,7 +3651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3743,7 +3745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3870,7 +3872,7 @@ dependencies = [
"paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-std 2.0.0",
@@ -3913,7 +3915,7 @@ version = "2.0.0"
dependencies = [
"impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
]
@@ -3923,7 +3925,7 @@ name = "srml-assets"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -3939,7 +3941,7 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -3958,7 +3960,7 @@ name = "srml-authority-discovery"
version = "0.1.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
@@ -3994,7 +3996,7 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
@@ -4016,7 +4018,7 @@ version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4033,7 +4035,7 @@ dependencies = [
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4053,7 +4055,7 @@ dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-sandbox 2.0.0",
@@ -4073,7 +4075,7 @@ version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4090,7 +4092,7 @@ dependencies = [
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4106,7 +4108,7 @@ version = "2.0.0"
dependencies = [
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4122,7 +4124,7 @@ name = "srml-example"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4138,7 +4140,7 @@ version = "2.0.0"
dependencies = [
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4155,7 +4157,7 @@ version = "2.0.0"
dependencies = [
"impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4170,7 +4172,7 @@ name = "srml-generic-asset"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4184,7 +4186,7 @@ name = "srml-grandpa"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
@@ -4202,7 +4204,7 @@ name = "srml-im-online"
version = "0.1.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
@@ -4222,7 +4224,7 @@ dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4237,7 +4239,7 @@ name = "srml-membership"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4251,7 +4253,7 @@ name = "srml-metadata"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
]
@@ -4261,7 +4263,7 @@ name = "srml-offences"
version = "1.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
@@ -4277,7 +4279,7 @@ name = "srml-scored-pool"
version = "1.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4295,7 +4297,7 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
@@ -4314,7 +4316,7 @@ version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-staking-primitives 2.0.0",
@@ -4347,7 +4349,7 @@ name = "srml-sudo"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4366,7 +4368,7 @@ dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4414,7 +4416,7 @@ version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"srml-support 2.0.0",
"substrate-inherents 2.0.0",
@@ -4430,7 +4432,7 @@ dependencies = [
"impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4445,7 +4447,7 @@ version = "2.0.0"
dependencies = [
"impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4460,7 +4462,7 @@ name = "srml-treasury"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4577,7 +4579,7 @@ name = "substrate-application-crypto"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -4648,6 +4650,30 @@ dependencies = [
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "substrate-chain-spec"
version = "2.0.0"
dependencies = [
"impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"substrate-chain-spec-derive 2.0.0",
"substrate-network 2.0.0",
"substrate-primitives 2.0.0",
"substrate-telemetry 2.0.0",
]
[[package]]
name = "substrate-chain-spec-derive"
version = "2.0.0"
dependencies = [
"proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "substrate-cli"
version = "2.0.0"
@@ -5009,7 +5035,7 @@ name = "substrate-finality-grandpa-primitives"
version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-application-crypto 2.0.0",
@@ -5077,7 +5103,7 @@ dependencies = [
"quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -5193,7 +5219,7 @@ dependencies = [
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
"substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -5248,7 +5274,7 @@ dependencies = [
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-version 2.0.0",
"substrate-primitives 2.0.0",
@@ -5260,7 +5286,7 @@ dependencies = [
name = "substrate-rpc-primitives"
version = "2.0.0"
dependencies = [
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-primitives 2.0.0",
]
@@ -5273,7 +5299,7 @@ dependencies = [
"jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
]
@@ -5294,7 +5320,7 @@ dependencies = [
name = "substrate-serializer"
version = "2.0.0"
dependencies = [
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -5314,7 +5340,7 @@ dependencies = [
"parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
@@ -5322,6 +5348,7 @@ dependencies = [
"substrate-application-crypto 2.0.0",
"substrate-authority-discovery 2.0.0",
"substrate-authority-discovery-primitives 2.0.0",
"substrate-chain-spec 2.0.0",
"substrate-client 2.0.0",
"substrate-client-db 2.0.0",
"substrate-consensus-babe-primitives 2.0.0",
@@ -5414,7 +5441,7 @@ dependencies = [
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"slog-async 2.3.0 (git+https://github.com/paritytech/slog-async)",
"slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -5448,7 +5475,7 @@ dependencies = [
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
"sr-primitives 2.0.0",
"sr-std 2.0.0",
@@ -5497,7 +5524,7 @@ dependencies = [
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"substrate-primitives 2.0.0",
"substrate-test-runtime 2.0.0",
@@ -5711,7 +5738,7 @@ name = "tinytemplate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -5933,7 +5960,7 @@ name = "toml"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -6011,7 +6038,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -6186,7 +6213,7 @@ name = "wabt"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -6881,7 +6908,7 @@ dependencies = [
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4"
"checksum serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "d46b3dfedb19360a74316866cef04687cd4d6a70df8e6a506c63512790769b72"
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
"checksum serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "c22a0820adfe2f257b098714323563dd06426502abbbce4f51b72ef544c5027f"
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
+2
View File
@@ -21,6 +21,8 @@ vergen = "3"
members = [
"core/authority-discovery",
"core/application-crypto",
"core/chain-spec",
"core/chain-spec/derive",
"core/cli",
"core/client",
"core/client/db",
+17
View File
@@ -0,0 +1,17 @@
[package]
name = "substrate-chain-spec"
version = "2.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
chain-spec-derive = { package = "substrate-chain-spec-derive", path = "./derive" }
impl-trait-for-tuples = "0.1.1"
network = { package = "substrate-network", path = "../../core/network" }
primitives = { package = "substrate-primitives", path = "../primitives" }
serde = { version = "1.0.101", features = ["derive"] }
serde_json = "1.0.40"
sr-primitives = { path = "../../core/sr-primitives" }
tel = { package = "substrate-telemetry", path = "../../core/telemetry" }
[dev-dependencies]
@@ -0,0 +1,17 @@
[package]
name = "substrate-chain-spec-derive"
version = "2.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[lib]
proc-macro = true
[dependencies]
proc-macro-crate = "0.1.3"
proc-macro2 = "1.0.1"
quote = "1.0.2"
syn = "1.0.5"
[dev-dependencies]
@@ -0,0 +1,191 @@
// Copyright 2019 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 proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{DeriveInput, Ident, Error};
use proc_macro_crate::crate_name;
const CRATE_NAME: &str = "substrate-chain-spec";
const ATTRIBUTE_NAME: &str = "forks";
/// Implements `Extension's` `Group` accessor.
///
/// The struct that derives this implementation will be usable within the `ChainSpec` file.
/// The derive implements a by-type accessor method.
pub fn extension_derive(ast: &DeriveInput) -> proc_macro::TokenStream {
derive(ast, |crate_name, name, generics: &syn::Generics, field_names, field_types, fields| {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let forks = fields.named.iter().find_map(|f| {
if f.attrs.iter().any(|attr| attr.path.is_ident(ATTRIBUTE_NAME)) {
let typ = &f.ty;
Some(quote! { #typ })
} else {
None
}
}).unwrap_or_else(|| quote! { #crate_name::NoExtension });
quote! {
impl #impl_generics #crate_name::Extension for #name #ty_generics #where_clause {
type Forks = #forks;
fn get<T: 'static>(&self) -> Option<&T> {
use std::any::{Any, TypeId};
match TypeId::of::<T>() {
#( x if x == TypeId::of::<#field_types>() => Any::downcast_ref(&self.#field_names) ),*,
_ => None,
}
}
}
}
})
}
/// Implements required traits and creates `Fork` structs for `ChainSpec` custom parameter group.
pub fn group_derive(ast: &DeriveInput) -> proc_macro::TokenStream {
derive(ast, |crate_name, name, generics: &syn::Generics, field_names, field_types, _fields| {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let fork_name = Ident::new(&format!("{}Fork", name), Span::call_site());
let fork_fields = generate_fork_fields(&crate_name, &field_names, &field_types);
let to_fork = generate_base_to_fork(&fork_name, &field_names);
let combine_with = generate_combine_with(&field_names);
let to_base = generate_fork_to_base(name, &field_names);
quote! {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)]
pub struct #fork_name #ty_generics #where_clause {
#fork_fields
}
impl #impl_generics #crate_name::Group for #name #ty_generics #where_clause {
type Fork = #fork_name #ty_generics;
fn to_fork(self) -> Self::Fork {
use #crate_name::Group;
#to_fork
}
}
impl #impl_generics #crate_name::Fork for #fork_name #ty_generics #where_clause {
type Base = #name #ty_generics;
fn combine_with(&mut self, other: Self) {
use #crate_name::Fork;
#combine_with
}
fn to_base(self) -> Option<Self::Base> {
use #crate_name::Fork;
#to_base
}
}
}
})
}
pub fn derive(
ast: &DeriveInput,
derive: impl Fn(
&Ident, &Ident, &syn::Generics, Vec<&Ident>, Vec<&syn::Type>, &syn::FieldsNamed,
) -> TokenStream,
) -> proc_macro::TokenStream {
let err = || {
let err = Error::new(
Span::call_site(),
"ChainSpecGroup is only avaible for structs with named fields."
).to_compile_error();
quote!( #err ).into()
};
let data = match &ast.data {
syn::Data::Struct(ref data) => data,
_ => return err(),
};
let fields = match &data.fields {
syn::Fields::Named(ref named) => named,
_ => return err(),
};
const PROOF: &str = "CARGO_PKG_NAME always defined when compiling; qed";
let name = &ast.ident;
let crate_name = match crate_name(CRATE_NAME) {
Ok(chain_spec_name) => chain_spec_name,
Err(e) => if std::env::var("CARGO_PKG_NAME").expect(PROOF) == CRATE_NAME {
// we return the name of the crate here instead of `crate` to support doc tests.
CRATE_NAME.replace("-", "_")
} else {
let err = Error::new(Span::call_site(), &e).to_compile_error();
return quote!( #err ).into()
},
};
let crate_name = Ident::new(&crate_name, Span::call_site());
let field_names = fields.named.iter().flat_map(|x| x.ident.as_ref()).collect::<Vec<_>>();
let field_types = fields.named.iter().map(|x| &x.ty).collect::<Vec<_>>();
derive(&crate_name, name, &ast.generics, field_names, field_types, fields).into()
}
fn generate_fork_fields(
crate_name: &Ident,
names: &[&Ident],
types: &[&syn::Type],
) -> TokenStream {
let crate_name = std::iter::repeat(crate_name);
quote! {
#( pub #names: Option<<#types as #crate_name::Group>::Fork>, )*
}
}
fn generate_base_to_fork(
fork_name: &Ident,
names: &[&Ident],
) -> TokenStream {
let names2 = names.to_vec();
quote!{
#fork_name {
#( #names: Some(self.#names2.to_fork()), )*
}
}
}
fn generate_combine_with(
names: &[&Ident],
) -> TokenStream {
let names2 = names.to_vec();
quote!{
#( self.#names.combine_with(other.#names2); )*
}
}
fn generate_fork_to_base(
fork: &Ident,
names: &[&Ident],
) -> TokenStream {
let names2 = names.to_vec();
quote!{
Some(#fork {
#( #names: self.#names2?.to_base()?, )*
})
}
}
@@ -0,0 +1,39 @@
// Copyright 2019 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/>.
//! Macros to derive chain spec extension traits implementation.
extern crate proc_macro;
mod impls;
use proc_macro::TokenStream;
#[proc_macro_derive(ChainSpecGroup)]
pub fn group_derive(input: TokenStream) -> TokenStream {
match syn::parse(input) {
Ok(ast) => impls::group_derive(&ast),
Err(e) => e.to_compile_error().into(),
}
}
#[proc_macro_derive(ChainSpecExtension, attributes(forks))]
pub fn extensions_derive(input: TokenStream) -> TokenStream {
match syn::parse(input) {
Ok(ast) => impls::extension_derive(&ast),
Err(e) => e.to_compile_error().into(),
}
}
@@ -0,0 +1,31 @@
{
"name": "Flaming Fir",
"id": "flaming-fir",
"properties": {
"tokenDecimals": 15,
"tokenSymbol": "FIR"
},
"bootNodes": [
"/ip4/35.246.224.91/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV",
"/ip4/35.246.224.91/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV",
"/ip4/35.246.210.11/tcp/30333/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f",
"/ip4/35.246.210.11/tcp/30334/ws/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f",
"/ip4/35.198.110.45/tcp/30333/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ",
"/ip4/35.198.110.45/tcp/30334/ws/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ",
"/ip4/35.198.114.154/tcp/30333/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6",
"/ip4/35.198.114.154/tcp/30334/ws/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6"
],
"telemetryEndpoints": [
["wss://telemetry.polkadot.io/submit/", 0]
],
"protocolId": "fir",
"consensusEngine": null,
"genesis": {
"raw": [
{
"0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"
},
{}
]
}
}
@@ -0,0 +1,32 @@
{
"name": "Flaming Fir",
"id": "flaming-fir",
"properties": {
"tokenDecimals": 15,
"tokenSymbol": "FIR"
},
"bootNodes": [
"/ip4/35.246.224.91/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV",
"/ip4/35.246.224.91/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV",
"/ip4/35.246.210.11/tcp/30333/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f",
"/ip4/35.246.210.11/tcp/30334/ws/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f",
"/ip4/35.198.110.45/tcp/30333/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ",
"/ip4/35.198.110.45/tcp/30334/ws/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ",
"/ip4/35.198.114.154/tcp/30333/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6",
"/ip4/35.198.114.154/tcp/30334/ws/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6"
],
"telemetryEndpoints": [
["wss://telemetry.polkadot.io/submit/", 0]
],
"protocolId": "fir",
"consensusEngine": null,
"myProperty": "Test Extension",
"genesis": {
"raw": [
{
"0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"
},
{}
]
}
}
@@ -53,14 +53,15 @@ impl<G: RuntimeGenesis> GenesisSource<G> {
match self {
GenesisSource::File(path) => {
let file = File::open(path).map_err(|e| format!("Error opening spec file: {}", e))?;
let genesis: GenesisContainer<G> =
json::from_reader(file).map_err(|e| format!("Error parsing spec file: {}", e))?;
let file = File::open(path)
.map_err(|e| format!("Error opening spec file: {}", e))?;
let genesis: GenesisContainer<G> = json::from_reader(file)
.map_err(|e| format!("Error parsing spec file: {}", e))?;
Ok(genesis.genesis)
},
GenesisSource::Binary(buf) => {
let genesis: GenesisContainer<G> =
json::from_reader(buf.as_ref()).map_err(|e| format!("Error parsing embedded file: {}", e))?;
let genesis: GenesisContainer<G> = json::from_reader(buf.as_ref())
.map_err(|e| format!("Error parsing embedded file: {}", e))?;
Ok(genesis.genesis)
},
GenesisSource::Factory(f) => Ok(Genesis::Runtime(f())),
@@ -68,7 +69,7 @@ impl<G: RuntimeGenesis> GenesisSource<G> {
}
}
impl<'a, G: RuntimeGenesis> BuildStorage for &'a ChainSpec<G> {
impl<'a, G: RuntimeGenesis, E> BuildStorage for &'a ChainSpec<G, E> {
fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> {
match self.genesis.resolve()? {
Genesis::Runtime(gc) => gc.build_storage(),
@@ -82,7 +83,10 @@ impl<'a, G: RuntimeGenesis> BuildStorage for &'a ChainSpec<G> {
}
}
fn assimilate_storage(self, _: &mut (StorageOverlay, ChildrenStorageOverlay)) -> Result<(), String> {
fn assimilate_storage(
self,
_: &mut (StorageOverlay, ChildrenStorageOverlay)
) -> Result<(), String> {
Err("`assimilate_storage` not implemented for `ChainSpec`.".into())
}
}
@@ -98,28 +102,39 @@ enum Genesis<G> {
),
}
#[derive(Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
struct ChainSpecFile {
#[serde(deny_unknown_fields)]
struct ChainSpecFile<E> {
pub name: String,
pub id: String,
pub boot_nodes: Vec<String>,
pub telemetry_endpoints: Option<TelemetryEndpoints>,
pub protocol_id: Option<String>,
pub consensus_engine: Option<String>,
pub properties: Option<Properties>,
#[serde(flatten)]
pub extensions: E,
// Never used, left only for backward compatibility.
consensus_engine: (),
#[serde(skip_serializing)]
genesis: serde::de::IgnoredAny,
}
/// Arbitrary properties defined in chain spec as a JSON object
pub type Properties = json::map::Map<String, json::Value>;
/// A type denoting empty extensions.
///
/// We use `Option` here since `()` is not flattenable by serde.
pub type NoExtension = Option<()>;
/// A configuration of a chain. Can be used to build a genesis block.
pub struct ChainSpec<G> {
spec: ChainSpecFile,
pub struct ChainSpec<G, E = NoExtension> {
spec: ChainSpecFile<E>,
genesis: GenesisSource<G>,
}
impl<G> Clone for ChainSpec<G> {
impl<G, E: Clone> Clone for ChainSpec<G, E> {
fn clone(&self) -> Self {
ChainSpec {
spec: self.spec.clone(),
@@ -128,7 +143,7 @@ impl<G> Clone for ChainSpec<G> {
}
}
impl<G> ChainSpec<G> {
impl<G, E> ChainSpec<G, E> {
/// A list of bootnode addresses.
pub fn boot_nodes(&self) -> &[String] {
&self.spec.boot_nodes
@@ -154,14 +169,10 @@ impl<G> ChainSpec<G> {
self.spec.protocol_id.as_ref().map(String::as_str)
}
/// Name of the consensus engine.
pub fn consensus_engine(&self) -> Option<&str> {
self.spec.consensus_engine.as_ref().map(String::as_str)
}
/// Additional loosly-typed properties of the chain.
///
/// Returns an empty JSON object if 'properties' not defined in config
pub fn properties(&self) -> Properties {
// Return an empty JSON object if 'properties' not defined in config
self.spec.properties.as_ref().unwrap_or(&json::map::Map::new()).clone()
}
@@ -170,24 +181,9 @@ impl<G> ChainSpec<G> {
self.spec.boot_nodes.push(addr.to_string())
}
/// Parse json content into a `ChainSpec`
pub fn from_json_bytes(json: impl Into<Cow<'static, [u8]>>) -> Result<Self, String> {
let json = json.into();
let spec = json::from_slice(json.as_ref()).map_err(|e| format!("Error parsing spec file: {}", e))?;
Ok(ChainSpec {
spec,
genesis: GenesisSource::Binary(json),
})
}
/// Parse json file into a `ChainSpec`
pub fn from_json_file(path: PathBuf) -> Result<Self, String> {
let file = File::open(&path).map_err(|e| format!("Error opening spec file: {}", e))?;
let spec = json::from_reader(file).map_err(|e| format!("Error parsing spec file: {}", e))?;
Ok(ChainSpec {
spec,
genesis: GenesisSource::File(path),
})
/// Returns a reference to defined chain spec extensions.
pub fn extensions(&self) -> &E {
&self.spec.extensions
}
/// Create hardcoded spec.
@@ -198,19 +194,21 @@ impl<G> ChainSpec<G> {
boot_nodes: Vec<String>,
telemetry_endpoints: Option<TelemetryEndpoints>,
protocol_id: Option<&str>,
consensus_engine: Option<&str>,
properties: Option<Properties>,
) -> Self
{
extensions: E,
) -> Self {
let spec = ChainSpecFile {
name: name.to_owned(),
id: id.to_owned(),
boot_nodes: boot_nodes,
telemetry_endpoints,
protocol_id: protocol_id.map(str::to_owned),
consensus_engine: consensus_engine.map(str::to_owned),
properties,
extensions,
consensus_engine: (),
genesis: Default::default(),
};
ChainSpec {
spec,
genesis: GenesisSource::Factory(constructor),
@@ -218,13 +216,38 @@ impl<G> ChainSpec<G> {
}
}
impl<G: RuntimeGenesis> ChainSpec<G> {
impl<G, E: serde::de::DeserializeOwned> ChainSpec<G, E> {
/// Parse json content into a `ChainSpec`
pub fn from_json_bytes(json: impl Into<Cow<'static, [u8]>>) -> Result<Self, String> {
let json = json.into();
let spec = json::from_slice(json.as_ref())
.map_err(|e| format!("Error parsing spec file: {}", e))?;
Ok(ChainSpec {
spec,
genesis: GenesisSource::Binary(json),
})
}
/// Parse json file into a `ChainSpec`
pub fn from_json_file(path: PathBuf) -> Result<Self, String> {
let file = File::open(&path)
.map_err(|e| format!("Error opening spec file: {}", e))?;
let spec = json::from_reader(file)
.map_err(|e| format!("Error parsing spec file: {}", e))?;
Ok(ChainSpec {
spec,
genesis: GenesisSource::File(path),
})
}
}
impl<G: RuntimeGenesis, E: serde::Serialize> ChainSpec<G, E> {
/// Dump to json string.
pub fn to_json(self, raw: bool) -> Result<String, String> {
#[derive(Serialize, Deserialize)]
struct Container<G> {
struct Container<G, E> {
#[serde(flatten)]
spec: ChainSpecFile,
spec: ChainSpecFile<E>,
genesis: Genesis<G>,
};
@@ -251,6 +274,58 @@ impl<G: RuntimeGenesis> ChainSpec<G> {
spec: self.spec,
genesis,
};
json::to_string_pretty(&spec).map_err(|e| format!("Error generating spec json: {}", e))
json::to_string_pretty(&spec)
.map_err(|e| format!("Error generating spec json: {}", e))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug, Serialize, Deserialize)]
struct Genesis(HashMap<String, String>);
impl BuildStorage for Genesis {
fn assimilate_storage(
self,
storage: &mut (StorageOverlay, ChildrenStorageOverlay),
) -> Result<(), String> {
storage.0.extend(
self.0.into_iter().map(|(a, b)| (a.into_bytes(), b.into_bytes()))
);
Ok(())
}
}
type TestSpec = ChainSpec<Genesis>;
#[test]
fn should_deserailize_example_chain_spec() {
let spec1 = TestSpec::from_json_bytes(Cow::Owned(
include_bytes!("../res/chain_spec.json").to_vec()
)).unwrap();
let spec2 = TestSpec::from_json_file(
PathBuf::from("./res/chain_spec.json")
).unwrap();
assert_eq!(spec1.to_json(false), spec2.to_json(false));
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Extension1 {
my_property: String,
}
type TestSpec2 = ChainSpec<Genesis, Extension1>;
#[test]
fn should_deserialize_chain_spec_with_extensions() {
let spec = TestSpec2::from_json_bytes(Cow::Owned(
include_bytes!("../res/chain_spec2.json").to_vec()
)).unwrap();
assert_eq!(spec.extensions().my_property, "Test Extension");
}
}
+363
View File
@@ -0,0 +1,363 @@
// Copyright 2019 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/>.
//! Chain Spec extensions helpers.
use std::fmt::Debug;
use std::collections::BTreeMap;
use serde::{Serialize, Deserialize, de::DeserializeOwned};
/// A `ChainSpec` extension.
///
/// This trait is implemented automatically by `ChainSpecGroup` macro.
pub trait Group: Clone + Sized {
/// An associated type containing fork definition.
type Fork: Fork<Base=Self>;
/// Convert to fork type.
fn to_fork(self) -> Self::Fork;
}
/// A `ChainSpec` extension fork definition.
///
/// Basically should look the same as `Group`, but
/// all parameters are optional. This allows changing
/// only one parameter as part of the fork.
/// The forks can be combined (summed up) to specify
/// a complete set of parameters
pub trait Fork: Serialize + DeserializeOwned + Clone + Sized {
/// A base `Group` type.
type Base: Group<Fork=Self>;
/// Combine with another struct.
///
/// All parameters set in `other` should override the
/// ones in the current struct.
fn combine_with(&mut self, other: Self);
/// Attempt to convert to the base type if all parameters are set.
fn to_base(self) -> Option<Self::Base>;
}
macro_rules! impl_trivial {
() => {};
($A : ty) => {
impl_trivial!($A ,);
};
($A : ty , $( $B : ty ),*) => {
impl_trivial!($( $B ),*);
impl Group for $A {
type Fork = $A;
fn to_fork(self) -> Self::Fork {
self
}
}
impl Fork for $A {
type Base = $A;
fn combine_with(&mut self, other: Self) {
*self = other;
}
fn to_base(self) -> Option<Self::Base> {
Some(self)
}
}
}
}
impl_trivial!((), u8, u16, u32, u64, usize, String, Vec<u8>);
impl<T: Group> Group for Option<T> {
type Fork = Option<T::Fork>;
fn to_fork(self) -> Self::Fork {
self.map(|a| a.to_fork())
}
}
impl<T: Fork> Fork for Option<T> {
type Base = Option<T::Base>;
fn combine_with(&mut self, other: Self) {
*self = match (self.take(), other) {
(Some(mut a), Some(b)) => {
a.combine_with(b);
Some(a)
},
(a, b) => a.or(b),
};
}
fn to_base(self) -> Option<Self::Base> {
self.map(|x| x.to_base())
}
}
/// A collection of `ChainSpec` extensions.
///
/// This type can be passed around and allows the core
/// modules to request a strongly-typed, but optional configuration.
pub trait Extension: Serialize + DeserializeOwned + Clone {
type Forks: IsForks;
/// Get an extension of specific type.
fn get<T: 'static>(&self) -> Option<&T>;
/// Get forkable extensions of specific type.
fn forks<BlockNumber, T>(&self) -> Option<Forks<BlockNumber, T>> where
BlockNumber: Ord + Clone + 'static,
T: Group + 'static,
<Self::Forks as IsForks>::Extension: Extension,
<<Self::Forks as IsForks>::Extension as Group>::Fork: Extension,
{
self.get::<Forks<BlockNumber, <Self::Forks as IsForks>::Extension>>()?
.for_type()
}
}
impl Extension for crate::NoExtension {
type Forks = Self;
fn get<T: 'static>(&self) -> Option<&T> { None }
}
pub trait IsForks {
type BlockNumber: Ord + 'static;
type Extension: Group + 'static;
}
impl IsForks for Option<()> {
type BlockNumber = u64;
type Extension = Self;
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct Forks<BlockNumber: Ord, T: Group> {
forks: BTreeMap<BlockNumber, T::Fork>,
#[serde(flatten)]
base: T,
}
impl<B: Ord, T: Group + Default> Default for Forks<B, T> {
fn default() -> Self {
Self {
base: Default::default(),
forks: Default::default(),
}
}
}
impl<B: Ord, T: Group> Forks<B, T> where
T::Fork: Debug,
{
/// Create new fork definition given the base and the forks.
pub fn new(base: T, forks: BTreeMap<B, T::Fork>) -> Self {
Self { base, forks }
}
/// Return a set of parameters for `Group` including all forks up to `block` (inclusive).
pub fn at_block(&self, block: B) -> T {
let mut start = self.base.clone().to_fork();
for (_, fork) in self.forks.range(..=block) {
start.combine_with(fork.clone());
}
start
.to_base()
.expect("We start from the `base` object, so it's always fully initialized; qed")
}
}
impl<B, T> IsForks for Forks<B, T> where
B: Ord + 'static,
T: Group + 'static,
{
type BlockNumber = B;
type Extension = T;
}
impl<B: Ord + Clone, T: Group + Extension> Forks<B, T> where
T::Fork: Extension,
{
/// Get forks definition for a subset of this extension.
///
/// Returns the `Forks` struct, but limited to a particular type
/// within the extension.
pub fn for_type<X>(&self) -> Option<Forks<B, X>> where
X: Group + 'static,
{
let base = self.base.get::<X>()?.clone();
let forks = self.forks.iter().filter_map(|(k, v)| {
Some((k.clone(), v.get::<Option<X::Fork>>()?.clone()?))
}).collect();
Some(Forks {
base,
forks,
})
}
}
impl<B, E> Extension for Forks<B, E> where
B: Serialize + DeserializeOwned + Ord + Clone + 'static,
E: Extension + Group + 'static,
{
type Forks = Self;
fn get<T: 'static>(&self) -> Option<&T> {
use std::any::{TypeId, Any};
match TypeId::of::<T>() {
x if x == TypeId::of::<E>() => Any::downcast_ref(&self.base),
_ => self.base.get(),
}
}
fn forks<BlockNumber, T>(&self) -> Option<Forks<BlockNumber, T>> where
BlockNumber: Ord + Clone + 'static,
T: Group + 'static,
<Self::Forks as IsForks>::Extension: Extension,
<<Self::Forks as IsForks>::Extension as Group>::Fork: Extension,
{
use std::any::{TypeId, Any};
if TypeId::of::<BlockNumber>() == TypeId::of::<B>() {
Any::downcast_ref(&self.for_type::<T>()?).cloned()
} else {
self.get::<Forks<BlockNumber, <Self::Forks as IsForks>::Extension>>()?
.for_type()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use chain_spec_derive::{ChainSpecGroup, ChainSpecExtension};
// Make the proc macro work for tests and doc tests.
use crate as substrate_chain_spec;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup)]
#[serde(deny_unknown_fields)]
pub struct Extension1 {
pub test: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup)]
#[serde(deny_unknown_fields)]
pub struct Extension2 {
pub test: u8,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
#[serde(deny_unknown_fields)]
pub struct Extensions {
pub ext1: Extension1,
pub ext2: Extension2,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)]
#[serde(deny_unknown_fields)]
pub struct Ext2 {
#[serde(flatten)]
ext1: Extension1,
#[forks]
forkable: Forks<u64, Extensions>,
}
#[test]
fn forks_should_work_correctly() {
use super::Extension as _ ;
let ext: Ext2 = serde_json::from_str(r#"
{
"test": 11,
"forkable": {
"ext1": {
"test": 15
},
"ext2": {
"test": 123
},
"forks": {
"1": {
"ext1": { "test": 5 }
},
"2": {
"ext2": { "test": 5 }
},
"5": {
"ext2": { "test": 1 }
}
}
}
}
"#).unwrap();
assert_eq!(ext.get::<Extension1>(), Some(&Extension1 {
test: 11
}));
// get forks definition
let forks = ext.get::<Forks<u64, Extensions>>().unwrap();
assert_eq!(forks.at_block(0), Extensions {
ext1: Extension1 { test: 15 },
ext2: Extension2 { test: 123 },
});
assert_eq!(forks.at_block(1), Extensions {
ext1: Extension1 { test: 5 },
ext2: Extension2 { test: 123 },
});
assert_eq!(forks.at_block(2), Extensions {
ext1: Extension1 { test: 5 },
ext2: Extension2 { test: 5 },
});
assert_eq!(forks.at_block(4), Extensions {
ext1: Extension1 { test: 5 },
ext2: Extension2 { test: 5 },
});
assert_eq!(forks.at_block(5), Extensions {
ext1: Extension1 { test: 5 },
ext2: Extension2 { test: 1 },
});
assert_eq!(forks.at_block(10), Extensions {
ext1: Extension1 { test: 5 },
ext2: Extension2 { test: 1 },
});
assert!(forks.at_block(10).get::<Extension2>().is_some());
// filter forks for `Extension2`
let ext2 = forks.for_type::<Extension2>().unwrap();
assert_eq!(ext2.at_block(0), Extension2 { test: 123 });
assert_eq!(ext2.at_block(2), Extension2 { test: 5 });
assert_eq!(ext2.at_block(10), Extension2 { test: 1 });
// make sure that it can return forks correctly
let ext2_2 = forks.forks::<u64, Extension2>().unwrap();
assert_eq!(ext2, ext2_2);
// also ext should be able to return forks correctly:
let ext2_3 = ext.forks::<u64, Extension2>().unwrap();
assert_eq!(ext2_2, ext2_3);
}
}
+124
View File
@@ -0,0 +1,124 @@
// Copyright 2019 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/>.
//! Substrate chain configurations.
//!
//! This crate contains structs and utilities to declare
//! a runtime-specific configuration file (a.k.a chain spec).
//!
//! Basic chain spec type containing all required parameters is
//! [`ChainSpec`](./struct.ChainSpec.html). It can be extended with
//! additional options that contain configuration specific to your chain.
//! Usually the extension is going to be an amalgamate of types exposed
//! by Substrate core modules. To allow the core modules to retrieve
//! their configuration from your extension you should use `ChainSpecExtension`
//! macro exposed by this crate.
//!
//! ```rust
//! use std::collections::HashMap;
//! use serde::{Serialize, Deserialize};
//! use substrate_chain_spec::{ChainSpec, ChainSpecExtension};
//!
//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)]
//! pub struct MyExtension {
//! pub known_blocks: HashMap<u64, String>,
//! }
//!
//! pub type MyChainSpec<G> = ChainSpec<G, MyExtension>;
//! ```
//!
//! Some parameters may require different values depending on the
//! current blockchain height (a.k.a. forks). You can use `ChainSpecGroup`
//! macro and provided [`Forks`](./struct.Forks.html) structure to put
//! such parameters to your chain spec.
//! This will allow to override a single parameter starting at specific
//! block number.
//!
//! ```rust
//! use serde::{Serialize, Deserialize};
//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension};
//!
//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)]
//! pub struct ClientParams {
//! max_block_size: usize,
//! max_extrinsic_size: usize,
//! }
//!
//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)]
//! pub struct PoolParams {
//! max_transaction_size: usize,
//! }
//!
//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
//! pub struct Extension {
//! pub client: ClientParams,
//! pub pool: PoolParams,
//! }
//!
//! pub type BlockNumber = u64;
//!
//! /// A chain spec supporting forkable `ClientParams`.
//! pub type MyChainSpec1<G> = ChainSpec<G, Forks<BlockNumber, ClientParams>>;
//!
//! /// A chain spec supporting forkable `Extension`.
//! pub type MyChainSpec2<G> = ChainSpec<G, Forks<BlockNumber, Extension>>;
//! ```
//!
//! It's also possible to have a set of parameters that is allowed to change
//! with block numbers (i.e. is forkable), and another set that is not subject to changes.
//! This is also possible by declaring an extension that contains `Forks` within it.
//!
//!
//! ```rust
//! use serde::{Serialize, Deserialize};
//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension};
//!
//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)]
//! pub struct ClientParams {
//! max_block_size: usize,
//! max_extrinsic_size: usize,
//! }
//!
//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)]
//! pub struct PoolParams {
//! max_transaction_size: usize,
//! }
//!
//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)]
//! pub struct Extension {
//! pub client: ClientParams,
//! #[forks]
//! pub pool: Forks<u64, PoolParams>,
//! }
//!
//! pub type MyChainSpec<G> = ChainSpec<G, Extension>;
//! ```
mod chain_spec;
mod extension;
pub use chain_spec::{ChainSpec, Properties, NoExtension};
pub use extension::{Group, Fork, Forks, Extension};
pub use chain_spec_derive::{ChainSpecExtension, ChainSpecGroup};
use serde::{Serialize, de::DeserializeOwned};
use sr_primitives::BuildStorage;
/// A set of traits for the runtime genesis config.
pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {}
impl<T: Serialize + DeserializeOwned + BuildStorage> RuntimeGenesis for T {}
+72 -51
View File
@@ -30,11 +30,14 @@ use client::ExecutionStrategies;
use service::{
config::Configuration,
ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert,
RuntimeGenesis, PruningMode, ChainSpec,
RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec,
};
use network::{
self, multiaddr::Protocol,
config::{NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr},
self,
multiaddr::Protocol,
config::{
NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr
},
};
use primitives::H256;
@@ -121,8 +124,10 @@ fn generate_node_name() -> String {
result
}
fn load_spec<F, G>(cli: &SharedParams, factory: F) -> error::Result<ChainSpec<G>>
where G: RuntimeGenesis, F: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
fn load_spec<F, G, E>(cli: &SharedParams, factory: F) -> error::Result<ChainSpec<G, E>> where
G: RuntimeGenesis,
E: ChainSpecExtension,
F: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
{
let chain_key = get_chain_key(cli);
let spec = match factory(&chain_key)? {
@@ -263,20 +268,23 @@ pub struct ParseAndPrepareRun<'a, RP> {
impl<'a, RP> ParseAndPrepareRun<'a, RP> {
/// Runs the command and runs the main client.
pub fn run<C, G, S, E, RS>(
pub fn run<C, G, E, S, Exit, RS>(
self,
spec_factory: S,
exit: E,
exit: Exit,
run_service: RS,
) -> error::Result<()>
where S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
where S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
RP: StructOpt + Clone,
C: Default,
G: RuntimeGenesis,
E: IntoExit,
RS: FnOnce(E, RunCmd, RP, Configuration<C, G>) -> Result<(), String>
E: ChainSpecExtension,
Exit: IntoExit,
RS: FnOnce(Exit, RunCmd, RP, Configuration<C, G, E>) -> Result<(), String>
{
let config = create_run_node_config(self.params.left.clone(), spec_factory, self.impl_name, self.version)?;
let config = create_run_node_config(
self.params.left.clone(), spec_factory, self.impl_name, self.version
)?;
run_service(exit, self.params.left, self.params.right, config).map_err(Into::into)
}
@@ -290,12 +298,13 @@ pub struct ParseAndPrepareBuildSpec<'a> {
impl<'a> ParseAndPrepareBuildSpec<'a> {
/// Runs the command and build the chain specs.
pub fn run<G, S>(
pub fn run<G, S, E>(
self,
spec_factory: S
) -> error::Result<()>
where S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
G: RuntimeGenesis
) -> error::Result<()> where
S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
G: RuntimeGenesis,
E: ChainSpecExtension,
{
info!("Building chain spec");
let raw_output = self.params.raw;
@@ -317,18 +326,19 @@ pub struct ParseAndPrepareExport<'a> {
impl<'a> ParseAndPrepareExport<'a> {
/// Runs the command and exports from the chain.
pub fn run_with_builder<C, G, F, B, S, E>(
pub fn run_with_builder<C, G, E, F, B, S, Exit>(
self,
builder: F,
spec_factory: S,
exit: E,
exit: Exit,
) -> error::Result<()>
where S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
F: FnOnce(Configuration<C, G>) -> Result<B, error::Error>,
where S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
B: ServiceBuilderExport,
C: Default,
G: RuntimeGenesis,
E: IntoExit
E: ChainSpecExtension,
Exit: IntoExit
{
let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?;
@@ -355,18 +365,19 @@ pub struct ParseAndPrepareImport<'a> {
impl<'a> ParseAndPrepareImport<'a> {
/// Runs the command and imports to the chain.
pub fn run_with_builder<C, G, F, B, S, E>(
pub fn run_with_builder<C, G, E, F, B, S, Exit>(
self,
builder: F,
spec_factory: S,
exit: E,
exit: Exit,
) -> error::Result<()>
where S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
F: FnOnce(Configuration<C, G>) -> Result<B, error::Error>,
where S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
B: ServiceBuilderImport,
C: Default,
G: RuntimeGenesis,
E: IntoExit
E: ChainSpecExtension,
Exit: IntoExit
{
let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?;
config.execution_strategies = ExecutionStrategies {
@@ -398,14 +409,17 @@ pub struct ParseAndPreparePurge<'a> {
impl<'a> ParseAndPreparePurge<'a> {
/// Runs the command and purges the chain.
pub fn run<G, S>(
pub fn run<G, E, S>(
self,
spec_factory: S
) -> error::Result<()>
where S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
G: RuntimeGenesis
) -> error::Result<()> where
S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
G: RuntimeGenesis,
E: ChainSpecExtension,
{
let config = create_config_with_db_path::<(), _, _>(spec_factory, &self.params.shared_params, self.version)?;
let config = create_config_with_db_path::<(), _, _, _>(
spec_factory, &self.params.shared_params, self.version
)?;
let db_path = config.database_path;
if !self.params.yes {
@@ -447,17 +461,21 @@ pub struct ParseAndPrepareRevert<'a> {
impl<'a> ParseAndPrepareRevert<'a> {
/// Runs the command and reverts the chain.
pub fn run_with_builder<C, G, F, B, S>(
pub fn run_with_builder<C, G, E, F, B, S>(
self,
builder: F,
spec_factory: S
) -> error::Result<()>
where S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
F: FnOnce(Configuration<C, G>) -> Result<B, error::Error>,
) -> error::Result<()> where
S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
B: ServiceBuilderRevert,
C: Default,
G: RuntimeGenesis {
let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?;
G: RuntimeGenesis,
E: ChainSpecExtension,
{
let config = create_config_with_db_path(
spec_factory, &self.params.shared_params, self.version
)?;
let blocks = self.params.num;
builder(config)?.revert_chain(blocks.into())?;
Ok(())
@@ -519,8 +537,8 @@ fn parse_ed25519_secret(hex: &String) -> error::Result<network::config::Ed25519S
}
/// Fill the given `PoolConfiguration` by looking at the cli parameters.
fn fill_transaction_pool_configuration<C, G>(
options: &mut Configuration<C, G>,
fn fill_transaction_pool_configuration<C, G, E>(
options: &mut Configuration<C, G, E>,
params: TransactionPoolParams,
) -> error::Result<()> {
// ready queue
@@ -595,8 +613,8 @@ fn input_keystore_password() -> Result<String, String> {
}
/// Fill the password field of the given config instance.
fn fill_config_keystore_password<C, G>(
config: &mut service::Configuration<C, G>,
fn fill_config_keystore_password<C, G, E>(
config: &mut service::Configuration<C, G, E>,
cli: &RunCmd,
) -> Result<(), String> {
config.keystore_password = if cli.password_interactive {
@@ -612,13 +630,14 @@ fn fill_config_keystore_password<C, G>(
Ok(())
}
fn create_run_node_config<C, G, S>(
fn create_run_node_config<C, G, E, S>(
cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo
) -> error::Result<Configuration<C, G>>
) -> error::Result<Configuration<C, G, E>>
where
C: Default,
G: RuntimeGenesis,
S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
E: ChainSpecExtension,
S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
{
let spec = load_spec(&cli.shared_params, spec_factory)?;
let mut config = service::Configuration::default_with_spec(spec.clone());
@@ -657,8 +676,8 @@ where
config.pruning = match cli.pruning {
Some(ref s) if s == "archive" => PruningMode::ArchiveAll,
None => PruningMode::default(),
Some(s) => PruningMode::keep_blocks(
s.parse().map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))?
Some(s) => PruningMode::keep_blocks(s.parse()
.map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))?
),
};
@@ -756,13 +775,14 @@ where
// 9803-9874 Unassigned
// 9926-9949 Unassigned
fn with_default_boot_node<G>(
spec: &mut ChainSpec<G>,
fn with_default_boot_node<G, E>(
spec: &mut ChainSpec<G, E>,
cli: BuildSpecCmd,
version: &VersionInfo,
) -> error::Result<()>
where
G: RuntimeGenesis
G: RuntimeGenesis,
E: ChainSpecExtension,
{
if spec.boot_nodes().is_empty() {
let base_path = base_path(&cli.shared_params, version);
@@ -781,13 +801,14 @@ where
}
/// Creates a configuration including the database path.
pub fn create_config_with_db_path<C, G, S>(
pub fn create_config_with_db_path<C, G, E, S>(
spec_factory: S, cli: &SharedParams, version: &VersionInfo,
) -> error::Result<Configuration<C, G>>
) -> error::Result<Configuration<C, G, E>>
where
C: Default,
G: RuntimeGenesis,
S: FnOnce(&str) -> Result<Option<ChainSpec<G>>, String>,
E: ChainSpecExtension,
S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
{
let spec = load_spec(cli, spec_factory)?;
let base_path = base_path(cli, version);
+3 -2
View File
@@ -40,7 +40,7 @@ use std::collections::{HashMap, HashSet};
use client::backend::NewBlockState;
use client::blockchain::{well_known_cache_keys, HeaderBackend};
use client::ExecutionStrategies;
use client::{ForkBlocks, ExecutionStrategies};
use client::backend::{StorageCollection, ChildStorageCollection};
use codec::{Decode, Encode};
use hash_db::{Hasher, Prefix};
@@ -206,6 +206,7 @@ pub fn new_client<E, S, Block, RA>(
settings: DatabaseSettings,
executor: E,
genesis_storage: S,
fork_blocks: ForkBlocks<Block>,
execution_strategies: ExecutionStrategies,
keystore: Option<primitives::traits::BareCryptoStorePtr>,
) -> Result<(
@@ -227,7 +228,7 @@ pub fn new_client<E, S, Block, RA>(
let backend = Arc::new(Backend::new(settings, CANONICALIZATION_DELAY)?);
let executor = client::LocalCallExecutor::new(backend.clone(), executor, keystore);
Ok((
client::Client::new(backend.clone(), executor, genesis_storage, execution_strategies)?,
client::Client::new(backend.clone(), executor, genesis_storage, fork_blocks, execution_strategies)?,
backend,
))
}
+28 -7
View File
@@ -47,7 +47,7 @@ use state_machine::{
};
use executor::{RuntimeVersion, RuntimeInfo};
use consensus::{
Error as ConsensusError, BlockStatus, BlockImportParams,
Error as ConsensusError, BlockStatus, BlockImportParams, BlockCheckParams,
ImportResult, BlockOrigin, ForkChoiceStrategy,
SelectChain, self,
};
@@ -87,6 +87,11 @@ type StorageUpdate<B, Block> = <
>::State as state_machine::Backend<Blake2Hasher>>::Transaction;
type ChangesUpdate<Block> = ChangesTrieTransaction<Blake2Hasher, NumberFor<Block>>;
/// Expected hashes of blocks at given heights.
///
/// This may be used as chain spec extension to filter out known, unwanted forks.
pub type ForkBlocks<Block> = Option<HashMap<NumberFor<Block>, <Block as BlockT>::Hash>>;
/// Execution strategies settings.
#[derive(Debug, Clone)]
pub struct ExecutionStrategies {
@@ -123,6 +128,7 @@ pub struct Client<B, E, Block, RA> where Block: BlockT {
finality_notification_sinks: Mutex<Vec<mpsc::UnboundedSender<FinalityNotification<Block>>>>,
// holds the block hash currently being imported. TODO: replace this with block queue
importing_block: RwLock<Option<Block::Hash>>,
fork_blocks: ForkBlocks<Block>,
execution_strategies: ExecutionStrategies,
_phantom: PhantomData<RA>,
}
@@ -263,7 +269,7 @@ pub fn new_with_backend<B, E, Block, S, RA>(
B: backend::LocalBackend<Block, Blake2Hasher>
{
let call_executor = LocalCallExecutor::new(backend.clone(), executor, keystore);
Client::new(backend, call_executor, build_genesis_storage, Default::default())
Client::new(backend, call_executor, build_genesis_storage, Default::default(), Default::default())
}
/// Figure out the block type for a given type (for now, just a `Client`).
@@ -290,6 +296,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
backend: Arc<B>,
executor: E,
build_genesis_storage: S,
fork_blocks: ForkBlocks<Block>,
execution_strategies: ExecutionStrategies
) -> error::Result<Self> {
if backend.blockchain().header(BlockId::Number(Zero::zero()))?.is_none() {
@@ -318,6 +325,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
import_notification_sinks: Default::default(),
finality_notification_sinks: Default::default(),
importing_block: Default::default(),
fork_blocks,
execution_strategies,
_phantom: Default::default(),
})
@@ -1499,9 +1507,22 @@ impl<'a, B, E, Block, RA> consensus::BlockImport<Block> for &'a Client<B, E, Blo
/// Check block preconditions.
fn check_block(
&mut self,
hash: Block::Hash,
parent_hash: Block::Hash,
block: BlockCheckParams<Block>,
) -> Result<ImportResult, Self::Error> {
let BlockCheckParams { hash, number, parent_hash } = block;
if let Some(h) = self.fork_blocks.as_ref().and_then(|x| x.get(&number)) {
if &hash != h {
trace!(
"Rejecting block from known invalid fork. Got {:?}, expected: {:?} at height {}",
hash,
h,
number
);
return Ok(ImportResult::KnownBad);
}
}
match self.block_status(&BlockId::Hash(parent_hash))
.map_err(|e| ConsensusError::ClientImport(e.to_string()))?
{
@@ -1518,6 +1539,7 @@ impl<'a, B, E, Block, RA> consensus::BlockImport<Block> for &'a Client<B, E, Blo
BlockStatus::KnownBad => return Ok(ImportResult::KnownBad),
}
Ok(ImportResult::imported(false))
}
}
@@ -1539,10 +1561,9 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
fn check_block(
&mut self,
hash: Block::Hash,
parent_hash: Block::Hash,
block: BlockCheckParams<Block>,
) -> Result<ImportResult, Self::Error> {
(&*self).check_block(hash, parent_hash)
(&*self).check_block(block)
}
}
+3 -2
View File
@@ -67,7 +67,8 @@
//! ),
//! // This parameter provides the storage for the chain genesis.
//! <(StorageOverlay, ChildrenStorageOverlay)>::default(),
//! Default::default()
//! Default::default(),
//! Default::default(),
//! );
//! ```
//!
@@ -115,7 +116,7 @@ pub use crate::client::{
new_in_mem,
BlockBody, ImportNotifications, FinalityNotifications, BlockchainEvents,
BlockImportNotification, Client, ClientInfo, ExecutionStrategies, FinalityNotification,
LongestChain, BlockOf, ProvideUncles,
LongestChain, BlockOf, ProvideUncles, ForkBlocks,
utils, apply_aux,
};
#[cfg(feature = "std")]
+1 -1
View File
@@ -67,7 +67,7 @@ pub fn new_light<B, S, GS, RA, E>(
{
let local_executor = LocalCallExecutor::new(backend.clone(), code_executor, None);
let executor = GenesisCallExecutor::new(backend.clone(), local_executor);
Client::new(backend, executor, genesis_storage, Default::default())
Client::new(backend, executor, genesis_storage, Default::default(), Default::default())
}
/// Create an instance of fetch data checker.
+3 -4
View File
@@ -89,7 +89,7 @@ use schnorrkel::{
},
};
use consensus_common::{
self, BlockImport, Environment, Proposer,
self, BlockImport, Environment, Proposer, BlockCheckParams,
ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError,
};
use srml_babe::{
@@ -1367,10 +1367,9 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
fn check_block(
&mut self,
hash: Block::Hash,
parent_hash: Block::Hash,
block: BlockCheckParams<Block>,
) -> Result<ImportResult, Self::Error> {
self.inner.check_block(hash, parent_hash).map_err(Into::into)
self.inner.check_block(block).map_err(Into::into)
}
}
+3 -4
View File
@@ -30,7 +30,7 @@ use consensus_common::import_queue::{
use network::test::*;
use network::test::{Block as TestBlock, PeersClient};
use network::config::BoxFinalityProofRequestBuilder;
use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor}};
use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor, NumberFor}};
use network::config::ProtocolConfig;
use tokio::runtime::current_thread;
use client::BlockchainEvents;
@@ -179,10 +179,9 @@ impl<B: BlockImport<TestBlock>> BlockImport<TestBlock> for PanickingBlockImport<
fn check_block(
&mut self,
hash: Hash,
parent_hash: Hash,
block: BlockCheckParams<TestBlock>,
) -> Result<ImportResult, Self::Error> {
Ok(self.0.check_block(hash, parent_hash).expect("checking block failed"))
Ok(self.0.check_block(block).expect("checking block failed"))
}
}
@@ -90,7 +90,17 @@ pub enum ForkChoiceStrategy {
Custom(bool),
}
/// Data required to import a Block
/// Data required to check validity of a Block.
pub struct BlockCheckParams<Block: BlockT> {
/// Hash of the block that we verify.
pub hash: Block::Hash,
/// Block number of the block that we verify.
pub number: NumberFor<Block>,
/// Parent hash of the block that we verify.
pub parent_hash: Block::Hash,
}
/// Data required to import a Block.
pub struct BlockImportParams<Block: BlockT> {
/// Origin of the Block
pub origin: BlockOrigin,
@@ -172,8 +182,7 @@ pub trait BlockImport<B: BlockT> {
/// Check block preconditions.
fn check_block(
&mut self,
hash: B::Hash,
parent_hash: B::Hash,
block: BlockCheckParams<B>,
) -> Result<ImportResult, Self::Error>;
/// Import a block.
@@ -192,10 +201,9 @@ impl<B: BlockT> BlockImport<B> for crate::import_queue::BoxBlockImport<B> {
/// Check block preconditions.
fn check_block(
&mut self,
hash: B::Hash,
parent_hash: B::Hash,
block: BlockCheckParams<B>,
) -> Result<ImportResult, Self::Error> {
(**self).check_block(hash, parent_hash)
(**self).check_block(block)
}
/// Import a block.
@@ -217,10 +225,9 @@ where for<'r> &'r T: BlockImport<B, Error = E>
fn check_block(
&mut self,
hash: B::Hash,
parent_hash: B::Hash,
block: BlockCheckParams<B>,
) -> Result<ImportResult, Self::Error> {
(&**self).check_block(hash, parent_hash)
(&**self).check_block(block)
}
fn import_block(
@@ -30,7 +30,7 @@ use sr_primitives::{Justification, traits::{Block as BlockT, Header as _, Number
use crate::error::Error as ConsensusError;
use crate::block_import::{
BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult,
FinalityProofImport,
BlockCheckParams, FinalityProofImport,
};
pub use basic_queue::BasicQueue;
@@ -194,7 +194,7 @@ pub fn import_single_block<B: BlockT, V: Verifier<B>>(
let number = header.number().clone();
let hash = header.hash();
let parent = header.parent_hash().clone();
let parent_hash = header.parent_hash().clone();
let import_error = |e| {
match e {
@@ -204,7 +204,7 @@ pub fn import_single_block<B: BlockT, V: Verifier<B>>(
},
Ok(ImportResult::Imported(aux)) => Ok(BlockImportResult::ImportedUnknown(number, aux, peer.clone())),
Ok(ImportResult::UnknownParent) => {
debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent);
debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent_hash);
Err(BlockImportError::UnknownParent)
},
Ok(ImportResult::KnownBad) => {
@@ -217,8 +217,7 @@ pub fn import_single_block<B: BlockT, V: Verifier<B>>(
}
}
};
match import_error(import_handle.check_block(hash, parent))? {
match import_error(import_handle.check_block(BlockCheckParams { hash, number, parent_hash }))? {
BlockImportResult::ImportedUnknown { .. } => (),
r => return Ok(r), // Any other successful result means that the block is already imported.
}
+1 -1
View File
@@ -48,7 +48,7 @@ const MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024 + 512;
pub use self::error::Error;
pub use block_import::{
BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult,
BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, BlockCheckParams, ImportResult,
JustificationImport, FinalityProofImport,
};
pub use select_chain::SelectChain;
@@ -27,7 +27,7 @@ use client::backend::Backend;
use client::utils::is_descendent_of;
use consensus_common::{
BlockImport, Error as ConsensusError,
BlockImportParams, ImportResult, JustificationImport,
BlockCheckParams, BlockImportParams, ImportResult, JustificationImport,
SelectChain,
};
use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog};
@@ -386,9 +386,11 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, SC> BlockImport<Block>
{
type Error = ConsensusError;
fn import_block(&mut self, mut block: BlockImportParams<Block>, new_cache: HashMap<well_known_cache_keys::Id, Vec<u8>>)
-> Result<ImportResult, Self::Error>
{
fn import_block(
&mut self,
mut block: BlockImportParams<Block>,
new_cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
) -> Result<ImportResult, Self::Error> {
let hash = block.post_header().hash();
let number = block.header.number().clone();
@@ -500,10 +502,9 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, SC> BlockImport<Block>
fn check_block(
&mut self,
hash: Block::Hash,
parent_hash: Block::Hash,
block: BlockCheckParams<Block>,
) -> Result<ImportResult, Self::Error> {
self.inner.check_block(hash, parent_hash)
self.inner.check_block(block)
}
}
@@ -30,7 +30,7 @@ use codec::{Encode, Decode};
use consensus_common::{
import_queue::Verifier,
BlockOrigin, BlockImport, FinalityProofImport, BlockImportParams, ImportResult, ImportedAux,
Error as ConsensusError,
BlockCheckParams, Error as ConsensusError,
};
use network::config::{BoxFinalityProofRequestBuilder, FinalityProofRequestBuilder};
use sr_primitives::Justification;
@@ -142,10 +142,9 @@ impl<B, E, Block: BlockT<Hash=H256>, RA> BlockImport<Block>
fn check_block(
&mut self,
hash: Block::Hash,
parent_hash: Block::Hash,
block: BlockCheckParams<Block>,
) -> Result<ImportResult, Self::Error> {
self.client.check_block(hash, parent_hash)
self.client.check_block(block)
}
}
@@ -591,10 +590,9 @@ pub mod tests {
fn check_block(
&mut self,
hash: Block::Hash,
parent_hash: Block::Hash,
block: BlockCheckParams<Block>,
) -> Result<ImportResult, Self::Error> {
self.0.check_block(hash, parent_hash)
self.0.check_block(block)
}
}
+6 -3
View File
@@ -44,7 +44,7 @@ use consensus::import_queue::{
};
use consensus::block_import::{BlockImport, ImportResult};
use consensus::Error as ConsensusError;
use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, JustificationImport};
use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport};
use futures::prelude::*;
use futures03::{StreamExt as _, TryStreamExt as _};
use crate::{NetworkWorker, NetworkService, config::ProtocolId};
@@ -431,8 +431,11 @@ impl<T: ?Sized> Clone for BlockImportAdapter<T> {
impl<T: ?Sized + BlockImport<Block>> BlockImport<Block> for BlockImportAdapter<T> {
type Error = T::Error;
fn check_block(&mut self, hash: Hash, parent_hash: Hash) -> Result<ImportResult, Self::Error> {
self.0.lock().check_block(hash, parent_hash)
fn check_block(
&mut self,
block: BlockCheckParams<Block>,
) -> Result<ImportResult, Self::Error> {
self.0.lock().check_block(block)
}
fn import_block(
+2 -1
View File
@@ -15,7 +15,7 @@ slog = {version = "^2", features = ["nested-values"]}
tokio-executor = "0.1.7"
tokio-timer = "0.2"
exit-future = "0.1"
serde = { version = "1.0", features = ["derive"] }
serde = { version = "1.0" }
serde_json = "1.0"
sysinfo = "0.9.0"
target_info = "0.1"
@@ -27,6 +27,7 @@ session = { package = "substrate-session", path = "../session" }
app-crypto = { package = "substrate-application-crypto", path = "../application-crypto" }
consensus_common = { package = "substrate-consensus-common", path = "../../core/consensus/common" }
network = { package = "substrate-network", path = "../../core/network" }
chain-spec = { package = "substrate-chain-spec", path = "../chain-spec" }
client = { package = "substrate-client", path = "../../core/client" }
client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] }
codec = { package = "parity-scale-codec", version = "1.0.0" }
+54 -35
View File
@@ -22,6 +22,7 @@ use client::{
BlockchainEvents, Client, runtime_api,
backend::RemoteBackend, light::blockchain::RemoteBlockchain,
};
use chain_spec::{RuntimeGenesis, Extension};
use codec::{Decode, Encode, IoReader};
use consensus_common::import_queue::ImportQueue;
use futures::{prelude::*, sync::mpsc};
@@ -33,12 +34,11 @@ use network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpe
use parking_lot::{Mutex, RwLock};
use primitives::{Blake2Hasher, H256, Hasher};
use rpc::{self, system::SystemInfo};
use sr_primitives::{BuildStorage, generic::BlockId};
use sr_primitives::generic::BlockId;
use sr_primitives::traits::{
Block as BlockT, Extrinsic, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion
};
use substrate_executor::{NativeExecutor, NativeExecutionDispatch};
use serde::{Serialize, de::DeserializeOwned};
use std::{io::{Read, Write, Seek}, marker::PhantomData, sync::Arc, sync::atomic::AtomicBool};
use sysinfo::{get_current_pid, ProcessExt, System, SystemExt};
use tel::{telemetry, SUBSTRATE_INFO};
@@ -62,10 +62,10 @@ use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool};
/// The order in which the `with_*` methods are called doesn't matter, as the correct binding of
/// generics is done when you call `build`.
///
pub struct ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
pub struct ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend>
{
config: Configuration<TCfg, TGen>,
config: Configuration<TCfg, TGen, TCSExt>,
client: Arc<TCl>,
backend: Arc<Backend>,
keystore: Arc<RwLock<Keystore>>,
@@ -128,16 +128,17 @@ type TLightCallExecutor<TBl, TExecDisp> = client::light::call_executor::GenesisC
>,
>;
impl<TCfg, TGen> ServiceBuilder<(), (), TCfg, TGen, (), (), (), (), (), (), (), (), (), (), ()>
where TGen: Serialize + DeserializeOwned + BuildStorage {
impl<TCfg, TGen, TCSExt> ServiceBuilder<(), (), TCfg, TGen, TCSExt, (), (), (), (), (), (), (), (), (), (), ()>
where TGen: RuntimeGenesis, TCSExt: Extension {
/// Start the service builder with a configuration.
pub fn new_full<TBl: BlockT<Hash=H256>, TRtApi, TExecDisp: NativeExecutionDispatch>(
config: Configuration<TCfg, TGen>
config: Configuration<TCfg, TGen, TCSExt>
) -> Result<ServiceBuilder<
TBl,
TRtApi,
TCfg,
TGen,
TCSExt,
TFullClient<TBl, TRtApi, TExecDisp>,
Arc<OnDemand<TBl>>,
(),
@@ -163,10 +164,17 @@ where TGen: Serialize + DeserializeOwned + BuildStorage {
let executor = NativeExecutor::<TExecDisp>::new(config.default_heap_pages);
let fork_blocks = config.chain_spec
.extensions()
.get::<client::ForkBlocks<TBl>>()
.cloned()
.unwrap_or_default();
let (client, backend) = client_db::new_client(
db_settings,
executor,
&config.chain_spec,
fork_blocks,
config.execution_strategies.clone(),
Some(keystore.clone()),
)?;
@@ -196,12 +204,13 @@ where TGen: Serialize + DeserializeOwned + BuildStorage {
/// Start the service builder with a configuration.
pub fn new_light<TBl: BlockT<Hash=H256>, TRtApi, TExecDisp: NativeExecutionDispatch + 'static>(
config: Configuration<TCfg, TGen>
config: Configuration<TCfg, TGen, TCSExt>
) -> Result<ServiceBuilder<
TBl,
TRtApi,
TCfg,
TGen,
TCSExt,
TLightClient<TBl, TRtApi, TExecDisp>,
Arc<OnDemand<TBl>>,
(),
@@ -264,8 +273,8 @@ where TGen: Serialize + DeserializeOwned + BuildStorage {
}
}
impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend>
ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
impl<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend>
ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend> {
/// Returns a reference to the client that was stored in this builder.
@@ -286,8 +295,10 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
/// Defines which head-of-chain strategy to use.
pub fn with_opt_select_chain<USc>(
self,
select_chain_builder: impl FnOnce(&Configuration<TCfg, TGen>, &Arc<Backend>) -> Result<Option<USc>, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
select_chain_builder: impl FnOnce(
&Configuration<TCfg, TGen, TCSExt>, &Arc<Backend>
) -> Result<Option<USc>, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend>, Error> {
let select_chain = select_chain_builder(&self.config, &self.backend)?;
@@ -313,8 +324,8 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
/// Defines which head-of-chain strategy to use.
pub fn with_select_chain<USc>(
self,
builder: impl FnOnce(&Configuration<TCfg, TGen>, &Arc<Backend>) -> Result<USc, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
builder: impl FnOnce(&Configuration<TCfg, TGen, TCSExt>, &Arc<Backend>) -> Result<USc, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend>, Error> {
self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some))
}
@@ -322,9 +333,9 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
/// Defines which import queue to use.
pub fn with_import_queue<UImpQu>(
self,
builder: impl FnOnce(&Configuration<TCfg, TGen>, Arc<TCl>, Option<TSc>, Arc<TExPool>)
builder: impl FnOnce(&Configuration<TCfg, TGen, TCSExt>, Arc<TCl>, Option<TSc>, Arc<TExPool>)
-> Result<UImpQu, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, UImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, UImpQu, TFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend>, Error>
where TSc: Clone {
let import_queue = builder(
@@ -356,8 +367,8 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
/// Defines which network specialization protocol to use.
pub fn with_network_protocol<UNetP>(
self,
network_protocol_builder: impl FnOnce(&Configuration<TCfg, TGen>) -> Result<UNetP, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
network_protocol_builder: impl FnOnce(&Configuration<TCfg, TGen, TCSExt>) -> Result<UNetP, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
UNetP, TExPool, TRpc, TRpcB, Backend>, Error> {
let network_protocol = network_protocol_builder(&self.config)?;
@@ -389,6 +400,7 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
TRtApi,
TCfg,
TGen,
TCSExt,
TCl,
TFchr,
TSc,
@@ -431,6 +443,7 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
TRtApi,
TCfg,
TGen,
TCSExt,
TCl,
TFchr,
TSc,
@@ -450,14 +463,14 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
pub fn with_import_queue_and_opt_fprb<UImpQu, UFprb>(
self,
builder: impl FnOnce(
&Configuration<TCfg, TGen>,
&Configuration<TCfg, TGen, TCSExt>,
Arc<TCl>,
Arc<Backend>,
Option<TFchr>,
Option<TSc>,
Arc<TExPool>,
) -> Result<(UImpQu, Option<UFprb>), Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend>, Error>
where TSc: Clone, TFchr: Clone {
let (import_queue, fprb) = builder(
@@ -492,14 +505,14 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
pub fn with_import_queue_and_fprb<UImpQu, UFprb>(
self,
builder: impl FnOnce(
&Configuration<TCfg, TGen>,
&Configuration<TCfg, TGen, TCSExt>,
Arc<TCl>,
Arc<Backend>,
Option<TFchr>,
Option<TSc>,
Arc<TExPool>,
) -> Result<(UImpQu, UFprb), Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend>, Error>
where TSc: Clone, TFchr: Clone {
self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx|
@@ -512,7 +525,7 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
pub fn with_transaction_pool<UExPool>(
self,
transaction_pool_builder: impl FnOnce(transaction_pool::txpool::Options, Arc<TCl>) -> Result<UExPool, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TNetP, UExPool, TRpc, TRpcB, Backend>, Error> {
let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?;
@@ -539,7 +552,7 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
pub fn with_rpc_extensions<URpc>(
self,
rpc_ext_builder: impl FnOnce(Arc<TCl>, Arc<TExPool>) -> URpc
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TNetP, TExPool, URpc, TRpcB, Backend>, Error> {
let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone());
@@ -567,7 +580,7 @@ impl<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPo
pub fn with_dht_event_tx(
self,
dht_event_tx: mpsc::Sender<DhtEvent>,
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TNetP, TExPool, TRpc, TRpcB, Backend>, Error> {
Ok(ServiceBuilder {
config: self.config,
@@ -708,10 +721,14 @@ pub trait ServiceBuilderRevert {
) -> Result<(), Error>;
}
impl<TBl, TRtApi, TCfg, TGen, TBackend, TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend>
ServiceBuilderImport for ServiceBuilder<TBl, TRtApi, TCfg, TGen, Client<TBackend, TExec, TBl, TRtApi>,
TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend>
where
impl<
TBl, TRtApi, TCfg, TGen, TCSExt, TBackend,
TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP,
TExPool, TRpc, TRpcB, Backend
> ServiceBuilderImport for ServiceBuilder<
TBl, TRtApi, TCfg, TGen, TCSExt, Client<TBackend, TExec, TBl, TRtApi>,
TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend
> where
TBl: BlockT<Hash = <Blake2Hasher as Hasher>::Out>,
TBackend: 'static + client::backend::Backend<TBl, Blake2Hasher> + Send,
TExec: 'static + client::CallExecutor<TBl, Blake2Hasher> + Send + Sync + Clone,
@@ -730,8 +747,8 @@ where
}
}
impl<TBl, TRtApi, TCfg, TGen, TBackend, TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB>
ServiceBuilderExport for ServiceBuilder<TBl, TRtApi, TCfg, TGen, Client<TBackend, TExec, TBl, TRtApi>,
impl<TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB>
ServiceBuilderExport for ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, Client<TBackend, TExec, TBl, TRtApi>,
TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend>
where
TBl: BlockT<Hash = <Blake2Hasher as Hasher>::Out>,
@@ -753,8 +770,8 @@ where
}
}
impl<TBl, TRtApi, TCfg, TGen, TBackend, TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB>
ServiceBuilderRevert for ServiceBuilder<TBl, TRtApi, TCfg, TGen, Client<TBackend, TExec, TBl, TRtApi>,
impl<TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB>
ServiceBuilderRevert for ServiceBuilder<TBl, TRtApi, TCfg, TGen, TCSExt, Client<TBackend, TExec, TBl, TRtApi>,
TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend>
where
TBl: BlockT<Hash = <Blake2Hasher as Hasher>::Out>,
@@ -772,12 +789,13 @@ where
}
}
impl<TBl, TRtApi, TCfg, TGen, TBackend, TExec, TSc, TImpQu, TNetP, TExPoolApi, TRpc, TRpcB>
impl<TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, TExec, TSc, TImpQu, TNetP, TExPoolApi, TRpc, TRpcB>
ServiceBuilder<
TBl,
TRtApi,
TCfg,
TGen,
TCSExt,
Client<TBackend, TExec, TBl, TRtApi>,
Arc<OnDemand<TBl>>,
TSc,
@@ -799,7 +817,8 @@ ServiceBuilder<
TBl: BlockT<Hash = <Blake2Hasher as Hasher>::Out>,
TRtApi: 'static + Send + Sync,
TCfg: Default,
TGen: Serialize + DeserializeOwned + BuildStorage,
TGen: RuntimeGenesis,
TCSExt: Extension,
TBackend: 'static + client::backend::Backend<TBl, Blake2Hasher> + Send,
TExec: 'static + client::CallExecutor<TBl, Blake2Hasher> + Send + Sync + Clone,
TSc: Clone,
+4 -4
View File
@@ -16,9 +16,8 @@
//! Chain utilities.
use crate::RuntimeGenesis;
use crate::error;
use crate::chain_spec::ChainSpec;
use chain_spec::{ChainSpec, RuntimeGenesis, Extension};
/// Defines the logic for an operation exporting blocks within a range.
#[macro_export]
@@ -222,8 +221,9 @@ macro_rules! revert_chain {
}
/// Build a chain spec json
pub fn build_spec<G>(spec: ChainSpec<G>, raw: bool) -> error::Result<String>
where G: RuntimeGenesis,
pub fn build_spec<G, E>(spec: ChainSpec<G, E>, raw: bool) -> error::Result<String> where
G: RuntimeGenesis,
E: Extension,
{
Ok(spec.to_json(raw)?)
}
+9 -7
View File
@@ -22,16 +22,14 @@ pub use network::config::{ExtTransport, NetworkConfiguration, Roles};
use std::{path::PathBuf, net::SocketAddr};
use transaction_pool;
use crate::chain_spec::ChainSpec;
use chain_spec::{ChainSpec, RuntimeGenesis, Extension, NoExtension};
use primitives::crypto::Protected;
use sr_primitives::BuildStorage;
use serde::{Serialize, de::DeserializeOwned};
use target_info::Target;
use tel::TelemetryEndpoints;
/// Service configuration.
#[derive(Clone)]
pub struct Configuration<C, G> {
pub struct Configuration<C, G, E = NoExtension> {
/// Implementation name
pub impl_name: &'static str,
/// Implementation version
@@ -57,7 +55,7 @@ pub struct Configuration<C, G> {
/// Pruning settings.
pub pruning: PruningMode,
/// Chain configuration.
pub chain_spec: ChainSpec<G>,
pub chain_spec: ChainSpec<G, E>,
/// Custom configuration.
pub custom: C,
/// Node name.
@@ -95,9 +93,13 @@ pub struct Configuration<C, G> {
pub dev_key_seed: Option<String>,
}
impl<C: Default, G: Serialize + DeserializeOwned + BuildStorage> Configuration<C, G> {
impl<C, G, E> Configuration<C, G, E> where
C: Default,
G: RuntimeGenesis,
E: Extension,
{
/// Create default config for given chain spec.
pub fn default_with_spec(chain_spec: ChainSpec<G>) -> Self {
pub fn default_with_spec(chain_spec: ChainSpec<G, E>) -> Self {
let mut configuration = Configuration {
impl_name: "parity-substrate",
impl_version: "0.0.0",
+8 -15
View File
@@ -19,7 +19,6 @@
#![warn(missing_docs)]
mod chain_spec;
pub mod config;
#[macro_use]
pub mod chain_ops;
@@ -31,7 +30,6 @@ use std::net::SocketAddr;
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, Instant};
use serde::{Serialize, de::DeserializeOwned};
use futures::sync::mpsc;
use parking_lot::Mutex;
@@ -43,14 +41,13 @@ use network::{NetworkService, NetworkState, specialization::NetworkSpecializatio
use log::{log, warn, debug, error, Level};
use codec::{Encode, Decode};
use primitives::{Blake2Hasher, H256};
use sr_primitives::BuildStorage;
use sr_primitives::generic::BlockId;
use sr_primitives::traits::NumberFor;
pub use self::error::Error;
pub use self::builder::{ServiceBuilder, ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert};
pub use config::{Configuration, Roles, PruningMode};
pub use chain_spec::{ChainSpec, Properties};
pub use chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension};
pub use transaction_pool::txpool::{
self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError
};
@@ -100,10 +97,6 @@ pub struct NewService<TBl, TCl, TSc, TNetStatus, TNet, TTxPool, TOc> {
marker: PhantomData<TBl>,
}
/// A set of traits for the runtime genesis config.
pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {}
impl<T: Serialize + DeserializeOwned + BuildStorage> RuntimeGenesis for T {}
/// Alias for a an implementation of `futures::future::Executor`.
pub type TaskExecutor = Arc<dyn Executor<Box<dyn Future<Item = (), Error = ()> + Send>> + Send + Sync>;
@@ -349,7 +342,7 @@ macro_rules! new_impl {
chain_name: $config.chain_spec.name().into(),
impl_name: $config.impl_name.into(),
impl_version: $config.impl_version.into(),
properties: $config.chain_spec.properties(),
properties: $config.chain_spec.properties().clone(),
};
$start_rpc(
client.clone(),
@@ -805,8 +798,8 @@ impl<TBl, TCl, TSc, TNetStatus, TNet, TTxPool, TOc> Drop for
/// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive.
#[cfg(not(target_os = "unknown"))]
fn start_rpc_servers<C, G, H: FnMut() -> rpc_servers::RpcHandler<rpc::Metadata>>(
config: &Configuration<C, G>,
fn start_rpc_servers<C, G, E, H: FnMut() -> rpc_servers::RpcHandler<rpc::Metadata>>(
config: &Configuration<C, G, E>,
mut gen_handler: H
) -> Result<Box<dyn std::any::Any + Send + Sync>, error::Error> {
fn maybe_start_server<T, F>(address: Option<SocketAddr>, mut start: F) -> Result<Option<T>, io::Error>
@@ -846,8 +839,8 @@ fn start_rpc_servers<C, G, H: FnMut() -> rpc_servers::RpcHandler<rpc::Metadata>>
/// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive.
#[cfg(target_os = "unknown")]
fn start_rpc_servers<C, G, H: FnMut() -> components::RpcHandler>(
_: &Configuration<C, G>,
fn start_rpc_servers<C, G, E, H: FnMut() -> components::RpcHandler>(
_: &Configuration<C, G, E>,
_: H
) -> Result<Box<std::any::Any + Send + Sync>, error::Error> {
Ok(Box::new(()))
@@ -888,7 +881,7 @@ fn transactions_to_propagate<PoolApi, B, H, E>(pool: &TransactionPool<PoolApi>)
where
PoolApi: ChainApi<Block=B, Hash=H, Error=E>,
B: BlockT,
H: std::hash::Hash + Eq + sr_primitives::traits::Member + serde::Serialize,
H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize,
E: txpool::error::IntoPoolError + From<txpool::error::Error>,
{
pool.ready()
@@ -907,7 +900,7 @@ where
C: network::ClientHandle<B> + Send + Sync,
PoolApi: ChainApi<Block=B, Hash=H, Error=E>,
B: BlockT,
H: std::hash::Hash + Eq + sr_primitives::traits::Member + serde::Serialize,
H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize,
E: txpool::error::IntoPoolError + From<txpool::error::Error>,
{
fn transactions(&self) -> Vec<(H, <B as BlockT>::Extrinsic)> {
+36 -29
View File
@@ -39,12 +39,12 @@ use sr_primitives::{generic::BlockId, traits::Block as BlockT};
/// Maximum duration of single wait call.
const MAX_WAIT_TIME: Duration = Duration::from_secs(60 * 3);
struct TestNet<G, F, L, U> {
struct TestNet<G, E, F, L, U> {
runtime: Runtime,
authority_nodes: Vec<(usize, SyncService<F>, U, Multiaddr)>,
full_nodes: Vec<(usize, SyncService<F>, U, Multiaddr)>,
light_nodes: Vec<(usize, SyncService<L>, Multiaddr)>,
chain_spec: ChainSpec<G>,
chain_spec: ChainSpec<G, E>,
base_port: u16,
nodes: usize,
}
@@ -79,7 +79,7 @@ impl<T: Future<Item=(), Error=service::Error>> Future for SyncService<T> {
}
}
impl<G, F, L, U> TestNet<G, F, L, U>
impl<G, E, F, L, U> TestNet<G, E, F, L, U>
where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static
{
pub fn run_until_all_full<FP, LP>(
@@ -124,14 +124,14 @@ where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static
}
}
fn node_config<G> (
fn node_config<G, E: Clone> (
index: usize,
spec: &ChainSpec<G>,
spec: &ChainSpec<G, E>,
role: Roles,
key_seed: Option<String>,
base_port: u16,
root: &TempDir,
) -> Configuration<(), G>
) -> Configuration<(), G, E>
{
let root = root.path().join(format!("node-{}", index));
@@ -193,18 +193,22 @@ fn node_config<G> (
}
}
impl<G, F, L, U> TestNet<G, F, L, U> where
impl<G, E, F, L, U> TestNet<G, E, F, L, U> where
F: AbstractService,
L: AbstractService,
E: Clone,
{
fn new(
temp: &TempDir,
spec: ChainSpec<G>,
full: impl Iterator<Item = impl FnOnce(Configuration<(), G>) -> Result<(F, U), Error>>,
light: impl Iterator<Item = impl FnOnce(Configuration<(), G>) -> Result<L, Error>>,
authorities: impl Iterator<Item = (String, impl FnOnce(Configuration<(), G>) -> Result<(F, U), Error>)>,
spec: ChainSpec<G, E>,
full: impl Iterator<Item = impl FnOnce(Configuration<(), G, E>) -> Result<(F, U), Error>>,
light: impl Iterator<Item = impl FnOnce(Configuration<(), G, E>) -> Result<L, Error>>,
authorities: impl Iterator<Item = (
String,
impl FnOnce(Configuration<(), G, E>) -> Result<(F, U), Error>
)>,
base_port: u16
) -> TestNet<G, F, L, U> {
) -> TestNet<G, E, F, L, U> {
let _ = env_logger::try_init();
fdlimit::raise_fd_limit();
let runtime = Runtime::new().expect("Error creating tokio runtime");
@@ -224,9 +228,9 @@ impl<G, F, L, U> TestNet<G, F, L, U> where
fn insert_nodes(
&mut self,
temp: &TempDir,
full: impl Iterator<Item = impl FnOnce(Configuration<(), G>) -> Result<(F, U), Error>>,
light: impl Iterator<Item = impl FnOnce(Configuration<(), G>) -> Result<L, Error>>,
authorities: impl Iterator<Item = (String, impl FnOnce(Configuration<(), G>) -> Result<(F, U), Error>)>
full: impl Iterator<Item = impl FnOnce(Configuration<(), G, E>) -> Result<(F, U), Error>>,
light: impl Iterator<Item = impl FnOnce(Configuration<(), G, E>) -> Result<L, Error>>,
authorities: impl Iterator<Item = (String, impl FnOnce(Configuration<(), G, E>) -> Result<(F, U), Error>)>
) {
let executor = self.runtime.executor();
@@ -274,16 +278,17 @@ impl<G, F, L, U> TestNet<G, F, L, U> where
}
}
pub fn connectivity<G, Fb, F, Lb, L>(
spec: ChainSpec<G>,
pub fn connectivity<G, E, Fb, F, Lb, L>(
spec: ChainSpec<G, E>,
full_builder: Fb,
light_builder: Lb,
light_node_interconnectivity: bool, // should normally be false, unless the light nodes
// aren't actually light.
) where
Fb: Fn(Configuration<(), G>) -> Result<F, Error>,
E: Clone,
Fb: Fn(Configuration<(), G, E>) -> Result<F, Error>,
F: AbstractService,
Lb: Fn(Configuration<(), G>) -> Result<L, Error>,
Lb: Fn(Configuration<(), G, E>) -> Result<L, Error>,
L: AbstractService,
{
const NUM_FULL_NODES: usize = 5;
@@ -377,20 +382,21 @@ pub fn connectivity<G, Fb, F, Lb, L>(
}
}
pub fn sync<G, Fb, F, Lb, L, B, E, U>(
spec: ChainSpec<G>,
pub fn sync<G, E, Fb, F, Lb, L, B, ExF, U>(
spec: ChainSpec<G, E>,
full_builder: Fb,
light_builder: Lb,
mut make_block_and_import: B,
mut extrinsic_factory: E
mut extrinsic_factory: ExF
) where
Fb: Fn(Configuration<(), G>) -> Result<(F, U), Error>,
Fb: Fn(Configuration<(), G, E>) -> Result<(F, U), Error>,
F: AbstractService,
Lb: Fn(Configuration<(), G>) -> Result<L, Error>,
Lb: Fn(Configuration<(), G, E>) -> Result<L, Error>,
L: AbstractService,
B: FnMut(&F, &mut U),
E: FnMut(&F, &U) -> <F::Block as BlockT>::Extrinsic,
ExF: FnMut(&F, &U) -> <F::Block as BlockT>::Extrinsic,
U: Clone + Send + 'static,
E: Clone,
{
const NUM_FULL_NODES: usize = 10;
// FIXME: BABE light client support is currently not working.
@@ -446,16 +452,17 @@ pub fn sync<G, Fb, F, Lb, L, B, E, U>(
);
}
pub fn consensus<G, Fb, F, Lb, L>(
spec: ChainSpec<G>,
pub fn consensus<G, E, Fb, F, Lb, L>(
spec: ChainSpec<G, E>,
full_builder: Fb,
light_builder: Lb,
authorities: impl IntoIterator<Item = String>
) where
Fb: Fn(Configuration<(), G>) -> Result<F, Error>,
Fb: Fn(Configuration<(), G, E>) -> Result<F, Error>,
F: AbstractService,
Lb: Fn(Configuration<(), G>) -> Result<L, Error>,
Lb: Fn(Configuration<(), G, E>) -> Result<L, Error>,
L: AbstractService,
E: Clone,
{
const NUM_FULL_NODES: usize = 10;
const NUM_LIGHT_NODES: usize = 10;
+1 -1
View File
@@ -92,7 +92,7 @@ pub struct TelemetryConfig {
/// maximum verbosity level.
///
/// The URL string can be either a URL or a multiaddress.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TelemetryEndpoints(Vec<(String, u8)>);
impl TelemetryEndpoints {
+1
View File
@@ -187,6 +187,7 @@ impl<Executor, Backend, G: GenesisInit> TestClientBuilder<Executor, Backend, G>
self.backend.clone(),
executor,
storage,
Default::default(),
self.execution_strategies,
).expect("Creates new client");
+7 -6
View File
@@ -4,7 +4,7 @@ use std::cell::RefCell;
use tokio::runtime::Runtime;
pub use substrate_cli::{VersionInfo, IntoExit, error};
use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom};
use substrate_service::{AbstractService, Roles as ServiceRoles};
use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration};
use crate::chain_spec;
use log::info;
@@ -14,9 +14,10 @@ pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()>
T: Into<std::ffi::OsString> + Clone,
E: IntoExit,
{
type Config<T> = Configuration<(), T>;
match parse_and_prepare::<NoCustom, NoCustom, _>(&version, "substrate-node", args) {
ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit,
|exit, _cli_args, _custom_args, config| {
ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit,
|exit, _cli_args, _custom_args, config: Config<_>| {
info!("{}", version.name);
info!(" version {}", config.full_version());
info!(" by {}, 2017, 2018", version.author);
@@ -38,12 +39,12 @@ pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()>
}.map_err(|e| format!("{:?}", e))
}),
ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec),
ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config|
ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>|
Ok(new_full_start!(config).0), load_spec, exit),
ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config|
ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>|
Ok(new_full_start!(config).0), load_spec, exit),
ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec),
ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _>(|config|
ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_>|
Ok(new_full_start!(config).0), load_spec),
ParseAndPrepare::CustomCommand(_) => Ok(())
}?;
+2 -1
View File
@@ -25,6 +25,7 @@ hex-literal = "0.2"
substrate-rpc = { package = "substrate-rpc", path = "../../core/rpc" }
substrate-basic-authorship = { path = "../../core/basic-authorship" }
substrate-service = { path = "../../core/service" }
chain-spec = { package = "substrate-chain-spec", path = "../../core/chain-spec" }
transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" }
network = { package = "substrate-network", path = "../../core/network" }
babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe" }
@@ -48,10 +49,10 @@ support = { package = "srml-support", path = "../../srml/support", default-featu
im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false }
sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false }
authority-discovery = { package = "substrate-authority-discovery", path = "../../core/authority-discovery"}
serde = { version = "1.0", features = [ "derive" ] }
client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] }
offchain = { package = "substrate-offchain", path = "../../core/offchain" }
[dev-dependencies]
keystore = { package = "substrate-keystore", path = "../../core/keystore" }
babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe", features = ["test-helpers"] }
+43 -9
View File
@@ -16,15 +16,16 @@
//! Substrate chain configurations.
use chain_spec::ChainSpecExtension;
use primitives::{Pair, Public, crypto::UncheckedInto};
pub use node_primitives::{AccountId, Balance};
use serde::{Serialize, Deserialize};
use node_runtime::{
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,
ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus,
StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY,
};
use node_runtime::Block;
use node_runtime::constants::{time::*, currency::*};
pub use node_runtime::GenesisConfig;
use substrate_service;
use hex_literal::hex;
use substrate_telemetry::TelemetryEndpoints;
@@ -33,11 +34,26 @@ use babe_primitives::{AuthorityId as BabeId};
use im_online::sr25519::{AuthorityId as ImOnlineId};
use sr_primitives::Perbill;
pub use node_primitives::{AccountId, Balance};
pub use node_runtime::GenesisConfig;
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
/// Specialized `ChainSpec`.
pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
/// Node `ChainSpec` extensions.
///
/// Additional parameters for some Substrate core modules,
/// customizable from the chain spec.
#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)]
pub struct Extensions {
/// Block numbers with known hashes.
pub fork_blocks: client::ForkBlocks<Block>,
}
/// Specialized `ChainSpec`.
pub type ChainSpec = substrate_service::ChainSpec<
GenesisConfig,
Extensions,
>;
/// Flaming Fir testnet generator
pub fn flaming_fir_config() -> Result<ChainSpec, String> {
ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..])
@@ -191,7 +207,7 @@ pub fn staging_testnet_config() -> ChainSpec {
Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])),
None,
None,
None,
Default::default(),
)
}
@@ -327,7 +343,16 @@ fn development_config_genesis() -> GenesisConfig {
/// Development config (single validator Alice)
pub fn development_config() -> ChainSpec {
ChainSpec::from_genesis("Development", "dev", development_config_genesis, vec![], None, None, None, None)
ChainSpec::from_genesis(
"Development",
"dev",
development_config_genesis,
vec![],
None,
None,
None,
Default::default(),
)
}
fn local_testnet_genesis() -> GenesisConfig {
@@ -344,7 +369,16 @@ fn local_testnet_genesis() -> GenesisConfig {
/// Local testnet config (multivalidator Alice + Bob)
pub fn local_testnet_config() -> ChainSpec {
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None)
ChainSpec::from_genesis(
"Local Testnet",
"local_testnet",
local_testnet_genesis,
vec![],
None,
None,
None,
Default::default(),
)
}
#[cfg(test)]
@@ -375,7 +409,7 @@ pub(crate) mod tests {
None,
None,
None,
None,
Default::default(),
)
}
@@ -389,7 +423,7 @@ pub(crate) mod tests {
None,
None,
None,
None,
Default::default(),
)
}
+9 -7
View File
@@ -28,7 +28,7 @@ mod factory_impl;
use tokio::prelude::Future;
use tokio::runtime::{Builder as RuntimeBuilder, Runtime};
pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams, ExecutionStrategyParam};
use substrate_service::{AbstractService, Roles as ServiceRoles};
use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration};
use log::info;
use structopt::{StructOpt, clap::App};
use cli::{AugmentClap, GetLogFilter, parse_and_prepare, ParseAndPrepare};
@@ -158,9 +158,11 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
T: Into<std::ffi::OsString> + Clone,
E: IntoExit,
{
type Config<A, B> = Configuration<(), A, B>;
match parse_and_prepare::<CustomSubcommands, NoCustom, _>(&version, "substrate-node", args) {
ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit,
|exit, _cli_args, _custom_args, config| {
ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit,
|exit, _cli_args, _custom_args, config: Config<_, _>| {
info!("{}", version.name);
info!(" version {}", config.full_version());
info!(" by Parity Technologies, 2017-2019");
@@ -183,15 +185,15 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
}.map_err(|e| format!("{:?}", e))
}),
ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec),
ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config|
ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>|
Ok(new_full_start!(config).0), load_spec, exit),
ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config|
ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>|
Ok(new_full_start!(config).0), load_spec, exit),
ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec),
ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _>(|config|
ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_, _>|
Ok(new_full_start!(config).0), load_spec),
ParseAndPrepare::CustomCommand(CustomSubcommands::Factory(cli_args)) => {
let mut config = cli::create_config_with_db_path::<(), _, _>(
let mut config: Config<_, _> = cli::create_config_with_db_path(
load_spec,
&cli_args.shared_params,
&version,
+5 -2
View File
@@ -239,8 +239,11 @@ type ConcreteClient =
#[allow(dead_code)]
type ConcreteBackend = Backend<ConcreteBlock>;
/// A specialized configuration object for setting up the node..
pub type NodeConfiguration<C> = Configuration<C, GenesisConfig, crate::chain_spec::Extensions>;
/// Builds a new service for a full client.
pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)
pub fn new_full<C: Send + Default + 'static>(config: NodeConfiguration<C>)
-> Result<
NewService<
ConcreteBlock,
@@ -262,7 +265,7 @@ pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisCon
}
/// Builds a new service for a light client.
pub fn new_light<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)
pub fn new_light<C: Send + Default + 'static>(config: NodeConfiguration<C>)
-> Result<impl AbstractService, ServiceError> {
type RpcExtension = jsonrpc_core::IoHandler<substrate_rpc::Metadata>;
let inherent_data_providers = InherentDataProviders::new();
+1 -1
View File
@@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 165,
impl_version: 166,
impl_version: 167,
apis: RUNTIME_API_VERSIONS,
};
@@ -38,7 +38,7 @@ fn generate_chain_spec() -> String {
None,
None,
None,
None,
Default::default(),
);
build_spec(chain_spec, false).unwrap()
}