mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 18:28:03 +00:00
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:
committed by
Gavin Wood
parent
c555b9bf88
commit
667ee95f5d
Generated
+95
-68
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
}
|
||||
+121
-46
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)?)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)> {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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(())
|
||||
}?;
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user